1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
221 dest->reversed = src->reversed;
224 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
226 /* if this is a leaf */
228 if (src->type == EX_VALUE)
230 dest->opval.val = copyValue (src->opval.val);
235 if (src->type == EX_LINK)
237 dest->opval.lnk = copyLinkChain (src->opval.lnk);
241 dest->opval.op = src->opval.op;
243 /* if this is a node that has special values */
244 copyAstValues (dest, src);
246 dest->trueLabel = copySymbol (src->trueLabel);
247 dest->falseLabel = copySymbol (src->falseLabel);
248 dest->left = copyAst (src->left);
249 dest->right = copyAst (src->right);
255 /*-----------------------------------------------------------------*/
256 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
257 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
258 /*-----------------------------------------------------------------*/
259 ast *removeIncDecOps (ast * tree) {
261 // traverse the tree and remove inc/dec ops
266 if (tree->type == EX_OP &&
267 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
274 tree->left=removeIncDecOps(tree->left);
275 tree->right=removeIncDecOps(tree->right);
280 /*-----------------------------------------------------------------*/
281 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
282 /* "*++s += 3" -> "*++s = *++s + 3" */
283 /*-----------------------------------------------------------------*/
284 ast *removePreIncDecOps (ast * tree) {
286 // traverse the tree and remove pre-inc/dec ops
291 if (tree->type == EX_OP &&
292 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
297 tree->left=removePreIncDecOps(tree->left);
298 tree->right=removePreIncDecOps(tree->right);
303 /*-----------------------------------------------------------------*/
304 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
305 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
306 /*-----------------------------------------------------------------*/
307 ast *removePostIncDecOps (ast * tree) {
309 // traverse the tree and remove pre-inc/dec ops
314 if (tree->type == EX_OP &&
315 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
320 tree->left=removePostIncDecOps(tree->left);
321 tree->right=removePostIncDecOps(tree->right);
326 /*-----------------------------------------------------------------*/
327 /* hasSEFcalls - returns TRUE if tree has a function call */
328 /*-----------------------------------------------------------------*/
330 hasSEFcalls (ast * tree)
335 if (tree->type == EX_OP &&
336 (tree->opval.op == CALL ||
337 tree->opval.op == PCALL ||
338 tree->opval.op == '=' ||
339 tree->opval.op == INC_OP ||
340 tree->opval.op == DEC_OP))
343 return (hasSEFcalls (tree->left) |
344 hasSEFcalls (tree->right));
347 /*-----------------------------------------------------------------*/
348 /* isAstEqual - compares two asts & returns 1 if they are equal */
349 /*-----------------------------------------------------------------*/
351 isAstEqual (ast * t1, ast * t2)
360 if (t1->type != t2->type)
366 if (t1->opval.op != t2->opval.op)
368 return (isAstEqual (t1->left, t2->left) &&
369 isAstEqual (t1->right, t2->right));
373 if (t1->opval.val->sym)
375 if (!t2->opval.val->sym)
378 return isSymbolEqual (t1->opval.val->sym,
383 if (t2->opval.val->sym)
386 return (floatFromVal (t1->opval.val) ==
387 floatFromVal (t2->opval.val));
391 /* only compare these two types */
399 /*-----------------------------------------------------------------*/
400 /* resolveSymbols - resolve symbols from the symbol table */
401 /*-----------------------------------------------------------------*/
403 resolveSymbols (ast * tree)
405 /* walk the entire tree and check for values */
406 /* with symbols if we find one then replace */
407 /* symbol with that from the symbol table */
414 /* if not block & function */
415 if (tree->type == EX_OP &&
416 (tree->opval.op != FUNCTION &&
417 tree->opval.op != BLOCK &&
418 tree->opval.op != NULLOP))
420 filename = tree->filename;
421 lineno = tree->lineno;
425 /* make sure we resolve the true & false labels for ifx */
426 if (tree->type == EX_OP && tree->opval.op == IFX)
432 if ((csym = findSym (LabelTab, tree->trueLabel,
433 tree->trueLabel->name)))
434 tree->trueLabel = csym;
436 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
437 tree->trueLabel->name);
440 if (tree->falseLabel)
442 if ((csym = findSym (LabelTab,
444 tree->falseLabel->name)))
445 tree->falseLabel = csym;
447 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
448 tree->falseLabel->name);
453 /* if this is a label resolve it from the labelTab */
454 if (IS_AST_VALUE (tree) &&
455 tree->opval.val->sym &&
456 tree->opval.val->sym->islbl)
459 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
460 tree->opval.val->sym->name);
463 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
464 tree->opval.val->sym->name);
466 tree->opval.val->sym = csym;
468 goto resolveChildren;
471 /* do only for leafs */
472 if (IS_AST_VALUE (tree) &&
473 tree->opval.val->sym &&
474 !tree->opval.val->sym->implicit)
477 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
479 /* if found in the symbol table & they r not the same */
480 if (csym && tree->opval.val->sym != csym)
482 tree->opval.val->sym = csym;
483 tree->opval.val->type = csym->type;
484 tree->opval.val->etype = csym->etype;
487 /* if not found in the symbol table */
488 /* mark it as undefined assume it is */
489 /* an integer in data space */
490 if (!csym && !tree->opval.val->sym->implicit)
493 /* if this is a function name then */
494 /* mark it as returning an int */
497 tree->opval.val->sym->type = newLink (DECLARATOR);
498 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
499 tree->opval.val->sym->type->next =
500 tree->opval.val->sym->etype = newIntLink ();
501 tree->opval.val->etype = tree->opval.val->etype;
502 tree->opval.val->type = tree->opval.val->sym->type;
503 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
504 tree->opval.val->sym->name);
505 //tree->opval.val->sym->undefined = 1;
506 allocVariables (tree->opval.val->sym);
510 tree->opval.val->sym->undefined = 1;
511 tree->opval.val->type =
512 tree->opval.val->etype = newIntLink ();
513 tree->opval.val->sym->type =
514 tree->opval.val->sym->etype = newIntLink ();
520 resolveSymbols (tree->left);
521 resolveSymbols (tree->right);
526 /*-----------------------------------------------------------------*/
527 /* setAstLineno - walks a ast tree & sets the line number */
528 /*-----------------------------------------------------------------*/
529 int setAstLineno (ast * tree, int lineno)
534 tree->lineno = lineno;
535 setAstLineno (tree->left, lineno);
536 setAstLineno (tree->right, lineno);
540 /*-----------------------------------------------------------------*/
541 /* funcOfType :- function of type with name */
542 /*-----------------------------------------------------------------*/
544 funcOfType (char *name, sym_link * type, sym_link * argType,
548 /* create the symbol */
549 sym = newSymbol (name, 0);
551 /* setup return value */
552 sym->type = newLink (DECLARATOR);
553 DCL_TYPE (sym->type) = FUNCTION;
554 sym->type->next = copyLinkChain (type);
555 sym->etype = getSpec (sym->type);
556 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
558 /* if arguments required */
562 args = FUNC_ARGS(sym->type) = newValue ();
566 args->type = copyLinkChain (argType);
567 args->etype = getSpec (args->type);
568 SPEC_EXTR(args->etype)=1;
571 args = args->next = newValue ();
578 allocVariables (sym);
583 /*-----------------------------------------------------------------*/
584 /* funcOfTypeVarg :- function of type with name and argtype */
585 /*-----------------------------------------------------------------*/
587 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
592 /* create the symbol */
593 sym = newSymbol (name, 0);
595 /* setup return value */
596 sym->type = newLink (DECLARATOR);
597 DCL_TYPE (sym->type) = FUNCTION;
598 sym->type->next = typeFromStr(rtype);
599 sym->etype = getSpec (sym->type);
601 /* if arguments required */
604 args = FUNC_ARGS(sym->type) = newValue ();
606 for ( i = 0 ; i < nArgs ; i++ ) {
607 args->type = typeFromStr(atypes[i]);
608 args->etype = getSpec (args->type);
609 SPEC_EXTR(args->etype)=1;
610 if ((i + 1) == nArgs) break;
611 args = args->next = newValue ();
618 allocVariables (sym);
623 /*-----------------------------------------------------------------*/
624 /* reverseParms - will reverse a parameter tree */
625 /*-----------------------------------------------------------------*/
627 reverseParms (ast * ptree)
633 /* top down if we find a nonParm tree then quit */
634 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
636 /* The various functions expect the parameter tree to be right heavy. */
637 /* Rotate the tree to be left heavy so that after reversal it is */
638 /* right heavy again. */
639 while ((ttree = ptree->right) && ttree->type == EX_OP &&
640 ttree->opval.op == PARAM)
642 ptree->right = ttree->right;
643 ttree->right = ttree->left;
644 ttree->left = ptree->left;
650 ptree->left = ptree->right;
651 ptree->right = ttree;
653 reverseParms (ptree->left);
654 reverseParms (ptree->right);
660 /*-----------------------------------------------------------------*/
661 /* processParms - makes sure the parameters are okay and do some */
662 /* processing with them */
663 /*-----------------------------------------------------------------*/
665 processParms (ast *func,
668 int *parmNumber, /* unused, although updated */
671 RESULT_TYPE resultType;
674 /* if none of them exist */
675 if (!defParm && !*actParm)
680 if (getenv("DEBUG_SANITY"))
682 fprintf (stderr, "processParms: %s ", defParm->name);
684 /* make sure the type is complete and sane */
685 checkTypeSanity(defParm->etype, defParm->name);
688 if (IS_CODEPTR (func->ftype))
689 functype = func->ftype->next;
691 functype = func->ftype;
693 /* if the function is being called via a pointer & */
694 /* it has not been defined a reentrant then we cannot */
695 /* have parameters */
696 /* PIC16 port can... */
697 if (!TARGET_IS_PIC16)
699 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
701 werror (W_NONRENT_ARGS);
707 /* if defined parameters ended but actual parameters */
708 /* exist and this is not defined as a variable arg */
709 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
711 werror (E_TOO_MANY_PARMS);
715 /* if defined parameters present but no actual parameters */
716 if (defParm && !*actParm)
718 werror (E_TOO_FEW_PARMS);
722 /* if this is a PARAM node then match left & right */
723 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
725 (*actParm)->decorated = 1;
726 return (processParms (func, defParm,
727 &(*actParm)->left, parmNumber, FALSE) ||
728 processParms (func, defParm ? defParm->next : NULL,
729 &(*actParm)->right, parmNumber, rightmost));
731 else if (defParm) /* not vararg */
733 /* If we have found a value node by following only right-hand links,
734 * then we know that there are no more values after us.
736 * Therefore, if there are more defined parameters, the caller didn't
739 if (rightmost && defParm->next)
741 werror (E_TOO_FEW_PARMS);
746 /* decorate parameter */
747 resultType = defParm ? getResultTypeFromType (defParm->etype) :
749 *actParm = decorateType (*actParm, resultType);
751 if (IS_VOID((*actParm)->ftype))
753 werror (E_VOID_VALUE_USED);
757 /* If this is a varargs function... */
758 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
763 if (IS_CAST_OP (*actParm)
764 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
766 /* Parameter was explicitly typecast; don't touch it. */
770 ftype = (*actParm)->ftype;
772 /* If it's a char, upcast to int. */
773 if (IS_INTEGRAL (ftype)
774 && (getSize (ftype) < (unsigned) INTSIZE))
776 newType = newAst_LINK(INTTYPE);
779 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
781 newType = newAst_LINK (copyLinkChain(ftype));
782 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
785 if (IS_AGGREGATE (ftype))
787 newType = newAst_LINK (copyLinkChain (ftype));
788 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
793 /* cast required; change this op to a cast. */
794 (*actParm)->decorated = 0;
795 *actParm = newNode (CAST, newType, *actParm);
796 (*actParm)->lineno = (*actParm)->right->lineno;
798 decorateType (*actParm, RESULT_TYPE_NONE);
803 /* if defined parameters ended but actual has not & */
805 if (!defParm && *actParm &&
806 (options.stackAuto || IFFUNC_ISREENT (functype)))
809 resolveSymbols (*actParm);
811 /* the parameter type must be at least castable */
812 if (compareType (defParm->type, (*actParm)->ftype) == 0)
814 werror (E_INCOMPAT_TYPES);
815 printFromToType ((*actParm)->ftype, defParm->type);
819 /* if the parameter is castable then add the cast */
820 if (compareType (defParm->type, (*actParm)->ftype) < 0)
824 resultType = getResultTypeFromType (defParm->etype);
825 pTree = resolveSymbols (copyAst (*actParm));
827 /* now change the current one to a cast */
828 (*actParm)->type = EX_OP;
829 (*actParm)->opval.op = CAST;
830 (*actParm)->left = newAst_LINK (defParm->type);
831 (*actParm)->right = pTree;
832 (*actParm)->decorated = 0; /* force typechecking */
833 decorateType (*actParm, resultType);
836 /* make a copy and change the regparm type to the defined parm */
837 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
838 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
839 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
844 /*-----------------------------------------------------------------*/
845 /* createIvalType - generates ival for basic types */
846 /*-----------------------------------------------------------------*/
848 createIvalType (ast * sym, sym_link * type, initList * ilist)
852 /* if initList is deep */
853 if (ilist->type == INIT_DEEP)
854 ilist = ilist->init.deep;
856 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
857 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
860 /*-----------------------------------------------------------------*/
861 /* createIvalStruct - generates initial value for structures */
862 /*-----------------------------------------------------------------*/
864 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
871 sflds = SPEC_STRUCT (type)->fields;
872 if (ilist->type != INIT_DEEP)
874 werror (E_INIT_STRUCT, "");
878 iloop = ilist->init.deep;
880 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
882 /* if we have come to end */
886 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
887 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
888 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
892 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
893 W_EXCESS_INITIALIZERS, "struct",
894 sym->opval.val->sym->name);
901 /*-----------------------------------------------------------------*/
902 /* createIvalArray - generates code for array initialization */
903 /*-----------------------------------------------------------------*/
905 createIvalArray (ast * sym, sym_link * type, initList * ilist)
909 int lcnt = 0, size = 0;
910 literalList *literalL;
912 /* take care of the special case */
913 /* array of characters can be init */
915 if (IS_CHAR (type->next))
916 if ((rast = createIvalCharPtr (sym,
918 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
920 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
922 /* not the special case */
923 if (ilist->type != INIT_DEEP)
925 werror (E_INIT_STRUCT, "");
929 iloop = ilist->init.deep;
930 lcnt = DCL_ELEM (type);
932 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
936 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
938 rast = newNode(ARRAYINIT, aSym, NULL);
939 rast->values.constlist = literalL;
941 // Make sure size is set to length of initializer list.
948 if (lcnt && size > lcnt)
950 // Array size was specified, and we have more initializers than needed.
951 char *name=sym->opval.val->sym->name;
952 int lineno=sym->opval.val->sym->lineDef;
953 char *filename=sym->opval.val->sym->fileDef;
955 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
964 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
965 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
966 rast = createIval (aSym, type->next, iloop, rast);
967 iloop = (iloop ? iloop->next : NULL);
973 /* no of elements given and we */
974 /* have generated for all of them */
977 // is this a better way? at least it won't crash
978 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
979 int lineno = iloop->lineno;
980 char *filename = iloop->filename;
981 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
988 /* if we have not been given a size */
989 if (!DCL_ELEM (type))
991 /* but this still updates the typedef instead of the instance ! see bug 770487 */
992 DCL_ELEM (type) = size;
995 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
999 /*-----------------------------------------------------------------*/
1000 /* createIvalCharPtr - generates initial values for char pointers */
1001 /*-----------------------------------------------------------------*/
1003 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1007 /* if this is a pointer & right is a literal array then */
1008 /* just assignment will do */
1009 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1010 SPEC_SCLS (iexpr->etype) == S_CODE)
1011 && IS_ARRAY (iexpr->ftype)))
1012 return newNode ('=', sym, iexpr);
1014 /* left side is an array so we have to assign each */
1016 if ((IS_LITERAL (iexpr->etype) ||
1017 SPEC_SCLS (iexpr->etype) == S_CODE)
1018 && IS_ARRAY (iexpr->ftype))
1020 /* for each character generate an assignment */
1021 /* to the array element */
1022 char *s = SPEC_CVAL (iexpr->etype).v_char;
1024 int size = getSize (iexpr->ftype);
1025 int symsize = getSize (type);
1029 if (size>(symsize+1))
1030 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1031 "string", sym->opval.val->sym->name);
1035 for (i=0;i<size;i++)
1037 rast = newNode (NULLOP,
1041 newAst_VALUE (valueFromLit ((float) i))),
1042 newAst_VALUE (valueFromLit (*s))));
1046 // now WE don't need iexpr's symbol anymore
1047 freeStringSymbol(AST_SYMBOL(iexpr));
1049 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1055 /*-----------------------------------------------------------------*/
1056 /* createIvalPtr - generates initial value for pointers */
1057 /*-----------------------------------------------------------------*/
1059 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1065 if (ilist->type == INIT_DEEP)
1066 ilist = ilist->init.deep;
1068 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1070 /* if character pointer */
1071 if (IS_CHAR (type->next))
1072 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1075 return newNode ('=', sym, iexpr);
1078 /*-----------------------------------------------------------------*/
1079 /* createIval - generates code for initial value */
1080 /*-----------------------------------------------------------------*/
1082 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1089 /* if structure then */
1090 if (IS_STRUCT (type))
1091 rast = createIvalStruct (sym, type, ilist);
1093 /* if this is a pointer */
1095 rast = createIvalPtr (sym, type, ilist);
1097 /* if this is an array */
1098 if (IS_ARRAY (type))
1099 rast = createIvalArray (sym, type, ilist);
1101 /* if type is SPECIFIER */
1103 rast = createIvalType (sym, type, ilist);
1106 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1108 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1111 /*-----------------------------------------------------------------*/
1112 /* initAggregates - initialises aggregate variables with initv */
1113 /*-----------------------------------------------------------------*/
1114 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1115 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1118 /*-----------------------------------------------------------------*/
1119 /* gatherAutoInit - creates assignment expressions for initial */
1121 /*-----------------------------------------------------------------*/
1123 gatherAutoInit (symbol * autoChain)
1130 for (sym = autoChain; sym; sym = sym->next)
1133 /* resolve the symbols in the ival */
1135 resolveIvalSym (sym->ival, sym->type);
1138 /* if we are PIC16 port,
1139 * and this is a static,
1140 * and have initial value,
1141 * and not S_CODE, don't emit in gs segment,
1142 * but allow glue.c:pic16emitRegularMap to put symbol
1143 * in idata section */
1144 if(TARGET_IS_PIC16 &&
1145 IS_STATIC (sym->etype) && sym->ival
1146 && SPEC_SCLS(sym->etype) != S_CODE) {
1147 SPEC_SCLS (sym->etype) = S_DATA;
1152 /* if this is a static variable & has an */
1153 /* initial value the code needs to be lifted */
1154 /* here to the main portion since they can be */
1155 /* initialised only once at the start */
1156 if (IS_STATIC (sym->etype) && sym->ival &&
1157 SPEC_SCLS (sym->etype) != S_CODE)
1161 /* insert the symbol into the symbol table */
1162 /* with level = 0 & name = rname */
1163 newSym = copySymbol (sym);
1164 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1166 /* now lift the code to main */
1167 if (IS_AGGREGATE (sym->type)) {
1168 work = initAggregates (sym, sym->ival, NULL);
1170 if (getNelements(sym->type, sym->ival)>1) {
1171 werrorfl (sym->fileDef, sym->lineDef,
1172 W_EXCESS_INITIALIZERS, "scalar",
1175 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1176 list2expr (sym->ival));
1179 setAstLineno (work, sym->lineDef);
1183 staticAutos = newNode (NULLOP, staticAutos, work);
1190 /* if there is an initial value */
1191 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1193 initList *ilist=sym->ival;
1195 while (ilist->type == INIT_DEEP) {
1196 ilist = ilist->init.deep;
1199 /* update lineno for error msg */
1200 lineno=sym->lineDef;
1201 setAstLineno (ilist->init.node, lineno);
1203 if (IS_AGGREGATE (sym->type)) {
1204 work = initAggregates (sym, sym->ival, NULL);
1206 if (getNelements(sym->type, sym->ival)>1) {
1207 werrorfl (sym->fileDef, sym->lineDef,
1208 W_EXCESS_INITIALIZERS, "scalar",
1211 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1212 list2expr (sym->ival));
1216 setAstLineno (work, sym->lineDef);
1220 init = newNode (NULLOP, init, work);
1229 /*-----------------------------------------------------------------*/
1230 /* freeStringSymbol - delete a literal string if no more usage */
1231 /*-----------------------------------------------------------------*/
1232 void freeStringSymbol(symbol *sym) {
1233 /* make sure this is a literal string */
1234 assert (sym->isstrlit);
1235 if (--sym->isstrlit == 0) { // lower the usage count
1236 memmap *segment=SPEC_OCLS(sym->etype);
1238 deleteSetItem(&segment->syms, sym);
1243 /*-----------------------------------------------------------------*/
1244 /* stringToSymbol - creates a symbol from a literal string */
1245 /*-----------------------------------------------------------------*/
1247 stringToSymbol (value * val)
1249 char name[SDCC_NAME_MAX + 1];
1250 static int charLbl = 0;
1255 // have we heard this before?
1256 for (sp=statsg->syms; sp; sp=sp->next) {
1258 size = getSize (sym->type);
1259 if (sym->isstrlit && size == getSize (val->type) &&
1260 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1261 // yes, this is old news. Don't publish it again.
1262 sym->isstrlit++; // but raise the usage count
1263 return symbolVal(sym);
1267 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1268 sym = newSymbol (name, 0); /* make it @ level 0 */
1269 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1271 /* copy the type from the value passed */
1272 sym->type = copyLinkChain (val->type);
1273 sym->etype = getSpec (sym->type);
1274 /* change to storage class & output class */
1275 SPEC_SCLS (sym->etype) = S_CODE;
1276 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1277 SPEC_STAT (sym->etype) = 1;
1278 /* make the level & block = 0 */
1279 sym->block = sym->level = 0;
1281 /* create an ival */
1282 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1287 allocVariables (sym);
1290 return symbolVal (sym);
1294 /*-----------------------------------------------------------------*/
1295 /* processBlockVars - will go thru the ast looking for block if */
1296 /* a block is found then will allocate the syms */
1297 /* will also gather the auto inits present */
1298 /*-----------------------------------------------------------------*/
1300 processBlockVars (ast * tree, int *stack, int action)
1305 /* if this is a block */
1306 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1310 if (action == ALLOCATE)
1312 *stack += allocVariables (tree->values.sym);
1313 autoInit = gatherAutoInit (tree->values.sym);
1315 /* if there are auto inits then do them */
1317 tree->left = newNode (NULLOP, autoInit, tree->left);
1319 else /* action is deallocate */
1320 deallocLocal (tree->values.sym);
1323 processBlockVars (tree->left, stack, action);
1324 processBlockVars (tree->right, stack, action);
1329 /*-------------------------------------------------------------*/
1330 /* constExprTree - returns TRUE if this tree is a constant */
1332 /*-------------------------------------------------------------*/
1333 bool constExprTree (ast *cexpr) {
1339 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1341 switch (cexpr->type)
1344 if (IS_AST_LIT_VALUE(cexpr)) {
1345 // this is a literal
1348 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1349 // a function's address will never change
1352 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1353 // an array's address will never change
1356 if (IS_AST_SYM_VALUE(cexpr) &&
1357 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1358 // a symbol in code space will never change
1359 // This is only for the 'char *s="hallo"' case and will have to leave
1360 //printf(" code space symbol");
1365 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1366 "unexpected link in expression tree\n");
1369 if (cexpr->opval.op==ARRAYINIT) {
1370 // this is a list of literals
1373 if (cexpr->opval.op=='=') {
1374 return constExprTree(cexpr->right);
1376 if (cexpr->opval.op==CAST) {
1377 // cast ignored, maybe we should throw a warning here?
1378 return constExprTree(cexpr->right);
1380 if (cexpr->opval.op=='&') {
1383 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1386 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1391 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1396 /*-----------------------------------------------------------------*/
1397 /* constExprValue - returns the value of a constant expression */
1398 /* or NULL if it is not a constant expression */
1399 /*-----------------------------------------------------------------*/
1401 constExprValue (ast * cexpr, int check)
1403 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1405 /* if this is not a constant then */
1406 if (!IS_LITERAL (cexpr->ftype))
1408 /* then check if this is a literal array
1410 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1411 SPEC_CVAL (cexpr->etype).v_char &&
1412 IS_ARRAY (cexpr->ftype))
1414 value *val = valFromType (cexpr->ftype);
1415 SPEC_SCLS (val->etype) = S_LITERAL;
1416 val->sym = cexpr->opval.val->sym;
1417 val->sym->type = copyLinkChain (cexpr->ftype);
1418 val->sym->etype = getSpec (val->sym->type);
1419 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1423 /* if we are casting a literal value then */
1424 if (IS_AST_OP (cexpr) &&
1425 cexpr->opval.op == CAST &&
1426 IS_LITERAL (cexpr->right->ftype))
1428 return valCastLiteral (cexpr->ftype,
1429 floatFromVal (cexpr->right->opval.val));
1432 if (IS_AST_VALUE (cexpr))
1434 return cexpr->opval.val;
1438 werror (E_CONST_EXPECTED, "found expression");
1443 /* return the value */
1444 return cexpr->opval.val;
1448 /*-----------------------------------------------------------------*/
1449 /* isLabelInAst - will return true if a given label is found */
1450 /*-----------------------------------------------------------------*/
1452 isLabelInAst (symbol * label, ast * tree)
1454 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1457 if (IS_AST_OP (tree) &&
1458 tree->opval.op == LABEL &&
1459 isSymbolEqual (AST_SYMBOL (tree->left), label))
1462 return isLabelInAst (label, tree->right) &&
1463 isLabelInAst (label, tree->left);
1467 /*-----------------------------------------------------------------*/
1468 /* isLoopCountable - return true if the loop count can be determi- */
1469 /* -ned at compile time . */
1470 /*-----------------------------------------------------------------*/
1472 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1473 symbol ** sym, ast ** init, ast ** end)
1476 /* the loop is considered countable if the following
1477 conditions are true :-
1479 a) initExpr :- <sym> = <const>
1480 b) condExpr :- <sym> < <const1>
1481 c) loopExpr :- <sym> ++
1484 /* first check the initExpr */
1485 if (IS_AST_OP (initExpr) &&
1486 initExpr->opval.op == '=' && /* is assignment */
1487 IS_AST_SYM_VALUE (initExpr->left))
1488 { /* left is a symbol */
1490 *sym = AST_SYMBOL (initExpr->left);
1491 *init = initExpr->right;
1496 /* for now the symbol has to be of
1498 if (!IS_INTEGRAL ((*sym)->type))
1501 /* now check condExpr */
1502 if (IS_AST_OP (condExpr))
1505 switch (condExpr->opval.op)
1508 if (IS_AST_SYM_VALUE (condExpr->left) &&
1509 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1510 IS_AST_LIT_VALUE (condExpr->right))
1512 *end = condExpr->right;
1518 if (IS_AST_OP (condExpr->left) &&
1519 condExpr->left->opval.op == '>' &&
1520 IS_AST_LIT_VALUE (condExpr->left->right) &&
1521 IS_AST_SYM_VALUE (condExpr->left->left) &&
1522 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1525 *end = newNode ('+', condExpr->left->right,
1526 newAst_VALUE (constVal ("1")));
1537 /* check loop expression is of the form <sym>++ */
1538 if (!IS_AST_OP (loopExpr))
1541 /* check if <sym> ++ */
1542 if (loopExpr->opval.op == INC_OP)
1548 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1549 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1556 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1557 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1565 if (loopExpr->opval.op == ADD_ASSIGN)
1568 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1569 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1570 IS_AST_LIT_VALUE (loopExpr->right) &&
1571 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1579 /*-----------------------------------------------------------------*/
1580 /* astHasVolatile - returns true if ast contains any volatile */
1581 /*-----------------------------------------------------------------*/
1583 astHasVolatile (ast * tree)
1588 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1591 if (IS_AST_OP (tree))
1592 return astHasVolatile (tree->left) ||
1593 astHasVolatile (tree->right);
1598 /*-----------------------------------------------------------------*/
1599 /* astHasPointer - return true if the ast contains any ptr variable */
1600 /*-----------------------------------------------------------------*/
1602 astHasPointer (ast * tree)
1607 if (IS_AST_LINK (tree))
1610 /* if we hit an array expression then check
1611 only the left side */
1612 if (IS_AST_OP (tree) && tree->opval.op == '[')
1613 return astHasPointer (tree->left);
1615 if (IS_AST_VALUE (tree))
1616 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1618 return astHasPointer (tree->left) ||
1619 astHasPointer (tree->right);
1623 /*-----------------------------------------------------------------*/
1624 /* astHasSymbol - return true if the ast has the given symbol */
1625 /*-----------------------------------------------------------------*/
1627 astHasSymbol (ast * tree, symbol * sym)
1629 if (!tree || IS_AST_LINK (tree))
1632 if (IS_AST_VALUE (tree))
1634 if (IS_AST_SYM_VALUE (tree))
1635 return isSymbolEqual (AST_SYMBOL (tree), sym);
1640 return astHasSymbol (tree->left, sym) ||
1641 astHasSymbol (tree->right, sym);
1644 /*-----------------------------------------------------------------*/
1645 /* astHasDeref - return true if the ast has an indirect access */
1646 /*-----------------------------------------------------------------*/
1648 astHasDeref (ast * tree)
1650 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1653 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1655 return astHasDeref (tree->left) || astHasDeref (tree->right);
1658 /*-----------------------------------------------------------------*/
1659 /* isConformingBody - the loop body has to conform to a set of rules */
1660 /* for the loop to be considered reversible read on for rules */
1661 /*-----------------------------------------------------------------*/
1663 isConformingBody (ast * pbody, symbol * sym, ast * body)
1666 /* we are going to do a pre-order traversal of the
1667 tree && check for the following conditions. (essentially
1668 a set of very shallow tests )
1669 a) the sym passed does not participate in
1670 any arithmetic operation
1671 b) There are no function calls
1672 c) all jumps are within the body
1673 d) address of loop control variable not taken
1674 e) if an assignment has a pointer on the
1675 left hand side make sure right does not have
1676 loop control variable */
1678 /* if we reach the end or a leaf then true */
1679 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1682 /* if anything else is "volatile" */
1683 if (IS_VOLATILE (TETYPE (pbody)))
1686 /* we will walk the body in a pre-order traversal for
1688 switch (pbody->opval.op)
1690 /*------------------------------------------------------------------*/
1692 // if the loopvar is used as an index
1693 /* array op is commutative -- must check both left & right */
1694 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1697 return isConformingBody (pbody->right, sym, body)
1698 && isConformingBody (pbody->left, sym, body);
1700 /*------------------------------------------------------------------*/
1705 /*------------------------------------------------------------------*/
1709 /* sure we are not sym is not modified */
1711 IS_AST_SYM_VALUE (pbody->left) &&
1712 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1716 IS_AST_SYM_VALUE (pbody->right) &&
1717 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1722 /*------------------------------------------------------------------*/
1724 case '*': /* can be unary : if right is null then unary operation */
1729 /* if right is NULL then unary operation */
1730 /*------------------------------------------------------------------*/
1731 /*----------------------------*/
1733 /*----------------------------*/
1736 if (IS_AST_SYM_VALUE (pbody->left) &&
1737 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1740 return isConformingBody (pbody->left, sym, body);
1744 if (astHasSymbol (pbody->left, sym) ||
1745 astHasSymbol (pbody->right, sym))
1750 /*------------------------------------------------------------------*/
1758 if (IS_AST_SYM_VALUE (pbody->left) &&
1759 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1762 if (IS_AST_SYM_VALUE (pbody->right) &&
1763 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1766 return isConformingBody (pbody->left, sym, body) &&
1767 isConformingBody (pbody->right, sym, body);
1775 if (IS_AST_SYM_VALUE (pbody->left) &&
1776 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1778 return isConformingBody (pbody->left, sym, body);
1780 /*------------------------------------------------------------------*/
1792 case SIZEOF: /* evaluate wihout code generation */
1794 if (IS_AST_SYM_VALUE (pbody->left) &&
1795 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1798 if (IS_AST_SYM_VALUE (pbody->right) &&
1799 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1802 return isConformingBody (pbody->left, sym, body) &&
1803 isConformingBody (pbody->right, sym, body);
1805 /*------------------------------------------------------------------*/
1808 /* if left has a pointer & right has loop
1809 control variable then we cannot */
1810 if (astHasPointer (pbody->left) &&
1811 astHasSymbol (pbody->right, sym))
1813 if (astHasVolatile (pbody->left))
1816 if (IS_AST_SYM_VALUE (pbody->left)) {
1817 // if the loopvar has an assignment
1818 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1820 // if the loopvar is used in another (maybe conditional) block
1821 if (astHasSymbol (pbody->right, sym) &&
1822 (pbody->level >= body->level)) {
1827 if (astHasVolatile (pbody->left))
1830 if (astHasDeref(pbody->right)) return FALSE;
1832 return isConformingBody (pbody->left, sym, body) &&
1833 isConformingBody (pbody->right, sym, body);
1844 assert ("Parser should not have generated this\n");
1846 /*------------------------------------------------------------------*/
1847 /*----------------------------*/
1848 /* comma operator */
1849 /*----------------------------*/
1851 return isConformingBody (pbody->left, sym, body) &&
1852 isConformingBody (pbody->right, sym, body);
1854 /*------------------------------------------------------------------*/
1855 /*----------------------------*/
1857 /*----------------------------*/
1859 /* if local & not passed as paramater then ok */
1860 if (sym->level && !astHasSymbol(pbody->right,sym))
1864 /*------------------------------------------------------------------*/
1865 /*----------------------------*/
1866 /* return statement */
1867 /*----------------------------*/
1872 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1877 if (astHasSymbol (pbody->left, sym))
1884 return isConformingBody (pbody->left, sym, body) &&
1885 isConformingBody (pbody->right, sym, body);
1891 /*-----------------------------------------------------------------*/
1892 /* isLoopReversible - takes a for loop as input && returns true */
1893 /* if the for loop is reversible. If yes will set the value of */
1894 /* the loop control var & init value & termination value */
1895 /*-----------------------------------------------------------------*/
1897 isLoopReversible (ast * loop, symbol ** loopCntrl,
1898 ast ** init, ast ** end)
1900 /* if option says don't do it then don't */
1901 if (optimize.noLoopReverse)
1903 /* there are several tests to determine this */
1905 /* for loop has to be of the form
1906 for ( <sym> = <const1> ;
1907 [<sym> < <const2>] ;
1908 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1910 if (!isLoopCountable (AST_FOR (loop, initExpr),
1911 AST_FOR (loop, condExpr),
1912 AST_FOR (loop, loopExpr),
1913 loopCntrl, init, end))
1916 /* now do some serious checking on the body of the loop
1919 return isConformingBody (loop->left, *loopCntrl, loop->left);
1923 /*-----------------------------------------------------------------*/
1924 /* replLoopSym - replace the loop sym by loop sym -1 */
1925 /*-----------------------------------------------------------------*/
1927 replLoopSym (ast * body, symbol * sym)
1930 if (!body || IS_AST_LINK (body))
1933 if (IS_AST_SYM_VALUE (body))
1936 if (isSymbolEqual (AST_SYMBOL (body), sym))
1940 body->opval.op = '-';
1941 body->left = newAst_VALUE (symbolVal (sym));
1942 body->right = newAst_VALUE (constVal ("1"));
1950 replLoopSym (body->left, sym);
1951 replLoopSym (body->right, sym);
1955 /*-----------------------------------------------------------------*/
1956 /* reverseLoop - do the actual loop reversal */
1957 /*-----------------------------------------------------------------*/
1959 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1963 /* create the following tree
1968 if (sym) goto for_continue ;
1971 /* put it together piece by piece */
1972 rloop = newNode (NULLOP,
1973 createIf (newAst_VALUE (symbolVal (sym)),
1975 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1978 newAst_VALUE (symbolVal (sym)),
1981 replLoopSym (loop->left, sym);
1982 setAstLineno (rloop, init->lineno);
1984 rloop = newNode (NULLOP,
1986 newAst_VALUE (symbolVal (sym)),
1987 newNode ('-', end, init)),
1988 createLabel (AST_FOR (loop, continueLabel),
1992 newNode (SUB_ASSIGN,
1993 newAst_VALUE (symbolVal (sym)),
1994 newAst_VALUE (constVal ("1"))),
1997 rloop->lineno=init->lineno;
1998 return decorateType (rloop, RESULT_TYPE_NONE);
2002 /*-----------------------------------------------------------------*/
2003 /* searchLitOp - search tree (*ops only) for an ast with literal */
2004 /*-----------------------------------------------------------------*/
2006 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2010 if (tree && optimize.global_cse)
2012 /* is there a literal operand? */
2014 IS_AST_OP(tree->right) &&
2015 tree->right->right &&
2016 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2018 if (IS_LITERAL (RTYPE (tree->right)) !=
2019 IS_LITERAL (LTYPE (tree->right)))
2021 tree->right->decorated = 0;
2022 tree->decorated = 0;
2026 ret = searchLitOp (tree->right, parent, ops);
2031 IS_AST_OP(tree->left) &&
2032 tree->left->right &&
2033 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2035 if (IS_LITERAL (RTYPE (tree->left)) !=
2036 IS_LITERAL (LTYPE (tree->left)))
2038 tree->left->decorated = 0;
2039 tree->decorated = 0;
2043 ret = searchLitOp (tree->left, parent, ops);
2051 /*-----------------------------------------------------------------*/
2052 /* getResultFromType */
2053 /*-----------------------------------------------------------------*/
2055 getResultTypeFromType (sym_link *type)
2057 /* type = getSpec (type); */
2059 return RESULT_TYPE_BIT;
2060 if (IS_BITFIELD (type))
2062 int blen = SPEC_BLEN (type);
2065 return RESULT_TYPE_BIT;
2067 return RESULT_TYPE_CHAR;
2068 return RESULT_TYPE_INT;
2071 return RESULT_TYPE_CHAR;
2074 return RESULT_TYPE_INT;
2075 return RESULT_TYPE_OTHER;
2078 /*-----------------------------------------------------------------*/
2079 /* addCast - adds casts to a type specified by RESULT_TYPE */
2080 /*-----------------------------------------------------------------*/
2082 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2085 bool upCasted = FALSE;
2089 case RESULT_TYPE_NONE:
2090 /* char: promote to int */
2092 getSize (tree->etype) >= INTSIZE)
2094 newLink = newIntLink();
2097 case RESULT_TYPE_CHAR:
2098 if (IS_CHAR (tree->etype) ||
2099 IS_FLOAT(tree->etype))
2101 newLink = newCharLink();
2103 case RESULT_TYPE_INT:
2105 if (getSize (tree->etype) > INTSIZE)
2107 /* warn ("Loosing significant digits"); */
2111 /* char: promote to int */
2113 getSize (tree->etype) >= INTSIZE)
2115 newLink = newIntLink();
2118 case RESULT_TYPE_OTHER:
2121 /* return type is long, float: promote char to int */
2122 if (getSize (tree->etype) >= INTSIZE)
2124 newLink = newIntLink();
2130 tree->decorated = 0;
2131 tree = newNode (CAST, newAst_LINK (newLink), tree);
2132 tree->lineno = tree->right->lineno;
2133 /* keep unsigned type during cast to smaller type,
2134 but not when promoting from char to int */
2136 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2137 return decorateType (tree, resultType);
2140 /*-----------------------------------------------------------------*/
2141 /* resultTypePropagate - decides if resultType can be propagated */
2142 /*-----------------------------------------------------------------*/
2144 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2146 switch (tree->opval.op)
2162 return RESULT_TYPE_NONE;
2166 return RESULT_TYPE_IFX;
2168 return RESULT_TYPE_NONE;
2172 /*-----------------------------------------------------------------*/
2173 /* getLeftResultType - gets type from left branch for propagation */
2174 /*-----------------------------------------------------------------*/
2176 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2178 switch (tree->opval.op)
2182 if (IS_PTR (LTYPE (tree)))
2183 return RESULT_TYPE_NONE;
2185 return getResultTypeFromType (LETYPE (tree));
2187 if (IS_PTR (currFunc->type->next))
2188 return RESULT_TYPE_NONE;
2190 return getResultTypeFromType (currFunc->type->next);
2192 if (!IS_ARRAY (LTYPE (tree)))
2194 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2195 return RESULT_TYPE_CHAR;
2202 /*--------------------------------------------------------------------*/
2203 /* decorateType - compute type for this tree, also does type checking.*/
2204 /* This is done bottom up, since type has to flow upwards. */
2205 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2206 /* result is a char and the operand(s) are int's. */
2207 /* It also does constant folding, and parameter checking. */
2208 /*--------------------------------------------------------------------*/
2210 decorateType (ast * tree, RESULT_TYPE resultType)
2214 RESULT_TYPE resultTypeProp;
2219 /* if already has type then do nothing */
2220 if (tree->decorated)
2223 tree->decorated = 1;
2226 /* print the line */
2227 /* if not block & function */
2228 if (tree->type == EX_OP &&
2229 (tree->opval.op != FUNCTION &&
2230 tree->opval.op != BLOCK &&
2231 tree->opval.op != NULLOP))
2233 filename = tree->filename;
2234 lineno = tree->lineno;
2238 /* if any child is an error | this one is an error do nothing */
2239 if (tree->isError ||
2240 (tree->left && tree->left->isError) ||
2241 (tree->right && tree->right->isError))
2244 /*------------------------------------------------------------------*/
2245 /*----------------------------*/
2246 /* leaf has been reached */
2247 /*----------------------------*/
2248 lineno=tree->lineno;
2249 /* if this is of type value */
2250 /* just get the type */
2251 if (tree->type == EX_VALUE)
2254 if (IS_LITERAL (tree->opval.val->etype))
2257 /* if this is a character array then declare it */
2258 if (IS_ARRAY (tree->opval.val->type))
2259 tree->opval.val = stringToSymbol (tree->opval.val);
2261 /* otherwise just copy the type information */
2262 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2266 if (tree->opval.val->sym)
2268 /* if the undefined flag is set then give error message */
2269 if (tree->opval.val->sym->undefined)
2271 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2273 TTYPE (tree) = TETYPE (tree) =
2274 tree->opval.val->type = tree->opval.val->sym->type =
2275 tree->opval.val->etype = tree->opval.val->sym->etype =
2276 copyLinkChain (INTTYPE);
2281 /* if impilicit i.e. struct/union member then no type */
2282 if (tree->opval.val->sym->implicit)
2283 TTYPE (tree) = TETYPE (tree) = NULL;
2288 /* else copy the type */
2289 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2291 /* and mark it as referenced */
2292 tree->opval.val->sym->isref = 1;
2300 /* if type link for the case of cast */
2301 if (tree->type == EX_LINK)
2303 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2311 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2313 if (tree->left && tree->left->type == EX_OPERAND
2314 && (tree->left->opval.op == INC_OP
2315 || tree->left->opval.op == DEC_OP)
2316 && tree->left->left)
2318 tree->left->right = tree->left->left;
2319 tree->left->left = NULL;
2321 if (tree->right && tree->right->type == EX_OPERAND
2322 && (tree->right->opval.op == INC_OP
2323 || tree->right->opval.op == DEC_OP)
2324 && tree->right->left)
2326 tree->right->right = tree->right->left;
2327 tree->right->left = NULL;
2332 /* Before decorating the left branch we've to decide in dependence
2333 upon tree->opval.op, if resultType can be propagated */
2334 resultTypeProp = resultTypePropagate (tree, resultType);
2336 if (tree->opval.op == '?')
2337 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2339 dtl = decorateType (tree->left, resultTypeProp);
2341 /* if an array node, we may need to swap branches */
2342 if (tree->opval.op == '[')
2344 /* determine which is the array & which the index */
2345 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2346 IS_INTEGRAL (LTYPE (tree)))
2348 ast *tempTree = tree->left;
2349 tree->left = tree->right;
2350 tree->right = tempTree;
2354 /* After decorating the left branch there's type information available
2355 in tree->left->?type. If the op is e.g. '=' we extract the type
2356 information from there and propagate it to the right branch. */
2357 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2359 switch (tree->opval.op)
2362 /* delay right side for '?' operator since conditional macro
2363 expansions might rely on this */
2367 /* decorate right side for CALL (parameter list) in processParms();
2368 there is resultType available */
2372 dtr = decorateType (tree->right, resultTypeProp);
2376 /* this is to take care of situations
2377 when the tree gets rewritten */
2378 if (dtl != tree->left)
2380 if (dtr != tree->right)
2382 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2386 /* depending on type of operator do */
2388 switch (tree->opval.op)
2390 /*------------------------------------------------------------------*/
2391 /*----------------------------*/
2393 /*----------------------------*/
2396 /* first check if this is a array or a pointer */
2397 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2399 werror (E_NEED_ARRAY_PTR, "[]");
2400 goto errorTreeReturn;
2403 /* check if the type of the idx */
2404 if (!IS_INTEGRAL (RTYPE (tree)))
2406 werror (E_IDX_NOT_INT);
2407 goto errorTreeReturn;
2410 /* if the left is an rvalue then error */
2413 werror (E_LVALUE_REQUIRED, "array access");
2414 goto errorTreeReturn;
2417 if (IS_LITERAL (RTYPE (tree)))
2419 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2420 int arraySize = DCL_ELEM (LTYPE (tree));
2421 if (arraySize && arrayIndex >= arraySize)
2423 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2428 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2431 /*------------------------------------------------------------------*/
2432 /*----------------------------*/
2434 /*----------------------------*/
2436 /* if this is not a structure */
2437 if (!IS_STRUCT (LTYPE (tree)))
2439 werror (E_STRUCT_UNION, ".");
2440 goto errorTreeReturn;
2442 TTYPE (tree) = structElemType (LTYPE (tree),
2443 (tree->right->type == EX_VALUE ?
2444 tree->right->opval.val : NULL));
2445 TETYPE (tree) = getSpec (TTYPE (tree));
2448 /*------------------------------------------------------------------*/
2449 /*----------------------------*/
2450 /* struct/union pointer */
2451 /*----------------------------*/
2453 /* if not pointer to a structure */
2454 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2456 werror (E_PTR_REQD);
2457 goto errorTreeReturn;
2460 if (!IS_STRUCT (LTYPE (tree)->next))
2462 werror (E_STRUCT_UNION, "->");
2463 goto errorTreeReturn;
2466 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2467 (tree->right->type == EX_VALUE ?
2468 tree->right->opval.val : NULL));
2469 TETYPE (tree) = getSpec (TTYPE (tree));
2471 /* adjust the storage class */
2472 switch (DCL_TYPE(tree->left->ftype)) {
2474 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2477 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2480 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2483 SPEC_SCLS (TETYPE (tree)) = 0;
2486 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2489 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2492 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2495 SPEC_SCLS (TETYPE (tree)) = 0;
2502 /* This breaks with extern declarations, bitfields, and perhaps other */
2503 /* cases (gcse). Let's leave this optimization disabled for now and */
2504 /* ponder if there's a safe way to do this. -- EEP */
2506 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2507 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2509 /* If defined struct type at addr var
2510 then rewrite (&struct var)->member
2512 and define membertype at (addr+offsetof(struct var,member)) temp
2515 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2516 AST_SYMBOL(tree->right));
2518 sym = newSymbol(genSymName (0), 0);
2519 sym->type = TTYPE (tree);
2520 sym->etype = getSpec(sym->type);
2521 sym->lineDef = tree->lineno;
2524 SPEC_STAT (sym->etype) = 1;
2525 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2527 SPEC_ABSA(sym->etype) = 1;
2528 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2531 AST_VALUE (tree) = symbolVal(sym);
2534 tree->type = EX_VALUE;
2542 /*------------------------------------------------------------------*/
2543 /*----------------------------*/
2544 /* ++/-- operation */
2545 /*----------------------------*/
2549 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2550 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2551 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2552 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2561 /*------------------------------------------------------------------*/
2562 /*----------------------------*/
2564 /*----------------------------*/
2565 case '&': /* can be unary */
2566 /* if right is NULL then unary operation */
2567 if (tree->right) /* not an unary operation */
2570 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2572 werror (E_BITWISE_OP);
2573 werror (W_CONTINUE, "left & right types are ");
2574 printTypeChain (LTYPE (tree), stderr);
2575 fprintf (stderr, ",");
2576 printTypeChain (RTYPE (tree), stderr);
2577 fprintf (stderr, "\n");
2578 goto errorTreeReturn;
2581 /* if they are both literal */
2582 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2584 tree->type = EX_VALUE;
2585 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2586 valFromType (RETYPE (tree)), '&');
2588 tree->right = tree->left = NULL;
2589 TETYPE (tree) = tree->opval.val->etype;
2590 TTYPE (tree) = tree->opval.val->type;
2594 /* see if this is a GETHBIT operation if yes
2597 ast *otree = optimizeGetHbit (tree);
2600 return decorateType (otree, RESULT_TYPE_NONE);
2603 /* if left is a literal exchange left & right */
2604 if (IS_LITERAL (LTYPE (tree)))
2606 ast *tTree = tree->left;
2607 tree->left = tree->right;
2608 tree->right = tTree;
2611 /* if right is a literal and */
2612 /* we can find a 2nd literal in an and-tree then */
2613 /* rearrange the tree */
2614 if (IS_LITERAL (RTYPE (tree)))
2617 ast *litTree = searchLitOp (tree, &parent, "&");
2621 ast *tTree = litTree->left;
2622 litTree->left = tree->right;
2623 tree->right = tTree;
2624 /* both operands in litTree are literal now */
2625 decorateType (parent, resultType);
2629 LRVAL (tree) = RRVAL (tree) = 1;
2631 TTYPE (tree) = computeType (LTYPE (tree),
2635 TETYPE (tree) = getSpec (TTYPE (tree));
2640 /*------------------------------------------------------------------*/
2641 /*----------------------------*/
2643 /*----------------------------*/
2644 p = newLink (DECLARATOR);
2645 /* if bit field then error */
2646 if (IS_BITVAR (tree->left->etype))
2648 werror (E_ILLEGAL_ADDR, "address of bit variable");
2649 goto errorTreeReturn;
2652 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2654 werror (E_ILLEGAL_ADDR, "address of register variable");
2655 goto errorTreeReturn;
2658 if (IS_FUNC (LTYPE (tree)))
2660 // this ought to be ignored
2661 return (tree->left);
2664 if (IS_LITERAL(LTYPE(tree)))
2666 werror (E_ILLEGAL_ADDR, "address of literal");
2667 goto errorTreeReturn;
2672 werror (E_LVALUE_REQUIRED, "address of");
2673 goto errorTreeReturn;
2676 DCL_TYPE (p) = POINTER;
2677 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2678 DCL_TYPE (p) = CPOINTER;
2679 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2680 DCL_TYPE (p) = FPOINTER;
2681 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2682 DCL_TYPE (p) = PPOINTER;
2683 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2684 DCL_TYPE (p) = IPOINTER;
2685 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2686 DCL_TYPE (p) = EEPPOINTER;
2687 else if (SPEC_OCLS(tree->left->etype))
2688 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2690 DCL_TYPE (p) = POINTER;
2692 if (IS_AST_SYM_VALUE (tree->left))
2694 AST_SYMBOL (tree->left)->addrtaken = 1;
2695 AST_SYMBOL (tree->left)->allocreq = 1;
2698 p->next = LTYPE (tree);
2700 TETYPE (tree) = getSpec (TTYPE (tree));
2705 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2706 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2708 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2709 AST_SYMBOL(tree->left->right));
2710 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2711 valueFromLit(element->offset));
2714 tree->type = EX_VALUE;
2715 tree->values.literalFromCast = 1;
2721 /*------------------------------------------------------------------*/
2722 /*----------------------------*/
2724 /*----------------------------*/
2726 /* if the rewrite succeeds then don't go any furthur */
2728 ast *wtree = optimizeRRCRLC (tree);
2730 return decorateType (wtree, RESULT_TYPE_NONE);
2732 wtree = optimizeSWAP (tree);
2734 return decorateType (wtree, RESULT_TYPE_NONE);
2737 /* if left is a literal exchange left & right */
2738 if (IS_LITERAL (LTYPE (tree)))
2740 ast *tTree = tree->left;
2741 tree->left = tree->right;
2742 tree->right = tTree;
2745 /* if right is a literal and */
2746 /* we can find a 2nd literal in an or-tree then */
2747 /* rearrange the tree */
2748 if (IS_LITERAL (RTYPE (tree)))
2751 ast *litTree = searchLitOp (tree, &parent, "|");
2755 ast *tTree = litTree->left;
2756 litTree->left = tree->right;
2757 tree->right = tTree;
2758 /* both operands in tTree are literal now */
2759 decorateType (parent, resultType);
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2767 /*----------------------------*/
2769 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2771 werror (E_BITWISE_OP);
2772 werror (W_CONTINUE, "left & right types are ");
2773 printTypeChain (LTYPE (tree), stderr);
2774 fprintf (stderr, ",");
2775 printTypeChain (RTYPE (tree), stderr);
2776 fprintf (stderr, "\n");
2777 goto errorTreeReturn;
2780 /* if they are both literal then rewrite the tree */
2781 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2783 tree->type = EX_VALUE;
2784 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2785 valFromType (RETYPE (tree)),
2787 tree->right = tree->left = NULL;
2788 TETYPE (tree) = tree->opval.val->etype;
2789 TTYPE (tree) = tree->opval.val->type;
2793 /* if left is a literal exchange left & right */
2794 if (IS_LITERAL (LTYPE (tree)))
2796 ast *tTree = tree->left;
2797 tree->left = tree->right;
2798 tree->right = tTree;
2801 /* if right is a literal and */
2802 /* we can find a 2nd literal in a xor-tree then */
2803 /* rearrange the tree */
2804 if (IS_LITERAL (RTYPE (tree)) &&
2805 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2808 ast *litTree = searchLitOp (tree, &parent, "^");
2812 ast *tTree = litTree->left;
2813 litTree->left = tree->right;
2814 tree->right = tTree;
2815 /* both operands in litTree are literal now */
2816 decorateType (parent, resultType);
2820 LRVAL (tree) = RRVAL (tree) = 1;
2822 TTYPE (tree) = computeType (LTYPE (tree),
2826 TETYPE (tree) = getSpec (TTYPE (tree));
2830 /*------------------------------------------------------------------*/
2831 /*----------------------------*/
2833 /*----------------------------*/
2835 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2837 werror (E_INVALID_OP, "divide");
2838 goto errorTreeReturn;
2840 /* if they are both literal then */
2841 /* rewrite the tree */
2842 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2844 tree->type = EX_VALUE;
2845 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2846 valFromType (RETYPE (tree)));
2847 tree->right = tree->left = NULL;
2848 TETYPE (tree) = getSpec (TTYPE (tree) =
2849 tree->opval.val->type);
2853 LRVAL (tree) = RRVAL (tree) = 1;
2855 TETYPE (tree) = getSpec (TTYPE (tree) =
2856 computeType (LTYPE (tree),
2861 /* if right is a literal and */
2862 /* left is also a division by a literal then */
2863 /* rearrange the tree */
2864 if (IS_LITERAL (RTYPE (tree))
2865 /* avoid infinite loop */
2866 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2869 ast *litTree = searchLitOp (tree, &parent, "/");
2872 if (IS_LITERAL (RTYPE (litTree)))
2876 litTree->right = newNode ('*',
2878 copyAst (tree->right));
2879 litTree->right->lineno = tree->lineno;
2881 tree->right->opval.val = constVal ("1");
2882 decorateType (parent, resultType);
2886 /* litTree->left is literal: no gcse possible.
2887 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2888 this would cause an infinit loop. */
2889 parent->decorated = 1;
2890 decorateType (litTree, resultType);
2897 /*------------------------------------------------------------------*/
2898 /*----------------------------*/
2900 /*----------------------------*/
2902 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2904 werror (E_BITWISE_OP);
2905 werror (W_CONTINUE, "left & right types are ");
2906 printTypeChain (LTYPE (tree), stderr);
2907 fprintf (stderr, ",");
2908 printTypeChain (RTYPE (tree), stderr);
2909 fprintf (stderr, "\n");
2910 goto errorTreeReturn;
2912 /* if they are both literal then */
2913 /* rewrite the tree */
2914 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2916 tree->type = EX_VALUE;
2917 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2918 valFromType (RETYPE (tree)));
2919 tree->right = tree->left = NULL;
2920 TETYPE (tree) = getSpec (TTYPE (tree) =
2921 tree->opval.val->type);
2924 LRVAL (tree) = RRVAL (tree) = 1;
2925 TETYPE (tree) = getSpec (TTYPE (tree) =
2926 computeType (LTYPE (tree),
2932 /*------------------------------------------------------------------*/
2933 /*----------------------------*/
2934 /* address dereference */
2935 /*----------------------------*/
2936 case '*': /* can be unary : if right is null then unary operation */
2939 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2941 werror (E_PTR_REQD);
2942 goto errorTreeReturn;
2947 werror (E_LVALUE_REQUIRED, "pointer deref");
2948 goto errorTreeReturn;
2950 if (IS_ADDRESS_OF_OP(tree->left))
2952 /* replace *&obj with obj */
2953 return tree->left->left;
2955 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2956 TETYPE (tree) = getSpec (TTYPE (tree));
2957 /* adjust the storage class */
2958 switch (DCL_TYPE(tree->left->ftype)) {
2960 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2963 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2966 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2969 SPEC_SCLS (TETYPE (tree)) = 0;
2972 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2975 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2978 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2981 SPEC_SCLS (TETYPE (tree)) = 0;
2990 /*------------------------------------------------------------------*/
2991 /*----------------------------*/
2992 /* multiplication */
2993 /*----------------------------*/
2994 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2996 werror (E_INVALID_OP, "multiplication");
2997 goto errorTreeReturn;
3000 /* if they are both literal then */
3001 /* rewrite the tree */
3002 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3004 tree->type = EX_VALUE;
3005 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3006 valFromType (RETYPE (tree)));
3007 tree->right = tree->left = NULL;
3008 TETYPE (tree) = getSpec (TTYPE (tree) =
3009 tree->opval.val->type);
3013 /* if left is a literal exchange left & right */
3014 if (IS_LITERAL (LTYPE (tree)))
3016 ast *tTree = tree->left;
3017 tree->left = tree->right;
3018 tree->right = tTree;
3021 /* if right is a literal and */
3022 /* we can find a 2nd literal in a mul-tree then */
3023 /* rearrange the tree */
3024 if (IS_LITERAL (RTYPE (tree)))
3027 ast *litTree = searchLitOp (tree, &parent, "*");
3031 ast *tTree = litTree->left;
3032 litTree->left = tree->right;
3033 tree->right = tTree;
3034 /* both operands in litTree are literal now */
3035 decorateType (parent, resultType);
3039 LRVAL (tree) = RRVAL (tree) = 1;
3040 tree->left = addCast (tree->left, resultType, FALSE);
3041 tree->right = addCast (tree->right, resultType, FALSE);
3042 TETYPE (tree) = getSpec (TTYPE (tree) =
3043 computeType (LTYPE (tree),
3050 /*------------------------------------------------------------------*/
3051 /*----------------------------*/
3052 /* unary '+' operator */
3053 /*----------------------------*/
3058 if (!IS_ARITHMETIC (LTYPE (tree)))
3060 werror (E_UNARY_OP, '+');
3061 goto errorTreeReturn;
3064 /* if left is a literal then do it */
3065 if (IS_LITERAL (LTYPE (tree)))
3067 tree->type = EX_VALUE;
3068 tree->opval.val = valFromType (LETYPE (tree));
3070 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3074 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3078 /*------------------------------------------------------------------*/
3079 /*----------------------------*/
3081 /*----------------------------*/
3083 /* this is not a unary operation */
3084 /* if both pointers then problem */
3085 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3086 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3088 werror (E_PTR_PLUS_PTR);
3089 goto errorTreeReturn;
3092 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3093 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3095 werror (E_PLUS_INVALID, "+");
3096 goto errorTreeReturn;
3099 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3100 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3102 werror (E_PLUS_INVALID, "+");
3103 goto errorTreeReturn;
3105 /* if they are both literal then */
3106 /* rewrite the tree */
3107 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3109 tree->type = EX_VALUE;
3110 tree->left = addCast (tree->left, resultType, TRUE);
3111 tree->right = addCast (tree->right, resultType, TRUE);
3112 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3113 valFromType (RETYPE (tree)));
3114 tree->right = tree->left = NULL;
3115 TETYPE (tree) = getSpec (TTYPE (tree) =
3116 tree->opval.val->type);
3120 /* if the right is a pointer or left is a literal
3121 xchange left & right */
3122 if (IS_ARRAY (RTYPE (tree)) ||
3123 IS_PTR (RTYPE (tree)) ||
3124 IS_LITERAL (LTYPE (tree)))
3126 ast *tTree = tree->left;
3127 tree->left = tree->right;
3128 tree->right = tTree;
3131 /* if right is a literal and */
3132 /* left is also an addition/subtraction with a literal then */
3133 /* rearrange the tree */
3134 if (IS_LITERAL (RTYPE (tree)))
3136 ast *litTree, *parent;
3137 litTree = searchLitOp (tree, &parent, "+-");
3140 if (litTree->opval.op == '+')
3144 ast *tTree = litTree->left;
3145 litTree->left = tree->right;
3146 tree->right = tree->left;
3149 else if (litTree->opval.op == '-')
3151 if (IS_LITERAL (RTYPE (litTree)))
3155 ast *tTree = litTree->left;
3156 litTree->left = tree->right;
3157 tree->right = tTree;
3163 ast *tTree = litTree->right;
3164 litTree->right = tree->right;
3165 tree->right = tTree;
3166 litTree->opval.op = '+';
3167 tree->opval.op = '-';
3170 decorateType (parent, resultType);
3174 LRVAL (tree) = RRVAL (tree) = 1;
3175 /* if the left is a pointer */
3176 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3177 TETYPE (tree) = getSpec (TTYPE (tree) =
3181 tree->left = addCast (tree->left, resultType, TRUE);
3182 tree->right = addCast (tree->right, resultType, TRUE);
3183 TETYPE (tree) = getSpec (TTYPE (tree) =
3184 computeType (LTYPE (tree),
3192 /*------------------------------------------------------------------*/
3193 /*----------------------------*/
3195 /*----------------------------*/
3196 case '-': /* can be unary */
3197 /* if right is null then unary */
3201 if (!IS_ARITHMETIC (LTYPE (tree)))
3203 werror (E_UNARY_OP, tree->opval.op);
3204 goto errorTreeReturn;
3207 /* if left is a literal then do it */
3208 if (IS_LITERAL (LTYPE (tree)))
3210 tree->type = EX_VALUE;
3211 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3213 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3214 SPEC_USIGN(TETYPE(tree)) = 0;
3218 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3222 /*------------------------------------------------------------------*/
3223 /*----------------------------*/
3225 /*----------------------------*/
3227 if (!(IS_PTR (LTYPE (tree)) ||
3228 IS_ARRAY (LTYPE (tree)) ||
3229 IS_ARITHMETIC (LTYPE (tree))))
3231 werror (E_PLUS_INVALID, "-");
3232 goto errorTreeReturn;
3235 if (!(IS_PTR (RTYPE (tree)) ||
3236 IS_ARRAY (RTYPE (tree)) ||
3237 IS_ARITHMETIC (RTYPE (tree))))
3239 werror (E_PLUS_INVALID, "-");
3240 goto errorTreeReturn;
3243 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3244 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3245 IS_INTEGRAL (RTYPE (tree))))
3247 werror (E_PLUS_INVALID, "-");
3248 goto errorTreeReturn;
3251 /* if they are both literal then */
3252 /* rewrite the tree */
3253 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3255 tree->type = EX_VALUE;
3256 tree->left = addCast (tree->left, resultType, TRUE);
3257 tree->right = addCast (tree->right, resultType, TRUE);
3258 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3259 valFromType (RETYPE (tree)));
3260 tree->right = tree->left = NULL;
3261 TETYPE (tree) = getSpec (TTYPE (tree) =
3262 tree->opval.val->type);
3266 /* if the left & right are equal then zero */
3267 if (isAstEqual (tree->left, tree->right))
3269 tree->type = EX_VALUE;
3270 tree->left = tree->right = NULL;
3271 tree->opval.val = constVal ("0");
3272 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3276 /* if both of them are pointers or arrays then */
3277 /* the result is going to be an integer */
3278 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3279 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3280 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3282 /* if only the left is a pointer */
3283 /* then result is a pointer */
3284 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3285 TETYPE (tree) = getSpec (TTYPE (tree) =
3289 tree->left = addCast (tree->left, resultType, TRUE);
3290 tree->right = addCast (tree->right, resultType, TRUE);
3292 TETYPE (tree) = getSpec (TTYPE (tree) =
3293 computeType (LTYPE (tree),
3299 LRVAL (tree) = RRVAL (tree) = 1;
3301 /* if right is a literal and */
3302 /* left is also an addition/subtraction with a literal then */
3303 /* rearrange the tree */
3304 if (IS_LITERAL (RTYPE (tree))
3305 /* avoid infinite loop */
3306 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3308 ast *litTree, *litParent;
3309 litTree = searchLitOp (tree, &litParent, "+-");
3312 if (litTree->opval.op == '+')
3316 ast *tTree = litTree->left;
3317 litTree->left = litTree->right;
3318 litTree->right = tree->right;
3319 tree->right = tTree;
3320 tree->opval.op = '+';
3321 litTree->opval.op = '-';
3323 else if (litTree->opval.op == '-')
3325 if (IS_LITERAL (RTYPE (litTree)))
3329 ast *tTree = litTree->left;
3330 litTree->left = tree->right;
3331 tree->right = litParent->left;
3332 litParent->left = tTree;
3333 litTree->opval.op = '+';
3335 tree->decorated = 0;
3336 decorateType (tree, resultType);
3342 ast *tTree = litTree->right;
3343 litTree->right = tree->right;
3344 tree->right = tTree;
3347 decorateType (litParent, resultType);
3352 /*------------------------------------------------------------------*/
3353 /*----------------------------*/
3355 /*----------------------------*/
3357 /* can be only integral type */
3358 if (!IS_INTEGRAL (LTYPE (tree)))
3360 werror (E_UNARY_OP, tree->opval.op);
3361 goto errorTreeReturn;
3364 /* if left is a literal then do it */
3365 if (IS_LITERAL (LTYPE (tree)))
3367 tree->type = EX_VALUE;
3368 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3370 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3371 return addCast (tree, resultType, TRUE);
3373 tree->left = addCast (tree->left, resultType, TRUE);
3375 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3378 /*------------------------------------------------------------------*/
3379 /*----------------------------*/
3381 /*----------------------------*/
3383 /* can be pointer */
3384 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3385 !IS_PTR (LTYPE (tree)) &&
3386 !IS_ARRAY (LTYPE (tree)))
3388 werror (E_UNARY_OP, tree->opval.op);
3389 goto errorTreeReturn;
3392 /* if left is a literal then do it */
3393 if (IS_LITERAL (LTYPE (tree)))
3395 tree->type = EX_VALUE;
3396 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3398 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3402 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3405 /*------------------------------------------------------------------*/
3406 /*----------------------------*/
3408 /*----------------------------*/
3412 TTYPE (tree) = LTYPE (tree);
3413 TETYPE (tree) = LETYPE (tree);
3417 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3422 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3424 werror (E_SHIFT_OP_INVALID);
3425 werror (W_CONTINUE, "left & right types are ");
3426 printTypeChain (LTYPE (tree), stderr);
3427 fprintf (stderr, ",");
3428 printTypeChain (RTYPE (tree), stderr);
3429 fprintf (stderr, "\n");
3430 goto errorTreeReturn;
3433 /* make smaller type only if it's a LEFT_OP */
3434 if (tree->opval.op == LEFT_OP)
3435 tree->left = addCast (tree->left, resultType, TRUE);
3437 /* if they are both literal then */
3438 /* rewrite the tree */
3439 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3441 tree->type = EX_VALUE;
3442 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3443 valFromType (RETYPE (tree)),
3444 (tree->opval.op == LEFT_OP ? 1 : 0));
3445 tree->right = tree->left = NULL;
3446 TETYPE (tree) = getSpec (TTYPE (tree) =
3447 tree->opval.val->type);
3451 LRVAL (tree) = RRVAL (tree) = 1;
3452 if (tree->opval.op == LEFT_OP)
3454 TETYPE (tree) = getSpec (TTYPE (tree) =
3455 computeType (LTYPE (tree),
3462 /* no promotion necessary */
3463 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3464 if (IS_LITERAL (TTYPE (tree)))
3465 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3468 /* if only the right side is a literal & we are
3469 shifting more than size of the left operand then zero */
3470 if (IS_LITERAL (RTYPE (tree)) &&
3471 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3472 (getSize (TETYPE (tree)) * 8))
3474 if (tree->opval.op==LEFT_OP ||
3475 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3477 lineno=tree->lineno;
3478 werror (W_SHIFT_CHANGED,
3479 (tree->opval.op == LEFT_OP ? "left" : "right"));
3480 tree->type = EX_VALUE;
3481 tree->left = tree->right = NULL;
3482 tree->opval.val = constVal ("0");
3483 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3490 /*------------------------------------------------------------------*/
3491 /*----------------------------*/
3493 /*----------------------------*/
3494 case CAST: /* change the type */
3495 /* cannot cast to an aggregate type */
3496 if (IS_AGGREGATE (LTYPE (tree)))
3498 werror (E_CAST_ILLEGAL);
3499 goto errorTreeReturn;
3502 /* make sure the type is complete and sane */
3503 changePointer(LTYPE(tree));
3504 checkTypeSanity(LETYPE(tree), "(cast)");
3506 /* If code memory is read only, then pointers to code memory */
3507 /* implicitly point to constants -- make this explicit */
3509 sym_link *t = LTYPE(tree);
3510 while (t && t->next)
3512 if (IS_CODEPTR(t) && port->mem.code_ro)
3514 if (IS_SPEC(t->next))
3515 SPEC_CONST (t->next) = 1;
3517 DCL_PTR_CONST (t->next) = 1;
3524 /* if the right is a literal replace the tree */
3525 if (IS_LITERAL (RETYPE (tree))) {
3526 if (!IS_PTR (LTYPE (tree))) {
3527 tree->type = EX_VALUE;
3529 valCastLiteral (LTYPE (tree),
3530 floatFromVal (valFromType (RETYPE (tree))));
3533 TTYPE (tree) = tree->opval.val->type;
3534 tree->values.literalFromCast = 1;
3535 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3536 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3537 sym_link *rest = LTYPE(tree)->next;
3538 werror(W_LITERAL_GENERIC);
3539 TTYPE(tree) = newLink(DECLARATOR);
3540 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3541 TTYPE(tree)->next = rest;
3542 tree->left->opval.lnk = TTYPE(tree);
3545 TTYPE (tree) = LTYPE (tree);
3549 TTYPE (tree) = LTYPE (tree);
3553 #if 0 // this is already checked, now this could be explicit
3554 /* if pointer to struct then check names */
3555 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3556 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3557 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3559 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3560 SPEC_STRUCT(LETYPE(tree))->tag);
3563 if (IS_ADDRESS_OF_OP(tree->right)
3564 && IS_AST_SYM_VALUE (tree->right->left)
3565 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3567 tree->type = EX_VALUE;
3569 valCastLiteral (LTYPE (tree),
3570 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3571 TTYPE (tree) = tree->opval.val->type;
3572 TETYPE (tree) = getSpec (TTYPE (tree));
3575 tree->values.literalFromCast = 1;
3579 /* handle offsetof macro: */
3580 /* #define offsetof(TYPE, MEMBER) \ */
3581 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3582 if (IS_ADDRESS_OF_OP(tree->right)
3583 && IS_AST_OP (tree->right->left)
3584 && tree->right->left->opval.op == PTR_OP
3585 && IS_AST_OP (tree->right->left->left)
3586 && tree->right->left->left->opval.op == CAST
3587 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3589 symbol *element = getStructElement (
3590 SPEC_STRUCT (LETYPE(tree->right->left)),
3591 AST_SYMBOL(tree->right->left->right)
3595 tree->type = EX_VALUE;
3596 tree->opval.val = valCastLiteral (
3599 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3602 TTYPE (tree) = tree->opval.val->type;
3603 TETYPE (tree) = getSpec (TTYPE (tree));
3610 /* if the right is a literal replace the tree */
3611 if (IS_LITERAL (RETYPE (tree))) {
3613 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3614 /* rewrite (type *)litaddr
3616 and define type at litaddr temp
3617 (but only if type's storage class is not generic)
3619 ast *newTree = newNode ('&', NULL, NULL);
3622 TTYPE (newTree) = LTYPE (tree);
3623 TETYPE (newTree) = getSpec(LTYPE (tree));
3625 /* define a global symbol at the casted address*/
3626 sym = newSymbol(genSymName (0), 0);
3627 sym->type = LTYPE (tree)->next;
3629 sym->type = newLink (V_VOID);
3630 sym->etype = getSpec(sym->type);
3631 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3632 sym->lineDef = tree->lineno;
3635 SPEC_STAT (sym->etype) = 1;
3636 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3637 SPEC_ABSA(sym->etype) = 1;
3638 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3641 newTree->left = newAst_VALUE(symbolVal(sym));
3642 newTree->left->lineno = tree->lineno;
3643 LTYPE (newTree) = sym->type;
3644 LETYPE (newTree) = sym->etype;
3645 LLVAL (newTree) = 1;
3646 LRVAL (newTree) = 0;
3647 TLVAL (newTree) = 1;
3651 if (!IS_PTR (LTYPE (tree))) {
3652 tree->type = EX_VALUE;
3654 valCastLiteral (LTYPE (tree),
3655 floatFromVal (valFromType (RTYPE (tree))));
3656 TTYPE (tree) = tree->opval.val->type;
3659 tree->values.literalFromCast = 1;
3660 TETYPE (tree) = getSpec (TTYPE (tree));
3664 TTYPE (tree) = LTYPE (tree);
3668 TETYPE (tree) = getSpec (TTYPE (tree));
3672 /*------------------------------------------------------------------*/
3673 /*----------------------------*/
3674 /* logical &&, || */
3675 /*----------------------------*/
3678 /* each must be arithmetic type or be a pointer */
3679 if (!IS_PTR (LTYPE (tree)) &&
3680 !IS_ARRAY (LTYPE (tree)) &&
3681 !IS_INTEGRAL (LTYPE (tree)))
3683 werror (E_COMPARE_OP);
3684 goto errorTreeReturn;
3687 if (!IS_PTR (RTYPE (tree)) &&
3688 !IS_ARRAY (RTYPE (tree)) &&
3689 !IS_INTEGRAL (RTYPE (tree)))
3691 werror (E_COMPARE_OP);
3692 goto errorTreeReturn;
3694 /* if they are both literal then */
3695 /* rewrite the tree */
3696 if (IS_LITERAL (RTYPE (tree)) &&
3697 IS_LITERAL (LTYPE (tree)))
3699 tree->type = EX_VALUE;
3700 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3701 valFromType (RTYPE (tree)),
3703 tree->right = tree->left = NULL;
3704 TETYPE (tree) = getSpec (TTYPE (tree) =
3705 tree->opval.val->type);
3708 LRVAL (tree) = RRVAL (tree) = 1;
3709 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3712 /*------------------------------------------------------------------*/
3713 /*----------------------------*/
3714 /* comparison operators */
3715 /*----------------------------*/
3723 ast *lt = optimizeCompare (tree);
3729 /* if they are pointers they must be castable */
3730 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3732 if (tree->opval.op==EQ_OP &&
3733 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3734 // we cannot cast a gptr to a !gptr: switch the leaves
3735 struct ast *s=tree->left;
3736 tree->left=tree->right;
3739 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3741 werror (E_COMPARE_OP);
3742 fprintf (stderr, "comparing type ");
3743 printTypeChain (LTYPE (tree), stderr);
3744 fprintf (stderr, "to type ");
3745 printTypeChain (RTYPE (tree), stderr);
3746 fprintf (stderr, "\n");
3747 goto errorTreeReturn;
3750 /* else they should be promotable to one another */
3753 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3754 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3756 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3758 werror (E_COMPARE_OP);
3759 fprintf (stderr, "comparing type ");
3760 printTypeChain (LTYPE (tree), stderr);
3761 fprintf (stderr, "to type ");
3762 printTypeChain (RTYPE (tree), stderr);
3763 fprintf (stderr, "\n");
3764 goto errorTreeReturn;
3767 /* if unsigned value < 0 then always false */
3768 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3769 if (SPEC_USIGN(LETYPE(tree)) &&
3770 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3771 IS_LITERAL(RTYPE(tree)) &&
3772 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3774 if (tree->opval.op == '<')
3778 if (tree->opval.op == '>')
3780 if (resultType == RESULT_TYPE_IFX)
3782 /* the parent is an ifx: */
3783 /* if (unsigned value) */
3787 /* (unsigned value) ? 1 : 0 */
3788 tree->opval.op = '?';
3789 tree->right = newNode (':',
3790 newAst_VALUE (constVal ("1")),
3791 tree->right); /* val 0 */
3792 tree->right->lineno = tree->lineno;
3793 tree->right->left->lineno = tree->lineno;
3794 decorateType (tree->right, RESULT_TYPE_NONE);
3797 /* if they are both literal then */
3798 /* rewrite the tree */
3799 if (IS_LITERAL (RTYPE (tree)) &&
3800 IS_LITERAL (LTYPE (tree)))
3802 tree->type = EX_VALUE;
3803 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3804 valFromType (RETYPE (tree)),
3806 tree->right = tree->left = NULL;
3807 TETYPE (tree) = getSpec (TTYPE (tree) =
3808 tree->opval.val->type);
3811 LRVAL (tree) = RRVAL (tree) = 1;
3812 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3815 /*------------------------------------------------------------------*/
3816 /*----------------------------*/
3818 /*----------------------------*/
3819 case SIZEOF: /* evaluate wihout code generation */
3820 /* change the type to a integer */
3822 int size = getSize (tree->right->ftype);
3823 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3824 if (!size && !IS_VOID(tree->right->ftype))
3825 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3827 tree->type = EX_VALUE;
3828 tree->opval.val = constVal (buffer);
3829 tree->right = tree->left = NULL;
3830 TETYPE (tree) = getSpec (TTYPE (tree) =
3831 tree->opval.val->type);
3834 /*------------------------------------------------------------------*/
3835 /*----------------------------*/
3837 /*----------------------------*/
3839 /* return typeof enum value */
3840 tree->type = EX_VALUE;
3843 if (IS_SPEC(tree->right->ftype)) {
3844 switch (SPEC_NOUN(tree->right->ftype)) {
3846 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3847 else typeofv = TYPEOF_INT;
3850 typeofv = TYPEOF_FLOAT;
3853 typeofv = TYPEOF_CHAR;
3856 typeofv = TYPEOF_VOID;
3859 typeofv = TYPEOF_STRUCT;
3862 typeofv = TYPEOF_BITFIELD;
3865 typeofv = TYPEOF_BIT;
3868 typeofv = TYPEOF_SBIT;
3874 switch (DCL_TYPE(tree->right->ftype)) {
3876 typeofv = TYPEOF_POINTER;
3879 typeofv = TYPEOF_FPOINTER;
3882 typeofv = TYPEOF_CPOINTER;
3885 typeofv = TYPEOF_GPOINTER;
3888 typeofv = TYPEOF_PPOINTER;
3891 typeofv = TYPEOF_IPOINTER;
3894 typeofv = TYPEOF_ARRAY;
3897 typeofv = TYPEOF_FUNCTION;
3903 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3904 tree->opval.val = constVal (buffer);
3905 tree->right = tree->left = NULL;
3906 TETYPE (tree) = getSpec (TTYPE (tree) =
3907 tree->opval.val->type);
3910 /*------------------------------------------------------------------*/
3911 /*----------------------------*/
3912 /* conditional operator '?' */
3913 /*----------------------------*/
3915 /* the type is value of the colon operator (on the right) */
3916 assert (IS_COLON_OP (tree->right));
3917 /* if already known then replace the tree : optimizer will do it
3918 but faster to do it here */
3919 if (IS_LITERAL (LTYPE (tree)))
3921 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3922 return decorateType (tree->right->left, resultTypeProp);
3924 return decorateType (tree->right->right, resultTypeProp);
3928 tree->right = decorateType (tree->right, resultTypeProp);
3929 TTYPE (tree) = RTYPE (tree);
3930 TETYPE (tree) = getSpec (TTYPE (tree));
3935 /* if they don't match we have a problem */
3936 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
3937 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
3939 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3940 goto errorTreeReturn;
3943 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3944 resultType, tree->opval.op);
3945 TETYPE (tree) = getSpec (TTYPE (tree));
3949 #if 0 // assignment operators are converted by the parser
3950 /*------------------------------------------------------------------*/
3951 /*----------------------------*/
3952 /* assignment operators */
3953 /*----------------------------*/
3956 /* for these it must be both must be integral */
3957 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3958 !IS_ARITHMETIC (RTYPE (tree)))
3960 werror (E_OPS_INTEGRAL);
3961 goto errorTreeReturn;
3964 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3966 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3967 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3971 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3972 goto errorTreeReturn;
3983 /* for these it must be both must be integral */
3984 if (!IS_INTEGRAL (LTYPE (tree)) ||
3985 !IS_INTEGRAL (RTYPE (tree)))
3987 werror (E_OPS_INTEGRAL);
3988 goto errorTreeReturn;
3991 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3993 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3994 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3998 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3999 goto errorTreeReturn;
4005 /*------------------------------------------------------------------*/
4006 /*----------------------------*/
4008 /*----------------------------*/
4010 if (!(IS_PTR (LTYPE (tree)) ||
4011 IS_ARITHMETIC (LTYPE (tree))))
4013 werror (E_PLUS_INVALID, "-=");
4014 goto errorTreeReturn;
4017 if (!(IS_PTR (RTYPE (tree)) ||
4018 IS_ARITHMETIC (RTYPE (tree))))
4020 werror (E_PLUS_INVALID, "-=");
4021 goto errorTreeReturn;
4024 TETYPE (tree) = getSpec (TTYPE (tree) =
4025 computeType (LTYPE (tree),
4030 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4031 werror (E_CODE_WRITE, "-=");
4035 werror (E_LVALUE_REQUIRED, "-=");
4036 goto errorTreeReturn;
4042 /*------------------------------------------------------------------*/
4043 /*----------------------------*/
4045 /*----------------------------*/
4047 /* this is not a unary operation */
4048 /* if both pointers then problem */
4049 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4051 werror (E_PTR_PLUS_PTR);
4052 goto errorTreeReturn;
4055 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4057 werror (E_PLUS_INVALID, "+=");
4058 goto errorTreeReturn;
4061 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4063 werror (E_PLUS_INVALID, "+=");
4064 goto errorTreeReturn;
4067 TETYPE (tree) = getSpec (TTYPE (tree) =
4068 computeType (LTYPE (tree),
4073 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4074 werror (E_CODE_WRITE, "+=");
4078 werror (E_LVALUE_REQUIRED, "+=");
4079 goto errorTreeReturn;
4082 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4083 tree->opval.op = '=';
4088 /*------------------------------------------------------------------*/
4089 /*----------------------------*/
4090 /* straight assignemnt */
4091 /*----------------------------*/
4093 /* cannot be an aggregate */
4094 if (IS_AGGREGATE (LTYPE (tree)))
4096 werror (E_AGGR_ASSIGN);
4097 goto errorTreeReturn;
4100 /* they should either match or be castable */
4101 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4103 werror (E_TYPE_MISMATCH, "assignment", " ");
4104 printFromToType(RTYPE(tree),LTYPE(tree));
4107 /* if the left side of the tree is of type void
4108 then report error */
4109 if (IS_VOID (LTYPE (tree)))
4111 werror (E_CAST_ZERO);
4112 printFromToType(RTYPE(tree), LTYPE(tree));
4115 TETYPE (tree) = getSpec (TTYPE (tree) =
4119 if (!tree->initMode ) {
4120 if (IS_CONSTANT(LTYPE(tree)))
4121 werror (E_CODE_WRITE, "=");
4125 werror (E_LVALUE_REQUIRED, "=");
4126 goto errorTreeReturn;
4131 /*------------------------------------------------------------------*/
4132 /*----------------------------*/
4133 /* comma operator */
4134 /*----------------------------*/
4136 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4139 /*------------------------------------------------------------------*/
4140 /*----------------------------*/
4142 /*----------------------------*/
4145 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4146 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4148 if (tree->left->opval.op == '*' && !tree->left->right)
4149 tree->left = tree->left->left;
4152 /* require a function or pointer to function */
4153 if (!IS_FUNC (LTYPE (tree))
4154 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4156 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4157 goto errorTreeReturn;
4160 /* if there are parms, make sure that
4161 parms are decorate / process / reverse only once */
4163 !tree->right->decorated)
4168 if (IS_CODEPTR(LTYPE(tree)))
4169 functype = LTYPE (tree)->next;
4171 functype = LTYPE (tree);
4173 if (processParms (tree->left, FUNC_ARGS(functype),
4174 &tree->right, &parmNumber, TRUE))
4176 goto errorTreeReturn;
4179 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4180 !IFFUNC_ISBUILTIN(functype))
4182 reverseParms (tree->right);
4185 TTYPE (tree) = functype->next;
4186 TETYPE (tree) = getSpec (TTYPE (tree));
4190 /*------------------------------------------------------------------*/
4191 /*----------------------------*/
4192 /* return statement */
4193 /*----------------------------*/
4198 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4200 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4201 printFromToType (RTYPE(tree), currFunc->type->next);
4202 goto errorTreeReturn;
4205 if (IS_VOID (currFunc->type->next)
4207 !IS_VOID (RTYPE (tree)))
4209 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4210 goto errorTreeReturn;
4213 /* if there is going to be a casting required then add it */
4214 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4217 decorateType (newNode (CAST,
4218 newAst_LINK (copyLinkChain (currFunc->type->next)),
4228 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4230 werror (W_VOID_FUNC, currFunc->name);
4231 goto errorTreeReturn;
4234 TTYPE (tree) = TETYPE (tree) = NULL;
4237 /*------------------------------------------------------------------*/
4238 /*----------------------------*/
4239 /* switch statement */
4240 /*----------------------------*/
4242 /* the switch value must be an integer */
4243 if (!IS_INTEGRAL (LTYPE (tree)))
4245 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4246 goto errorTreeReturn;
4249 TTYPE (tree) = TETYPE (tree) = NULL;
4252 /*------------------------------------------------------------------*/
4253 /*----------------------------*/
4255 /*----------------------------*/
4257 tree->left = backPatchLabels (tree->left,
4260 TTYPE (tree) = TETYPE (tree) = NULL;
4263 /*------------------------------------------------------------------*/
4264 /*----------------------------*/
4266 /*----------------------------*/
4269 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4270 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4271 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4273 /* if the for loop is reversible then
4274 reverse it otherwise do what we normally
4280 if (isLoopReversible (tree, &sym, &init, &end))
4281 return reverseLoop (tree, sym, init, end);
4283 return decorateType (createFor (AST_FOR (tree, trueLabel),
4284 AST_FOR (tree, continueLabel),
4285 AST_FOR (tree, falseLabel),
4286 AST_FOR (tree, condLabel),
4287 AST_FOR (tree, initExpr),
4288 AST_FOR (tree, condExpr),
4289 AST_FOR (tree, loopExpr),
4290 tree->left), RESULT_TYPE_NONE);
4293 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4294 "node PARAM shouldn't be processed here");
4295 /* but in processParams() */
4298 TTYPE (tree) = TETYPE (tree) = NULL;
4302 /* some error found this tree will be killed */
4304 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4305 tree->opval.op = NULLOP;
4311 /*-----------------------------------------------------------------*/
4312 /* sizeofOp - processes size of operation */
4313 /*-----------------------------------------------------------------*/
4315 sizeofOp (sym_link * type)
4320 /* make sure the type is complete and sane */
4321 checkTypeSanity(type, "(sizeof)");
4323 /* get the size and convert it to character */
4324 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4325 if (!size && !IS_VOID(type))
4326 werror (E_SIZEOF_INCOMPLETE_TYPE);
4328 /* now convert into value */
4329 return constVal (buff);
4333 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4334 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4335 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4336 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4337 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4338 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4339 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4341 /*-----------------------------------------------------------------*/
4342 /* backPatchLabels - change and or not operators to flow control */
4343 /*-----------------------------------------------------------------*/
4345 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4351 if (!(IS_ANDORNOT (tree)))
4354 /* if this an and */
4357 static int localLbl = 0;
4360 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4361 localLabel = newSymbol (buffer, NestLevel);
4363 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4365 /* if left is already a IFX then just change the if true label in that */
4366 if (!IS_IFX (tree->left))
4367 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4369 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4370 /* right is a IFX then just join */
4371 if (IS_IFX (tree->right))
4372 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4374 tree->right = createLabel (localLabel, tree->right);
4375 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4377 return newNode (NULLOP, tree->left, tree->right);
4380 /* if this is an or operation */
4383 static int localLbl = 0;
4386 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4387 localLabel = newSymbol (buffer, NestLevel);
4389 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4391 /* if left is already a IFX then just change the if true label in that */
4392 if (!IS_IFX (tree->left))
4393 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4395 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4396 /* right is a IFX then just join */
4397 if (IS_IFX (tree->right))
4398 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4400 tree->right = createLabel (localLabel, tree->right);
4401 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4403 return newNode (NULLOP, tree->left, tree->right);
4409 int wasnot = IS_NOT (tree->left);
4410 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4412 /* if the left is already a IFX */
4413 if (!IS_IFX (tree->left))
4414 tree->left = newNode (IFX, tree->left, NULL);
4418 tree->left->trueLabel = trueLabel;
4419 tree->left->falseLabel = falseLabel;
4423 tree->left->trueLabel = falseLabel;
4424 tree->left->falseLabel = trueLabel;
4431 tree->trueLabel = trueLabel;
4432 tree->falseLabel = falseLabel;
4439 /*-----------------------------------------------------------------*/
4440 /* createBlock - create expression tree for block */
4441 /*-----------------------------------------------------------------*/
4443 createBlock (symbol * decl, ast * body)
4447 /* if the block has nothing */
4451 ex = newNode (BLOCK, NULL, body);
4452 ex->values.sym = decl;
4459 /*-----------------------------------------------------------------*/
4460 /* createLabel - creates the expression tree for labels */
4461 /*-----------------------------------------------------------------*/
4463 createLabel (symbol * label, ast * stmnt)
4466 char name[SDCC_NAME_MAX + 1];
4469 /* must create fresh symbol if the symbol name */
4470 /* exists in the symbol table, since there can */
4471 /* be a variable with the same name as the labl */
4472 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4473 (csym->level == label->level))
4474 label = newSymbol (label->name, label->level);
4476 /* change the name before putting it in add _ */
4477 SNPRINTF(name, sizeof(name), "%s", label->name);
4479 /* put the label in the LabelSymbol table */
4480 /* but first check if a label of the same */
4482 if ((csym = findSym (LabelTab, NULL, name)))
4483 werror (E_DUPLICATE_LABEL, label->name);
4485 addSym (LabelTab, label, name, label->level, 0, 0);
4489 label->key = labelKey++;
4490 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4496 /*-----------------------------------------------------------------*/
4497 /* createCase - generates the parsetree for a case statement */
4498 /*-----------------------------------------------------------------*/
4500 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4502 char caseLbl[SDCC_NAME_MAX + 1];
4506 /* if the switch statement does not exist */
4507 /* then case is out of context */
4510 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4514 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4515 /* if not a constant then error */
4516 if (!IS_LITERAL (caseVal->ftype))
4518 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4522 /* if not a integer than error */
4523 if (!IS_INTEGRAL (caseVal->ftype))
4525 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4529 /* find the end of the switch values chain */
4530 if (!(val = swStat->values.switchVals.swVals))
4531 swStat->values.switchVals.swVals = caseVal->opval.val;
4534 /* also order the cases according to value */
4536 int cVal = (int) floatFromVal (caseVal->opval.val);
4537 while (val && (int) floatFromVal (val) < cVal)
4543 /* if we reached the end then */
4546 pval->next = caseVal->opval.val;
4548 else if ((int) floatFromVal (val) == cVal)
4550 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4556 /* we found a value greater than */
4557 /* the current value we must add this */
4558 /* before the value */
4559 caseVal->opval.val->next = val;
4561 /* if this was the first in chain */
4562 if (swStat->values.switchVals.swVals == val)
4563 swStat->values.switchVals.swVals =
4566 pval->next = caseVal->opval.val;
4571 /* create the case label */
4572 SNPRINTF(caseLbl, sizeof(caseLbl),
4574 swStat->values.switchVals.swNum,
4575 (int) floatFromVal (caseVal->opval.val));
4577 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4582 /*-----------------------------------------------------------------*/
4583 /* createDefault - creates the parse tree for the default statement */
4584 /*-----------------------------------------------------------------*/
4586 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4588 char defLbl[SDCC_NAME_MAX + 1];
4590 /* if the switch statement does not exist */
4591 /* then case is out of context */
4594 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4598 if (swStat->values.switchVals.swDefault)
4600 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4605 /* turn on the default flag */
4606 swStat->values.switchVals.swDefault = 1;
4608 /* create the label */
4609 SNPRINTF (defLbl, sizeof(defLbl),
4610 "_default_%d", swStat->values.switchVals.swNum);
4611 return createLabel (newSymbol (defLbl, 0), stmnt);
4614 /*-----------------------------------------------------------------*/
4615 /* createIf - creates the parsetree for the if statement */
4616 /*-----------------------------------------------------------------*/
4618 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4620 static int Lblnum = 0;
4622 symbol *ifTrue, *ifFalse, *ifEnd;
4624 /* if neither exists */
4625 if (!elseBody && !ifBody) {
4626 // if there are no side effects (i++, j() etc)
4627 if (!hasSEFcalls(condAst)) {
4632 /* create the labels */
4633 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4634 ifFalse = newSymbol (buffer, NestLevel);
4635 /* if no else body then end == false */
4640 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4641 ifEnd = newSymbol (buffer, NestLevel);
4644 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4645 ifTrue = newSymbol (buffer, NestLevel);
4649 /* attach the ifTrue label to the top of it body */
4650 ifBody = createLabel (ifTrue, ifBody);
4651 /* attach a goto end to the ifBody if else is present */
4654 ifBody = newNode (NULLOP, ifBody,
4656 newAst_VALUE (symbolVal (ifEnd)),
4658 /* put the elseLabel on the else body */
4659 elseBody = createLabel (ifFalse, elseBody);
4660 /* out the end at the end of the body */
4661 elseBody = newNode (NULLOP,
4663 createLabel (ifEnd, NULL));
4667 ifBody = newNode (NULLOP, ifBody,
4668 createLabel (ifFalse, NULL));
4670 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4671 if (IS_IFX (condAst))
4674 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4676 return newNode (NULLOP, ifTree,
4677 newNode (NULLOP, ifBody, elseBody));
4681 /*-----------------------------------------------------------------*/
4682 /* createDo - creates parse tree for do */
4685 /* _docontinue_n: */
4686 /* condition_expression +-> trueLabel -> _dobody_n */
4688 /* +-> falseLabel-> _dobreak_n */
4690 /*-----------------------------------------------------------------*/
4692 createDo (symbol * trueLabel, symbol * continueLabel,
4693 symbol * falseLabel, ast * condAst, ast * doBody)
4698 /* if the body does not exist then it is simple */
4701 condAst = backPatchLabels (condAst, continueLabel, NULL);
4702 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4703 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4704 doTree->trueLabel = continueLabel;
4705 doTree->falseLabel = NULL;
4709 /* otherwise we have a body */
4710 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4712 /* attach the body label to the top */
4713 doBody = createLabel (trueLabel, doBody);
4714 /* attach the continue label to end of body */
4715 doBody = newNode (NULLOP, doBody,
4716 createLabel (continueLabel, NULL));
4718 /* now put the break label at the end */
4719 if (IS_IFX (condAst))
4722 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4724 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4726 /* putting it together */
4727 return newNode (NULLOP, doBody, doTree);
4730 /*-----------------------------------------------------------------*/
4731 /* createFor - creates parse tree for 'for' statement */
4734 /* condExpr +-> trueLabel -> _forbody_n */
4736 /* +-> falseLabel-> _forbreak_n */
4739 /* _forcontinue_n: */
4741 /* goto _forcond_n ; */
4743 /*-----------------------------------------------------------------*/
4745 createFor (symbol * trueLabel, symbol * continueLabel,
4746 symbol * falseLabel, symbol * condLabel,
4747 ast * initExpr, ast * condExpr, ast * loopExpr,
4752 /* if loopexpression not present then we can generate it */
4753 /* the same way as a while */
4755 return newNode (NULLOP, initExpr,
4756 createWhile (trueLabel, continueLabel,
4757 falseLabel, condExpr, forBody));
4758 /* vanilla for statement */
4759 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4761 if (condExpr && !IS_IFX (condExpr))
4762 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4765 /* attach condition label to condition */
4766 condExpr = createLabel (condLabel, condExpr);
4768 /* attach body label to body */
4769 forBody = createLabel (trueLabel, forBody);
4771 /* attach continue to forLoop expression & attach */
4772 /* goto the forcond @ and of loopExpression */
4773 loopExpr = createLabel (continueLabel,
4777 newAst_VALUE (symbolVal (condLabel)),
4779 /* now start putting them together */
4780 forTree = newNode (NULLOP, initExpr, condExpr);
4781 forTree = newNode (NULLOP, forTree, forBody);
4782 forTree = newNode (NULLOP, forTree, loopExpr);
4783 /* finally add the break label */
4784 forTree = newNode (NULLOP, forTree,
4785 createLabel (falseLabel, NULL));
4789 /*-----------------------------------------------------------------*/
4790 /* createWhile - creates parse tree for while statement */
4791 /* the while statement will be created as follows */
4793 /* _while_continue_n: */
4794 /* condition_expression +-> trueLabel -> _while_boby_n */
4796 /* +-> falseLabel -> _while_break_n */
4797 /* _while_body_n: */
4799 /* goto _while_continue_n */
4800 /* _while_break_n: */
4801 /*-----------------------------------------------------------------*/
4803 createWhile (symbol * trueLabel, symbol * continueLabel,
4804 symbol * falseLabel, ast * condExpr, ast * whileBody)
4808 /* put the continue label */
4809 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4810 condExpr = createLabel (continueLabel, condExpr);
4811 condExpr->lineno = 0;
4813 /* put the body label in front of the body */
4814 whileBody = createLabel (trueLabel, whileBody);
4815 whileBody->lineno = 0;
4816 /* put a jump to continue at the end of the body */
4817 /* and put break label at the end of the body */
4818 whileBody = newNode (NULLOP,
4821 newAst_VALUE (symbolVal (continueLabel)),
4822 createLabel (falseLabel, NULL)));
4824 /* put it all together */
4825 if (IS_IFX (condExpr))
4826 whileTree = condExpr;
4829 whileTree = newNode (IFX, condExpr, NULL);
4830 /* put the true & false labels in place */
4831 whileTree->trueLabel = trueLabel;
4832 whileTree->falseLabel = falseLabel;
4835 return newNode (NULLOP, whileTree, whileBody);
4838 /*-----------------------------------------------------------------*/
4839 /* optimizeGetHbit - get highest order bit of the expression */
4840 /*-----------------------------------------------------------------*/
4842 optimizeGetHbit (ast * tree)
4845 /* if this is not a bit and */
4846 if (!IS_BITAND (tree))
4849 /* will look for tree of the form
4850 ( expr >> ((sizeof expr) -1) ) & 1 */
4851 if (!IS_AST_LIT_VALUE (tree->right))
4854 if (AST_LIT_VALUE (tree->right) != 1)
4857 if (!IS_RIGHT_OP (tree->left))
4860 if (!IS_AST_LIT_VALUE (tree->left->right))
4863 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4864 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4867 /* make sure the port supports GETHBIT */
4868 if (port->hasExtBitOp
4869 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4872 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4876 /*-----------------------------------------------------------------*/
4877 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4878 /*-----------------------------------------------------------------*/
4880 optimizeRRCRLC (ast * root)
4882 /* will look for trees of the form
4883 (?expr << 1) | (?expr >> 7) or
4884 (?expr >> 7) | (?expr << 1) will make that
4885 into a RLC : operation ..
4887 (?expr >> 1) | (?expr << 7) or
4888 (?expr << 7) | (?expr >> 1) will make that
4889 into a RRC operation
4890 note : by 7 I mean (number of bits required to hold the
4892 /* if the root operations is not a | operation the not */
4893 if (!IS_BITOR (root))
4896 /* I have to think of a better way to match patterns this sucks */
4897 /* that aside let start looking for the first case : I use a the
4898 negative check a lot to improve the efficiency */
4899 /* (?expr << 1) | (?expr >> 7) */
4900 if (IS_LEFT_OP (root->left) &&
4901 IS_RIGHT_OP (root->right))
4904 if (!SPEC_USIGN (TETYPE (root->left->left)))
4907 if (!IS_AST_LIT_VALUE (root->left->right) ||
4908 !IS_AST_LIT_VALUE (root->right->right))
4911 /* make sure it is the same expression */
4912 if (!isAstEqual (root->left->left,
4916 if (AST_LIT_VALUE (root->left->right) != 1)
4919 if (AST_LIT_VALUE (root->right->right) !=
4920 (getSize (TTYPE (root->left->left)) * 8 - 1))
4923 /* make sure the port supports RLC */
4924 if (port->hasExtBitOp
4925 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4928 /* whew got the first case : create the AST */
4929 return newNode (RLC, root->left->left, NULL);
4933 /* check for second case */
4934 /* (?expr >> 7) | (?expr << 1) */
4935 if (IS_LEFT_OP (root->right) &&
4936 IS_RIGHT_OP (root->left))
4939 if (!SPEC_USIGN (TETYPE (root->left->left)))
4942 if (!IS_AST_LIT_VALUE (root->left->right) ||
4943 !IS_AST_LIT_VALUE (root->right->right))
4946 /* make sure it is the same symbol */
4947 if (!isAstEqual (root->left->left,
4951 if (AST_LIT_VALUE (root->right->right) != 1)
4954 if (AST_LIT_VALUE (root->left->right) !=
4955 (getSize (TTYPE (root->left->left)) * 8 - 1))
4958 /* make sure the port supports RLC */
4959 if (port->hasExtBitOp
4960 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4963 /* whew got the first case : create the AST */
4964 return newNode (RLC, root->left->left, NULL);
4969 /* third case for RRC */
4970 /* (?symbol >> 1) | (?symbol << 7) */
4971 if (IS_LEFT_OP (root->right) &&
4972 IS_RIGHT_OP (root->left))
4975 if (!SPEC_USIGN (TETYPE (root->left->left)))
4978 if (!IS_AST_LIT_VALUE (root->left->right) ||
4979 !IS_AST_LIT_VALUE (root->right->right))
4982 /* make sure it is the same symbol */
4983 if (!isAstEqual (root->left->left,
4987 if (AST_LIT_VALUE (root->left->right) != 1)
4990 if (AST_LIT_VALUE (root->right->right) !=
4991 (getSize (TTYPE (root->left->left)) * 8 - 1))
4994 /* make sure the port supports RRC */
4995 if (port->hasExtBitOp
4996 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4999 /* whew got the first case : create the AST */
5000 return newNode (RRC, root->left->left, NULL);
5004 /* fourth and last case for now */
5005 /* (?symbol << 7) | (?symbol >> 1) */
5006 if (IS_RIGHT_OP (root->right) &&
5007 IS_LEFT_OP (root->left))
5010 if (!SPEC_USIGN (TETYPE (root->left->left)))
5013 if (!IS_AST_LIT_VALUE (root->left->right) ||
5014 !IS_AST_LIT_VALUE (root->right->right))
5017 /* make sure it is the same symbol */
5018 if (!isAstEqual (root->left->left,
5022 if (AST_LIT_VALUE (root->right->right) != 1)
5025 if (AST_LIT_VALUE (root->left->right) !=
5026 (getSize (TTYPE (root->left->left)) * 8 - 1))
5029 /* make sure the port supports RRC */
5030 if (port->hasExtBitOp
5031 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5034 /* whew got the first case : create the AST */
5035 return newNode (RRC, root->left->left, NULL);
5039 /* not found return root */
5043 /*-----------------------------------------------------------------*/
5044 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5045 /*-----------------------------------------------------------------*/
5047 optimizeSWAP (ast * root)
5049 /* will look for trees of the form
5050 (?expr << 4) | (?expr >> 4) or
5051 (?expr >> 4) | (?expr << 4) will make that
5052 into a SWAP : operation ..
5053 note : by 4 I mean (number of bits required to hold the
5055 /* if the root operations is not a | operation the not */
5056 if (!IS_BITOR (root))
5059 /* (?expr << 4) | (?expr >> 4) */
5060 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5061 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5064 if (!SPEC_USIGN (TETYPE (root->left->left)))
5067 if (!IS_AST_LIT_VALUE (root->left->right) ||
5068 !IS_AST_LIT_VALUE (root->right->right))
5071 /* make sure it is the same expression */
5072 if (!isAstEqual (root->left->left,
5076 if (AST_LIT_VALUE (root->left->right) !=
5077 (getSize (TTYPE (root->left->left)) * 4))
5080 if (AST_LIT_VALUE (root->right->right) !=
5081 (getSize (TTYPE (root->left->left)) * 4))
5084 /* make sure the port supports SWAP */
5085 if (port->hasExtBitOp
5086 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5089 /* found it : create the AST */
5090 return newNode (SWAP, root->left->left, NULL);
5094 /* not found return root */
5098 /*-----------------------------------------------------------------*/
5099 /* optimizeCompare - otimizes compares for bit variables */
5100 /*-----------------------------------------------------------------*/
5102 optimizeCompare (ast * root)
5104 ast *optExpr = NULL;
5107 unsigned int litValue;
5109 /* if nothing then return nothing */
5113 /* if not a compare op then do leaves */
5114 if (!IS_COMPARE_OP (root))
5116 root->left = optimizeCompare (root->left);
5117 root->right = optimizeCompare (root->right);
5121 /* if left & right are the same then depending
5122 of the operation do */
5123 if (isAstEqual (root->left, root->right))
5125 switch (root->opval.op)
5130 optExpr = newAst_VALUE (constVal ("0"));
5135 optExpr = newAst_VALUE (constVal ("1"));
5139 return decorateType (optExpr, RESULT_TYPE_NONE);
5142 vleft = (root->left->type == EX_VALUE ?
5143 root->left->opval.val : NULL);
5145 vright = (root->right->type == EX_VALUE ?
5146 root->right->opval.val : NULL);
5148 /* if left is a BITVAR in BITSPACE */
5149 /* and right is a LITERAL then opt- */
5150 /* imize else do nothing */
5151 if (vleft && vright &&
5152 IS_BITVAR (vleft->etype) &&
5153 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5154 IS_LITERAL (vright->etype))
5157 /* if right side > 1 then comparison may never succeed */
5158 if ((litValue = (int) floatFromVal (vright)) > 1)
5160 werror (W_BAD_COMPARE);
5166 switch (root->opval.op)
5168 case '>': /* bit value greater than 1 cannot be */
5169 werror (W_BAD_COMPARE);
5173 case '<': /* bit value < 1 means 0 */
5175 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5178 case LE_OP: /* bit value <= 1 means no check */
5179 optExpr = newAst_VALUE (vright);
5182 case GE_OP: /* bit value >= 1 means only check for = */
5184 optExpr = newAst_VALUE (vleft);
5189 { /* literal is zero */
5190 switch (root->opval.op)
5192 case '<': /* bit value < 0 cannot be */
5193 werror (W_BAD_COMPARE);
5197 case '>': /* bit value > 0 means 1 */
5199 optExpr = newAst_VALUE (vleft);
5202 case LE_OP: /* bit value <= 0 means no check */
5203 case GE_OP: /* bit value >= 0 means no check */
5204 werror (W_BAD_COMPARE);
5208 case EQ_OP: /* bit == 0 means ! of bit */
5209 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5213 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5214 } /* end-of-if of BITVAR */
5219 /*-----------------------------------------------------------------*/
5220 /* addSymToBlock : adds the symbol to the first block we find */
5221 /*-----------------------------------------------------------------*/
5223 addSymToBlock (symbol * sym, ast * tree)
5225 /* reached end of tree or a leaf */
5226 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5230 if (IS_AST_OP (tree) &&
5231 tree->opval.op == BLOCK)
5234 symbol *lsym = copySymbol (sym);
5236 lsym->next = AST_VALUES (tree, sym);
5237 AST_VALUES (tree, sym) = lsym;
5241 addSymToBlock (sym, tree->left);
5242 addSymToBlock (sym, tree->right);
5245 /*-----------------------------------------------------------------*/
5246 /* processRegParms - do processing for register parameters */
5247 /*-----------------------------------------------------------------*/
5249 processRegParms (value * args, ast * body)
5253 if (IS_REGPARM (args->etype))
5254 addSymToBlock (args->sym, body);
5259 /*-----------------------------------------------------------------*/
5260 /* resetParmKey - resets the operandkeys for the symbols */
5261 /*-----------------------------------------------------------------*/
5262 DEFSETFUNC (resetParmKey)
5273 /*-----------------------------------------------------------------*/
5274 /* createFunction - This is the key node that calls the iCode for */
5275 /* generating the code for a function. Note code */
5276 /* is generated function by function, later when */
5277 /* add inter-procedural analysis this will change */
5278 /*-----------------------------------------------------------------*/
5280 createFunction (symbol * name, ast * body)
5286 iCode *piCode = NULL;
5288 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5289 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5291 /* if check function return 0 then some problem */
5292 if (checkFunction (name, NULL) == 0)
5295 /* create a dummy block if none exists */
5297 body = newNode (BLOCK, NULL, NULL);
5301 /* check if the function name already in the symbol table */
5302 if ((csym = findSym (SymbolTab, NULL, name->name)))
5305 /* special case for compiler defined functions
5306 we need to add the name to the publics list : this
5307 actually means we are now compiling the compiler
5311 addSet (&publics, name);
5317 allocVariables (name);
5319 name->lastLine = mylineno;
5322 /* set the stack pointer */
5323 stackPtr = -port->stack.direction * port->stack.call_overhead;
5324 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5326 if (IFFUNC_ISISR (name->type))
5327 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5329 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5331 if (options.useXstack)
5332 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5334 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5337 fetype = getSpec (name->type); /* get the specifier for the function */
5338 /* if this is a reentrant function then */
5339 if (IFFUNC_ISREENT (name->type))
5342 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5344 /* do processing for parameters that are passed in registers */
5345 processRegParms (FUNC_ARGS(name->type), body);
5347 /* set the stack pointer */
5351 /* allocate & autoinit the block variables */
5352 processBlockVars (body, &stack, ALLOCATE);
5354 /* save the stack information */
5355 if (options.useXstack)
5356 name->xstack = SPEC_STAK (fetype) = stack;
5358 name->stack = SPEC_STAK (fetype) = stack;
5360 /* name needs to be mangled */
5361 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5363 body = resolveSymbols (body); /* resolve the symbols */
5364 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5367 ex = newAst_VALUE (symbolVal (name)); /* create name */
5368 ex = newNode (FUNCTION, ex, body);
5369 ex->values.args = FUNC_ARGS(name->type);
5371 if (options.dump_tree) PA(ex);
5374 werror (E_FUNC_NO_CODE, name->name);
5378 /* create the node & generate intermediate code */
5380 codeOutFile = code->oFile;
5381 piCode = iCodeFromAst (ex);
5385 werror (E_FUNC_NO_CODE, name->name);
5389 eBBlockFromiCode (piCode);
5391 /* if there are any statics then do them */
5394 GcurMemmap = statsg;
5395 codeOutFile = statsg->oFile;
5396 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5402 /* dealloc the block variables */
5403 processBlockVars (body, &stack, DEALLOCATE);
5404 outputDebugStackSymbols();
5405 /* deallocate paramaters */
5406 deallocParms (FUNC_ARGS(name->type));
5408 if (IFFUNC_ISREENT (name->type))
5411 /* we are done freeup memory & cleanup */
5413 if (port->reset_labelKey) labelKey = 1;
5415 FUNC_HASBODY(name->type) = 1;
5416 addSet (&operKeyReset, name);
5417 applyToSet (operKeyReset, resetParmKey);
5422 cleanUpLevel (LabelTab, 0);
5423 cleanUpBlock (StructTab, 1);
5424 cleanUpBlock (TypedefTab, 1);
5426 xstack->syms = NULL;
5427 istack->syms = NULL;
5432 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5433 /*-----------------------------------------------------------------*/
5434 /* ast_print : prints the ast (for debugging purposes) */
5435 /*-----------------------------------------------------------------*/
5437 void ast_print (ast * tree, FILE *outfile, int indent)
5442 /* can print only decorated trees */
5443 if (!tree->decorated) return;
5445 /* if any child is an error | this one is an error do nothing */
5446 if (tree->isError ||
5447 (tree->left && tree->left->isError) ||
5448 (tree->right && tree->right->isError)) {
5449 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5453 /* print the line */
5454 /* if not block & function */
5455 if (tree->type == EX_OP &&
5456 (tree->opval.op != FUNCTION &&
5457 tree->opval.op != BLOCK &&
5458 tree->opval.op != NULLOP)) {
5461 if (tree->opval.op == FUNCTION) {
5463 value *args=FUNC_ARGS(tree->left->opval.val->type);
5464 fprintf(outfile,"FUNCTION (%s=%p) type (",
5465 tree->left->opval.val->name, tree);
5466 printTypeChain (tree->left->opval.val->type->next,outfile);
5467 fprintf(outfile,") args (");
5470 fprintf (outfile, ", ");
5472 printTypeChain (args ? args->type : NULL, outfile);
5474 args= args ? args->next : NULL;
5476 fprintf(outfile,")\n");
5477 ast_print(tree->left,outfile,indent);
5478 ast_print(tree->right,outfile,indent);
5481 if (tree->opval.op == BLOCK) {
5482 symbol *decls = tree->values.sym;
5483 INDENT(indent,outfile);
5484 fprintf(outfile,"{\n");
5486 INDENT(indent+2,outfile);
5487 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5488 decls->name, decls);
5489 printTypeChain(decls->type,outfile);
5490 fprintf(outfile,")\n");
5492 decls = decls->next;
5494 ast_print(tree->right,outfile,indent+2);
5495 INDENT(indent,outfile);
5496 fprintf(outfile,"}\n");
5499 if (tree->opval.op == NULLOP) {
5500 ast_print(tree->left,outfile,indent);
5501 ast_print(tree->right,outfile,indent);
5504 INDENT(indent,outfile);
5506 /*------------------------------------------------------------------*/
5507 /*----------------------------*/
5508 /* leaf has been reached */
5509 /*----------------------------*/
5510 /* if this is of type value */
5511 /* just get the type */
5512 if (tree->type == EX_VALUE) {
5514 if (IS_LITERAL (tree->opval.val->etype)) {
5515 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5516 if (SPEC_USIGN (tree->opval.val->etype))
5517 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5519 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5520 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5521 floatFromVal(tree->opval.val));
5522 } else if (tree->opval.val->sym) {
5523 /* if the undefined flag is set then give error message */
5524 if (tree->opval.val->sym->undefined) {
5525 fprintf(outfile,"UNDEFINED SYMBOL ");
5527 fprintf(outfile,"SYMBOL ");
5529 fprintf(outfile,"(%s=%p)",
5530 tree->opval.val->sym->name,tree);
5533 fprintf(outfile," type (");
5534 printTypeChain(tree->ftype,outfile);
5535 fprintf(outfile,")\n");
5537 fprintf(outfile,"\n");
5542 /* if type link for the case of cast */
5543 if (tree->type == EX_LINK) {
5544 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5545 printTypeChain(tree->opval.lnk,outfile);
5546 fprintf(outfile,")\n");
5551 /* depending on type of operator do */
5553 switch (tree->opval.op) {
5554 /*------------------------------------------------------------------*/
5555 /*----------------------------*/
5557 /*----------------------------*/
5559 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5560 printTypeChain(tree->ftype,outfile);
5561 fprintf(outfile,")\n");
5562 ast_print(tree->left,outfile,indent+2);
5563 ast_print(tree->right,outfile,indent+2);
5566 /*------------------------------------------------------------------*/
5567 /*----------------------------*/
5569 /*----------------------------*/
5571 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5572 printTypeChain(tree->ftype,outfile);
5573 fprintf(outfile,")\n");
5574 ast_print(tree->left,outfile,indent+2);
5575 ast_print(tree->right,outfile,indent+2);
5578 /*------------------------------------------------------------------*/
5579 /*----------------------------*/
5580 /* struct/union pointer */
5581 /*----------------------------*/
5583 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5584 printTypeChain(tree->ftype,outfile);
5585 fprintf(outfile,")\n");
5586 ast_print(tree->left,outfile,indent+2);
5587 ast_print(tree->right,outfile,indent+2);
5590 /*------------------------------------------------------------------*/
5591 /*----------------------------*/
5592 /* ++/-- operation */
5593 /*----------------------------*/
5596 fprintf(outfile,"post-");
5598 fprintf(outfile,"pre-");
5599 fprintf(outfile,"INC_OP (%p) type (",tree);
5600 printTypeChain(tree->ftype,outfile);
5601 fprintf(outfile,")\n");
5602 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5603 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5608 fprintf(outfile,"post-");
5610 fprintf(outfile,"pre-");
5611 fprintf(outfile,"DEC_OP (%p) type (",tree);
5612 printTypeChain(tree->ftype,outfile);
5613 fprintf(outfile,")\n");
5614 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5615 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5618 /*------------------------------------------------------------------*/
5619 /*----------------------------*/
5621 /*----------------------------*/
5624 fprintf(outfile,"& (%p) type (",tree);
5625 printTypeChain(tree->ftype,outfile);
5626 fprintf(outfile,")\n");
5627 ast_print(tree->left,outfile,indent+2);
5628 ast_print(tree->right,outfile,indent+2);
5630 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5631 printTypeChain(tree->ftype,outfile);
5632 fprintf(outfile,")\n");
5633 ast_print(tree->left,outfile,indent+2);
5634 ast_print(tree->right,outfile,indent+2);
5637 /*----------------------------*/
5639 /*----------------------------*/
5641 fprintf(outfile,"OR (%p) type (",tree);
5642 printTypeChain(tree->ftype,outfile);
5643 fprintf(outfile,")\n");
5644 ast_print(tree->left,outfile,indent+2);
5645 ast_print(tree->right,outfile,indent+2);
5647 /*------------------------------------------------------------------*/
5648 /*----------------------------*/
5650 /*----------------------------*/
5652 fprintf(outfile,"XOR (%p) type (",tree);
5653 printTypeChain(tree->ftype,outfile);
5654 fprintf(outfile,")\n");
5655 ast_print(tree->left,outfile,indent+2);
5656 ast_print(tree->right,outfile,indent+2);
5659 /*------------------------------------------------------------------*/
5660 /*----------------------------*/
5662 /*----------------------------*/
5664 fprintf(outfile,"DIV (%p) type (",tree);
5665 printTypeChain(tree->ftype,outfile);
5666 fprintf(outfile,")\n");
5667 ast_print(tree->left,outfile,indent+2);
5668 ast_print(tree->right,outfile,indent+2);
5670 /*------------------------------------------------------------------*/
5671 /*----------------------------*/
5673 /*----------------------------*/
5675 fprintf(outfile,"MOD (%p) type (",tree);
5676 printTypeChain(tree->ftype,outfile);
5677 fprintf(outfile,")\n");
5678 ast_print(tree->left,outfile,indent+2);
5679 ast_print(tree->right,outfile,indent+2);
5682 /*------------------------------------------------------------------*/
5683 /*----------------------------*/
5684 /* address dereference */
5685 /*----------------------------*/
5686 case '*': /* can be unary : if right is null then unary operation */
5688 fprintf(outfile,"DEREF (%p) type (",tree);
5689 printTypeChain(tree->ftype,outfile);
5690 fprintf(outfile,")\n");
5691 ast_print(tree->left,outfile,indent+2);
5694 /*------------------------------------------------------------------*/
5695 /*----------------------------*/
5696 /* multiplication */
5697 /*----------------------------*/
5698 fprintf(outfile,"MULT (%p) type (",tree);
5699 printTypeChain(tree->ftype,outfile);
5700 fprintf(outfile,")\n");
5701 ast_print(tree->left,outfile,indent+2);
5702 ast_print(tree->right,outfile,indent+2);
5706 /*------------------------------------------------------------------*/
5707 /*----------------------------*/
5708 /* unary '+' operator */
5709 /*----------------------------*/
5713 fprintf(outfile,"UPLUS (%p) type (",tree);
5714 printTypeChain(tree->ftype,outfile);
5715 fprintf(outfile,")\n");
5716 ast_print(tree->left,outfile,indent+2);
5718 /*------------------------------------------------------------------*/
5719 /*----------------------------*/
5721 /*----------------------------*/
5722 fprintf(outfile,"ADD (%p) type (",tree);
5723 printTypeChain(tree->ftype,outfile);
5724 fprintf(outfile,")\n");
5725 ast_print(tree->left,outfile,indent+2);
5726 ast_print(tree->right,outfile,indent+2);
5729 /*------------------------------------------------------------------*/
5730 /*----------------------------*/
5732 /*----------------------------*/
5733 case '-': /* can be unary */
5735 fprintf(outfile,"UMINUS (%p) type (",tree);
5736 printTypeChain(tree->ftype,outfile);
5737 fprintf(outfile,")\n");
5738 ast_print(tree->left,outfile,indent+2);
5740 /*------------------------------------------------------------------*/
5741 /*----------------------------*/
5743 /*----------------------------*/
5744 fprintf(outfile,"SUB (%p) type (",tree);
5745 printTypeChain(tree->ftype,outfile);
5746 fprintf(outfile,")\n");
5747 ast_print(tree->left,outfile,indent+2);
5748 ast_print(tree->right,outfile,indent+2);
5751 /*------------------------------------------------------------------*/
5752 /*----------------------------*/
5754 /*----------------------------*/
5756 fprintf(outfile,"COMPL (%p) type (",tree);
5757 printTypeChain(tree->ftype,outfile);
5758 fprintf(outfile,")\n");
5759 ast_print(tree->left,outfile,indent+2);
5761 /*------------------------------------------------------------------*/
5762 /*----------------------------*/
5764 /*----------------------------*/
5766 fprintf(outfile,"NOT (%p) type (",tree);
5767 printTypeChain(tree->ftype,outfile);
5768 fprintf(outfile,")\n");
5769 ast_print(tree->left,outfile,indent+2);
5771 /*------------------------------------------------------------------*/
5772 /*----------------------------*/
5774 /*----------------------------*/
5776 fprintf(outfile,"RRC (%p) type (",tree);
5777 printTypeChain(tree->ftype,outfile);
5778 fprintf(outfile,")\n");
5779 ast_print(tree->left,outfile,indent+2);
5783 fprintf(outfile,"RLC (%p) type (",tree);
5784 printTypeChain(tree->ftype,outfile);
5785 fprintf(outfile,")\n");
5786 ast_print(tree->left,outfile,indent+2);
5789 fprintf(outfile,"SWAP (%p) type (",tree);
5790 printTypeChain(tree->ftype,outfile);
5791 fprintf(outfile,")\n");
5792 ast_print(tree->left,outfile,indent+2);
5795 fprintf(outfile,"GETHBIT (%p) type (",tree);
5796 printTypeChain(tree->ftype,outfile);
5797 fprintf(outfile,")\n");
5798 ast_print(tree->left,outfile,indent+2);
5801 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5802 printTypeChain(tree->ftype,outfile);
5803 fprintf(outfile,")\n");
5804 ast_print(tree->left,outfile,indent+2);
5805 ast_print(tree->right,outfile,indent+2);
5808 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5809 printTypeChain(tree->ftype,outfile);
5810 fprintf(outfile,")\n");
5811 ast_print(tree->left,outfile,indent+2);
5812 ast_print(tree->right,outfile,indent+2);
5814 /*------------------------------------------------------------------*/
5815 /*----------------------------*/
5817 /*----------------------------*/
5818 case CAST: /* change the type */
5819 fprintf(outfile,"CAST (%p) from type (",tree);
5820 printTypeChain(tree->right->ftype,outfile);
5821 fprintf(outfile,") to type (");
5822 printTypeChain(tree->ftype,outfile);
5823 fprintf(outfile,")\n");
5824 ast_print(tree->right,outfile,indent+2);
5828 fprintf(outfile,"ANDAND (%p) type (",tree);
5829 printTypeChain(tree->ftype,outfile);
5830 fprintf(outfile,")\n");
5831 ast_print(tree->left,outfile,indent+2);
5832 ast_print(tree->right,outfile,indent+2);
5835 fprintf(outfile,"OROR (%p) type (",tree);
5836 printTypeChain(tree->ftype,outfile);
5837 fprintf(outfile,")\n");
5838 ast_print(tree->left,outfile,indent+2);
5839 ast_print(tree->right,outfile,indent+2);
5842 /*------------------------------------------------------------------*/
5843 /*----------------------------*/
5844 /* comparison operators */
5845 /*----------------------------*/
5847 fprintf(outfile,"GT(>) (%p) type (",tree);
5848 printTypeChain(tree->ftype,outfile);
5849 fprintf(outfile,")\n");
5850 ast_print(tree->left,outfile,indent+2);
5851 ast_print(tree->right,outfile,indent+2);
5854 fprintf(outfile,"LT(<) (%p) type (",tree);
5855 printTypeChain(tree->ftype,outfile);
5856 fprintf(outfile,")\n");
5857 ast_print(tree->left,outfile,indent+2);
5858 ast_print(tree->right,outfile,indent+2);
5861 fprintf(outfile,"LE(<=) (%p) type (",tree);
5862 printTypeChain(tree->ftype,outfile);
5863 fprintf(outfile,")\n");
5864 ast_print(tree->left,outfile,indent+2);
5865 ast_print(tree->right,outfile,indent+2);
5868 fprintf(outfile,"GE(>=) (%p) type (",tree);
5869 printTypeChain(tree->ftype,outfile);
5870 fprintf(outfile,")\n");
5871 ast_print(tree->left,outfile,indent+2);
5872 ast_print(tree->right,outfile,indent+2);
5875 fprintf(outfile,"EQ(==) (%p) type (",tree);
5876 printTypeChain(tree->ftype,outfile);
5877 fprintf(outfile,")\n");
5878 ast_print(tree->left,outfile,indent+2);
5879 ast_print(tree->right,outfile,indent+2);
5882 fprintf(outfile,"NE(!=) (%p) type (",tree);
5883 printTypeChain(tree->ftype,outfile);
5884 fprintf(outfile,")\n");
5885 ast_print(tree->left,outfile,indent+2);
5886 ast_print(tree->right,outfile,indent+2);
5887 /*------------------------------------------------------------------*/
5888 /*----------------------------*/
5890 /*----------------------------*/
5891 case SIZEOF: /* evaluate wihout code generation */
5892 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5895 /*------------------------------------------------------------------*/
5896 /*----------------------------*/
5897 /* conditional operator '?' */
5898 /*----------------------------*/
5900 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5901 printTypeChain(tree->ftype,outfile);
5902 fprintf(outfile,")\n");
5903 ast_print(tree->left,outfile,indent+2);
5904 ast_print(tree->right,outfile,indent+2);
5908 fprintf(outfile,"COLON(:) (%p) type (",tree);
5909 printTypeChain(tree->ftype,outfile);
5910 fprintf(outfile,")\n");
5911 ast_print(tree->left,outfile,indent+2);
5912 ast_print(tree->right,outfile,indent+2);
5915 /*------------------------------------------------------------------*/
5916 /*----------------------------*/
5917 /* assignment operators */
5918 /*----------------------------*/
5920 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5921 printTypeChain(tree->ftype,outfile);
5922 fprintf(outfile,")\n");
5923 ast_print(tree->left,outfile,indent+2);
5924 ast_print(tree->right,outfile,indent+2);
5927 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5928 printTypeChain(tree->ftype,outfile);
5929 fprintf(outfile,")\n");
5930 ast_print(tree->left,outfile,indent+2);
5931 ast_print(tree->right,outfile,indent+2);
5934 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5935 printTypeChain(tree->ftype,outfile);
5936 fprintf(outfile,")\n");
5937 ast_print(tree->left,outfile,indent+2);
5938 ast_print(tree->right,outfile,indent+2);
5941 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5942 printTypeChain(tree->ftype,outfile);
5943 fprintf(outfile,")\n");
5944 ast_print(tree->left,outfile,indent+2);
5945 ast_print(tree->right,outfile,indent+2);
5948 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5949 printTypeChain(tree->ftype,outfile);
5950 fprintf(outfile,")\n");
5951 ast_print(tree->left,outfile,indent+2);
5952 ast_print(tree->right,outfile,indent+2);
5955 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5956 printTypeChain(tree->ftype,outfile);
5957 fprintf(outfile,")\n");
5958 ast_print(tree->left,outfile,indent+2);
5959 ast_print(tree->right,outfile,indent+2);
5962 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5963 printTypeChain(tree->ftype,outfile);
5964 fprintf(outfile,")\n");
5965 ast_print(tree->left,outfile,indent+2);
5966 ast_print(tree->right,outfile,indent+2);
5968 /*------------------------------------------------------------------*/
5969 /*----------------------------*/
5971 /*----------------------------*/
5973 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5974 printTypeChain(tree->ftype,outfile);
5975 fprintf(outfile,")\n");
5976 ast_print(tree->left,outfile,indent+2);
5977 ast_print(tree->right,outfile,indent+2);
5979 /*------------------------------------------------------------------*/
5980 /*----------------------------*/
5982 /*----------------------------*/
5984 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5985 printTypeChain(tree->ftype,outfile);
5986 fprintf(outfile,")\n");
5987 ast_print(tree->left,outfile,indent+2);
5988 ast_print(tree->right,outfile,indent+2);
5990 /*------------------------------------------------------------------*/
5991 /*----------------------------*/
5992 /* straight assignemnt */
5993 /*----------------------------*/
5995 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5996 printTypeChain(tree->ftype,outfile);
5997 fprintf(outfile,")\n");
5998 ast_print(tree->left,outfile,indent+2);
5999 ast_print(tree->right,outfile,indent+2);
6001 /*------------------------------------------------------------------*/
6002 /*----------------------------*/
6003 /* comma operator */
6004 /*----------------------------*/
6006 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6007 printTypeChain(tree->ftype,outfile);
6008 fprintf(outfile,")\n");
6009 ast_print(tree->left,outfile,indent+2);
6010 ast_print(tree->right,outfile,indent+2);
6012 /*------------------------------------------------------------------*/
6013 /*----------------------------*/
6015 /*----------------------------*/
6018 fprintf(outfile,"CALL (%p) type (",tree);
6019 printTypeChain(tree->ftype,outfile);
6020 fprintf(outfile,")\n");
6021 ast_print(tree->left,outfile,indent+2);
6022 ast_print(tree->right,outfile,indent+2);
6025 fprintf(outfile,"PARMS\n");
6026 ast_print(tree->left,outfile,indent+2);
6027 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6028 ast_print(tree->right,outfile,indent+2);
6031 /*------------------------------------------------------------------*/
6032 /*----------------------------*/
6033 /* return statement */
6034 /*----------------------------*/
6036 fprintf(outfile,"RETURN (%p) type (",tree);
6038 printTypeChain(tree->right->ftype,outfile);
6040 fprintf(outfile,")\n");
6041 ast_print(tree->right,outfile,indent+2);
6043 /*------------------------------------------------------------------*/
6044 /*----------------------------*/
6045 /* label statement */
6046 /*----------------------------*/
6048 fprintf(outfile,"LABEL (%p)\n",tree);
6049 ast_print(tree->left,outfile,indent+2);
6050 ast_print(tree->right,outfile,indent);
6052 /*------------------------------------------------------------------*/
6053 /*----------------------------*/
6054 /* switch statement */
6055 /*----------------------------*/
6059 fprintf(outfile,"SWITCH (%p) ",tree);
6060 ast_print(tree->left,outfile,0);
6061 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6062 INDENT(indent+2,outfile);
6063 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6064 (int) floatFromVal(val),
6065 tree->values.switchVals.swNum,
6066 (int) floatFromVal(val));
6068 ast_print(tree->right,outfile,indent);
6071 /*------------------------------------------------------------------*/
6072 /*----------------------------*/
6074 /*----------------------------*/
6076 fprintf(outfile,"IF (%p) \n",tree);
6077 ast_print(tree->left,outfile,indent+2);
6078 if (tree->trueLabel) {
6079 INDENT(indent+2,outfile);
6080 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6082 if (tree->falseLabel) {
6083 INDENT(indent+2,outfile);
6084 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6086 ast_print(tree->right,outfile,indent+2);
6088 /*----------------------------*/
6089 /* goto Statement */
6090 /*----------------------------*/
6092 fprintf(outfile,"GOTO (%p) \n",tree);
6093 ast_print(tree->left,outfile,indent+2);
6094 fprintf(outfile,"\n");
6096 /*------------------------------------------------------------------*/
6097 /*----------------------------*/
6099 /*----------------------------*/
6101 fprintf(outfile,"FOR (%p) \n",tree);
6102 if (AST_FOR( tree, initExpr)) {
6103 INDENT(indent+2,outfile);
6104 fprintf(outfile,"INIT EXPR ");
6105 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6107 if (AST_FOR( tree, condExpr)) {
6108 INDENT(indent+2,outfile);
6109 fprintf(outfile,"COND EXPR ");
6110 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6112 if (AST_FOR( tree, loopExpr)) {
6113 INDENT(indent+2,outfile);
6114 fprintf(outfile,"LOOP EXPR ");
6115 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6117 fprintf(outfile,"FOR LOOP BODY \n");
6118 ast_print(tree->left,outfile,indent+2);
6121 fprintf(outfile,"CRITICAL (%p) \n",tree);
6122 ast_print(tree->left,outfile,indent+2);
6130 ast_print(t,stdout,0);
6135 /*-----------------------------------------------------------------*/
6136 /* astErrors : returns non-zero if errors present in tree */
6137 /*-----------------------------------------------------------------*/
6138 int astErrors(ast *t)
6147 if (t->type == EX_VALUE
6148 && t->opval.val->sym
6149 && t->opval.val->sym->undefined)
6152 errors += astErrors(t->left);
6153 errors += astErrors(t->right);