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 /*------------------------------------------------------------------*/
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 /* searchLitOp - search tree (*ops only) for an ast with literal */
1888 /*-----------------------------------------------------------------*/
1890 searchLitOp (ast *tree, ast **parent, const char *ops)
1894 if (tree && optimize.global_cse)
1896 /* is there a literal operand? */
1898 IS_AST_OP(tree->right) &&
1899 tree->right->right &&
1900 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1902 if (IS_LITERAL (RTYPE (tree->right)) ^
1903 IS_LITERAL (LTYPE (tree->right)))
1905 tree->right->decorated = 0;
1906 tree->decorated = 0;
1910 ret = searchLitOp (tree->right, parent, ops);
1915 IS_AST_OP(tree->left) &&
1916 tree->left->right &&
1917 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1919 if (IS_LITERAL (RTYPE (tree->left)) ^
1920 IS_LITERAL (LTYPE (tree->left)))
1922 tree->left->decorated = 0;
1923 tree->decorated = 0;
1927 ret = searchLitOp (tree->left, parent, ops);
1935 /*-----------------------------------------------------------------*/
1936 /* decorateType - compute type for this tree also does type checking */
1937 /* this is done bottom up, since type have to flow upwards */
1938 /* it also does constant folding, and paramater checking */
1939 /*-----------------------------------------------------------------*/
1941 decorateType (ast * tree)
1949 /* if already has type then do nothing */
1950 if (tree->decorated)
1953 tree->decorated = 1;
1956 /* print the line */
1957 /* if not block & function */
1958 if (tree->type == EX_OP &&
1959 (tree->opval.op != FUNCTION &&
1960 tree->opval.op != BLOCK &&
1961 tree->opval.op != NULLOP))
1963 filename = tree->filename;
1964 lineno = tree->lineno;
1968 /* if any child is an error | this one is an error do nothing */
1969 if (tree->isError ||
1970 (tree->left && tree->left->isError) ||
1971 (tree->right && tree->right->isError))
1974 /*------------------------------------------------------------------*/
1975 /*----------------------------*/
1976 /* leaf has been reached */
1977 /*----------------------------*/
1978 lineno=tree->lineno;
1979 /* if this is of type value */
1980 /* just get the type */
1981 if (tree->type == EX_VALUE)
1984 if (IS_LITERAL (tree->opval.val->etype))
1987 /* if this is a character array then declare it */
1988 if (IS_ARRAY (tree->opval.val->type))
1989 tree->opval.val = stringToSymbol (tree->opval.val);
1991 /* otherwise just copy the type information */
1992 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1996 if (tree->opval.val->sym)
1998 /* if the undefined flag is set then give error message */
1999 if (tree->opval.val->sym->undefined)
2001 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2003 TTYPE (tree) = TETYPE (tree) =
2004 tree->opval.val->type = tree->opval.val->sym->type =
2005 tree->opval.val->etype = tree->opval.val->sym->etype =
2006 copyLinkChain (INTTYPE);
2011 /* if impilicit i.e. struct/union member then no type */
2012 if (tree->opval.val->sym->implicit)
2013 TTYPE (tree) = TETYPE (tree) = NULL;
2018 /* else copy the type */
2019 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2021 /* and mark it as referenced */
2022 tree->opval.val->sym->isref = 1;
2030 /* if type link for the case of cast */
2031 if (tree->type == EX_LINK)
2033 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2040 dtl = decorateType (tree->left);
2041 /* delay right side for '?' operator since conditional macro expansions might
2043 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2045 /* this is to take care of situations
2046 when the tree gets rewritten */
2047 if (dtl != tree->left)
2049 if (dtr != tree->right)
2051 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2054 if (IS_AST_OP(tree) &&
2055 (tree->opval.op == CAST || tree->opval.op == '=') &&
2056 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2057 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2058 // this is a cast/assign to a bigger type
2059 if (IS_AST_OP(tree->right) &&
2060 IS_INTEGRAL(tree->right->ftype) &&
2061 (tree->right->opval.op == LEFT_OP ||
2062 tree->right->opval.op == '*' ||
2063 tree->right->opval.op == '+' ||
2064 tree->right->opval.op == '-') &&
2065 tree->right->right) {
2066 // we should cast an operand instead of the result
2067 tree->right->decorated = 0;
2068 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2070 tree->right = decorateType(tree->right);
2075 /* depending on type of operator do */
2077 switch (tree->opval.op)
2079 /*------------------------------------------------------------------*/
2080 /*----------------------------*/
2082 /*----------------------------*/
2085 /* determine which is the array & which the index */
2086 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2089 ast *tempTree = tree->left;
2090 tree->left = tree->right;
2091 tree->right = tempTree;
2094 /* first check if this is a array or a pointer */
2095 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2097 werror (E_NEED_ARRAY_PTR, "[]");
2098 goto errorTreeReturn;
2101 /* check if the type of the idx */
2102 if (!IS_INTEGRAL (RTYPE (tree)))
2104 werror (E_IDX_NOT_INT);
2105 goto errorTreeReturn;
2108 /* if the left is an rvalue then error */
2111 werror (E_LVALUE_REQUIRED, "array access");
2112 goto errorTreeReturn;
2115 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2118 /*------------------------------------------------------------------*/
2119 /*----------------------------*/
2121 /*----------------------------*/
2123 /* if this is not a structure */
2124 if (!IS_STRUCT (LTYPE (tree)))
2126 werror (E_STRUCT_UNION, ".");
2127 goto errorTreeReturn;
2129 TTYPE (tree) = structElemType (LTYPE (tree),
2130 (tree->right->type == EX_VALUE ?
2131 tree->right->opval.val : NULL));
2132 TETYPE (tree) = getSpec (TTYPE (tree));
2135 /*------------------------------------------------------------------*/
2136 /*----------------------------*/
2137 /* struct/union pointer */
2138 /*----------------------------*/
2140 /* if not pointer to a structure */
2141 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2143 werror (E_PTR_REQD);
2144 goto errorTreeReturn;
2147 if (!IS_STRUCT (LTYPE (tree)->next))
2149 werror (E_STRUCT_UNION, "->");
2150 goto errorTreeReturn;
2153 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2154 (tree->right->type == EX_VALUE ?
2155 tree->right->opval.val : NULL));
2156 TETYPE (tree) = getSpec (TTYPE (tree));
2158 /* adjust the storage class */
2159 switch (DCL_TYPE(tree->left->ftype)) {
2163 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2166 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2171 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2174 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2177 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2185 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2186 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2188 /* If defined struct type at addr var
2189 then rewrite (&struct var)->member
2191 and define membertype at (addr+offsetof(struct var,member)) temp
2194 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2195 AST_SYMBOL(tree->right));
2197 sym = newSymbol(genSymName (0), 0);
2198 sym->type = TTYPE (tree);
2199 sym->etype = getSpec(sym->type);
2200 sym->lineDef = tree->lineno;
2203 SPEC_STAT (sym->etype) = 1;
2204 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2206 SPEC_ABSA(sym->etype) = 1;
2207 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2210 AST_VALUE (tree) = symbolVal(sym);
2213 tree->type = EX_VALUE;
2220 /*------------------------------------------------------------------*/
2221 /*----------------------------*/
2222 /* ++/-- operation */
2223 /*----------------------------*/
2227 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2228 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2229 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2230 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2239 /*------------------------------------------------------------------*/
2240 /*----------------------------*/
2242 /*----------------------------*/
2243 case '&': /* can be unary */
2244 /* if right is NULL then unary operation */
2245 if (tree->right) /* not an unary operation */
2248 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2250 werror (E_BITWISE_OP);
2251 werror (W_CONTINUE, "left & right types are ");
2252 printTypeChain (LTYPE (tree), stderr);
2253 fprintf (stderr, ",");
2254 printTypeChain (RTYPE (tree), stderr);
2255 fprintf (stderr, "\n");
2256 goto errorTreeReturn;
2259 /* if they are both literal */
2260 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2262 tree->type = EX_VALUE;
2263 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2264 valFromType (RETYPE (tree)), '&');
2266 tree->right = tree->left = NULL;
2267 TETYPE (tree) = tree->opval.val->etype;
2268 TTYPE (tree) = tree->opval.val->type;
2272 /* see if this is a GETHBIT operation if yes
2275 ast *otree = optimizeGetHbit (tree);
2278 return decorateType (otree);
2282 computeType (LTYPE (tree), RTYPE (tree));
2283 TETYPE (tree) = getSpec (TTYPE (tree));
2285 /* if left is a literal exchange left & right */
2286 if (IS_LITERAL (LTYPE (tree)))
2288 ast *tTree = tree->left;
2289 tree->left = tree->right;
2290 tree->right = tTree;
2293 /* if right is a literal and */
2294 /* we can find a 2nd literal in a and-tree then */
2295 /* rearrange the tree */
2296 if (IS_LITERAL (RTYPE (tree)))
2299 ast *litTree = searchLitOp (tree, &parent, "&");
2302 ast *tTree = litTree->left;
2303 litTree->left = tree->right;
2304 tree->right = tTree;
2305 /* both operands in tTree are literal now */
2306 decorateType (parent);
2310 LRVAL (tree) = RRVAL (tree) = 1;
2314 /*------------------------------------------------------------------*/
2315 /*----------------------------*/
2317 /*----------------------------*/
2318 p = newLink (DECLARATOR);
2319 /* if bit field then error */
2320 if (IS_BITVAR (tree->left->etype))
2322 werror (E_ILLEGAL_ADDR, "address of bit variable");
2323 goto errorTreeReturn;
2326 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2328 werror (E_ILLEGAL_ADDR, "address of register variable");
2329 goto errorTreeReturn;
2332 if (IS_FUNC (LTYPE (tree)))
2334 // this ought to be ignored
2335 return (tree->left);
2338 if (IS_LITERAL(LTYPE(tree)))
2340 werror (E_ILLEGAL_ADDR, "address of literal");
2341 goto errorTreeReturn;
2346 werror (E_LVALUE_REQUIRED, "address of");
2347 goto errorTreeReturn;
2349 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2350 DCL_TYPE (p) = CPOINTER;
2351 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2352 DCL_TYPE (p) = FPOINTER;
2353 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2354 DCL_TYPE (p) = PPOINTER;
2355 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2356 DCL_TYPE (p) = IPOINTER;
2357 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2358 DCL_TYPE (p) = EEPPOINTER;
2359 else if (SPEC_OCLS(tree->left->etype))
2360 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2362 DCL_TYPE (p) = POINTER;
2364 if (IS_AST_SYM_VALUE (tree->left))
2366 AST_SYMBOL (tree->left)->addrtaken = 1;
2367 AST_SYMBOL (tree->left)->allocreq = 1;
2370 p->next = LTYPE (tree);
2372 TETYPE (tree) = getSpec (TTYPE (tree));
2377 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2378 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2380 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2381 AST_SYMBOL(tree->left->right));
2382 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2383 valueFromLit(element->offset));
2386 tree->type = EX_VALUE;
2387 tree->values.literalFromCast = 1;
2393 /*------------------------------------------------------------------*/
2394 /*----------------------------*/
2396 /*----------------------------*/
2398 /* if the rewrite succeeds then don't go any furthur */
2400 ast *wtree = optimizeRRCRLC (tree);
2402 return decorateType (wtree);
2406 /* if left is a literal exchange left & right */
2407 if (IS_LITERAL (LTYPE (tree)))
2409 ast *tTree = tree->left;
2410 tree->left = tree->right;
2411 tree->right = tTree;
2414 /* if right is a literal and */
2415 /* we can find a 2nd literal in a or-tree then */
2416 /* rearrange the tree */
2417 if (IS_LITERAL (RTYPE (tree)))
2420 ast *litTree = searchLitOp (tree, &parent, "|");
2423 ast *tTree = litTree->left;
2424 litTree->left = tree->right;
2425 tree->right = tTree;
2426 /* both operands in tTree are literal now */
2427 decorateType (parent);
2430 /*------------------------------------------------------------------*/
2431 /*----------------------------*/
2433 /*----------------------------*/
2435 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2437 werror (E_BITWISE_OP);
2438 werror (W_CONTINUE, "left & right types are ");
2439 printTypeChain (LTYPE (tree), stderr);
2440 fprintf (stderr, ",");
2441 printTypeChain (RTYPE (tree), stderr);
2442 fprintf (stderr, "\n");
2443 goto errorTreeReturn;
2446 /* if they are both literal then */
2447 /* rewrite the tree */
2448 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2450 tree->type = EX_VALUE;
2451 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2452 valFromType (RETYPE (tree)),
2454 tree->right = tree->left = NULL;
2455 TETYPE (tree) = tree->opval.val->etype;
2456 TTYPE (tree) = tree->opval.val->type;
2460 /* if left is a literal exchange left & right */
2461 if (IS_LITERAL (LTYPE (tree)))
2463 ast *tTree = tree->left;
2464 tree->left = tree->right;
2465 tree->right = tTree;
2468 /* if right is a literal and */
2469 /* we can find a 2nd literal in a xor-tree then */
2470 /* rearrange the tree */
2471 if (IS_LITERAL (RTYPE (tree)))
2474 ast *litTree = searchLitOp (tree, &parent, "^");
2477 ast *tTree = litTree->left;
2478 litTree->left = tree->right;
2479 tree->right = tTree;
2480 /* both operands in litTree are literal now */
2481 decorateType (parent);
2485 LRVAL (tree) = RRVAL (tree) = 1;
2486 TETYPE (tree) = getSpec (TTYPE (tree) =
2487 computeType (LTYPE (tree),
2490 /*------------------------------------------------------------------*/
2491 /*----------------------------*/
2493 /*----------------------------*/
2495 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2497 werror (E_INVALID_OP, "divide");
2498 goto errorTreeReturn;
2500 /* if they are both literal then */
2501 /* rewrite the tree */
2502 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2504 tree->type = EX_VALUE;
2505 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2506 valFromType (RETYPE (tree)));
2507 tree->right = tree->left = NULL;
2508 TETYPE (tree) = getSpec (TTYPE (tree) =
2509 tree->opval.val->type);
2513 LRVAL (tree) = RRVAL (tree) = 1;
2514 TETYPE (tree) = getSpec (TTYPE (tree) =
2515 computeType (LTYPE (tree),
2518 /* if right is a literal and */
2519 /* left is also a division by a literal then */
2520 /* rearrange the tree */
2521 if (IS_LITERAL (RTYPE (tree))
2522 /* avoid infinite loop */
2523 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2526 ast *litTree = searchLitOp (tree, &parent, "/");
2529 if (IS_LITERAL (RTYPE (litTree)))
2532 litTree->right = newNode ('*', litTree->right, tree->right);
2533 litTree->right->lineno = tree->lineno;
2535 tree->right->opval.val = constVal ("1");
2536 decorateType (parent);
2540 /* litTree->left is literal: no gcse possible.
2541 We can't call decorateType(parent), because
2542 this would cause an infinit loop. */
2543 parent->decorated = 1;
2544 decorateType (litTree);
2551 /*------------------------------------------------------------------*/
2552 /*----------------------------*/
2554 /*----------------------------*/
2556 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2558 werror (E_BITWISE_OP);
2559 werror (W_CONTINUE, "left & right types are ");
2560 printTypeChain (LTYPE (tree), stderr);
2561 fprintf (stderr, ",");
2562 printTypeChain (RTYPE (tree), stderr);
2563 fprintf (stderr, "\n");
2564 goto errorTreeReturn;
2566 /* if they are both literal then */
2567 /* rewrite the tree */
2568 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2570 tree->type = EX_VALUE;
2571 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2572 valFromType (RETYPE (tree)));
2573 tree->right = tree->left = NULL;
2574 TETYPE (tree) = getSpec (TTYPE (tree) =
2575 tree->opval.val->type);
2578 LRVAL (tree) = RRVAL (tree) = 1;
2579 TETYPE (tree) = getSpec (TTYPE (tree) =
2580 computeType (LTYPE (tree),
2584 /*------------------------------------------------------------------*/
2585 /*----------------------------*/
2586 /* address dereference */
2587 /*----------------------------*/
2588 case '*': /* can be unary : if right is null then unary operation */
2591 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2593 werror (E_PTR_REQD);
2594 goto errorTreeReturn;
2599 werror (E_LVALUE_REQUIRED, "pointer deref");
2600 goto errorTreeReturn;
2602 if (IS_ADDRESS_OF_OP(tree->left))
2604 /* replace *&obj with obj */
2605 return tree->left->left;
2607 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2608 TETYPE (tree) = getSpec (TTYPE (tree));
2612 /*------------------------------------------------------------------*/
2613 /*----------------------------*/
2614 /* multiplication */
2615 /*----------------------------*/
2616 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2618 werror (E_INVALID_OP, "multiplication");
2619 goto errorTreeReturn;
2622 /* if they are both literal then */
2623 /* rewrite the tree */
2624 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2626 tree->type = EX_VALUE;
2627 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2628 valFromType (RETYPE (tree)));
2629 tree->right = tree->left = NULL;
2630 TETYPE (tree) = getSpec (TTYPE (tree) =
2631 tree->opval.val->type);
2635 /* if left is a literal exchange left & right */
2636 if (IS_LITERAL (LTYPE (tree)))
2638 ast *tTree = tree->left;
2639 tree->left = tree->right;
2640 tree->right = tTree;
2643 /* if right is a literal and */
2644 /* we can find a 2nd literal in a mul-tree then */
2645 /* rearrange the tree */
2646 if (IS_LITERAL (RTYPE (tree)))
2649 ast *litTree = searchLitOp (tree, &parent, "*");
2652 ast *tTree = litTree->left;
2653 litTree->left = tree->right;
2654 tree->right = tTree;
2655 /* both operands in litTree are literal now */
2656 decorateType (parent);
2660 LRVAL (tree) = RRVAL (tree) = 1;
2661 TETYPE (tree) = getSpec (TTYPE (tree) =
2662 computeType (LTYPE (tree),
2665 /* promote result to int if left & right are char
2666 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2667 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2668 SPEC_NOUN(TETYPE(tree)) = V_INT;
2673 /*------------------------------------------------------------------*/
2674 /*----------------------------*/
2675 /* unary '+' operator */
2676 /*----------------------------*/
2681 if (!IS_INTEGRAL (LTYPE (tree)))
2683 werror (E_UNARY_OP, '+');
2684 goto errorTreeReturn;
2687 /* if left is a literal then do it */
2688 if (IS_LITERAL (LTYPE (tree)))
2690 tree->type = EX_VALUE;
2691 tree->opval.val = valFromType (LETYPE (tree));
2693 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2697 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2701 /*------------------------------------------------------------------*/
2702 /*----------------------------*/
2704 /*----------------------------*/
2706 /* this is not a unary operation */
2707 /* if both pointers then problem */
2708 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2709 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2711 werror (E_PTR_PLUS_PTR);
2712 goto errorTreeReturn;
2715 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2716 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2718 werror (E_PLUS_INVALID, "+");
2719 goto errorTreeReturn;
2722 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2723 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2725 werror (E_PLUS_INVALID, "+");
2726 goto errorTreeReturn;
2728 /* if they are both literal then */
2729 /* rewrite the tree */
2730 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2732 tree->type = EX_VALUE;
2733 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2734 valFromType (RETYPE (tree)));
2735 tree->right = tree->left = NULL;
2736 TETYPE (tree) = getSpec (TTYPE (tree) =
2737 tree->opval.val->type);
2741 /* if the right is a pointer or left is a literal
2742 xchange left & right */
2743 if (IS_ARRAY (RTYPE (tree)) ||
2744 IS_PTR (RTYPE (tree)) ||
2745 IS_LITERAL (LTYPE (tree)))
2747 ast *tTree = tree->left;
2748 tree->left = tree->right;
2749 tree->right = tTree;
2752 /* if right is a literal and */
2753 /* left is also an addition/subtraction with a literal then */
2754 /* rearrange the tree */
2755 if (IS_LITERAL (RTYPE (tree)))
2757 ast *litTree, *parent;
2758 litTree = searchLitOp (tree, &parent, "+-");
2761 if (litTree->opval.op == '+')
2764 ast *tTree = litTree->left;
2765 litTree->left = tree->right;
2766 tree->right = tree->left;
2769 else if (litTree->opval.op == '-')
2771 if (IS_LITERAL (RTYPE (litTree)))
2774 ast *tTree = litTree->left;
2775 litTree->left = tree->right;
2776 tree->right = tTree;
2781 ast *tTree = litTree->right;
2782 litTree->right = tree->right;
2783 tree->right = tTree;
2784 litTree->opval.op = '+';
2785 tree->opval.op = '-';
2788 decorateType (parent);
2792 LRVAL (tree) = RRVAL (tree) = 1;
2793 /* if the left is a pointer */
2794 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2795 TETYPE (tree) = getSpec (TTYPE (tree) =
2798 TETYPE (tree) = getSpec (TTYPE (tree) =
2799 computeType (LTYPE (tree),
2803 /*------------------------------------------------------------------*/
2804 /*----------------------------*/
2806 /*----------------------------*/
2807 case '-': /* can be unary */
2808 /* if right is null then unary */
2812 if (!IS_ARITHMETIC (LTYPE (tree)))
2814 werror (E_UNARY_OP, tree->opval.op);
2815 goto errorTreeReturn;
2818 /* if left is a literal then do it */
2819 if (IS_LITERAL (LTYPE (tree)))
2821 tree->type = EX_VALUE;
2822 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2824 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2825 SPEC_USIGN(TETYPE(tree)) = 0;
2829 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2833 /*------------------------------------------------------------------*/
2834 /*----------------------------*/
2836 /*----------------------------*/
2838 if (!(IS_PTR (LTYPE (tree)) ||
2839 IS_ARRAY (LTYPE (tree)) ||
2840 IS_ARITHMETIC (LTYPE (tree))))
2842 werror (E_PLUS_INVALID, "-");
2843 goto errorTreeReturn;
2846 if (!(IS_PTR (RTYPE (tree)) ||
2847 IS_ARRAY (RTYPE (tree)) ||
2848 IS_ARITHMETIC (RTYPE (tree))))
2850 werror (E_PLUS_INVALID, "-");
2851 goto errorTreeReturn;
2854 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2855 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2856 IS_INTEGRAL (RTYPE (tree))))
2858 werror (E_PLUS_INVALID, "-");
2859 goto errorTreeReturn;
2862 /* if they are both literal then */
2863 /* rewrite the tree */
2864 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2866 tree->type = EX_VALUE;
2867 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2868 valFromType (RETYPE (tree)));
2869 tree->right = tree->left = NULL;
2870 TETYPE (tree) = getSpec (TTYPE (tree) =
2871 tree->opval.val->type);
2875 /* if the left & right are equal then zero */
2876 if (isAstEqual (tree->left, tree->right))
2878 tree->type = EX_VALUE;
2879 tree->left = tree->right = NULL;
2880 tree->opval.val = constVal ("0");
2881 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2885 /* if both of them are pointers or arrays then */
2886 /* the result is going to be an integer */
2887 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2888 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2889 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2891 /* if only the left is a pointer */
2892 /* then result is a pointer */
2893 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2894 TETYPE (tree) = getSpec (TTYPE (tree) =
2897 TETYPE (tree) = getSpec (TTYPE (tree) =
2898 computeType (LTYPE (tree),
2901 LRVAL (tree) = RRVAL (tree) = 1;
2903 /* if right is a literal and */
2904 /* left is also an addition/subtraction with a literal then */
2905 /* rearrange the tree */
2906 if (IS_LITERAL (RTYPE (tree))
2907 /* avoid infinite loop */
2908 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
2910 ast *litTree, *litParent;
2911 litTree = searchLitOp (tree, &litParent, "+-");
2914 if (litTree->opval.op == '+')
2917 litTree->right = newNode ('-', litTree->right, tree->right);
2918 litTree->right->lineno = tree->lineno;
2920 tree->right->opval.val = constVal ("0");
2922 else if (litTree->opval.op == '-')
2924 if (IS_LITERAL (RTYPE (litTree)))
2927 litTree->right = newNode ('+', tree->right, litTree->right);
2928 litTree->right->lineno = tree->lineno;
2930 tree->right->opval.val = constVal ("0");
2935 ast *tTree = litTree->right;
2936 litTree->right = tree->right;
2937 tree->right = tTree;
2940 decorateType (litParent);
2945 /*------------------------------------------------------------------*/
2946 /*----------------------------*/
2948 /*----------------------------*/
2950 /* can be only integral type */
2951 if (!IS_INTEGRAL (LTYPE (tree)))
2953 werror (E_UNARY_OP, tree->opval.op);
2954 goto errorTreeReturn;
2957 /* if left is a literal then do it */
2958 if (IS_LITERAL (LTYPE (tree)))
2960 tree->type = EX_VALUE;
2961 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2963 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2967 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2970 /*------------------------------------------------------------------*/
2971 /*----------------------------*/
2973 /*----------------------------*/
2975 /* can be pointer */
2976 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2977 !IS_PTR (LTYPE (tree)) &&
2978 !IS_ARRAY (LTYPE (tree)))
2980 werror (E_UNARY_OP, tree->opval.op);
2981 goto errorTreeReturn;
2984 /* if left is a literal then do it */
2985 if (IS_LITERAL (LTYPE (tree)))
2987 tree->type = EX_VALUE;
2988 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2990 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2994 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2997 /*------------------------------------------------------------------*/
2998 /*----------------------------*/
3000 /*----------------------------*/
3003 TTYPE (tree) = LTYPE (tree);
3004 TETYPE (tree) = LETYPE (tree);
3008 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3013 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3015 werror (E_SHIFT_OP_INVALID);
3016 werror (W_CONTINUE, "left & right types are ");
3017 printTypeChain (LTYPE (tree), stderr);
3018 fprintf (stderr, ",");
3019 printTypeChain (RTYPE (tree), stderr);
3020 fprintf (stderr, "\n");
3021 goto errorTreeReturn;
3024 /* if they are both literal then */
3025 /* rewrite the tree */
3026 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3028 tree->type = EX_VALUE;
3029 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3030 valFromType (RETYPE (tree)),
3031 (tree->opval.op == LEFT_OP ? 1 : 0));
3032 tree->right = tree->left = NULL;
3033 TETYPE (tree) = getSpec (TTYPE (tree) =
3034 tree->opval.val->type);
3038 /* if only the right side is a literal & we are
3039 shifting more than size of the left operand then zero */
3040 if (IS_LITERAL (RTYPE (tree)) &&
3041 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3042 (getSize (LTYPE (tree)) * 8))
3044 if (tree->opval.op==LEFT_OP ||
3045 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3046 lineno=tree->lineno;
3047 werror (W_SHIFT_CHANGED,
3048 (tree->opval.op == LEFT_OP ? "left" : "right"));
3049 tree->type = EX_VALUE;
3050 tree->left = tree->right = NULL;
3051 tree->opval.val = constVal ("0");
3052 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3056 LRVAL (tree) = RRVAL (tree) = 1;
3057 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
3059 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
3063 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3067 /*------------------------------------------------------------------*/
3068 /*----------------------------*/
3070 /*----------------------------*/
3071 case CAST: /* change the type */
3072 /* cannot cast to an aggregate type */
3073 if (IS_AGGREGATE (LTYPE (tree)))
3075 werror (E_CAST_ILLEGAL);
3076 goto errorTreeReturn;
3079 /* make sure the type is complete and sane */
3080 checkTypeSanity(LETYPE(tree), "(cast)");
3083 /* if the right is a literal replace the tree */
3084 if (IS_LITERAL (RETYPE (tree))) {
3085 if (!IS_PTR (LTYPE (tree))) {
3086 tree->type = EX_VALUE;
3088 valCastLiteral (LTYPE (tree),
3089 floatFromVal (valFromType (RETYPE (tree))));
3092 TTYPE (tree) = tree->opval.val->type;
3093 tree->values.literalFromCast = 1;
3094 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3095 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3096 sym_link *rest = LTYPE(tree)->next;
3097 werror(W_LITERAL_GENERIC);
3098 TTYPE(tree) = newLink(DECLARATOR);
3099 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3100 TTYPE(tree)->next = rest;
3101 tree->left->opval.lnk = TTYPE(tree);
3104 TTYPE (tree) = LTYPE (tree);
3108 TTYPE (tree) = LTYPE (tree);
3112 #if 0 // this is already checked, now this could be explicit
3113 /* if pointer to struct then check names */
3114 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3115 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3116 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3118 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3119 SPEC_STRUCT(LETYPE(tree))->tag);
3122 if (IS_ADDRESS_OF_OP(tree->right)
3123 && IS_AST_SYM_VALUE (tree->right->left)
3124 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3126 tree->type = EX_VALUE;
3128 valCastLiteral (LTYPE (tree),
3129 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3130 TTYPE (tree) = tree->opval.val->type;
3131 TETYPE (tree) = getSpec (TTYPE (tree));
3134 tree->values.literalFromCast = 1;
3138 /* handle offsetof macro: */
3139 /* #define offsetof(TYPE, MEMBER) \ */
3140 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3141 if (IS_ADDRESS_OF_OP(tree->right)
3142 && IS_AST_OP (tree->right->left)
3143 && tree->right->left->opval.op == PTR_OP
3144 && IS_AST_OP (tree->right->left->left)
3145 && tree->right->left->left->opval.op == CAST
3146 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3148 symbol *element = getStructElement (
3149 SPEC_STRUCT (LETYPE(tree->right->left)),
3150 AST_SYMBOL(tree->right->left->right)
3154 tree->type = EX_VALUE;
3155 tree->opval.val = valCastLiteral (
3158 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3161 TTYPE (tree) = tree->opval.val->type;
3162 TETYPE (tree) = getSpec (TTYPE (tree));
3169 /* if the right is a literal replace the tree */
3170 if (IS_LITERAL (RETYPE (tree))) {
3171 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3172 /* rewrite (type *)litaddr
3174 and define type at litaddr temp
3175 (but only if type's storage class is not generic)
3177 ast *newTree = newNode ('&', NULL, NULL);
3180 TTYPE (newTree) = LTYPE (tree);
3181 TETYPE (newTree) = getSpec(LTYPE (tree));
3183 /* define a global symbol at the casted address*/
3184 sym = newSymbol(genSymName (0), 0);
3185 sym->type = LTYPE (tree)->next;
3187 sym->type = newLink (V_VOID);
3188 sym->etype = getSpec(sym->type);
3189 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3190 sym->lineDef = tree->lineno;
3193 SPEC_STAT (sym->etype) = 1;
3194 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3195 SPEC_ABSA(sym->etype) = 1;
3196 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3199 newTree->left = newAst_VALUE(symbolVal(sym));
3200 newTree->left->lineno = tree->lineno;
3201 LTYPE (newTree) = sym->type;
3202 LETYPE (newTree) = sym->etype;
3203 LLVAL (newTree) = 1;
3204 LRVAL (newTree) = 0;
3205 TLVAL (newTree) = 1;
3208 if (!IS_PTR (LTYPE (tree))) {
3209 tree->type = EX_VALUE;
3211 valCastLiteral (LTYPE (tree),
3212 floatFromVal (valFromType (RETYPE (tree))));
3213 TTYPE (tree) = tree->opval.val->type;
3216 tree->values.literalFromCast = 1;
3217 TETYPE (tree) = getSpec (TTYPE (tree));
3221 TTYPE (tree) = LTYPE (tree);
3225 TETYPE (tree) = getSpec (TTYPE (tree));
3229 /*------------------------------------------------------------------*/
3230 /*----------------------------*/
3231 /* logical &&, || */
3232 /*----------------------------*/
3235 /* each must me arithmetic type or be a pointer */
3236 if (!IS_PTR (LTYPE (tree)) &&
3237 !IS_ARRAY (LTYPE (tree)) &&
3238 !IS_INTEGRAL (LTYPE (tree)))
3240 werror (E_COMPARE_OP);
3241 goto errorTreeReturn;
3244 if (!IS_PTR (RTYPE (tree)) &&
3245 !IS_ARRAY (RTYPE (tree)) &&
3246 !IS_INTEGRAL (RTYPE (tree)))
3248 werror (E_COMPARE_OP);
3249 goto errorTreeReturn;
3251 /* if they are both literal then */
3252 /* rewrite the tree */
3253 if (IS_LITERAL (RTYPE (tree)) &&
3254 IS_LITERAL (LTYPE (tree)))
3256 tree->type = EX_VALUE;
3257 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3258 valFromType (RETYPE (tree)),
3260 tree->right = tree->left = NULL;
3261 TETYPE (tree) = getSpec (TTYPE (tree) =
3262 tree->opval.val->type);
3265 LRVAL (tree) = RRVAL (tree) = 1;
3266 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3269 /*------------------------------------------------------------------*/
3270 /*----------------------------*/
3271 /* comparison operators */
3272 /*----------------------------*/
3280 ast *lt = optimizeCompare (tree);
3286 /* if they are pointers they must be castable */
3287 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3289 if (tree->opval.op==EQ_OP &&
3290 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3291 // we cannot cast a gptr to a !gptr: switch the leaves
3292 struct ast *s=tree->left;
3293 tree->left=tree->right;
3296 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3298 werror (E_COMPARE_OP);
3299 fprintf (stderr, "comparring type ");
3300 printTypeChain (LTYPE (tree), stderr);
3301 fprintf (stderr, "to type ");
3302 printTypeChain (RTYPE (tree), stderr);
3303 fprintf (stderr, "\n");
3304 goto errorTreeReturn;
3307 /* else they should be promotable to one another */
3310 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3311 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3313 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3315 werror (E_COMPARE_OP);
3316 fprintf (stderr, "comparing type ");
3317 printTypeChain (LTYPE (tree), stderr);
3318 fprintf (stderr, "to type ");
3319 printTypeChain (RTYPE (tree), stderr);
3320 fprintf (stderr, "\n");
3321 goto errorTreeReturn;
3324 /* if unsigned value < 0 then always false */
3325 /* if (unsigned value) > 0 then (unsigned value) */
3326 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3327 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3329 if (tree->opval.op == '<') {
3332 if (tree->opval.op == '>') {
3336 /* if they are both literal then */
3337 /* rewrite the tree */
3338 if (IS_LITERAL (RTYPE (tree)) &&
3339 IS_LITERAL (LTYPE (tree)))
3341 tree->type = EX_VALUE;
3342 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3343 valFromType (RETYPE (tree)),
3345 tree->right = tree->left = NULL;
3346 TETYPE (tree) = getSpec (TTYPE (tree) =
3347 tree->opval.val->type);
3350 LRVAL (tree) = RRVAL (tree) = 1;
3351 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3354 /*------------------------------------------------------------------*/
3355 /*----------------------------*/
3357 /*----------------------------*/
3358 case SIZEOF: /* evaluate wihout code generation */
3359 /* change the type to a integer */
3360 tree->type = EX_VALUE;
3361 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3362 tree->opval.val = constVal (buffer);
3363 tree->right = tree->left = NULL;
3364 TETYPE (tree) = getSpec (TTYPE (tree) =
3365 tree->opval.val->type);
3368 /*------------------------------------------------------------------*/
3369 /*----------------------------*/
3371 /*----------------------------*/
3373 /* return typeof enum value */
3374 tree->type = EX_VALUE;
3377 if (IS_SPEC(tree->right->ftype)) {
3378 switch (SPEC_NOUN(tree->right->ftype)) {
3380 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3381 else typeofv = TYPEOF_INT;
3384 typeofv = TYPEOF_FLOAT;
3387 typeofv = TYPEOF_CHAR;
3390 typeofv = TYPEOF_VOID;
3393 typeofv = TYPEOF_STRUCT;
3396 typeofv = TYPEOF_BITFIELD;
3399 typeofv = TYPEOF_BIT;
3402 typeofv = TYPEOF_SBIT;
3408 switch (DCL_TYPE(tree->right->ftype)) {
3410 typeofv = TYPEOF_POINTER;
3413 typeofv = TYPEOF_FPOINTER;
3416 typeofv = TYPEOF_CPOINTER;
3419 typeofv = TYPEOF_GPOINTER;
3422 typeofv = TYPEOF_PPOINTER;
3425 typeofv = TYPEOF_IPOINTER;
3428 typeofv = TYPEOF_ARRAY;
3431 typeofv = TYPEOF_FUNCTION;
3437 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3438 tree->opval.val = constVal (buffer);
3439 tree->right = tree->left = NULL;
3440 TETYPE (tree) = getSpec (TTYPE (tree) =
3441 tree->opval.val->type);
3444 /*------------------------------------------------------------------*/
3445 /*----------------------------*/
3446 /* conditional operator '?' */
3447 /*----------------------------*/
3449 /* the type is value of the colon operator (on the right) */
3450 assert(IS_COLON_OP(tree->right));
3451 /* if already known then replace the tree : optimizer will do it
3452 but faster to do it here */
3453 if (IS_LITERAL (LTYPE(tree))) {
3454 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3455 return decorateType(tree->right->left) ;
3457 return decorateType(tree->right->right) ;
3460 tree->right = decorateType(tree->right);
3461 TTYPE (tree) = RTYPE(tree);
3462 TETYPE (tree) = getSpec (TTYPE (tree));
3467 /* if they don't match we have a problem */
3468 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3470 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3471 goto errorTreeReturn;
3474 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3475 TETYPE (tree) = getSpec (TTYPE (tree));
3479 #if 0 // assignment operators are converted by the parser
3480 /*------------------------------------------------------------------*/
3481 /*----------------------------*/
3482 /* assignment operators */
3483 /*----------------------------*/
3486 /* for these it must be both must be integral */
3487 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3488 !IS_ARITHMETIC (RTYPE (tree)))
3490 werror (E_OPS_INTEGRAL);
3491 goto errorTreeReturn;
3494 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3496 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3497 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3501 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3502 goto errorTreeReturn;
3513 /* for these it must be both must be integral */
3514 if (!IS_INTEGRAL (LTYPE (tree)) ||
3515 !IS_INTEGRAL (RTYPE (tree)))
3517 werror (E_OPS_INTEGRAL);
3518 goto errorTreeReturn;
3521 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3523 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3524 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3528 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3529 goto errorTreeReturn;
3535 /*------------------------------------------------------------------*/
3536 /*----------------------------*/
3538 /*----------------------------*/
3540 if (!(IS_PTR (LTYPE (tree)) ||
3541 IS_ARITHMETIC (LTYPE (tree))))
3543 werror (E_PLUS_INVALID, "-=");
3544 goto errorTreeReturn;
3547 if (!(IS_PTR (RTYPE (tree)) ||
3548 IS_ARITHMETIC (RTYPE (tree))))
3550 werror (E_PLUS_INVALID, "-=");
3551 goto errorTreeReturn;
3554 TETYPE (tree) = getSpec (TTYPE (tree) =
3555 computeType (LTYPE (tree),
3558 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3559 werror (E_CODE_WRITE, "-=");
3563 werror (E_LVALUE_REQUIRED, "-=");
3564 goto errorTreeReturn;
3570 /*------------------------------------------------------------------*/
3571 /*----------------------------*/
3573 /*----------------------------*/
3575 /* this is not a unary operation */
3576 /* if both pointers then problem */
3577 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3579 werror (E_PTR_PLUS_PTR);
3580 goto errorTreeReturn;
3583 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3585 werror (E_PLUS_INVALID, "+=");
3586 goto errorTreeReturn;
3589 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3591 werror (E_PLUS_INVALID, "+=");
3592 goto errorTreeReturn;
3595 TETYPE (tree) = getSpec (TTYPE (tree) =
3596 computeType (LTYPE (tree),
3599 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3600 werror (E_CODE_WRITE, "+=");
3604 werror (E_LVALUE_REQUIRED, "+=");
3605 goto errorTreeReturn;
3608 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3609 tree->opval.op = '=';
3614 /*------------------------------------------------------------------*/
3615 /*----------------------------*/
3616 /* straight assignemnt */
3617 /*----------------------------*/
3619 /* cannot be an aggregate */
3620 if (IS_AGGREGATE (LTYPE (tree)))
3622 werror (E_AGGR_ASSIGN);
3623 goto errorTreeReturn;
3626 /* they should either match or be castable */
3627 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3629 werror (E_TYPE_MISMATCH, "assignment", " ");
3630 printFromToType(RTYPE(tree),LTYPE(tree));
3633 /* if the left side of the tree is of type void
3634 then report error */
3635 if (IS_VOID (LTYPE (tree)))
3637 werror (E_CAST_ZERO);
3638 printFromToType(RTYPE(tree), LTYPE(tree));
3641 TETYPE (tree) = getSpec (TTYPE (tree) =
3645 if (!tree->initMode ) {
3646 if (IS_CONSTANT(LTYPE(tree)))
3647 werror (E_CODE_WRITE, "=");
3651 werror (E_LVALUE_REQUIRED, "=");
3652 goto errorTreeReturn;
3657 /*------------------------------------------------------------------*/
3658 /*----------------------------*/
3659 /* comma operator */
3660 /*----------------------------*/
3662 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3665 /*------------------------------------------------------------------*/
3666 /*----------------------------*/
3668 /*----------------------------*/
3672 if (processParms (tree->left,
3673 FUNC_ARGS(tree->left->ftype),
3674 tree->right, &parmNumber, TRUE)) {
3675 goto errorTreeReturn;
3678 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3679 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3681 reverseParms (tree->right);
3684 if (IS_CODEPTR(LTYPE(tree))) {
3685 TTYPE(tree) = LTYPE(tree)->next->next;
3687 TTYPE(tree) = LTYPE(tree)->next;
3689 TETYPE (tree) = getSpec (TTYPE (tree));
3692 /*------------------------------------------------------------------*/
3693 /*----------------------------*/
3694 /* return statement */
3695 /*----------------------------*/
3700 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3702 werror (W_RETURN_MISMATCH);
3703 printFromToType (RTYPE(tree), currFunc->type->next);
3704 goto errorTreeReturn;
3707 if (IS_VOID (currFunc->type->next)
3709 !IS_VOID (RTYPE (tree)))
3711 werror (E_FUNC_VOID);
3712 goto errorTreeReturn;
3715 /* if there is going to be a casing required then add it */
3716 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3719 decorateType (newNode (CAST,
3720 newAst_LINK (copyLinkChain (currFunc->type->next)),
3729 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3731 werror (W_VOID_FUNC, currFunc->name);
3732 goto errorTreeReturn;
3735 TTYPE (tree) = TETYPE (tree) = NULL;
3738 /*------------------------------------------------------------------*/
3739 /*----------------------------*/
3740 /* switch statement */
3741 /*----------------------------*/
3743 /* the switch value must be an integer */
3744 if (!IS_INTEGRAL (LTYPE (tree)))
3746 werror (E_SWITCH_NON_INTEGER);
3747 goto errorTreeReturn;
3750 TTYPE (tree) = TETYPE (tree) = NULL;
3753 /*------------------------------------------------------------------*/
3754 /*----------------------------*/
3756 /*----------------------------*/
3758 tree->left = backPatchLabels (tree->left,
3761 TTYPE (tree) = TETYPE (tree) = NULL;
3764 /*------------------------------------------------------------------*/
3765 /*----------------------------*/
3767 /*----------------------------*/
3770 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3771 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3772 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3774 /* if the for loop is reversible then
3775 reverse it otherwise do what we normally
3781 if (isLoopReversible (tree, &sym, &init, &end))
3782 return reverseLoop (tree, sym, init, end);
3784 return decorateType (createFor (AST_FOR (tree, trueLabel),
3785 AST_FOR (tree, continueLabel),
3786 AST_FOR (tree, falseLabel),
3787 AST_FOR (tree, condLabel),
3788 AST_FOR (tree, initExpr),
3789 AST_FOR (tree, condExpr),
3790 AST_FOR (tree, loopExpr),
3794 TTYPE (tree) = TETYPE (tree) = NULL;
3798 /* some error found this tree will be killed */
3800 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3801 tree->opval.op = NULLOP;
3807 /*-----------------------------------------------------------------*/
3808 /* sizeofOp - processes size of operation */
3809 /*-----------------------------------------------------------------*/
3811 sizeofOp (sym_link * type)
3815 /* make sure the type is complete and sane */
3816 checkTypeSanity(type, "(sizeof)");
3818 /* get the size and convert it to character */
3819 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3821 /* now convert into value */
3822 return constVal (buff);
3826 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3827 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3828 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3829 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3830 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3831 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3832 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3834 /*-----------------------------------------------------------------*/
3835 /* backPatchLabels - change and or not operators to flow control */
3836 /*-----------------------------------------------------------------*/
3838 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3844 if (!(IS_ANDORNOT (tree)))
3847 /* if this an and */
3850 static int localLbl = 0;
3853 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3854 localLabel = newSymbol (buffer, NestLevel);
3856 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3858 /* if left is already a IFX then just change the if true label in that */
3859 if (!IS_IFX (tree->left))
3860 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3862 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3863 /* right is a IFX then just join */
3864 if (IS_IFX (tree->right))
3865 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3867 tree->right = createLabel (localLabel, tree->right);
3868 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3870 return newNode (NULLOP, tree->left, tree->right);
3873 /* if this is an or operation */
3876 static int localLbl = 0;
3879 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3880 localLabel = newSymbol (buffer, NestLevel);
3882 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3884 /* if left is already a IFX then just change the if true label in that */
3885 if (!IS_IFX (tree->left))
3886 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3888 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3889 /* right is a IFX then just join */
3890 if (IS_IFX (tree->right))
3891 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3893 tree->right = createLabel (localLabel, tree->right);
3894 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3896 return newNode (NULLOP, tree->left, tree->right);
3902 int wasnot = IS_NOT (tree->left);
3903 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3905 /* if the left is already a IFX */
3906 if (!IS_IFX (tree->left))
3907 tree->left = newNode (IFX, tree->left, NULL);
3911 tree->left->trueLabel = trueLabel;
3912 tree->left->falseLabel = falseLabel;
3916 tree->left->trueLabel = falseLabel;
3917 tree->left->falseLabel = trueLabel;
3924 tree->trueLabel = trueLabel;
3925 tree->falseLabel = falseLabel;
3932 /*-----------------------------------------------------------------*/
3933 /* createBlock - create expression tree for block */
3934 /*-----------------------------------------------------------------*/
3936 createBlock (symbol * decl, ast * body)
3940 /* if the block has nothing */
3944 ex = newNode (BLOCK, NULL, body);
3945 ex->values.sym = decl;
3947 ex->right = ex->right;
3953 /*-----------------------------------------------------------------*/
3954 /* createLabel - creates the expression tree for labels */
3955 /*-----------------------------------------------------------------*/
3957 createLabel (symbol * label, ast * stmnt)
3960 char name[SDCC_NAME_MAX + 1];
3963 /* must create fresh symbol if the symbol name */
3964 /* exists in the symbol table, since there can */
3965 /* be a variable with the same name as the labl */
3966 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3967 (csym->level == label->level))
3968 label = newSymbol (label->name, label->level);
3970 /* change the name before putting it in add _ */
3971 SNPRINTF(name, sizeof(name), "%s", label->name);
3973 /* put the label in the LabelSymbol table */
3974 /* but first check if a label of the same */
3976 if ((csym = findSym (LabelTab, NULL, name)))
3977 werror (E_DUPLICATE_LABEL, label->name);
3979 addSym (LabelTab, label, name, label->level, 0, 0);
3982 label->key = labelKey++;
3983 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3989 /*-----------------------------------------------------------------*/
3990 /* createCase - generates the parsetree for a case statement */
3991 /*-----------------------------------------------------------------*/
3993 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3995 char caseLbl[SDCC_NAME_MAX + 1];
3999 /* if the switch statement does not exist */
4000 /* then case is out of context */
4003 werror (E_CASE_CONTEXT);
4007 caseVal = decorateType (resolveSymbols (caseVal));
4008 /* if not a constant then error */
4009 if (!IS_LITERAL (caseVal->ftype))
4011 werror (E_CASE_CONSTANT);
4015 /* if not a integer than error */
4016 if (!IS_INTEGRAL (caseVal->ftype))
4018 werror (E_CASE_NON_INTEGER);
4022 /* find the end of the switch values chain */
4023 if (!(val = swStat->values.switchVals.swVals))
4024 swStat->values.switchVals.swVals = caseVal->opval.val;
4027 /* also order the cases according to value */
4029 int cVal = (int) floatFromVal (caseVal->opval.val);
4030 while (val && (int) floatFromVal (val) < cVal)
4036 /* if we reached the end then */
4039 pval->next = caseVal->opval.val;
4043 /* we found a value greater than */
4044 /* the current value we must add this */
4045 /* before the value */
4046 caseVal->opval.val->next = val;
4048 /* if this was the first in chain */
4049 if (swStat->values.switchVals.swVals == val)
4050 swStat->values.switchVals.swVals =
4053 pval->next = caseVal->opval.val;
4058 /* create the case label */
4059 SNPRINTF(caseLbl, sizeof(caseLbl),
4061 swStat->values.switchVals.swNum,
4062 (int) floatFromVal (caseVal->opval.val));
4064 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4069 /*-----------------------------------------------------------------*/
4070 /* createDefault - creates the parse tree for the default statement */
4071 /*-----------------------------------------------------------------*/
4073 createDefault (ast * swStat, ast * stmnt)
4075 char defLbl[SDCC_NAME_MAX + 1];
4077 /* if the switch statement does not exist */
4078 /* then case is out of context */
4081 werror (E_CASE_CONTEXT);
4085 /* turn on the default flag */
4086 swStat->values.switchVals.swDefault = 1;
4088 /* create the label */
4089 SNPRINTF (defLbl, sizeof(defLbl),
4090 "_default_%d", swStat->values.switchVals.swNum);
4091 return createLabel (newSymbol (defLbl, 0), stmnt);
4094 /*-----------------------------------------------------------------*/
4095 /* createIf - creates the parsetree for the if statement */
4096 /*-----------------------------------------------------------------*/
4098 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4100 static int Lblnum = 0;
4102 symbol *ifTrue, *ifFalse, *ifEnd;
4104 /* if neither exists */
4105 if (!elseBody && !ifBody) {
4106 // if there are no side effects (i++, j() etc)
4107 if (!hasSEFcalls(condAst)) {
4112 /* create the labels */
4113 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4114 ifFalse = newSymbol (buffer, NestLevel);
4115 /* if no else body then end == false */
4120 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4121 ifEnd = newSymbol (buffer, NestLevel);
4124 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4125 ifTrue = newSymbol (buffer, NestLevel);
4129 /* attach the ifTrue label to the top of it body */
4130 ifBody = createLabel (ifTrue, ifBody);
4131 /* attach a goto end to the ifBody if else is present */
4134 ifBody = newNode (NULLOP, ifBody,
4136 newAst_VALUE (symbolVal (ifEnd)),
4138 /* put the elseLabel on the else body */
4139 elseBody = createLabel (ifFalse, elseBody);
4140 /* out the end at the end of the body */
4141 elseBody = newNode (NULLOP,
4143 createLabel (ifEnd, NULL));
4147 ifBody = newNode (NULLOP, ifBody,
4148 createLabel (ifFalse, NULL));
4150 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4151 if (IS_IFX (condAst))
4154 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4156 return newNode (NULLOP, ifTree,
4157 newNode (NULLOP, ifBody, elseBody));
4161 /*-----------------------------------------------------------------*/
4162 /* createDo - creates parse tree for do */
4165 /* _docontinue_n: */
4166 /* condition_expression +-> trueLabel -> _dobody_n */
4168 /* +-> falseLabel-> _dobreak_n */
4170 /*-----------------------------------------------------------------*/
4172 createDo (symbol * trueLabel, symbol * continueLabel,
4173 symbol * falseLabel, ast * condAst, ast * doBody)
4178 /* if the body does not exist then it is simple */
4181 condAst = backPatchLabels (condAst, continueLabel, NULL);
4182 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4183 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4184 doTree->trueLabel = continueLabel;
4185 doTree->falseLabel = NULL;
4189 /* otherwise we have a body */
4190 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4192 /* attach the body label to the top */
4193 doBody = createLabel (trueLabel, doBody);
4194 /* attach the continue label to end of body */
4195 doBody = newNode (NULLOP, doBody,
4196 createLabel (continueLabel, NULL));
4198 /* now put the break label at the end */
4199 if (IS_IFX (condAst))
4202 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4204 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4206 /* putting it together */
4207 return newNode (NULLOP, doBody, doTree);
4210 /*-----------------------------------------------------------------*/
4211 /* createFor - creates parse tree for 'for' statement */
4214 /* condExpr +-> trueLabel -> _forbody_n */
4216 /* +-> falseLabel-> _forbreak_n */
4219 /* _forcontinue_n: */
4221 /* goto _forcond_n ; */
4223 /*-----------------------------------------------------------------*/
4225 createFor (symbol * trueLabel, symbol * continueLabel,
4226 symbol * falseLabel, symbol * condLabel,
4227 ast * initExpr, ast * condExpr, ast * loopExpr,
4232 /* if loopexpression not present then we can generate it */
4233 /* the same way as a while */
4235 return newNode (NULLOP, initExpr,
4236 createWhile (trueLabel, continueLabel,
4237 falseLabel, condExpr, forBody));
4238 /* vanilla for statement */
4239 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4241 if (condExpr && !IS_IFX (condExpr))
4242 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4245 /* attach condition label to condition */
4246 condExpr = createLabel (condLabel, condExpr);
4248 /* attach body label to body */
4249 forBody = createLabel (trueLabel, forBody);
4251 /* attach continue to forLoop expression & attach */
4252 /* goto the forcond @ and of loopExpression */
4253 loopExpr = createLabel (continueLabel,
4257 newAst_VALUE (symbolVal (condLabel)),
4259 /* now start putting them together */
4260 forTree = newNode (NULLOP, initExpr, condExpr);
4261 forTree = newNode (NULLOP, forTree, forBody);
4262 forTree = newNode (NULLOP, forTree, loopExpr);
4263 /* finally add the break label */
4264 forTree = newNode (NULLOP, forTree,
4265 createLabel (falseLabel, NULL));
4269 /*-----------------------------------------------------------------*/
4270 /* createWhile - creates parse tree for while statement */
4271 /* the while statement will be created as follows */
4273 /* _while_continue_n: */
4274 /* condition_expression +-> trueLabel -> _while_boby_n */
4276 /* +-> falseLabel -> _while_break_n */
4277 /* _while_body_n: */
4279 /* goto _while_continue_n */
4280 /* _while_break_n: */
4281 /*-----------------------------------------------------------------*/
4283 createWhile (symbol * trueLabel, symbol * continueLabel,
4284 symbol * falseLabel, ast * condExpr, ast * whileBody)
4288 /* put the continue label */
4289 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4290 condExpr = createLabel (continueLabel, condExpr);
4291 condExpr->lineno = 0;
4293 /* put the body label in front of the body */
4294 whileBody = createLabel (trueLabel, whileBody);
4295 whileBody->lineno = 0;
4296 /* put a jump to continue at the end of the body */
4297 /* and put break label at the end of the body */
4298 whileBody = newNode (NULLOP,
4301 newAst_VALUE (symbolVal (continueLabel)),
4302 createLabel (falseLabel, NULL)));
4304 /* put it all together */
4305 if (IS_IFX (condExpr))
4306 whileTree = condExpr;
4309 whileTree = newNode (IFX, condExpr, NULL);
4310 /* put the true & false labels in place */
4311 whileTree->trueLabel = trueLabel;
4312 whileTree->falseLabel = falseLabel;
4315 return newNode (NULLOP, whileTree, whileBody);
4318 /*-----------------------------------------------------------------*/
4319 /* optimizeGetHbit - get highest order bit of the expression */
4320 /*-----------------------------------------------------------------*/
4322 optimizeGetHbit (ast * tree)
4325 /* if this is not a bit and */
4326 if (!IS_BITAND (tree))
4329 /* will look for tree of the form
4330 ( expr >> ((sizeof expr) -1) ) & 1 */
4331 if (!IS_AST_LIT_VALUE (tree->right))
4334 if (AST_LIT_VALUE (tree->right) != 1)
4337 if (!IS_RIGHT_OP (tree->left))
4340 if (!IS_AST_LIT_VALUE (tree->left->right))
4343 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4344 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4347 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4351 /*-----------------------------------------------------------------*/
4352 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4353 /*-----------------------------------------------------------------*/
4355 optimizeRRCRLC (ast * root)
4357 /* will look for trees of the form
4358 (?expr << 1) | (?expr >> 7) or
4359 (?expr >> 7) | (?expr << 1) will make that
4360 into a RLC : operation ..
4362 (?expr >> 1) | (?expr << 7) or
4363 (?expr << 7) | (?expr >> 1) will make that
4364 into a RRC operation
4365 note : by 7 I mean (number of bits required to hold the
4367 /* if the root operations is not a | operation the not */
4368 if (!IS_BITOR (root))
4371 /* I have to think of a better way to match patterns this sucks */
4372 /* that aside let start looking for the first case : I use a the
4373 negative check a lot to improve the efficiency */
4374 /* (?expr << 1) | (?expr >> 7) */
4375 if (IS_LEFT_OP (root->left) &&
4376 IS_RIGHT_OP (root->right))
4379 if (!SPEC_USIGN (TETYPE (root->left->left)))
4382 if (!IS_AST_LIT_VALUE (root->left->right) ||
4383 !IS_AST_LIT_VALUE (root->right->right))
4386 /* make sure it is the same expression */
4387 if (!isAstEqual (root->left->left,
4391 if (AST_LIT_VALUE (root->left->right) != 1)
4394 if (AST_LIT_VALUE (root->right->right) !=
4395 (getSize (TTYPE (root->left->left)) * 8 - 1))
4398 /* whew got the first case : create the AST */
4399 return newNode (RLC, root->left->left, NULL);
4403 /* check for second case */
4404 /* (?expr >> 7) | (?expr << 1) */
4405 if (IS_LEFT_OP (root->right) &&
4406 IS_RIGHT_OP (root->left))
4409 if (!SPEC_USIGN (TETYPE (root->left->left)))
4412 if (!IS_AST_LIT_VALUE (root->left->right) ||
4413 !IS_AST_LIT_VALUE (root->right->right))
4416 /* make sure it is the same symbol */
4417 if (!isAstEqual (root->left->left,
4421 if (AST_LIT_VALUE (root->right->right) != 1)
4424 if (AST_LIT_VALUE (root->left->right) !=
4425 (getSize (TTYPE (root->left->left)) * 8 - 1))
4428 /* whew got the first case : create the AST */
4429 return newNode (RLC, root->left->left, NULL);
4434 /* third case for RRC */
4435 /* (?symbol >> 1) | (?symbol << 7) */
4436 if (IS_LEFT_OP (root->right) &&
4437 IS_RIGHT_OP (root->left))
4440 if (!SPEC_USIGN (TETYPE (root->left->left)))
4443 if (!IS_AST_LIT_VALUE (root->left->right) ||
4444 !IS_AST_LIT_VALUE (root->right->right))
4447 /* make sure it is the same symbol */
4448 if (!isAstEqual (root->left->left,
4452 if (AST_LIT_VALUE (root->left->right) != 1)
4455 if (AST_LIT_VALUE (root->right->right) !=
4456 (getSize (TTYPE (root->left->left)) * 8 - 1))
4459 /* whew got the first case : create the AST */
4460 return newNode (RRC, root->left->left, NULL);
4464 /* fourth and last case for now */
4465 /* (?symbol << 7) | (?symbol >> 1) */
4466 if (IS_RIGHT_OP (root->right) &&
4467 IS_LEFT_OP (root->left))
4470 if (!SPEC_USIGN (TETYPE (root->left->left)))
4473 if (!IS_AST_LIT_VALUE (root->left->right) ||
4474 !IS_AST_LIT_VALUE (root->right->right))
4477 /* make sure it is the same symbol */
4478 if (!isAstEqual (root->left->left,
4482 if (AST_LIT_VALUE (root->right->right) != 1)
4485 if (AST_LIT_VALUE (root->left->right) !=
4486 (getSize (TTYPE (root->left->left)) * 8 - 1))
4489 /* whew got the first case : create the AST */
4490 return newNode (RRC, root->left->left, NULL);
4494 /* not found return root */
4498 /*-----------------------------------------------------------------*/
4499 /* optimizeCompare - otimizes compares for bit variables */
4500 /*-----------------------------------------------------------------*/
4502 optimizeCompare (ast * root)
4504 ast *optExpr = NULL;
4507 unsigned int litValue;
4509 /* if nothing then return nothing */
4513 /* if not a compare op then do leaves */
4514 if (!IS_COMPARE_OP (root))
4516 root->left = optimizeCompare (root->left);
4517 root->right = optimizeCompare (root->right);
4521 /* if left & right are the same then depending
4522 of the operation do */
4523 if (isAstEqual (root->left, root->right))
4525 switch (root->opval.op)
4530 optExpr = newAst_VALUE (constVal ("0"));
4535 optExpr = newAst_VALUE (constVal ("1"));
4539 return decorateType (optExpr);
4542 vleft = (root->left->type == EX_VALUE ?
4543 root->left->opval.val : NULL);
4545 vright = (root->right->type == EX_VALUE ?
4546 root->right->opval.val : NULL);
4548 /* if left is a BITVAR in BITSPACE */
4549 /* and right is a LITERAL then opt- */
4550 /* imize else do nothing */
4551 if (vleft && vright &&
4552 IS_BITVAR (vleft->etype) &&
4553 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4554 IS_LITERAL (vright->etype))
4557 /* if right side > 1 then comparison may never succeed */
4558 if ((litValue = (int) floatFromVal (vright)) > 1)
4560 werror (W_BAD_COMPARE);
4566 switch (root->opval.op)
4568 case '>': /* bit value greater than 1 cannot be */
4569 werror (W_BAD_COMPARE);
4573 case '<': /* bit value < 1 means 0 */
4575 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4578 case LE_OP: /* bit value <= 1 means no check */
4579 optExpr = newAst_VALUE (vright);
4582 case GE_OP: /* bit value >= 1 means only check for = */
4584 optExpr = newAst_VALUE (vleft);
4589 { /* literal is zero */
4590 switch (root->opval.op)
4592 case '<': /* bit value < 0 cannot be */
4593 werror (W_BAD_COMPARE);
4597 case '>': /* bit value > 0 means 1 */
4599 optExpr = newAst_VALUE (vleft);
4602 case LE_OP: /* bit value <= 0 means no check */
4603 case GE_OP: /* bit value >= 0 means no check */
4604 werror (W_BAD_COMPARE);
4608 case EQ_OP: /* bit == 0 means ! of bit */
4609 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4613 return decorateType (resolveSymbols (optExpr));
4614 } /* end-of-if of BITVAR */
4619 /*-----------------------------------------------------------------*/
4620 /* addSymToBlock : adds the symbol to the first block we find */
4621 /*-----------------------------------------------------------------*/
4623 addSymToBlock (symbol * sym, ast * tree)
4625 /* reached end of tree or a leaf */
4626 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4630 if (IS_AST_OP (tree) &&
4631 tree->opval.op == BLOCK)
4634 symbol *lsym = copySymbol (sym);
4636 lsym->next = AST_VALUES (tree, sym);
4637 AST_VALUES (tree, sym) = lsym;
4641 addSymToBlock (sym, tree->left);
4642 addSymToBlock (sym, tree->right);
4645 /*-----------------------------------------------------------------*/
4646 /* processRegParms - do processing for register parameters */
4647 /*-----------------------------------------------------------------*/
4649 processRegParms (value * args, ast * body)
4653 if (IS_REGPARM (args->etype))
4654 addSymToBlock (args->sym, body);
4659 /*-----------------------------------------------------------------*/
4660 /* resetParmKey - resets the operandkeys for the symbols */
4661 /*-----------------------------------------------------------------*/
4662 DEFSETFUNC (resetParmKey)
4673 /*-----------------------------------------------------------------*/
4674 /* createFunction - This is the key node that calls the iCode for */
4675 /* generating the code for a function. Note code */
4676 /* is generated function by function, later when */
4677 /* add inter-procedural analysis this will change */
4678 /*-----------------------------------------------------------------*/
4680 createFunction (symbol * name, ast * body)
4686 iCode *piCode = NULL;
4688 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4689 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4691 /* if check function return 0 then some problem */
4692 if (checkFunction (name, NULL) == 0)
4695 /* create a dummy block if none exists */
4697 body = newNode (BLOCK, NULL, NULL);
4701 /* check if the function name already in the symbol table */
4702 if ((csym = findSym (SymbolTab, NULL, name->name)))
4705 /* special case for compiler defined functions
4706 we need to add the name to the publics list : this
4707 actually means we are now compiling the compiler
4711 addSet (&publics, name);
4717 allocVariables (name);
4719 name->lastLine = mylineno;
4722 /* set the stack pointer */
4723 /* PENDING: check this for the mcs51 */
4724 stackPtr = -port->stack.direction * port->stack.call_overhead;
4725 if (IFFUNC_ISISR (name->type))
4726 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4727 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4728 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4730 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4732 fetype = getSpec (name->type); /* get the specifier for the function */
4733 /* if this is a reentrant function then */
4734 if (IFFUNC_ISREENT (name->type))
4737 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4739 /* do processing for parameters that are passed in registers */
4740 processRegParms (FUNC_ARGS(name->type), body);
4742 /* set the stack pointer */
4746 /* allocate & autoinit the block variables */
4747 processBlockVars (body, &stack, ALLOCATE);
4749 /* save the stack information */
4750 if (options.useXstack)
4751 name->xstack = SPEC_STAK (fetype) = stack;
4753 name->stack = SPEC_STAK (fetype) = stack;
4755 /* name needs to be mangled */
4756 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4758 body = resolveSymbols (body); /* resolve the symbols */
4759 body = decorateType (body); /* propagateType & do semantic checks */
4761 ex = newAst_VALUE (symbolVal (name)); /* create name */
4762 ex = newNode (FUNCTION, ex, body);
4763 ex->values.args = FUNC_ARGS(name->type);
4765 if (options.dump_tree) PA(ex);
4768 werror (E_FUNC_NO_CODE, name->name);
4772 /* create the node & generate intermediate code */
4774 codeOutFile = code->oFile;
4775 piCode = iCodeFromAst (ex);
4779 werror (E_FUNC_NO_CODE, name->name);
4783 eBBlockFromiCode (piCode);
4785 /* if there are any statics then do them */
4788 GcurMemmap = statsg;
4789 codeOutFile = statsg->oFile;
4790 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4796 /* dealloc the block variables */
4797 processBlockVars (body, &stack, DEALLOCATE);
4798 outputDebugStackSymbols();
4799 /* deallocate paramaters */
4800 deallocParms (FUNC_ARGS(name->type));
4802 if (IFFUNC_ISREENT (name->type))
4805 /* we are done freeup memory & cleanup */
4807 if (port->reset_labelKey) labelKey = 1;
4809 FUNC_HASBODY(name->type) = 1;
4810 addSet (&operKeyReset, name);
4811 applyToSet (operKeyReset, resetParmKey);
4816 cleanUpLevel (LabelTab, 0);
4817 cleanUpBlock (StructTab, 1);
4818 cleanUpBlock (TypedefTab, 1);
4820 xstack->syms = NULL;
4821 istack->syms = NULL;
4826 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4827 /*-----------------------------------------------------------------*/
4828 /* ast_print : prints the ast (for debugging purposes) */
4829 /*-----------------------------------------------------------------*/
4831 void ast_print (ast * tree, FILE *outfile, int indent)
4836 /* can print only decorated trees */
4837 if (!tree->decorated) return;
4839 /* if any child is an error | this one is an error do nothing */
4840 if (tree->isError ||
4841 (tree->left && tree->left->isError) ||
4842 (tree->right && tree->right->isError)) {
4843 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4847 /* print the line */
4848 /* if not block & function */
4849 if (tree->type == EX_OP &&
4850 (tree->opval.op != FUNCTION &&
4851 tree->opval.op != BLOCK &&
4852 tree->opval.op != NULLOP)) {
4855 if (tree->opval.op == FUNCTION) {
4857 value *args=FUNC_ARGS(tree->left->opval.val->type);
4858 fprintf(outfile,"FUNCTION (%s=%p) type (",
4859 tree->left->opval.val->name, tree);
4860 printTypeChain (tree->left->opval.val->type->next,outfile);
4861 fprintf(outfile,") args (");
4864 fprintf (outfile, ", ");
4866 printTypeChain (args ? args->type : NULL, outfile);
4868 args= args ? args->next : NULL;
4870 fprintf(outfile,")\n");
4871 ast_print(tree->left,outfile,indent);
4872 ast_print(tree->right,outfile,indent);
4875 if (tree->opval.op == BLOCK) {
4876 symbol *decls = tree->values.sym;
4877 INDENT(indent,outfile);
4878 fprintf(outfile,"{\n");
4880 INDENT(indent+2,outfile);
4881 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4882 decls->name, decls);
4883 printTypeChain(decls->type,outfile);
4884 fprintf(outfile,")\n");
4886 decls = decls->next;
4888 ast_print(tree->right,outfile,indent+2);
4889 INDENT(indent,outfile);
4890 fprintf(outfile,"}\n");
4893 if (tree->opval.op == NULLOP) {
4894 ast_print(tree->left,outfile,indent);
4895 ast_print(tree->right,outfile,indent);
4898 INDENT(indent,outfile);
4900 /*------------------------------------------------------------------*/
4901 /*----------------------------*/
4902 /* leaf has been reached */
4903 /*----------------------------*/
4904 /* if this is of type value */
4905 /* just get the type */
4906 if (tree->type == EX_VALUE) {
4908 if (IS_LITERAL (tree->opval.val->etype)) {
4909 fprintf(outfile,"CONSTANT (%p) value = ", tree);
4910 if (SPEC_USIGN (tree->opval.val->etype))
4911 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
4913 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
4914 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
4915 floatFromVal(tree->opval.val));
4916 } else if (tree->opval.val->sym) {
4917 /* if the undefined flag is set then give error message */
4918 if (tree->opval.val->sym->undefined) {
4919 fprintf(outfile,"UNDEFINED SYMBOL ");
4921 fprintf(outfile,"SYMBOL ");
4923 fprintf(outfile,"(%s=%p)",
4924 tree->opval.val->sym->name,tree);
4927 fprintf(outfile," type (");
4928 printTypeChain(tree->ftype,outfile);
4929 fprintf(outfile,")\n");
4931 fprintf(outfile,"\n");
4936 /* if type link for the case of cast */
4937 if (tree->type == EX_LINK) {
4938 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4939 printTypeChain(tree->opval.lnk,outfile);
4940 fprintf(outfile,")\n");
4945 /* depending on type of operator do */
4947 switch (tree->opval.op) {
4948 /*------------------------------------------------------------------*/
4949 /*----------------------------*/
4951 /*----------------------------*/
4953 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4954 printTypeChain(tree->ftype,outfile);
4955 fprintf(outfile,")\n");
4956 ast_print(tree->left,outfile,indent+2);
4957 ast_print(tree->right,outfile,indent+2);
4960 /*------------------------------------------------------------------*/
4961 /*----------------------------*/
4963 /*----------------------------*/
4965 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4966 printTypeChain(tree->ftype,outfile);
4967 fprintf(outfile,")\n");
4968 ast_print(tree->left,outfile,indent+2);
4969 ast_print(tree->right,outfile,indent+2);
4972 /*------------------------------------------------------------------*/
4973 /*----------------------------*/
4974 /* struct/union pointer */
4975 /*----------------------------*/
4977 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4978 printTypeChain(tree->ftype,outfile);
4979 fprintf(outfile,")\n");
4980 ast_print(tree->left,outfile,indent+2);
4981 ast_print(tree->right,outfile,indent+2);
4984 /*------------------------------------------------------------------*/
4985 /*----------------------------*/
4986 /* ++/-- operation */
4987 /*----------------------------*/
4990 fprintf(outfile,"post-");
4992 fprintf(outfile,"pre-");
4993 fprintf(outfile,"INC_OP (%p) type (",tree);
4994 printTypeChain(tree->ftype,outfile);
4995 fprintf(outfile,")\n");
4996 ast_print(tree->left,outfile,indent+2); /* postincrement case */
4997 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5002 fprintf(outfile,"post-");
5004 fprintf(outfile,"pre-");
5005 fprintf(outfile,"DEC_OP (%p) type (",tree);
5006 printTypeChain(tree->ftype,outfile);
5007 fprintf(outfile,")\n");
5008 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5009 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5012 /*------------------------------------------------------------------*/
5013 /*----------------------------*/
5015 /*----------------------------*/
5018 fprintf(outfile,"& (%p) type (",tree);
5019 printTypeChain(tree->ftype,outfile);
5020 fprintf(outfile,")\n");
5021 ast_print(tree->left,outfile,indent+2);
5022 ast_print(tree->right,outfile,indent+2);
5024 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5025 printTypeChain(tree->ftype,outfile);
5026 fprintf(outfile,")\n");
5027 ast_print(tree->left,outfile,indent+2);
5028 ast_print(tree->right,outfile,indent+2);
5031 /*----------------------------*/
5033 /*----------------------------*/
5035 fprintf(outfile,"OR (%p) type (",tree);
5036 printTypeChain(tree->ftype,outfile);
5037 fprintf(outfile,")\n");
5038 ast_print(tree->left,outfile,indent+2);
5039 ast_print(tree->right,outfile,indent+2);
5041 /*------------------------------------------------------------------*/
5042 /*----------------------------*/
5044 /*----------------------------*/
5046 fprintf(outfile,"XOR (%p) type (",tree);
5047 printTypeChain(tree->ftype,outfile);
5048 fprintf(outfile,")\n");
5049 ast_print(tree->left,outfile,indent+2);
5050 ast_print(tree->right,outfile,indent+2);
5053 /*------------------------------------------------------------------*/
5054 /*----------------------------*/
5056 /*----------------------------*/
5058 fprintf(outfile,"DIV (%p) type (",tree);
5059 printTypeChain(tree->ftype,outfile);
5060 fprintf(outfile,")\n");
5061 ast_print(tree->left,outfile,indent+2);
5062 ast_print(tree->right,outfile,indent+2);
5064 /*------------------------------------------------------------------*/
5065 /*----------------------------*/
5067 /*----------------------------*/
5069 fprintf(outfile,"MOD (%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 /*------------------------------------------------------------------*/
5077 /*----------------------------*/
5078 /* address dereference */
5079 /*----------------------------*/
5080 case '*': /* can be unary : if right is null then unary operation */
5082 fprintf(outfile,"DEREF (%p) type (",tree);
5083 printTypeChain(tree->ftype,outfile);
5084 fprintf(outfile,")\n");
5085 ast_print(tree->left,outfile,indent+2);
5088 /*------------------------------------------------------------------*/
5089 /*----------------------------*/
5090 /* multiplication */
5091 /*----------------------------*/
5092 fprintf(outfile,"MULT (%p) type (",tree);
5093 printTypeChain(tree->ftype,outfile);
5094 fprintf(outfile,")\n");
5095 ast_print(tree->left,outfile,indent+2);
5096 ast_print(tree->right,outfile,indent+2);
5100 /*------------------------------------------------------------------*/
5101 /*----------------------------*/
5102 /* unary '+' operator */
5103 /*----------------------------*/
5107 fprintf(outfile,"UPLUS (%p) type (",tree);
5108 printTypeChain(tree->ftype,outfile);
5109 fprintf(outfile,")\n");
5110 ast_print(tree->left,outfile,indent+2);
5112 /*------------------------------------------------------------------*/
5113 /*----------------------------*/
5115 /*----------------------------*/
5116 fprintf(outfile,"ADD (%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);
5123 /*------------------------------------------------------------------*/
5124 /*----------------------------*/
5126 /*----------------------------*/
5127 case '-': /* can be unary */
5129 fprintf(outfile,"UMINUS (%p) type (",tree);
5130 printTypeChain(tree->ftype,outfile);
5131 fprintf(outfile,")\n");
5132 ast_print(tree->left,outfile,indent+2);
5134 /*------------------------------------------------------------------*/
5135 /*----------------------------*/
5137 /*----------------------------*/
5138 fprintf(outfile,"SUB (%p) type (",tree);
5139 printTypeChain(tree->ftype,outfile);
5140 fprintf(outfile,")\n");
5141 ast_print(tree->left,outfile,indent+2);
5142 ast_print(tree->right,outfile,indent+2);
5145 /*------------------------------------------------------------------*/
5146 /*----------------------------*/
5148 /*----------------------------*/
5150 fprintf(outfile,"COMPL (%p) type (",tree);
5151 printTypeChain(tree->ftype,outfile);
5152 fprintf(outfile,")\n");
5153 ast_print(tree->left,outfile,indent+2);
5155 /*------------------------------------------------------------------*/
5156 /*----------------------------*/
5158 /*----------------------------*/
5160 fprintf(outfile,"NOT (%p) type (",tree);
5161 printTypeChain(tree->ftype,outfile);
5162 fprintf(outfile,")\n");
5163 ast_print(tree->left,outfile,indent+2);
5165 /*------------------------------------------------------------------*/
5166 /*----------------------------*/
5168 /*----------------------------*/
5170 fprintf(outfile,"RRC (%p) type (",tree);
5171 printTypeChain(tree->ftype,outfile);
5172 fprintf(outfile,")\n");
5173 ast_print(tree->left,outfile,indent+2);
5177 fprintf(outfile,"RLC (%p) type (",tree);
5178 printTypeChain(tree->ftype,outfile);
5179 fprintf(outfile,")\n");
5180 ast_print(tree->left,outfile,indent+2);
5183 fprintf(outfile,"GETHBIT (%p) type (",tree);
5184 printTypeChain(tree->ftype,outfile);
5185 fprintf(outfile,")\n");
5186 ast_print(tree->left,outfile,indent+2);
5189 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5190 printTypeChain(tree->ftype,outfile);
5191 fprintf(outfile,")\n");
5192 ast_print(tree->left,outfile,indent+2);
5193 ast_print(tree->right,outfile,indent+2);
5196 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5197 printTypeChain(tree->ftype,outfile);
5198 fprintf(outfile,")\n");
5199 ast_print(tree->left,outfile,indent+2);
5200 ast_print(tree->right,outfile,indent+2);
5202 /*------------------------------------------------------------------*/
5203 /*----------------------------*/
5205 /*----------------------------*/
5206 case CAST: /* change the type */
5207 fprintf(outfile,"CAST (%p) from type (",tree);
5208 printTypeChain(tree->right->ftype,outfile);
5209 fprintf(outfile,") to type (");
5210 printTypeChain(tree->ftype,outfile);
5211 fprintf(outfile,")\n");
5212 ast_print(tree->right,outfile,indent+2);
5216 fprintf(outfile,"ANDAND (%p) type (",tree);
5217 printTypeChain(tree->ftype,outfile);
5218 fprintf(outfile,")\n");
5219 ast_print(tree->left,outfile,indent+2);
5220 ast_print(tree->right,outfile,indent+2);
5223 fprintf(outfile,"OROR (%p) type (",tree);
5224 printTypeChain(tree->ftype,outfile);
5225 fprintf(outfile,")\n");
5226 ast_print(tree->left,outfile,indent+2);
5227 ast_print(tree->right,outfile,indent+2);
5230 /*------------------------------------------------------------------*/
5231 /*----------------------------*/
5232 /* comparison operators */
5233 /*----------------------------*/
5235 fprintf(outfile,"GT(>) (%p) type (",tree);
5236 printTypeChain(tree->ftype,outfile);
5237 fprintf(outfile,")\n");
5238 ast_print(tree->left,outfile,indent+2);
5239 ast_print(tree->right,outfile,indent+2);
5242 fprintf(outfile,"LT(<) (%p) type (",tree);
5243 printTypeChain(tree->ftype,outfile);
5244 fprintf(outfile,")\n");
5245 ast_print(tree->left,outfile,indent+2);
5246 ast_print(tree->right,outfile,indent+2);
5249 fprintf(outfile,"LE(<=) (%p) type (",tree);
5250 printTypeChain(tree->ftype,outfile);
5251 fprintf(outfile,")\n");
5252 ast_print(tree->left,outfile,indent+2);
5253 ast_print(tree->right,outfile,indent+2);
5256 fprintf(outfile,"GE(>=) (%p) type (",tree);
5257 printTypeChain(tree->ftype,outfile);
5258 fprintf(outfile,")\n");
5259 ast_print(tree->left,outfile,indent+2);
5260 ast_print(tree->right,outfile,indent+2);
5263 fprintf(outfile,"EQ(==) (%p) type (",tree);
5264 printTypeChain(tree->ftype,outfile);
5265 fprintf(outfile,")\n");
5266 ast_print(tree->left,outfile,indent+2);
5267 ast_print(tree->right,outfile,indent+2);
5270 fprintf(outfile,"NE(!=) (%p) type (",tree);
5271 printTypeChain(tree->ftype,outfile);
5272 fprintf(outfile,")\n");
5273 ast_print(tree->left,outfile,indent+2);
5274 ast_print(tree->right,outfile,indent+2);
5275 /*------------------------------------------------------------------*/
5276 /*----------------------------*/
5278 /*----------------------------*/
5279 case SIZEOF: /* evaluate wihout code generation */
5280 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5283 /*------------------------------------------------------------------*/
5284 /*----------------------------*/
5285 /* conditional operator '?' */
5286 /*----------------------------*/
5288 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5289 printTypeChain(tree->ftype,outfile);
5290 fprintf(outfile,")\n");
5291 ast_print(tree->left,outfile,indent+2);
5292 ast_print(tree->right,outfile,indent+2);
5296 fprintf(outfile,"COLON(:) (%p) type (",tree);
5297 printTypeChain(tree->ftype,outfile);
5298 fprintf(outfile,")\n");
5299 ast_print(tree->left,outfile,indent+2);
5300 ast_print(tree->right,outfile,indent+2);
5303 /*------------------------------------------------------------------*/
5304 /*----------------------------*/
5305 /* assignment operators */
5306 /*----------------------------*/
5308 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5309 printTypeChain(tree->ftype,outfile);
5310 fprintf(outfile,")\n");
5311 ast_print(tree->left,outfile,indent+2);
5312 ast_print(tree->right,outfile,indent+2);
5315 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5316 printTypeChain(tree->ftype,outfile);
5317 fprintf(outfile,")\n");
5318 ast_print(tree->left,outfile,indent+2);
5319 ast_print(tree->right,outfile,indent+2);
5322 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5323 printTypeChain(tree->ftype,outfile);
5324 fprintf(outfile,")\n");
5325 ast_print(tree->left,outfile,indent+2);
5326 ast_print(tree->right,outfile,indent+2);
5329 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5330 printTypeChain(tree->ftype,outfile);
5331 fprintf(outfile,")\n");
5332 ast_print(tree->left,outfile,indent+2);
5333 ast_print(tree->right,outfile,indent+2);
5336 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5337 printTypeChain(tree->ftype,outfile);
5338 fprintf(outfile,")\n");
5339 ast_print(tree->left,outfile,indent+2);
5340 ast_print(tree->right,outfile,indent+2);
5343 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5344 printTypeChain(tree->ftype,outfile);
5345 fprintf(outfile,")\n");
5346 ast_print(tree->left,outfile,indent+2);
5347 ast_print(tree->right,outfile,indent+2);
5350 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5351 printTypeChain(tree->ftype,outfile);
5352 fprintf(outfile,")\n");
5353 ast_print(tree->left,outfile,indent+2);
5354 ast_print(tree->right,outfile,indent+2);
5356 /*------------------------------------------------------------------*/
5357 /*----------------------------*/
5359 /*----------------------------*/
5361 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5362 printTypeChain(tree->ftype,outfile);
5363 fprintf(outfile,")\n");
5364 ast_print(tree->left,outfile,indent+2);
5365 ast_print(tree->right,outfile,indent+2);
5367 /*------------------------------------------------------------------*/
5368 /*----------------------------*/
5370 /*----------------------------*/
5372 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5373 printTypeChain(tree->ftype,outfile);
5374 fprintf(outfile,")\n");
5375 ast_print(tree->left,outfile,indent+2);
5376 ast_print(tree->right,outfile,indent+2);
5378 /*------------------------------------------------------------------*/
5379 /*----------------------------*/
5380 /* straight assignemnt */
5381 /*----------------------------*/
5383 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5384 printTypeChain(tree->ftype,outfile);
5385 fprintf(outfile,")\n");
5386 ast_print(tree->left,outfile,indent+2);
5387 ast_print(tree->right,outfile,indent+2);
5389 /*------------------------------------------------------------------*/
5390 /*----------------------------*/
5391 /* comma operator */
5392 /*----------------------------*/
5394 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5395 printTypeChain(tree->ftype,outfile);
5396 fprintf(outfile,")\n");
5397 ast_print(tree->left,outfile,indent+2);
5398 ast_print(tree->right,outfile,indent+2);
5400 /*------------------------------------------------------------------*/
5401 /*----------------------------*/
5403 /*----------------------------*/
5406 fprintf(outfile,"CALL (%p) type (",tree);
5407 printTypeChain(tree->ftype,outfile);
5408 fprintf(outfile,")\n");
5409 ast_print(tree->left,outfile,indent+2);
5410 ast_print(tree->right,outfile,indent+2);
5413 fprintf(outfile,"PARMS\n");
5414 ast_print(tree->left,outfile,indent+2);
5415 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5416 ast_print(tree->right,outfile,indent+2);
5419 /*------------------------------------------------------------------*/
5420 /*----------------------------*/
5421 /* return statement */
5422 /*----------------------------*/
5424 fprintf(outfile,"RETURN (%p) type (",tree);
5426 printTypeChain(tree->right->ftype,outfile);
5428 fprintf(outfile,")\n");
5429 ast_print(tree->right,outfile,indent+2);
5431 /*------------------------------------------------------------------*/
5432 /*----------------------------*/
5433 /* label statement */
5434 /*----------------------------*/
5436 fprintf(outfile,"LABEL (%p)\n",tree);
5437 ast_print(tree->left,outfile,indent+2);
5438 ast_print(tree->right,outfile,indent);
5440 /*------------------------------------------------------------------*/
5441 /*----------------------------*/
5442 /* switch statement */
5443 /*----------------------------*/
5447 fprintf(outfile,"SWITCH (%p) ",tree);
5448 ast_print(tree->left,outfile,0);
5449 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5450 INDENT(indent+2,outfile);
5451 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5452 (int) floatFromVal(val),
5453 tree->values.switchVals.swNum,
5454 (int) floatFromVal(val));
5456 ast_print(tree->right,outfile,indent);
5459 /*------------------------------------------------------------------*/
5460 /*----------------------------*/
5462 /*----------------------------*/
5464 fprintf(outfile,"IF (%p) \n",tree);
5465 ast_print(tree->left,outfile,indent+2);
5466 if (tree->trueLabel) {
5467 INDENT(indent+2,outfile);
5468 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5470 if (tree->falseLabel) {
5471 INDENT(indent+2,outfile);
5472 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5474 ast_print(tree->right,outfile,indent+2);
5476 /*----------------------------*/
5477 /* goto Statement */
5478 /*----------------------------*/
5480 fprintf(outfile,"GOTO (%p) \n",tree);
5481 ast_print(tree->left,outfile,indent+2);
5482 fprintf(outfile,"\n");
5484 /*------------------------------------------------------------------*/
5485 /*----------------------------*/
5487 /*----------------------------*/
5489 fprintf(outfile,"FOR (%p) \n",tree);
5490 if (AST_FOR( tree, initExpr)) {
5491 INDENT(indent+2,outfile);
5492 fprintf(outfile,"INIT EXPR ");
5493 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5495 if (AST_FOR( tree, condExpr)) {
5496 INDENT(indent+2,outfile);
5497 fprintf(outfile,"COND EXPR ");
5498 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5500 if (AST_FOR( tree, loopExpr)) {
5501 INDENT(indent+2,outfile);
5502 fprintf(outfile,"LOOP EXPR ");
5503 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5505 fprintf(outfile,"FOR LOOP BODY \n");
5506 ast_print(tree->left,outfile,indent+2);
5515 ast_print(t,stdout,0);