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 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
50 symbol *currFunc=NULL;
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : mylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
113 /*-----------------------------------------------------------------*/
114 /* newNode - creates a new node */
115 /*-----------------------------------------------------------------*/
117 newNode (long op, ast * left, ast * right)
128 /*-----------------------------------------------------------------*/
129 /* newIfxNode - creates a new Ifx Node */
130 /*-----------------------------------------------------------------*/
132 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
136 /* if this is a literal then we already know the result */
137 if (condAst->etype && IS_LITERAL (condAst->etype))
139 /* then depending on the expression value */
140 if (floatFromVal (condAst->opval.val))
141 ifxNode = newNode (GOTO,
142 newAst_VALUE (symbolVal (trueLabel)),
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (falseLabel)),
151 ifxNode = newNode (IFX, condAst, NULL);
152 ifxNode->trueLabel = trueLabel;
153 ifxNode->falseLabel = falseLabel;
159 /*-----------------------------------------------------------------*/
160 /* copyAstValues - copies value portion of ast if needed */
161 /*-----------------------------------------------------------------*/
163 copyAstValues (ast * dest, ast * src)
165 switch (src->opval.op)
168 dest->values.sym = copySymbolChain (src->values.sym);
172 dest->values.switchVals.swVals =
173 copyValue (src->values.switchVals.swVals);
174 dest->values.switchVals.swDefault =
175 src->values.switchVals.swDefault;
176 dest->values.switchVals.swNum =
177 src->values.switchVals.swNum;
181 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
185 dest->values.constlist = copyLiteralList(src->values.constlist);
189 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
190 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
191 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
192 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
193 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
194 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
195 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
200 /*-----------------------------------------------------------------*/
201 /* copyAst - makes a copy of a given astession */
202 /*-----------------------------------------------------------------*/
211 dest = Safe_alloc ( sizeof (ast));
213 dest->type = src->type;
214 dest->lineno = src->lineno;
215 dest->level = src->level;
216 dest->funcName = src->funcName;
219 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
221 /* if this is a leaf */
223 if (src->type == EX_VALUE)
225 dest->opval.val = copyValue (src->opval.val);
230 if (src->type == EX_LINK)
232 dest->opval.lnk = copyLinkChain (src->opval.lnk);
236 dest->opval.op = src->opval.op;
238 /* if this is a node that has special values */
239 copyAstValues (dest, src);
241 dest->trueLabel = copySymbol (src->trueLabel);
242 dest->falseLabel = copySymbol (src->falseLabel);
243 dest->left = copyAst (src->left);
244 dest->right = copyAst (src->right);
250 /*-----------------------------------------------------------------*/
251 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
252 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
253 /*-----------------------------------------------------------------*/
254 ast *removeIncDecOps (ast * tree) {
256 // traverse the tree and remove inc/dec ops
261 if (tree->type == EX_OP &&
262 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
269 tree->left=removeIncDecOps(tree->left);
270 tree->right=removeIncDecOps(tree->right);
275 /*-----------------------------------------------------------------*/
276 /* hasSEFcalls - returns TRUE if tree has a function call */
277 /*-----------------------------------------------------------------*/
279 hasSEFcalls (ast * tree)
284 if (tree->type == EX_OP &&
285 (tree->opval.op == CALL ||
286 tree->opval.op == PCALL ||
287 tree->opval.op == '=' ||
288 tree->opval.op == INC_OP ||
289 tree->opval.op == DEC_OP))
292 return (hasSEFcalls (tree->left) |
293 hasSEFcalls (tree->right));
296 /*-----------------------------------------------------------------*/
297 /* isAstEqual - compares two asts & returns 1 if they are equal */
298 /*-----------------------------------------------------------------*/
300 isAstEqual (ast * t1, ast * t2)
309 if (t1->type != t2->type)
315 if (t1->opval.op != t2->opval.op)
317 return (isAstEqual (t1->left, t2->left) &&
318 isAstEqual (t1->right, t2->right));
322 if (t1->opval.val->sym)
324 if (!t2->opval.val->sym)
327 return isSymbolEqual (t1->opval.val->sym,
332 if (t2->opval.val->sym)
335 return (floatFromVal (t1->opval.val) ==
336 floatFromVal (t2->opval.val));
340 /* only compare these two types */
348 /*-----------------------------------------------------------------*/
349 /* resolveSymbols - resolve symbols from the symbol table */
350 /*-----------------------------------------------------------------*/
352 resolveSymbols (ast * tree)
354 /* walk the entire tree and check for values */
355 /* with symbols if we find one then replace */
356 /* symbol with that from the symbol table */
363 /* if not block & function */
364 if (tree->type == EX_OP &&
365 (tree->opval.op != FUNCTION &&
366 tree->opval.op != BLOCK &&
367 tree->opval.op != NULLOP))
369 filename = tree->filename;
370 lineno = tree->lineno;
374 /* make sure we resolve the true & false labels for ifx */
375 if (tree->type == EX_OP && tree->opval.op == IFX)
381 if ((csym = findSym (LabelTab, tree->trueLabel,
382 tree->trueLabel->name)))
383 tree->trueLabel = csym;
385 werror (E_LABEL_UNDEF, tree->trueLabel->name);
388 if (tree->falseLabel)
390 if ((csym = findSym (LabelTab,
392 tree->falseLabel->name)))
393 tree->falseLabel = csym;
395 werror (E_LABEL_UNDEF, tree->falseLabel->name);
400 /* if this is a label resolve it from the labelTab */
401 if (IS_AST_VALUE (tree) &&
402 tree->opval.val->sym &&
403 tree->opval.val->sym->islbl)
406 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
407 tree->opval.val->sym->name);
410 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
412 tree->opval.val->sym = csym;
414 goto resolveChildren;
417 /* do only for leafs */
418 if (IS_AST_VALUE (tree) &&
419 tree->opval.val->sym &&
420 !tree->opval.val->sym->implicit)
423 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
425 /* if found in the symbol table & they r not the same */
426 if (csym && tree->opval.val->sym != csym)
428 tree->opval.val->sym = csym;
429 tree->opval.val->type = csym->type;
430 tree->opval.val->etype = csym->etype;
433 /* if not found in the symbol table */
434 /* mark it as undefined assume it is */
435 /* an integer in data space */
436 if (!csym && !tree->opval.val->sym->implicit)
439 /* if this is a function name then */
440 /* mark it as returning an int */
443 tree->opval.val->sym->type = newLink (DECLARATOR);
444 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
445 tree->opval.val->sym->type->next =
446 tree->opval.val->sym->etype = newIntLink ();
447 tree->opval.val->etype = tree->opval.val->etype;
448 tree->opval.val->type = tree->opval.val->sym->type;
449 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
450 allocVariables (tree->opval.val->sym);
454 tree->opval.val->sym->undefined = 1;
455 tree->opval.val->type =
456 tree->opval.val->etype = newIntLink ();
457 tree->opval.val->sym->type =
458 tree->opval.val->sym->etype = newIntLink ();
464 resolveSymbols (tree->left);
465 resolveSymbols (tree->right);
470 /*-----------------------------------------------------------------*/
471 /* setAstLineno - walks a ast tree & sets the line number */
472 /*-----------------------------------------------------------------*/
473 int setAstLineno (ast * tree, int lineno)
478 tree->lineno = lineno;
479 setAstLineno (tree->left, lineno);
480 setAstLineno (tree->right, lineno);
484 /*-----------------------------------------------------------------*/
485 /* funcOfType :- function of type with name */
486 /*-----------------------------------------------------------------*/
488 funcOfType (char *name, sym_link * type, sym_link * argType,
492 /* create the symbol */
493 sym = newSymbol (name, 0);
495 /* setup return value */
496 sym->type = newLink (DECLARATOR);
497 DCL_TYPE (sym->type) = FUNCTION;
498 sym->type->next = copyLinkChain (type);
499 sym->etype = getSpec (sym->type);
500 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
502 /* if arguments required */
506 args = FUNC_ARGS(sym->type) = newValue ();
510 args->type = copyLinkChain (argType);
511 args->etype = getSpec (args->type);
512 SPEC_EXTR(args->etype)=1;
515 args = args->next = newValue ();
522 allocVariables (sym);
527 /*-----------------------------------------------------------------*/
528 /* funcOfTypeVarg :- function of type with name and argtype */
529 /*-----------------------------------------------------------------*/
531 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
536 /* create the symbol */
537 sym = newSymbol (name, 0);
539 /* setup return value */
540 sym->type = newLink (DECLARATOR);
541 DCL_TYPE (sym->type) = FUNCTION;
542 sym->type->next = typeFromStr(rtype);
543 sym->etype = getSpec (sym->type);
545 /* if arguments required */
548 args = FUNC_ARGS(sym->type) = newValue ();
550 for ( i = 0 ; i < nArgs ; i++ ) {
551 args->type = typeFromStr(atypes[i]);
552 args->etype = getSpec (args->type);
553 SPEC_EXTR(args->etype)=1;
554 if ((i + 1) == nArgs) break;
555 args = args->next = newValue ();
562 allocVariables (sym);
567 /*-----------------------------------------------------------------*/
568 /* reverseParms - will reverse a parameter tree */
569 /*-----------------------------------------------------------------*/
571 reverseParms (ast * ptree)
577 /* top down if we find a nonParm tree then quit */
578 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
581 ptree->left = ptree->right;
582 ptree->right = ttree;
583 reverseParms (ptree->left);
584 reverseParms (ptree->right);
590 /*-----------------------------------------------------------------*/
591 /* processParms - makes sure the parameters are okay and do some */
592 /* processing with them */
593 /*-----------------------------------------------------------------*/
595 processParms (ast * func,
598 int *parmNumber, // unused, although updated
601 /* if none of them exist */
602 if (!defParm && !actParm)
606 if (getenv("DEBUG_SANITY")) {
607 fprintf (stderr, "processParms: %s ", defParm->name);
609 /* make sure the type is complete and sane */
610 checkTypeSanity(defParm->etype, defParm->name);
613 /* if the function is being called via a pointer & */
614 /* it has not been defined a reentrant then we cannot */
615 /* have parameters */
616 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
618 werror (W_NONRENT_ARGS);
622 /* if defined parameters ended but actual parameters */
623 /* exist and this is not defined as a variable arg */
624 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
626 werror (E_TOO_MANY_PARMS);
630 /* if defined parameters present but no actual parameters */
631 if (defParm && !actParm)
633 werror (E_TOO_FEW_PARMS);
637 if (IS_VOID(actParm->ftype)) {
638 werror (E_VOID_VALUE_USED);
642 /* If this is a varargs function... */
643 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
648 if (IS_CAST_OP (actParm)
649 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
651 /* Parameter was explicitly typecast; don't touch it. */
655 ftype = actParm->ftype;
657 /* If it's a small integer, upcast to int. */
658 if (IS_INTEGRAL (ftype)
659 && (getSize (ftype) < (unsigned) INTSIZE))
661 if (IS_AST_OP(actParm) &&
662 (actParm->opval.op == LEFT_OP ||
663 actParm->opval.op == '*' ||
664 actParm->opval.op == '+' ||
665 actParm->opval.op == '-') &&
667 // we should cast an operand instead of the result
668 actParm->decorated = 0;
669 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
671 actParm = decorateType(actParm);
673 newType = newAst_LINK(INTTYPE);
677 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
679 newType = newAst_LINK (copyLinkChain(ftype));
680 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
683 if (IS_AGGREGATE (ftype))
685 newType = newAst_LINK (copyLinkChain (ftype));
686 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
690 /* cast required; change this op to a cast. */
691 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
693 actParm->type = EX_OP;
694 actParm->opval.op = CAST;
695 actParm->left = newType;
696 actParm->right = parmCopy;
697 decorateType (actParm);
699 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
701 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
702 processParms (func, NULL, actParm->right, parmNumber, rightmost));
707 /* if defined parameters ended but actual has not & */
709 if (!defParm && actParm &&
710 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
713 resolveSymbols (actParm);
714 /* if this is a PARAM node then match left & right */
715 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
717 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
718 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
722 /* If we have found a value node by following only right-hand links,
723 * then we know that there are no more values after us.
725 * Therefore, if there are more defined parameters, the caller didn't
728 if (rightmost && defParm->next)
730 werror (E_TOO_FEW_PARMS);
735 /* the parameter type must be at least castable */
736 if (compareType (defParm->type, actParm->ftype) == 0) {
737 werror (E_INCOMPAT_TYPES);
738 printFromToType (actParm->ftype, defParm->type);
742 /* if the parameter is castable then add the cast */
743 if (compareType (defParm->type, actParm->ftype) < 0)
745 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
747 /* now change the current one to a cast */
748 actParm->type = EX_OP;
749 actParm->opval.op = CAST;
750 actParm->left = newAst_LINK (defParm->type);
751 actParm->right = pTree;
752 actParm->etype = defParm->etype;
753 actParm->ftype = defParm->type;
754 actParm->decorated=0; /* force typechecking */
755 decorateType (actParm);
758 /* make a copy and change the regparm type to the defined parm */
759 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
760 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
761 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
765 /*-----------------------------------------------------------------*/
766 /* createIvalType - generates ival for basic types */
767 /*-----------------------------------------------------------------*/
769 createIvalType (ast * sym, sym_link * type, initList * ilist)
773 /* if initList is deep */
774 if (ilist->type == INIT_DEEP)
775 ilist = ilist->init.deep;
777 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
778 return decorateType (newNode ('=', sym, iExpr));
781 /*-----------------------------------------------------------------*/
782 /* createIvalStruct - generates initial value for structures */
783 /*-----------------------------------------------------------------*/
785 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
792 sflds = SPEC_STRUCT (type)->fields;
793 if (ilist->type != INIT_DEEP)
795 werror (E_INIT_STRUCT, "");
799 iloop = ilist->init.deep;
801 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
803 /* if we have come to end */
807 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
808 lAst = decorateType (resolveSymbols (lAst));
809 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
813 werror (W_EXCESS_INITIALIZERS, "struct",
814 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
821 /*-----------------------------------------------------------------*/
822 /* createIvalArray - generates code for array initialization */
823 /*-----------------------------------------------------------------*/
825 createIvalArray (ast * sym, sym_link * type, initList * ilist)
829 int lcnt = 0, size = 0;
830 literalList *literalL;
832 /* take care of the special case */
833 /* array of characters can be init */
835 if (IS_CHAR (type->next))
836 if ((rast = createIvalCharPtr (sym,
838 decorateType (resolveSymbols (list2expr (ilist))))))
840 return decorateType (resolveSymbols (rast));
842 /* not the special case */
843 if (ilist->type != INIT_DEEP)
845 werror (E_INIT_STRUCT, "");
849 iloop = ilist->init.deep;
850 lcnt = DCL_ELEM (type);
852 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
856 aSym = decorateType (resolveSymbols(sym));
858 rast = newNode(ARRAYINIT, aSym, NULL);
859 rast->values.constlist = literalL;
861 // Make sure size is set to length of initializer list.
868 if (lcnt && size > lcnt)
870 // Array size was specified, and we have more initializers than needed.
871 char *name=sym->opval.val->sym->name;
872 int lineno=sym->opval.val->sym->lineDef;
874 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
883 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
884 aSym = decorateType (resolveSymbols (aSym));
885 rast = createIval (aSym, type->next, iloop, rast);
886 iloop = (iloop ? iloop->next : NULL);
892 /* no of elements given and we */
893 /* have generated for all of them */
896 // there has to be a better way
897 char *name=sym->opval.val->sym->name;
898 int lineno=sym->opval.val->sym->lineDef;
899 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
906 /* if we have not been given a size */
907 if (!DCL_ELEM (type))
909 DCL_ELEM (type) = size;
912 return decorateType (resolveSymbols (rast));
916 /*-----------------------------------------------------------------*/
917 /* createIvalCharPtr - generates initial values for char pointers */
918 /*-----------------------------------------------------------------*/
920 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
924 /* if this is a pointer & right is a literal array then */
925 /* just assignment will do */
926 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
927 SPEC_SCLS (iexpr->etype) == S_CODE)
928 && IS_ARRAY (iexpr->ftype)))
929 return newNode ('=', sym, iexpr);
931 /* left side is an array so we have to assign each */
933 if ((IS_LITERAL (iexpr->etype) ||
934 SPEC_SCLS (iexpr->etype) == S_CODE)
935 && IS_ARRAY (iexpr->ftype))
937 /* for each character generate an assignment */
938 /* to the array element */
939 char *s = SPEC_CVAL (iexpr->etype).v_char;
944 rast = newNode (NULLOP,
948 newAst_VALUE (valueFromLit ((float) i))),
949 newAst_VALUE (valueFromLit (*s))));
953 rast = newNode (NULLOP,
957 newAst_VALUE (valueFromLit ((float) i))),
958 newAst_VALUE (valueFromLit (*s))));
960 // now WE don't need iexpr's symbol anymore
961 freeStringSymbol(AST_SYMBOL(iexpr));
963 return decorateType (resolveSymbols (rast));
969 /*-----------------------------------------------------------------*/
970 /* createIvalPtr - generates initial value for pointers */
971 /*-----------------------------------------------------------------*/
973 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
979 if (ilist->type == INIT_DEEP)
980 ilist = ilist->init.deep;
982 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
984 /* if character pointer */
985 if (IS_CHAR (type->next))
986 if ((rast = createIvalCharPtr (sym, type, iexpr)))
989 return newNode ('=', sym, iexpr);
992 /*-----------------------------------------------------------------*/
993 /* createIval - generates code for initial value */
994 /*-----------------------------------------------------------------*/
996 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1003 /* if structure then */
1004 if (IS_STRUCT (type))
1005 rast = createIvalStruct (sym, type, ilist);
1007 /* if this is a pointer */
1009 rast = createIvalPtr (sym, type, ilist);
1011 /* if this is an array */
1012 if (IS_ARRAY (type))
1013 rast = createIvalArray (sym, type, ilist);
1015 /* if type is SPECIFIER */
1017 rast = createIvalType (sym, type, ilist);
1020 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1022 return decorateType (resolveSymbols (rast));
1025 /*-----------------------------------------------------------------*/
1026 /* initAggregates - initialises aggregate variables with initv */
1027 /*-----------------------------------------------------------------*/
1028 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1029 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1032 /*-----------------------------------------------------------------*/
1033 /* gatherAutoInit - creates assignment expressions for initial */
1035 /*-----------------------------------------------------------------*/
1037 gatherAutoInit (symbol * autoChain)
1044 for (sym = autoChain; sym; sym = sym->next)
1047 /* resolve the symbols in the ival */
1049 resolveIvalSym (sym->ival);
1051 /* if this is a static variable & has an */
1052 /* initial value the code needs to be lifted */
1053 /* here to the main portion since they can be */
1054 /* initialised only once at the start */
1055 if (IS_STATIC (sym->etype) && sym->ival &&
1056 SPEC_SCLS (sym->etype) != S_CODE)
1060 /* insert the symbol into the symbol table */
1061 /* with level = 0 & name = rname */
1062 newSym = copySymbol (sym);
1063 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1065 /* now lift the code to main */
1066 if (IS_AGGREGATE (sym->type)) {
1067 work = initAggregates (sym, sym->ival, NULL);
1069 if (getNelements(sym->type, sym->ival)>1) {
1070 werror (W_EXCESS_INITIALIZERS, "scalar",
1071 sym->name, sym->lineDef);
1073 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1074 list2expr (sym->ival));
1077 setAstLineno (work, sym->lineDef);
1081 staticAutos = newNode (NULLOP, staticAutos, work);
1088 /* if there is an initial value */
1089 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1091 initList *ilist=sym->ival;
1093 while (ilist->type == INIT_DEEP) {
1094 ilist = ilist->init.deep;
1097 /* update lineno for error msg */
1098 lineno=sym->lineDef;
1099 setAstLineno (ilist->init.node, lineno);
1101 if (IS_AGGREGATE (sym->type)) {
1102 work = initAggregates (sym, sym->ival, NULL);
1104 if (getNelements(sym->type, sym->ival)>1) {
1105 werror (W_EXCESS_INITIALIZERS, "scalar",
1106 sym->name, sym->lineDef);
1108 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1109 list2expr (sym->ival));
1113 setAstLineno (work, sym->lineDef);
1117 init = newNode (NULLOP, init, work);
1126 /*-----------------------------------------------------------------*/
1127 /* freeStringSymbol - delete a literal string if no more usage */
1128 /*-----------------------------------------------------------------*/
1129 void freeStringSymbol(symbol *sym) {
1130 /* make sure this is a literal string */
1131 assert (sym->isstrlit);
1132 if (--sym->isstrlit == 0) { // lower the usage count
1133 memmap *segment=SPEC_OCLS(sym->etype);
1135 deleteSetItem(&segment->syms, sym);
1140 /*-----------------------------------------------------------------*/
1141 /* stringToSymbol - creates a symbol from a literal string */
1142 /*-----------------------------------------------------------------*/
1144 stringToSymbol (value * val)
1146 char name[SDCC_NAME_MAX + 1];
1147 static int charLbl = 0;
1151 // have we heard this before?
1152 for (sp=statsg->syms; sp; sp=sp->next) {
1154 if (sym->isstrlit &&
1155 !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
1156 // yes, this is old news. Don't publish it again.
1157 sym->isstrlit++; // but raise the usage count
1158 return symbolVal(sym);
1162 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1163 sym = newSymbol (name, 0); /* make it @ level 0 */
1164 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1166 /* copy the type from the value passed */
1167 sym->type = copyLinkChain (val->type);
1168 sym->etype = getSpec (sym->type);
1169 /* change to storage class & output class */
1170 SPEC_SCLS (sym->etype) = S_CODE;
1171 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1172 SPEC_STAT (sym->etype) = 1;
1173 /* make the level & block = 0 */
1174 sym->block = sym->level = 0;
1176 /* create an ival */
1177 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1182 allocVariables (sym);
1185 return symbolVal (sym);
1189 /*-----------------------------------------------------------------*/
1190 /* processBlockVars - will go thru the ast looking for block if */
1191 /* a block is found then will allocate the syms */
1192 /* will also gather the auto inits present */
1193 /*-----------------------------------------------------------------*/
1195 processBlockVars (ast * tree, int *stack, int action)
1200 /* if this is a block */
1201 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1205 if (action == ALLOCATE)
1207 *stack += allocVariables (tree->values.sym);
1208 autoInit = gatherAutoInit (tree->values.sym);
1210 /* if there are auto inits then do them */
1212 tree->left = newNode (NULLOP, autoInit, tree->left);
1214 else /* action is deallocate */
1215 deallocLocal (tree->values.sym);
1218 processBlockVars (tree->left, stack, action);
1219 processBlockVars (tree->right, stack, action);
1224 /*-------------------------------------------------------------*/
1225 /* constExprTree - returns TRUE if this tree is a constant */
1227 /*-------------------------------------------------------------*/
1228 bool constExprTree (ast *cexpr) {
1234 cexpr = decorateType (resolveSymbols (cexpr));
1236 switch (cexpr->type)
1239 if (IS_AST_LIT_VALUE(cexpr)) {
1240 // this is a literal
1243 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1244 // a function's address will never change
1247 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1248 // an array's address will never change
1251 if (IS_AST_SYM_VALUE(cexpr) &&
1252 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1253 // a symbol in code space will never change
1254 // This is only for the 'char *s="hallo"' case and will have to leave
1255 //printf(" code space symbol");
1260 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1261 "unexpected link in expression tree\n");
1264 if (cexpr->opval.op==ARRAYINIT) {
1265 // this is a list of literals
1268 if (cexpr->opval.op=='=') {
1269 return constExprTree(cexpr->right);
1271 if (cexpr->opval.op==CAST) {
1272 // cast ignored, maybe we should throw a warning here?
1273 return constExprTree(cexpr->right);
1275 if (cexpr->opval.op=='&') {
1278 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1281 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1286 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1291 /*-----------------------------------------------------------------*/
1292 /* constExprValue - returns the value of a constant expression */
1293 /* or NULL if it is not a constant expression */
1294 /*-----------------------------------------------------------------*/
1296 constExprValue (ast * cexpr, int check)
1298 cexpr = decorateType (resolveSymbols (cexpr));
1300 /* if this is not a constant then */
1301 if (!IS_LITERAL (cexpr->ftype))
1303 /* then check if this is a literal array
1305 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1306 SPEC_CVAL (cexpr->etype).v_char &&
1307 IS_ARRAY (cexpr->ftype))
1309 value *val = valFromType (cexpr->ftype);
1310 SPEC_SCLS (val->etype) = S_LITERAL;
1311 val->sym = cexpr->opval.val->sym;
1312 val->sym->type = copyLinkChain (cexpr->ftype);
1313 val->sym->etype = getSpec (val->sym->type);
1314 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1318 /* if we are casting a literal value then */
1319 if (IS_AST_OP (cexpr) &&
1320 cexpr->opval.op == CAST &&
1321 IS_LITERAL (cexpr->right->ftype))
1323 return valCastLiteral (cexpr->ftype,
1324 floatFromVal (cexpr->right->opval.val));
1327 if (IS_AST_VALUE (cexpr))
1329 return cexpr->opval.val;
1333 werror (E_CONST_EXPECTED, "found expression");
1338 /* return the value */
1339 return cexpr->opval.val;
1343 /*-----------------------------------------------------------------*/
1344 /* isLabelInAst - will return true if a given label is found */
1345 /*-----------------------------------------------------------------*/
1347 isLabelInAst (symbol * label, ast * tree)
1349 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1352 if (IS_AST_OP (tree) &&
1353 tree->opval.op == LABEL &&
1354 isSymbolEqual (AST_SYMBOL (tree->left), label))
1357 return isLabelInAst (label, tree->right) &&
1358 isLabelInAst (label, tree->left);
1362 /*-----------------------------------------------------------------*/
1363 /* isLoopCountable - return true if the loop count can be determi- */
1364 /* -ned at compile time . */
1365 /*-----------------------------------------------------------------*/
1367 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1368 symbol ** sym, ast ** init, ast ** end)
1371 /* the loop is considered countable if the following
1372 conditions are true :-
1374 a) initExpr :- <sym> = <const>
1375 b) condExpr :- <sym> < <const1>
1376 c) loopExpr :- <sym> ++
1379 /* first check the initExpr */
1380 if (IS_AST_OP (initExpr) &&
1381 initExpr->opval.op == '=' && /* is assignment */
1382 IS_AST_SYM_VALUE (initExpr->left))
1383 { /* left is a symbol */
1385 *sym = AST_SYMBOL (initExpr->left);
1386 *init = initExpr->right;
1391 /* for now the symbol has to be of
1393 if (!IS_INTEGRAL ((*sym)->type))
1396 /* now check condExpr */
1397 if (IS_AST_OP (condExpr))
1400 switch (condExpr->opval.op)
1403 if (IS_AST_SYM_VALUE (condExpr->left) &&
1404 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1405 IS_AST_LIT_VALUE (condExpr->right))
1407 *end = condExpr->right;
1413 if (IS_AST_OP (condExpr->left) &&
1414 condExpr->left->opval.op == '>' &&
1415 IS_AST_LIT_VALUE (condExpr->left->right) &&
1416 IS_AST_SYM_VALUE (condExpr->left->left) &&
1417 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1420 *end = newNode ('+', condExpr->left->right,
1421 newAst_VALUE (constVal ("1")));
1432 /* check loop expression is of the form <sym>++ */
1433 if (!IS_AST_OP (loopExpr))
1436 /* check if <sym> ++ */
1437 if (loopExpr->opval.op == INC_OP)
1443 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1444 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1451 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1452 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1460 if (loopExpr->opval.op == ADD_ASSIGN)
1463 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1464 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1465 IS_AST_LIT_VALUE (loopExpr->right) &&
1466 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1474 /*-----------------------------------------------------------------*/
1475 /* astHasVolatile - returns true if ast contains any volatile */
1476 /*-----------------------------------------------------------------*/
1478 astHasVolatile (ast * tree)
1483 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1486 if (IS_AST_OP (tree))
1487 return astHasVolatile (tree->left) ||
1488 astHasVolatile (tree->right);
1493 /*-----------------------------------------------------------------*/
1494 /* astHasPointer - return true if the ast contains any ptr variable */
1495 /*-----------------------------------------------------------------*/
1497 astHasPointer (ast * tree)
1502 if (IS_AST_LINK (tree))
1505 /* if we hit an array expression then check
1506 only the left side */
1507 if (IS_AST_OP (tree) && tree->opval.op == '[')
1508 return astHasPointer (tree->left);
1510 if (IS_AST_VALUE (tree))
1511 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1513 return astHasPointer (tree->left) ||
1514 astHasPointer (tree->right);
1518 /*-----------------------------------------------------------------*/
1519 /* astHasSymbol - return true if the ast has the given symbol */
1520 /*-----------------------------------------------------------------*/
1522 astHasSymbol (ast * tree, symbol * sym)
1524 if (!tree || IS_AST_LINK (tree))
1527 if (IS_AST_VALUE (tree))
1529 if (IS_AST_SYM_VALUE (tree))
1530 return isSymbolEqual (AST_SYMBOL (tree), sym);
1535 return astHasSymbol (tree->left, sym) ||
1536 astHasSymbol (tree->right, sym);
1539 /*-----------------------------------------------------------------*/
1540 /* astHasDeref - return true if the ast has an indirect access */
1541 /*-----------------------------------------------------------------*/
1543 astHasDeref (ast * tree)
1545 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1548 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1550 return astHasDeref (tree->left) || astHasDeref (tree->right);
1553 /*-----------------------------------------------------------------*/
1554 /* isConformingBody - the loop body has to conform to a set of rules */
1555 /* for the loop to be considered reversible read on for rules */
1556 /*-----------------------------------------------------------------*/
1558 isConformingBody (ast * pbody, symbol * sym, ast * body)
1561 /* we are going to do a pre-order traversal of the
1562 tree && check for the following conditions. (essentially
1563 a set of very shallow tests )
1564 a) the sym passed does not participate in
1565 any arithmetic operation
1566 b) There are no function calls
1567 c) all jumps are within the body
1568 d) address of loop control variable not taken
1569 e) if an assignment has a pointer on the
1570 left hand side make sure right does not have
1571 loop control variable */
1573 /* if we reach the end or a leaf then true */
1574 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1577 /* if anything else is "volatile" */
1578 if (IS_VOLATILE (TETYPE (pbody)))
1581 /* we will walk the body in a pre-order traversal for
1583 switch (pbody->opval.op)
1585 /*------------------------------------------------------------------*/
1587 // if the loopvar is used as an index
1588 if (astHasSymbol(pbody->right, sym)) {
1591 return isConformingBody (pbody->right, sym, body);
1593 /*------------------------------------------------------------------*/
1598 /*------------------------------------------------------------------*/
1599 case INC_OP: /* incerement operator unary so left only */
1602 /* sure we are not sym is not modified */
1604 IS_AST_SYM_VALUE (pbody->left) &&
1605 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1609 IS_AST_SYM_VALUE (pbody->right) &&
1610 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1615 /*------------------------------------------------------------------*/
1617 case '*': /* can be unary : if right is null then unary operation */
1622 /* if right is NULL then unary operation */
1623 /*------------------------------------------------------------------*/
1624 /*----------------------------*/
1626 /*----------------------------*/
1629 if (IS_AST_SYM_VALUE (pbody->left) &&
1630 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1633 return isConformingBody (pbody->left, sym, body);
1637 if (astHasSymbol (pbody->left, sym) ||
1638 astHasSymbol (pbody->right, sym))
1643 /*------------------------------------------------------------------*/
1651 if (IS_AST_SYM_VALUE (pbody->left) &&
1652 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1655 if (IS_AST_SYM_VALUE (pbody->right) &&
1656 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1659 return isConformingBody (pbody->left, sym, body) &&
1660 isConformingBody (pbody->right, sym, body);
1667 if (IS_AST_SYM_VALUE (pbody->left) &&
1668 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1670 return isConformingBody (pbody->left, sym, body);
1672 /*------------------------------------------------------------------*/
1684 case SIZEOF: /* evaluate wihout code generation */
1686 return isConformingBody (pbody->left, sym, body) &&
1687 isConformingBody (pbody->right, sym, body);
1689 /*------------------------------------------------------------------*/
1692 /* if left has a pointer & right has loop
1693 control variable then we cannot */
1694 if (astHasPointer (pbody->left) &&
1695 astHasSymbol (pbody->right, sym))
1697 if (astHasVolatile (pbody->left))
1700 if (IS_AST_SYM_VALUE (pbody->left)) {
1701 // if the loopvar has an assignment
1702 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1704 // if the loopvar is used in another (maybe conditional) block
1705 if (astHasSymbol (pbody->right, sym) &&
1706 (pbody->level >= body->level)) {
1711 if (astHasVolatile (pbody->left))
1714 if (astHasDeref(pbody->right)) return FALSE;
1716 return isConformingBody (pbody->left, sym, body) &&
1717 isConformingBody (pbody->right, sym, body);
1728 assert ("Parser should not have generated this\n");
1730 /*------------------------------------------------------------------*/
1731 /*----------------------------*/
1732 /* comma operator */
1733 /*----------------------------*/
1735 return isConformingBody (pbody->left, sym, body) &&
1736 isConformingBody (pbody->right, sym, body);
1738 /*------------------------------------------------------------------*/
1739 /*----------------------------*/
1741 /*----------------------------*/
1743 /* if local & not passed as paramater then ok */
1744 if (sym->level && !astHasSymbol(pbody->right,sym))
1748 /*------------------------------------------------------------------*/
1749 /*----------------------------*/
1750 /* return statement */
1751 /*----------------------------*/
1756 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1761 if (astHasSymbol (pbody->left, sym))
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1775 /*-----------------------------------------------------------------*/
1776 /* isLoopReversible - takes a for loop as input && returns true */
1777 /* if the for loop is reversible. If yes will set the value of */
1778 /* the loop control var & init value & termination value */
1779 /*-----------------------------------------------------------------*/
1781 isLoopReversible (ast * loop, symbol ** loopCntrl,
1782 ast ** init, ast ** end)
1784 /* if option says don't do it then don't */
1785 if (optimize.noLoopReverse)
1787 /* there are several tests to determine this */
1789 /* for loop has to be of the form
1790 for ( <sym> = <const1> ;
1791 [<sym> < <const2>] ;
1792 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1794 if (!isLoopCountable (AST_FOR (loop, initExpr),
1795 AST_FOR (loop, condExpr),
1796 AST_FOR (loop, loopExpr),
1797 loopCntrl, init, end))
1800 /* now do some serious checking on the body of the loop
1803 return isConformingBody (loop->left, *loopCntrl, loop->left);
1807 /*-----------------------------------------------------------------*/
1808 /* replLoopSym - replace the loop sym by loop sym -1 */
1809 /*-----------------------------------------------------------------*/
1811 replLoopSym (ast * body, symbol * sym)
1814 if (!body || IS_AST_LINK (body))
1817 if (IS_AST_SYM_VALUE (body))
1820 if (isSymbolEqual (AST_SYMBOL (body), sym))
1824 body->opval.op = '-';
1825 body->left = newAst_VALUE (symbolVal (sym));
1826 body->right = newAst_VALUE (constVal ("1"));
1834 replLoopSym (body->left, sym);
1835 replLoopSym (body->right, sym);
1839 /*-----------------------------------------------------------------*/
1840 /* reverseLoop - do the actual loop reversal */
1841 /*-----------------------------------------------------------------*/
1843 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1847 /* create the following tree
1852 if (sym) goto for_continue ;
1855 /* put it together piece by piece */
1856 rloop = newNode (NULLOP,
1857 createIf (newAst_VALUE (symbolVal (sym)),
1859 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1862 newAst_VALUE (symbolVal (sym)),
1865 replLoopSym (loop->left, sym);
1866 setAstLineno (rloop, init->lineno);
1868 rloop = newNode (NULLOP,
1870 newAst_VALUE (symbolVal (sym)),
1871 newNode ('-', end, init)),
1872 createLabel (AST_FOR (loop, continueLabel),
1876 newNode (SUB_ASSIGN,
1877 newAst_VALUE (symbolVal (sym)),
1878 newAst_VALUE (constVal ("1"))),
1881 rloop->lineno=init->lineno;
1882 return decorateType (rloop);
1886 /*-----------------------------------------------------------------*/
1887 /* decorateType - compute type for this tree also does type cheking */
1888 /* this is done bottom up, since type have to flow upwards */
1889 /* it also does constant folding, and paramater checking */
1890 /*-----------------------------------------------------------------*/
1892 decorateType (ast * tree)
1900 /* if already has type then do nothing */
1901 if (tree->decorated)
1904 tree->decorated = 1;
1907 /* print the line */
1908 /* if not block & function */
1909 if (tree->type == EX_OP &&
1910 (tree->opval.op != FUNCTION &&
1911 tree->opval.op != BLOCK &&
1912 tree->opval.op != NULLOP))
1914 filename = tree->filename;
1915 lineno = tree->lineno;
1919 /* if any child is an error | this one is an error do nothing */
1920 if (tree->isError ||
1921 (tree->left && tree->left->isError) ||
1922 (tree->right && tree->right->isError))
1925 /*------------------------------------------------------------------*/
1926 /*----------------------------*/
1927 /* leaf has been reached */
1928 /*----------------------------*/
1929 lineno=tree->lineno;
1930 /* if this is of type value */
1931 /* just get the type */
1932 if (tree->type == EX_VALUE)
1935 if (IS_LITERAL (tree->opval.val->etype))
1938 /* if this is a character array then declare it */
1939 if (IS_ARRAY (tree->opval.val->type))
1940 tree->opval.val = stringToSymbol (tree->opval.val);
1942 /* otherwise just copy the type information */
1943 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1947 if (tree->opval.val->sym)
1949 /* if the undefined flag is set then give error message */
1950 if (tree->opval.val->sym->undefined)
1952 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1954 TTYPE (tree) = TETYPE (tree) =
1955 tree->opval.val->type = tree->opval.val->sym->type =
1956 tree->opval.val->etype = tree->opval.val->sym->etype =
1957 copyLinkChain (INTTYPE);
1962 /* if impilicit i.e. struct/union member then no type */
1963 if (tree->opval.val->sym->implicit)
1964 TTYPE (tree) = TETYPE (tree) = NULL;
1969 /* else copy the type */
1970 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1972 /* and mark it as referenced */
1973 tree->opval.val->sym->isref = 1;
1981 /* if type link for the case of cast */
1982 if (tree->type == EX_LINK)
1984 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1991 dtl = decorateType (tree->left);
1992 /* delay right side for '?' operator since conditional macro expansions might
1994 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1996 /* this is to take care of situations
1997 when the tree gets rewritten */
1998 if (dtl != tree->left)
2000 if (dtr != tree->right)
2002 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2005 if (IS_AST_OP(tree) &&
2006 (tree->opval.op == CAST || tree->opval.op == '=') &&
2007 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2008 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2009 // this is a cast/assign to a bigger type
2010 if (IS_AST_OP(tree->right) &&
2011 IS_INTEGRAL(tree->right->ftype) &&
2012 (tree->right->opval.op == LEFT_OP ||
2013 tree->right->opval.op == '*' ||
2014 tree->right->opval.op == '+' ||
2015 tree->right->opval.op == '-') &&
2016 tree->right->right) {
2017 // we should cast an operand instead of the result
2018 tree->right->decorated = 0;
2019 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2021 tree->right = decorateType(tree->right);
2026 /* depending on type of operator do */
2028 switch (tree->opval.op)
2030 /*------------------------------------------------------------------*/
2031 /*----------------------------*/
2033 /*----------------------------*/
2036 /* determine which is the array & which the index */
2037 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2040 ast *tempTree = tree->left;
2041 tree->left = tree->right;
2042 tree->right = tempTree;
2045 /* first check if this is a array or a pointer */
2046 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2048 werror (E_NEED_ARRAY_PTR, "[]");
2049 goto errorTreeReturn;
2052 /* check if the type of the idx */
2053 if (!IS_INTEGRAL (RTYPE (tree)))
2055 werror (E_IDX_NOT_INT);
2056 goto errorTreeReturn;
2059 /* if the left is an rvalue then error */
2062 werror (E_LVALUE_REQUIRED, "array access");
2063 goto errorTreeReturn;
2066 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2069 /*------------------------------------------------------------------*/
2070 /*----------------------------*/
2072 /*----------------------------*/
2074 /* if this is not a structure */
2075 if (!IS_STRUCT (LTYPE (tree)))
2077 werror (E_STRUCT_UNION, ".");
2078 goto errorTreeReturn;
2080 TTYPE (tree) = structElemType (LTYPE (tree),
2081 (tree->right->type == EX_VALUE ?
2082 tree->right->opval.val : NULL));
2083 TETYPE (tree) = getSpec (TTYPE (tree));
2086 /*------------------------------------------------------------------*/
2087 /*----------------------------*/
2088 /* struct/union pointer */
2089 /*----------------------------*/
2091 /* if not pointer to a structure */
2092 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2094 werror (E_PTR_REQD);
2095 goto errorTreeReturn;
2098 if (!IS_STRUCT (LTYPE (tree)->next))
2100 werror (E_STRUCT_UNION, "->");
2101 goto errorTreeReturn;
2104 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2105 (tree->right->type == EX_VALUE ?
2106 tree->right->opval.val : NULL));
2107 TETYPE (tree) = getSpec (TTYPE (tree));
2109 /* adjust the storage class */
2110 switch (DCL_TYPE(tree->left->ftype)) {
2114 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2117 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2122 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2125 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2128 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2136 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2137 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2139 /* If defined struct type at addr var
2140 then rewrite (&struct var)->member
2142 and define membertype at (addr+offsetof(struct var,member)) temp
2145 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2146 AST_SYMBOL(tree->right));
2148 sym = newSymbol(genSymName (0), 0);
2149 sym->type = TTYPE (tree);
2150 sym->etype = getSpec(sym->type);
2151 sym->lineDef = tree->lineno;
2154 SPEC_STAT (sym->etype) = 1;
2155 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2157 SPEC_ABSA(sym->etype) = 1;
2158 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2161 AST_VALUE (tree) = symbolVal(sym);
2164 tree->type = EX_VALUE;
2171 /*------------------------------------------------------------------*/
2172 /*----------------------------*/
2173 /* ++/-- operation */
2174 /*----------------------------*/
2175 case INC_OP: /* increment operator unary so left only */
2178 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2179 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2180 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2181 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2190 /*------------------------------------------------------------------*/
2191 /*----------------------------*/
2193 /*----------------------------*/
2194 case '&': /* can be unary */
2195 /* if right is NULL then unary operation */
2196 if (tree->right) /* not an unary operation */
2199 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2201 werror (E_BITWISE_OP);
2202 werror (W_CONTINUE, "left & right types are ");
2203 printTypeChain (LTYPE (tree), stderr);
2204 fprintf (stderr, ",");
2205 printTypeChain (RTYPE (tree), stderr);
2206 fprintf (stderr, "\n");
2207 goto errorTreeReturn;
2210 /* if they are both literal */
2211 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2213 tree->type = EX_VALUE;
2214 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2215 valFromType (RETYPE (tree)), '&');
2217 tree->right = tree->left = NULL;
2218 TETYPE (tree) = tree->opval.val->etype;
2219 TTYPE (tree) = tree->opval.val->type;
2223 /* see if this is a GETHBIT operation if yes
2226 ast *otree = optimizeGetHbit (tree);
2229 return decorateType (otree);
2233 computeType (LTYPE (tree), RTYPE (tree));
2234 TETYPE (tree) = getSpec (TTYPE (tree));
2236 LRVAL (tree) = RRVAL (tree) = 1;
2240 /*------------------------------------------------------------------*/
2241 /*----------------------------*/
2243 /*----------------------------*/
2244 p = newLink (DECLARATOR);
2245 /* if bit field then error */
2246 if (IS_BITVAR (tree->left->etype))
2248 werror (E_ILLEGAL_ADDR, "address of bit variable");
2249 goto errorTreeReturn;
2252 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2254 werror (E_ILLEGAL_ADDR, "address of register variable");
2255 goto errorTreeReturn;
2258 if (IS_FUNC (LTYPE (tree)))
2260 // this ought to be ignored
2261 return (tree->left);
2264 if (IS_LITERAL(LTYPE(tree)))
2266 werror (E_ILLEGAL_ADDR, "address of literal");
2267 goto errorTreeReturn;
2272 werror (E_LVALUE_REQUIRED, "address of");
2273 goto errorTreeReturn;
2275 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2276 DCL_TYPE (p) = CPOINTER;
2277 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2278 DCL_TYPE (p) = FPOINTER;
2279 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2280 DCL_TYPE (p) = PPOINTER;
2281 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2282 DCL_TYPE (p) = IPOINTER;
2283 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2284 DCL_TYPE (p) = EEPPOINTER;
2285 else if (SPEC_OCLS(tree->left->etype))
2286 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2288 DCL_TYPE (p) = POINTER;
2290 if (IS_AST_SYM_VALUE (tree->left))
2292 AST_SYMBOL (tree->left)->addrtaken = 1;
2293 AST_SYMBOL (tree->left)->allocreq = 1;
2296 p->next = LTYPE (tree);
2298 TETYPE (tree) = getSpec (TTYPE (tree));
2303 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2304 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2306 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2307 AST_SYMBOL(tree->left->right));
2308 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2309 valueFromLit(element->offset));
2312 tree->type = EX_VALUE;
2313 tree->values.literalFromCast = 1;
2319 /*------------------------------------------------------------------*/
2320 /*----------------------------*/
2322 /*----------------------------*/
2324 /* if the rewrite succeeds then don't go any furthur */
2326 ast *wtree = optimizeRRCRLC (tree);
2328 return decorateType (wtree);
2331 /*------------------------------------------------------------------*/
2332 /*----------------------------*/
2334 /*----------------------------*/
2336 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2338 werror (E_BITWISE_OP);
2339 werror (W_CONTINUE, "left & right types are ");
2340 printTypeChain (LTYPE (tree), stderr);
2341 fprintf (stderr, ",");
2342 printTypeChain (RTYPE (tree), stderr);
2343 fprintf (stderr, "\n");
2344 goto errorTreeReturn;
2347 /* if they are both literal then */
2348 /* rewrite the tree */
2349 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2351 tree->type = EX_VALUE;
2352 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2353 valFromType (RETYPE (tree)),
2355 tree->right = tree->left = NULL;
2356 TETYPE (tree) = tree->opval.val->etype;
2357 TTYPE (tree) = tree->opval.val->type;
2360 LRVAL (tree) = RRVAL (tree) = 1;
2361 TETYPE (tree) = getSpec (TTYPE (tree) =
2362 computeType (LTYPE (tree),
2365 /*------------------------------------------------------------------*/
2366 /*----------------------------*/
2368 /*----------------------------*/
2370 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2372 werror (E_INVALID_OP, "divide");
2373 goto errorTreeReturn;
2375 /* if they are both literal then */
2376 /* rewrite the tree */
2377 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2379 tree->type = EX_VALUE;
2380 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2381 valFromType (RETYPE (tree)));
2382 tree->right = tree->left = NULL;
2383 TETYPE (tree) = getSpec (TTYPE (tree) =
2384 tree->opval.val->type);
2387 LRVAL (tree) = RRVAL (tree) = 1;
2388 TETYPE (tree) = getSpec (TTYPE (tree) =
2389 computeType (LTYPE (tree),
2393 /*------------------------------------------------------------------*/
2394 /*----------------------------*/
2396 /*----------------------------*/
2398 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2400 werror (E_BITWISE_OP);
2401 werror (W_CONTINUE, "left & right types are ");
2402 printTypeChain (LTYPE (tree), stderr);
2403 fprintf (stderr, ",");
2404 printTypeChain (RTYPE (tree), stderr);
2405 fprintf (stderr, "\n");
2406 goto errorTreeReturn;
2408 /* if they are both literal then */
2409 /* rewrite the tree */
2410 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2412 tree->type = EX_VALUE;
2413 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2414 valFromType (RETYPE (tree)));
2415 tree->right = tree->left = NULL;
2416 TETYPE (tree) = getSpec (TTYPE (tree) =
2417 tree->opval.val->type);
2420 LRVAL (tree) = RRVAL (tree) = 1;
2421 TETYPE (tree) = getSpec (TTYPE (tree) =
2422 computeType (LTYPE (tree),
2426 /*------------------------------------------------------------------*/
2427 /*----------------------------*/
2428 /* address dereference */
2429 /*----------------------------*/
2430 case '*': /* can be unary : if right is null then unary operation */
2433 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2435 werror (E_PTR_REQD);
2436 goto errorTreeReturn;
2441 werror (E_LVALUE_REQUIRED, "pointer deref");
2442 goto errorTreeReturn;
2444 if (IS_ADDRESS_OF_OP(tree->left))
2446 /* replace *&obj with obj */
2447 return tree->left->left;
2449 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2450 TETYPE (tree) = getSpec (TTYPE (tree));
2454 /*------------------------------------------------------------------*/
2455 /*----------------------------*/
2456 /* multiplication */
2457 /*----------------------------*/
2458 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2460 werror (E_INVALID_OP, "multiplication");
2461 goto errorTreeReturn;
2464 /* if they are both literal then */
2465 /* rewrite the tree */
2466 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2468 tree->type = EX_VALUE;
2469 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2470 valFromType (RETYPE (tree)));
2471 tree->right = tree->left = NULL;
2472 TETYPE (tree) = getSpec (TTYPE (tree) =
2473 tree->opval.val->type);
2477 /* if left is a literal exchange left & right */
2478 if (IS_LITERAL (LTYPE (tree)))
2480 ast *tTree = tree->left;
2481 tree->left = tree->right;
2482 tree->right = tTree;
2485 LRVAL (tree) = RRVAL (tree) = 1;
2486 TETYPE (tree) = getSpec (TTYPE (tree) =
2487 computeType (LTYPE (tree),
2490 /* promote result to int if left & right are char
2491 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2492 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2493 SPEC_NOUN(TETYPE(tree)) = V_INT;
2498 /*------------------------------------------------------------------*/
2499 /*----------------------------*/
2500 /* unary '+' operator */
2501 /*----------------------------*/
2506 if (!IS_INTEGRAL (LTYPE (tree)))
2508 werror (E_UNARY_OP, '+');
2509 goto errorTreeReturn;
2512 /* if left is a literal then do it */
2513 if (IS_LITERAL (LTYPE (tree)))
2515 tree->type = EX_VALUE;
2516 tree->opval.val = valFromType (LETYPE (tree));
2518 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2522 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2526 /*------------------------------------------------------------------*/
2527 /*----------------------------*/
2529 /*----------------------------*/
2531 /* this is not a unary operation */
2532 /* if both pointers then problem */
2533 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2534 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2536 werror (E_PTR_PLUS_PTR);
2537 goto errorTreeReturn;
2540 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2541 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2543 werror (E_PLUS_INVALID, "+");
2544 goto errorTreeReturn;
2547 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2548 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2550 werror (E_PLUS_INVALID, "+");
2551 goto errorTreeReturn;
2553 /* if they are both literal then */
2554 /* rewrite the tree */
2555 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2557 tree->type = EX_VALUE;
2558 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2559 valFromType (RETYPE (tree)));
2560 tree->right = tree->left = NULL;
2561 TETYPE (tree) = getSpec (TTYPE (tree) =
2562 tree->opval.val->type);
2566 /* if the right is a pointer or left is a literal
2567 xchange left & right */
2568 if (IS_ARRAY (RTYPE (tree)) ||
2569 IS_PTR (RTYPE (tree)) ||
2570 IS_LITERAL (LTYPE (tree)))
2572 ast *tTree = tree->left;
2573 tree->left = tree->right;
2574 tree->right = tTree;
2577 LRVAL (tree) = RRVAL (tree) = 1;
2578 /* if the left is a pointer */
2579 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2580 TETYPE (tree) = getSpec (TTYPE (tree) =
2583 TETYPE (tree) = getSpec (TTYPE (tree) =
2584 computeType (LTYPE (tree),
2588 /*------------------------------------------------------------------*/
2589 /*----------------------------*/
2591 /*----------------------------*/
2592 case '-': /* can be unary */
2593 /* if right is null then unary */
2597 if (!IS_ARITHMETIC (LTYPE (tree)))
2599 werror (E_UNARY_OP, tree->opval.op);
2600 goto errorTreeReturn;
2603 /* if left is a literal then do it */
2604 if (IS_LITERAL (LTYPE (tree)))
2606 tree->type = EX_VALUE;
2607 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2609 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2610 SPEC_USIGN(TETYPE(tree)) = 0;
2614 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2618 /*------------------------------------------------------------------*/
2619 /*----------------------------*/
2621 /*----------------------------*/
2623 if (!(IS_PTR (LTYPE (tree)) ||
2624 IS_ARRAY (LTYPE (tree)) ||
2625 IS_ARITHMETIC (LTYPE (tree))))
2627 werror (E_PLUS_INVALID, "-");
2628 goto errorTreeReturn;
2631 if (!(IS_PTR (RTYPE (tree)) ||
2632 IS_ARRAY (RTYPE (tree)) ||
2633 IS_ARITHMETIC (RTYPE (tree))))
2635 werror (E_PLUS_INVALID, "-");
2636 goto errorTreeReturn;
2639 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2640 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2641 IS_INTEGRAL (RTYPE (tree))))
2643 werror (E_PLUS_INVALID, "-");
2644 goto errorTreeReturn;
2647 /* if they are both literal then */
2648 /* rewrite the tree */
2649 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2651 tree->type = EX_VALUE;
2652 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2653 valFromType (RETYPE (tree)));
2654 tree->right = tree->left = NULL;
2655 TETYPE (tree) = getSpec (TTYPE (tree) =
2656 tree->opval.val->type);
2660 /* if the left & right are equal then zero */
2661 if (isAstEqual (tree->left, tree->right))
2663 tree->type = EX_VALUE;
2664 tree->left = tree->right = NULL;
2665 tree->opval.val = constVal ("0");
2666 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2670 /* if both of them are pointers or arrays then */
2671 /* the result is going to be an integer */
2672 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2673 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2674 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2676 /* if only the left is a pointer */
2677 /* then result is a pointer */
2678 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2679 TETYPE (tree) = getSpec (TTYPE (tree) =
2682 TETYPE (tree) = getSpec (TTYPE (tree) =
2683 computeType (LTYPE (tree),
2685 LRVAL (tree) = RRVAL (tree) = 1;
2688 /*------------------------------------------------------------------*/
2689 /*----------------------------*/
2691 /*----------------------------*/
2693 /* can be only integral type */
2694 if (!IS_INTEGRAL (LTYPE (tree)))
2696 werror (E_UNARY_OP, tree->opval.op);
2697 goto errorTreeReturn;
2700 /* if left is a literal then do it */
2701 if (IS_LITERAL (LTYPE (tree)))
2703 tree->type = EX_VALUE;
2704 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2706 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2710 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2713 /*------------------------------------------------------------------*/
2714 /*----------------------------*/
2716 /*----------------------------*/
2718 /* can be pointer */
2719 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2720 !IS_PTR (LTYPE (tree)) &&
2721 !IS_ARRAY (LTYPE (tree)))
2723 werror (E_UNARY_OP, tree->opval.op);
2724 goto errorTreeReturn;
2727 /* if left is a literal then do it */
2728 if (IS_LITERAL (LTYPE (tree)))
2730 tree->type = EX_VALUE;
2731 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2733 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2737 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2740 /*------------------------------------------------------------------*/
2741 /*----------------------------*/
2743 /*----------------------------*/
2746 TTYPE (tree) = LTYPE (tree);
2747 TETYPE (tree) = LETYPE (tree);
2751 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2756 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2758 werror (E_SHIFT_OP_INVALID);
2759 werror (W_CONTINUE, "left & right types are ");
2760 printTypeChain (LTYPE (tree), stderr);
2761 fprintf (stderr, ",");
2762 printTypeChain (RTYPE (tree), stderr);
2763 fprintf (stderr, "\n");
2764 goto errorTreeReturn;
2767 /* if they are both literal then */
2768 /* rewrite the tree */
2769 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2771 tree->type = EX_VALUE;
2772 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2773 valFromType (RETYPE (tree)),
2774 (tree->opval.op == LEFT_OP ? 1 : 0));
2775 tree->right = tree->left = NULL;
2776 TETYPE (tree) = getSpec (TTYPE (tree) =
2777 tree->opval.val->type);
2781 /* if only the right side is a literal & we are
2782 shifting more than size of the left operand then zero */
2783 if (IS_LITERAL (RTYPE (tree)) &&
2784 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2785 (getSize (LTYPE (tree)) * 8))
2787 if (tree->opval.op==LEFT_OP ||
2788 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2789 lineno=tree->lineno;
2790 werror (W_SHIFT_CHANGED,
2791 (tree->opval.op == LEFT_OP ? "left" : "right"));
2792 tree->type = EX_VALUE;
2793 tree->left = tree->right = NULL;
2794 tree->opval.val = constVal ("0");
2795 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2799 LRVAL (tree) = RRVAL (tree) = 1;
2800 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2802 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2806 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2810 /*------------------------------------------------------------------*/
2811 /*----------------------------*/
2813 /*----------------------------*/
2814 case CAST: /* change the type */
2815 /* cannot cast to an aggregate type */
2816 if (IS_AGGREGATE (LTYPE (tree)))
2818 werror (E_CAST_ILLEGAL);
2819 goto errorTreeReturn;
2822 /* make sure the type is complete and sane */
2823 checkTypeSanity(LETYPE(tree), "(cast)");
2826 /* if the right is a literal replace the tree */
2827 if (IS_LITERAL (RETYPE (tree))) {
2828 if (!IS_PTR (LTYPE (tree))) {
2829 tree->type = EX_VALUE;
2831 valCastLiteral (LTYPE (tree),
2832 floatFromVal (valFromType (RETYPE (tree))));
2835 TTYPE (tree) = tree->opval.val->type;
2836 tree->values.literalFromCast = 1;
2837 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2838 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2839 sym_link *rest = LTYPE(tree)->next;
2840 werror(W_LITERAL_GENERIC);
2841 TTYPE(tree) = newLink(DECLARATOR);
2842 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2843 TTYPE(tree)->next = rest;
2844 tree->left->opval.lnk = TTYPE(tree);
2847 TTYPE (tree) = LTYPE (tree);
2851 TTYPE (tree) = LTYPE (tree);
2855 #if 0 // this is already checked, now this could be explicit
2856 /* if pointer to struct then check names */
2857 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2858 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2859 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2861 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2862 SPEC_STRUCT(LETYPE(tree))->tag);
2865 if (IS_ADDRESS_OF_OP(tree->right)
2866 && IS_AST_SYM_VALUE (tree->right->left)
2867 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
2869 tree->type = EX_VALUE;
2871 valCastLiteral (LTYPE (tree),
2872 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
2873 TTYPE (tree) = tree->opval.val->type;
2874 TETYPE (tree) = getSpec (TTYPE (tree));
2877 tree->values.literalFromCast = 1;
2881 /* handle offsetof macro: */
2882 /* #define offsetof(TYPE, MEMBER) \ */
2883 /* ((unsigned) &((TYPE *)0)->MEMBER) */
2884 if (IS_ADDRESS_OF_OP(tree->right)
2885 && IS_AST_OP (tree->right->left)
2886 && tree->right->left->opval.op == PTR_OP
2887 && IS_AST_OP (tree->right->left->left)
2888 && tree->right->left->left->opval.op == CAST
2889 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
2891 symbol *element = getStructElement (
2892 SPEC_STRUCT (LETYPE(tree->right->left)),
2893 AST_SYMBOL(tree->right->left->right)
2897 tree->type = EX_VALUE;
2898 tree->opval.val = valCastLiteral (
2901 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
2904 TTYPE (tree) = tree->opval.val->type;
2905 TETYPE (tree) = getSpec (TTYPE (tree));
2912 /* if the right is a literal replace the tree */
2913 if (IS_LITERAL (RETYPE (tree))) {
2914 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
2915 /* rewrite (type *)litaddr
2917 and define type at litaddr temp
2918 (but only if type's storage class is not generic)
2920 ast *newTree = newNode ('&', NULL, NULL);
2923 TTYPE (newTree) = LTYPE (tree);
2924 TETYPE (newTree) = getSpec(LTYPE (tree));
2926 /* define a global symbol at the casted address*/
2927 sym = newSymbol(genSymName (0), 0);
2928 sym->type = LTYPE (tree)->next;
2930 sym->type = newLink (V_VOID);
2931 sym->etype = getSpec(sym->type);
2932 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
2933 sym->lineDef = tree->lineno;
2936 SPEC_STAT (sym->etype) = 1;
2937 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
2938 SPEC_ABSA(sym->etype) = 1;
2939 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2942 newTree->left = newAst_VALUE(symbolVal(sym));
2943 newTree->left->lineno = tree->lineno;
2944 LTYPE (newTree) = sym->type;
2945 LETYPE (newTree) = sym->etype;
2946 LLVAL (newTree) = 1;
2947 LRVAL (newTree) = 0;
2948 TLVAL (newTree) = 1;
2951 if (!IS_PTR (LTYPE (tree))) {
2952 tree->type = EX_VALUE;
2954 valCastLiteral (LTYPE (tree),
2955 floatFromVal (valFromType (RETYPE (tree))));
2956 TTYPE (tree) = tree->opval.val->type;
2959 tree->values.literalFromCast = 1;
2960 TETYPE (tree) = getSpec (TTYPE (tree));
2964 TTYPE (tree) = LTYPE (tree);
2968 TETYPE (tree) = getSpec (TTYPE (tree));
2972 /*------------------------------------------------------------------*/
2973 /*----------------------------*/
2974 /* logical &&, || */
2975 /*----------------------------*/
2978 /* each must me arithmetic type or be a pointer */
2979 if (!IS_PTR (LTYPE (tree)) &&
2980 !IS_ARRAY (LTYPE (tree)) &&
2981 !IS_INTEGRAL (LTYPE (tree)))
2983 werror (E_COMPARE_OP);
2984 goto errorTreeReturn;
2987 if (!IS_PTR (RTYPE (tree)) &&
2988 !IS_ARRAY (RTYPE (tree)) &&
2989 !IS_INTEGRAL (RTYPE (tree)))
2991 werror (E_COMPARE_OP);
2992 goto errorTreeReturn;
2994 /* if they are both literal then */
2995 /* rewrite the tree */
2996 if (IS_LITERAL (RTYPE (tree)) &&
2997 IS_LITERAL (LTYPE (tree)))
2999 tree->type = EX_VALUE;
3000 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3001 valFromType (RETYPE (tree)),
3003 tree->right = tree->left = NULL;
3004 TETYPE (tree) = getSpec (TTYPE (tree) =
3005 tree->opval.val->type);
3008 LRVAL (tree) = RRVAL (tree) = 1;
3009 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3012 /*------------------------------------------------------------------*/
3013 /*----------------------------*/
3014 /* comparison operators */
3015 /*----------------------------*/
3023 ast *lt = optimizeCompare (tree);
3029 /* if they are pointers they must be castable */
3030 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3032 if (tree->opval.op==EQ_OP &&
3033 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3034 // we cannot cast a gptr to a !gptr: switch the leaves
3035 struct ast *s=tree->left;
3036 tree->left=tree->right;
3039 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3041 werror (E_COMPARE_OP);
3042 fprintf (stderr, "comparring type ");
3043 printTypeChain (LTYPE (tree), stderr);
3044 fprintf (stderr, "to type ");
3045 printTypeChain (RTYPE (tree), stderr);
3046 fprintf (stderr, "\n");
3047 goto errorTreeReturn;
3050 /* else they should be promotable to one another */
3053 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3054 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3056 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3058 werror (E_COMPARE_OP);
3059 fprintf (stderr, "comparing type ");
3060 printTypeChain (LTYPE (tree), stderr);
3061 fprintf (stderr, "to type ");
3062 printTypeChain (RTYPE (tree), stderr);
3063 fprintf (stderr, "\n");
3064 goto errorTreeReturn;
3067 /* if unsigned value < 0 then always false */
3068 /* if (unsigned value) > 0 then (unsigned value) */
3069 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3070 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3072 if (tree->opval.op == '<') {
3075 if (tree->opval.op == '>') {
3079 /* if they are both literal then */
3080 /* rewrite the tree */
3081 if (IS_LITERAL (RTYPE (tree)) &&
3082 IS_LITERAL (LTYPE (tree)))
3084 tree->type = EX_VALUE;
3085 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3086 valFromType (RETYPE (tree)),
3088 tree->right = tree->left = NULL;
3089 TETYPE (tree) = getSpec (TTYPE (tree) =
3090 tree->opval.val->type);
3093 LRVAL (tree) = RRVAL (tree) = 1;
3094 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3097 /*------------------------------------------------------------------*/
3098 /*----------------------------*/
3100 /*----------------------------*/
3101 case SIZEOF: /* evaluate wihout code generation */
3102 /* change the type to a integer */
3103 tree->type = EX_VALUE;
3104 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3105 tree->opval.val = constVal (buffer);
3106 tree->right = tree->left = NULL;
3107 TETYPE (tree) = getSpec (TTYPE (tree) =
3108 tree->opval.val->type);
3111 /*------------------------------------------------------------------*/
3112 /*----------------------------*/
3114 /*----------------------------*/
3116 /* return typeof enum value */
3117 tree->type = EX_VALUE;
3120 if (IS_SPEC(tree->right->ftype)) {
3121 switch (SPEC_NOUN(tree->right->ftype)) {
3123 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3124 else typeofv = TYPEOF_INT;
3127 typeofv = TYPEOF_FLOAT;
3130 typeofv = TYPEOF_CHAR;
3133 typeofv = TYPEOF_VOID;
3136 typeofv = TYPEOF_STRUCT;
3139 typeofv = TYPEOF_BITFIELD;
3142 typeofv = TYPEOF_BIT;
3145 typeofv = TYPEOF_SBIT;
3151 switch (DCL_TYPE(tree->right->ftype)) {
3153 typeofv = TYPEOF_POINTER;
3156 typeofv = TYPEOF_FPOINTER;
3159 typeofv = TYPEOF_CPOINTER;
3162 typeofv = TYPEOF_GPOINTER;
3165 typeofv = TYPEOF_PPOINTER;
3168 typeofv = TYPEOF_IPOINTER;
3171 typeofv = TYPEOF_ARRAY;
3174 typeofv = TYPEOF_FUNCTION;
3180 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3181 tree->opval.val = constVal (buffer);
3182 tree->right = tree->left = NULL;
3183 TETYPE (tree) = getSpec (TTYPE (tree) =
3184 tree->opval.val->type);
3187 /*------------------------------------------------------------------*/
3188 /*----------------------------*/
3189 /* conditional operator '?' */
3190 /*----------------------------*/
3192 /* the type is value of the colon operator (on the right) */
3193 assert(IS_COLON_OP(tree->right));
3194 /* if already known then replace the tree : optimizer will do it
3195 but faster to do it here */
3196 if (IS_LITERAL (LTYPE(tree))) {
3197 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3198 return decorateType(tree->right->left) ;
3200 return decorateType(tree->right->right) ;
3203 tree->right = decorateType(tree->right);
3204 TTYPE (tree) = RTYPE(tree);
3205 TETYPE (tree) = getSpec (TTYPE (tree));
3210 /* if they don't match we have a problem */
3211 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3213 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3214 goto errorTreeReturn;
3217 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3218 TETYPE (tree) = getSpec (TTYPE (tree));
3222 #if 0 // assignment operators are converted by the parser
3223 /*------------------------------------------------------------------*/
3224 /*----------------------------*/
3225 /* assignment operators */
3226 /*----------------------------*/
3229 /* for these it must be both must be integral */
3230 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3231 !IS_ARITHMETIC (RTYPE (tree)))
3233 werror (E_OPS_INTEGRAL);
3234 goto errorTreeReturn;
3237 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3239 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3240 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3244 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3245 goto errorTreeReturn;
3256 /* for these it must be both must be integral */
3257 if (!IS_INTEGRAL (LTYPE (tree)) ||
3258 !IS_INTEGRAL (RTYPE (tree)))
3260 werror (E_OPS_INTEGRAL);
3261 goto errorTreeReturn;
3264 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3266 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3267 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3271 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3272 goto errorTreeReturn;
3278 /*------------------------------------------------------------------*/
3279 /*----------------------------*/
3281 /*----------------------------*/
3283 if (!(IS_PTR (LTYPE (tree)) ||
3284 IS_ARITHMETIC (LTYPE (tree))))
3286 werror (E_PLUS_INVALID, "-=");
3287 goto errorTreeReturn;
3290 if (!(IS_PTR (RTYPE (tree)) ||
3291 IS_ARITHMETIC (RTYPE (tree))))
3293 werror (E_PLUS_INVALID, "-=");
3294 goto errorTreeReturn;
3297 TETYPE (tree) = getSpec (TTYPE (tree) =
3298 computeType (LTYPE (tree),
3301 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3302 werror (E_CODE_WRITE, "-=");
3306 werror (E_LVALUE_REQUIRED, "-=");
3307 goto errorTreeReturn;
3313 /*------------------------------------------------------------------*/
3314 /*----------------------------*/
3316 /*----------------------------*/
3318 /* this is not a unary operation */
3319 /* if both pointers then problem */
3320 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3322 werror (E_PTR_PLUS_PTR);
3323 goto errorTreeReturn;
3326 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3328 werror (E_PLUS_INVALID, "+=");
3329 goto errorTreeReturn;
3332 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3334 werror (E_PLUS_INVALID, "+=");
3335 goto errorTreeReturn;
3338 TETYPE (tree) = getSpec (TTYPE (tree) =
3339 computeType (LTYPE (tree),
3342 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3343 werror (E_CODE_WRITE, "+=");
3347 werror (E_LVALUE_REQUIRED, "+=");
3348 goto errorTreeReturn;
3351 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3352 tree->opval.op = '=';
3357 /*------------------------------------------------------------------*/
3358 /*----------------------------*/
3359 /* straight assignemnt */
3360 /*----------------------------*/
3362 /* cannot be an aggregate */
3363 if (IS_AGGREGATE (LTYPE (tree)))
3365 werror (E_AGGR_ASSIGN);
3366 goto errorTreeReturn;
3369 /* they should either match or be castable */
3370 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3372 werror (E_TYPE_MISMATCH, "assignment", " ");
3373 printFromToType(RTYPE(tree),LTYPE(tree));
3376 /* if the left side of the tree is of type void
3377 then report error */
3378 if (IS_VOID (LTYPE (tree)))
3380 werror (E_CAST_ZERO);
3381 printFromToType(RTYPE(tree), LTYPE(tree));
3384 TETYPE (tree) = getSpec (TTYPE (tree) =
3388 if (!tree->initMode ) {
3389 if (IS_CONSTANT(LTYPE(tree)))
3390 werror (E_CODE_WRITE, "=");
3394 werror (E_LVALUE_REQUIRED, "=");
3395 goto errorTreeReturn;
3400 /*------------------------------------------------------------------*/
3401 /*----------------------------*/
3402 /* comma operator */
3403 /*----------------------------*/
3405 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3408 /*------------------------------------------------------------------*/
3409 /*----------------------------*/
3411 /*----------------------------*/
3415 if (processParms (tree->left,
3416 FUNC_ARGS(tree->left->ftype),
3417 tree->right, &parmNumber, TRUE)) {
3418 goto errorTreeReturn;
3421 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3422 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3424 reverseParms (tree->right);
3427 if (IS_CODEPTR(LTYPE(tree))) {
3428 TTYPE(tree) = LTYPE(tree)->next->next;
3430 TTYPE(tree) = LTYPE(tree)->next;
3432 TETYPE (tree) = getSpec (TTYPE (tree));
3435 /*------------------------------------------------------------------*/
3436 /*----------------------------*/
3437 /* return statement */
3438 /*----------------------------*/
3443 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3445 werror (W_RETURN_MISMATCH);
3446 printFromToType (RTYPE(tree), currFunc->type->next);
3447 goto errorTreeReturn;
3450 if (IS_VOID (currFunc->type->next)
3452 !IS_VOID (RTYPE (tree)))
3454 werror (E_FUNC_VOID);
3455 goto errorTreeReturn;
3458 /* if there is going to be a casing required then add it */
3459 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3462 decorateType (newNode (CAST,
3463 newAst_LINK (copyLinkChain (currFunc->type->next)),
3472 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3474 werror (W_VOID_FUNC, currFunc->name);
3475 goto errorTreeReturn;
3478 TTYPE (tree) = TETYPE (tree) = NULL;
3481 /*------------------------------------------------------------------*/
3482 /*----------------------------*/
3483 /* switch statement */
3484 /*----------------------------*/
3486 /* the switch value must be an integer */
3487 if (!IS_INTEGRAL (LTYPE (tree)))
3489 werror (E_SWITCH_NON_INTEGER);
3490 goto errorTreeReturn;
3493 TTYPE (tree) = TETYPE (tree) = NULL;
3496 /*------------------------------------------------------------------*/
3497 /*----------------------------*/
3499 /*----------------------------*/
3501 tree->left = backPatchLabels (tree->left,
3504 TTYPE (tree) = TETYPE (tree) = NULL;
3507 /*------------------------------------------------------------------*/
3508 /*----------------------------*/
3510 /*----------------------------*/
3513 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3514 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3515 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3517 /* if the for loop is reversible then
3518 reverse it otherwise do what we normally
3524 if (isLoopReversible (tree, &sym, &init, &end))
3525 return reverseLoop (tree, sym, init, end);
3527 return decorateType (createFor (AST_FOR (tree, trueLabel),
3528 AST_FOR (tree, continueLabel),
3529 AST_FOR (tree, falseLabel),
3530 AST_FOR (tree, condLabel),
3531 AST_FOR (tree, initExpr),
3532 AST_FOR (tree, condExpr),
3533 AST_FOR (tree, loopExpr),
3537 TTYPE (tree) = TETYPE (tree) = NULL;
3541 /* some error found this tree will be killed */
3543 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3544 tree->opval.op = NULLOP;
3550 /*-----------------------------------------------------------------*/
3551 /* sizeofOp - processes size of operation */
3552 /*-----------------------------------------------------------------*/
3554 sizeofOp (sym_link * type)
3558 /* make sure the type is complete and sane */
3559 checkTypeSanity(type, "(sizeof)");
3561 /* get the size and convert it to character */
3562 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3564 /* now convert into value */
3565 return constVal (buff);
3569 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3570 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3571 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3572 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3573 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3574 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3575 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3577 /*-----------------------------------------------------------------*/
3578 /* backPatchLabels - change and or not operators to flow control */
3579 /*-----------------------------------------------------------------*/
3581 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3587 if (!(IS_ANDORNOT (tree)))
3590 /* if this an and */
3593 static int localLbl = 0;
3596 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3597 localLabel = newSymbol (buffer, NestLevel);
3599 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3601 /* if left is already a IFX then just change the if true label in that */
3602 if (!IS_IFX (tree->left))
3603 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3605 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3606 /* right is a IFX then just join */
3607 if (IS_IFX (tree->right))
3608 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3610 tree->right = createLabel (localLabel, tree->right);
3611 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3613 return newNode (NULLOP, tree->left, tree->right);
3616 /* if this is an or operation */
3619 static int localLbl = 0;
3622 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3623 localLabel = newSymbol (buffer, NestLevel);
3625 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3627 /* if left is already a IFX then just change the if true label in that */
3628 if (!IS_IFX (tree->left))
3629 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3631 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3632 /* right is a IFX then just join */
3633 if (IS_IFX (tree->right))
3634 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3636 tree->right = createLabel (localLabel, tree->right);
3637 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3639 return newNode (NULLOP, tree->left, tree->right);
3645 int wasnot = IS_NOT (tree->left);
3646 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3648 /* if the left is already a IFX */
3649 if (!IS_IFX (tree->left))
3650 tree->left = newNode (IFX, tree->left, NULL);
3654 tree->left->trueLabel = trueLabel;
3655 tree->left->falseLabel = falseLabel;
3659 tree->left->trueLabel = falseLabel;
3660 tree->left->falseLabel = trueLabel;
3667 tree->trueLabel = trueLabel;
3668 tree->falseLabel = falseLabel;
3675 /*-----------------------------------------------------------------*/
3676 /* createBlock - create expression tree for block */
3677 /*-----------------------------------------------------------------*/
3679 createBlock (symbol * decl, ast * body)
3683 /* if the block has nothing */
3687 ex = newNode (BLOCK, NULL, body);
3688 ex->values.sym = decl;
3690 ex->right = ex->right;
3696 /*-----------------------------------------------------------------*/
3697 /* createLabel - creates the expression tree for labels */
3698 /*-----------------------------------------------------------------*/
3700 createLabel (symbol * label, ast * stmnt)
3703 char name[SDCC_NAME_MAX + 1];
3706 /* must create fresh symbol if the symbol name */
3707 /* exists in the symbol table, since there can */
3708 /* be a variable with the same name as the labl */
3709 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3710 (csym->level == label->level))
3711 label = newSymbol (label->name, label->level);
3713 /* change the name before putting it in add _ */
3714 SNPRINTF(name, sizeof(name), "%s", label->name);
3716 /* put the label in the LabelSymbol table */
3717 /* but first check if a label of the same */
3719 if ((csym = findSym (LabelTab, NULL, name)))
3720 werror (E_DUPLICATE_LABEL, label->name);
3722 addSym (LabelTab, label, name, label->level, 0, 0);
3725 label->key = labelKey++;
3726 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3732 /*-----------------------------------------------------------------*/
3733 /* createCase - generates the parsetree for a case statement */
3734 /*-----------------------------------------------------------------*/
3736 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3738 char caseLbl[SDCC_NAME_MAX + 1];
3742 /* if the switch statement does not exist */
3743 /* then case is out of context */
3746 werror (E_CASE_CONTEXT);
3750 caseVal = decorateType (resolveSymbols (caseVal));
3751 /* if not a constant then error */
3752 if (!IS_LITERAL (caseVal->ftype))
3754 werror (E_CASE_CONSTANT);
3758 /* if not a integer than error */
3759 if (!IS_INTEGRAL (caseVal->ftype))
3761 werror (E_CASE_NON_INTEGER);
3765 /* find the end of the switch values chain */
3766 if (!(val = swStat->values.switchVals.swVals))
3767 swStat->values.switchVals.swVals = caseVal->opval.val;
3770 /* also order the cases according to value */
3772 int cVal = (int) floatFromVal (caseVal->opval.val);
3773 while (val && (int) floatFromVal (val) < cVal)
3779 /* if we reached the end then */
3782 pval->next = caseVal->opval.val;
3786 /* we found a value greater than */
3787 /* the current value we must add this */
3788 /* before the value */
3789 caseVal->opval.val->next = val;
3791 /* if this was the first in chain */
3792 if (swStat->values.switchVals.swVals == val)
3793 swStat->values.switchVals.swVals =
3796 pval->next = caseVal->opval.val;
3801 /* create the case label */
3802 SNPRINTF(caseLbl, sizeof(caseLbl),
3804 swStat->values.switchVals.swNum,
3805 (int) floatFromVal (caseVal->opval.val));
3807 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3812 /*-----------------------------------------------------------------*/
3813 /* createDefault - creates the parse tree for the default statement */
3814 /*-----------------------------------------------------------------*/
3816 createDefault (ast * swStat, ast * stmnt)
3818 char defLbl[SDCC_NAME_MAX + 1];
3820 /* if the switch statement does not exist */
3821 /* then case is out of context */
3824 werror (E_CASE_CONTEXT);
3828 /* turn on the default flag */
3829 swStat->values.switchVals.swDefault = 1;
3831 /* create the label */
3832 SNPRINTF (defLbl, sizeof(defLbl),
3833 "_default_%d", swStat->values.switchVals.swNum);
3834 return createLabel (newSymbol (defLbl, 0), stmnt);
3837 /*-----------------------------------------------------------------*/
3838 /* createIf - creates the parsetree for the if statement */
3839 /*-----------------------------------------------------------------*/
3841 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3843 static int Lblnum = 0;
3845 symbol *ifTrue, *ifFalse, *ifEnd;
3847 /* if neither exists */
3848 if (!elseBody && !ifBody) {
3849 // if there are no side effects (i++, j() etc)
3850 if (!hasSEFcalls(condAst)) {
3855 /* create the labels */
3856 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3857 ifFalse = newSymbol (buffer, NestLevel);
3858 /* if no else body then end == false */
3863 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3864 ifEnd = newSymbol (buffer, NestLevel);
3867 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3868 ifTrue = newSymbol (buffer, NestLevel);
3872 /* attach the ifTrue label to the top of it body */
3873 ifBody = createLabel (ifTrue, ifBody);
3874 /* attach a goto end to the ifBody if else is present */
3877 ifBody = newNode (NULLOP, ifBody,
3879 newAst_VALUE (symbolVal (ifEnd)),
3881 /* put the elseLabel on the else body */
3882 elseBody = createLabel (ifFalse, elseBody);
3883 /* out the end at the end of the body */
3884 elseBody = newNode (NULLOP,
3886 createLabel (ifEnd, NULL));
3890 ifBody = newNode (NULLOP, ifBody,
3891 createLabel (ifFalse, NULL));
3893 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3894 if (IS_IFX (condAst))
3897 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3899 return newNode (NULLOP, ifTree,
3900 newNode (NULLOP, ifBody, elseBody));
3904 /*-----------------------------------------------------------------*/
3905 /* createDo - creates parse tree for do */
3908 /* _docontinue_n: */
3909 /* condition_expression +-> trueLabel -> _dobody_n */
3911 /* +-> falseLabel-> _dobreak_n */
3913 /*-----------------------------------------------------------------*/
3915 createDo (symbol * trueLabel, symbol * continueLabel,
3916 symbol * falseLabel, ast * condAst, ast * doBody)
3921 /* if the body does not exist then it is simple */
3924 condAst = backPatchLabels (condAst, continueLabel, NULL);
3925 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3926 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3927 doTree->trueLabel = continueLabel;
3928 doTree->falseLabel = NULL;
3932 /* otherwise we have a body */
3933 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3935 /* attach the body label to the top */
3936 doBody = createLabel (trueLabel, doBody);
3937 /* attach the continue label to end of body */
3938 doBody = newNode (NULLOP, doBody,
3939 createLabel (continueLabel, NULL));
3941 /* now put the break label at the end */
3942 if (IS_IFX (condAst))
3945 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3947 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3949 /* putting it together */
3950 return newNode (NULLOP, doBody, doTree);
3953 /*-----------------------------------------------------------------*/
3954 /* createFor - creates parse tree for 'for' statement */
3957 /* condExpr +-> trueLabel -> _forbody_n */
3959 /* +-> falseLabel-> _forbreak_n */
3962 /* _forcontinue_n: */
3964 /* goto _forcond_n ; */
3966 /*-----------------------------------------------------------------*/
3968 createFor (symbol * trueLabel, symbol * continueLabel,
3969 symbol * falseLabel, symbol * condLabel,
3970 ast * initExpr, ast * condExpr, ast * loopExpr,
3975 /* if loopexpression not present then we can generate it */
3976 /* the same way as a while */
3978 return newNode (NULLOP, initExpr,
3979 createWhile (trueLabel, continueLabel,
3980 falseLabel, condExpr, forBody));
3981 /* vanilla for statement */
3982 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3984 if (condExpr && !IS_IFX (condExpr))
3985 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3988 /* attach condition label to condition */
3989 condExpr = createLabel (condLabel, condExpr);
3991 /* attach body label to body */
3992 forBody = createLabel (trueLabel, forBody);
3994 /* attach continue to forLoop expression & attach */
3995 /* goto the forcond @ and of loopExpression */
3996 loopExpr = createLabel (continueLabel,
4000 newAst_VALUE (symbolVal (condLabel)),
4002 /* now start putting them together */
4003 forTree = newNode (NULLOP, initExpr, condExpr);
4004 forTree = newNode (NULLOP, forTree, forBody);
4005 forTree = newNode (NULLOP, forTree, loopExpr);
4006 /* finally add the break label */
4007 forTree = newNode (NULLOP, forTree,
4008 createLabel (falseLabel, NULL));
4012 /*-----------------------------------------------------------------*/
4013 /* createWhile - creates parse tree for while statement */
4014 /* the while statement will be created as follows */
4016 /* _while_continue_n: */
4017 /* condition_expression +-> trueLabel -> _while_boby_n */
4019 /* +-> falseLabel -> _while_break_n */
4020 /* _while_body_n: */
4022 /* goto _while_continue_n */
4023 /* _while_break_n: */
4024 /*-----------------------------------------------------------------*/
4026 createWhile (symbol * trueLabel, symbol * continueLabel,
4027 symbol * falseLabel, ast * condExpr, ast * whileBody)
4031 /* put the continue label */
4032 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4033 condExpr = createLabel (continueLabel, condExpr);
4034 condExpr->lineno = 0;
4036 /* put the body label in front of the body */
4037 whileBody = createLabel (trueLabel, whileBody);
4038 whileBody->lineno = 0;
4039 /* put a jump to continue at the end of the body */
4040 /* and put break label at the end of the body */
4041 whileBody = newNode (NULLOP,
4044 newAst_VALUE (symbolVal (continueLabel)),
4045 createLabel (falseLabel, NULL)));
4047 /* put it all together */
4048 if (IS_IFX (condExpr))
4049 whileTree = condExpr;
4052 whileTree = newNode (IFX, condExpr, NULL);
4053 /* put the true & false labels in place */
4054 whileTree->trueLabel = trueLabel;
4055 whileTree->falseLabel = falseLabel;
4058 return newNode (NULLOP, whileTree, whileBody);
4061 /*-----------------------------------------------------------------*/
4062 /* optimizeGetHbit - get highest order bit of the expression */
4063 /*-----------------------------------------------------------------*/
4065 optimizeGetHbit (ast * tree)
4068 /* if this is not a bit and */
4069 if (!IS_BITAND (tree))
4072 /* will look for tree of the form
4073 ( expr >> ((sizeof expr) -1) ) & 1 */
4074 if (!IS_AST_LIT_VALUE (tree->right))
4077 if (AST_LIT_VALUE (tree->right) != 1)
4080 if (!IS_RIGHT_OP (tree->left))
4083 if (!IS_AST_LIT_VALUE (tree->left->right))
4086 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4087 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4090 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4094 /*-----------------------------------------------------------------*/
4095 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4096 /*-----------------------------------------------------------------*/
4098 optimizeRRCRLC (ast * root)
4100 /* will look for trees of the form
4101 (?expr << 1) | (?expr >> 7) or
4102 (?expr >> 7) | (?expr << 1) will make that
4103 into a RLC : operation ..
4105 (?expr >> 1) | (?expr << 7) or
4106 (?expr << 7) | (?expr >> 1) will make that
4107 into a RRC operation
4108 note : by 7 I mean (number of bits required to hold the
4110 /* if the root operations is not a | operation the not */
4111 if (!IS_BITOR (root))
4114 /* I have to think of a better way to match patterns this sucks */
4115 /* that aside let start looking for the first case : I use a the
4116 negative check a lot to improve the efficiency */
4117 /* (?expr << 1) | (?expr >> 7) */
4118 if (IS_LEFT_OP (root->left) &&
4119 IS_RIGHT_OP (root->right))
4122 if (!SPEC_USIGN (TETYPE (root->left->left)))
4125 if (!IS_AST_LIT_VALUE (root->left->right) ||
4126 !IS_AST_LIT_VALUE (root->right->right))
4129 /* make sure it is the same expression */
4130 if (!isAstEqual (root->left->left,
4134 if (AST_LIT_VALUE (root->left->right) != 1)
4137 if (AST_LIT_VALUE (root->right->right) !=
4138 (getSize (TTYPE (root->left->left)) * 8 - 1))
4141 /* whew got the first case : create the AST */
4142 return newNode (RLC, root->left->left, NULL);
4146 /* check for second case */
4147 /* (?expr >> 7) | (?expr << 1) */
4148 if (IS_LEFT_OP (root->right) &&
4149 IS_RIGHT_OP (root->left))
4152 if (!SPEC_USIGN (TETYPE (root->left->left)))
4155 if (!IS_AST_LIT_VALUE (root->left->right) ||
4156 !IS_AST_LIT_VALUE (root->right->right))
4159 /* make sure it is the same symbol */
4160 if (!isAstEqual (root->left->left,
4164 if (AST_LIT_VALUE (root->right->right) != 1)
4167 if (AST_LIT_VALUE (root->left->right) !=
4168 (getSize (TTYPE (root->left->left)) * 8 - 1))
4171 /* whew got the first case : create the AST */
4172 return newNode (RLC, root->left->left, NULL);
4177 /* third case for RRC */
4178 /* (?symbol >> 1) | (?symbol << 7) */
4179 if (IS_LEFT_OP (root->right) &&
4180 IS_RIGHT_OP (root->left))
4183 if (!SPEC_USIGN (TETYPE (root->left->left)))
4186 if (!IS_AST_LIT_VALUE (root->left->right) ||
4187 !IS_AST_LIT_VALUE (root->right->right))
4190 /* make sure it is the same symbol */
4191 if (!isAstEqual (root->left->left,
4195 if (AST_LIT_VALUE (root->left->right) != 1)
4198 if (AST_LIT_VALUE (root->right->right) !=
4199 (getSize (TTYPE (root->left->left)) * 8 - 1))
4202 /* whew got the first case : create the AST */
4203 return newNode (RRC, root->left->left, NULL);
4207 /* fourth and last case for now */
4208 /* (?symbol << 7) | (?symbol >> 1) */
4209 if (IS_RIGHT_OP (root->right) &&
4210 IS_LEFT_OP (root->left))
4213 if (!SPEC_USIGN (TETYPE (root->left->left)))
4216 if (!IS_AST_LIT_VALUE (root->left->right) ||
4217 !IS_AST_LIT_VALUE (root->right->right))
4220 /* make sure it is the same symbol */
4221 if (!isAstEqual (root->left->left,
4225 if (AST_LIT_VALUE (root->right->right) != 1)
4228 if (AST_LIT_VALUE (root->left->right) !=
4229 (getSize (TTYPE (root->left->left)) * 8 - 1))
4232 /* whew got the first case : create the AST */
4233 return newNode (RRC, root->left->left, NULL);
4237 /* not found return root */
4241 /*-----------------------------------------------------------------*/
4242 /* optimizeCompare - otimizes compares for bit variables */
4243 /*-----------------------------------------------------------------*/
4245 optimizeCompare (ast * root)
4247 ast *optExpr = NULL;
4250 unsigned int litValue;
4252 /* if nothing then return nothing */
4256 /* if not a compare op then do leaves */
4257 if (!IS_COMPARE_OP (root))
4259 root->left = optimizeCompare (root->left);
4260 root->right = optimizeCompare (root->right);
4264 /* if left & right are the same then depending
4265 of the operation do */
4266 if (isAstEqual (root->left, root->right))
4268 switch (root->opval.op)
4273 optExpr = newAst_VALUE (constVal ("0"));
4278 optExpr = newAst_VALUE (constVal ("1"));
4282 return decorateType (optExpr);
4285 vleft = (root->left->type == EX_VALUE ?
4286 root->left->opval.val : NULL);
4288 vright = (root->right->type == EX_VALUE ?
4289 root->right->opval.val : NULL);
4291 /* if left is a BITVAR in BITSPACE */
4292 /* and right is a LITERAL then opt- */
4293 /* imize else do nothing */
4294 if (vleft && vright &&
4295 IS_BITVAR (vleft->etype) &&
4296 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4297 IS_LITERAL (vright->etype))
4300 /* if right side > 1 then comparison may never succeed */
4301 if ((litValue = (int) floatFromVal (vright)) > 1)
4303 werror (W_BAD_COMPARE);
4309 switch (root->opval.op)
4311 case '>': /* bit value greater than 1 cannot be */
4312 werror (W_BAD_COMPARE);
4316 case '<': /* bit value < 1 means 0 */
4318 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4321 case LE_OP: /* bit value <= 1 means no check */
4322 optExpr = newAst_VALUE (vright);
4325 case GE_OP: /* bit value >= 1 means only check for = */
4327 optExpr = newAst_VALUE (vleft);
4332 { /* literal is zero */
4333 switch (root->opval.op)
4335 case '<': /* bit value < 0 cannot be */
4336 werror (W_BAD_COMPARE);
4340 case '>': /* bit value > 0 means 1 */
4342 optExpr = newAst_VALUE (vleft);
4345 case LE_OP: /* bit value <= 0 means no check */
4346 case GE_OP: /* bit value >= 0 means no check */
4347 werror (W_BAD_COMPARE);
4351 case EQ_OP: /* bit == 0 means ! of bit */
4352 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4356 return decorateType (resolveSymbols (optExpr));
4357 } /* end-of-if of BITVAR */
4362 /*-----------------------------------------------------------------*/
4363 /* addSymToBlock : adds the symbol to the first block we find */
4364 /*-----------------------------------------------------------------*/
4366 addSymToBlock (symbol * sym, ast * tree)
4368 /* reached end of tree or a leaf */
4369 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4373 if (IS_AST_OP (tree) &&
4374 tree->opval.op == BLOCK)
4377 symbol *lsym = copySymbol (sym);
4379 lsym->next = AST_VALUES (tree, sym);
4380 AST_VALUES (tree, sym) = lsym;
4384 addSymToBlock (sym, tree->left);
4385 addSymToBlock (sym, tree->right);
4388 /*-----------------------------------------------------------------*/
4389 /* processRegParms - do processing for register parameters */
4390 /*-----------------------------------------------------------------*/
4392 processRegParms (value * args, ast * body)
4396 if (IS_REGPARM (args->etype))
4397 addSymToBlock (args->sym, body);
4402 /*-----------------------------------------------------------------*/
4403 /* resetParmKey - resets the operandkeys for the symbols */
4404 /*-----------------------------------------------------------------*/
4405 DEFSETFUNC (resetParmKey)
4416 /*-----------------------------------------------------------------*/
4417 /* createFunction - This is the key node that calls the iCode for */
4418 /* generating the code for a function. Note code */
4419 /* is generated function by function, later when */
4420 /* add inter-procedural analysis this will change */
4421 /*-----------------------------------------------------------------*/
4423 createFunction (symbol * name, ast * body)
4429 iCode *piCode = NULL;
4431 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4432 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4434 /* if check function return 0 then some problem */
4435 if (checkFunction (name, NULL) == 0)
4438 /* create a dummy block if none exists */
4440 body = newNode (BLOCK, NULL, NULL);
4444 /* check if the function name already in the symbol table */
4445 if ((csym = findSym (SymbolTab, NULL, name->name)))
4448 /* special case for compiler defined functions
4449 we need to add the name to the publics list : this
4450 actually means we are now compiling the compiler
4454 addSet (&publics, name);
4460 allocVariables (name);
4462 name->lastLine = mylineno;
4465 /* set the stack pointer */
4466 /* PENDING: check this for the mcs51 */
4467 stackPtr = -port->stack.direction * port->stack.call_overhead;
4468 if (IFFUNC_ISISR (name->type))
4469 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4470 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4471 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4473 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4475 fetype = getSpec (name->type); /* get the specifier for the function */
4476 /* if this is a reentrant function then */
4477 if (IFFUNC_ISREENT (name->type))
4480 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4482 /* do processing for parameters that are passed in registers */
4483 processRegParms (FUNC_ARGS(name->type), body);
4485 /* set the stack pointer */
4489 /* allocate & autoinit the block variables */
4490 processBlockVars (body, &stack, ALLOCATE);
4492 /* save the stack information */
4493 if (options.useXstack)
4494 name->xstack = SPEC_STAK (fetype) = stack;
4496 name->stack = SPEC_STAK (fetype) = stack;
4498 /* name needs to be mangled */
4499 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4501 body = resolveSymbols (body); /* resolve the symbols */
4502 body = decorateType (body); /* propagateType & do semantic checks */
4504 ex = newAst_VALUE (symbolVal (name)); /* create name */
4505 ex = newNode (FUNCTION, ex, body);
4506 ex->values.args = FUNC_ARGS(name->type);
4508 if (options.dump_tree) PA(ex);
4511 werror (E_FUNC_NO_CODE, name->name);
4515 /* create the node & generate intermediate code */
4517 codeOutFile = code->oFile;
4518 piCode = iCodeFromAst (ex);
4522 werror (E_FUNC_NO_CODE, name->name);
4526 eBBlockFromiCode (piCode);
4528 /* if there are any statics then do them */
4531 GcurMemmap = statsg;
4532 codeOutFile = statsg->oFile;
4533 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4539 /* dealloc the block variables */
4540 processBlockVars (body, &stack, DEALLOCATE);
4541 outputDebugStackSymbols();
4542 /* deallocate paramaters */
4543 deallocParms (FUNC_ARGS(name->type));
4545 if (IFFUNC_ISREENT (name->type))
4548 /* we are done freeup memory & cleanup */
4550 if (port->reset_labelKey) labelKey = 1;
4552 FUNC_HASBODY(name->type) = 1;
4553 addSet (&operKeyReset, name);
4554 applyToSet (operKeyReset, resetParmKey);
4559 cleanUpLevel (LabelTab, 0);
4560 cleanUpBlock (StructTab, 1);
4561 cleanUpBlock (TypedefTab, 1);
4563 xstack->syms = NULL;
4564 istack->syms = NULL;
4569 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4570 /*-----------------------------------------------------------------*/
4571 /* ast_print : prints the ast (for debugging purposes) */
4572 /*-----------------------------------------------------------------*/
4574 void ast_print (ast * tree, FILE *outfile, int indent)
4579 /* can print only decorated trees */
4580 if (!tree->decorated) return;
4582 /* if any child is an error | this one is an error do nothing */
4583 if (tree->isError ||
4584 (tree->left && tree->left->isError) ||
4585 (tree->right && tree->right->isError)) {
4586 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4590 /* print the line */
4591 /* if not block & function */
4592 if (tree->type == EX_OP &&
4593 (tree->opval.op != FUNCTION &&
4594 tree->opval.op != BLOCK &&
4595 tree->opval.op != NULLOP)) {
4598 if (tree->opval.op == FUNCTION) {
4600 value *args=FUNC_ARGS(tree->left->opval.val->type);
4601 fprintf(outfile,"FUNCTION (%s=%p) type (",
4602 tree->left->opval.val->name, tree);
4603 printTypeChain (tree->left->opval.val->type->next,outfile);
4604 fprintf(outfile,") args (");
4607 fprintf (outfile, ", ");
4609 printTypeChain (args ? args->type : NULL, outfile);
4611 args= args ? args->next : NULL;
4613 fprintf(outfile,")\n");
4614 ast_print(tree->left,outfile,indent);
4615 ast_print(tree->right,outfile,indent);
4618 if (tree->opval.op == BLOCK) {
4619 symbol *decls = tree->values.sym;
4620 INDENT(indent,outfile);
4621 fprintf(outfile,"{\n");
4623 INDENT(indent+2,outfile);
4624 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4625 decls->name, decls);
4626 printTypeChain(decls->type,outfile);
4627 fprintf(outfile,")\n");
4629 decls = decls->next;
4631 ast_print(tree->right,outfile,indent+2);
4632 INDENT(indent,outfile);
4633 fprintf(outfile,"}\n");
4636 if (tree->opval.op == NULLOP) {
4637 ast_print(tree->left,outfile,indent);
4638 ast_print(tree->right,outfile,indent);
4641 INDENT(indent,outfile);
4643 /*------------------------------------------------------------------*/
4644 /*----------------------------*/
4645 /* leaf has been reached */
4646 /*----------------------------*/
4647 /* if this is of type value */
4648 /* just get the type */
4649 if (tree->type == EX_VALUE) {
4651 if (IS_LITERAL (tree->opval.val->etype)) {
4652 fprintf(outfile,"CONSTANT (%p) value = ", tree);
4653 if (SPEC_USIGN (tree->opval.val->etype))
4654 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
4656 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
4657 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
4658 floatFromVal(tree->opval.val));
4659 } else if (tree->opval.val->sym) {
4660 /* if the undefined flag is set then give error message */
4661 if (tree->opval.val->sym->undefined) {
4662 fprintf(outfile,"UNDEFINED SYMBOL ");
4664 fprintf(outfile,"SYMBOL ");
4666 fprintf(outfile,"(%s=%p)",
4667 tree->opval.val->sym->name,tree);
4670 fprintf(outfile," type (");
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4674 fprintf(outfile,"\n");
4679 /* if type link for the case of cast */
4680 if (tree->type == EX_LINK) {
4681 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4682 printTypeChain(tree->opval.lnk,outfile);
4683 fprintf(outfile,")\n");
4688 /* depending on type of operator do */
4690 switch (tree->opval.op) {
4691 /*------------------------------------------------------------------*/
4692 /*----------------------------*/
4694 /*----------------------------*/
4696 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+2);
4700 ast_print(tree->right,outfile,indent+2);
4703 /*------------------------------------------------------------------*/
4704 /*----------------------------*/
4706 /*----------------------------*/
4708 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4709 printTypeChain(tree->ftype,outfile);
4710 fprintf(outfile,")\n");
4711 ast_print(tree->left,outfile,indent+2);
4712 ast_print(tree->right,outfile,indent+2);
4715 /*------------------------------------------------------------------*/
4716 /*----------------------------*/
4717 /* struct/union pointer */
4718 /*----------------------------*/
4720 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4721 printTypeChain(tree->ftype,outfile);
4722 fprintf(outfile,")\n");
4723 ast_print(tree->left,outfile,indent+2);
4724 ast_print(tree->right,outfile,indent+2);
4727 /*------------------------------------------------------------------*/
4728 /*----------------------------*/
4729 /* ++/-- operation */
4730 /*----------------------------*/
4731 case INC_OP: /* incerement operator unary so left only */
4732 fprintf(outfile,"INC_OP (%p) type (",tree);
4733 printTypeChain(tree->ftype,outfile);
4734 fprintf(outfile,")\n");
4735 ast_print(tree->left,outfile,indent+2);
4739 fprintf(outfile,"DEC_OP (%p) type (",tree);
4740 printTypeChain(tree->ftype,outfile);
4741 fprintf(outfile,")\n");
4742 ast_print(tree->left,outfile,indent+2);
4745 /*------------------------------------------------------------------*/
4746 /*----------------------------*/
4748 /*----------------------------*/
4751 fprintf(outfile,"& (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+2);
4755 ast_print(tree->right,outfile,indent+2);
4757 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+2);
4761 ast_print(tree->right,outfile,indent+2);
4764 /*----------------------------*/
4766 /*----------------------------*/
4768 fprintf(outfile,"OR (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+2);
4772 ast_print(tree->right,outfile,indent+2);
4774 /*------------------------------------------------------------------*/
4775 /*----------------------------*/
4777 /*----------------------------*/
4779 fprintf(outfile,"XOR (%p) type (",tree);
4780 printTypeChain(tree->ftype,outfile);
4781 fprintf(outfile,")\n");
4782 ast_print(tree->left,outfile,indent+2);
4783 ast_print(tree->right,outfile,indent+2);
4786 /*------------------------------------------------------------------*/
4787 /*----------------------------*/
4789 /*----------------------------*/
4791 fprintf(outfile,"DIV (%p) type (",tree);
4792 printTypeChain(tree->ftype,outfile);
4793 fprintf(outfile,")\n");
4794 ast_print(tree->left,outfile,indent+2);
4795 ast_print(tree->right,outfile,indent+2);
4797 /*------------------------------------------------------------------*/
4798 /*----------------------------*/
4800 /*----------------------------*/
4802 fprintf(outfile,"MOD (%p) type (",tree);
4803 printTypeChain(tree->ftype,outfile);
4804 fprintf(outfile,")\n");
4805 ast_print(tree->left,outfile,indent+2);
4806 ast_print(tree->right,outfile,indent+2);
4809 /*------------------------------------------------------------------*/
4810 /*----------------------------*/
4811 /* address dereference */
4812 /*----------------------------*/
4813 case '*': /* can be unary : if right is null then unary operation */
4815 fprintf(outfile,"DEREF (%p) type (",tree);
4816 printTypeChain(tree->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->left,outfile,indent+2);
4821 /*------------------------------------------------------------------*/
4822 /*----------------------------*/
4823 /* multiplication */
4824 /*----------------------------*/
4825 fprintf(outfile,"MULT (%p) type (",tree);
4826 printTypeChain(tree->ftype,outfile);
4827 fprintf(outfile,")\n");
4828 ast_print(tree->left,outfile,indent+2);
4829 ast_print(tree->right,outfile,indent+2);
4833 /*------------------------------------------------------------------*/
4834 /*----------------------------*/
4835 /* unary '+' operator */
4836 /*----------------------------*/
4840 fprintf(outfile,"UPLUS (%p) type (",tree);
4841 printTypeChain(tree->ftype,outfile);
4842 fprintf(outfile,")\n");
4843 ast_print(tree->left,outfile,indent+2);
4845 /*------------------------------------------------------------------*/
4846 /*----------------------------*/
4848 /*----------------------------*/
4849 fprintf(outfile,"ADD (%p) type (",tree);
4850 printTypeChain(tree->ftype,outfile);
4851 fprintf(outfile,")\n");
4852 ast_print(tree->left,outfile,indent+2);
4853 ast_print(tree->right,outfile,indent+2);
4856 /*------------------------------------------------------------------*/
4857 /*----------------------------*/
4859 /*----------------------------*/
4860 case '-': /* can be unary */
4862 fprintf(outfile,"UMINUS (%p) type (",tree);
4863 printTypeChain(tree->ftype,outfile);
4864 fprintf(outfile,")\n");
4865 ast_print(tree->left,outfile,indent+2);
4867 /*------------------------------------------------------------------*/
4868 /*----------------------------*/
4870 /*----------------------------*/
4871 fprintf(outfile,"SUB (%p) type (",tree);
4872 printTypeChain(tree->ftype,outfile);
4873 fprintf(outfile,")\n");
4874 ast_print(tree->left,outfile,indent+2);
4875 ast_print(tree->right,outfile,indent+2);
4878 /*------------------------------------------------------------------*/
4879 /*----------------------------*/
4881 /*----------------------------*/
4883 fprintf(outfile,"COMPL (%p) type (",tree);
4884 printTypeChain(tree->ftype,outfile);
4885 fprintf(outfile,")\n");
4886 ast_print(tree->left,outfile,indent+2);
4888 /*------------------------------------------------------------------*/
4889 /*----------------------------*/
4891 /*----------------------------*/
4893 fprintf(outfile,"NOT (%p) type (",tree);
4894 printTypeChain(tree->ftype,outfile);
4895 fprintf(outfile,")\n");
4896 ast_print(tree->left,outfile,indent+2);
4898 /*------------------------------------------------------------------*/
4899 /*----------------------------*/
4901 /*----------------------------*/
4903 fprintf(outfile,"RRC (%p) type (",tree);
4904 printTypeChain(tree->ftype,outfile);
4905 fprintf(outfile,")\n");
4906 ast_print(tree->left,outfile,indent+2);
4910 fprintf(outfile,"RLC (%p) type (",tree);
4911 printTypeChain(tree->ftype,outfile);
4912 fprintf(outfile,")\n");
4913 ast_print(tree->left,outfile,indent+2);
4916 fprintf(outfile,"GETHBIT (%p) type (",tree);
4917 printTypeChain(tree->ftype,outfile);
4918 fprintf(outfile,")\n");
4919 ast_print(tree->left,outfile,indent+2);
4922 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4923 printTypeChain(tree->ftype,outfile);
4924 fprintf(outfile,")\n");
4925 ast_print(tree->left,outfile,indent+2);
4926 ast_print(tree->right,outfile,indent+2);
4929 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4930 printTypeChain(tree->ftype,outfile);
4931 fprintf(outfile,")\n");
4932 ast_print(tree->left,outfile,indent+2);
4933 ast_print(tree->right,outfile,indent+2);
4935 /*------------------------------------------------------------------*/
4936 /*----------------------------*/
4938 /*----------------------------*/
4939 case CAST: /* change the type */
4940 fprintf(outfile,"CAST (%p) from type (",tree);
4941 printTypeChain(tree->right->ftype,outfile);
4942 fprintf(outfile,") to type (");
4943 printTypeChain(tree->ftype,outfile);
4944 fprintf(outfile,")\n");
4945 ast_print(tree->right,outfile,indent+2);
4949 fprintf(outfile,"ANDAND (%p) type (",tree);
4950 printTypeChain(tree->ftype,outfile);
4951 fprintf(outfile,")\n");
4952 ast_print(tree->left,outfile,indent+2);
4953 ast_print(tree->right,outfile,indent+2);
4956 fprintf(outfile,"OROR (%p) type (",tree);
4957 printTypeChain(tree->ftype,outfile);
4958 fprintf(outfile,")\n");
4959 ast_print(tree->left,outfile,indent+2);
4960 ast_print(tree->right,outfile,indent+2);
4963 /*------------------------------------------------------------------*/
4964 /*----------------------------*/
4965 /* comparison operators */
4966 /*----------------------------*/
4968 fprintf(outfile,"GT(>) (%p) type (",tree);
4969 printTypeChain(tree->ftype,outfile);
4970 fprintf(outfile,")\n");
4971 ast_print(tree->left,outfile,indent+2);
4972 ast_print(tree->right,outfile,indent+2);
4975 fprintf(outfile,"LT(<) (%p) type (",tree);
4976 printTypeChain(tree->ftype,outfile);
4977 fprintf(outfile,")\n");
4978 ast_print(tree->left,outfile,indent+2);
4979 ast_print(tree->right,outfile,indent+2);
4982 fprintf(outfile,"LE(<=) (%p) type (",tree);
4983 printTypeChain(tree->ftype,outfile);
4984 fprintf(outfile,")\n");
4985 ast_print(tree->left,outfile,indent+2);
4986 ast_print(tree->right,outfile,indent+2);
4989 fprintf(outfile,"GE(>=) (%p) type (",tree);
4990 printTypeChain(tree->ftype,outfile);
4991 fprintf(outfile,")\n");
4992 ast_print(tree->left,outfile,indent+2);
4993 ast_print(tree->right,outfile,indent+2);
4996 fprintf(outfile,"EQ(==) (%p) type (",tree);
4997 printTypeChain(tree->ftype,outfile);
4998 fprintf(outfile,")\n");
4999 ast_print(tree->left,outfile,indent+2);
5000 ast_print(tree->right,outfile,indent+2);
5003 fprintf(outfile,"NE(!=) (%p) type (",tree);
5004 printTypeChain(tree->ftype,outfile);
5005 fprintf(outfile,")\n");
5006 ast_print(tree->left,outfile,indent+2);
5007 ast_print(tree->right,outfile,indent+2);
5008 /*------------------------------------------------------------------*/
5009 /*----------------------------*/
5011 /*----------------------------*/
5012 case SIZEOF: /* evaluate wihout code generation */
5013 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5016 /*------------------------------------------------------------------*/
5017 /*----------------------------*/
5018 /* conditional operator '?' */
5019 /*----------------------------*/
5021 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5022 printTypeChain(tree->ftype,outfile);
5023 fprintf(outfile,")\n");
5024 ast_print(tree->left,outfile,indent+2);
5025 ast_print(tree->right,outfile,indent+2);
5029 fprintf(outfile,"COLON(:) (%p) type (",tree);
5030 printTypeChain(tree->ftype,outfile);
5031 fprintf(outfile,")\n");
5032 ast_print(tree->left,outfile,indent+2);
5033 ast_print(tree->right,outfile,indent+2);
5036 /*------------------------------------------------------------------*/
5037 /*----------------------------*/
5038 /* assignment operators */
5039 /*----------------------------*/
5041 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5042 printTypeChain(tree->ftype,outfile);
5043 fprintf(outfile,")\n");
5044 ast_print(tree->left,outfile,indent+2);
5045 ast_print(tree->right,outfile,indent+2);
5048 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5049 printTypeChain(tree->ftype,outfile);
5050 fprintf(outfile,")\n");
5051 ast_print(tree->left,outfile,indent+2);
5052 ast_print(tree->right,outfile,indent+2);
5055 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5056 printTypeChain(tree->ftype,outfile);
5057 fprintf(outfile,")\n");
5058 ast_print(tree->left,outfile,indent+2);
5059 ast_print(tree->right,outfile,indent+2);
5062 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5063 printTypeChain(tree->ftype,outfile);
5064 fprintf(outfile,")\n");
5065 ast_print(tree->left,outfile,indent+2);
5066 ast_print(tree->right,outfile,indent+2);
5069 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5070 printTypeChain(tree->ftype,outfile);
5071 fprintf(outfile,")\n");
5072 ast_print(tree->left,outfile,indent+2);
5073 ast_print(tree->right,outfile,indent+2);
5076 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5077 printTypeChain(tree->ftype,outfile);
5078 fprintf(outfile,")\n");
5079 ast_print(tree->left,outfile,indent+2);
5080 ast_print(tree->right,outfile,indent+2);
5083 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5084 printTypeChain(tree->ftype,outfile);
5085 fprintf(outfile,")\n");
5086 ast_print(tree->left,outfile,indent+2);
5087 ast_print(tree->right,outfile,indent+2);
5089 /*------------------------------------------------------------------*/
5090 /*----------------------------*/
5092 /*----------------------------*/
5094 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5095 printTypeChain(tree->ftype,outfile);
5096 fprintf(outfile,")\n");
5097 ast_print(tree->left,outfile,indent+2);
5098 ast_print(tree->right,outfile,indent+2);
5100 /*------------------------------------------------------------------*/
5101 /*----------------------------*/
5103 /*----------------------------*/
5105 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5106 printTypeChain(tree->ftype,outfile);
5107 fprintf(outfile,")\n");
5108 ast_print(tree->left,outfile,indent+2);
5109 ast_print(tree->right,outfile,indent+2);
5111 /*------------------------------------------------------------------*/
5112 /*----------------------------*/
5113 /* straight assignemnt */
5114 /*----------------------------*/
5116 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5117 printTypeChain(tree->ftype,outfile);
5118 fprintf(outfile,")\n");
5119 ast_print(tree->left,outfile,indent+2);
5120 ast_print(tree->right,outfile,indent+2);
5122 /*------------------------------------------------------------------*/
5123 /*----------------------------*/
5124 /* comma operator */
5125 /*----------------------------*/
5127 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5128 printTypeChain(tree->ftype,outfile);
5129 fprintf(outfile,")\n");
5130 ast_print(tree->left,outfile,indent+2);
5131 ast_print(tree->right,outfile,indent+2);
5133 /*------------------------------------------------------------------*/
5134 /*----------------------------*/
5136 /*----------------------------*/
5139 fprintf(outfile,"CALL (%p) type (",tree);
5140 printTypeChain(tree->ftype,outfile);
5141 fprintf(outfile,")\n");
5142 ast_print(tree->left,outfile,indent+2);
5143 ast_print(tree->right,outfile,indent+2);
5146 fprintf(outfile,"PARMS\n");
5147 ast_print(tree->left,outfile,indent+2);
5148 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5149 ast_print(tree->right,outfile,indent+2);
5152 /*------------------------------------------------------------------*/
5153 /*----------------------------*/
5154 /* return statement */
5155 /*----------------------------*/
5157 fprintf(outfile,"RETURN (%p) type (",tree);
5159 printTypeChain(tree->right->ftype,outfile);
5161 fprintf(outfile,")\n");
5162 ast_print(tree->right,outfile,indent+2);
5164 /*------------------------------------------------------------------*/
5165 /*----------------------------*/
5166 /* label statement */
5167 /*----------------------------*/
5169 fprintf(outfile,"LABEL (%p)\n",tree);
5170 ast_print(tree->left,outfile,indent+2);
5171 ast_print(tree->right,outfile,indent);
5173 /*------------------------------------------------------------------*/
5174 /*----------------------------*/
5175 /* switch statement */
5176 /*----------------------------*/
5180 fprintf(outfile,"SWITCH (%p) ",tree);
5181 ast_print(tree->left,outfile,0);
5182 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5183 INDENT(indent+2,outfile);
5184 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5185 (int) floatFromVal(val),
5186 tree->values.switchVals.swNum,
5187 (int) floatFromVal(val));
5189 ast_print(tree->right,outfile,indent);
5192 /*------------------------------------------------------------------*/
5193 /*----------------------------*/
5195 /*----------------------------*/
5197 fprintf(outfile,"IF (%p) \n",tree);
5198 ast_print(tree->left,outfile,indent+2);
5199 if (tree->trueLabel) {
5200 INDENT(indent+2,outfile);
5201 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5203 if (tree->falseLabel) {
5204 INDENT(indent+2,outfile);
5205 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5207 ast_print(tree->right,outfile,indent+2);
5209 /*----------------------------*/
5210 /* goto Statement */
5211 /*----------------------------*/
5213 fprintf(outfile,"GOTO (%p) \n",tree);
5214 ast_print(tree->left,outfile,indent+2);
5215 fprintf(outfile,"\n");
5217 /*------------------------------------------------------------------*/
5218 /*----------------------------*/
5220 /*----------------------------*/
5222 fprintf(outfile,"FOR (%p) \n",tree);
5223 if (AST_FOR( tree, initExpr)) {
5224 INDENT(indent+2,outfile);
5225 fprintf(outfile,"INIT EXPR ");
5226 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5228 if (AST_FOR( tree, condExpr)) {
5229 INDENT(indent+2,outfile);
5230 fprintf(outfile,"COND EXPR ");
5231 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5233 if (AST_FOR( tree, loopExpr)) {
5234 INDENT(indent+2,outfile);
5235 fprintf(outfile,"LOOP EXPR ");
5236 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5238 fprintf(outfile,"FOR LOOP BODY \n");
5239 ast_print(tree->left,outfile,indent+2);
5248 ast_print(t,stdout,0);