1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
221 dest->reversed = src->reversed;
224 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
226 /* if this is a leaf */
228 if (src->type == EX_VALUE)
230 dest->opval.val = copyValue (src->opval.val);
235 if (src->type == EX_LINK)
237 dest->opval.lnk = copyLinkChain (src->opval.lnk);
241 dest->opval.op = src->opval.op;
243 /* if this is a node that has special values */
244 copyAstValues (dest, src);
246 dest->trueLabel = copySymbol (src->trueLabel);
247 dest->falseLabel = copySymbol (src->falseLabel);
248 dest->left = copyAst (src->left);
249 dest->right = copyAst (src->right);
255 /*-----------------------------------------------------------------*/
256 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
257 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
258 /*-----------------------------------------------------------------*/
259 ast *removeIncDecOps (ast * tree) {
261 // traverse the tree and remove inc/dec ops
266 if (tree->type == EX_OP &&
267 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
274 tree->left=removeIncDecOps(tree->left);
275 tree->right=removeIncDecOps(tree->right);
280 /*-----------------------------------------------------------------*/
281 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
282 /* "*++s += 3" -> "*++s = *++s + 3" */
283 /*-----------------------------------------------------------------*/
284 ast *removePreIncDecOps (ast * tree) {
286 // traverse the tree and remove pre-inc/dec ops
291 if (tree->type == EX_OP &&
292 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
297 tree->left=removePreIncDecOps(tree->left);
298 tree->right=removePreIncDecOps(tree->right);
303 /*-----------------------------------------------------------------*/
304 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
305 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
306 /*-----------------------------------------------------------------*/
307 ast *removePostIncDecOps (ast * tree) {
309 // traverse the tree and remove pre-inc/dec ops
314 if (tree->type == EX_OP &&
315 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
320 tree->left=removePostIncDecOps(tree->left);
321 tree->right=removePostIncDecOps(tree->right);
326 /*-----------------------------------------------------------------*/
327 /* hasSEFcalls - returns TRUE if tree has a function call */
328 /*-----------------------------------------------------------------*/
330 hasSEFcalls (ast * tree)
335 if (tree->type == EX_OP &&
336 (tree->opval.op == CALL ||
337 tree->opval.op == PCALL ||
338 tree->opval.op == '=' ||
339 tree->opval.op == INC_OP ||
340 tree->opval.op == DEC_OP))
343 return (hasSEFcalls (tree->left) |
344 hasSEFcalls (tree->right));
347 /*-----------------------------------------------------------------*/
348 /* isAstEqual - compares two asts & returns 1 if they are equal */
349 /*-----------------------------------------------------------------*/
351 isAstEqual (ast * t1, ast * t2)
360 if (t1->type != t2->type)
366 if (t1->opval.op != t2->opval.op)
368 return (isAstEqual (t1->left, t2->left) &&
369 isAstEqual (t1->right, t2->right));
373 if (t1->opval.val->sym)
375 if (!t2->opval.val->sym)
378 return isSymbolEqual (t1->opval.val->sym,
383 if (t2->opval.val->sym)
386 return (floatFromVal (t1->opval.val) ==
387 floatFromVal (t2->opval.val));
391 /* only compare these two types */
399 /*-----------------------------------------------------------------*/
400 /* resolveSymbols - resolve symbols from the symbol table */
401 /*-----------------------------------------------------------------*/
403 resolveSymbols (ast * tree)
405 /* walk the entire tree and check for values */
406 /* with symbols if we find one then replace */
407 /* symbol with that from the symbol table */
414 /* if not block & function */
415 if (tree->type == EX_OP &&
416 (tree->opval.op != FUNCTION &&
417 tree->opval.op != BLOCK &&
418 tree->opval.op != NULLOP))
420 filename = tree->filename;
421 lineno = tree->lineno;
425 /* make sure we resolve the true & false labels for ifx */
426 if (tree->type == EX_OP && tree->opval.op == IFX)
432 if ((csym = findSym (LabelTab, tree->trueLabel,
433 tree->trueLabel->name)))
434 tree->trueLabel = csym;
436 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
437 tree->trueLabel->name);
440 if (tree->falseLabel)
442 if ((csym = findSym (LabelTab,
444 tree->falseLabel->name)))
445 tree->falseLabel = csym;
447 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
448 tree->falseLabel->name);
453 /* if this is a label resolve it from the labelTab */
454 if (IS_AST_VALUE (tree) &&
455 tree->opval.val->sym &&
456 tree->opval.val->sym->islbl)
459 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
460 tree->opval.val->sym->name);
463 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
464 tree->opval.val->sym->name);
466 tree->opval.val->sym = csym;
468 goto resolveChildren;
471 /* do only for leafs */
472 if (IS_AST_VALUE (tree) &&
473 tree->opval.val->sym &&
474 !tree->opval.val->sym->implicit)
477 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
479 /* if found in the symbol table & they r not the same */
480 if (csym && tree->opval.val->sym != csym)
482 tree->opval.val->sym = csym;
483 tree->opval.val->type = csym->type;
484 tree->opval.val->etype = csym->etype;
487 /* if not found in the symbol table */
488 /* mark it as undefined assume it is */
489 /* an integer in data space */
490 if (!csym && !tree->opval.val->sym->implicit)
493 /* if this is a function name then */
494 /* mark it as returning an int */
497 tree->opval.val->sym->type = newLink (DECLARATOR);
498 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
499 tree->opval.val->sym->type->next =
500 tree->opval.val->sym->etype = newIntLink ();
501 tree->opval.val->etype = tree->opval.val->etype;
502 tree->opval.val->type = tree->opval.val->sym->type;
503 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
504 tree->opval.val->sym->name);
505 //tree->opval.val->sym->undefined = 1;
506 allocVariables (tree->opval.val->sym);
510 tree->opval.val->sym->undefined = 1;
511 tree->opval.val->type =
512 tree->opval.val->etype = newIntLink ();
513 tree->opval.val->sym->type =
514 tree->opval.val->sym->etype = newIntLink ();
520 resolveSymbols (tree->left);
521 resolveSymbols (tree->right);
526 /*-----------------------------------------------------------------*/
527 /* setAstLineno - walks a ast tree & sets the line number */
528 /*-----------------------------------------------------------------*/
529 int setAstLineno (ast * tree, int lineno)
534 tree->lineno = lineno;
535 setAstLineno (tree->left, lineno);
536 setAstLineno (tree->right, lineno);
540 /*-----------------------------------------------------------------*/
541 /* funcOfType :- function of type with name */
542 /*-----------------------------------------------------------------*/
544 funcOfType (char *name, sym_link * type, sym_link * argType,
548 /* create the symbol */
549 sym = newSymbol (name, 0);
551 /* setup return value */
552 sym->type = newLink (DECLARATOR);
553 DCL_TYPE (sym->type) = FUNCTION;
554 sym->type->next = copyLinkChain (type);
555 sym->etype = getSpec (sym->type);
556 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
558 /* if arguments required */
562 args = FUNC_ARGS(sym->type) = newValue ();
566 args->type = copyLinkChain (argType);
567 args->etype = getSpec (args->type);
568 SPEC_EXTR(args->etype)=1;
571 args = args->next = newValue ();
578 allocVariables (sym);
583 /*-----------------------------------------------------------------*/
584 /* funcOfTypeVarg :- function of type with name and argtype */
585 /*-----------------------------------------------------------------*/
587 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
592 /* create the symbol */
593 sym = newSymbol (name, 0);
595 /* setup return value */
596 sym->type = newLink (DECLARATOR);
597 DCL_TYPE (sym->type) = FUNCTION;
598 sym->type->next = typeFromStr(rtype);
599 sym->etype = getSpec (sym->type);
601 /* if arguments required */
604 args = FUNC_ARGS(sym->type) = newValue ();
606 for ( i = 0 ; i < nArgs ; i++ ) {
607 args->type = typeFromStr(atypes[i]);
608 args->etype = getSpec (args->type);
609 SPEC_EXTR(args->etype)=1;
610 if ((i + 1) == nArgs) break;
611 args = args->next = newValue ();
618 allocVariables (sym);
623 /*-----------------------------------------------------------------*/
624 /* reverseParms - will reverse a parameter tree */
625 /*-----------------------------------------------------------------*/
627 reverseParms (ast * ptree)
633 /* top down if we find a nonParm tree then quit */
634 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
636 /* The various functions expect the parameter tree to be right heavy. */
637 /* Rotate the tree to be left heavy so that after reversal it is */
638 /* right heavy again. */
639 while ((ttree = ptree->right) && ttree->type == EX_OP &&
640 ttree->opval.op == PARAM)
642 ptree->right = ttree->right;
643 ttree->right = ttree->left;
644 ttree->left = ptree->left;
650 ptree->left = ptree->right;
651 ptree->right = ttree;
653 reverseParms (ptree->left);
654 reverseParms (ptree->right);
660 /*-----------------------------------------------------------------*/
661 /* processParms - makes sure the parameters are okay and do some */
662 /* processing with them */
663 /*-----------------------------------------------------------------*/
665 processParms (ast *func,
668 int *parmNumber, /* unused, although updated */
671 RESULT_TYPE resultType;
674 /* if none of them exist */
675 if (!defParm && !*actParm)
680 if (getenv("DEBUG_SANITY"))
682 fprintf (stderr, "processParms: %s ", defParm->name);
684 /* make sure the type is complete and sane */
685 checkTypeSanity(defParm->etype, defParm->name);
688 if (IS_CODEPTR (func->ftype))
689 functype = func->ftype->next;
691 functype = func->ftype;
693 /* if the function is being called via a pointer & */
694 /* it has not been defined a reentrant then we cannot */
695 /* have parameters */
696 /* PIC16 port can... */
697 if (!TARGET_IS_PIC16)
699 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
701 werror (W_NONRENT_ARGS);
707 /* if defined parameters ended but actual parameters */
708 /* exist and this is not defined as a variable arg */
709 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
711 werror (E_TOO_MANY_PARMS);
715 /* if defined parameters present but no actual parameters */
716 if (defParm && !*actParm)
718 werror (E_TOO_FEW_PARMS);
722 /* if this is a PARAM node then match left & right */
723 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
725 (*actParm)->decorated = 1;
726 return (processParms (func, defParm,
727 &(*actParm)->left, parmNumber, FALSE) ||
728 processParms (func, defParm ? defParm->next : NULL,
729 &(*actParm)->right, parmNumber, rightmost));
731 else if (defParm) /* not vararg */
733 /* If we have found a value node by following only right-hand links,
734 * then we know that there are no more values after us.
736 * Therefore, if there are more defined parameters, the caller didn't
739 if (rightmost && defParm->next)
741 werror (E_TOO_FEW_PARMS);
746 /* decorate parameter */
747 resultType = defParm ? getResultTypeFromType (defParm->etype) :
749 *actParm = decorateType (*actParm, resultType);
751 if (IS_VOID((*actParm)->ftype))
753 werror (E_VOID_VALUE_USED);
757 /* If this is a varargs function... */
758 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
763 if (IS_CAST_OP (*actParm)
764 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
766 /* Parameter was explicitly typecast; don't touch it. */
770 ftype = (*actParm)->ftype;
772 /* If it's a char, upcast to int. */
773 if (IS_INTEGRAL (ftype)
774 && (getSize (ftype) < (unsigned) INTSIZE))
776 newType = newAst_LINK(INTTYPE);
779 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
781 newType = newAst_LINK (copyLinkChain(ftype));
782 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
785 if (IS_AGGREGATE (ftype))
787 newType = newAst_LINK (copyLinkChain (ftype));
788 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
793 /* cast required; change this op to a cast. */
794 (*actParm)->decorated = 0;
795 *actParm = newNode (CAST, newType, *actParm);
796 (*actParm)->lineno = (*actParm)->right->lineno;
798 decorateType (*actParm, RESULT_TYPE_NONE);
803 /* if defined parameters ended but actual has not & */
805 if (!defParm && *actParm &&
806 (options.stackAuto || IFFUNC_ISREENT (functype)))
809 resolveSymbols (*actParm);
811 /* the parameter type must be at least castable */
812 if (compareType (defParm->type, (*actParm)->ftype) == 0)
814 werror (E_INCOMPAT_TYPES);
815 printFromToType ((*actParm)->ftype, defParm->type);
819 /* if the parameter is castable then add the cast */
820 if (compareType (defParm->type, (*actParm)->ftype) < 0)
824 resultType = getResultTypeFromType (defParm->etype);
825 pTree = resolveSymbols (copyAst (*actParm));
827 /* now change the current one to a cast */
828 (*actParm)->type = EX_OP;
829 (*actParm)->opval.op = CAST;
830 (*actParm)->left = newAst_LINK (defParm->type);
831 (*actParm)->right = pTree;
832 (*actParm)->decorated = 0; /* force typechecking */
833 decorateType (*actParm, resultType);
836 /* make a copy and change the regparm type to the defined parm */
837 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
838 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
839 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
844 /*-----------------------------------------------------------------*/
845 /* createIvalType - generates ival for basic types */
846 /*-----------------------------------------------------------------*/
848 createIvalType (ast * sym, sym_link * type, initList * ilist)
852 /* if initList is deep */
853 if (ilist->type == INIT_DEEP)
854 ilist = ilist->init.deep;
856 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
857 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
860 /*-----------------------------------------------------------------*/
861 /* createIvalStruct - generates initial value for structures */
862 /*-----------------------------------------------------------------*/
864 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
871 sflds = SPEC_STRUCT (type)->fields;
872 if (ilist->type != INIT_DEEP)
874 werror (E_INIT_STRUCT, "");
878 iloop = ilist->init.deep;
880 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
882 /* if we have come to end */
886 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
887 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
888 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
892 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
893 W_EXCESS_INITIALIZERS, "struct",
894 sym->opval.val->sym->name);
901 /*-----------------------------------------------------------------*/
902 /* createIvalArray - generates code for array initialization */
903 /*-----------------------------------------------------------------*/
905 createIvalArray (ast * sym, sym_link * type, initList * ilist)
909 int lcnt = 0, size = 0;
910 literalList *literalL;
912 /* take care of the special case */
913 /* array of characters can be init */
915 if (IS_CHAR (type->next))
916 if ((rast = createIvalCharPtr (sym,
918 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
920 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
922 /* not the special case */
923 if (ilist->type != INIT_DEEP)
925 werror (E_INIT_STRUCT, "");
929 iloop = ilist->init.deep;
930 lcnt = DCL_ELEM (type);
932 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
936 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
938 rast = newNode(ARRAYINIT, aSym, NULL);
939 rast->values.constlist = literalL;
941 // Make sure size is set to length of initializer list.
948 if (lcnt && size > lcnt)
950 // Array size was specified, and we have more initializers than needed.
951 char *name=sym->opval.val->sym->name;
952 int lineno=sym->opval.val->sym->lineDef;
953 char *filename=sym->opval.val->sym->fileDef;
955 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
964 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
965 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
966 rast = createIval (aSym, type->next, iloop, rast);
967 iloop = (iloop ? iloop->next : NULL);
973 /* no of elements given and we */
974 /* have generated for all of them */
977 // is this a better way? at least it won't crash
978 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
979 int lineno = iloop->lineno;
980 char *filename = iloop->filename;
981 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
988 /* if we have not been given a size */
989 if (!DCL_ELEM (type))
991 /* but this still updates the typedef instead of the instance ! see bug 770487 */
992 DCL_ELEM (type) = size;
995 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
999 /*-----------------------------------------------------------------*/
1000 /* createIvalCharPtr - generates initial values for char pointers */
1001 /*-----------------------------------------------------------------*/
1003 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1007 /* if this is a pointer & right is a literal array then */
1008 /* just assignment will do */
1009 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1010 SPEC_SCLS (iexpr->etype) == S_CODE)
1011 && IS_ARRAY (iexpr->ftype)))
1012 return newNode ('=', sym, iexpr);
1014 /* left side is an array so we have to assign each */
1016 if ((IS_LITERAL (iexpr->etype) ||
1017 SPEC_SCLS (iexpr->etype) == S_CODE)
1018 && IS_ARRAY (iexpr->ftype))
1020 /* for each character generate an assignment */
1021 /* to the array element */
1022 char *s = SPEC_CVAL (iexpr->etype).v_char;
1024 int size = getSize (iexpr->ftype);
1025 int symsize = getSize (type);
1029 if (size>(symsize+1))
1030 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1031 "string", sym->opval.val->sym->name);
1035 for (i=0;i<size;i++)
1037 rast = newNode (NULLOP,
1041 newAst_VALUE (valueFromLit ((float) i))),
1042 newAst_VALUE (valueFromLit (*s))));
1046 // now WE don't need iexpr's symbol anymore
1047 freeStringSymbol(AST_SYMBOL(iexpr));
1049 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1055 /*-----------------------------------------------------------------*/
1056 /* createIvalPtr - generates initial value for pointers */
1057 /*-----------------------------------------------------------------*/
1059 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1065 if (ilist->type == INIT_DEEP)
1066 ilist = ilist->init.deep;
1068 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1070 /* if character pointer */
1071 if (IS_CHAR (type->next))
1072 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1075 return newNode ('=', sym, iexpr);
1078 /*-----------------------------------------------------------------*/
1079 /* createIval - generates code for initial value */
1080 /*-----------------------------------------------------------------*/
1082 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1089 /* if structure then */
1090 if (IS_STRUCT (type))
1091 rast = createIvalStruct (sym, type, ilist);
1093 /* if this is a pointer */
1095 rast = createIvalPtr (sym, type, ilist);
1097 /* if this is an array */
1098 if (IS_ARRAY (type))
1099 rast = createIvalArray (sym, type, ilist);
1101 /* if type is SPECIFIER */
1103 rast = createIvalType (sym, type, ilist);
1106 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1108 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1111 /*-----------------------------------------------------------------*/
1112 /* initAggregates - initialises aggregate variables with initv */
1113 /*-----------------------------------------------------------------*/
1114 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1115 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1118 /*-----------------------------------------------------------------*/
1119 /* gatherAutoInit - creates assignment expressions for initial */
1121 /*-----------------------------------------------------------------*/
1123 gatherAutoInit (symbol * autoChain)
1130 for (sym = autoChain; sym; sym = sym->next)
1133 /* resolve the symbols in the ival */
1135 resolveIvalSym (sym->ival, sym->type);
1138 /* if we are PIC16 port,
1139 * and this is a static,
1140 * and have initial value,
1141 * and not S_CODE, don't emit in gs segment,
1142 * but allow glue.c:pic16emitRegularMap to put symbol
1143 * in idata section */
1144 if(TARGET_IS_PIC16 &&
1145 IS_STATIC (sym->etype) && sym->ival
1146 && SPEC_SCLS(sym->etype) != S_CODE) {
1147 SPEC_SCLS (sym->etype) = S_DATA;
1152 /* if this is a static variable & has an */
1153 /* initial value the code needs to be lifted */
1154 /* here to the main portion since they can be */
1155 /* initialised only once at the start */
1156 if (IS_STATIC (sym->etype) && sym->ival &&
1157 SPEC_SCLS (sym->etype) != S_CODE)
1161 /* insert the symbol into the symbol table */
1162 /* with level = 0 & name = rname */
1163 newSym = copySymbol (sym);
1164 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1166 /* now lift the code to main */
1167 if (IS_AGGREGATE (sym->type)) {
1168 work = initAggregates (sym, sym->ival, NULL);
1170 if (getNelements(sym->type, sym->ival)>1) {
1171 werrorfl (sym->fileDef, sym->lineDef,
1172 W_EXCESS_INITIALIZERS, "scalar",
1175 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1176 list2expr (sym->ival));
1179 setAstLineno (work, sym->lineDef);
1183 staticAutos = newNode (NULLOP, staticAutos, work);
1190 /* if there is an initial value */
1191 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1193 initList *ilist=sym->ival;
1195 while (ilist->type == INIT_DEEP) {
1196 ilist = ilist->init.deep;
1199 /* update lineno for error msg */
1200 lineno=sym->lineDef;
1201 setAstLineno (ilist->init.node, lineno);
1203 if (IS_AGGREGATE (sym->type)) {
1204 work = initAggregates (sym, sym->ival, NULL);
1206 if (getNelements(sym->type, sym->ival)>1) {
1207 werrorfl (sym->fileDef, sym->lineDef,
1208 W_EXCESS_INITIALIZERS, "scalar",
1211 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1212 list2expr (sym->ival));
1216 setAstLineno (work, sym->lineDef);
1220 init = newNode (NULLOP, init, work);
1229 /*-----------------------------------------------------------------*/
1230 /* freeStringSymbol - delete a literal string if no more usage */
1231 /*-----------------------------------------------------------------*/
1232 void freeStringSymbol(symbol *sym) {
1233 /* make sure this is a literal string */
1234 assert (sym->isstrlit);
1235 if (--sym->isstrlit == 0) { // lower the usage count
1236 memmap *segment=SPEC_OCLS(sym->etype);
1238 deleteSetItem(&segment->syms, sym);
1243 /*-----------------------------------------------------------------*/
1244 /* stringToSymbol - creates a symbol from a literal string */
1245 /*-----------------------------------------------------------------*/
1247 stringToSymbol (value * val)
1249 char name[SDCC_NAME_MAX + 1];
1250 static int charLbl = 0;
1255 // have we heard this before?
1256 for (sp=statsg->syms; sp; sp=sp->next) {
1258 size = getSize (sym->type);
1259 if (sym->isstrlit && size == getSize (val->type) &&
1260 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1261 // yes, this is old news. Don't publish it again.
1262 sym->isstrlit++; // but raise the usage count
1263 return symbolVal(sym);
1267 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1268 sym = newSymbol (name, 0); /* make it @ level 0 */
1269 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1271 /* copy the type from the value passed */
1272 sym->type = copyLinkChain (val->type);
1273 sym->etype = getSpec (sym->type);
1274 /* change to storage class & output class */
1275 SPEC_SCLS (sym->etype) = S_CODE;
1276 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1277 SPEC_STAT (sym->etype) = 1;
1278 /* make the level & block = 0 */
1279 sym->block = sym->level = 0;
1281 /* create an ival */
1282 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1287 allocVariables (sym);
1290 return symbolVal (sym);
1294 /*-----------------------------------------------------------------*/
1295 /* processBlockVars - will go thru the ast looking for block if */
1296 /* a block is found then will allocate the syms */
1297 /* will also gather the auto inits present */
1298 /*-----------------------------------------------------------------*/
1300 processBlockVars (ast * tree, int *stack, int action)
1305 /* if this is a block */
1306 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1310 if (action == ALLOCATE)
1312 *stack += allocVariables (tree->values.sym);
1313 autoInit = gatherAutoInit (tree->values.sym);
1315 /* if there are auto inits then do them */
1317 tree->left = newNode (NULLOP, autoInit, tree->left);
1319 else /* action is deallocate */
1320 deallocLocal (tree->values.sym);
1323 processBlockVars (tree->left, stack, action);
1324 processBlockVars (tree->right, stack, action);
1329 /*-------------------------------------------------------------*/
1330 /* constExprTree - returns TRUE if this tree is a constant */
1332 /*-------------------------------------------------------------*/
1333 bool constExprTree (ast *cexpr) {
1339 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1341 switch (cexpr->type)
1344 if (IS_AST_LIT_VALUE(cexpr)) {
1345 // this is a literal
1348 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1349 // a function's address will never change
1352 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1353 // an array's address will never change
1356 if (IS_AST_SYM_VALUE(cexpr) &&
1357 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1358 // a symbol in code space will never change
1359 // This is only for the 'char *s="hallo"' case and will have to leave
1360 //printf(" code space symbol");
1365 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1366 "unexpected link in expression tree\n");
1369 if (cexpr->opval.op==ARRAYINIT) {
1370 // this is a list of literals
1373 if (cexpr->opval.op=='=') {
1374 return constExprTree(cexpr->right);
1376 if (cexpr->opval.op==CAST) {
1377 // cast ignored, maybe we should throw a warning here?
1378 return constExprTree(cexpr->right);
1380 if (cexpr->opval.op=='&') {
1383 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1386 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1391 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1396 /*-----------------------------------------------------------------*/
1397 /* constExprValue - returns the value of a constant expression */
1398 /* or NULL if it is not a constant expression */
1399 /*-----------------------------------------------------------------*/
1401 constExprValue (ast * cexpr, int check)
1403 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1405 /* if this is not a constant then */
1406 if (!IS_LITERAL (cexpr->ftype))
1408 /* then check if this is a literal array
1410 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1411 SPEC_CVAL (cexpr->etype).v_char &&
1412 IS_ARRAY (cexpr->ftype))
1414 value *val = valFromType (cexpr->ftype);
1415 SPEC_SCLS (val->etype) = S_LITERAL;
1416 val->sym = cexpr->opval.val->sym;
1417 val->sym->type = copyLinkChain (cexpr->ftype);
1418 val->sym->etype = getSpec (val->sym->type);
1419 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1423 /* if we are casting a literal value then */
1424 if (IS_AST_OP (cexpr) &&
1425 cexpr->opval.op == CAST &&
1426 IS_LITERAL (cexpr->right->ftype))
1428 return valCastLiteral (cexpr->ftype,
1429 floatFromVal (cexpr->right->opval.val));
1432 if (IS_AST_VALUE (cexpr))
1434 return cexpr->opval.val;
1438 werror (E_CONST_EXPECTED, "found expression");
1443 /* return the value */
1444 return cexpr->opval.val;
1448 /*-----------------------------------------------------------------*/
1449 /* isLabelInAst - will return true if a given label is found */
1450 /*-----------------------------------------------------------------*/
1452 isLabelInAst (symbol * label, ast * tree)
1454 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1457 if (IS_AST_OP (tree) &&
1458 tree->opval.op == LABEL &&
1459 isSymbolEqual (AST_SYMBOL (tree->left), label))
1462 return isLabelInAst (label, tree->right) &&
1463 isLabelInAst (label, tree->left);
1467 /*-----------------------------------------------------------------*/
1468 /* isLoopCountable - return true if the loop count can be determi- */
1469 /* -ned at compile time . */
1470 /*-----------------------------------------------------------------*/
1472 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1473 symbol ** sym, ast ** init, ast ** end)
1476 /* the loop is considered countable if the following
1477 conditions are true :-
1479 a) initExpr :- <sym> = <const>
1480 b) condExpr :- <sym> < <const1>
1481 c) loopExpr :- <sym> ++
1484 /* first check the initExpr */
1485 if (IS_AST_OP (initExpr) &&
1486 initExpr->opval.op == '=' && /* is assignment */
1487 IS_AST_SYM_VALUE (initExpr->left))
1488 { /* left is a symbol */
1490 *sym = AST_SYMBOL (initExpr->left);
1491 *init = initExpr->right;
1496 /* for now the symbol has to be of
1498 if (!IS_INTEGRAL ((*sym)->type))
1501 /* now check condExpr */
1502 if (IS_AST_OP (condExpr))
1505 switch (condExpr->opval.op)
1508 if (IS_AST_SYM_VALUE (condExpr->left) &&
1509 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1510 IS_AST_LIT_VALUE (condExpr->right))
1512 *end = condExpr->right;
1518 if (IS_AST_OP (condExpr->left) &&
1519 condExpr->left->opval.op == '>' &&
1520 IS_AST_LIT_VALUE (condExpr->left->right) &&
1521 IS_AST_SYM_VALUE (condExpr->left->left) &&
1522 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1525 *end = newNode ('+', condExpr->left->right,
1526 newAst_VALUE (constVal ("1")));
1539 /* check loop expression is of the form <sym>++ */
1540 if (!IS_AST_OP (loopExpr))
1543 /* check if <sym> ++ */
1544 if (loopExpr->opval.op == INC_OP)
1550 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1551 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1558 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1559 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1567 if (loopExpr->opval.op == ADD_ASSIGN)
1570 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1571 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1572 IS_AST_LIT_VALUE (loopExpr->right) &&
1573 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1581 /*-----------------------------------------------------------------*/
1582 /* astHasVolatile - returns true if ast contains any volatile */
1583 /*-----------------------------------------------------------------*/
1585 astHasVolatile (ast * tree)
1590 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1593 if (IS_AST_OP (tree))
1594 return astHasVolatile (tree->left) ||
1595 astHasVolatile (tree->right);
1600 /*-----------------------------------------------------------------*/
1601 /* astHasPointer - return true if the ast contains any ptr variable */
1602 /*-----------------------------------------------------------------*/
1604 astHasPointer (ast * tree)
1609 if (IS_AST_LINK (tree))
1612 /* if we hit an array expression then check
1613 only the left side */
1614 if (IS_AST_OP (tree) && tree->opval.op == '[')
1615 return astHasPointer (tree->left);
1617 if (IS_AST_VALUE (tree))
1618 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1620 return astHasPointer (tree->left) ||
1621 astHasPointer (tree->right);
1625 /*-----------------------------------------------------------------*/
1626 /* astHasSymbol - return true if the ast has the given symbol */
1627 /*-----------------------------------------------------------------*/
1629 astHasSymbol (ast * tree, symbol * sym)
1631 if (!tree || IS_AST_LINK (tree))
1634 if (IS_AST_VALUE (tree))
1636 if (IS_AST_SYM_VALUE (tree))
1637 return isSymbolEqual (AST_SYMBOL (tree), sym);
1642 return astHasSymbol (tree->left, sym) ||
1643 astHasSymbol (tree->right, sym);
1646 /*-----------------------------------------------------------------*/
1647 /* astHasDeref - return true if the ast has an indirect access */
1648 /*-----------------------------------------------------------------*/
1650 astHasDeref (ast * tree)
1652 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1655 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1657 return astHasDeref (tree->left) || astHasDeref (tree->right);
1660 /*-----------------------------------------------------------------*/
1661 /* isConformingBody - the loop body has to conform to a set of rules */
1662 /* for the loop to be considered reversible read on for rules */
1663 /*-----------------------------------------------------------------*/
1665 isConformingBody (ast * pbody, symbol * sym, ast * body)
1668 /* we are going to do a pre-order traversal of the
1669 tree && check for the following conditions. (essentially
1670 a set of very shallow tests )
1671 a) the sym passed does not participate in
1672 any arithmetic operation
1673 b) There are no function calls
1674 c) all jumps are within the body
1675 d) address of loop control variable not taken
1676 e) if an assignment has a pointer on the
1677 left hand side make sure right does not have
1678 loop control variable */
1680 /* if we reach the end or a leaf then true */
1681 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1684 /* if anything else is "volatile" */
1685 if (IS_VOLATILE (TETYPE (pbody)))
1688 /* we will walk the body in a pre-order traversal for
1690 switch (pbody->opval.op)
1692 /*------------------------------------------------------------------*/
1694 // if the loopvar is used as an index
1695 /* array op is commutative -- must check both left & right */
1696 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1699 return isConformingBody (pbody->right, sym, body)
1700 && isConformingBody (pbody->left, sym, body);
1702 /*------------------------------------------------------------------*/
1707 /*------------------------------------------------------------------*/
1711 /* sure we are not sym is not modified */
1713 IS_AST_SYM_VALUE (pbody->left) &&
1714 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1718 IS_AST_SYM_VALUE (pbody->right) &&
1719 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1724 /*------------------------------------------------------------------*/
1726 case '*': /* can be unary : if right is null then unary operation */
1731 /* if right is NULL then unary operation */
1732 /*------------------------------------------------------------------*/
1733 /*----------------------------*/
1735 /*----------------------------*/
1738 if (IS_AST_SYM_VALUE (pbody->left) &&
1739 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1742 return isConformingBody (pbody->left, sym, body);
1746 if (astHasSymbol (pbody->left, sym) ||
1747 astHasSymbol (pbody->right, sym))
1752 /*------------------------------------------------------------------*/
1760 if (IS_AST_SYM_VALUE (pbody->left) &&
1761 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1764 if (IS_AST_SYM_VALUE (pbody->right) &&
1765 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1777 if (IS_AST_SYM_VALUE (pbody->left) &&
1778 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1780 return isConformingBody (pbody->left, sym, body);
1782 /*------------------------------------------------------------------*/
1794 case SIZEOF: /* evaluate wihout code generation */
1796 if (IS_AST_SYM_VALUE (pbody->left) &&
1797 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1800 if (IS_AST_SYM_VALUE (pbody->right) &&
1801 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1804 return isConformingBody (pbody->left, sym, body) &&
1805 isConformingBody (pbody->right, sym, body);
1807 /*------------------------------------------------------------------*/
1810 /* if left has a pointer & right has loop
1811 control variable then we cannot */
1812 if (astHasPointer (pbody->left) &&
1813 astHasSymbol (pbody->right, sym))
1815 if (astHasVolatile (pbody->left))
1818 if (IS_AST_SYM_VALUE (pbody->left)) {
1819 // if the loopvar has an assignment
1820 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1822 // if the loopvar is used in another (maybe conditional) block
1823 if (astHasSymbol (pbody->right, sym) &&
1824 (pbody->level >= body->level)) {
1829 if (astHasVolatile (pbody->left))
1832 if (astHasDeref(pbody->right)) return FALSE;
1834 return isConformingBody (pbody->left, sym, body) &&
1835 isConformingBody (pbody->right, sym, body);
1846 assert ("Parser should not have generated this\n");
1848 /*------------------------------------------------------------------*/
1849 /*----------------------------*/
1850 /* comma operator */
1851 /*----------------------------*/
1853 return isConformingBody (pbody->left, sym, body) &&
1854 isConformingBody (pbody->right, sym, body);
1856 /*------------------------------------------------------------------*/
1857 /*----------------------------*/
1859 /*----------------------------*/
1861 /* if local & not passed as paramater then ok */
1862 if (sym->level && !astHasSymbol(pbody->right,sym))
1866 /*------------------------------------------------------------------*/
1867 /*----------------------------*/
1868 /* return statement */
1869 /*----------------------------*/
1874 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1879 if (astHasSymbol (pbody->left, sym))
1886 return isConformingBody (pbody->left, sym, body) &&
1887 isConformingBody (pbody->right, sym, body);
1893 /*-----------------------------------------------------------------*/
1894 /* isLoopReversible - takes a for loop as input && returns true */
1895 /* if the for loop is reversible. If yes will set the value of */
1896 /* the loop control var & init value & termination value */
1897 /*-----------------------------------------------------------------*/
1899 isLoopReversible (ast * loop, symbol ** loopCntrl,
1900 ast ** init, ast ** end)
1902 /* if option says don't do it then don't */
1903 if (optimize.noLoopReverse)
1905 /* there are several tests to determine this */
1907 /* for loop has to be of the form
1908 for ( <sym> = <const1> ;
1909 [<sym> < <const2>] ;
1910 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1912 if (!isLoopCountable (AST_FOR (loop, initExpr),
1913 AST_FOR (loop, condExpr),
1914 AST_FOR (loop, loopExpr),
1915 loopCntrl, init, end))
1918 /* now do some serious checking on the body of the loop
1921 return isConformingBody (loop->left, *loopCntrl, loop->left);
1925 /*-----------------------------------------------------------------*/
1926 /* replLoopSym - replace the loop sym by loop sym -1 */
1927 /*-----------------------------------------------------------------*/
1929 replLoopSym (ast * body, symbol * sym)
1932 if (!body || IS_AST_LINK (body))
1935 if (IS_AST_SYM_VALUE (body))
1938 if (isSymbolEqual (AST_SYMBOL (body), sym))
1942 body->opval.op = '-';
1943 body->left = newAst_VALUE (symbolVal (sym));
1944 body->right = newAst_VALUE (constVal ("1"));
1952 replLoopSym (body->left, sym);
1953 replLoopSym (body->right, sym);
1957 /*-----------------------------------------------------------------*/
1958 /* reverseLoop - do the actual loop reversal */
1959 /*-----------------------------------------------------------------*/
1961 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1965 /* create the following tree
1970 if (sym) goto for_continue ;
1973 /* put it together piece by piece */
1974 rloop = newNode (NULLOP,
1975 createIf (newAst_VALUE (symbolVal (sym)),
1977 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1980 newAst_VALUE (symbolVal (sym)),
1983 replLoopSym (loop->left, sym);
1984 setAstLineno (rloop, init->lineno);
1986 rloop = newNode (NULLOP,
1988 newAst_VALUE (symbolVal (sym)),
1989 newNode ('-', end, init)),
1990 createLabel (AST_FOR (loop, continueLabel),
1994 newNode (SUB_ASSIGN,
1995 newAst_VALUE (symbolVal (sym)),
1996 newAst_VALUE (constVal ("1"))),
1999 rloop->lineno=init->lineno;
2000 return decorateType (rloop, RESULT_TYPE_NONE);
2004 /*-----------------------------------------------------------------*/
2005 /* searchLitOp - search tree (*ops only) for an ast with literal */
2006 /*-----------------------------------------------------------------*/
2008 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2012 if (tree && optimize.global_cse)
2014 /* is there a literal operand? */
2016 IS_AST_OP(tree->right) &&
2017 tree->right->right &&
2018 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2020 if (IS_LITERAL (RTYPE (tree->right)) !=
2021 IS_LITERAL (LTYPE (tree->right)))
2023 tree->right->decorated = 0;
2024 tree->decorated = 0;
2028 ret = searchLitOp (tree->right, parent, ops);
2033 IS_AST_OP(tree->left) &&
2034 tree->left->right &&
2035 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2037 if (IS_LITERAL (RTYPE (tree->left)) !=
2038 IS_LITERAL (LTYPE (tree->left)))
2040 tree->left->decorated = 0;
2041 tree->decorated = 0;
2045 ret = searchLitOp (tree->left, parent, ops);
2053 /*-----------------------------------------------------------------*/
2054 /* getResultFromType */
2055 /*-----------------------------------------------------------------*/
2057 getResultTypeFromType (sym_link *type)
2059 /* type = getSpec (type); */
2061 return RESULT_TYPE_BIT;
2062 if (IS_BITFIELD (type))
2064 int blen = SPEC_BLEN (type);
2067 return RESULT_TYPE_BIT;
2069 return RESULT_TYPE_CHAR;
2070 return RESULT_TYPE_INT;
2073 return RESULT_TYPE_CHAR;
2076 return RESULT_TYPE_INT;
2077 return RESULT_TYPE_OTHER;
2080 /*-----------------------------------------------------------------*/
2081 /* addCast - adds casts to a type specified by RESULT_TYPE */
2082 /*-----------------------------------------------------------------*/
2084 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2087 bool upCasted = FALSE;
2091 case RESULT_TYPE_NONE:
2092 /* char: promote to int */
2094 getSize (tree->etype) >= INTSIZE)
2096 newLink = newIntLink();
2099 case RESULT_TYPE_CHAR:
2100 if (IS_CHAR (tree->etype) ||
2101 IS_FLOAT(tree->etype))
2103 newLink = newCharLink();
2105 case RESULT_TYPE_INT:
2107 if (getSize (tree->etype) > INTSIZE)
2109 /* warn ("Loosing significant digits"); */
2113 /* char: promote to int */
2115 getSize (tree->etype) >= INTSIZE)
2117 newLink = newIntLink();
2120 case RESULT_TYPE_OTHER:
2123 /* return type is long, float: promote char to int */
2124 if (getSize (tree->etype) >= INTSIZE)
2126 newLink = newIntLink();
2132 tree->decorated = 0;
2133 tree = newNode (CAST, newAst_LINK (newLink), tree);
2134 tree->lineno = tree->right->lineno;
2135 /* keep unsigned type during cast to smaller type,
2136 but not when promoting from char to int */
2138 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2139 return decorateType (tree, resultType);
2142 /*-----------------------------------------------------------------*/
2143 /* resultTypePropagate - decides if resultType can be propagated */
2144 /*-----------------------------------------------------------------*/
2146 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2148 switch (tree->opval.op)
2164 return RESULT_TYPE_NONE;
2168 return RESULT_TYPE_IFX;
2170 return RESULT_TYPE_NONE;
2174 /*-----------------------------------------------------------------*/
2175 /* getLeftResultType - gets type from left branch for propagation */
2176 /*-----------------------------------------------------------------*/
2178 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2180 switch (tree->opval.op)
2184 if (IS_PTR (LTYPE (tree)))
2185 return RESULT_TYPE_NONE;
2187 return getResultTypeFromType (LETYPE (tree));
2189 if (IS_PTR (currFunc->type->next))
2190 return RESULT_TYPE_NONE;
2192 return getResultTypeFromType (currFunc->type->next);
2194 if (!IS_ARRAY (LTYPE (tree)))
2196 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2197 return RESULT_TYPE_CHAR;
2204 /*--------------------------------------------------------------------*/
2205 /* decorateType - compute type for this tree, also does type checking.*/
2206 /* This is done bottom up, since type has to flow upwards. */
2207 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2208 /* result is a char and the operand(s) are int's. */
2209 /* It also does constant folding, and parameter checking. */
2210 /*--------------------------------------------------------------------*/
2212 decorateType (ast * tree, RESULT_TYPE resultType)
2216 RESULT_TYPE resultTypeProp;
2221 /* if already has type then do nothing */
2222 if (tree->decorated)
2225 tree->decorated = 1;
2228 /* print the line */
2229 /* if not block & function */
2230 if (tree->type == EX_OP &&
2231 (tree->opval.op != FUNCTION &&
2232 tree->opval.op != BLOCK &&
2233 tree->opval.op != NULLOP))
2235 filename = tree->filename;
2236 lineno = tree->lineno;
2240 /* if any child is an error | this one is an error do nothing */
2241 if (tree->isError ||
2242 (tree->left && tree->left->isError) ||
2243 (tree->right && tree->right->isError))
2246 /*------------------------------------------------------------------*/
2247 /*----------------------------*/
2248 /* leaf has been reached */
2249 /*----------------------------*/
2250 lineno=tree->lineno;
2251 /* if this is of type value */
2252 /* just get the type */
2253 if (tree->type == EX_VALUE)
2256 if (IS_LITERAL (tree->opval.val->etype))
2259 /* if this is a character array then declare it */
2260 if (IS_ARRAY (tree->opval.val->type))
2261 tree->opval.val = stringToSymbol (tree->opval.val);
2263 /* otherwise just copy the type information */
2264 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2268 if (tree->opval.val->sym)
2270 /* if the undefined flag is set then give error message */
2271 if (tree->opval.val->sym->undefined)
2273 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2275 TTYPE (tree) = TETYPE (tree) =
2276 tree->opval.val->type = tree->opval.val->sym->type =
2277 tree->opval.val->etype = tree->opval.val->sym->etype =
2278 copyLinkChain (INTTYPE);
2283 /* if impilicit i.e. struct/union member then no type */
2284 if (tree->opval.val->sym->implicit)
2285 TTYPE (tree) = TETYPE (tree) = NULL;
2290 /* else copy the type */
2291 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2293 /* and mark it as referenced */
2294 tree->opval.val->sym->isref = 1;
2302 /* if type link for the case of cast */
2303 if (tree->type == EX_LINK)
2305 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2313 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2315 if (tree->left && tree->left->type == EX_OPERAND
2316 && (tree->left->opval.op == INC_OP
2317 || tree->left->opval.op == DEC_OP)
2318 && tree->left->left)
2320 tree->left->right = tree->left->left;
2321 tree->left->left = NULL;
2323 if (tree->right && tree->right->type == EX_OPERAND
2324 && (tree->right->opval.op == INC_OP
2325 || tree->right->opval.op == DEC_OP)
2326 && tree->right->left)
2328 tree->right->right = tree->right->left;
2329 tree->right->left = NULL;
2334 /* Before decorating the left branch we've to decide in dependence
2335 upon tree->opval.op, if resultType can be propagated */
2336 resultTypeProp = resultTypePropagate (tree, resultType);
2338 if (tree->opval.op == '?')
2339 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2341 dtl = decorateType (tree->left, resultTypeProp);
2343 /* if an array node, we may need to swap branches */
2344 if (tree->opval.op == '[')
2346 /* determine which is the array & which the index */
2347 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2348 IS_INTEGRAL (LTYPE (tree)))
2350 ast *tempTree = tree->left;
2351 tree->left = tree->right;
2352 tree->right = tempTree;
2356 /* After decorating the left branch there's type information available
2357 in tree->left->?type. If the op is e.g. '=' we extract the type
2358 information from there and propagate it to the right branch. */
2359 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2361 switch (tree->opval.op)
2364 /* delay right side for '?' operator since conditional macro
2365 expansions might rely on this */
2369 /* decorate right side for CALL (parameter list) in processParms();
2370 there is resultType available */
2374 dtr = decorateType (tree->right, resultTypeProp);
2378 /* this is to take care of situations
2379 when the tree gets rewritten */
2380 if (dtl != tree->left)
2382 if (dtr != tree->right)
2384 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2388 /* depending on type of operator do */
2390 switch (tree->opval.op)
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2395 /*----------------------------*/
2398 /* first check if this is a array or a pointer */
2399 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2401 werror (E_NEED_ARRAY_PTR, "[]");
2402 goto errorTreeReturn;
2405 /* check if the type of the idx */
2406 if (!IS_INTEGRAL (RTYPE (tree)))
2408 werror (E_IDX_NOT_INT);
2409 goto errorTreeReturn;
2412 /* if the left is an rvalue then error */
2415 werror (E_LVALUE_REQUIRED, "array access");
2416 goto errorTreeReturn;
2419 if (IS_LITERAL (RTYPE (tree)))
2421 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2422 int arraySize = DCL_ELEM (LTYPE (tree));
2423 if (arraySize && arrayIndex >= arraySize)
2425 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2430 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2433 /*------------------------------------------------------------------*/
2434 /*----------------------------*/
2436 /*----------------------------*/
2438 /* if this is not a structure */
2439 if (!IS_STRUCT (LTYPE (tree)))
2441 werror (E_STRUCT_UNION, ".");
2442 goto errorTreeReturn;
2444 TTYPE (tree) = structElemType (LTYPE (tree),
2445 (tree->right->type == EX_VALUE ?
2446 tree->right->opval.val : NULL));
2447 TETYPE (tree) = getSpec (TTYPE (tree));
2450 /*------------------------------------------------------------------*/
2451 /*----------------------------*/
2452 /* struct/union pointer */
2453 /*----------------------------*/
2455 /* if not pointer to a structure */
2456 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2458 werror (E_PTR_REQD);
2459 goto errorTreeReturn;
2462 if (!IS_STRUCT (LTYPE (tree)->next))
2464 werror (E_STRUCT_UNION, "->");
2465 goto errorTreeReturn;
2468 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2469 (tree->right->type == EX_VALUE ?
2470 tree->right->opval.val : NULL));
2471 TETYPE (tree) = getSpec (TTYPE (tree));
2473 /* adjust the storage class */
2474 switch (DCL_TYPE(tree->left->ftype)) {
2476 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2479 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2482 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2485 SPEC_SCLS (TETYPE (tree)) = 0;
2488 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2491 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2494 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2497 SPEC_SCLS (TETYPE (tree)) = 0;
2504 /* This breaks with extern declarations, bitfields, and perhaps other */
2505 /* cases (gcse). Let's leave this optimization disabled for now and */
2506 /* ponder if there's a safe way to do this. -- EEP */
2508 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2509 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2511 /* If defined struct type at addr var
2512 then rewrite (&struct var)->member
2514 and define membertype at (addr+offsetof(struct var,member)) temp
2517 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2518 AST_SYMBOL(tree->right));
2520 sym = newSymbol(genSymName (0), 0);
2521 sym->type = TTYPE (tree);
2522 sym->etype = getSpec(sym->type);
2523 sym->lineDef = tree->lineno;
2526 SPEC_STAT (sym->etype) = 1;
2527 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2529 SPEC_ABSA(sym->etype) = 1;
2530 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2533 AST_VALUE (tree) = symbolVal(sym);
2536 tree->type = EX_VALUE;
2544 /*------------------------------------------------------------------*/
2545 /*----------------------------*/
2546 /* ++/-- operation */
2547 /*----------------------------*/
2551 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2552 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2553 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2554 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2563 /*------------------------------------------------------------------*/
2564 /*----------------------------*/
2566 /*----------------------------*/
2567 case '&': /* can be unary */
2568 /* if right is NULL then unary operation */
2569 if (tree->right) /* not an unary operation */
2572 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2574 werror (E_BITWISE_OP);
2575 werror (W_CONTINUE, "left & right types are ");
2576 printTypeChain (LTYPE (tree), stderr);
2577 fprintf (stderr, ",");
2578 printTypeChain (RTYPE (tree), stderr);
2579 fprintf (stderr, "\n");
2580 goto errorTreeReturn;
2583 /* if they are both literal */
2584 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2586 tree->type = EX_VALUE;
2587 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2588 valFromType (RETYPE (tree)), '&');
2590 tree->right = tree->left = NULL;
2591 TETYPE (tree) = tree->opval.val->etype;
2592 TTYPE (tree) = tree->opval.val->type;
2596 /* see if this is a GETHBIT operation if yes
2599 ast *otree = optimizeGetHbit (tree);
2602 return decorateType (otree, RESULT_TYPE_NONE);
2605 /* if left is a literal exchange left & right */
2606 if (IS_LITERAL (LTYPE (tree)))
2608 ast *tTree = tree->left;
2609 tree->left = tree->right;
2610 tree->right = tTree;
2613 /* if right is a literal and */
2614 /* we can find a 2nd literal in an and-tree then */
2615 /* rearrange the tree */
2616 if (IS_LITERAL (RTYPE (tree)))
2619 ast *litTree = searchLitOp (tree, &parent, "&");
2623 ast *tTree = litTree->left;
2624 litTree->left = tree->right;
2625 tree->right = tTree;
2626 /* both operands in litTree are literal now */
2627 decorateType (parent, resultType);
2631 LRVAL (tree) = RRVAL (tree) = 1;
2633 TTYPE (tree) = computeType (LTYPE (tree),
2637 TETYPE (tree) = getSpec (TTYPE (tree));
2642 /*------------------------------------------------------------------*/
2643 /*----------------------------*/
2645 /*----------------------------*/
2646 p = newLink (DECLARATOR);
2647 /* if bit field then error */
2648 if (IS_BITVAR (tree->left->etype))
2650 werror (E_ILLEGAL_ADDR, "address of bit variable");
2651 goto errorTreeReturn;
2654 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2656 werror (E_ILLEGAL_ADDR, "address of register variable");
2657 goto errorTreeReturn;
2660 if (IS_FUNC (LTYPE (tree)))
2662 // this ought to be ignored
2663 return (tree->left);
2666 if (IS_LITERAL(LTYPE(tree)))
2668 werror (E_ILLEGAL_ADDR, "address of literal");
2669 goto errorTreeReturn;
2674 werror (E_LVALUE_REQUIRED, "address of");
2675 goto errorTreeReturn;
2678 DCL_TYPE (p) = POINTER;
2679 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2680 DCL_TYPE (p) = CPOINTER;
2681 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2682 DCL_TYPE (p) = FPOINTER;
2683 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2684 DCL_TYPE (p) = PPOINTER;
2685 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2686 DCL_TYPE (p) = IPOINTER;
2687 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2688 DCL_TYPE (p) = EEPPOINTER;
2689 else if (SPEC_OCLS(tree->left->etype))
2690 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2692 DCL_TYPE (p) = POINTER;
2694 if (IS_AST_SYM_VALUE (tree->left))
2696 AST_SYMBOL (tree->left)->addrtaken = 1;
2697 AST_SYMBOL (tree->left)->allocreq = 1;
2700 p->next = LTYPE (tree);
2702 TETYPE (tree) = getSpec (TTYPE (tree));
2707 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2708 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2710 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2711 AST_SYMBOL(tree->left->right));
2712 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2713 valueFromLit(element->offset));
2716 tree->type = EX_VALUE;
2717 tree->values.literalFromCast = 1;
2723 /*------------------------------------------------------------------*/
2724 /*----------------------------*/
2726 /*----------------------------*/
2728 /* if the rewrite succeeds then don't go any furthur */
2730 ast *wtree = optimizeRRCRLC (tree);
2732 return decorateType (wtree, RESULT_TYPE_NONE);
2734 wtree = optimizeSWAP (tree);
2736 return decorateType (wtree, RESULT_TYPE_NONE);
2739 /* if left is a literal exchange left & right */
2740 if (IS_LITERAL (LTYPE (tree)))
2742 ast *tTree = tree->left;
2743 tree->left = tree->right;
2744 tree->right = tTree;
2747 /* if right is a literal and */
2748 /* we can find a 2nd literal in an or-tree then */
2749 /* rearrange the tree */
2750 if (IS_LITERAL (RTYPE (tree)))
2753 ast *litTree = searchLitOp (tree, &parent, "|");
2757 ast *tTree = litTree->left;
2758 litTree->left = tree->right;
2759 tree->right = tTree;
2760 /* both operands in tTree are literal now */
2761 decorateType (parent, resultType);
2766 /*------------------------------------------------------------------*/
2767 /*----------------------------*/
2769 /*----------------------------*/
2771 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2773 werror (E_BITWISE_OP);
2774 werror (W_CONTINUE, "left & right types are ");
2775 printTypeChain (LTYPE (tree), stderr);
2776 fprintf (stderr, ",");
2777 printTypeChain (RTYPE (tree), stderr);
2778 fprintf (stderr, "\n");
2779 goto errorTreeReturn;
2782 /* if they are both literal then rewrite the tree */
2783 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2785 tree->type = EX_VALUE;
2786 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2787 valFromType (RETYPE (tree)),
2789 tree->right = tree->left = NULL;
2790 TETYPE (tree) = tree->opval.val->etype;
2791 TTYPE (tree) = tree->opval.val->type;
2795 /* if left is a literal exchange left & right */
2796 if (IS_LITERAL (LTYPE (tree)))
2798 ast *tTree = tree->left;
2799 tree->left = tree->right;
2800 tree->right = tTree;
2803 /* if right is a literal and */
2804 /* we can find a 2nd literal in a xor-tree then */
2805 /* rearrange the tree */
2806 if (IS_LITERAL (RTYPE (tree)) &&
2807 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2810 ast *litTree = searchLitOp (tree, &parent, "^");
2814 ast *tTree = litTree->left;
2815 litTree->left = tree->right;
2816 tree->right = tTree;
2817 /* both operands in litTree are literal now */
2818 decorateType (parent, resultType);
2822 LRVAL (tree) = RRVAL (tree) = 1;
2824 TTYPE (tree) = computeType (LTYPE (tree),
2828 TETYPE (tree) = getSpec (TTYPE (tree));
2832 /*------------------------------------------------------------------*/
2833 /*----------------------------*/
2835 /*----------------------------*/
2837 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2839 werror (E_INVALID_OP, "divide");
2840 goto errorTreeReturn;
2842 /* if they are both literal then */
2843 /* rewrite the tree */
2844 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2846 tree->type = EX_VALUE;
2847 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2848 valFromType (RETYPE (tree)));
2849 tree->right = tree->left = NULL;
2850 TETYPE (tree) = getSpec (TTYPE (tree) =
2851 tree->opval.val->type);
2855 LRVAL (tree) = RRVAL (tree) = 1;
2857 TETYPE (tree) = getSpec (TTYPE (tree) =
2858 computeType (LTYPE (tree),
2863 /* if right is a literal and */
2864 /* left is also a division by a literal then */
2865 /* rearrange the tree */
2866 if (IS_LITERAL (RTYPE (tree))
2867 /* avoid infinite loop */
2868 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2871 ast *litTree = searchLitOp (tree, &parent, "/");
2874 if (IS_LITERAL (RTYPE (litTree)))
2878 litTree->right = newNode ('*',
2880 copyAst (tree->right));
2881 litTree->right->lineno = tree->lineno;
2883 tree->right->opval.val = constVal ("1");
2884 decorateType (parent, resultType);
2888 /* litTree->left is literal: no gcse possible.
2889 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2890 this would cause an infinit loop. */
2891 parent->decorated = 1;
2892 decorateType (litTree, resultType);
2899 /*------------------------------------------------------------------*/
2900 /*----------------------------*/
2902 /*----------------------------*/
2904 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2906 werror (E_BITWISE_OP);
2907 werror (W_CONTINUE, "left & right types are ");
2908 printTypeChain (LTYPE (tree), stderr);
2909 fprintf (stderr, ",");
2910 printTypeChain (RTYPE (tree), stderr);
2911 fprintf (stderr, "\n");
2912 goto errorTreeReturn;
2914 /* if they are both literal then */
2915 /* rewrite the tree */
2916 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2918 tree->type = EX_VALUE;
2919 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2920 valFromType (RETYPE (tree)));
2921 tree->right = tree->left = NULL;
2922 TETYPE (tree) = getSpec (TTYPE (tree) =
2923 tree->opval.val->type);
2926 LRVAL (tree) = RRVAL (tree) = 1;
2927 TETYPE (tree) = getSpec (TTYPE (tree) =
2928 computeType (LTYPE (tree),
2934 /*------------------------------------------------------------------*/
2935 /*----------------------------*/
2936 /* address dereference */
2937 /*----------------------------*/
2938 case '*': /* can be unary : if right is null then unary operation */
2941 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2943 werror (E_PTR_REQD);
2944 goto errorTreeReturn;
2949 werror (E_LVALUE_REQUIRED, "pointer deref");
2950 goto errorTreeReturn;
2952 if (IS_ADDRESS_OF_OP(tree->left))
2954 /* replace *&obj with obj */
2955 return tree->left->left;
2957 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2958 TETYPE (tree) = getSpec (TTYPE (tree));
2959 /* adjust the storage class */
2960 switch (DCL_TYPE(tree->left->ftype)) {
2962 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2965 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2968 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2971 SPEC_SCLS (TETYPE (tree)) = 0;
2974 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2977 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2980 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2983 SPEC_SCLS (TETYPE (tree)) = 0;
2992 /*------------------------------------------------------------------*/
2993 /*----------------------------*/
2994 /* multiplication */
2995 /*----------------------------*/
2996 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2998 werror (E_INVALID_OP, "multiplication");
2999 goto errorTreeReturn;
3002 /* if they are both literal then */
3003 /* rewrite the tree */
3004 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3006 tree->type = EX_VALUE;
3007 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3008 valFromType (RETYPE (tree)));
3009 tree->right = tree->left = NULL;
3010 TETYPE (tree) = getSpec (TTYPE (tree) =
3011 tree->opval.val->type);
3015 /* if left is a literal exchange left & right */
3016 if (IS_LITERAL (LTYPE (tree)))
3018 ast *tTree = tree->left;
3019 tree->left = tree->right;
3020 tree->right = tTree;
3023 /* if right is a literal and */
3024 /* we can find a 2nd literal in a mul-tree then */
3025 /* rearrange the tree */
3026 if (IS_LITERAL (RTYPE (tree)))
3029 ast *litTree = searchLitOp (tree, &parent, "*");
3033 ast *tTree = litTree->left;
3034 litTree->left = tree->right;
3035 tree->right = tTree;
3036 /* both operands in litTree are literal now */
3037 decorateType (parent, resultType);
3041 LRVAL (tree) = RRVAL (tree) = 1;
3042 tree->left = addCast (tree->left, resultType, FALSE);
3043 tree->right = addCast (tree->right, resultType, FALSE);
3044 TETYPE (tree) = getSpec (TTYPE (tree) =
3045 computeType (LTYPE (tree),
3052 /*------------------------------------------------------------------*/
3053 /*----------------------------*/
3054 /* unary '+' operator */
3055 /*----------------------------*/
3060 if (!IS_ARITHMETIC (LTYPE (tree)))
3062 werror (E_UNARY_OP, '+');
3063 goto errorTreeReturn;
3066 /* if left is a literal then do it */
3067 if (IS_LITERAL (LTYPE (tree)))
3069 tree->type = EX_VALUE;
3070 tree->opval.val = valFromType (LETYPE (tree));
3072 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3076 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3083 /*----------------------------*/
3085 /* this is not a unary operation */
3086 /* if both pointers then problem */
3087 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3088 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3090 werror (E_PTR_PLUS_PTR);
3091 goto errorTreeReturn;
3094 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3095 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3097 werror (E_PLUS_INVALID, "+");
3098 goto errorTreeReturn;
3101 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3102 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3104 werror (E_PLUS_INVALID, "+");
3105 goto errorTreeReturn;
3107 /* if they are both literal then */
3108 /* rewrite the tree */
3109 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3111 tree->type = EX_VALUE;
3112 tree->left = addCast (tree->left, resultType, TRUE);
3113 tree->right = addCast (tree->right, resultType, TRUE);
3114 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3115 valFromType (RETYPE (tree)));
3116 tree->right = tree->left = NULL;
3117 TETYPE (tree) = getSpec (TTYPE (tree) =
3118 tree->opval.val->type);
3122 /* if the right is a pointer or left is a literal
3123 xchange left & right */
3124 if (IS_ARRAY (RTYPE (tree)) ||
3125 IS_PTR (RTYPE (tree)) ||
3126 IS_LITERAL (LTYPE (tree)))
3128 ast *tTree = tree->left;
3129 tree->left = tree->right;
3130 tree->right = tTree;
3133 /* if right is a literal and */
3134 /* left is also an addition/subtraction with a literal then */
3135 /* rearrange the tree */
3136 if (IS_LITERAL (RTYPE (tree)))
3138 ast *litTree, *parent;
3139 litTree = searchLitOp (tree, &parent, "+-");
3142 if (litTree->opval.op == '+')
3146 ast *tTree = litTree->left;
3147 litTree->left = tree->right;
3148 tree->right = tree->left;
3151 else if (litTree->opval.op == '-')
3153 if (IS_LITERAL (RTYPE (litTree)))
3157 ast *tTree = litTree->left;
3158 litTree->left = tree->right;
3159 tree->right = tTree;
3165 ast *tTree = litTree->right;
3166 litTree->right = tree->right;
3167 tree->right = tTree;
3168 litTree->opval.op = '+';
3169 tree->opval.op = '-';
3172 decorateType (parent, resultType);
3176 LRVAL (tree) = RRVAL (tree) = 1;
3177 /* if the left is a pointer */
3178 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3179 TETYPE (tree) = getSpec (TTYPE (tree) =
3183 tree->left = addCast (tree->left, resultType, TRUE);
3184 tree->right = addCast (tree->right, resultType, TRUE);
3185 TETYPE (tree) = getSpec (TTYPE (tree) =
3186 computeType (LTYPE (tree),
3194 /*------------------------------------------------------------------*/
3195 /*----------------------------*/
3197 /*----------------------------*/
3198 case '-': /* can be unary */
3199 /* if right is null then unary */
3203 if (!IS_ARITHMETIC (LTYPE (tree)))
3205 werror (E_UNARY_OP, tree->opval.op);
3206 goto errorTreeReturn;
3209 /* if left is a literal then do it */
3210 if (IS_LITERAL (LTYPE (tree)))
3212 tree->type = EX_VALUE;
3213 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3215 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3216 SPEC_USIGN(TETYPE(tree)) = 0;
3220 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3224 /*------------------------------------------------------------------*/
3225 /*----------------------------*/
3227 /*----------------------------*/
3229 if (!(IS_PTR (LTYPE (tree)) ||
3230 IS_ARRAY (LTYPE (tree)) ||
3231 IS_ARITHMETIC (LTYPE (tree))))
3233 werror (E_PLUS_INVALID, "-");
3234 goto errorTreeReturn;
3237 if (!(IS_PTR (RTYPE (tree)) ||
3238 IS_ARRAY (RTYPE (tree)) ||
3239 IS_ARITHMETIC (RTYPE (tree))))
3241 werror (E_PLUS_INVALID, "-");
3242 goto errorTreeReturn;
3245 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3246 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3247 IS_INTEGRAL (RTYPE (tree))))
3249 werror (E_PLUS_INVALID, "-");
3250 goto errorTreeReturn;
3253 /* if they are both literal then */
3254 /* rewrite the tree */
3255 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3257 tree->type = EX_VALUE;
3258 tree->left = addCast (tree->left, resultType, TRUE);
3259 tree->right = addCast (tree->right, resultType, TRUE);
3260 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3261 valFromType (RETYPE (tree)));
3262 tree->right = tree->left = NULL;
3263 TETYPE (tree) = getSpec (TTYPE (tree) =
3264 tree->opval.val->type);
3268 /* if the left & right are equal then zero */
3269 if (isAstEqual (tree->left, tree->right))
3271 tree->type = EX_VALUE;
3272 tree->left = tree->right = NULL;
3273 tree->opval.val = constVal ("0");
3274 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3278 /* if both of them are pointers or arrays then */
3279 /* the result is going to be an integer */
3280 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3281 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3282 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3284 /* if only the left is a pointer */
3285 /* then result is a pointer */
3286 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3287 TETYPE (tree) = getSpec (TTYPE (tree) =
3291 tree->left = addCast (tree->left, resultType, TRUE);
3292 tree->right = addCast (tree->right, resultType, TRUE);
3294 TETYPE (tree) = getSpec (TTYPE (tree) =
3295 computeType (LTYPE (tree),
3301 LRVAL (tree) = RRVAL (tree) = 1;
3303 /* if right is a literal and */
3304 /* left is also an addition/subtraction with a literal then */
3305 /* rearrange the tree */
3306 if (IS_LITERAL (RTYPE (tree))
3307 /* avoid infinite loop */
3308 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3310 ast *litTree, *litParent;
3311 litTree = searchLitOp (tree, &litParent, "+-");
3314 if (litTree->opval.op == '+')
3318 ast *tTree = litTree->left;
3319 litTree->left = litTree->right;
3320 litTree->right = tree->right;
3321 tree->right = tTree;
3322 tree->opval.op = '+';
3323 litTree->opval.op = '-';
3325 else if (litTree->opval.op == '-')
3327 if (IS_LITERAL (RTYPE (litTree)))
3331 ast *tTree = litTree->left;
3332 litTree->left = tree->right;
3333 tree->right = litParent->left;
3334 litParent->left = tTree;
3335 litTree->opval.op = '+';
3337 tree->decorated = 0;
3338 decorateType (tree, resultType);
3344 ast *tTree = litTree->right;
3345 litTree->right = tree->right;
3346 tree->right = tTree;
3349 decorateType (litParent, resultType);
3354 /*------------------------------------------------------------------*/
3355 /*----------------------------*/
3357 /*----------------------------*/
3359 /* can be only integral type */
3360 if (!IS_INTEGRAL (LTYPE (tree)))
3362 werror (E_UNARY_OP, tree->opval.op);
3363 goto errorTreeReturn;
3366 /* if left is a literal then do it */
3367 if (IS_LITERAL (LTYPE (tree)))
3369 tree->type = EX_VALUE;
3370 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3372 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3373 return addCast (tree, resultType, TRUE);
3375 tree->left = addCast (tree->left, resultType, TRUE);
3377 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3380 /*------------------------------------------------------------------*/
3381 /*----------------------------*/
3383 /*----------------------------*/
3385 /* can be pointer */
3386 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3387 !IS_PTR (LTYPE (tree)) &&
3388 !IS_ARRAY (LTYPE (tree)))
3390 werror (E_UNARY_OP, tree->opval.op);
3391 goto errorTreeReturn;
3394 /* if left is a literal then do it */
3395 if (IS_LITERAL (LTYPE (tree)))
3397 tree->type = EX_VALUE;
3398 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3400 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3404 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3407 /*------------------------------------------------------------------*/
3408 /*----------------------------*/
3410 /*----------------------------*/
3414 TTYPE (tree) = LTYPE (tree);
3415 TETYPE (tree) = LETYPE (tree);
3419 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3424 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3426 werror (E_SHIFT_OP_INVALID);
3427 werror (W_CONTINUE, "left & right types are ");
3428 printTypeChain (LTYPE (tree), stderr);
3429 fprintf (stderr, ",");
3430 printTypeChain (RTYPE (tree), stderr);
3431 fprintf (stderr, "\n");
3432 goto errorTreeReturn;
3435 /* make smaller type only if it's a LEFT_OP */
3436 if (tree->opval.op == LEFT_OP)
3437 tree->left = addCast (tree->left, resultType, TRUE);
3439 /* if they are both literal then */
3440 /* rewrite the tree */
3441 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3443 tree->type = EX_VALUE;
3444 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3445 valFromType (RETYPE (tree)),
3446 (tree->opval.op == LEFT_OP ? 1 : 0));
3447 tree->right = tree->left = NULL;
3448 TETYPE (tree) = getSpec (TTYPE (tree) =
3449 tree->opval.val->type);
3453 LRVAL (tree) = RRVAL (tree) = 1;
3454 if (tree->opval.op == LEFT_OP)
3456 TETYPE (tree) = getSpec (TTYPE (tree) =
3457 computeType (LTYPE (tree),
3464 /* no promotion necessary */
3465 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3466 if (IS_LITERAL (TTYPE (tree)))
3467 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3470 /* if only the right side is a literal & we are
3471 shifting more than size of the left operand then zero */
3472 if (IS_LITERAL (RTYPE (tree)) &&
3473 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3474 (getSize (TETYPE (tree)) * 8))
3476 if (tree->opval.op==LEFT_OP ||
3477 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3479 lineno=tree->lineno;
3480 werror (W_SHIFT_CHANGED,
3481 (tree->opval.op == LEFT_OP ? "left" : "right"));
3482 tree->type = EX_VALUE;
3483 tree->left = tree->right = NULL;
3484 tree->opval.val = constVal ("0");
3485 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3492 /*------------------------------------------------------------------*/
3493 /*----------------------------*/
3495 /*----------------------------*/
3496 case CAST: /* change the type */
3497 /* cannot cast to an aggregate type */
3498 if (IS_AGGREGATE (LTYPE (tree)))
3500 werror (E_CAST_ILLEGAL);
3501 goto errorTreeReturn;
3504 /* make sure the type is complete and sane */
3505 changePointer(LTYPE(tree));
3506 checkTypeSanity(LETYPE(tree), "(cast)");
3508 /* If code memory is read only, then pointers to code memory */
3509 /* implicitly point to constants -- make this explicit */
3511 sym_link *t = LTYPE(tree);
3512 while (t && t->next)
3514 if (IS_CODEPTR(t) && port->mem.code_ro)
3516 if (IS_SPEC(t->next))
3517 SPEC_CONST (t->next) = 1;
3519 DCL_PTR_CONST (t->next) = 1;
3526 /* if the right is a literal replace the tree */
3527 if (IS_LITERAL (RETYPE (tree))) {
3528 if (!IS_PTR (LTYPE (tree))) {
3529 tree->type = EX_VALUE;
3531 valCastLiteral (LTYPE (tree),
3532 floatFromVal (valFromType (RETYPE (tree))));
3535 TTYPE (tree) = tree->opval.val->type;
3536 tree->values.literalFromCast = 1;
3537 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3538 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3539 sym_link *rest = LTYPE(tree)->next;
3540 werror(W_LITERAL_GENERIC);
3541 TTYPE(tree) = newLink(DECLARATOR);
3542 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3543 TTYPE(tree)->next = rest;
3544 tree->left->opval.lnk = TTYPE(tree);
3547 TTYPE (tree) = LTYPE (tree);
3551 TTYPE (tree) = LTYPE (tree);
3555 #if 0 // this is already checked, now this could be explicit
3556 /* if pointer to struct then check names */
3557 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3558 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3559 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3561 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3562 SPEC_STRUCT(LETYPE(tree))->tag);
3565 if (IS_ADDRESS_OF_OP(tree->right)
3566 && IS_AST_SYM_VALUE (tree->right->left)
3567 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3569 tree->type = EX_VALUE;
3571 valCastLiteral (LTYPE (tree),
3572 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3573 TTYPE (tree) = tree->opval.val->type;
3574 TETYPE (tree) = getSpec (TTYPE (tree));
3577 tree->values.literalFromCast = 1;
3581 /* handle offsetof macro: */
3582 /* #define offsetof(TYPE, MEMBER) \ */
3583 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3584 if (IS_ADDRESS_OF_OP(tree->right)
3585 && IS_AST_OP (tree->right->left)
3586 && tree->right->left->opval.op == PTR_OP
3587 && IS_AST_OP (tree->right->left->left)
3588 && tree->right->left->left->opval.op == CAST
3589 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3591 symbol *element = getStructElement (
3592 SPEC_STRUCT (LETYPE(tree->right->left)),
3593 AST_SYMBOL(tree->right->left->right)
3597 tree->type = EX_VALUE;
3598 tree->opval.val = valCastLiteral (
3601 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3604 TTYPE (tree) = tree->opval.val->type;
3605 TETYPE (tree) = getSpec (TTYPE (tree));
3612 /* if the right is a literal replace the tree */
3613 if (IS_LITERAL (RETYPE (tree))) {
3615 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3616 /* rewrite (type *)litaddr
3618 and define type at litaddr temp
3619 (but only if type's storage class is not generic)
3621 ast *newTree = newNode ('&', NULL, NULL);
3624 TTYPE (newTree) = LTYPE (tree);
3625 TETYPE (newTree) = getSpec(LTYPE (tree));
3627 /* define a global symbol at the casted address*/
3628 sym = newSymbol(genSymName (0), 0);
3629 sym->type = LTYPE (tree)->next;
3631 sym->type = newLink (V_VOID);
3632 sym->etype = getSpec(sym->type);
3633 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3634 sym->lineDef = tree->lineno;
3637 SPEC_STAT (sym->etype) = 1;
3638 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3639 SPEC_ABSA(sym->etype) = 1;
3640 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3643 newTree->left = newAst_VALUE(symbolVal(sym));
3644 newTree->left->lineno = tree->lineno;
3645 LTYPE (newTree) = sym->type;
3646 LETYPE (newTree) = sym->etype;
3647 LLVAL (newTree) = 1;
3648 LRVAL (newTree) = 0;
3649 TLVAL (newTree) = 1;
3653 if (!IS_PTR (LTYPE (tree))) {
3654 tree->type = EX_VALUE;
3656 valCastLiteral (LTYPE (tree),
3657 floatFromVal (valFromType (RTYPE (tree))));
3658 TTYPE (tree) = tree->opval.val->type;
3661 tree->values.literalFromCast = 1;
3662 TETYPE (tree) = getSpec (TTYPE (tree));
3666 TTYPE (tree) = LTYPE (tree);
3670 TETYPE (tree) = getSpec (TTYPE (tree));
3674 /*------------------------------------------------------------------*/
3675 /*----------------------------*/
3676 /* logical &&, || */
3677 /*----------------------------*/
3680 /* each must be arithmetic type or be a pointer */
3681 if (!IS_PTR (LTYPE (tree)) &&
3682 !IS_ARRAY (LTYPE (tree)) &&
3683 !IS_INTEGRAL (LTYPE (tree)))
3685 werror (E_COMPARE_OP);
3686 goto errorTreeReturn;
3689 if (!IS_PTR (RTYPE (tree)) &&
3690 !IS_ARRAY (RTYPE (tree)) &&
3691 !IS_INTEGRAL (RTYPE (tree)))
3693 werror (E_COMPARE_OP);
3694 goto errorTreeReturn;
3696 /* if they are both literal then */
3697 /* rewrite the tree */
3698 if (IS_LITERAL (RTYPE (tree)) &&
3699 IS_LITERAL (LTYPE (tree)))
3701 tree->type = EX_VALUE;
3702 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3703 valFromType (RTYPE (tree)),
3705 tree->right = tree->left = NULL;
3706 TETYPE (tree) = getSpec (TTYPE (tree) =
3707 tree->opval.val->type);
3710 LRVAL (tree) = RRVAL (tree) = 1;
3711 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3714 /*------------------------------------------------------------------*/
3715 /*----------------------------*/
3716 /* comparison operators */
3717 /*----------------------------*/
3725 ast *lt = optimizeCompare (tree);
3731 /* if they are pointers they must be castable */
3732 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3734 if (tree->opval.op==EQ_OP &&
3735 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3736 // we cannot cast a gptr to a !gptr: switch the leaves
3737 struct ast *s=tree->left;
3738 tree->left=tree->right;
3741 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3743 werror (E_COMPARE_OP);
3744 fprintf (stderr, "comparing type ");
3745 printTypeChain (LTYPE (tree), stderr);
3746 fprintf (stderr, "to type ");
3747 printTypeChain (RTYPE (tree), stderr);
3748 fprintf (stderr, "\n");
3749 goto errorTreeReturn;
3752 /* else they should be promotable to one another */
3755 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3756 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3758 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3760 werror (E_COMPARE_OP);
3761 fprintf (stderr, "comparing type ");
3762 printTypeChain (LTYPE (tree), stderr);
3763 fprintf (stderr, "to type ");
3764 printTypeChain (RTYPE (tree), stderr);
3765 fprintf (stderr, "\n");
3766 goto errorTreeReturn;
3769 /* if unsigned value < 0 then always false */
3770 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3771 if (SPEC_USIGN(LETYPE(tree)) &&
3772 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3773 IS_LITERAL(RTYPE(tree)) &&
3774 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3776 if (tree->opval.op == '<')
3780 if (tree->opval.op == '>')
3782 if (resultType == RESULT_TYPE_IFX)
3784 /* the parent is an ifx: */
3785 /* if (unsigned value) */
3789 /* (unsigned value) ? 1 : 0 */
3790 tree->opval.op = '?';
3791 tree->right = newNode (':',
3792 newAst_VALUE (constVal ("1")),
3793 tree->right); /* val 0 */
3794 tree->right->lineno = tree->lineno;
3795 tree->right->left->lineno = tree->lineno;
3796 decorateType (tree->right, RESULT_TYPE_NONE);
3799 /* if they are both literal then */
3800 /* rewrite the tree */
3801 if (IS_LITERAL (RTYPE (tree)) &&
3802 IS_LITERAL (LTYPE (tree)))
3804 tree->type = EX_VALUE;
3805 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3806 valFromType (RETYPE (tree)),
3808 tree->right = tree->left = NULL;
3809 TETYPE (tree) = getSpec (TTYPE (tree) =
3810 tree->opval.val->type);
3813 LRVAL (tree) = RRVAL (tree) = 1;
3814 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3817 /*------------------------------------------------------------------*/
3818 /*----------------------------*/
3820 /*----------------------------*/
3821 case SIZEOF: /* evaluate wihout code generation */
3822 /* change the type to a integer */
3824 int size = getSize (tree->right->ftype);
3825 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3826 if (!size && !IS_VOID(tree->right->ftype))
3827 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3829 tree->type = EX_VALUE;
3830 tree->opval.val = constVal (buffer);
3831 tree->right = tree->left = NULL;
3832 TETYPE (tree) = getSpec (TTYPE (tree) =
3833 tree->opval.val->type);
3836 /*------------------------------------------------------------------*/
3837 /*----------------------------*/
3839 /*----------------------------*/
3841 /* return typeof enum value */
3842 tree->type = EX_VALUE;
3845 if (IS_SPEC(tree->right->ftype)) {
3846 switch (SPEC_NOUN(tree->right->ftype)) {
3848 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3849 else typeofv = TYPEOF_INT;
3852 typeofv = TYPEOF_FLOAT;
3855 typeofv = TYPEOF_CHAR;
3858 typeofv = TYPEOF_VOID;
3861 typeofv = TYPEOF_STRUCT;
3864 typeofv = TYPEOF_BITFIELD;
3867 typeofv = TYPEOF_BIT;
3870 typeofv = TYPEOF_SBIT;
3876 switch (DCL_TYPE(tree->right->ftype)) {
3878 typeofv = TYPEOF_POINTER;
3881 typeofv = TYPEOF_FPOINTER;
3884 typeofv = TYPEOF_CPOINTER;
3887 typeofv = TYPEOF_GPOINTER;
3890 typeofv = TYPEOF_PPOINTER;
3893 typeofv = TYPEOF_IPOINTER;
3896 typeofv = TYPEOF_ARRAY;
3899 typeofv = TYPEOF_FUNCTION;
3905 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3906 tree->opval.val = constVal (buffer);
3907 tree->right = tree->left = NULL;
3908 TETYPE (tree) = getSpec (TTYPE (tree) =
3909 tree->opval.val->type);
3912 /*------------------------------------------------------------------*/
3913 /*----------------------------*/
3914 /* conditional operator '?' */
3915 /*----------------------------*/
3917 /* the type is value of the colon operator (on the right) */
3918 assert (IS_COLON_OP (tree->right));
3919 /* if already known then replace the tree : optimizer will do it
3920 but faster to do it here */
3921 if (IS_LITERAL (LTYPE (tree)))
3923 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3924 return decorateType (tree->right->left, resultTypeProp);
3926 return decorateType (tree->right->right, resultTypeProp);
3930 tree->right = decorateType (tree->right, resultTypeProp);
3931 TTYPE (tree) = RTYPE (tree);
3932 TETYPE (tree) = getSpec (TTYPE (tree));
3937 /* if they don't match we have a problem */
3938 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
3939 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
3941 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3942 goto errorTreeReturn;
3945 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3946 resultType, tree->opval.op);
3947 TETYPE (tree) = getSpec (TTYPE (tree));
3951 #if 0 // assignment operators are converted by the parser
3952 /*------------------------------------------------------------------*/
3953 /*----------------------------*/
3954 /* assignment operators */
3955 /*----------------------------*/
3958 /* for these it must be both must be integral */
3959 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3960 !IS_ARITHMETIC (RTYPE (tree)))
3962 werror (E_OPS_INTEGRAL);
3963 goto errorTreeReturn;
3966 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3968 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3969 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3973 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3974 goto errorTreeReturn;
3985 /* for these it must be both must be integral */
3986 if (!IS_INTEGRAL (LTYPE (tree)) ||
3987 !IS_INTEGRAL (RTYPE (tree)))
3989 werror (E_OPS_INTEGRAL);
3990 goto errorTreeReturn;
3993 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3995 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3996 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4000 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4001 goto errorTreeReturn;
4007 /*------------------------------------------------------------------*/
4008 /*----------------------------*/
4010 /*----------------------------*/
4012 if (!(IS_PTR (LTYPE (tree)) ||
4013 IS_ARITHMETIC (LTYPE (tree))))
4015 werror (E_PLUS_INVALID, "-=");
4016 goto errorTreeReturn;
4019 if (!(IS_PTR (RTYPE (tree)) ||
4020 IS_ARITHMETIC (RTYPE (tree))))
4022 werror (E_PLUS_INVALID, "-=");
4023 goto errorTreeReturn;
4026 TETYPE (tree) = getSpec (TTYPE (tree) =
4027 computeType (LTYPE (tree),
4032 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4033 werror (E_CODE_WRITE, "-=");
4037 werror (E_LVALUE_REQUIRED, "-=");
4038 goto errorTreeReturn;
4044 /*------------------------------------------------------------------*/
4045 /*----------------------------*/
4047 /*----------------------------*/
4049 /* this is not a unary operation */
4050 /* if both pointers then problem */
4051 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4053 werror (E_PTR_PLUS_PTR);
4054 goto errorTreeReturn;
4057 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4059 werror (E_PLUS_INVALID, "+=");
4060 goto errorTreeReturn;
4063 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4065 werror (E_PLUS_INVALID, "+=");
4066 goto errorTreeReturn;
4069 TETYPE (tree) = getSpec (TTYPE (tree) =
4070 computeType (LTYPE (tree),
4075 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4076 werror (E_CODE_WRITE, "+=");
4080 werror (E_LVALUE_REQUIRED, "+=");
4081 goto errorTreeReturn;
4084 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4085 tree->opval.op = '=';
4090 /*------------------------------------------------------------------*/
4091 /*----------------------------*/
4092 /* straight assignemnt */
4093 /*----------------------------*/
4095 /* cannot be an aggregate */
4096 if (IS_AGGREGATE (LTYPE (tree)))
4098 werror (E_AGGR_ASSIGN);
4099 goto errorTreeReturn;
4102 /* they should either match or be castable */
4103 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4105 werror (E_TYPE_MISMATCH, "assignment", " ");
4106 printFromToType(RTYPE(tree),LTYPE(tree));
4109 /* if the left side of the tree is of type void
4110 then report error */
4111 if (IS_VOID (LTYPE (tree)))
4113 werror (E_CAST_ZERO);
4114 printFromToType(RTYPE(tree), LTYPE(tree));
4117 TETYPE (tree) = getSpec (TTYPE (tree) =
4121 if (!tree->initMode ) {
4122 if (IS_CONSTANT(LTYPE(tree)))
4123 werror (E_CODE_WRITE, "=");
4127 werror (E_LVALUE_REQUIRED, "=");
4128 goto errorTreeReturn;
4133 /*------------------------------------------------------------------*/
4134 /*----------------------------*/
4135 /* comma operator */
4136 /*----------------------------*/
4138 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4141 /*------------------------------------------------------------------*/
4142 /*----------------------------*/
4144 /*----------------------------*/
4147 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4148 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4150 if (tree->left->opval.op == '*' && !tree->left->right)
4151 tree->left = tree->left->left;
4154 /* require a function or pointer to function */
4155 if (!IS_FUNC (LTYPE (tree))
4156 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4158 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4159 goto errorTreeReturn;
4162 /* if there are parms, make sure that
4163 parms are decorate / process / reverse only once */
4165 !tree->right->decorated)
4170 if (IS_CODEPTR(LTYPE(tree)))
4171 functype = LTYPE (tree)->next;
4173 functype = LTYPE (tree);
4175 if (processParms (tree->left, FUNC_ARGS(functype),
4176 &tree->right, &parmNumber, TRUE))
4178 goto errorTreeReturn;
4181 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4182 !IFFUNC_ISBUILTIN(functype))
4184 reverseParms (tree->right);
4187 TTYPE (tree) = functype->next;
4188 TETYPE (tree) = getSpec (TTYPE (tree));
4192 /*------------------------------------------------------------------*/
4193 /*----------------------------*/
4194 /* return statement */
4195 /*----------------------------*/
4200 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4202 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4203 printFromToType (RTYPE(tree), currFunc->type->next);
4204 goto errorTreeReturn;
4207 if (IS_VOID (currFunc->type->next)
4209 !IS_VOID (RTYPE (tree)))
4211 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4212 goto errorTreeReturn;
4215 /* if there is going to be a casting required then add it */
4216 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4219 decorateType (newNode (CAST,
4220 newAst_LINK (copyLinkChain (currFunc->type->next)),
4230 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4232 werror (W_VOID_FUNC, currFunc->name);
4233 goto errorTreeReturn;
4236 TTYPE (tree) = TETYPE (tree) = NULL;
4239 /*------------------------------------------------------------------*/
4240 /*----------------------------*/
4241 /* switch statement */
4242 /*----------------------------*/
4244 /* the switch value must be an integer */
4245 if (!IS_INTEGRAL (LTYPE (tree)))
4247 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4248 goto errorTreeReturn;
4251 TTYPE (tree) = TETYPE (tree) = NULL;
4254 /*------------------------------------------------------------------*/
4255 /*----------------------------*/
4257 /*----------------------------*/
4259 tree->left = backPatchLabels (tree->left,
4262 TTYPE (tree) = TETYPE (tree) = NULL;
4265 /*------------------------------------------------------------------*/
4266 /*----------------------------*/
4268 /*----------------------------*/
4271 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4272 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4273 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4275 /* if the for loop is reversible then
4276 reverse it otherwise do what we normally
4282 if (isLoopReversible (tree, &sym, &init, &end))
4283 return reverseLoop (tree, sym, init, end);
4285 return decorateType (createFor (AST_FOR (tree, trueLabel),
4286 AST_FOR (tree, continueLabel),
4287 AST_FOR (tree, falseLabel),
4288 AST_FOR (tree, condLabel),
4289 AST_FOR (tree, initExpr),
4290 AST_FOR (tree, condExpr),
4291 AST_FOR (tree, loopExpr),
4292 tree->left), RESULT_TYPE_NONE);
4295 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4296 "node PARAM shouldn't be processed here");
4297 /* but in processParams() */
4300 TTYPE (tree) = TETYPE (tree) = NULL;
4304 /* some error found this tree will be killed */
4306 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4307 tree->opval.op = NULLOP;
4313 /*-----------------------------------------------------------------*/
4314 /* sizeofOp - processes size of operation */
4315 /*-----------------------------------------------------------------*/
4317 sizeofOp (sym_link * type)
4322 /* make sure the type is complete and sane */
4323 checkTypeSanity(type, "(sizeof)");
4325 /* get the size and convert it to character */
4326 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4327 if (!size && !IS_VOID(type))
4328 werror (E_SIZEOF_INCOMPLETE_TYPE);
4330 /* now convert into value */
4331 return constVal (buff);
4335 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4336 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4337 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4338 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4339 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4340 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4341 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4343 /*-----------------------------------------------------------------*/
4344 /* backPatchLabels - change and or not operators to flow control */
4345 /*-----------------------------------------------------------------*/
4347 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4353 if (!(IS_ANDORNOT (tree)))
4356 /* if this an and */
4359 static int localLbl = 0;
4362 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4363 localLabel = newSymbol (buffer, NestLevel);
4365 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4367 /* if left is already a IFX then just change the if true label in that */
4368 if (!IS_IFX (tree->left))
4369 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4371 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4372 /* right is a IFX then just join */
4373 if (IS_IFX (tree->right))
4374 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4376 tree->right = createLabel (localLabel, tree->right);
4377 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4379 return newNode (NULLOP, tree->left, tree->right);
4382 /* if this is an or operation */
4385 static int localLbl = 0;
4388 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4389 localLabel = newSymbol (buffer, NestLevel);
4391 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4393 /* if left is already a IFX then just change the if true label in that */
4394 if (!IS_IFX (tree->left))
4395 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4397 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4398 /* right is a IFX then just join */
4399 if (IS_IFX (tree->right))
4400 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4402 tree->right = createLabel (localLabel, tree->right);
4403 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4405 return newNode (NULLOP, tree->left, tree->right);
4411 int wasnot = IS_NOT (tree->left);
4412 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4414 /* if the left is already a IFX */
4415 if (!IS_IFX (tree->left))
4416 tree->left = newNode (IFX, tree->left, NULL);
4420 tree->left->trueLabel = trueLabel;
4421 tree->left->falseLabel = falseLabel;
4425 tree->left->trueLabel = falseLabel;
4426 tree->left->falseLabel = trueLabel;
4433 tree->trueLabel = trueLabel;
4434 tree->falseLabel = falseLabel;
4441 /*-----------------------------------------------------------------*/
4442 /* createBlock - create expression tree for block */
4443 /*-----------------------------------------------------------------*/
4445 createBlock (symbol * decl, ast * body)
4449 /* if the block has nothing */
4453 ex = newNode (BLOCK, NULL, body);
4454 ex->values.sym = decl;
4461 /*-----------------------------------------------------------------*/
4462 /* createLabel - creates the expression tree for labels */
4463 /*-----------------------------------------------------------------*/
4465 createLabel (symbol * label, ast * stmnt)
4468 char name[SDCC_NAME_MAX + 1];
4471 /* must create fresh symbol if the symbol name */
4472 /* exists in the symbol table, since there can */
4473 /* be a variable with the same name as the labl */
4474 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4475 (csym->level == label->level))
4476 label = newSymbol (label->name, label->level);
4478 /* change the name before putting it in add _ */
4479 SNPRINTF(name, sizeof(name), "%s", label->name);
4481 /* put the label in the LabelSymbol table */
4482 /* but first check if a label of the same */
4484 if ((csym = findSym (LabelTab, NULL, name)))
4485 werror (E_DUPLICATE_LABEL, label->name);
4487 addSym (LabelTab, label, name, label->level, 0, 0);
4491 label->key = labelKey++;
4492 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4498 /*-----------------------------------------------------------------*/
4499 /* createCase - generates the parsetree for a case statement */
4500 /*-----------------------------------------------------------------*/
4502 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4504 char caseLbl[SDCC_NAME_MAX + 1];
4508 /* if the switch statement does not exist */
4509 /* then case is out of context */
4512 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4516 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4517 /* if not a constant then error */
4518 if (!IS_LITERAL (caseVal->ftype))
4520 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4524 /* if not a integer than error */
4525 if (!IS_INTEGRAL (caseVal->ftype))
4527 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4531 /* find the end of the switch values chain */
4532 if (!(val = swStat->values.switchVals.swVals))
4533 swStat->values.switchVals.swVals = caseVal->opval.val;
4536 /* also order the cases according to value */
4538 int cVal = (int) floatFromVal (caseVal->opval.val);
4539 while (val && (int) floatFromVal (val) < cVal)
4545 /* if we reached the end then */
4548 pval->next = caseVal->opval.val;
4550 else if ((int) floatFromVal (val) == cVal)
4552 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4558 /* we found a value greater than */
4559 /* the current value we must add this */
4560 /* before the value */
4561 caseVal->opval.val->next = val;
4563 /* if this was the first in chain */
4564 if (swStat->values.switchVals.swVals == val)
4565 swStat->values.switchVals.swVals =
4568 pval->next = caseVal->opval.val;
4573 /* create the case label */
4574 SNPRINTF(caseLbl, sizeof(caseLbl),
4576 swStat->values.switchVals.swNum,
4577 (int) floatFromVal (caseVal->opval.val));
4579 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4584 /*-----------------------------------------------------------------*/
4585 /* createDefault - creates the parse tree for the default statement */
4586 /*-----------------------------------------------------------------*/
4588 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4590 char defLbl[SDCC_NAME_MAX + 1];
4592 /* if the switch statement does not exist */
4593 /* then case is out of context */
4596 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4600 if (swStat->values.switchVals.swDefault)
4602 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4607 /* turn on the default flag */
4608 swStat->values.switchVals.swDefault = 1;
4610 /* create the label */
4611 SNPRINTF (defLbl, sizeof(defLbl),
4612 "_default_%d", swStat->values.switchVals.swNum);
4613 return createLabel (newSymbol (defLbl, 0), stmnt);
4616 /*-----------------------------------------------------------------*/
4617 /* createIf - creates the parsetree for the if statement */
4618 /*-----------------------------------------------------------------*/
4620 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4622 static int Lblnum = 0;
4624 symbol *ifTrue, *ifFalse, *ifEnd;
4626 /* if neither exists */
4627 if (!elseBody && !ifBody) {
4628 // if there are no side effects (i++, j() etc)
4629 if (!hasSEFcalls(condAst)) {
4634 /* create the labels */
4635 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4636 ifFalse = newSymbol (buffer, NestLevel);
4637 /* if no else body then end == false */
4642 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4643 ifEnd = newSymbol (buffer, NestLevel);
4646 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4647 ifTrue = newSymbol (buffer, NestLevel);
4651 /* attach the ifTrue label to the top of it body */
4652 ifBody = createLabel (ifTrue, ifBody);
4653 /* attach a goto end to the ifBody if else is present */
4656 ifBody = newNode (NULLOP, ifBody,
4658 newAst_VALUE (symbolVal (ifEnd)),
4660 /* put the elseLabel on the else body */
4661 elseBody = createLabel (ifFalse, elseBody);
4662 /* out the end at the end of the body */
4663 elseBody = newNode (NULLOP,
4665 createLabel (ifEnd, NULL));
4669 ifBody = newNode (NULLOP, ifBody,
4670 createLabel (ifFalse, NULL));
4672 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4673 if (IS_IFX (condAst))
4676 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4678 return newNode (NULLOP, ifTree,
4679 newNode (NULLOP, ifBody, elseBody));
4683 /*-----------------------------------------------------------------*/
4684 /* createDo - creates parse tree for do */
4687 /* _docontinue_n: */
4688 /* condition_expression +-> trueLabel -> _dobody_n */
4690 /* +-> falseLabel-> _dobreak_n */
4692 /*-----------------------------------------------------------------*/
4694 createDo (symbol * trueLabel, symbol * continueLabel,
4695 symbol * falseLabel, ast * condAst, ast * doBody)
4700 /* if the body does not exist then it is simple */
4703 condAst = backPatchLabels (condAst, continueLabel, NULL);
4704 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4705 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4706 doTree->trueLabel = continueLabel;
4707 doTree->falseLabel = NULL;
4711 /* otherwise we have a body */
4712 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4714 /* attach the body label to the top */
4715 doBody = createLabel (trueLabel, doBody);
4716 /* attach the continue label to end of body */
4717 doBody = newNode (NULLOP, doBody,
4718 createLabel (continueLabel, NULL));
4720 /* now put the break label at the end */
4721 if (IS_IFX (condAst))
4724 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4726 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4728 /* putting it together */
4729 return newNode (NULLOP, doBody, doTree);
4732 /*-----------------------------------------------------------------*/
4733 /* createFor - creates parse tree for 'for' statement */
4736 /* condExpr +-> trueLabel -> _forbody_n */
4738 /* +-> falseLabel-> _forbreak_n */
4741 /* _forcontinue_n: */
4743 /* goto _forcond_n ; */
4745 /*-----------------------------------------------------------------*/
4747 createFor (symbol * trueLabel, symbol * continueLabel,
4748 symbol * falseLabel, symbol * condLabel,
4749 ast * initExpr, ast * condExpr, ast * loopExpr,
4754 /* if loopexpression not present then we can generate it */
4755 /* the same way as a while */
4757 return newNode (NULLOP, initExpr,
4758 createWhile (trueLabel, continueLabel,
4759 falseLabel, condExpr, forBody));
4760 /* vanilla for statement */
4761 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4763 if (condExpr && !IS_IFX (condExpr))
4764 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4767 /* attach condition label to condition */
4768 condExpr = createLabel (condLabel, condExpr);
4770 /* attach body label to body */
4771 forBody = createLabel (trueLabel, forBody);
4773 /* attach continue to forLoop expression & attach */
4774 /* goto the forcond @ and of loopExpression */
4775 loopExpr = createLabel (continueLabel,
4779 newAst_VALUE (symbolVal (condLabel)),
4781 /* now start putting them together */
4782 forTree = newNode (NULLOP, initExpr, condExpr);
4783 forTree = newNode (NULLOP, forTree, forBody);
4784 forTree = newNode (NULLOP, forTree, loopExpr);
4785 /* finally add the break label */
4786 forTree = newNode (NULLOP, forTree,
4787 createLabel (falseLabel, NULL));
4791 /*-----------------------------------------------------------------*/
4792 /* createWhile - creates parse tree for while statement */
4793 /* the while statement will be created as follows */
4795 /* _while_continue_n: */
4796 /* condition_expression +-> trueLabel -> _while_boby_n */
4798 /* +-> falseLabel -> _while_break_n */
4799 /* _while_body_n: */
4801 /* goto _while_continue_n */
4802 /* _while_break_n: */
4803 /*-----------------------------------------------------------------*/
4805 createWhile (symbol * trueLabel, symbol * continueLabel,
4806 symbol * falseLabel, ast * condExpr, ast * whileBody)
4810 /* put the continue label */
4811 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4812 condExpr = createLabel (continueLabel, condExpr);
4813 condExpr->lineno = 0;
4815 /* put the body label in front of the body */
4816 whileBody = createLabel (trueLabel, whileBody);
4817 whileBody->lineno = 0;
4818 /* put a jump to continue at the end of the body */
4819 /* and put break label at the end of the body */
4820 whileBody = newNode (NULLOP,
4823 newAst_VALUE (symbolVal (continueLabel)),
4824 createLabel (falseLabel, NULL)));
4826 /* put it all together */
4827 if (IS_IFX (condExpr))
4828 whileTree = condExpr;
4831 whileTree = newNode (IFX, condExpr, NULL);
4832 /* put the true & false labels in place */
4833 whileTree->trueLabel = trueLabel;
4834 whileTree->falseLabel = falseLabel;
4837 return newNode (NULLOP, whileTree, whileBody);
4840 /*-----------------------------------------------------------------*/
4841 /* optimizeGetHbit - get highest order bit of the expression */
4842 /*-----------------------------------------------------------------*/
4844 optimizeGetHbit (ast * tree)
4847 /* if this is not a bit and */
4848 if (!IS_BITAND (tree))
4851 /* will look for tree of the form
4852 ( expr >> ((sizeof expr) -1) ) & 1 */
4853 if (!IS_AST_LIT_VALUE (tree->right))
4856 if (AST_LIT_VALUE (tree->right) != 1)
4859 if (!IS_RIGHT_OP (tree->left))
4862 if (!IS_AST_LIT_VALUE (tree->left->right))
4865 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4866 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4869 /* make sure the port supports GETHBIT */
4870 if (port->hasExtBitOp
4871 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4874 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4878 /*-----------------------------------------------------------------*/
4879 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4880 /*-----------------------------------------------------------------*/
4882 optimizeRRCRLC (ast * root)
4884 /* will look for trees of the form
4885 (?expr << 1) | (?expr >> 7) or
4886 (?expr >> 7) | (?expr << 1) will make that
4887 into a RLC : operation ..
4889 (?expr >> 1) | (?expr << 7) or
4890 (?expr << 7) | (?expr >> 1) will make that
4891 into a RRC operation
4892 note : by 7 I mean (number of bits required to hold the
4894 /* if the root operations is not a | operation the not */
4895 if (!IS_BITOR (root))
4898 /* I have to think of a better way to match patterns this sucks */
4899 /* that aside let start looking for the first case : I use a the
4900 negative check a lot to improve the efficiency */
4901 /* (?expr << 1) | (?expr >> 7) */
4902 if (IS_LEFT_OP (root->left) &&
4903 IS_RIGHT_OP (root->right))
4906 if (!SPEC_USIGN (TETYPE (root->left->left)))
4909 if (!IS_AST_LIT_VALUE (root->left->right) ||
4910 !IS_AST_LIT_VALUE (root->right->right))
4913 /* make sure it is the same expression */
4914 if (!isAstEqual (root->left->left,
4918 if (AST_LIT_VALUE (root->left->right) != 1)
4921 if (AST_LIT_VALUE (root->right->right) !=
4922 (getSize (TTYPE (root->left->left)) * 8 - 1))
4925 /* make sure the port supports RLC */
4926 if (port->hasExtBitOp
4927 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4930 /* whew got the first case : create the AST */
4931 return newNode (RLC, root->left->left, NULL);
4935 /* check for second case */
4936 /* (?expr >> 7) | (?expr << 1) */
4937 if (IS_LEFT_OP (root->right) &&
4938 IS_RIGHT_OP (root->left))
4941 if (!SPEC_USIGN (TETYPE (root->left->left)))
4944 if (!IS_AST_LIT_VALUE (root->left->right) ||
4945 !IS_AST_LIT_VALUE (root->right->right))
4948 /* make sure it is the same symbol */
4949 if (!isAstEqual (root->left->left,
4953 if (AST_LIT_VALUE (root->right->right) != 1)
4956 if (AST_LIT_VALUE (root->left->right) !=
4957 (getSize (TTYPE (root->left->left)) * 8 - 1))
4960 /* make sure the port supports RLC */
4961 if (port->hasExtBitOp
4962 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4965 /* whew got the first case : create the AST */
4966 return newNode (RLC, root->left->left, NULL);
4971 /* third case for RRC */
4972 /* (?symbol >> 1) | (?symbol << 7) */
4973 if (IS_LEFT_OP (root->right) &&
4974 IS_RIGHT_OP (root->left))
4977 if (!SPEC_USIGN (TETYPE (root->left->left)))
4980 if (!IS_AST_LIT_VALUE (root->left->right) ||
4981 !IS_AST_LIT_VALUE (root->right->right))
4984 /* make sure it is the same symbol */
4985 if (!isAstEqual (root->left->left,
4989 if (AST_LIT_VALUE (root->left->right) != 1)
4992 if (AST_LIT_VALUE (root->right->right) !=
4993 (getSize (TTYPE (root->left->left)) * 8 - 1))
4996 /* make sure the port supports RRC */
4997 if (port->hasExtBitOp
4998 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5001 /* whew got the first case : create the AST */
5002 return newNode (RRC, root->left->left, NULL);
5006 /* fourth and last case for now */
5007 /* (?symbol << 7) | (?symbol >> 1) */
5008 if (IS_RIGHT_OP (root->right) &&
5009 IS_LEFT_OP (root->left))
5012 if (!SPEC_USIGN (TETYPE (root->left->left)))
5015 if (!IS_AST_LIT_VALUE (root->left->right) ||
5016 !IS_AST_LIT_VALUE (root->right->right))
5019 /* make sure it is the same symbol */
5020 if (!isAstEqual (root->left->left,
5024 if (AST_LIT_VALUE (root->right->right) != 1)
5027 if (AST_LIT_VALUE (root->left->right) !=
5028 (getSize (TTYPE (root->left->left)) * 8 - 1))
5031 /* make sure the port supports RRC */
5032 if (port->hasExtBitOp
5033 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5036 /* whew got the first case : create the AST */
5037 return newNode (RRC, root->left->left, NULL);
5041 /* not found return root */
5045 /*-----------------------------------------------------------------*/
5046 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5047 /*-----------------------------------------------------------------*/
5049 optimizeSWAP (ast * root)
5051 /* will look for trees of the form
5052 (?expr << 4) | (?expr >> 4) or
5053 (?expr >> 4) | (?expr << 4) will make that
5054 into a SWAP : operation ..
5055 note : by 4 I mean (number of bits required to hold the
5057 /* if the root operations is not a | operation the not */
5058 if (!IS_BITOR (root))
5061 /* (?expr << 4) | (?expr >> 4) */
5062 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5063 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5066 if (!SPEC_USIGN (TETYPE (root->left->left)))
5069 if (!IS_AST_LIT_VALUE (root->left->right) ||
5070 !IS_AST_LIT_VALUE (root->right->right))
5073 /* make sure it is the same expression */
5074 if (!isAstEqual (root->left->left,
5078 if (AST_LIT_VALUE (root->left->right) !=
5079 (getSize (TTYPE (root->left->left)) * 4))
5082 if (AST_LIT_VALUE (root->right->right) !=
5083 (getSize (TTYPE (root->left->left)) * 4))
5086 /* make sure the port supports SWAP */
5087 if (port->hasExtBitOp
5088 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5091 /* found it : create the AST */
5092 return newNode (SWAP, root->left->left, NULL);
5096 /* not found return root */
5100 /*-----------------------------------------------------------------*/
5101 /* optimizeCompare - otimizes compares for bit variables */
5102 /*-----------------------------------------------------------------*/
5104 optimizeCompare (ast * root)
5106 ast *optExpr = NULL;
5109 unsigned int litValue;
5111 /* if nothing then return nothing */
5115 /* if not a compare op then do leaves */
5116 if (!IS_COMPARE_OP (root))
5118 root->left = optimizeCompare (root->left);
5119 root->right = optimizeCompare (root->right);
5123 /* if left & right are the same then depending
5124 of the operation do */
5125 if (isAstEqual (root->left, root->right))
5127 switch (root->opval.op)
5132 optExpr = newAst_VALUE (constVal ("0"));
5137 optExpr = newAst_VALUE (constVal ("1"));
5141 return decorateType (optExpr, RESULT_TYPE_NONE);
5144 vleft = (root->left->type == EX_VALUE ?
5145 root->left->opval.val : NULL);
5147 vright = (root->right->type == EX_VALUE ?
5148 root->right->opval.val : NULL);
5150 /* if left is a BITVAR in BITSPACE */
5151 /* and right is a LITERAL then opt- */
5152 /* imize else do nothing */
5153 if (vleft && vright &&
5154 IS_BITVAR (vleft->etype) &&
5155 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5156 IS_LITERAL (vright->etype))
5159 /* if right side > 1 then comparison may never succeed */
5160 if ((litValue = (int) floatFromVal (vright)) > 1)
5162 werror (W_BAD_COMPARE);
5168 switch (root->opval.op)
5170 case '>': /* bit value greater than 1 cannot be */
5171 werror (W_BAD_COMPARE);
5175 case '<': /* bit value < 1 means 0 */
5177 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5180 case LE_OP: /* bit value <= 1 means no check */
5181 optExpr = newAst_VALUE (vright);
5184 case GE_OP: /* bit value >= 1 means only check for = */
5186 optExpr = newAst_VALUE (vleft);
5191 { /* literal is zero */
5192 switch (root->opval.op)
5194 case '<': /* bit value < 0 cannot be */
5195 werror (W_BAD_COMPARE);
5199 case '>': /* bit value > 0 means 1 */
5201 optExpr = newAst_VALUE (vleft);
5204 case LE_OP: /* bit value <= 0 means no check */
5205 case GE_OP: /* bit value >= 0 means no check */
5206 werror (W_BAD_COMPARE);
5210 case EQ_OP: /* bit == 0 means ! of bit */
5211 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5215 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5216 } /* end-of-if of BITVAR */
5221 /*-----------------------------------------------------------------*/
5222 /* addSymToBlock : adds the symbol to the first block we find */
5223 /*-----------------------------------------------------------------*/
5225 addSymToBlock (symbol * sym, ast * tree)
5227 /* reached end of tree or a leaf */
5228 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5232 if (IS_AST_OP (tree) &&
5233 tree->opval.op == BLOCK)
5236 symbol *lsym = copySymbol (sym);
5238 lsym->next = AST_VALUES (tree, sym);
5239 AST_VALUES (tree, sym) = lsym;
5243 addSymToBlock (sym, tree->left);
5244 addSymToBlock (sym, tree->right);
5247 /*-----------------------------------------------------------------*/
5248 /* processRegParms - do processing for register parameters */
5249 /*-----------------------------------------------------------------*/
5251 processRegParms (value * args, ast * body)
5255 if (IS_REGPARM (args->etype))
5256 addSymToBlock (args->sym, body);
5261 /*-----------------------------------------------------------------*/
5262 /* resetParmKey - resets the operandkeys for the symbols */
5263 /*-----------------------------------------------------------------*/
5264 DEFSETFUNC (resetParmKey)
5275 /*-----------------------------------------------------------------*/
5276 /* createFunction - This is the key node that calls the iCode for */
5277 /* generating the code for a function. Note code */
5278 /* is generated function by function, later when */
5279 /* add inter-procedural analysis this will change */
5280 /*-----------------------------------------------------------------*/
5282 createFunction (symbol * name, ast * body)
5288 iCode *piCode = NULL;
5290 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5291 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5293 /* if check function return 0 then some problem */
5294 if (checkFunction (name, NULL) == 0)
5297 /* create a dummy block if none exists */
5299 body = newNode (BLOCK, NULL, NULL);
5303 /* check if the function name already in the symbol table */
5304 if ((csym = findSym (SymbolTab, NULL, name->name)))
5307 /* special case for compiler defined functions
5308 we need to add the name to the publics list : this
5309 actually means we are now compiling the compiler
5313 addSet (&publics, name);
5319 allocVariables (name);
5321 name->lastLine = mylineno;
5324 /* set the stack pointer */
5325 stackPtr = -port->stack.direction * port->stack.call_overhead;
5326 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5328 if (IFFUNC_ISISR (name->type))
5329 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5331 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5333 if (options.useXstack)
5334 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5336 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5339 fetype = getSpec (name->type); /* get the specifier for the function */
5340 /* if this is a reentrant function then */
5341 if (IFFUNC_ISREENT (name->type))
5344 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5346 /* do processing for parameters that are passed in registers */
5347 processRegParms (FUNC_ARGS(name->type), body);
5349 /* set the stack pointer */
5353 /* allocate & autoinit the block variables */
5354 processBlockVars (body, &stack, ALLOCATE);
5356 /* save the stack information */
5357 if (options.useXstack)
5358 name->xstack = SPEC_STAK (fetype) = stack;
5360 name->stack = SPEC_STAK (fetype) = stack;
5362 /* name needs to be mangled */
5363 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5365 body = resolveSymbols (body); /* resolve the symbols */
5366 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5369 ex = newAst_VALUE (symbolVal (name)); /* create name */
5370 ex = newNode (FUNCTION, ex, body);
5371 ex->values.args = FUNC_ARGS(name->type);
5373 if (options.dump_tree) PA(ex);
5376 werror (E_FUNC_NO_CODE, name->name);
5380 /* create the node & generate intermediate code */
5382 codeOutFile = code->oFile;
5383 piCode = iCodeFromAst (ex);
5387 werror (E_FUNC_NO_CODE, name->name);
5391 eBBlockFromiCode (piCode);
5393 /* if there are any statics then do them */
5396 GcurMemmap = statsg;
5397 codeOutFile = statsg->oFile;
5398 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5404 /* dealloc the block variables */
5405 processBlockVars (body, &stack, DEALLOCATE);
5406 outputDebugStackSymbols();
5407 /* deallocate paramaters */
5408 deallocParms (FUNC_ARGS(name->type));
5410 if (IFFUNC_ISREENT (name->type))
5413 /* we are done freeup memory & cleanup */
5415 if (port->reset_labelKey) labelKey = 1;
5417 FUNC_HASBODY(name->type) = 1;
5418 addSet (&operKeyReset, name);
5419 applyToSet (operKeyReset, resetParmKey);
5424 cleanUpLevel (LabelTab, 0);
5425 cleanUpBlock (StructTab, 1);
5426 cleanUpBlock (TypedefTab, 1);
5428 xstack->syms = NULL;
5429 istack->syms = NULL;
5434 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5435 /*-----------------------------------------------------------------*/
5436 /* ast_print : prints the ast (for debugging purposes) */
5437 /*-----------------------------------------------------------------*/
5439 void ast_print (ast * tree, FILE *outfile, int indent)
5444 /* can print only decorated trees */
5445 if (!tree->decorated) return;
5447 /* if any child is an error | this one is an error do nothing */
5448 if (tree->isError ||
5449 (tree->left && tree->left->isError) ||
5450 (tree->right && tree->right->isError)) {
5451 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5455 /* print the line */
5456 /* if not block & function */
5457 if (tree->type == EX_OP &&
5458 (tree->opval.op != FUNCTION &&
5459 tree->opval.op != BLOCK &&
5460 tree->opval.op != NULLOP)) {
5463 if (tree->opval.op == FUNCTION) {
5465 value *args=FUNC_ARGS(tree->left->opval.val->type);
5466 fprintf(outfile,"FUNCTION (%s=%p) type (",
5467 tree->left->opval.val->name, tree);
5468 printTypeChain (tree->left->opval.val->type->next,outfile);
5469 fprintf(outfile,") args (");
5472 fprintf (outfile, ", ");
5474 printTypeChain (args ? args->type : NULL, outfile);
5476 args= args ? args->next : NULL;
5478 fprintf(outfile,")\n");
5479 ast_print(tree->left,outfile,indent);
5480 ast_print(tree->right,outfile,indent);
5483 if (tree->opval.op == BLOCK) {
5484 symbol *decls = tree->values.sym;
5485 INDENT(indent,outfile);
5486 fprintf(outfile,"{\n");
5488 INDENT(indent+2,outfile);
5489 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5490 decls->name, decls);
5491 printTypeChain(decls->type,outfile);
5492 fprintf(outfile,")\n");
5494 decls = decls->next;
5496 ast_print(tree->right,outfile,indent+2);
5497 INDENT(indent,outfile);
5498 fprintf(outfile,"}\n");
5501 if (tree->opval.op == NULLOP) {
5502 ast_print(tree->left,outfile,indent);
5503 ast_print(tree->right,outfile,indent);
5506 INDENT(indent,outfile);
5508 /*------------------------------------------------------------------*/
5509 /*----------------------------*/
5510 /* leaf has been reached */
5511 /*----------------------------*/
5512 /* if this is of type value */
5513 /* just get the type */
5514 if (tree->type == EX_VALUE) {
5516 if (IS_LITERAL (tree->opval.val->etype)) {
5517 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5518 if (SPEC_USIGN (tree->opval.val->etype))
5519 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5521 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5522 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5523 floatFromVal(tree->opval.val));
5524 } else if (tree->opval.val->sym) {
5525 /* if the undefined flag is set then give error message */
5526 if (tree->opval.val->sym->undefined) {
5527 fprintf(outfile,"UNDEFINED SYMBOL ");
5529 fprintf(outfile,"SYMBOL ");
5531 fprintf(outfile,"(%s=%p)",
5532 tree->opval.val->sym->name,tree);
5535 fprintf(outfile," type (");
5536 printTypeChain(tree->ftype,outfile);
5537 fprintf(outfile,")\n");
5539 fprintf(outfile,"\n");
5544 /* if type link for the case of cast */
5545 if (tree->type == EX_LINK) {
5546 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5547 printTypeChain(tree->opval.lnk,outfile);
5548 fprintf(outfile,")\n");
5553 /* depending on type of operator do */
5555 switch (tree->opval.op) {
5556 /*------------------------------------------------------------------*/
5557 /*----------------------------*/
5559 /*----------------------------*/
5561 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5562 printTypeChain(tree->ftype,outfile);
5563 fprintf(outfile,")\n");
5564 ast_print(tree->left,outfile,indent+2);
5565 ast_print(tree->right,outfile,indent+2);
5568 /*------------------------------------------------------------------*/
5569 /*----------------------------*/
5571 /*----------------------------*/
5573 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5574 printTypeChain(tree->ftype,outfile);
5575 fprintf(outfile,")\n");
5576 ast_print(tree->left,outfile,indent+2);
5577 ast_print(tree->right,outfile,indent+2);
5580 /*------------------------------------------------------------------*/
5581 /*----------------------------*/
5582 /* struct/union pointer */
5583 /*----------------------------*/
5585 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5586 printTypeChain(tree->ftype,outfile);
5587 fprintf(outfile,")\n");
5588 ast_print(tree->left,outfile,indent+2);
5589 ast_print(tree->right,outfile,indent+2);
5592 /*------------------------------------------------------------------*/
5593 /*----------------------------*/
5594 /* ++/-- operation */
5595 /*----------------------------*/
5598 fprintf(outfile,"post-");
5600 fprintf(outfile,"pre-");
5601 fprintf(outfile,"INC_OP (%p) type (",tree);
5602 printTypeChain(tree->ftype,outfile);
5603 fprintf(outfile,")\n");
5604 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5605 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5610 fprintf(outfile,"post-");
5612 fprintf(outfile,"pre-");
5613 fprintf(outfile,"DEC_OP (%p) type (",tree);
5614 printTypeChain(tree->ftype,outfile);
5615 fprintf(outfile,")\n");
5616 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5617 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5620 /*------------------------------------------------------------------*/
5621 /*----------------------------*/
5623 /*----------------------------*/
5626 fprintf(outfile,"& (%p) type (",tree);
5627 printTypeChain(tree->ftype,outfile);
5628 fprintf(outfile,")\n");
5629 ast_print(tree->left,outfile,indent+2);
5630 ast_print(tree->right,outfile,indent+2);
5632 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5633 printTypeChain(tree->ftype,outfile);
5634 fprintf(outfile,")\n");
5635 ast_print(tree->left,outfile,indent+2);
5636 ast_print(tree->right,outfile,indent+2);
5639 /*----------------------------*/
5641 /*----------------------------*/
5643 fprintf(outfile,"OR (%p) type (",tree);
5644 printTypeChain(tree->ftype,outfile);
5645 fprintf(outfile,")\n");
5646 ast_print(tree->left,outfile,indent+2);
5647 ast_print(tree->right,outfile,indent+2);
5649 /*------------------------------------------------------------------*/
5650 /*----------------------------*/
5652 /*----------------------------*/
5654 fprintf(outfile,"XOR (%p) type (",tree);
5655 printTypeChain(tree->ftype,outfile);
5656 fprintf(outfile,")\n");
5657 ast_print(tree->left,outfile,indent+2);
5658 ast_print(tree->right,outfile,indent+2);
5661 /*------------------------------------------------------------------*/
5662 /*----------------------------*/
5664 /*----------------------------*/
5666 fprintf(outfile,"DIV (%p) type (",tree);
5667 printTypeChain(tree->ftype,outfile);
5668 fprintf(outfile,")\n");
5669 ast_print(tree->left,outfile,indent+2);
5670 ast_print(tree->right,outfile,indent+2);
5672 /*------------------------------------------------------------------*/
5673 /*----------------------------*/
5675 /*----------------------------*/
5677 fprintf(outfile,"MOD (%p) type (",tree);
5678 printTypeChain(tree->ftype,outfile);
5679 fprintf(outfile,")\n");
5680 ast_print(tree->left,outfile,indent+2);
5681 ast_print(tree->right,outfile,indent+2);
5684 /*------------------------------------------------------------------*/
5685 /*----------------------------*/
5686 /* address dereference */
5687 /*----------------------------*/
5688 case '*': /* can be unary : if right is null then unary operation */
5690 fprintf(outfile,"DEREF (%p) type (",tree);
5691 printTypeChain(tree->ftype,outfile);
5692 fprintf(outfile,")\n");
5693 ast_print(tree->left,outfile,indent+2);
5696 /*------------------------------------------------------------------*/
5697 /*----------------------------*/
5698 /* multiplication */
5699 /*----------------------------*/
5700 fprintf(outfile,"MULT (%p) type (",tree);
5701 printTypeChain(tree->ftype,outfile);
5702 fprintf(outfile,")\n");
5703 ast_print(tree->left,outfile,indent+2);
5704 ast_print(tree->right,outfile,indent+2);
5708 /*------------------------------------------------------------------*/
5709 /*----------------------------*/
5710 /* unary '+' operator */
5711 /*----------------------------*/
5715 fprintf(outfile,"UPLUS (%p) type (",tree);
5716 printTypeChain(tree->ftype,outfile);
5717 fprintf(outfile,")\n");
5718 ast_print(tree->left,outfile,indent+2);
5720 /*------------------------------------------------------------------*/
5721 /*----------------------------*/
5723 /*----------------------------*/
5724 fprintf(outfile,"ADD (%p) type (",tree);
5725 printTypeChain(tree->ftype,outfile);
5726 fprintf(outfile,")\n");
5727 ast_print(tree->left,outfile,indent+2);
5728 ast_print(tree->right,outfile,indent+2);
5731 /*------------------------------------------------------------------*/
5732 /*----------------------------*/
5734 /*----------------------------*/
5735 case '-': /* can be unary */
5737 fprintf(outfile,"UMINUS (%p) type (",tree);
5738 printTypeChain(tree->ftype,outfile);
5739 fprintf(outfile,")\n");
5740 ast_print(tree->left,outfile,indent+2);
5742 /*------------------------------------------------------------------*/
5743 /*----------------------------*/
5745 /*----------------------------*/
5746 fprintf(outfile,"SUB (%p) type (",tree);
5747 printTypeChain(tree->ftype,outfile);
5748 fprintf(outfile,")\n");
5749 ast_print(tree->left,outfile,indent+2);
5750 ast_print(tree->right,outfile,indent+2);
5753 /*------------------------------------------------------------------*/
5754 /*----------------------------*/
5756 /*----------------------------*/
5758 fprintf(outfile,"COMPL (%p) type (",tree);
5759 printTypeChain(tree->ftype,outfile);
5760 fprintf(outfile,")\n");
5761 ast_print(tree->left,outfile,indent+2);
5763 /*------------------------------------------------------------------*/
5764 /*----------------------------*/
5766 /*----------------------------*/
5768 fprintf(outfile,"NOT (%p) type (",tree);
5769 printTypeChain(tree->ftype,outfile);
5770 fprintf(outfile,")\n");
5771 ast_print(tree->left,outfile,indent+2);
5773 /*------------------------------------------------------------------*/
5774 /*----------------------------*/
5776 /*----------------------------*/
5778 fprintf(outfile,"RRC (%p) type (",tree);
5779 printTypeChain(tree->ftype,outfile);
5780 fprintf(outfile,")\n");
5781 ast_print(tree->left,outfile,indent+2);
5785 fprintf(outfile,"RLC (%p) type (",tree);
5786 printTypeChain(tree->ftype,outfile);
5787 fprintf(outfile,")\n");
5788 ast_print(tree->left,outfile,indent+2);
5791 fprintf(outfile,"SWAP (%p) type (",tree);
5792 printTypeChain(tree->ftype,outfile);
5793 fprintf(outfile,")\n");
5794 ast_print(tree->left,outfile,indent+2);
5797 fprintf(outfile,"GETHBIT (%p) type (",tree);
5798 printTypeChain(tree->ftype,outfile);
5799 fprintf(outfile,")\n");
5800 ast_print(tree->left,outfile,indent+2);
5803 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5804 printTypeChain(tree->ftype,outfile);
5805 fprintf(outfile,")\n");
5806 ast_print(tree->left,outfile,indent+2);
5807 ast_print(tree->right,outfile,indent+2);
5810 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5811 printTypeChain(tree->ftype,outfile);
5812 fprintf(outfile,")\n");
5813 ast_print(tree->left,outfile,indent+2);
5814 ast_print(tree->right,outfile,indent+2);
5816 /*------------------------------------------------------------------*/
5817 /*----------------------------*/
5819 /*----------------------------*/
5820 case CAST: /* change the type */
5821 fprintf(outfile,"CAST (%p) from type (",tree);
5822 printTypeChain(tree->right->ftype,outfile);
5823 fprintf(outfile,") to type (");
5824 printTypeChain(tree->ftype,outfile);
5825 fprintf(outfile,")\n");
5826 ast_print(tree->right,outfile,indent+2);
5830 fprintf(outfile,"ANDAND (%p) type (",tree);
5831 printTypeChain(tree->ftype,outfile);
5832 fprintf(outfile,")\n");
5833 ast_print(tree->left,outfile,indent+2);
5834 ast_print(tree->right,outfile,indent+2);
5837 fprintf(outfile,"OROR (%p) type (",tree);
5838 printTypeChain(tree->ftype,outfile);
5839 fprintf(outfile,")\n");
5840 ast_print(tree->left,outfile,indent+2);
5841 ast_print(tree->right,outfile,indent+2);
5844 /*------------------------------------------------------------------*/
5845 /*----------------------------*/
5846 /* comparison operators */
5847 /*----------------------------*/
5849 fprintf(outfile,"GT(>) (%p) type (",tree);
5850 printTypeChain(tree->ftype,outfile);
5851 fprintf(outfile,")\n");
5852 ast_print(tree->left,outfile,indent+2);
5853 ast_print(tree->right,outfile,indent+2);
5856 fprintf(outfile,"LT(<) (%p) type (",tree);
5857 printTypeChain(tree->ftype,outfile);
5858 fprintf(outfile,")\n");
5859 ast_print(tree->left,outfile,indent+2);
5860 ast_print(tree->right,outfile,indent+2);
5863 fprintf(outfile,"LE(<=) (%p) type (",tree);
5864 printTypeChain(tree->ftype,outfile);
5865 fprintf(outfile,")\n");
5866 ast_print(tree->left,outfile,indent+2);
5867 ast_print(tree->right,outfile,indent+2);
5870 fprintf(outfile,"GE(>=) (%p) type (",tree);
5871 printTypeChain(tree->ftype,outfile);
5872 fprintf(outfile,")\n");
5873 ast_print(tree->left,outfile,indent+2);
5874 ast_print(tree->right,outfile,indent+2);
5877 fprintf(outfile,"EQ(==) (%p) type (",tree);
5878 printTypeChain(tree->ftype,outfile);
5879 fprintf(outfile,")\n");
5880 ast_print(tree->left,outfile,indent+2);
5881 ast_print(tree->right,outfile,indent+2);
5884 fprintf(outfile,"NE(!=) (%p) type (",tree);
5885 printTypeChain(tree->ftype,outfile);
5886 fprintf(outfile,")\n");
5887 ast_print(tree->left,outfile,indent+2);
5888 ast_print(tree->right,outfile,indent+2);
5889 /*------------------------------------------------------------------*/
5890 /*----------------------------*/
5892 /*----------------------------*/
5893 case SIZEOF: /* evaluate wihout code generation */
5894 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5897 /*------------------------------------------------------------------*/
5898 /*----------------------------*/
5899 /* conditional operator '?' */
5900 /*----------------------------*/
5902 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5903 printTypeChain(tree->ftype,outfile);
5904 fprintf(outfile,")\n");
5905 ast_print(tree->left,outfile,indent+2);
5906 ast_print(tree->right,outfile,indent+2);
5910 fprintf(outfile,"COLON(:) (%p) type (",tree);
5911 printTypeChain(tree->ftype,outfile);
5912 fprintf(outfile,")\n");
5913 ast_print(tree->left,outfile,indent+2);
5914 ast_print(tree->right,outfile,indent+2);
5917 /*------------------------------------------------------------------*/
5918 /*----------------------------*/
5919 /* assignment operators */
5920 /*----------------------------*/
5922 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5923 printTypeChain(tree->ftype,outfile);
5924 fprintf(outfile,")\n");
5925 ast_print(tree->left,outfile,indent+2);
5926 ast_print(tree->right,outfile,indent+2);
5929 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5930 printTypeChain(tree->ftype,outfile);
5931 fprintf(outfile,")\n");
5932 ast_print(tree->left,outfile,indent+2);
5933 ast_print(tree->right,outfile,indent+2);
5936 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5937 printTypeChain(tree->ftype,outfile);
5938 fprintf(outfile,")\n");
5939 ast_print(tree->left,outfile,indent+2);
5940 ast_print(tree->right,outfile,indent+2);
5943 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5944 printTypeChain(tree->ftype,outfile);
5945 fprintf(outfile,")\n");
5946 ast_print(tree->left,outfile,indent+2);
5947 ast_print(tree->right,outfile,indent+2);
5950 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5951 printTypeChain(tree->ftype,outfile);
5952 fprintf(outfile,")\n");
5953 ast_print(tree->left,outfile,indent+2);
5954 ast_print(tree->right,outfile,indent+2);
5957 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5958 printTypeChain(tree->ftype,outfile);
5959 fprintf(outfile,")\n");
5960 ast_print(tree->left,outfile,indent+2);
5961 ast_print(tree->right,outfile,indent+2);
5964 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5965 printTypeChain(tree->ftype,outfile);
5966 fprintf(outfile,")\n");
5967 ast_print(tree->left,outfile,indent+2);
5968 ast_print(tree->right,outfile,indent+2);
5970 /*------------------------------------------------------------------*/
5971 /*----------------------------*/
5973 /*----------------------------*/
5975 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5976 printTypeChain(tree->ftype,outfile);
5977 fprintf(outfile,")\n");
5978 ast_print(tree->left,outfile,indent+2);
5979 ast_print(tree->right,outfile,indent+2);
5981 /*------------------------------------------------------------------*/
5982 /*----------------------------*/
5984 /*----------------------------*/
5986 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5987 printTypeChain(tree->ftype,outfile);
5988 fprintf(outfile,")\n");
5989 ast_print(tree->left,outfile,indent+2);
5990 ast_print(tree->right,outfile,indent+2);
5992 /*------------------------------------------------------------------*/
5993 /*----------------------------*/
5994 /* straight assignemnt */
5995 /*----------------------------*/
5997 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5998 printTypeChain(tree->ftype,outfile);
5999 fprintf(outfile,")\n");
6000 ast_print(tree->left,outfile,indent+2);
6001 ast_print(tree->right,outfile,indent+2);
6003 /*------------------------------------------------------------------*/
6004 /*----------------------------*/
6005 /* comma operator */
6006 /*----------------------------*/
6008 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6009 printTypeChain(tree->ftype,outfile);
6010 fprintf(outfile,")\n");
6011 ast_print(tree->left,outfile,indent+2);
6012 ast_print(tree->right,outfile,indent+2);
6014 /*------------------------------------------------------------------*/
6015 /*----------------------------*/
6017 /*----------------------------*/
6020 fprintf(outfile,"CALL (%p) type (",tree);
6021 printTypeChain(tree->ftype,outfile);
6022 fprintf(outfile,")\n");
6023 ast_print(tree->left,outfile,indent+2);
6024 ast_print(tree->right,outfile,indent+2);
6027 fprintf(outfile,"PARMS\n");
6028 ast_print(tree->left,outfile,indent+2);
6029 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6030 ast_print(tree->right,outfile,indent+2);
6033 /*------------------------------------------------------------------*/
6034 /*----------------------------*/
6035 /* return statement */
6036 /*----------------------------*/
6038 fprintf(outfile,"RETURN (%p) type (",tree);
6040 printTypeChain(tree->right->ftype,outfile);
6042 fprintf(outfile,")\n");
6043 ast_print(tree->right,outfile,indent+2);
6045 /*------------------------------------------------------------------*/
6046 /*----------------------------*/
6047 /* label statement */
6048 /*----------------------------*/
6050 fprintf(outfile,"LABEL (%p)\n",tree);
6051 ast_print(tree->left,outfile,indent+2);
6052 ast_print(tree->right,outfile,indent);
6054 /*------------------------------------------------------------------*/
6055 /*----------------------------*/
6056 /* switch statement */
6057 /*----------------------------*/
6061 fprintf(outfile,"SWITCH (%p) ",tree);
6062 ast_print(tree->left,outfile,0);
6063 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6064 INDENT(indent+2,outfile);
6065 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6066 (int) floatFromVal(val),
6067 tree->values.switchVals.swNum,
6068 (int) floatFromVal(val));
6070 ast_print(tree->right,outfile,indent);
6073 /*------------------------------------------------------------------*/
6074 /*----------------------------*/
6076 /*----------------------------*/
6078 fprintf(outfile,"IF (%p) \n",tree);
6079 ast_print(tree->left,outfile,indent+2);
6080 if (tree->trueLabel) {
6081 INDENT(indent+2,outfile);
6082 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6084 if (tree->falseLabel) {
6085 INDENT(indent+2,outfile);
6086 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6088 ast_print(tree->right,outfile,indent+2);
6090 /*----------------------------*/
6091 /* goto Statement */
6092 /*----------------------------*/
6094 fprintf(outfile,"GOTO (%p) \n",tree);
6095 ast_print(tree->left,outfile,indent+2);
6096 fprintf(outfile,"\n");
6098 /*------------------------------------------------------------------*/
6099 /*----------------------------*/
6101 /*----------------------------*/
6103 fprintf(outfile,"FOR (%p) \n",tree);
6104 if (AST_FOR( tree, initExpr)) {
6105 INDENT(indent+2,outfile);
6106 fprintf(outfile,"INIT EXPR ");
6107 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6109 if (AST_FOR( tree, condExpr)) {
6110 INDENT(indent+2,outfile);
6111 fprintf(outfile,"COND EXPR ");
6112 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6114 if (AST_FOR( tree, loopExpr)) {
6115 INDENT(indent+2,outfile);
6116 fprintf(outfile,"LOOP EXPR ");
6117 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6119 fprintf(outfile,"FOR LOOP BODY \n");
6120 ast_print(tree->left,outfile,indent+2);
6123 fprintf(outfile,"CRITICAL (%p) \n",tree);
6124 ast_print(tree->left,outfile,indent+2);
6132 ast_print(t,stdout,0);
6137 /*-----------------------------------------------------------------*/
6138 /* astErrors : returns non-zero if errors present in tree */
6139 /*-----------------------------------------------------------------*/
6140 int astErrors(ast *t)
6149 if (t->type == EX_VALUE
6150 && t->opval.val->sym
6151 && t->opval.val->sym->undefined)
6154 errors += astErrors(t->left);
6155 errors += astErrors(t->right);