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")));
1537 /* check loop expression is of the form <sym>++ */
1538 if (!IS_AST_OP (loopExpr))
1541 /* check if <sym> ++ */
1542 if (loopExpr->opval.op == INC_OP)
1548 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1549 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1556 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1557 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1565 if (loopExpr->opval.op == ADD_ASSIGN)
1568 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1569 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1570 IS_AST_LIT_VALUE (loopExpr->right) &&
1571 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1579 /*-----------------------------------------------------------------*/
1580 /* astHasVolatile - returns true if ast contains any volatile */
1581 /*-----------------------------------------------------------------*/
1583 astHasVolatile (ast * tree)
1588 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1591 if (IS_AST_OP (tree))
1592 return astHasVolatile (tree->left) ||
1593 astHasVolatile (tree->right);
1598 /*-----------------------------------------------------------------*/
1599 /* astHasPointer - return true if the ast contains any ptr variable */
1600 /*-----------------------------------------------------------------*/
1602 astHasPointer (ast * tree)
1607 if (IS_AST_LINK (tree))
1610 /* if we hit an array expression then check
1611 only the left side */
1612 if (IS_AST_OP (tree) && tree->opval.op == '[')
1613 return astHasPointer (tree->left);
1615 if (IS_AST_VALUE (tree))
1616 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1618 return astHasPointer (tree->left) ||
1619 astHasPointer (tree->right);
1623 /*-----------------------------------------------------------------*/
1624 /* astHasSymbol - return true if the ast has the given symbol */
1625 /*-----------------------------------------------------------------*/
1627 astHasSymbol (ast * tree, symbol * sym)
1629 if (!tree || IS_AST_LINK (tree))
1632 if (IS_AST_VALUE (tree))
1634 if (IS_AST_SYM_VALUE (tree))
1635 return isSymbolEqual (AST_SYMBOL (tree), sym);
1640 return astHasSymbol (tree->left, sym) ||
1641 astHasSymbol (tree->right, sym);
1644 /*-----------------------------------------------------------------*/
1645 /* astHasDeref - return true if the ast has an indirect access */
1646 /*-----------------------------------------------------------------*/
1648 astHasDeref (ast * tree)
1650 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1653 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1655 return astHasDeref (tree->left) || astHasDeref (tree->right);
1658 /*-----------------------------------------------------------------*/
1659 /* isConformingBody - the loop body has to conform to a set of rules */
1660 /* for the loop to be considered reversible read on for rules */
1661 /*-----------------------------------------------------------------*/
1663 isConformingBody (ast * pbody, symbol * sym, ast * body)
1666 /* we are going to do a pre-order traversal of the
1667 tree && check for the following conditions. (essentially
1668 a set of very shallow tests )
1669 a) the sym passed does not participate in
1670 any arithmetic operation
1671 b) There are no function calls
1672 c) all jumps are within the body
1673 d) address of loop control variable not taken
1674 e) if an assignment has a pointer on the
1675 left hand side make sure right does not have
1676 loop control variable */
1678 /* if we reach the end or a leaf then true */
1679 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1682 /* if anything else is "volatile" */
1683 if (IS_VOLATILE (TETYPE (pbody)))
1686 /* we will walk the body in a pre-order traversal for
1688 switch (pbody->opval.op)
1690 /*------------------------------------------------------------------*/
1692 // if the loopvar is used as an index
1693 /* array op is commutative -- must check both left & right */
1694 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1697 return isConformingBody (pbody->right, sym, body)
1698 && isConformingBody (pbody->left, sym, body);
1700 /*------------------------------------------------------------------*/
1705 /*------------------------------------------------------------------*/
1709 /* sure we are not sym is not modified */
1711 IS_AST_SYM_VALUE (pbody->left) &&
1712 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1716 IS_AST_SYM_VALUE (pbody->right) &&
1717 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1722 /*------------------------------------------------------------------*/
1724 case '*': /* can be unary : if right is null then unary operation */
1729 /* if right is NULL then unary operation */
1730 /*------------------------------------------------------------------*/
1731 /*----------------------------*/
1733 /*----------------------------*/
1736 if (IS_AST_SYM_VALUE (pbody->left) &&
1737 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1740 return isConformingBody (pbody->left, sym, body);
1744 if (astHasSymbol (pbody->left, sym) ||
1745 astHasSymbol (pbody->right, sym))
1750 /*------------------------------------------------------------------*/
1758 if (IS_AST_SYM_VALUE (pbody->left) &&
1759 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1762 if (IS_AST_SYM_VALUE (pbody->right) &&
1763 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1766 return isConformingBody (pbody->left, sym, body) &&
1767 isConformingBody (pbody->right, sym, body);
1775 if (IS_AST_SYM_VALUE (pbody->left) &&
1776 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1778 return isConformingBody (pbody->left, sym, body);
1780 /*------------------------------------------------------------------*/
1792 case SIZEOF: /* evaluate wihout code generation */
1794 if (IS_AST_SYM_VALUE (pbody->left) &&
1795 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1798 if (IS_AST_SYM_VALUE (pbody->right) &&
1799 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1802 return isConformingBody (pbody->left, sym, body) &&
1803 isConformingBody (pbody->right, sym, body);
1805 /*------------------------------------------------------------------*/
1808 /* if left has a pointer & right has loop
1809 control variable then we cannot */
1810 if (astHasPointer (pbody->left) &&
1811 astHasSymbol (pbody->right, sym))
1813 if (astHasVolatile (pbody->left))
1816 if (IS_AST_SYM_VALUE (pbody->left)) {
1817 // if the loopvar has an assignment
1818 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1820 // if the loopvar is used in another (maybe conditional) block
1821 if (astHasSymbol (pbody->right, sym) &&
1822 (pbody->level >= body->level)) {
1827 if (astHasVolatile (pbody->left))
1830 if (astHasDeref(pbody->right)) return FALSE;
1832 return isConformingBody (pbody->left, sym, body) &&
1833 isConformingBody (pbody->right, sym, body);
1844 assert ("Parser should not have generated this\n");
1846 /*------------------------------------------------------------------*/
1847 /*----------------------------*/
1848 /* comma operator */
1849 /*----------------------------*/
1851 return isConformingBody (pbody->left, sym, body) &&
1852 isConformingBody (pbody->right, sym, body);
1854 /*------------------------------------------------------------------*/
1855 /*----------------------------*/
1857 /*----------------------------*/
1859 /* if local & not passed as paramater then ok */
1860 if (sym->level && !astHasSymbol(pbody->right,sym))
1864 /*------------------------------------------------------------------*/
1865 /*----------------------------*/
1866 /* return statement */
1867 /*----------------------------*/
1872 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1877 if (astHasSymbol (pbody->left, sym))
1884 return isConformingBody (pbody->left, sym, body) &&
1885 isConformingBody (pbody->right, sym, body);
1891 /*-----------------------------------------------------------------*/
1892 /* isLoopReversible - takes a for loop as input && returns true */
1893 /* if the for loop is reversible. If yes will set the value of */
1894 /* the loop control var & init value & termination value */
1895 /*-----------------------------------------------------------------*/
1897 isLoopReversible (ast * loop, symbol ** loopCntrl,
1898 ast ** init, ast ** end)
1900 /* if option says don't do it then don't */
1901 if (optimize.noLoopReverse)
1903 /* there are several tests to determine this */
1905 /* for loop has to be of the form
1906 for ( <sym> = <const1> ;
1907 [<sym> < <const2>] ;
1908 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1910 if (!isLoopCountable (AST_FOR (loop, initExpr),
1911 AST_FOR (loop, condExpr),
1912 AST_FOR (loop, loopExpr),
1913 loopCntrl, init, end))
1916 /* now do some serious checking on the body of the loop
1919 return isConformingBody (loop->left, *loopCntrl, loop->left);
1923 /*-----------------------------------------------------------------*/
1924 /* replLoopSym - replace the loop sym by loop sym -1 */
1925 /*-----------------------------------------------------------------*/
1927 replLoopSym (ast * body, symbol * sym)
1930 if (!body || IS_AST_LINK (body))
1933 if (IS_AST_SYM_VALUE (body))
1936 if (isSymbolEqual (AST_SYMBOL (body), sym))
1940 body->opval.op = '-';
1941 body->left = newAst_VALUE (symbolVal (sym));
1942 body->right = newAst_VALUE (constVal ("1"));
1950 replLoopSym (body->left, sym);
1951 replLoopSym (body->right, sym);
1955 /*-----------------------------------------------------------------*/
1956 /* reverseLoop - do the actual loop reversal */
1957 /*-----------------------------------------------------------------*/
1959 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1963 /* create the following tree
1968 if (sym) goto for_continue ;
1971 /* put it together piece by piece */
1972 rloop = newNode (NULLOP,
1973 createIf (newAst_VALUE (symbolVal (sym)),
1975 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1978 newAst_VALUE (symbolVal (sym)),
1981 replLoopSym (loop->left, sym);
1982 setAstLineno (rloop, init->lineno);
1984 rloop = newNode (NULLOP,
1986 newAst_VALUE (symbolVal (sym)),
1987 newNode ('-', end, init)),
1988 createLabel (AST_FOR (loop, continueLabel),
1992 newNode (SUB_ASSIGN,
1993 newAst_VALUE (symbolVal (sym)),
1994 newAst_VALUE (constVal ("1"))),
1997 rloop->lineno=init->lineno;
1998 return decorateType (rloop, RESULT_TYPE_NONE);
2002 /*-----------------------------------------------------------------*/
2003 /* searchLitOp - search tree (*ops only) for an ast with literal */
2004 /*-----------------------------------------------------------------*/
2006 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2010 if (tree && optimize.global_cse)
2012 /* is there a literal operand? */
2014 IS_AST_OP(tree->right) &&
2015 tree->right->right &&
2016 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2018 if (IS_LITERAL (RTYPE (tree->right)) !=
2019 IS_LITERAL (LTYPE (tree->right)))
2021 tree->right->decorated = 0;
2022 tree->decorated = 0;
2026 ret = searchLitOp (tree->right, parent, ops);
2031 IS_AST_OP(tree->left) &&
2032 tree->left->right &&
2033 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2035 if (IS_LITERAL (RTYPE (tree->left)) !=
2036 IS_LITERAL (LTYPE (tree->left)))
2038 tree->left->decorated = 0;
2039 tree->decorated = 0;
2043 ret = searchLitOp (tree->left, parent, ops);
2051 /*-----------------------------------------------------------------*/
2052 /* getResultFromType */
2053 /*-----------------------------------------------------------------*/
2055 getResultTypeFromType (sym_link *type)
2057 /* type = getSpec (type); */
2059 return RESULT_TYPE_BIT;
2060 if (IS_BITFIELD (type))
2062 int blen = SPEC_BLEN (type);
2065 return RESULT_TYPE_BIT;
2067 return RESULT_TYPE_CHAR;
2068 return RESULT_TYPE_INT;
2071 return RESULT_TYPE_CHAR;
2074 return RESULT_TYPE_INT;
2075 return RESULT_TYPE_OTHER;
2078 /*-----------------------------------------------------------------*/
2079 /* addCast - adds casts to a type specified by RESULT_TYPE */
2080 /*-----------------------------------------------------------------*/
2082 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2085 bool upCasted = FALSE;
2089 case RESULT_TYPE_NONE:
2090 /* char: promote to int */
2092 getSize (tree->etype) >= INTSIZE)
2094 newLink = newIntLink();
2097 case RESULT_TYPE_CHAR:
2098 if (IS_CHAR (tree->etype) ||
2099 IS_FLOAT(tree->etype))
2101 newLink = newCharLink();
2103 case RESULT_TYPE_INT:
2105 if (getSize (tree->etype) > INTSIZE)
2107 /* warn ("Loosing significant digits"); */
2111 /* char: promote to int */
2113 getSize (tree->etype) >= INTSIZE)
2115 newLink = newIntLink();
2118 case RESULT_TYPE_OTHER:
2121 /* return type is long, float: promote char to int */
2122 if (getSize (tree->etype) >= INTSIZE)
2124 newLink = newIntLink();
2130 tree->decorated = 0;
2131 tree = newNode (CAST, newAst_LINK (newLink), tree);
2132 tree->lineno = tree->right->lineno;
2133 /* keep unsigned type during cast to smaller type,
2134 but not when promoting from char to int */
2136 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2137 return decorateType (tree, resultType);
2140 /*-----------------------------------------------------------------*/
2141 /* resultTypePropagate - decides if resultType can be propagated */
2142 /*-----------------------------------------------------------------*/
2144 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2146 switch (tree->opval.op)
2162 return RESULT_TYPE_NONE;
2166 return RESULT_TYPE_IFX;
2168 return RESULT_TYPE_NONE;
2172 /*-----------------------------------------------------------------*/
2173 /* getLeftResultType - gets type from left branch for propagation */
2174 /*-----------------------------------------------------------------*/
2176 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2178 switch (tree->opval.op)
2182 if (IS_PTR (LTYPE (tree)))
2183 return RESULT_TYPE_NONE;
2185 return getResultTypeFromType (LETYPE (tree));
2187 if (IS_PTR (currFunc->type->next))
2188 return RESULT_TYPE_NONE;
2190 return getResultTypeFromType (currFunc->type->next);
2192 if (!IS_ARRAY (LTYPE (tree)))
2194 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2195 return RESULT_TYPE_CHAR;
2202 /*--------------------------------------------------------------------*/
2203 /* decorateType - compute type for this tree, also does type checking.*/
2204 /* This is done bottom up, since type has to flow upwards. */
2205 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2206 /* result is a char and the operand(s) are int's. */
2207 /* It also does constant folding, and parameter checking. */
2208 /*--------------------------------------------------------------------*/
2210 decorateType (ast * tree, RESULT_TYPE resultType)
2214 RESULT_TYPE resultTypeProp;
2219 /* if already has type then do nothing */
2220 if (tree->decorated)
2223 tree->decorated = 1;
2226 /* print the line */
2227 /* if not block & function */
2228 if (tree->type == EX_OP &&
2229 (tree->opval.op != FUNCTION &&
2230 tree->opval.op != BLOCK &&
2231 tree->opval.op != NULLOP))
2233 filename = tree->filename;
2234 lineno = tree->lineno;
2238 /* if any child is an error | this one is an error do nothing */
2239 if (tree->isError ||
2240 (tree->left && tree->left->isError) ||
2241 (tree->right && tree->right->isError))
2244 /*------------------------------------------------------------------*/
2245 /*----------------------------*/
2246 /* leaf has been reached */
2247 /*----------------------------*/
2248 lineno=tree->lineno;
2249 /* if this is of type value */
2250 /* just get the type */
2251 if (tree->type == EX_VALUE)
2254 if (IS_LITERAL (tree->opval.val->etype))
2257 /* if this is a character array then declare it */
2258 if (IS_ARRAY (tree->opval.val->type))
2259 tree->opval.val = stringToSymbol (tree->opval.val);
2261 /* otherwise just copy the type information */
2262 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2266 if (tree->opval.val->sym)
2268 /* if the undefined flag is set then give error message */
2269 if (tree->opval.val->sym->undefined)
2271 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2273 TTYPE (tree) = TETYPE (tree) =
2274 tree->opval.val->type = tree->opval.val->sym->type =
2275 tree->opval.val->etype = tree->opval.val->sym->etype =
2276 copyLinkChain (INTTYPE);
2281 /* if impilicit i.e. struct/union member then no type */
2282 if (tree->opval.val->sym->implicit)
2283 TTYPE (tree) = TETYPE (tree) = NULL;
2288 /* else copy the type */
2289 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2291 /* and mark it as referenced */
2292 tree->opval.val->sym->isref = 1;
2300 /* if type link for the case of cast */
2301 if (tree->type == EX_LINK)
2303 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2311 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2313 if (tree->left && tree->left->type == EX_OPERAND
2314 && (tree->left->opval.op == INC_OP
2315 || tree->left->opval.op == DEC_OP)
2316 && tree->left->left)
2318 tree->left->right = tree->left->left;
2319 tree->left->left = NULL;
2321 if (tree->right && tree->right->type == EX_OPERAND
2322 && (tree->right->opval.op == INC_OP
2323 || tree->right->opval.op == DEC_OP)
2324 && tree->right->left)
2326 tree->right->right = tree->right->left;
2327 tree->right->left = NULL;
2332 /* Before decorating the left branch we've to decide in dependence
2333 upon tree->opval.op, if resultType can be propagated */
2334 resultTypeProp = resultTypePropagate (tree, resultType);
2336 if (tree->opval.op == '?')
2337 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2339 dtl = decorateType (tree->left, resultTypeProp);
2341 /* if an array node, we may need to swap branches */
2342 if (tree->opval.op == '[')
2344 /* determine which is the array & which the index */
2345 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2346 IS_INTEGRAL (LTYPE (tree)))
2348 ast *tempTree = tree->left;
2349 tree->left = tree->right;
2350 tree->right = tempTree;
2354 /* After decorating the left branch there's type information available
2355 in tree->left->?type. If the op is e.g. '=' we extract the type
2356 information from there and propagate it to the right branch. */
2357 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2359 switch (tree->opval.op)
2362 /* delay right side for '?' operator since conditional macro
2363 expansions might rely on this */
2367 /* decorate right side for CALL (parameter list) in processParms();
2368 there is resultType available */
2372 dtr = decorateType (tree->right, resultTypeProp);
2376 /* this is to take care of situations
2377 when the tree gets rewritten */
2378 if (dtl != tree->left)
2380 if (dtr != tree->right)
2382 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2386 /* depending on type of operator do */
2388 switch (tree->opval.op)
2390 /*------------------------------------------------------------------*/
2391 /*----------------------------*/
2393 /*----------------------------*/
2396 /* first check if this is a array or a pointer */
2397 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2399 werror (E_NEED_ARRAY_PTR, "[]");
2400 goto errorTreeReturn;
2403 /* check if the type of the idx */
2404 if (!IS_INTEGRAL (RTYPE (tree)))
2406 werror (E_IDX_NOT_INT);
2407 goto errorTreeReturn;
2410 /* if the left is an rvalue then error */
2413 werror (E_LVALUE_REQUIRED, "array access");
2414 goto errorTreeReturn;
2417 if (IS_LITERAL (RTYPE (tree)))
2419 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2420 int arraySize = DCL_ELEM (LTYPE (tree));
2421 if (arraySize && arrayIndex >= arraySize)
2423 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2428 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2431 /*------------------------------------------------------------------*/
2432 /*----------------------------*/
2434 /*----------------------------*/
2436 /* if this is not a structure */
2437 if (!IS_STRUCT (LTYPE (tree)))
2439 werror (E_STRUCT_UNION, ".");
2440 goto errorTreeReturn;
2442 TTYPE (tree) = structElemType (LTYPE (tree),
2443 (tree->right->type == EX_VALUE ?
2444 tree->right->opval.val : NULL));
2445 TETYPE (tree) = getSpec (TTYPE (tree));
2448 /*------------------------------------------------------------------*/
2449 /*----------------------------*/
2450 /* struct/union pointer */
2451 /*----------------------------*/
2453 /* if not pointer to a structure */
2454 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2456 werror (E_PTR_REQD);
2457 goto errorTreeReturn;
2460 if (!IS_STRUCT (LTYPE (tree)->next))
2462 werror (E_STRUCT_UNION, "->");
2463 goto errorTreeReturn;
2466 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2467 (tree->right->type == EX_VALUE ?
2468 tree->right->opval.val : NULL));
2469 TETYPE (tree) = getSpec (TTYPE (tree));
2471 /* adjust the storage class */
2472 switch (DCL_TYPE(tree->left->ftype)) {
2474 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2477 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2480 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2483 SPEC_SCLS (TETYPE (tree)) = 0;
2486 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2489 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2492 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2495 SPEC_SCLS (TETYPE (tree)) = 0;
2502 /* This breaks with extern declarations, bitfields, and perhaps other */
2503 /* cases (gcse). Let's leave this optimization disabled for now and */
2504 /* ponder if there's a safe way to do this. -- EEP */
2506 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2507 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2509 /* If defined struct type at addr var
2510 then rewrite (&struct var)->member
2512 and define membertype at (addr+offsetof(struct var,member)) temp
2515 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2516 AST_SYMBOL(tree->right));
2518 sym = newSymbol(genSymName (0), 0);
2519 sym->type = TTYPE (tree);
2520 sym->etype = getSpec(sym->type);
2521 sym->lineDef = tree->lineno;
2524 SPEC_STAT (sym->etype) = 1;
2525 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2527 SPEC_ABSA(sym->etype) = 1;
2528 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2531 AST_VALUE (tree) = symbolVal(sym);
2534 tree->type = EX_VALUE;
2542 /*------------------------------------------------------------------*/
2543 /*----------------------------*/
2544 /* ++/-- operation */
2545 /*----------------------------*/
2549 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2550 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2551 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2552 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2561 /*------------------------------------------------------------------*/
2562 /*----------------------------*/
2564 /*----------------------------*/
2565 case '&': /* can be unary */
2566 /* if right is NULL then unary operation */
2567 if (tree->right) /* not an unary operation */
2570 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2572 werror (E_BITWISE_OP);
2573 werror (W_CONTINUE, "left & right types are ");
2574 printTypeChain (LTYPE (tree), stderr);
2575 fprintf (stderr, ",");
2576 printTypeChain (RTYPE (tree), stderr);
2577 fprintf (stderr, "\n");
2578 goto errorTreeReturn;
2581 /* if they are both literal */
2582 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2584 tree->type = EX_VALUE;
2585 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2586 valFromType (RETYPE (tree)), '&');
2588 tree->right = tree->left = NULL;
2589 TETYPE (tree) = tree->opval.val->etype;
2590 TTYPE (tree) = tree->opval.val->type;
2594 /* see if this is a GETHBIT operation if yes
2597 ast *otree = optimizeGetHbit (tree);
2600 return decorateType (otree, RESULT_TYPE_NONE);
2603 /* if left is a literal exchange left & right */
2604 if (IS_LITERAL (LTYPE (tree)))
2606 ast *tTree = tree->left;
2607 tree->left = tree->right;
2608 tree->right = tTree;
2611 /* if right is a literal and */
2612 /* we can find a 2nd literal in an and-tree then */
2613 /* rearrange the tree */
2614 if (IS_LITERAL (RTYPE (tree)))
2617 ast *litTree = searchLitOp (tree, &parent, "&");
2621 ast *tTree = litTree->left;
2622 litTree->left = tree->right;
2623 tree->right = tTree;
2624 /* both operands in litTree are literal now */
2625 decorateType (parent, resultType);
2629 LRVAL (tree) = RRVAL (tree) = 1;
2631 TTYPE (tree) = computeType (LTYPE (tree),
2635 TETYPE (tree) = getSpec (TTYPE (tree));
2640 /*------------------------------------------------------------------*/
2641 /*----------------------------*/
2643 /*----------------------------*/
2644 p = newLink (DECLARATOR);
2645 /* if bit field then error */
2646 if (IS_BITVAR (tree->left->etype))
2648 werror (E_ILLEGAL_ADDR, "address of bit variable");
2649 goto errorTreeReturn;
2652 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2654 werror (E_ILLEGAL_ADDR, "address of register variable");
2655 goto errorTreeReturn;
2658 if (IS_FUNC (LTYPE (tree)))
2660 // this ought to be ignored
2661 return (tree->left);
2664 if (IS_LITERAL(LTYPE(tree)))
2666 werror (E_ILLEGAL_ADDR, "address of literal");
2667 goto errorTreeReturn;
2672 werror (E_LVALUE_REQUIRED, "address of");
2673 goto errorTreeReturn;
2676 DCL_TYPE (p) = POINTER;
2677 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2678 DCL_TYPE (p) = CPOINTER;
2679 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2680 DCL_TYPE (p) = FPOINTER;
2681 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2682 DCL_TYPE (p) = PPOINTER;
2683 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2684 DCL_TYPE (p) = IPOINTER;
2685 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2686 DCL_TYPE (p) = EEPPOINTER;
2687 else if (SPEC_OCLS(tree->left->etype))
2688 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2690 DCL_TYPE (p) = POINTER;
2692 if (IS_AST_SYM_VALUE (tree->left))
2694 AST_SYMBOL (tree->left)->addrtaken = 1;
2695 AST_SYMBOL (tree->left)->allocreq = 1;
2698 p->next = LTYPE (tree);
2700 TETYPE (tree) = getSpec (TTYPE (tree));
2705 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2706 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2708 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2709 AST_SYMBOL(tree->left->right));
2710 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2711 valueFromLit(element->offset));
2714 tree->type = EX_VALUE;
2715 tree->values.literalFromCast = 1;
2721 /*------------------------------------------------------------------*/
2722 /*----------------------------*/
2724 /*----------------------------*/
2726 /* if the rewrite succeeds then don't go any furthur */
2728 ast *wtree = optimizeRRCRLC (tree);
2730 return decorateType (wtree, RESULT_TYPE_NONE);
2732 wtree = optimizeSWAP (tree);
2734 return decorateType (wtree, RESULT_TYPE_NONE);
2737 /* if left is a literal exchange left & right */
2738 if (IS_LITERAL (LTYPE (tree)))
2740 ast *tTree = tree->left;
2741 tree->left = tree->right;
2742 tree->right = tTree;
2745 /* if right is a literal and */
2746 /* we can find a 2nd literal in an or-tree then */
2747 /* rearrange the tree */
2748 if (IS_LITERAL (RTYPE (tree)))
2751 ast *litTree = searchLitOp (tree, &parent, "|");
2755 ast *tTree = litTree->left;
2756 litTree->left = tree->right;
2757 tree->right = tTree;
2758 /* both operands in tTree are literal now */
2759 decorateType (parent, resultType);
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2767 /*----------------------------*/
2769 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2771 werror (E_BITWISE_OP);
2772 werror (W_CONTINUE, "left & right types are ");
2773 printTypeChain (LTYPE (tree), stderr);
2774 fprintf (stderr, ",");
2775 printTypeChain (RTYPE (tree), stderr);
2776 fprintf (stderr, "\n");
2777 goto errorTreeReturn;
2780 /* if they are both literal then rewrite the tree */
2781 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2783 tree->type = EX_VALUE;
2784 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2785 valFromType (RETYPE (tree)),
2787 tree->right = tree->left = NULL;
2788 TETYPE (tree) = tree->opval.val->etype;
2789 TTYPE (tree) = tree->opval.val->type;
2793 /* if left is a literal exchange left & right */
2794 if (IS_LITERAL (LTYPE (tree)))
2796 ast *tTree = tree->left;
2797 tree->left = tree->right;
2798 tree->right = tTree;
2801 /* if right is a literal and */
2802 /* we can find a 2nd literal in a xor-tree then */
2803 /* rearrange the tree */
2804 if (IS_LITERAL (RTYPE (tree)) &&
2805 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2808 ast *litTree = searchLitOp (tree, &parent, "^");
2812 ast *tTree = litTree->left;
2813 litTree->left = tree->right;
2814 tree->right = tTree;
2815 /* both operands in litTree are literal now */
2816 decorateType (parent, resultType);
2820 LRVAL (tree) = RRVAL (tree) = 1;
2822 TTYPE (tree) = computeType (LTYPE (tree),
2826 TETYPE (tree) = getSpec (TTYPE (tree));
2830 /*------------------------------------------------------------------*/
2831 /*----------------------------*/
2833 /*----------------------------*/
2835 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2837 werror (E_INVALID_OP, "divide");
2838 goto errorTreeReturn;
2840 /* if they are both literal then */
2841 /* rewrite the tree */
2842 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2844 tree->type = EX_VALUE;
2845 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2846 valFromType (RETYPE (tree)));
2847 tree->right = tree->left = NULL;
2848 TETYPE (tree) = getSpec (TTYPE (tree) =
2849 tree->opval.val->type);
2853 LRVAL (tree) = RRVAL (tree) = 1;
2855 TETYPE (tree) = getSpec (TTYPE (tree) =
2856 computeType (LTYPE (tree),
2861 /* if right is a literal and */
2862 /* left is also a division by a literal then */
2863 /* rearrange the tree */
2864 if (IS_LITERAL (RTYPE (tree))
2865 /* avoid infinite loop */
2866 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2869 ast *litTree = searchLitOp (tree, &parent, "/");
2872 if (IS_LITERAL (RTYPE (litTree)))
2876 litTree->right = newNode ('*',
2878 copyAst (tree->right));
2879 litTree->right->lineno = tree->lineno;
2881 tree->right->opval.val = constVal ("1");
2882 decorateType (parent, resultType);
2886 /* litTree->left is literal: no gcse possible.
2887 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2888 this would cause an infinit loop. */
2889 parent->decorated = 1;
2890 decorateType (litTree, resultType);
2897 /*------------------------------------------------------------------*/
2898 /*----------------------------*/
2900 /*----------------------------*/
2902 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2904 werror (E_BITWISE_OP);
2905 werror (W_CONTINUE, "left & right types are ");
2906 printTypeChain (LTYPE (tree), stderr);
2907 fprintf (stderr, ",");
2908 printTypeChain (RTYPE (tree), stderr);
2909 fprintf (stderr, "\n");
2910 goto errorTreeReturn;
2912 /* if they are both literal then */
2913 /* rewrite the tree */
2914 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2916 tree->type = EX_VALUE;
2917 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2918 valFromType (RETYPE (tree)));
2919 tree->right = tree->left = NULL;
2920 TETYPE (tree) = getSpec (TTYPE (tree) =
2921 tree->opval.val->type);
2924 LRVAL (tree) = RRVAL (tree) = 1;
2925 TETYPE (tree) = getSpec (TTYPE (tree) =
2926 computeType (LTYPE (tree),
2932 /*------------------------------------------------------------------*/
2933 /*----------------------------*/
2934 /* address dereference */
2935 /*----------------------------*/
2936 case '*': /* can be unary : if right is null then unary operation */
2939 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2941 werror (E_PTR_REQD);
2942 goto errorTreeReturn;
2947 werror (E_LVALUE_REQUIRED, "pointer deref");
2948 goto errorTreeReturn;
2950 if (IS_ADDRESS_OF_OP(tree->left))
2952 /* replace *&obj with obj */
2953 return tree->left->left;
2955 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2956 TETYPE (tree) = getSpec (TTYPE (tree));
2957 /* adjust the storage class */
2958 switch (DCL_TYPE(tree->left->ftype)) {
2960 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2963 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2966 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2969 SPEC_SCLS (TETYPE (tree)) = 0;
2972 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2975 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2978 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2981 SPEC_SCLS (TETYPE (tree)) = 0;
2990 /*------------------------------------------------------------------*/
2991 /*----------------------------*/
2992 /* multiplication */
2993 /*----------------------------*/
2994 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2996 werror (E_INVALID_OP, "multiplication");
2997 goto errorTreeReturn;
3000 /* if they are both literal then */
3001 /* rewrite the tree */
3002 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3004 tree->type = EX_VALUE;
3005 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3006 valFromType (RETYPE (tree)));
3007 tree->right = tree->left = NULL;
3008 TETYPE (tree) = getSpec (TTYPE (tree) =
3009 tree->opval.val->type);
3013 /* if left is a literal exchange left & right */
3014 if (IS_LITERAL (LTYPE (tree)))
3016 ast *tTree = tree->left;
3017 tree->left = tree->right;
3018 tree->right = tTree;
3021 /* if right is a literal and */
3022 /* we can find a 2nd literal in a mul-tree then */
3023 /* rearrange the tree */
3024 if (IS_LITERAL (RTYPE (tree)))
3027 ast *litTree = searchLitOp (tree, &parent, "*");
3031 ast *tTree = litTree->left;
3032 litTree->left = tree->right;
3033 tree->right = tTree;
3034 /* both operands in litTree are literal now */
3035 decorateType (parent, resultType);
3039 LRVAL (tree) = RRVAL (tree) = 1;
3040 tree->left = addCast (tree->left, resultType, FALSE);
3041 tree->right = addCast (tree->right, resultType, FALSE);
3042 TETYPE (tree) = getSpec (TTYPE (tree) =
3043 computeType (LTYPE (tree),
3050 /*------------------------------------------------------------------*/
3051 /*----------------------------*/
3052 /* unary '+' operator */
3053 /*----------------------------*/
3058 if (!IS_ARITHMETIC (LTYPE (tree)))
3060 werror (E_UNARY_OP, '+');
3061 goto errorTreeReturn;
3064 /* if left is a literal then do it */
3065 if (IS_LITERAL (LTYPE (tree)))
3067 tree->type = EX_VALUE;
3068 tree->opval.val = valFromType (LETYPE (tree));
3070 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3074 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3078 /*------------------------------------------------------------------*/
3079 /*----------------------------*/
3081 /*----------------------------*/
3083 /* this is not a unary operation */
3084 /* if both pointers then problem */
3085 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3086 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3088 werror (E_PTR_PLUS_PTR);
3089 goto errorTreeReturn;
3092 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3093 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3095 werror (E_PLUS_INVALID, "+");
3096 goto errorTreeReturn;
3099 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3100 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3102 werror (E_PLUS_INVALID, "+");
3103 goto errorTreeReturn;
3105 /* if they are both literal then */
3106 /* rewrite the tree */
3107 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3109 tree->type = EX_VALUE;
3110 tree->left = addCast (tree->left, resultType, TRUE);
3111 tree->right = addCast (tree->right, resultType, TRUE);
3112 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3113 valFromType (RETYPE (tree)));
3114 tree->right = tree->left = NULL;
3115 TETYPE (tree) = getSpec (TTYPE (tree) =
3116 tree->opval.val->type);
3120 /* if the right is a pointer or left is a literal
3121 xchange left & right */
3122 if (IS_ARRAY (RTYPE (tree)) ||
3123 IS_PTR (RTYPE (tree)) ||
3124 IS_LITERAL (LTYPE (tree)))
3126 ast *tTree = tree->left;
3127 tree->left = tree->right;
3128 tree->right = tTree;
3131 /* if right is a literal and */
3132 /* left is also an addition/subtraction with a literal then */
3133 /* rearrange the tree */
3134 if (IS_LITERAL (RTYPE (tree)))
3136 ast *litTree, *parent;
3137 litTree = searchLitOp (tree, &parent, "+-");
3140 if (litTree->opval.op == '+')
3144 ast *tTree = litTree->left;
3145 litTree->left = tree->right;
3146 tree->right = tree->left;
3149 else if (litTree->opval.op == '-')
3151 if (IS_LITERAL (RTYPE (litTree)))
3155 ast *tTree = litTree->left;
3156 litTree->left = tree->right;
3157 tree->right = tTree;
3163 ast *tTree = litTree->right;
3164 litTree->right = tree->right;
3165 tree->right = tTree;
3166 litTree->opval.op = '+';
3167 tree->opval.op = '-';
3170 decorateType (parent, resultType);
3174 LRVAL (tree) = RRVAL (tree) = 1;
3175 /* if the left is a pointer */
3176 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3177 TETYPE (tree) = getSpec (TTYPE (tree) =
3181 tree->left = addCast (tree->left, resultType, TRUE);
3182 tree->right = addCast (tree->right, resultType, TRUE);
3183 TETYPE (tree) = getSpec (TTYPE (tree) =
3184 computeType (LTYPE (tree),
3192 /*------------------------------------------------------------------*/
3193 /*----------------------------*/
3195 /*----------------------------*/
3196 case '-': /* can be unary */
3197 /* if right is null then unary */
3201 if (!IS_ARITHMETIC (LTYPE (tree)))
3203 werror (E_UNARY_OP, tree->opval.op);
3204 goto errorTreeReturn;
3207 /* if left is a literal then do it */
3208 if (IS_LITERAL (LTYPE (tree)))
3210 tree->type = EX_VALUE;
3211 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3213 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3214 SPEC_USIGN(TETYPE(tree)) = 0;
3218 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3222 /*------------------------------------------------------------------*/
3223 /*----------------------------*/
3225 /*----------------------------*/
3227 if (!(IS_PTR (LTYPE (tree)) ||
3228 IS_ARRAY (LTYPE (tree)) ||
3229 IS_ARITHMETIC (LTYPE (tree))))
3231 werror (E_PLUS_INVALID, "-");
3232 goto errorTreeReturn;
3235 if (!(IS_PTR (RTYPE (tree)) ||
3236 IS_ARRAY (RTYPE (tree)) ||
3237 IS_ARITHMETIC (RTYPE (tree))))
3239 werror (E_PLUS_INVALID, "-");
3240 goto errorTreeReturn;
3243 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3244 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3245 IS_INTEGRAL (RTYPE (tree))))
3247 werror (E_PLUS_INVALID, "-");
3248 goto errorTreeReturn;
3251 /* if they are both literal then */
3252 /* rewrite the tree */
3253 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3255 tree->type = EX_VALUE;
3256 tree->left = addCast (tree->left, resultType, TRUE);
3257 tree->right = addCast (tree->right, resultType, TRUE);
3258 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3259 valFromType (RETYPE (tree)));
3260 tree->right = tree->left = NULL;
3261 TETYPE (tree) = getSpec (TTYPE (tree) =
3262 tree->opval.val->type);
3266 /* if the left & right are equal then zero */
3267 if (isAstEqual (tree->left, tree->right))
3269 tree->type = EX_VALUE;
3270 tree->left = tree->right = NULL;
3271 tree->opval.val = constVal ("0");
3272 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3276 /* if both of them are pointers or arrays then */
3277 /* the result is going to be an integer */
3278 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3279 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3280 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3282 /* if only the left is a pointer */
3283 /* then result is a pointer */
3284 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3285 TETYPE (tree) = getSpec (TTYPE (tree) =
3289 tree->left = addCast (tree->left, resultType, TRUE);
3290 tree->right = addCast (tree->right, resultType, TRUE);
3292 TETYPE (tree) = getSpec (TTYPE (tree) =
3293 computeType (LTYPE (tree),
3299 LRVAL (tree) = RRVAL (tree) = 1;
3301 /* if right is a literal and */
3302 /* left is also an addition/subtraction with a literal then */
3303 /* rearrange the tree */
3304 if (IS_LITERAL (RTYPE (tree))
3305 /* avoid infinite loop */
3306 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3308 ast *litTree, *litParent;
3309 litTree = searchLitOp (tree, &litParent, "+-");
3312 if (litTree->opval.op == '+')
3316 ast *tTree = litTree->left;
3317 litTree->left = litTree->right;
3318 litTree->right = tree->right;
3319 tree->right = tTree;
3320 tree->opval.op = '+';
3321 litTree->opval.op = '-';
3323 else if (litTree->opval.op == '-')
3325 if (IS_LITERAL (RTYPE (litTree)))
3329 ast *tTree = litTree->left;
3330 litTree->left = tree->right;
3331 tree->right = litParent->left;
3332 litParent->left = tTree;
3333 litTree->opval.op = '+';
3335 tree->decorated = 0;
3336 decorateType (tree, resultType);
3342 ast *tTree = litTree->right;
3343 litTree->right = tree->right;
3344 tree->right = tTree;
3347 decorateType (litParent, resultType);
3352 /*------------------------------------------------------------------*/
3353 /*----------------------------*/
3355 /*----------------------------*/
3357 /* can be only integral type */
3358 if (!IS_INTEGRAL (LTYPE (tree)))
3360 werror (E_UNARY_OP, tree->opval.op);
3361 goto errorTreeReturn;
3364 /* if left is a literal then do it */
3365 if (IS_LITERAL (LTYPE (tree)))
3367 tree->type = EX_VALUE;
3368 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3370 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3371 return addCast (tree, resultType, TRUE);
3373 tree->left = addCast (tree->left, resultType, TRUE);
3375 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3378 /*------------------------------------------------------------------*/
3379 /*----------------------------*/
3381 /*----------------------------*/
3383 /* can be pointer */
3384 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3385 !IS_PTR (LTYPE (tree)) &&
3386 !IS_ARRAY (LTYPE (tree)))
3388 werror (E_UNARY_OP, tree->opval.op);
3389 goto errorTreeReturn;
3392 /* if left is a literal then do it */
3393 if (IS_LITERAL (LTYPE (tree)))
3395 tree->type = EX_VALUE;
3396 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3398 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3402 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3405 /*------------------------------------------------------------------*/
3406 /*----------------------------*/
3408 /*----------------------------*/
3412 TTYPE (tree) = LTYPE (tree);
3413 TETYPE (tree) = LETYPE (tree);
3417 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3422 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3424 werror (E_SHIFT_OP_INVALID);
3425 werror (W_CONTINUE, "left & right types are ");
3426 printTypeChain (LTYPE (tree), stderr);
3427 fprintf (stderr, ",");
3428 printTypeChain (RTYPE (tree), stderr);
3429 fprintf (stderr, "\n");
3430 goto errorTreeReturn;
3433 /* make smaller type only if it's a LEFT_OP */
3434 if (tree->opval.op == LEFT_OP)
3435 tree->left = addCast (tree->left, resultType, TRUE);
3437 /* if they are both literal then */
3438 /* rewrite the tree */
3439 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3441 tree->type = EX_VALUE;
3442 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3443 valFromType (RETYPE (tree)),
3444 (tree->opval.op == LEFT_OP ? 1 : 0));
3445 tree->right = tree->left = NULL;
3446 TETYPE (tree) = getSpec (TTYPE (tree) =
3447 tree->opval.val->type);
3451 LRVAL (tree) = RRVAL (tree) = 1;
3452 if (tree->opval.op == LEFT_OP)
3454 TETYPE (tree) = getSpec (TTYPE (tree) =
3455 computeType (LTYPE (tree),
3462 /* no promotion necessary */
3463 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3464 if (IS_LITERAL (TTYPE (tree)))
3465 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3468 /* if only the right side is a literal & we are
3469 shifting more than size of the left operand then zero */
3470 if (IS_LITERAL (RTYPE (tree)) &&
3471 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3472 (getSize (TETYPE (tree)) * 8))
3474 if (tree->opval.op==LEFT_OP ||
3475 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3477 lineno=tree->lineno;
3478 werror (W_SHIFT_CHANGED,
3479 (tree->opval.op == LEFT_OP ? "left" : "right"));
3480 tree->type = EX_VALUE;
3481 tree->left = tree->right = NULL;
3482 tree->opval.val = constVal ("0");
3483 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3490 /*------------------------------------------------------------------*/
3491 /*----------------------------*/
3493 /*----------------------------*/
3494 case CAST: /* change the type */
3495 /* cannot cast to an aggregate type */
3496 if (IS_AGGREGATE (LTYPE (tree)))
3498 werror (E_CAST_ILLEGAL);
3499 goto errorTreeReturn;
3502 /* make sure the type is complete and sane */
3503 changePointer(LTYPE(tree));
3504 checkTypeSanity(LETYPE(tree), "(cast)");
3506 /* If code memory is read only, then pointers to code memory */
3507 /* implicitly point to constants -- make this explicit */
3509 sym_link *t = LTYPE(tree);
3510 while (t && t->next)
3512 if (IS_CODEPTR(t) && port->mem.code_ro)
3514 if (IS_SPEC(t->next))
3515 SPEC_CONST (t->next) = 1;
3517 DCL_PTR_CONST (t->next) = 1;
3524 /* if the right is a literal replace the tree */
3525 if (IS_LITERAL (RETYPE (tree))) {
3526 if (!IS_PTR (LTYPE (tree))) {
3527 tree->type = EX_VALUE;
3529 valCastLiteral (LTYPE (tree),
3530 floatFromVal (valFromType (RETYPE (tree))));
3533 TTYPE (tree) = tree->opval.val->type;
3534 tree->values.literalFromCast = 1;
3535 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3536 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3537 sym_link *rest = LTYPE(tree)->next;
3538 werror(W_LITERAL_GENERIC);
3539 TTYPE(tree) = newLink(DECLARATOR);
3540 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3541 TTYPE(tree)->next = rest;
3542 tree->left->opval.lnk = TTYPE(tree);
3545 TTYPE (tree) = LTYPE (tree);
3549 TTYPE (tree) = LTYPE (tree);
3553 #if 0 // this is already checked, now this could be explicit
3554 /* if pointer to struct then check names */
3555 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3556 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3557 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3559 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3560 SPEC_STRUCT(LETYPE(tree))->tag);
3563 if (IS_ADDRESS_OF_OP(tree->right)
3564 && IS_AST_SYM_VALUE (tree->right->left)
3565 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3567 tree->type = EX_VALUE;
3569 valCastLiteral (LTYPE (tree),
3570 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3571 TTYPE (tree) = tree->opval.val->type;
3572 TETYPE (tree) = getSpec (TTYPE (tree));
3575 tree->values.literalFromCast = 1;
3579 /* handle offsetof macro: */
3580 /* #define offsetof(TYPE, MEMBER) \ */
3581 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3582 if (IS_ADDRESS_OF_OP(tree->right)
3583 && IS_AST_OP (tree->right->left)
3584 && tree->right->left->opval.op == PTR_OP
3585 && IS_AST_OP (tree->right->left->left)
3586 && tree->right->left->left->opval.op == CAST
3587 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3589 symbol *element = getStructElement (
3590 SPEC_STRUCT (LETYPE(tree->right->left)),
3591 AST_SYMBOL(tree->right->left->right)
3595 tree->type = EX_VALUE;
3596 tree->opval.val = valCastLiteral (
3599 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3602 TTYPE (tree) = tree->opval.val->type;
3603 TETYPE (tree) = getSpec (TTYPE (tree));
3610 /* if the right is a literal replace the tree */
3611 if (IS_LITERAL (RETYPE (tree))) {
3613 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3614 /* rewrite (type *)litaddr
3616 and define type at litaddr temp
3617 (but only if type's storage class is not generic)
3619 ast *newTree = newNode ('&', NULL, NULL);
3622 TTYPE (newTree) = LTYPE (tree);
3623 TETYPE (newTree) = getSpec(LTYPE (tree));
3625 /* define a global symbol at the casted address*/
3626 sym = newSymbol(genSymName (0), 0);
3627 sym->type = LTYPE (tree)->next;
3629 sym->type = newLink (V_VOID);
3630 sym->etype = getSpec(sym->type);
3631 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3632 sym->lineDef = tree->lineno;
3635 SPEC_STAT (sym->etype) = 1;
3636 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3637 SPEC_ABSA(sym->etype) = 1;
3638 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3641 newTree->left = newAst_VALUE(symbolVal(sym));
3642 newTree->left->lineno = tree->lineno;
3643 LTYPE (newTree) = sym->type;
3644 LETYPE (newTree) = sym->etype;
3645 LLVAL (newTree) = 1;
3646 LRVAL (newTree) = 0;
3647 TLVAL (newTree) = 1;
3651 if (!IS_PTR (LTYPE (tree))) {
3652 tree->type = EX_VALUE;
3654 valCastLiteral (LTYPE (tree),
3655 floatFromVal (valFromType (RTYPE (tree))));
3656 TTYPE (tree) = tree->opval.val->type;
3659 tree->values.literalFromCast = 1;
3660 TETYPE (tree) = getSpec (TTYPE (tree));
3664 TTYPE (tree) = LTYPE (tree);
3668 TETYPE (tree) = getSpec (TTYPE (tree));
3672 /*------------------------------------------------------------------*/
3673 /*----------------------------*/
3674 /* logical &&, || */
3675 /*----------------------------*/
3678 /* each must be arithmetic type or be a pointer */
3679 if (!IS_PTR (LTYPE (tree)) &&
3680 !IS_ARRAY (LTYPE (tree)) &&
3681 !IS_INTEGRAL (LTYPE (tree)))
3683 werror (E_COMPARE_OP);
3684 goto errorTreeReturn;
3687 if (!IS_PTR (RTYPE (tree)) &&
3688 !IS_ARRAY (RTYPE (tree)) &&
3689 !IS_INTEGRAL (RTYPE (tree)))
3691 werror (E_COMPARE_OP);
3692 goto errorTreeReturn;
3694 /* if they are both literal then */
3695 /* rewrite the tree */
3696 if (IS_LITERAL (RTYPE (tree)) &&
3697 IS_LITERAL (LTYPE (tree)))
3699 tree->type = EX_VALUE;
3700 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3701 valFromType (RTYPE (tree)),
3703 tree->right = tree->left = NULL;
3704 TETYPE (tree) = getSpec (TTYPE (tree) =
3705 tree->opval.val->type);
3708 LRVAL (tree) = RRVAL (tree) = 1;
3709 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3712 /*------------------------------------------------------------------*/
3713 /*----------------------------*/
3714 /* comparison operators */
3715 /*----------------------------*/
3723 ast *lt = optimizeCompare (tree);
3729 /* if they are pointers they must be castable */
3730 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3732 if (tree->opval.op==EQ_OP &&
3733 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3734 // we cannot cast a gptr to a !gptr: switch the leaves
3735 struct ast *s=tree->left;
3736 tree->left=tree->right;
3739 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3741 werror (E_COMPARE_OP);
3742 fprintf (stderr, "comparing type ");
3743 printTypeChain (LTYPE (tree), stderr);
3744 fprintf (stderr, "to type ");
3745 printTypeChain (RTYPE (tree), stderr);
3746 fprintf (stderr, "\n");
3747 goto errorTreeReturn;
3750 /* else they should be promotable to one another */
3753 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3754 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3756 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3758 werror (E_COMPARE_OP);
3759 fprintf (stderr, "comparing type ");
3760 printTypeChain (LTYPE (tree), stderr);
3761 fprintf (stderr, "to type ");
3762 printTypeChain (RTYPE (tree), stderr);
3763 fprintf (stderr, "\n");
3764 goto errorTreeReturn;
3767 /* if unsigned value < 0 then always false */
3768 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3769 if (SPEC_USIGN(LETYPE(tree)) &&
3770 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3771 IS_LITERAL(RTYPE(tree)) &&
3772 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3774 if (tree->opval.op == '<')
3778 if (tree->opval.op == '>')
3780 if (resultType == RESULT_TYPE_IFX)
3782 /* the parent is an ifx: */
3783 /* if (unsigned value) */
3787 /* (unsigned value) ? 1 : 0 */
3788 tree->opval.op = '?';
3789 tree->right = newNode (':',
3790 newAst_VALUE (constVal ("1")),
3791 tree->right); /* val 0 */
3792 tree->right->lineno = tree->lineno;
3793 tree->right->left->lineno = tree->lineno;
3794 decorateType (tree->right, RESULT_TYPE_NONE);
3797 /* if they are both literal then */
3798 /* rewrite the tree */
3799 if (IS_LITERAL (RTYPE (tree)) &&
3800 IS_LITERAL (LTYPE (tree)))
3802 tree->type = EX_VALUE;
3803 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3804 valFromType (RETYPE (tree)),
3806 tree->right = tree->left = NULL;
3807 TETYPE (tree) = getSpec (TTYPE (tree) =
3808 tree->opval.val->type);
3811 LRVAL (tree) = RRVAL (tree) = 1;
3812 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3815 /*------------------------------------------------------------------*/
3816 /*----------------------------*/
3818 /*----------------------------*/
3819 case SIZEOF: /* evaluate wihout code generation */
3820 /* change the type to a integer */
3822 int size = getSize (tree->right->ftype);
3823 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3824 if (!size && !IS_VOID(tree->right->ftype))
3825 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3827 tree->type = EX_VALUE;
3828 tree->opval.val = constVal (buffer);
3829 tree->right = tree->left = NULL;
3830 TETYPE (tree) = getSpec (TTYPE (tree) =
3831 tree->opval.val->type);
3834 /*------------------------------------------------------------------*/
3835 /*----------------------------*/
3837 /*----------------------------*/
3839 /* return typeof enum value */
3840 tree->type = EX_VALUE;
3843 if (IS_SPEC(tree->right->ftype)) {
3844 switch (SPEC_NOUN(tree->right->ftype)) {
3846 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3847 else typeofv = TYPEOF_INT;
3850 typeofv = TYPEOF_FLOAT;
3853 typeofv = TYPEOF_CHAR;
3856 typeofv = TYPEOF_VOID;
3859 typeofv = TYPEOF_STRUCT;
3862 typeofv = TYPEOF_BITFIELD;
3865 typeofv = TYPEOF_BIT;
3868 typeofv = TYPEOF_SBIT;
3874 switch (DCL_TYPE(tree->right->ftype)) {
3876 typeofv = TYPEOF_POINTER;
3879 typeofv = TYPEOF_FPOINTER;
3882 typeofv = TYPEOF_CPOINTER;
3885 typeofv = TYPEOF_GPOINTER;
3888 typeofv = TYPEOF_PPOINTER;
3891 typeofv = TYPEOF_IPOINTER;
3894 typeofv = TYPEOF_ARRAY;
3897 typeofv = TYPEOF_FUNCTION;
3903 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3904 tree->opval.val = constVal (buffer);
3905 tree->right = tree->left = NULL;
3906 TETYPE (tree) = getSpec (TTYPE (tree) =
3907 tree->opval.val->type);
3910 /*------------------------------------------------------------------*/
3911 /*----------------------------*/
3912 /* conditional operator '?' */
3913 /*----------------------------*/
3915 /* the type is value of the colon operator (on the right) */
3916 assert (IS_COLON_OP (tree->right));
3917 /* if already known then replace the tree : optimizer will do it
3918 but faster to do it here */
3919 if (IS_LITERAL (LTYPE (tree)))
3921 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3922 return decorateType (tree->right->left, resultTypeProp);
3924 return decorateType (tree->right->right, resultTypeProp);
3928 tree->right = decorateType (tree->right, resultTypeProp);
3929 TTYPE (tree) = RTYPE (tree);
3930 TETYPE (tree) = getSpec (TTYPE (tree));
3935 /* if they don't match we have a problem */
3936 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3938 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3939 goto errorTreeReturn;
3942 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3943 resultType, tree->opval.op);
3944 TETYPE (tree) = getSpec (TTYPE (tree));
3948 #if 0 // assignment operators are converted by the parser
3949 /*------------------------------------------------------------------*/
3950 /*----------------------------*/
3951 /* assignment operators */
3952 /*----------------------------*/
3955 /* for these it must be both must be integral */
3956 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3957 !IS_ARITHMETIC (RTYPE (tree)))
3959 werror (E_OPS_INTEGRAL);
3960 goto errorTreeReturn;
3963 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3965 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3966 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3970 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3971 goto errorTreeReturn;
3982 /* for these it must be both must be integral */
3983 if (!IS_INTEGRAL (LTYPE (tree)) ||
3984 !IS_INTEGRAL (RTYPE (tree)))
3986 werror (E_OPS_INTEGRAL);
3987 goto errorTreeReturn;
3990 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3992 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3993 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3997 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3998 goto errorTreeReturn;
4004 /*------------------------------------------------------------------*/
4005 /*----------------------------*/
4007 /*----------------------------*/
4009 if (!(IS_PTR (LTYPE (tree)) ||
4010 IS_ARITHMETIC (LTYPE (tree))))
4012 werror (E_PLUS_INVALID, "-=");
4013 goto errorTreeReturn;
4016 if (!(IS_PTR (RTYPE (tree)) ||
4017 IS_ARITHMETIC (RTYPE (tree))))
4019 werror (E_PLUS_INVALID, "-=");
4020 goto errorTreeReturn;
4023 TETYPE (tree) = getSpec (TTYPE (tree) =
4024 computeType (LTYPE (tree),
4029 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4030 werror (E_CODE_WRITE, "-=");
4034 werror (E_LVALUE_REQUIRED, "-=");
4035 goto errorTreeReturn;
4041 /*------------------------------------------------------------------*/
4042 /*----------------------------*/
4044 /*----------------------------*/
4046 /* this is not a unary operation */
4047 /* if both pointers then problem */
4048 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4050 werror (E_PTR_PLUS_PTR);
4051 goto errorTreeReturn;
4054 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4056 werror (E_PLUS_INVALID, "+=");
4057 goto errorTreeReturn;
4060 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4062 werror (E_PLUS_INVALID, "+=");
4063 goto errorTreeReturn;
4066 TETYPE (tree) = getSpec (TTYPE (tree) =
4067 computeType (LTYPE (tree),
4072 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4073 werror (E_CODE_WRITE, "+=");
4077 werror (E_LVALUE_REQUIRED, "+=");
4078 goto errorTreeReturn;
4081 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4082 tree->opval.op = '=';
4087 /*------------------------------------------------------------------*/
4088 /*----------------------------*/
4089 /* straight assignemnt */
4090 /*----------------------------*/
4092 /* cannot be an aggregate */
4093 if (IS_AGGREGATE (LTYPE (tree)))
4095 werror (E_AGGR_ASSIGN);
4096 goto errorTreeReturn;
4099 /* they should either match or be castable */
4100 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4102 werror (E_TYPE_MISMATCH, "assignment", " ");
4103 printFromToType(RTYPE(tree),LTYPE(tree));
4106 /* if the left side of the tree is of type void
4107 then report error */
4108 if (IS_VOID (LTYPE (tree)))
4110 werror (E_CAST_ZERO);
4111 printFromToType(RTYPE(tree), LTYPE(tree));
4114 TETYPE (tree) = getSpec (TTYPE (tree) =
4118 if (!tree->initMode ) {
4119 if (IS_CONSTANT(LTYPE(tree)))
4120 werror (E_CODE_WRITE, "=");
4124 werror (E_LVALUE_REQUIRED, "=");
4125 goto errorTreeReturn;
4130 /*------------------------------------------------------------------*/
4131 /*----------------------------*/
4132 /* comma operator */
4133 /*----------------------------*/
4135 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4138 /*------------------------------------------------------------------*/
4139 /*----------------------------*/
4141 /*----------------------------*/
4144 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4145 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4147 if (tree->left->opval.op == '*' && !tree->left->right)
4148 tree->left = tree->left->left;
4151 /* require a function or pointer to function */
4152 if (!IS_FUNC (LTYPE (tree))
4153 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4155 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4156 goto errorTreeReturn;
4159 /* if there are parms, make sure that
4160 parms are decorate / process / reverse only once */
4162 !tree->right->decorated)
4167 if (IS_CODEPTR(LTYPE(tree)))
4168 functype = LTYPE (tree)->next;
4170 functype = LTYPE (tree);
4172 if (processParms (tree->left, FUNC_ARGS(functype),
4173 &tree->right, &parmNumber, TRUE))
4175 goto errorTreeReturn;
4178 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4179 !IFFUNC_ISBUILTIN(functype))
4181 reverseParms (tree->right);
4184 TTYPE (tree) = functype->next;
4185 TETYPE (tree) = getSpec (TTYPE (tree));
4189 /*------------------------------------------------------------------*/
4190 /*----------------------------*/
4191 /* return statement */
4192 /*----------------------------*/
4197 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4199 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4200 printFromToType (RTYPE(tree), currFunc->type->next);
4201 goto errorTreeReturn;
4204 if (IS_VOID (currFunc->type->next)
4206 !IS_VOID (RTYPE (tree)))
4208 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4209 goto errorTreeReturn;
4212 /* if there is going to be a casting required then add it */
4213 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4216 decorateType (newNode (CAST,
4217 newAst_LINK (copyLinkChain (currFunc->type->next)),
4227 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4229 werror (W_VOID_FUNC, currFunc->name);
4230 goto errorTreeReturn;
4233 TTYPE (tree) = TETYPE (tree) = NULL;
4236 /*------------------------------------------------------------------*/
4237 /*----------------------------*/
4238 /* switch statement */
4239 /*----------------------------*/
4241 /* the switch value must be an integer */
4242 if (!IS_INTEGRAL (LTYPE (tree)))
4244 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4245 goto errorTreeReturn;
4248 TTYPE (tree) = TETYPE (tree) = NULL;
4251 /*------------------------------------------------------------------*/
4252 /*----------------------------*/
4254 /*----------------------------*/
4256 tree->left = backPatchLabels (tree->left,
4259 TTYPE (tree) = TETYPE (tree) = NULL;
4262 /*------------------------------------------------------------------*/
4263 /*----------------------------*/
4265 /*----------------------------*/
4268 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4269 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4270 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4272 /* if the for loop is reversible then
4273 reverse it otherwise do what we normally
4279 if (isLoopReversible (tree, &sym, &init, &end))
4280 return reverseLoop (tree, sym, init, end);
4282 return decorateType (createFor (AST_FOR (tree, trueLabel),
4283 AST_FOR (tree, continueLabel),
4284 AST_FOR (tree, falseLabel),
4285 AST_FOR (tree, condLabel),
4286 AST_FOR (tree, initExpr),
4287 AST_FOR (tree, condExpr),
4288 AST_FOR (tree, loopExpr),
4289 tree->left), RESULT_TYPE_NONE);
4292 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4293 "node PARAM shouldn't be processed here");
4294 /* but in processParams() */
4297 TTYPE (tree) = TETYPE (tree) = NULL;
4301 /* some error found this tree will be killed */
4303 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4304 tree->opval.op = NULLOP;
4310 /*-----------------------------------------------------------------*/
4311 /* sizeofOp - processes size of operation */
4312 /*-----------------------------------------------------------------*/
4314 sizeofOp (sym_link * type)
4319 /* make sure the type is complete and sane */
4320 checkTypeSanity(type, "(sizeof)");
4322 /* get the size and convert it to character */
4323 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4324 if (!size && !IS_VOID(type))
4325 werror (E_SIZEOF_INCOMPLETE_TYPE);
4327 /* now convert into value */
4328 return constVal (buff);
4332 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4333 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4334 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4335 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4336 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4337 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4338 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4340 /*-----------------------------------------------------------------*/
4341 /* backPatchLabels - change and or not operators to flow control */
4342 /*-----------------------------------------------------------------*/
4344 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4350 if (!(IS_ANDORNOT (tree)))
4353 /* if this an and */
4356 static int localLbl = 0;
4359 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4360 localLabel = newSymbol (buffer, NestLevel);
4362 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4364 /* if left is already a IFX then just change the if true label in that */
4365 if (!IS_IFX (tree->left))
4366 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4368 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4369 /* right is a IFX then just join */
4370 if (IS_IFX (tree->right))
4371 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4373 tree->right = createLabel (localLabel, tree->right);
4374 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4376 return newNode (NULLOP, tree->left, tree->right);
4379 /* if this is an or operation */
4382 static int localLbl = 0;
4385 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4386 localLabel = newSymbol (buffer, NestLevel);
4388 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4390 /* if left is already a IFX then just change the if true label in that */
4391 if (!IS_IFX (tree->left))
4392 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4394 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4395 /* right is a IFX then just join */
4396 if (IS_IFX (tree->right))
4397 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4399 tree->right = createLabel (localLabel, tree->right);
4400 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4402 return newNode (NULLOP, tree->left, tree->right);
4408 int wasnot = IS_NOT (tree->left);
4409 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4411 /* if the left is already a IFX */
4412 if (!IS_IFX (tree->left))
4413 tree->left = newNode (IFX, tree->left, NULL);
4417 tree->left->trueLabel = trueLabel;
4418 tree->left->falseLabel = falseLabel;
4422 tree->left->trueLabel = falseLabel;
4423 tree->left->falseLabel = trueLabel;
4430 tree->trueLabel = trueLabel;
4431 tree->falseLabel = falseLabel;
4438 /*-----------------------------------------------------------------*/
4439 /* createBlock - create expression tree for block */
4440 /*-----------------------------------------------------------------*/
4442 createBlock (symbol * decl, ast * body)
4446 /* if the block has nothing */
4450 ex = newNode (BLOCK, NULL, body);
4451 ex->values.sym = decl;
4458 /*-----------------------------------------------------------------*/
4459 /* createLabel - creates the expression tree for labels */
4460 /*-----------------------------------------------------------------*/
4462 createLabel (symbol * label, ast * stmnt)
4465 char name[SDCC_NAME_MAX + 1];
4468 /* must create fresh symbol if the symbol name */
4469 /* exists in the symbol table, since there can */
4470 /* be a variable with the same name as the labl */
4471 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4472 (csym->level == label->level))
4473 label = newSymbol (label->name, label->level);
4475 /* change the name before putting it in add _ */
4476 SNPRINTF(name, sizeof(name), "%s", label->name);
4478 /* put the label in the LabelSymbol table */
4479 /* but first check if a label of the same */
4481 if ((csym = findSym (LabelTab, NULL, name)))
4482 werror (E_DUPLICATE_LABEL, label->name);
4484 addSym (LabelTab, label, name, label->level, 0, 0);
4488 label->key = labelKey++;
4489 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4495 /*-----------------------------------------------------------------*/
4496 /* createCase - generates the parsetree for a case statement */
4497 /*-----------------------------------------------------------------*/
4499 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4501 char caseLbl[SDCC_NAME_MAX + 1];
4505 /* if the switch statement does not exist */
4506 /* then case is out of context */
4509 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4513 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4514 /* if not a constant then error */
4515 if (!IS_LITERAL (caseVal->ftype))
4517 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4521 /* if not a integer than error */
4522 if (!IS_INTEGRAL (caseVal->ftype))
4524 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4528 /* find the end of the switch values chain */
4529 if (!(val = swStat->values.switchVals.swVals))
4530 swStat->values.switchVals.swVals = caseVal->opval.val;
4533 /* also order the cases according to value */
4535 int cVal = (int) floatFromVal (caseVal->opval.val);
4536 while (val && (int) floatFromVal (val) < cVal)
4542 /* if we reached the end then */
4545 pval->next = caseVal->opval.val;
4547 else if ((int) floatFromVal (val) == cVal)
4549 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4555 /* we found a value greater than */
4556 /* the current value we must add this */
4557 /* before the value */
4558 caseVal->opval.val->next = val;
4560 /* if this was the first in chain */
4561 if (swStat->values.switchVals.swVals == val)
4562 swStat->values.switchVals.swVals =
4565 pval->next = caseVal->opval.val;
4570 /* create the case label */
4571 SNPRINTF(caseLbl, sizeof(caseLbl),
4573 swStat->values.switchVals.swNum,
4574 (int) floatFromVal (caseVal->opval.val));
4576 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4581 /*-----------------------------------------------------------------*/
4582 /* createDefault - creates the parse tree for the default statement */
4583 /*-----------------------------------------------------------------*/
4585 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4587 char defLbl[SDCC_NAME_MAX + 1];
4589 /* if the switch statement does not exist */
4590 /* then case is out of context */
4593 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4597 if (swStat->values.switchVals.swDefault)
4599 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4604 /* turn on the default flag */
4605 swStat->values.switchVals.swDefault = 1;
4607 /* create the label */
4608 SNPRINTF (defLbl, sizeof(defLbl),
4609 "_default_%d", swStat->values.switchVals.swNum);
4610 return createLabel (newSymbol (defLbl, 0), stmnt);
4613 /*-----------------------------------------------------------------*/
4614 /* createIf - creates the parsetree for the if statement */
4615 /*-----------------------------------------------------------------*/
4617 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4619 static int Lblnum = 0;
4621 symbol *ifTrue, *ifFalse, *ifEnd;
4623 /* if neither exists */
4624 if (!elseBody && !ifBody) {
4625 // if there are no side effects (i++, j() etc)
4626 if (!hasSEFcalls(condAst)) {
4631 /* create the labels */
4632 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4633 ifFalse = newSymbol (buffer, NestLevel);
4634 /* if no else body then end == false */
4639 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4640 ifEnd = newSymbol (buffer, NestLevel);
4643 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4644 ifTrue = newSymbol (buffer, NestLevel);
4648 /* attach the ifTrue label to the top of it body */
4649 ifBody = createLabel (ifTrue, ifBody);
4650 /* attach a goto end to the ifBody if else is present */
4653 ifBody = newNode (NULLOP, ifBody,
4655 newAst_VALUE (symbolVal (ifEnd)),
4657 /* put the elseLabel on the else body */
4658 elseBody = createLabel (ifFalse, elseBody);
4659 /* out the end at the end of the body */
4660 elseBody = newNode (NULLOP,
4662 createLabel (ifEnd, NULL));
4666 ifBody = newNode (NULLOP, ifBody,
4667 createLabel (ifFalse, NULL));
4669 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4670 if (IS_IFX (condAst))
4673 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4675 return newNode (NULLOP, ifTree,
4676 newNode (NULLOP, ifBody, elseBody));
4680 /*-----------------------------------------------------------------*/
4681 /* createDo - creates parse tree for do */
4684 /* _docontinue_n: */
4685 /* condition_expression +-> trueLabel -> _dobody_n */
4687 /* +-> falseLabel-> _dobreak_n */
4689 /*-----------------------------------------------------------------*/
4691 createDo (symbol * trueLabel, symbol * continueLabel,
4692 symbol * falseLabel, ast * condAst, ast * doBody)
4697 /* if the body does not exist then it is simple */
4700 condAst = backPatchLabels (condAst, continueLabel, NULL);
4701 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4702 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4703 doTree->trueLabel = continueLabel;
4704 doTree->falseLabel = NULL;
4708 /* otherwise we have a body */
4709 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4711 /* attach the body label to the top */
4712 doBody = createLabel (trueLabel, doBody);
4713 /* attach the continue label to end of body */
4714 doBody = newNode (NULLOP, doBody,
4715 createLabel (continueLabel, NULL));
4717 /* now put the break label at the end */
4718 if (IS_IFX (condAst))
4721 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4723 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4725 /* putting it together */
4726 return newNode (NULLOP, doBody, doTree);
4729 /*-----------------------------------------------------------------*/
4730 /* createFor - creates parse tree for 'for' statement */
4733 /* condExpr +-> trueLabel -> _forbody_n */
4735 /* +-> falseLabel-> _forbreak_n */
4738 /* _forcontinue_n: */
4740 /* goto _forcond_n ; */
4742 /*-----------------------------------------------------------------*/
4744 createFor (symbol * trueLabel, symbol * continueLabel,
4745 symbol * falseLabel, symbol * condLabel,
4746 ast * initExpr, ast * condExpr, ast * loopExpr,
4751 /* if loopexpression not present then we can generate it */
4752 /* the same way as a while */
4754 return newNode (NULLOP, initExpr,
4755 createWhile (trueLabel, continueLabel,
4756 falseLabel, condExpr, forBody));
4757 /* vanilla for statement */
4758 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4760 if (condExpr && !IS_IFX (condExpr))
4761 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4764 /* attach condition label to condition */
4765 condExpr = createLabel (condLabel, condExpr);
4767 /* attach body label to body */
4768 forBody = createLabel (trueLabel, forBody);
4770 /* attach continue to forLoop expression & attach */
4771 /* goto the forcond @ and of loopExpression */
4772 loopExpr = createLabel (continueLabel,
4776 newAst_VALUE (symbolVal (condLabel)),
4778 /* now start putting them together */
4779 forTree = newNode (NULLOP, initExpr, condExpr);
4780 forTree = newNode (NULLOP, forTree, forBody);
4781 forTree = newNode (NULLOP, forTree, loopExpr);
4782 /* finally add the break label */
4783 forTree = newNode (NULLOP, forTree,
4784 createLabel (falseLabel, NULL));
4788 /*-----------------------------------------------------------------*/
4789 /* createWhile - creates parse tree for while statement */
4790 /* the while statement will be created as follows */
4792 /* _while_continue_n: */
4793 /* condition_expression +-> trueLabel -> _while_boby_n */
4795 /* +-> falseLabel -> _while_break_n */
4796 /* _while_body_n: */
4798 /* goto _while_continue_n */
4799 /* _while_break_n: */
4800 /*-----------------------------------------------------------------*/
4802 createWhile (symbol * trueLabel, symbol * continueLabel,
4803 symbol * falseLabel, ast * condExpr, ast * whileBody)
4807 /* put the continue label */
4808 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4809 condExpr = createLabel (continueLabel, condExpr);
4810 condExpr->lineno = 0;
4812 /* put the body label in front of the body */
4813 whileBody = createLabel (trueLabel, whileBody);
4814 whileBody->lineno = 0;
4815 /* put a jump to continue at the end of the body */
4816 /* and put break label at the end of the body */
4817 whileBody = newNode (NULLOP,
4820 newAst_VALUE (symbolVal (continueLabel)),
4821 createLabel (falseLabel, NULL)));
4823 /* put it all together */
4824 if (IS_IFX (condExpr))
4825 whileTree = condExpr;
4828 whileTree = newNode (IFX, condExpr, NULL);
4829 /* put the true & false labels in place */
4830 whileTree->trueLabel = trueLabel;
4831 whileTree->falseLabel = falseLabel;
4834 return newNode (NULLOP, whileTree, whileBody);
4837 /*-----------------------------------------------------------------*/
4838 /* optimizeGetHbit - get highest order bit of the expression */
4839 /*-----------------------------------------------------------------*/
4841 optimizeGetHbit (ast * tree)
4844 /* if this is not a bit and */
4845 if (!IS_BITAND (tree))
4848 /* will look for tree of the form
4849 ( expr >> ((sizeof expr) -1) ) & 1 */
4850 if (!IS_AST_LIT_VALUE (tree->right))
4853 if (AST_LIT_VALUE (tree->right) != 1)
4856 if (!IS_RIGHT_OP (tree->left))
4859 if (!IS_AST_LIT_VALUE (tree->left->right))
4862 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4863 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4866 /* make sure the port supports GETHBIT */
4867 if (port->hasExtBitOp
4868 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4871 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4875 /*-----------------------------------------------------------------*/
4876 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4877 /*-----------------------------------------------------------------*/
4879 optimizeRRCRLC (ast * root)
4881 /* will look for trees of the form
4882 (?expr << 1) | (?expr >> 7) or
4883 (?expr >> 7) | (?expr << 1) will make that
4884 into a RLC : operation ..
4886 (?expr >> 1) | (?expr << 7) or
4887 (?expr << 7) | (?expr >> 1) will make that
4888 into a RRC operation
4889 note : by 7 I mean (number of bits required to hold the
4891 /* if the root operations is not a | operation the not */
4892 if (!IS_BITOR (root))
4895 /* I have to think of a better way to match patterns this sucks */
4896 /* that aside let start looking for the first case : I use a the
4897 negative check a lot to improve the efficiency */
4898 /* (?expr << 1) | (?expr >> 7) */
4899 if (IS_LEFT_OP (root->left) &&
4900 IS_RIGHT_OP (root->right))
4903 if (!SPEC_USIGN (TETYPE (root->left->left)))
4906 if (!IS_AST_LIT_VALUE (root->left->right) ||
4907 !IS_AST_LIT_VALUE (root->right->right))
4910 /* make sure it is the same expression */
4911 if (!isAstEqual (root->left->left,
4915 if (AST_LIT_VALUE (root->left->right) != 1)
4918 if (AST_LIT_VALUE (root->right->right) !=
4919 (getSize (TTYPE (root->left->left)) * 8 - 1))
4922 /* make sure the port supports RLC */
4923 if (port->hasExtBitOp
4924 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4927 /* whew got the first case : create the AST */
4928 return newNode (RLC, root->left->left, NULL);
4932 /* check for second case */
4933 /* (?expr >> 7) | (?expr << 1) */
4934 if (IS_LEFT_OP (root->right) &&
4935 IS_RIGHT_OP (root->left))
4938 if (!SPEC_USIGN (TETYPE (root->left->left)))
4941 if (!IS_AST_LIT_VALUE (root->left->right) ||
4942 !IS_AST_LIT_VALUE (root->right->right))
4945 /* make sure it is the same symbol */
4946 if (!isAstEqual (root->left->left,
4950 if (AST_LIT_VALUE (root->right->right) != 1)
4953 if (AST_LIT_VALUE (root->left->right) !=
4954 (getSize (TTYPE (root->left->left)) * 8 - 1))
4957 /* make sure the port supports RLC */
4958 if (port->hasExtBitOp
4959 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4962 /* whew got the first case : create the AST */
4963 return newNode (RLC, root->left->left, NULL);
4968 /* third case for RRC */
4969 /* (?symbol >> 1) | (?symbol << 7) */
4970 if (IS_LEFT_OP (root->right) &&
4971 IS_RIGHT_OP (root->left))
4974 if (!SPEC_USIGN (TETYPE (root->left->left)))
4977 if (!IS_AST_LIT_VALUE (root->left->right) ||
4978 !IS_AST_LIT_VALUE (root->right->right))
4981 /* make sure it is the same symbol */
4982 if (!isAstEqual (root->left->left,
4986 if (AST_LIT_VALUE (root->left->right) != 1)
4989 if (AST_LIT_VALUE (root->right->right) !=
4990 (getSize (TTYPE (root->left->left)) * 8 - 1))
4993 /* make sure the port supports RRC */
4994 if (port->hasExtBitOp
4995 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4998 /* whew got the first case : create the AST */
4999 return newNode (RRC, root->left->left, NULL);
5003 /* fourth and last case for now */
5004 /* (?symbol << 7) | (?symbol >> 1) */
5005 if (IS_RIGHT_OP (root->right) &&
5006 IS_LEFT_OP (root->left))
5009 if (!SPEC_USIGN (TETYPE (root->left->left)))
5012 if (!IS_AST_LIT_VALUE (root->left->right) ||
5013 !IS_AST_LIT_VALUE (root->right->right))
5016 /* make sure it is the same symbol */
5017 if (!isAstEqual (root->left->left,
5021 if (AST_LIT_VALUE (root->right->right) != 1)
5024 if (AST_LIT_VALUE (root->left->right) !=
5025 (getSize (TTYPE (root->left->left)) * 8 - 1))
5028 /* make sure the port supports RRC */
5029 if (port->hasExtBitOp
5030 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5033 /* whew got the first case : create the AST */
5034 return newNode (RRC, root->left->left, NULL);
5038 /* not found return root */
5042 /*-----------------------------------------------------------------*/
5043 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5044 /*-----------------------------------------------------------------*/
5046 optimizeSWAP (ast * root)
5048 /* will look for trees of the form
5049 (?expr << 4) | (?expr >> 4) or
5050 (?expr >> 4) | (?expr << 4) will make that
5051 into a SWAP : operation ..
5052 note : by 4 I mean (number of bits required to hold the
5054 /* if the root operations is not a | operation the not */
5055 if (!IS_BITOR (root))
5058 /* (?expr << 4) | (?expr >> 4) */
5059 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5060 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5063 if (!SPEC_USIGN (TETYPE (root->left->left)))
5066 if (!IS_AST_LIT_VALUE (root->left->right) ||
5067 !IS_AST_LIT_VALUE (root->right->right))
5070 /* make sure it is the same expression */
5071 if (!isAstEqual (root->left->left,
5075 if (AST_LIT_VALUE (root->left->right) !=
5076 (getSize (TTYPE (root->left->left)) * 4))
5079 if (AST_LIT_VALUE (root->right->right) !=
5080 (getSize (TTYPE (root->left->left)) * 4))
5083 /* make sure the port supports SWAP */
5084 if (port->hasExtBitOp
5085 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5088 /* found it : create the AST */
5089 return newNode (SWAP, root->left->left, NULL);
5093 /* not found return root */
5097 /*-----------------------------------------------------------------*/
5098 /* optimizeCompare - otimizes compares for bit variables */
5099 /*-----------------------------------------------------------------*/
5101 optimizeCompare (ast * root)
5103 ast *optExpr = NULL;
5106 unsigned int litValue;
5108 /* if nothing then return nothing */
5112 /* if not a compare op then do leaves */
5113 if (!IS_COMPARE_OP (root))
5115 root->left = optimizeCompare (root->left);
5116 root->right = optimizeCompare (root->right);
5120 /* if left & right are the same then depending
5121 of the operation do */
5122 if (isAstEqual (root->left, root->right))
5124 switch (root->opval.op)
5129 optExpr = newAst_VALUE (constVal ("0"));
5134 optExpr = newAst_VALUE (constVal ("1"));
5138 return decorateType (optExpr, RESULT_TYPE_NONE);
5141 vleft = (root->left->type == EX_VALUE ?
5142 root->left->opval.val : NULL);
5144 vright = (root->right->type == EX_VALUE ?
5145 root->right->opval.val : NULL);
5147 /* if left is a BITVAR in BITSPACE */
5148 /* and right is a LITERAL then opt- */
5149 /* imize else do nothing */
5150 if (vleft && vright &&
5151 IS_BITVAR (vleft->etype) &&
5152 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5153 IS_LITERAL (vright->etype))
5156 /* if right side > 1 then comparison may never succeed */
5157 if ((litValue = (int) floatFromVal (vright)) > 1)
5159 werror (W_BAD_COMPARE);
5165 switch (root->opval.op)
5167 case '>': /* bit value greater than 1 cannot be */
5168 werror (W_BAD_COMPARE);
5172 case '<': /* bit value < 1 means 0 */
5174 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5177 case LE_OP: /* bit value <= 1 means no check */
5178 optExpr = newAst_VALUE (vright);
5181 case GE_OP: /* bit value >= 1 means only check for = */
5183 optExpr = newAst_VALUE (vleft);
5188 { /* literal is zero */
5189 switch (root->opval.op)
5191 case '<': /* bit value < 0 cannot be */
5192 werror (W_BAD_COMPARE);
5196 case '>': /* bit value > 0 means 1 */
5198 optExpr = newAst_VALUE (vleft);
5201 case LE_OP: /* bit value <= 0 means no check */
5202 case GE_OP: /* bit value >= 0 means no check */
5203 werror (W_BAD_COMPARE);
5207 case EQ_OP: /* bit == 0 means ! of bit */
5208 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5212 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5213 } /* end-of-if of BITVAR */
5218 /*-----------------------------------------------------------------*/
5219 /* addSymToBlock : adds the symbol to the first block we find */
5220 /*-----------------------------------------------------------------*/
5222 addSymToBlock (symbol * sym, ast * tree)
5224 /* reached end of tree or a leaf */
5225 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5229 if (IS_AST_OP (tree) &&
5230 tree->opval.op == BLOCK)
5233 symbol *lsym = copySymbol (sym);
5235 lsym->next = AST_VALUES (tree, sym);
5236 AST_VALUES (tree, sym) = lsym;
5240 addSymToBlock (sym, tree->left);
5241 addSymToBlock (sym, tree->right);
5244 /*-----------------------------------------------------------------*/
5245 /* processRegParms - do processing for register parameters */
5246 /*-----------------------------------------------------------------*/
5248 processRegParms (value * args, ast * body)
5252 if (IS_REGPARM (args->etype))
5253 addSymToBlock (args->sym, body);
5258 /*-----------------------------------------------------------------*/
5259 /* resetParmKey - resets the operandkeys for the symbols */
5260 /*-----------------------------------------------------------------*/
5261 DEFSETFUNC (resetParmKey)
5272 /*-----------------------------------------------------------------*/
5273 /* createFunction - This is the key node that calls the iCode for */
5274 /* generating the code for a function. Note code */
5275 /* is generated function by function, later when */
5276 /* add inter-procedural analysis this will change */
5277 /*-----------------------------------------------------------------*/
5279 createFunction (symbol * name, ast * body)
5285 iCode *piCode = NULL;
5287 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5288 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5290 /* if check function return 0 then some problem */
5291 if (checkFunction (name, NULL) == 0)
5294 /* create a dummy block if none exists */
5296 body = newNode (BLOCK, NULL, NULL);
5300 /* check if the function name already in the symbol table */
5301 if ((csym = findSym (SymbolTab, NULL, name->name)))
5304 /* special case for compiler defined functions
5305 we need to add the name to the publics list : this
5306 actually means we are now compiling the compiler
5310 addSet (&publics, name);
5316 allocVariables (name);
5318 name->lastLine = mylineno;
5321 /* set the stack pointer */
5322 stackPtr = -port->stack.direction * port->stack.call_overhead;
5323 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5325 if (IFFUNC_ISISR (name->type))
5326 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5328 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5330 if (options.useXstack)
5331 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5333 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5336 fetype = getSpec (name->type); /* get the specifier for the function */
5337 /* if this is a reentrant function then */
5338 if (IFFUNC_ISREENT (name->type))
5341 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5343 /* do processing for parameters that are passed in registers */
5344 processRegParms (FUNC_ARGS(name->type), body);
5346 /* set the stack pointer */
5350 /* allocate & autoinit the block variables */
5351 processBlockVars (body, &stack, ALLOCATE);
5353 /* save the stack information */
5354 if (options.useXstack)
5355 name->xstack = SPEC_STAK (fetype) = stack;
5357 name->stack = SPEC_STAK (fetype) = stack;
5359 /* name needs to be mangled */
5360 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5362 body = resolveSymbols (body); /* resolve the symbols */
5363 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5366 ex = newAst_VALUE (symbolVal (name)); /* create name */
5367 ex = newNode (FUNCTION, ex, body);
5368 ex->values.args = FUNC_ARGS(name->type);
5370 if (options.dump_tree) PA(ex);
5373 werror (E_FUNC_NO_CODE, name->name);
5377 /* create the node & generate intermediate code */
5379 codeOutFile = code->oFile;
5380 piCode = iCodeFromAst (ex);
5384 werror (E_FUNC_NO_CODE, name->name);
5388 eBBlockFromiCode (piCode);
5390 /* if there are any statics then do them */
5393 GcurMemmap = statsg;
5394 codeOutFile = statsg->oFile;
5395 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5401 /* dealloc the block variables */
5402 processBlockVars (body, &stack, DEALLOCATE);
5403 outputDebugStackSymbols();
5404 /* deallocate paramaters */
5405 deallocParms (FUNC_ARGS(name->type));
5407 if (IFFUNC_ISREENT (name->type))
5410 /* we are done freeup memory & cleanup */
5412 if (port->reset_labelKey) labelKey = 1;
5414 FUNC_HASBODY(name->type) = 1;
5415 addSet (&operKeyReset, name);
5416 applyToSet (operKeyReset, resetParmKey);
5421 cleanUpLevel (LabelTab, 0);
5422 cleanUpBlock (StructTab, 1);
5423 cleanUpBlock (TypedefTab, 1);
5425 xstack->syms = NULL;
5426 istack->syms = NULL;
5431 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5432 /*-----------------------------------------------------------------*/
5433 /* ast_print : prints the ast (for debugging purposes) */
5434 /*-----------------------------------------------------------------*/
5436 void ast_print (ast * tree, FILE *outfile, int indent)
5441 /* can print only decorated trees */
5442 if (!tree->decorated) return;
5444 /* if any child is an error | this one is an error do nothing */
5445 if (tree->isError ||
5446 (tree->left && tree->left->isError) ||
5447 (tree->right && tree->right->isError)) {
5448 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5452 /* print the line */
5453 /* if not block & function */
5454 if (tree->type == EX_OP &&
5455 (tree->opval.op != FUNCTION &&
5456 tree->opval.op != BLOCK &&
5457 tree->opval.op != NULLOP)) {
5460 if (tree->opval.op == FUNCTION) {
5462 value *args=FUNC_ARGS(tree->left->opval.val->type);
5463 fprintf(outfile,"FUNCTION (%s=%p) type (",
5464 tree->left->opval.val->name, tree);
5465 printTypeChain (tree->left->opval.val->type->next,outfile);
5466 fprintf(outfile,") args (");
5469 fprintf (outfile, ", ");
5471 printTypeChain (args ? args->type : NULL, outfile);
5473 args= args ? args->next : NULL;
5475 fprintf(outfile,")\n");
5476 ast_print(tree->left,outfile,indent);
5477 ast_print(tree->right,outfile,indent);
5480 if (tree->opval.op == BLOCK) {
5481 symbol *decls = tree->values.sym;
5482 INDENT(indent,outfile);
5483 fprintf(outfile,"{\n");
5485 INDENT(indent+2,outfile);
5486 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5487 decls->name, decls);
5488 printTypeChain(decls->type,outfile);
5489 fprintf(outfile,")\n");
5491 decls = decls->next;
5493 ast_print(tree->right,outfile,indent+2);
5494 INDENT(indent,outfile);
5495 fprintf(outfile,"}\n");
5498 if (tree->opval.op == NULLOP) {
5499 ast_print(tree->left,outfile,indent);
5500 ast_print(tree->right,outfile,indent);
5503 INDENT(indent,outfile);
5505 /*------------------------------------------------------------------*/
5506 /*----------------------------*/
5507 /* leaf has been reached */
5508 /*----------------------------*/
5509 /* if this is of type value */
5510 /* just get the type */
5511 if (tree->type == EX_VALUE) {
5513 if (IS_LITERAL (tree->opval.val->etype)) {
5514 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5515 if (SPEC_USIGN (tree->opval.val->etype))
5516 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5518 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5519 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5520 floatFromVal(tree->opval.val));
5521 } else if (tree->opval.val->sym) {
5522 /* if the undefined flag is set then give error message */
5523 if (tree->opval.val->sym->undefined) {
5524 fprintf(outfile,"UNDEFINED SYMBOL ");
5526 fprintf(outfile,"SYMBOL ");
5528 fprintf(outfile,"(%s=%p)",
5529 tree->opval.val->sym->name,tree);
5532 fprintf(outfile," type (");
5533 printTypeChain(tree->ftype,outfile);
5534 fprintf(outfile,")\n");
5536 fprintf(outfile,"\n");
5541 /* if type link for the case of cast */
5542 if (tree->type == EX_LINK) {
5543 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5544 printTypeChain(tree->opval.lnk,outfile);
5545 fprintf(outfile,")\n");
5550 /* depending on type of operator do */
5552 switch (tree->opval.op) {
5553 /*------------------------------------------------------------------*/
5554 /*----------------------------*/
5556 /*----------------------------*/
5558 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5559 printTypeChain(tree->ftype,outfile);
5560 fprintf(outfile,")\n");
5561 ast_print(tree->left,outfile,indent+2);
5562 ast_print(tree->right,outfile,indent+2);
5565 /*------------------------------------------------------------------*/
5566 /*----------------------------*/
5568 /*----------------------------*/
5570 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5571 printTypeChain(tree->ftype,outfile);
5572 fprintf(outfile,")\n");
5573 ast_print(tree->left,outfile,indent+2);
5574 ast_print(tree->right,outfile,indent+2);
5577 /*------------------------------------------------------------------*/
5578 /*----------------------------*/
5579 /* struct/union pointer */
5580 /*----------------------------*/
5582 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5583 printTypeChain(tree->ftype,outfile);
5584 fprintf(outfile,")\n");
5585 ast_print(tree->left,outfile,indent+2);
5586 ast_print(tree->right,outfile,indent+2);
5589 /*------------------------------------------------------------------*/
5590 /*----------------------------*/
5591 /* ++/-- operation */
5592 /*----------------------------*/
5595 fprintf(outfile,"post-");
5597 fprintf(outfile,"pre-");
5598 fprintf(outfile,"INC_OP (%p) type (",tree);
5599 printTypeChain(tree->ftype,outfile);
5600 fprintf(outfile,")\n");
5601 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5602 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5607 fprintf(outfile,"post-");
5609 fprintf(outfile,"pre-");
5610 fprintf(outfile,"DEC_OP (%p) type (",tree);
5611 printTypeChain(tree->ftype,outfile);
5612 fprintf(outfile,")\n");
5613 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5614 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5617 /*------------------------------------------------------------------*/
5618 /*----------------------------*/
5620 /*----------------------------*/
5623 fprintf(outfile,"& (%p) type (",tree);
5624 printTypeChain(tree->ftype,outfile);
5625 fprintf(outfile,")\n");
5626 ast_print(tree->left,outfile,indent+2);
5627 ast_print(tree->right,outfile,indent+2);
5629 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5630 printTypeChain(tree->ftype,outfile);
5631 fprintf(outfile,")\n");
5632 ast_print(tree->left,outfile,indent+2);
5633 ast_print(tree->right,outfile,indent+2);
5636 /*----------------------------*/
5638 /*----------------------------*/
5640 fprintf(outfile,"OR (%p) type (",tree);
5641 printTypeChain(tree->ftype,outfile);
5642 fprintf(outfile,")\n");
5643 ast_print(tree->left,outfile,indent+2);
5644 ast_print(tree->right,outfile,indent+2);
5646 /*------------------------------------------------------------------*/
5647 /*----------------------------*/
5649 /*----------------------------*/
5651 fprintf(outfile,"XOR (%p) type (",tree);
5652 printTypeChain(tree->ftype,outfile);
5653 fprintf(outfile,")\n");
5654 ast_print(tree->left,outfile,indent+2);
5655 ast_print(tree->right,outfile,indent+2);
5658 /*------------------------------------------------------------------*/
5659 /*----------------------------*/
5661 /*----------------------------*/
5663 fprintf(outfile,"DIV (%p) type (",tree);
5664 printTypeChain(tree->ftype,outfile);
5665 fprintf(outfile,")\n");
5666 ast_print(tree->left,outfile,indent+2);
5667 ast_print(tree->right,outfile,indent+2);
5669 /*------------------------------------------------------------------*/
5670 /*----------------------------*/
5672 /*----------------------------*/
5674 fprintf(outfile,"MOD (%p) type (",tree);
5675 printTypeChain(tree->ftype,outfile);
5676 fprintf(outfile,")\n");
5677 ast_print(tree->left,outfile,indent+2);
5678 ast_print(tree->right,outfile,indent+2);
5681 /*------------------------------------------------------------------*/
5682 /*----------------------------*/
5683 /* address dereference */
5684 /*----------------------------*/
5685 case '*': /* can be unary : if right is null then unary operation */
5687 fprintf(outfile,"DEREF (%p) type (",tree);
5688 printTypeChain(tree->ftype,outfile);
5689 fprintf(outfile,")\n");
5690 ast_print(tree->left,outfile,indent+2);
5693 /*------------------------------------------------------------------*/
5694 /*----------------------------*/
5695 /* multiplication */
5696 /*----------------------------*/
5697 fprintf(outfile,"MULT (%p) type (",tree);
5698 printTypeChain(tree->ftype,outfile);
5699 fprintf(outfile,")\n");
5700 ast_print(tree->left,outfile,indent+2);
5701 ast_print(tree->right,outfile,indent+2);
5705 /*------------------------------------------------------------------*/
5706 /*----------------------------*/
5707 /* unary '+' operator */
5708 /*----------------------------*/
5712 fprintf(outfile,"UPLUS (%p) type (",tree);
5713 printTypeChain(tree->ftype,outfile);
5714 fprintf(outfile,")\n");
5715 ast_print(tree->left,outfile,indent+2);
5717 /*------------------------------------------------------------------*/
5718 /*----------------------------*/
5720 /*----------------------------*/
5721 fprintf(outfile,"ADD (%p) type (",tree);
5722 printTypeChain(tree->ftype,outfile);
5723 fprintf(outfile,")\n");
5724 ast_print(tree->left,outfile,indent+2);
5725 ast_print(tree->right,outfile,indent+2);
5728 /*------------------------------------------------------------------*/
5729 /*----------------------------*/
5731 /*----------------------------*/
5732 case '-': /* can be unary */
5734 fprintf(outfile,"UMINUS (%p) type (",tree);
5735 printTypeChain(tree->ftype,outfile);
5736 fprintf(outfile,")\n");
5737 ast_print(tree->left,outfile,indent+2);
5739 /*------------------------------------------------------------------*/
5740 /*----------------------------*/
5742 /*----------------------------*/
5743 fprintf(outfile,"SUB (%p) type (",tree);
5744 printTypeChain(tree->ftype,outfile);
5745 fprintf(outfile,")\n");
5746 ast_print(tree->left,outfile,indent+2);
5747 ast_print(tree->right,outfile,indent+2);
5750 /*------------------------------------------------------------------*/
5751 /*----------------------------*/
5753 /*----------------------------*/
5755 fprintf(outfile,"COMPL (%p) type (",tree);
5756 printTypeChain(tree->ftype,outfile);
5757 fprintf(outfile,")\n");
5758 ast_print(tree->left,outfile,indent+2);
5760 /*------------------------------------------------------------------*/
5761 /*----------------------------*/
5763 /*----------------------------*/
5765 fprintf(outfile,"NOT (%p) type (",tree);
5766 printTypeChain(tree->ftype,outfile);
5767 fprintf(outfile,")\n");
5768 ast_print(tree->left,outfile,indent+2);
5770 /*------------------------------------------------------------------*/
5771 /*----------------------------*/
5773 /*----------------------------*/
5775 fprintf(outfile,"RRC (%p) type (",tree);
5776 printTypeChain(tree->ftype,outfile);
5777 fprintf(outfile,")\n");
5778 ast_print(tree->left,outfile,indent+2);
5782 fprintf(outfile,"RLC (%p) type (",tree);
5783 printTypeChain(tree->ftype,outfile);
5784 fprintf(outfile,")\n");
5785 ast_print(tree->left,outfile,indent+2);
5788 fprintf(outfile,"SWAP (%p) type (",tree);
5789 printTypeChain(tree->ftype,outfile);
5790 fprintf(outfile,")\n");
5791 ast_print(tree->left,outfile,indent+2);
5794 fprintf(outfile,"GETHBIT (%p) type (",tree);
5795 printTypeChain(tree->ftype,outfile);
5796 fprintf(outfile,")\n");
5797 ast_print(tree->left,outfile,indent+2);
5800 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5801 printTypeChain(tree->ftype,outfile);
5802 fprintf(outfile,")\n");
5803 ast_print(tree->left,outfile,indent+2);
5804 ast_print(tree->right,outfile,indent+2);
5807 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5808 printTypeChain(tree->ftype,outfile);
5809 fprintf(outfile,")\n");
5810 ast_print(tree->left,outfile,indent+2);
5811 ast_print(tree->right,outfile,indent+2);
5813 /*------------------------------------------------------------------*/
5814 /*----------------------------*/
5816 /*----------------------------*/
5817 case CAST: /* change the type */
5818 fprintf(outfile,"CAST (%p) from type (",tree);
5819 printTypeChain(tree->right->ftype,outfile);
5820 fprintf(outfile,") to type (");
5821 printTypeChain(tree->ftype,outfile);
5822 fprintf(outfile,")\n");
5823 ast_print(tree->right,outfile,indent+2);
5827 fprintf(outfile,"ANDAND (%p) type (",tree);
5828 printTypeChain(tree->ftype,outfile);
5829 fprintf(outfile,")\n");
5830 ast_print(tree->left,outfile,indent+2);
5831 ast_print(tree->right,outfile,indent+2);
5834 fprintf(outfile,"OROR (%p) type (",tree);
5835 printTypeChain(tree->ftype,outfile);
5836 fprintf(outfile,")\n");
5837 ast_print(tree->left,outfile,indent+2);
5838 ast_print(tree->right,outfile,indent+2);
5841 /*------------------------------------------------------------------*/
5842 /*----------------------------*/
5843 /* comparison operators */
5844 /*----------------------------*/
5846 fprintf(outfile,"GT(>) (%p) type (",tree);
5847 printTypeChain(tree->ftype,outfile);
5848 fprintf(outfile,")\n");
5849 ast_print(tree->left,outfile,indent+2);
5850 ast_print(tree->right,outfile,indent+2);
5853 fprintf(outfile,"LT(<) (%p) type (",tree);
5854 printTypeChain(tree->ftype,outfile);
5855 fprintf(outfile,")\n");
5856 ast_print(tree->left,outfile,indent+2);
5857 ast_print(tree->right,outfile,indent+2);
5860 fprintf(outfile,"LE(<=) (%p) type (",tree);
5861 printTypeChain(tree->ftype,outfile);
5862 fprintf(outfile,")\n");
5863 ast_print(tree->left,outfile,indent+2);
5864 ast_print(tree->right,outfile,indent+2);
5867 fprintf(outfile,"GE(>=) (%p) type (",tree);
5868 printTypeChain(tree->ftype,outfile);
5869 fprintf(outfile,")\n");
5870 ast_print(tree->left,outfile,indent+2);
5871 ast_print(tree->right,outfile,indent+2);
5874 fprintf(outfile,"EQ(==) (%p) type (",tree);
5875 printTypeChain(tree->ftype,outfile);
5876 fprintf(outfile,")\n");
5877 ast_print(tree->left,outfile,indent+2);
5878 ast_print(tree->right,outfile,indent+2);
5881 fprintf(outfile,"NE(!=) (%p) type (",tree);
5882 printTypeChain(tree->ftype,outfile);
5883 fprintf(outfile,")\n");
5884 ast_print(tree->left,outfile,indent+2);
5885 ast_print(tree->right,outfile,indent+2);
5886 /*------------------------------------------------------------------*/
5887 /*----------------------------*/
5889 /*----------------------------*/
5890 case SIZEOF: /* evaluate wihout code generation */
5891 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5894 /*------------------------------------------------------------------*/
5895 /*----------------------------*/
5896 /* conditional operator '?' */
5897 /*----------------------------*/
5899 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5900 printTypeChain(tree->ftype,outfile);
5901 fprintf(outfile,")\n");
5902 ast_print(tree->left,outfile,indent+2);
5903 ast_print(tree->right,outfile,indent+2);
5907 fprintf(outfile,"COLON(:) (%p) type (",tree);
5908 printTypeChain(tree->ftype,outfile);
5909 fprintf(outfile,")\n");
5910 ast_print(tree->left,outfile,indent+2);
5911 ast_print(tree->right,outfile,indent+2);
5914 /*------------------------------------------------------------------*/
5915 /*----------------------------*/
5916 /* assignment operators */
5917 /*----------------------------*/
5919 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5920 printTypeChain(tree->ftype,outfile);
5921 fprintf(outfile,")\n");
5922 ast_print(tree->left,outfile,indent+2);
5923 ast_print(tree->right,outfile,indent+2);
5926 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5927 printTypeChain(tree->ftype,outfile);
5928 fprintf(outfile,")\n");
5929 ast_print(tree->left,outfile,indent+2);
5930 ast_print(tree->right,outfile,indent+2);
5933 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5934 printTypeChain(tree->ftype,outfile);
5935 fprintf(outfile,")\n");
5936 ast_print(tree->left,outfile,indent+2);
5937 ast_print(tree->right,outfile,indent+2);
5940 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5941 printTypeChain(tree->ftype,outfile);
5942 fprintf(outfile,")\n");
5943 ast_print(tree->left,outfile,indent+2);
5944 ast_print(tree->right,outfile,indent+2);
5947 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5948 printTypeChain(tree->ftype,outfile);
5949 fprintf(outfile,")\n");
5950 ast_print(tree->left,outfile,indent+2);
5951 ast_print(tree->right,outfile,indent+2);
5954 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5955 printTypeChain(tree->ftype,outfile);
5956 fprintf(outfile,")\n");
5957 ast_print(tree->left,outfile,indent+2);
5958 ast_print(tree->right,outfile,indent+2);
5961 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5962 printTypeChain(tree->ftype,outfile);
5963 fprintf(outfile,")\n");
5964 ast_print(tree->left,outfile,indent+2);
5965 ast_print(tree->right,outfile,indent+2);
5967 /*------------------------------------------------------------------*/
5968 /*----------------------------*/
5970 /*----------------------------*/
5972 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5973 printTypeChain(tree->ftype,outfile);
5974 fprintf(outfile,")\n");
5975 ast_print(tree->left,outfile,indent+2);
5976 ast_print(tree->right,outfile,indent+2);
5978 /*------------------------------------------------------------------*/
5979 /*----------------------------*/
5981 /*----------------------------*/
5983 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5984 printTypeChain(tree->ftype,outfile);
5985 fprintf(outfile,")\n");
5986 ast_print(tree->left,outfile,indent+2);
5987 ast_print(tree->right,outfile,indent+2);
5989 /*------------------------------------------------------------------*/
5990 /*----------------------------*/
5991 /* straight assignemnt */
5992 /*----------------------------*/
5994 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5995 printTypeChain(tree->ftype,outfile);
5996 fprintf(outfile,")\n");
5997 ast_print(tree->left,outfile,indent+2);
5998 ast_print(tree->right,outfile,indent+2);
6000 /*------------------------------------------------------------------*/
6001 /*----------------------------*/
6002 /* comma operator */
6003 /*----------------------------*/
6005 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6006 printTypeChain(tree->ftype,outfile);
6007 fprintf(outfile,")\n");
6008 ast_print(tree->left,outfile,indent+2);
6009 ast_print(tree->right,outfile,indent+2);
6011 /*------------------------------------------------------------------*/
6012 /*----------------------------*/
6014 /*----------------------------*/
6017 fprintf(outfile,"CALL (%p) type (",tree);
6018 printTypeChain(tree->ftype,outfile);
6019 fprintf(outfile,")\n");
6020 ast_print(tree->left,outfile,indent+2);
6021 ast_print(tree->right,outfile,indent+2);
6024 fprintf(outfile,"PARMS\n");
6025 ast_print(tree->left,outfile,indent+2);
6026 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6027 ast_print(tree->right,outfile,indent+2);
6030 /*------------------------------------------------------------------*/
6031 /*----------------------------*/
6032 /* return statement */
6033 /*----------------------------*/
6035 fprintf(outfile,"RETURN (%p) type (",tree);
6037 printTypeChain(tree->right->ftype,outfile);
6039 fprintf(outfile,")\n");
6040 ast_print(tree->right,outfile,indent+2);
6042 /*------------------------------------------------------------------*/
6043 /*----------------------------*/
6044 /* label statement */
6045 /*----------------------------*/
6047 fprintf(outfile,"LABEL (%p)\n",tree);
6048 ast_print(tree->left,outfile,indent+2);
6049 ast_print(tree->right,outfile,indent);
6051 /*------------------------------------------------------------------*/
6052 /*----------------------------*/
6053 /* switch statement */
6054 /*----------------------------*/
6058 fprintf(outfile,"SWITCH (%p) ",tree);
6059 ast_print(tree->left,outfile,0);
6060 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6061 INDENT(indent+2,outfile);
6062 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6063 (int) floatFromVal(val),
6064 tree->values.switchVals.swNum,
6065 (int) floatFromVal(val));
6067 ast_print(tree->right,outfile,indent);
6070 /*------------------------------------------------------------------*/
6071 /*----------------------------*/
6073 /*----------------------------*/
6075 fprintf(outfile,"IF (%p) \n",tree);
6076 ast_print(tree->left,outfile,indent+2);
6077 if (tree->trueLabel) {
6078 INDENT(indent+2,outfile);
6079 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6081 if (tree->falseLabel) {
6082 INDENT(indent+2,outfile);
6083 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6085 ast_print(tree->right,outfile,indent+2);
6087 /*----------------------------*/
6088 /* goto Statement */
6089 /*----------------------------*/
6091 fprintf(outfile,"GOTO (%p) \n",tree);
6092 ast_print(tree->left,outfile,indent+2);
6093 fprintf(outfile,"\n");
6095 /*------------------------------------------------------------------*/
6096 /*----------------------------*/
6098 /*----------------------------*/
6100 fprintf(outfile,"FOR (%p) \n",tree);
6101 if (AST_FOR( tree, initExpr)) {
6102 INDENT(indent+2,outfile);
6103 fprintf(outfile,"INIT EXPR ");
6104 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6106 if (AST_FOR( tree, condExpr)) {
6107 INDENT(indent+2,outfile);
6108 fprintf(outfile,"COND EXPR ");
6109 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6111 if (AST_FOR( tree, loopExpr)) {
6112 INDENT(indent+2,outfile);
6113 fprintf(outfile,"LOOP EXPR ");
6114 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6116 fprintf(outfile,"FOR LOOP BODY \n");
6117 ast_print(tree->left,outfile,indent+2);
6120 fprintf(outfile,"CRITICAL (%p) \n",tree);
6121 ast_print(tree->left,outfile,indent+2);
6129 ast_print(t,stdout,0);
6134 /*-----------------------------------------------------------------*/
6135 /* astErrors : returns non-zero if errors present in tree */
6136 /*-----------------------------------------------------------------*/
6137 int astErrors(ast *t)
6146 if (t->type == EX_VALUE
6147 && t->opval.val->sym
6148 && t->opval.val->sym->undefined)
6151 errors += astErrors(t->left);
6152 errors += astErrors(t->right);