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 if (IS_AST_SYM_VALUE (pbody->left) &&
1687 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1690 if (IS_AST_SYM_VALUE (pbody->right) &&
1691 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1694 return isConformingBody (pbody->left, sym, body) &&
1695 isConformingBody (pbody->right, sym, body);
1697 /*------------------------------------------------------------------*/
1700 /* if left has a pointer & right has loop
1701 control variable then we cannot */
1702 if (astHasPointer (pbody->left) &&
1703 astHasSymbol (pbody->right, sym))
1705 if (astHasVolatile (pbody->left))
1708 if (IS_AST_SYM_VALUE (pbody->left)) {
1709 // if the loopvar has an assignment
1710 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1712 // if the loopvar is used in another (maybe conditional) block
1713 if (astHasSymbol (pbody->right, sym) &&
1714 (pbody->level >= body->level)) {
1719 if (astHasVolatile (pbody->left))
1722 if (astHasDeref(pbody->right)) return FALSE;
1724 return isConformingBody (pbody->left, sym, body) &&
1725 isConformingBody (pbody->right, sym, body);
1736 assert ("Parser should not have generated this\n");
1738 /*------------------------------------------------------------------*/
1739 /*----------------------------*/
1740 /* comma operator */
1741 /*----------------------------*/
1743 return isConformingBody (pbody->left, sym, body) &&
1744 isConformingBody (pbody->right, sym, body);
1746 /*------------------------------------------------------------------*/
1747 /*----------------------------*/
1749 /*----------------------------*/
1751 /* if local & not passed as paramater then ok */
1752 if (sym->level && !astHasSymbol(pbody->right,sym))
1756 /*------------------------------------------------------------------*/
1757 /*----------------------------*/
1758 /* return statement */
1759 /*----------------------------*/
1764 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1769 if (astHasSymbol (pbody->left, sym))
1776 return isConformingBody (pbody->left, sym, body) &&
1777 isConformingBody (pbody->right, sym, body);
1783 /*-----------------------------------------------------------------*/
1784 /* isLoopReversible - takes a for loop as input && returns true */
1785 /* if the for loop is reversible. If yes will set the value of */
1786 /* the loop control var & init value & termination value */
1787 /*-----------------------------------------------------------------*/
1789 isLoopReversible (ast * loop, symbol ** loopCntrl,
1790 ast ** init, ast ** end)
1792 /* if option says don't do it then don't */
1793 if (optimize.noLoopReverse)
1795 /* there are several tests to determine this */
1797 /* for loop has to be of the form
1798 for ( <sym> = <const1> ;
1799 [<sym> < <const2>] ;
1800 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1802 if (!isLoopCountable (AST_FOR (loop, initExpr),
1803 AST_FOR (loop, condExpr),
1804 AST_FOR (loop, loopExpr),
1805 loopCntrl, init, end))
1808 /* now do some serious checking on the body of the loop
1811 return isConformingBody (loop->left, *loopCntrl, loop->left);
1815 /*-----------------------------------------------------------------*/
1816 /* replLoopSym - replace the loop sym by loop sym -1 */
1817 /*-----------------------------------------------------------------*/
1819 replLoopSym (ast * body, symbol * sym)
1822 if (!body || IS_AST_LINK (body))
1825 if (IS_AST_SYM_VALUE (body))
1828 if (isSymbolEqual (AST_SYMBOL (body), sym))
1832 body->opval.op = '-';
1833 body->left = newAst_VALUE (symbolVal (sym));
1834 body->right = newAst_VALUE (constVal ("1"));
1842 replLoopSym (body->left, sym);
1843 replLoopSym (body->right, sym);
1847 /*-----------------------------------------------------------------*/
1848 /* reverseLoop - do the actual loop reversal */
1849 /*-----------------------------------------------------------------*/
1851 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1855 /* create the following tree
1860 if (sym) goto for_continue ;
1863 /* put it together piece by piece */
1864 rloop = newNode (NULLOP,
1865 createIf (newAst_VALUE (symbolVal (sym)),
1867 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1870 newAst_VALUE (symbolVal (sym)),
1873 replLoopSym (loop->left, sym);
1874 setAstLineno (rloop, init->lineno);
1876 rloop = newNode (NULLOP,
1878 newAst_VALUE (symbolVal (sym)),
1879 newNode ('-', end, init)),
1880 createLabel (AST_FOR (loop, continueLabel),
1884 newNode (SUB_ASSIGN,
1885 newAst_VALUE (symbolVal (sym)),
1886 newAst_VALUE (constVal ("1"))),
1889 rloop->lineno=init->lineno;
1890 return decorateType (rloop);
1894 /*-----------------------------------------------------------------*/
1895 /* searchLitOp - search tree (*ops only) for an ast with literal */
1896 /*-----------------------------------------------------------------*/
1898 searchLitOp (ast *tree, ast **parent, const char *ops)
1902 if (tree && optimize.global_cse)
1904 /* is there a literal operand? */
1906 IS_AST_OP(tree->right) &&
1907 tree->right->right &&
1908 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1910 if (IS_LITERAL (RTYPE (tree->right)) ^
1911 IS_LITERAL (LTYPE (tree->right)))
1913 tree->right->decorated = 0;
1914 tree->decorated = 0;
1918 ret = searchLitOp (tree->right, parent, ops);
1923 IS_AST_OP(tree->left) &&
1924 tree->left->right &&
1925 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1927 if (IS_LITERAL (RTYPE (tree->left)) ^
1928 IS_LITERAL (LTYPE (tree->left)))
1930 tree->left->decorated = 0;
1931 tree->decorated = 0;
1935 ret = searchLitOp (tree->left, parent, ops);
1943 /*-----------------------------------------------------------------*/
1944 /* decorateType - compute type for this tree also does type checking */
1945 /* this is done bottom up, since type have to flow upwards */
1946 /* it also does constant folding, and paramater checking */
1947 /*-----------------------------------------------------------------*/
1949 decorateType (ast * tree)
1957 /* if already has type then do nothing */
1958 if (tree->decorated)
1961 tree->decorated = 1;
1964 /* print the line */
1965 /* if not block & function */
1966 if (tree->type == EX_OP &&
1967 (tree->opval.op != FUNCTION &&
1968 tree->opval.op != BLOCK &&
1969 tree->opval.op != NULLOP))
1971 filename = tree->filename;
1972 lineno = tree->lineno;
1976 /* if any child is an error | this one is an error do nothing */
1977 if (tree->isError ||
1978 (tree->left && tree->left->isError) ||
1979 (tree->right && tree->right->isError))
1982 /*------------------------------------------------------------------*/
1983 /*----------------------------*/
1984 /* leaf has been reached */
1985 /*----------------------------*/
1986 lineno=tree->lineno;
1987 /* if this is of type value */
1988 /* just get the type */
1989 if (tree->type == EX_VALUE)
1992 if (IS_LITERAL (tree->opval.val->etype))
1995 /* if this is a character array then declare it */
1996 if (IS_ARRAY (tree->opval.val->type))
1997 tree->opval.val = stringToSymbol (tree->opval.val);
1999 /* otherwise just copy the type information */
2000 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2004 if (tree->opval.val->sym)
2006 /* if the undefined flag is set then give error message */
2007 if (tree->opval.val->sym->undefined)
2009 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2011 TTYPE (tree) = TETYPE (tree) =
2012 tree->opval.val->type = tree->opval.val->sym->type =
2013 tree->opval.val->etype = tree->opval.val->sym->etype =
2014 copyLinkChain (INTTYPE);
2019 /* if impilicit i.e. struct/union member then no type */
2020 if (tree->opval.val->sym->implicit)
2021 TTYPE (tree) = TETYPE (tree) = NULL;
2026 /* else copy the type */
2027 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2029 /* and mark it as referenced */
2030 tree->opval.val->sym->isref = 1;
2038 /* if type link for the case of cast */
2039 if (tree->type == EX_LINK)
2041 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2048 dtl = decorateType (tree->left);
2049 /* delay right side for '?' operator since conditional macro expansions might
2051 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2053 /* this is to take care of situations
2054 when the tree gets rewritten */
2055 if (dtl != tree->left)
2057 if (dtr != tree->right)
2059 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2062 if (IS_AST_OP(tree) &&
2063 (tree->opval.op == CAST || tree->opval.op == '=') &&
2064 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2065 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2066 // this is a cast/assign to a bigger type
2067 if (IS_AST_OP(tree->right) &&
2068 IS_INTEGRAL(tree->right->ftype) &&
2069 (tree->right->opval.op == LEFT_OP ||
2070 tree->right->opval.op == '*' ||
2071 tree->right->opval.op == '+' ||
2072 tree->right->opval.op == '-') &&
2073 tree->right->right) {
2074 // we should cast an operand instead of the result
2075 tree->right->decorated = 0;
2076 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2078 tree->right = decorateType(tree->right);
2083 /* depending on type of operator do */
2085 switch (tree->opval.op)
2087 /*------------------------------------------------------------------*/
2088 /*----------------------------*/
2090 /*----------------------------*/
2093 /* determine which is the array & which the index */
2094 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2097 ast *tempTree = tree->left;
2098 tree->left = tree->right;
2099 tree->right = tempTree;
2102 /* first check if this is a array or a pointer */
2103 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2105 werror (E_NEED_ARRAY_PTR, "[]");
2106 goto errorTreeReturn;
2109 /* check if the type of the idx */
2110 if (!IS_INTEGRAL (RTYPE (tree)))
2112 werror (E_IDX_NOT_INT);
2113 goto errorTreeReturn;
2116 /* if the left is an rvalue then error */
2119 werror (E_LVALUE_REQUIRED, "array access");
2120 goto errorTreeReturn;
2123 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2126 /*------------------------------------------------------------------*/
2127 /*----------------------------*/
2129 /*----------------------------*/
2131 /* if this is not a structure */
2132 if (!IS_STRUCT (LTYPE (tree)))
2134 werror (E_STRUCT_UNION, ".");
2135 goto errorTreeReturn;
2137 TTYPE (tree) = structElemType (LTYPE (tree),
2138 (tree->right->type == EX_VALUE ?
2139 tree->right->opval.val : NULL));
2140 TETYPE (tree) = getSpec (TTYPE (tree));
2143 /*------------------------------------------------------------------*/
2144 /*----------------------------*/
2145 /* struct/union pointer */
2146 /*----------------------------*/
2148 /* if not pointer to a structure */
2149 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2151 werror (E_PTR_REQD);
2152 goto errorTreeReturn;
2155 if (!IS_STRUCT (LTYPE (tree)->next))
2157 werror (E_STRUCT_UNION, "->");
2158 goto errorTreeReturn;
2161 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2162 (tree->right->type == EX_VALUE ?
2163 tree->right->opval.val : NULL));
2164 TETYPE (tree) = getSpec (TTYPE (tree));
2166 /* adjust the storage class */
2167 switch (DCL_TYPE(tree->left->ftype)) {
2171 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2174 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2179 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2182 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2185 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2193 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2194 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2196 /* If defined struct type at addr var
2197 then rewrite (&struct var)->member
2199 and define membertype at (addr+offsetof(struct var,member)) temp
2202 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2203 AST_SYMBOL(tree->right));
2205 sym = newSymbol(genSymName (0), 0);
2206 sym->type = TTYPE (tree);
2207 sym->etype = getSpec(sym->type);
2208 sym->lineDef = tree->lineno;
2211 SPEC_STAT (sym->etype) = 1;
2212 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2214 SPEC_ABSA(sym->etype) = 1;
2215 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2218 AST_VALUE (tree) = symbolVal(sym);
2221 tree->type = EX_VALUE;
2228 /*------------------------------------------------------------------*/
2229 /*----------------------------*/
2230 /* ++/-- operation */
2231 /*----------------------------*/
2235 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2236 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2237 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2238 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2247 /*------------------------------------------------------------------*/
2248 /*----------------------------*/
2250 /*----------------------------*/
2251 case '&': /* can be unary */
2252 /* if right is NULL then unary operation */
2253 if (tree->right) /* not an unary operation */
2256 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2258 werror (E_BITWISE_OP);
2259 werror (W_CONTINUE, "left & right types are ");
2260 printTypeChain (LTYPE (tree), stderr);
2261 fprintf (stderr, ",");
2262 printTypeChain (RTYPE (tree), stderr);
2263 fprintf (stderr, "\n");
2264 goto errorTreeReturn;
2267 /* if they are both literal */
2268 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2270 tree->type = EX_VALUE;
2271 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2272 valFromType (RETYPE (tree)), '&');
2274 tree->right = tree->left = NULL;
2275 TETYPE (tree) = tree->opval.val->etype;
2276 TTYPE (tree) = tree->opval.val->type;
2280 /* see if this is a GETHBIT operation if yes
2283 ast *otree = optimizeGetHbit (tree);
2286 return decorateType (otree);
2290 computeType (LTYPE (tree), RTYPE (tree));
2291 TETYPE (tree) = getSpec (TTYPE (tree));
2293 /* if left is a literal exchange left & right */
2294 if (IS_LITERAL (LTYPE (tree)))
2296 ast *tTree = tree->left;
2297 tree->left = tree->right;
2298 tree->right = tTree;
2301 /* if right is a literal and */
2302 /* we can find a 2nd literal in a and-tree then */
2303 /* rearrange the tree */
2304 if (IS_LITERAL (RTYPE (tree)))
2307 ast *litTree = searchLitOp (tree, &parent, "&");
2310 ast *tTree = litTree->left;
2311 litTree->left = tree->right;
2312 tree->right = tTree;
2313 /* both operands in tTree are literal now */
2314 decorateType (parent);
2318 LRVAL (tree) = RRVAL (tree) = 1;
2322 /*------------------------------------------------------------------*/
2323 /*----------------------------*/
2325 /*----------------------------*/
2326 p = newLink (DECLARATOR);
2327 /* if bit field then error */
2328 if (IS_BITVAR (tree->left->etype))
2330 werror (E_ILLEGAL_ADDR, "address of bit variable");
2331 goto errorTreeReturn;
2334 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2336 werror (E_ILLEGAL_ADDR, "address of register variable");
2337 goto errorTreeReturn;
2340 if (IS_FUNC (LTYPE (tree)))
2342 // this ought to be ignored
2343 return (tree->left);
2346 if (IS_LITERAL(LTYPE(tree)))
2348 werror (E_ILLEGAL_ADDR, "address of literal");
2349 goto errorTreeReturn;
2354 werror (E_LVALUE_REQUIRED, "address of");
2355 goto errorTreeReturn;
2357 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2358 DCL_TYPE (p) = CPOINTER;
2359 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2360 DCL_TYPE (p) = FPOINTER;
2361 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2362 DCL_TYPE (p) = PPOINTER;
2363 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2364 DCL_TYPE (p) = IPOINTER;
2365 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2366 DCL_TYPE (p) = EEPPOINTER;
2367 else if (SPEC_OCLS(tree->left->etype))
2368 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2370 DCL_TYPE (p) = POINTER;
2372 if (IS_AST_SYM_VALUE (tree->left))
2374 AST_SYMBOL (tree->left)->addrtaken = 1;
2375 AST_SYMBOL (tree->left)->allocreq = 1;
2378 p->next = LTYPE (tree);
2380 TETYPE (tree) = getSpec (TTYPE (tree));
2385 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2386 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2388 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2389 AST_SYMBOL(tree->left->right));
2390 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2391 valueFromLit(element->offset));
2394 tree->type = EX_VALUE;
2395 tree->values.literalFromCast = 1;
2401 /*------------------------------------------------------------------*/
2402 /*----------------------------*/
2404 /*----------------------------*/
2406 /* if the rewrite succeeds then don't go any furthur */
2408 ast *wtree = optimizeRRCRLC (tree);
2410 return decorateType (wtree);
2414 /* if left is a literal exchange left & right */
2415 if (IS_LITERAL (LTYPE (tree)))
2417 ast *tTree = tree->left;
2418 tree->left = tree->right;
2419 tree->right = tTree;
2422 /* if right is a literal and */
2423 /* we can find a 2nd literal in a or-tree then */
2424 /* rearrange the tree */
2425 if (IS_LITERAL (RTYPE (tree)))
2428 ast *litTree = searchLitOp (tree, &parent, "|");
2431 ast *tTree = litTree->left;
2432 litTree->left = tree->right;
2433 tree->right = tTree;
2434 /* both operands in tTree are literal now */
2435 decorateType (parent);
2438 /*------------------------------------------------------------------*/
2439 /*----------------------------*/
2441 /*----------------------------*/
2443 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2445 werror (E_BITWISE_OP);
2446 werror (W_CONTINUE, "left & right types are ");
2447 printTypeChain (LTYPE (tree), stderr);
2448 fprintf (stderr, ",");
2449 printTypeChain (RTYPE (tree), stderr);
2450 fprintf (stderr, "\n");
2451 goto errorTreeReturn;
2454 /* if they are both literal then */
2455 /* rewrite the tree */
2456 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2458 tree->type = EX_VALUE;
2459 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2460 valFromType (RETYPE (tree)),
2462 tree->right = tree->left = NULL;
2463 TETYPE (tree) = tree->opval.val->etype;
2464 TTYPE (tree) = tree->opval.val->type;
2468 /* if left is a literal exchange left & right */
2469 if (IS_LITERAL (LTYPE (tree)))
2471 ast *tTree = tree->left;
2472 tree->left = tree->right;
2473 tree->right = tTree;
2476 /* if right is a literal and */
2477 /* we can find a 2nd literal in a xor-tree then */
2478 /* rearrange the tree */
2479 if (IS_LITERAL (RTYPE (tree)))
2482 ast *litTree = searchLitOp (tree, &parent, "^");
2485 ast *tTree = litTree->left;
2486 litTree->left = tree->right;
2487 tree->right = tTree;
2488 /* both operands in litTree are literal now */
2489 decorateType (parent);
2493 LRVAL (tree) = RRVAL (tree) = 1;
2494 TETYPE (tree) = getSpec (TTYPE (tree) =
2495 computeType (LTYPE (tree),
2498 /*------------------------------------------------------------------*/
2499 /*----------------------------*/
2501 /*----------------------------*/
2503 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2505 werror (E_INVALID_OP, "divide");
2506 goto errorTreeReturn;
2508 /* if they are both literal then */
2509 /* rewrite the tree */
2510 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2512 tree->type = EX_VALUE;
2513 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2514 valFromType (RETYPE (tree)));
2515 tree->right = tree->left = NULL;
2516 TETYPE (tree) = getSpec (TTYPE (tree) =
2517 tree->opval.val->type);
2521 LRVAL (tree) = RRVAL (tree) = 1;
2522 TETYPE (tree) = getSpec (TTYPE (tree) =
2523 computeType (LTYPE (tree),
2526 /* if right is a literal and */
2527 /* left is also a division by a literal then */
2528 /* rearrange the tree */
2529 if (IS_LITERAL (RTYPE (tree))
2530 /* avoid infinite loop */
2531 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2534 ast *litTree = searchLitOp (tree, &parent, "/");
2537 if (IS_LITERAL (RTYPE (litTree)))
2540 litTree->right = newNode ('*', litTree->right, tree->right);
2541 litTree->right->lineno = tree->lineno;
2543 tree->right->opval.val = constVal ("1");
2544 decorateType (parent);
2548 /* litTree->left is literal: no gcse possible.
2549 We can't call decorateType(parent), because
2550 this would cause an infinit loop. */
2551 parent->decorated = 1;
2552 decorateType (litTree);
2559 /*------------------------------------------------------------------*/
2560 /*----------------------------*/
2562 /*----------------------------*/
2564 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2566 werror (E_BITWISE_OP);
2567 werror (W_CONTINUE, "left & right types are ");
2568 printTypeChain (LTYPE (tree), stderr);
2569 fprintf (stderr, ",");
2570 printTypeChain (RTYPE (tree), stderr);
2571 fprintf (stderr, "\n");
2572 goto errorTreeReturn;
2574 /* if they are both literal then */
2575 /* rewrite the tree */
2576 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2578 tree->type = EX_VALUE;
2579 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2580 valFromType (RETYPE (tree)));
2581 tree->right = tree->left = NULL;
2582 TETYPE (tree) = getSpec (TTYPE (tree) =
2583 tree->opval.val->type);
2586 LRVAL (tree) = RRVAL (tree) = 1;
2587 TETYPE (tree) = getSpec (TTYPE (tree) =
2588 computeType (LTYPE (tree),
2592 /*------------------------------------------------------------------*/
2593 /*----------------------------*/
2594 /* address dereference */
2595 /*----------------------------*/
2596 case '*': /* can be unary : if right is null then unary operation */
2599 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2601 werror (E_PTR_REQD);
2602 goto errorTreeReturn;
2607 werror (E_LVALUE_REQUIRED, "pointer deref");
2608 goto errorTreeReturn;
2610 if (IS_ADDRESS_OF_OP(tree->left))
2612 /* replace *&obj with obj */
2613 return tree->left->left;
2615 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2616 TETYPE (tree) = getSpec (TTYPE (tree));
2620 /*------------------------------------------------------------------*/
2621 /*----------------------------*/
2622 /* multiplication */
2623 /*----------------------------*/
2624 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2626 werror (E_INVALID_OP, "multiplication");
2627 goto errorTreeReturn;
2630 /* if they are both literal then */
2631 /* rewrite the tree */
2632 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2634 tree->type = EX_VALUE;
2635 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2636 valFromType (RETYPE (tree)));
2637 tree->right = tree->left = NULL;
2638 TETYPE (tree) = getSpec (TTYPE (tree) =
2639 tree->opval.val->type);
2643 /* if left is a literal exchange left & right */
2644 if (IS_LITERAL (LTYPE (tree)))
2646 ast *tTree = tree->left;
2647 tree->left = tree->right;
2648 tree->right = tTree;
2651 /* if right is a literal and */
2652 /* we can find a 2nd literal in a mul-tree then */
2653 /* rearrange the tree */
2654 if (IS_LITERAL (RTYPE (tree)))
2657 ast *litTree = searchLitOp (tree, &parent, "*");
2660 ast *tTree = litTree->left;
2661 litTree->left = tree->right;
2662 tree->right = tTree;
2663 /* both operands in litTree are literal now */
2664 decorateType (parent);
2668 LRVAL (tree) = RRVAL (tree) = 1;
2669 TETYPE (tree) = getSpec (TTYPE (tree) =
2670 computeType (LTYPE (tree),
2673 /* promote result to int if left & right are char
2674 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2675 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2676 SPEC_NOUN(TETYPE(tree)) = V_INT;
2681 /*------------------------------------------------------------------*/
2682 /*----------------------------*/
2683 /* unary '+' operator */
2684 /*----------------------------*/
2689 if (!IS_INTEGRAL (LTYPE (tree)))
2691 werror (E_UNARY_OP, '+');
2692 goto errorTreeReturn;
2695 /* if left is a literal then do it */
2696 if (IS_LITERAL (LTYPE (tree)))
2698 tree->type = EX_VALUE;
2699 tree->opval.val = valFromType (LETYPE (tree));
2701 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2705 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2709 /*------------------------------------------------------------------*/
2710 /*----------------------------*/
2712 /*----------------------------*/
2714 /* this is not a unary operation */
2715 /* if both pointers then problem */
2716 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2717 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2719 werror (E_PTR_PLUS_PTR);
2720 goto errorTreeReturn;
2723 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2724 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2726 werror (E_PLUS_INVALID, "+");
2727 goto errorTreeReturn;
2730 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2731 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2733 werror (E_PLUS_INVALID, "+");
2734 goto errorTreeReturn;
2736 /* if they are both literal then */
2737 /* rewrite the tree */
2738 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2740 tree->type = EX_VALUE;
2741 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2742 valFromType (RETYPE (tree)));
2743 tree->right = tree->left = NULL;
2744 TETYPE (tree) = getSpec (TTYPE (tree) =
2745 tree->opval.val->type);
2749 /* if the right is a pointer or left is a literal
2750 xchange left & right */
2751 if (IS_ARRAY (RTYPE (tree)) ||
2752 IS_PTR (RTYPE (tree)) ||
2753 IS_LITERAL (LTYPE (tree)))
2755 ast *tTree = tree->left;
2756 tree->left = tree->right;
2757 tree->right = tTree;
2760 /* if right is a literal and */
2761 /* left is also an addition/subtraction with a literal then */
2762 /* rearrange the tree */
2763 if (IS_LITERAL (RTYPE (tree)))
2765 ast *litTree, *parent;
2766 litTree = searchLitOp (tree, &parent, "+-");
2769 if (litTree->opval.op == '+')
2772 ast *tTree = litTree->left;
2773 litTree->left = tree->right;
2774 tree->right = tree->left;
2777 else if (litTree->opval.op == '-')
2779 if (IS_LITERAL (RTYPE (litTree)))
2782 ast *tTree = litTree->left;
2783 litTree->left = tree->right;
2784 tree->right = tTree;
2789 ast *tTree = litTree->right;
2790 litTree->right = tree->right;
2791 tree->right = tTree;
2792 litTree->opval.op = '+';
2793 tree->opval.op = '-';
2796 decorateType (parent);
2800 LRVAL (tree) = RRVAL (tree) = 1;
2801 /* if the left is a pointer */
2802 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2803 TETYPE (tree) = getSpec (TTYPE (tree) =
2806 TETYPE (tree) = getSpec (TTYPE (tree) =
2807 computeType (LTYPE (tree),
2811 /*------------------------------------------------------------------*/
2812 /*----------------------------*/
2814 /*----------------------------*/
2815 case '-': /* can be unary */
2816 /* if right is null then unary */
2820 if (!IS_ARITHMETIC (LTYPE (tree)))
2822 werror (E_UNARY_OP, tree->opval.op);
2823 goto errorTreeReturn;
2826 /* if left is a literal then do it */
2827 if (IS_LITERAL (LTYPE (tree)))
2829 tree->type = EX_VALUE;
2830 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2832 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2833 SPEC_USIGN(TETYPE(tree)) = 0;
2837 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2841 /*------------------------------------------------------------------*/
2842 /*----------------------------*/
2844 /*----------------------------*/
2846 if (!(IS_PTR (LTYPE (tree)) ||
2847 IS_ARRAY (LTYPE (tree)) ||
2848 IS_ARITHMETIC (LTYPE (tree))))
2850 werror (E_PLUS_INVALID, "-");
2851 goto errorTreeReturn;
2854 if (!(IS_PTR (RTYPE (tree)) ||
2855 IS_ARRAY (RTYPE (tree)) ||
2856 IS_ARITHMETIC (RTYPE (tree))))
2858 werror (E_PLUS_INVALID, "-");
2859 goto errorTreeReturn;
2862 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2863 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2864 IS_INTEGRAL (RTYPE (tree))))
2866 werror (E_PLUS_INVALID, "-");
2867 goto errorTreeReturn;
2870 /* if they are both literal then */
2871 /* rewrite the tree */
2872 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2874 tree->type = EX_VALUE;
2875 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2876 valFromType (RETYPE (tree)));
2877 tree->right = tree->left = NULL;
2878 TETYPE (tree) = getSpec (TTYPE (tree) =
2879 tree->opval.val->type);
2883 /* if the left & right are equal then zero */
2884 if (isAstEqual (tree->left, tree->right))
2886 tree->type = EX_VALUE;
2887 tree->left = tree->right = NULL;
2888 tree->opval.val = constVal ("0");
2889 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2893 /* if both of them are pointers or arrays then */
2894 /* the result is going to be an integer */
2895 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2896 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2897 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2899 /* if only the left is a pointer */
2900 /* then result is a pointer */
2901 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2902 TETYPE (tree) = getSpec (TTYPE (tree) =
2905 TETYPE (tree) = getSpec (TTYPE (tree) =
2906 computeType (LTYPE (tree),
2909 LRVAL (tree) = RRVAL (tree) = 1;
2911 /* if right is a literal and */
2912 /* left is also an addition/subtraction with a literal then */
2913 /* rearrange the tree */
2914 if (IS_LITERAL (RTYPE (tree))
2915 /* avoid infinite loop */
2916 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
2918 ast *litTree, *litParent;
2919 litTree = searchLitOp (tree, &litParent, "+-");
2922 if (litTree->opval.op == '+')
2925 litTree->right = newNode ('-', litTree->right, tree->right);
2926 litTree->right->lineno = tree->lineno;
2928 tree->right->opval.val = constVal ("0");
2930 else if (litTree->opval.op == '-')
2932 if (IS_LITERAL (RTYPE (litTree)))
2935 litTree->right = newNode ('+', tree->right, litTree->right);
2936 litTree->right->lineno = tree->lineno;
2938 tree->right->opval.val = constVal ("0");
2943 ast *tTree = litTree->right;
2944 litTree->right = tree->right;
2945 tree->right = tTree;
2948 decorateType (litParent);
2953 /*------------------------------------------------------------------*/
2954 /*----------------------------*/
2956 /*----------------------------*/
2958 /* can be only integral type */
2959 if (!IS_INTEGRAL (LTYPE (tree)))
2961 werror (E_UNARY_OP, tree->opval.op);
2962 goto errorTreeReturn;
2965 /* if left is a literal then do it */
2966 if (IS_LITERAL (LTYPE (tree)))
2968 tree->type = EX_VALUE;
2969 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2971 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2975 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2978 /*------------------------------------------------------------------*/
2979 /*----------------------------*/
2981 /*----------------------------*/
2983 /* can be pointer */
2984 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2985 !IS_PTR (LTYPE (tree)) &&
2986 !IS_ARRAY (LTYPE (tree)))
2988 werror (E_UNARY_OP, tree->opval.op);
2989 goto errorTreeReturn;
2992 /* if left is a literal then do it */
2993 if (IS_LITERAL (LTYPE (tree)))
2995 tree->type = EX_VALUE;
2996 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2998 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3002 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3005 /*------------------------------------------------------------------*/
3006 /*----------------------------*/
3008 /*----------------------------*/
3011 TTYPE (tree) = LTYPE (tree);
3012 TETYPE (tree) = LETYPE (tree);
3016 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3021 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3023 werror (E_SHIFT_OP_INVALID);
3024 werror (W_CONTINUE, "left & right types are ");
3025 printTypeChain (LTYPE (tree), stderr);
3026 fprintf (stderr, ",");
3027 printTypeChain (RTYPE (tree), stderr);
3028 fprintf (stderr, "\n");
3029 goto errorTreeReturn;
3032 /* if they are both literal then */
3033 /* rewrite the tree */
3034 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3036 tree->type = EX_VALUE;
3037 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3038 valFromType (RETYPE (tree)),
3039 (tree->opval.op == LEFT_OP ? 1 : 0));
3040 tree->right = tree->left = NULL;
3041 TETYPE (tree) = getSpec (TTYPE (tree) =
3042 tree->opval.val->type);
3046 /* if only the right side is a literal & we are
3047 shifting more than size of the left operand then zero */
3048 if (IS_LITERAL (RTYPE (tree)) &&
3049 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3050 (getSize (LTYPE (tree)) * 8))
3052 if (tree->opval.op==LEFT_OP ||
3053 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3054 lineno=tree->lineno;
3055 werror (W_SHIFT_CHANGED,
3056 (tree->opval.op == LEFT_OP ? "left" : "right"));
3057 tree->type = EX_VALUE;
3058 tree->left = tree->right = NULL;
3059 tree->opval.val = constVal ("0");
3060 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3064 LRVAL (tree) = RRVAL (tree) = 1;
3065 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3066 if (IS_LITERAL (TTYPE (tree)))
3067 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3070 /*------------------------------------------------------------------*/
3071 /*----------------------------*/
3073 /*----------------------------*/
3074 case CAST: /* change the type */
3075 /* cannot cast to an aggregate type */
3076 if (IS_AGGREGATE (LTYPE (tree)))
3078 werror (E_CAST_ILLEGAL);
3079 goto errorTreeReturn;
3082 /* make sure the type is complete and sane */
3083 checkTypeSanity(LETYPE(tree), "(cast)");
3086 /* if the right is a literal replace the tree */
3087 if (IS_LITERAL (RETYPE (tree))) {
3088 if (!IS_PTR (LTYPE (tree))) {
3089 tree->type = EX_VALUE;
3091 valCastLiteral (LTYPE (tree),
3092 floatFromVal (valFromType (RETYPE (tree))));
3095 TTYPE (tree) = tree->opval.val->type;
3096 tree->values.literalFromCast = 1;
3097 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3098 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3099 sym_link *rest = LTYPE(tree)->next;
3100 werror(W_LITERAL_GENERIC);
3101 TTYPE(tree) = newLink(DECLARATOR);
3102 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3103 TTYPE(tree)->next = rest;
3104 tree->left->opval.lnk = TTYPE(tree);
3107 TTYPE (tree) = LTYPE (tree);
3111 TTYPE (tree) = LTYPE (tree);
3115 #if 0 // this is already checked, now this could be explicit
3116 /* if pointer to struct then check names */
3117 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3118 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3119 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3121 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3122 SPEC_STRUCT(LETYPE(tree))->tag);
3125 if (IS_ADDRESS_OF_OP(tree->right)
3126 && IS_AST_SYM_VALUE (tree->right->left)
3127 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3129 tree->type = EX_VALUE;
3131 valCastLiteral (LTYPE (tree),
3132 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3133 TTYPE (tree) = tree->opval.val->type;
3134 TETYPE (tree) = getSpec (TTYPE (tree));
3137 tree->values.literalFromCast = 1;
3141 /* handle offsetof macro: */
3142 /* #define offsetof(TYPE, MEMBER) \ */
3143 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3144 if (IS_ADDRESS_OF_OP(tree->right)
3145 && IS_AST_OP (tree->right->left)
3146 && tree->right->left->opval.op == PTR_OP
3147 && IS_AST_OP (tree->right->left->left)
3148 && tree->right->left->left->opval.op == CAST
3149 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3151 symbol *element = getStructElement (
3152 SPEC_STRUCT (LETYPE(tree->right->left)),
3153 AST_SYMBOL(tree->right->left->right)
3157 tree->type = EX_VALUE;
3158 tree->opval.val = valCastLiteral (
3161 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3164 TTYPE (tree) = tree->opval.val->type;
3165 TETYPE (tree) = getSpec (TTYPE (tree));
3172 /* if the right is a literal replace the tree */
3173 if (IS_LITERAL (RETYPE (tree))) {
3174 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3175 /* rewrite (type *)litaddr
3177 and define type at litaddr temp
3178 (but only if type's storage class is not generic)
3180 ast *newTree = newNode ('&', NULL, NULL);
3183 TTYPE (newTree) = LTYPE (tree);
3184 TETYPE (newTree) = getSpec(LTYPE (tree));
3186 /* define a global symbol at the casted address*/
3187 sym = newSymbol(genSymName (0), 0);
3188 sym->type = LTYPE (tree)->next;
3190 sym->type = newLink (V_VOID);
3191 sym->etype = getSpec(sym->type);
3192 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3193 sym->lineDef = tree->lineno;
3196 SPEC_STAT (sym->etype) = 1;
3197 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3198 SPEC_ABSA(sym->etype) = 1;
3199 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3202 newTree->left = newAst_VALUE(symbolVal(sym));
3203 newTree->left->lineno = tree->lineno;
3204 LTYPE (newTree) = sym->type;
3205 LETYPE (newTree) = sym->etype;
3206 LLVAL (newTree) = 1;
3207 LRVAL (newTree) = 0;
3208 TLVAL (newTree) = 1;
3211 if (!IS_PTR (LTYPE (tree))) {
3212 tree->type = EX_VALUE;
3214 valCastLiteral (LTYPE (tree),
3215 floatFromVal (valFromType (RETYPE (tree))));
3216 TTYPE (tree) = tree->opval.val->type;
3219 tree->values.literalFromCast = 1;
3220 TETYPE (tree) = getSpec (TTYPE (tree));
3224 TTYPE (tree) = LTYPE (tree);
3228 TETYPE (tree) = getSpec (TTYPE (tree));
3232 /*------------------------------------------------------------------*/
3233 /*----------------------------*/
3234 /* logical &&, || */
3235 /*----------------------------*/
3238 /* each must me arithmetic type or be a pointer */
3239 if (!IS_PTR (LTYPE (tree)) &&
3240 !IS_ARRAY (LTYPE (tree)) &&
3241 !IS_INTEGRAL (LTYPE (tree)))
3243 werror (E_COMPARE_OP);
3244 goto errorTreeReturn;
3247 if (!IS_PTR (RTYPE (tree)) &&
3248 !IS_ARRAY (RTYPE (tree)) &&
3249 !IS_INTEGRAL (RTYPE (tree)))
3251 werror (E_COMPARE_OP);
3252 goto errorTreeReturn;
3254 /* if they are both literal then */
3255 /* rewrite the tree */
3256 if (IS_LITERAL (RTYPE (tree)) &&
3257 IS_LITERAL (LTYPE (tree)))
3259 tree->type = EX_VALUE;
3260 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3261 valFromType (RETYPE (tree)),
3263 tree->right = tree->left = NULL;
3264 TETYPE (tree) = getSpec (TTYPE (tree) =
3265 tree->opval.val->type);
3268 LRVAL (tree) = RRVAL (tree) = 1;
3269 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3272 /*------------------------------------------------------------------*/
3273 /*----------------------------*/
3274 /* comparison operators */
3275 /*----------------------------*/
3283 ast *lt = optimizeCompare (tree);
3289 /* if they are pointers they must be castable */
3290 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3292 if (tree->opval.op==EQ_OP &&
3293 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3294 // we cannot cast a gptr to a !gptr: switch the leaves
3295 struct ast *s=tree->left;
3296 tree->left=tree->right;
3299 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3301 werror (E_COMPARE_OP);
3302 fprintf (stderr, "comparring type ");
3303 printTypeChain (LTYPE (tree), stderr);
3304 fprintf (stderr, "to type ");
3305 printTypeChain (RTYPE (tree), stderr);
3306 fprintf (stderr, "\n");
3307 goto errorTreeReturn;
3310 /* else they should be promotable to one another */
3313 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3314 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3316 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3318 werror (E_COMPARE_OP);
3319 fprintf (stderr, "comparing type ");
3320 printTypeChain (LTYPE (tree), stderr);
3321 fprintf (stderr, "to type ");
3322 printTypeChain (RTYPE (tree), stderr);
3323 fprintf (stderr, "\n");
3324 goto errorTreeReturn;
3327 /* if unsigned value < 0 then always false */
3328 /* if (unsigned value) > 0 then (unsigned value) */
3329 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3330 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3332 if (tree->opval.op == '<') {
3335 if (tree->opval.op == '>') {
3339 /* if they are both literal then */
3340 /* rewrite the tree */
3341 if (IS_LITERAL (RTYPE (tree)) &&
3342 IS_LITERAL (LTYPE (tree)))
3344 tree->type = EX_VALUE;
3345 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3346 valFromType (RETYPE (tree)),
3348 tree->right = tree->left = NULL;
3349 TETYPE (tree) = getSpec (TTYPE (tree) =
3350 tree->opval.val->type);
3353 LRVAL (tree) = RRVAL (tree) = 1;
3354 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3357 /*------------------------------------------------------------------*/
3358 /*----------------------------*/
3360 /*----------------------------*/
3361 case SIZEOF: /* evaluate wihout code generation */
3362 /* change the type to a integer */
3363 tree->type = EX_VALUE;
3364 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3365 tree->opval.val = constVal (buffer);
3366 tree->right = tree->left = NULL;
3367 TETYPE (tree) = getSpec (TTYPE (tree) =
3368 tree->opval.val->type);
3371 /*------------------------------------------------------------------*/
3372 /*----------------------------*/
3374 /*----------------------------*/
3376 /* return typeof enum value */
3377 tree->type = EX_VALUE;
3380 if (IS_SPEC(tree->right->ftype)) {
3381 switch (SPEC_NOUN(tree->right->ftype)) {
3383 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3384 else typeofv = TYPEOF_INT;
3387 typeofv = TYPEOF_FLOAT;
3390 typeofv = TYPEOF_CHAR;
3393 typeofv = TYPEOF_VOID;
3396 typeofv = TYPEOF_STRUCT;
3399 typeofv = TYPEOF_BITFIELD;
3402 typeofv = TYPEOF_BIT;
3405 typeofv = TYPEOF_SBIT;
3411 switch (DCL_TYPE(tree->right->ftype)) {
3413 typeofv = TYPEOF_POINTER;
3416 typeofv = TYPEOF_FPOINTER;
3419 typeofv = TYPEOF_CPOINTER;
3422 typeofv = TYPEOF_GPOINTER;
3425 typeofv = TYPEOF_PPOINTER;
3428 typeofv = TYPEOF_IPOINTER;
3431 typeofv = TYPEOF_ARRAY;
3434 typeofv = TYPEOF_FUNCTION;
3440 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3441 tree->opval.val = constVal (buffer);
3442 tree->right = tree->left = NULL;
3443 TETYPE (tree) = getSpec (TTYPE (tree) =
3444 tree->opval.val->type);
3447 /*------------------------------------------------------------------*/
3448 /*----------------------------*/
3449 /* conditional operator '?' */
3450 /*----------------------------*/
3452 /* the type is value of the colon operator (on the right) */
3453 assert(IS_COLON_OP(tree->right));
3454 /* if already known then replace the tree : optimizer will do it
3455 but faster to do it here */
3456 if (IS_LITERAL (LTYPE(tree))) {
3457 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3458 return decorateType(tree->right->left) ;
3460 return decorateType(tree->right->right) ;
3463 tree->right = decorateType(tree->right);
3464 TTYPE (tree) = RTYPE(tree);
3465 TETYPE (tree) = getSpec (TTYPE (tree));
3470 /* if they don't match we have a problem */
3471 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3473 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3474 goto errorTreeReturn;
3477 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3478 TETYPE (tree) = getSpec (TTYPE (tree));
3482 #if 0 // assignment operators are converted by the parser
3483 /*------------------------------------------------------------------*/
3484 /*----------------------------*/
3485 /* assignment operators */
3486 /*----------------------------*/
3489 /* for these it must be both must be integral */
3490 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3491 !IS_ARITHMETIC (RTYPE (tree)))
3493 werror (E_OPS_INTEGRAL);
3494 goto errorTreeReturn;
3497 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3499 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3500 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3504 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3505 goto errorTreeReturn;
3516 /* for these it must be both must be integral */
3517 if (!IS_INTEGRAL (LTYPE (tree)) ||
3518 !IS_INTEGRAL (RTYPE (tree)))
3520 werror (E_OPS_INTEGRAL);
3521 goto errorTreeReturn;
3524 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3526 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3527 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3531 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3532 goto errorTreeReturn;
3538 /*------------------------------------------------------------------*/
3539 /*----------------------------*/
3541 /*----------------------------*/
3543 if (!(IS_PTR (LTYPE (tree)) ||
3544 IS_ARITHMETIC (LTYPE (tree))))
3546 werror (E_PLUS_INVALID, "-=");
3547 goto errorTreeReturn;
3550 if (!(IS_PTR (RTYPE (tree)) ||
3551 IS_ARITHMETIC (RTYPE (tree))))
3553 werror (E_PLUS_INVALID, "-=");
3554 goto errorTreeReturn;
3557 TETYPE (tree) = getSpec (TTYPE (tree) =
3558 computeType (LTYPE (tree),
3561 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3562 werror (E_CODE_WRITE, "-=");
3566 werror (E_LVALUE_REQUIRED, "-=");
3567 goto errorTreeReturn;
3573 /*------------------------------------------------------------------*/
3574 /*----------------------------*/
3576 /*----------------------------*/
3578 /* this is not a unary operation */
3579 /* if both pointers then problem */
3580 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3582 werror (E_PTR_PLUS_PTR);
3583 goto errorTreeReturn;
3586 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3588 werror (E_PLUS_INVALID, "+=");
3589 goto errorTreeReturn;
3592 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3594 werror (E_PLUS_INVALID, "+=");
3595 goto errorTreeReturn;
3598 TETYPE (tree) = getSpec (TTYPE (tree) =
3599 computeType (LTYPE (tree),
3602 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3603 werror (E_CODE_WRITE, "+=");
3607 werror (E_LVALUE_REQUIRED, "+=");
3608 goto errorTreeReturn;
3611 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3612 tree->opval.op = '=';
3617 /*------------------------------------------------------------------*/
3618 /*----------------------------*/
3619 /* straight assignemnt */
3620 /*----------------------------*/
3622 /* cannot be an aggregate */
3623 if (IS_AGGREGATE (LTYPE (tree)))
3625 werror (E_AGGR_ASSIGN);
3626 goto errorTreeReturn;
3629 /* they should either match or be castable */
3630 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3632 werror (E_TYPE_MISMATCH, "assignment", " ");
3633 printFromToType(RTYPE(tree),LTYPE(tree));
3636 /* if the left side of the tree is of type void
3637 then report error */
3638 if (IS_VOID (LTYPE (tree)))
3640 werror (E_CAST_ZERO);
3641 printFromToType(RTYPE(tree), LTYPE(tree));
3644 TETYPE (tree) = getSpec (TTYPE (tree) =
3648 if (!tree->initMode ) {
3649 if (IS_CONSTANT(LTYPE(tree)))
3650 werror (E_CODE_WRITE, "=");
3654 werror (E_LVALUE_REQUIRED, "=");
3655 goto errorTreeReturn;
3660 /*------------------------------------------------------------------*/
3661 /*----------------------------*/
3662 /* comma operator */
3663 /*----------------------------*/
3665 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3668 /*------------------------------------------------------------------*/
3669 /*----------------------------*/
3671 /*----------------------------*/
3675 if (processParms (tree->left,
3676 FUNC_ARGS(tree->left->ftype),
3677 tree->right, &parmNumber, TRUE)) {
3678 goto errorTreeReturn;
3681 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3682 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3684 reverseParms (tree->right);
3687 if (IS_CODEPTR(LTYPE(tree))) {
3688 TTYPE(tree) = LTYPE(tree)->next->next;
3690 TTYPE(tree) = LTYPE(tree)->next;
3692 TETYPE (tree) = getSpec (TTYPE (tree));
3695 /*------------------------------------------------------------------*/
3696 /*----------------------------*/
3697 /* return statement */
3698 /*----------------------------*/
3703 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3705 werror (W_RETURN_MISMATCH);
3706 printFromToType (RTYPE(tree), currFunc->type->next);
3707 goto errorTreeReturn;
3710 if (IS_VOID (currFunc->type->next)
3712 !IS_VOID (RTYPE (tree)))
3714 werror (E_FUNC_VOID);
3715 goto errorTreeReturn;
3718 /* if there is going to be a casing required then add it */
3719 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3722 decorateType (newNode (CAST,
3723 newAst_LINK (copyLinkChain (currFunc->type->next)),
3732 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3734 werror (W_VOID_FUNC, currFunc->name);
3735 goto errorTreeReturn;
3738 TTYPE (tree) = TETYPE (tree) = NULL;
3741 /*------------------------------------------------------------------*/
3742 /*----------------------------*/
3743 /* switch statement */
3744 /*----------------------------*/
3746 /* the switch value must be an integer */
3747 if (!IS_INTEGRAL (LTYPE (tree)))
3749 werror (E_SWITCH_NON_INTEGER);
3750 goto errorTreeReturn;
3753 TTYPE (tree) = TETYPE (tree) = NULL;
3756 /*------------------------------------------------------------------*/
3757 /*----------------------------*/
3759 /*----------------------------*/
3761 tree->left = backPatchLabels (tree->left,
3764 TTYPE (tree) = TETYPE (tree) = NULL;
3767 /*------------------------------------------------------------------*/
3768 /*----------------------------*/
3770 /*----------------------------*/
3773 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3774 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3775 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3777 /* if the for loop is reversible then
3778 reverse it otherwise do what we normally
3784 if (isLoopReversible (tree, &sym, &init, &end))
3785 return reverseLoop (tree, sym, init, end);
3787 return decorateType (createFor (AST_FOR (tree, trueLabel),
3788 AST_FOR (tree, continueLabel),
3789 AST_FOR (tree, falseLabel),
3790 AST_FOR (tree, condLabel),
3791 AST_FOR (tree, initExpr),
3792 AST_FOR (tree, condExpr),
3793 AST_FOR (tree, loopExpr),
3797 TTYPE (tree) = TETYPE (tree) = NULL;
3801 /* some error found this tree will be killed */
3803 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3804 tree->opval.op = NULLOP;
3810 /*-----------------------------------------------------------------*/
3811 /* sizeofOp - processes size of operation */
3812 /*-----------------------------------------------------------------*/
3814 sizeofOp (sym_link * type)
3818 /* make sure the type is complete and sane */
3819 checkTypeSanity(type, "(sizeof)");
3821 /* get the size and convert it to character */
3822 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3824 /* now convert into value */
3825 return constVal (buff);
3829 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3830 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3831 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3832 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3833 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3834 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3835 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3837 /*-----------------------------------------------------------------*/
3838 /* backPatchLabels - change and or not operators to flow control */
3839 /*-----------------------------------------------------------------*/
3841 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3847 if (!(IS_ANDORNOT (tree)))
3850 /* if this an and */
3853 static int localLbl = 0;
3856 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3857 localLabel = newSymbol (buffer, NestLevel);
3859 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3861 /* if left is already a IFX then just change the if true label in that */
3862 if (!IS_IFX (tree->left))
3863 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3865 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3866 /* right is a IFX then just join */
3867 if (IS_IFX (tree->right))
3868 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3870 tree->right = createLabel (localLabel, tree->right);
3871 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3873 return newNode (NULLOP, tree->left, tree->right);
3876 /* if this is an or operation */
3879 static int localLbl = 0;
3882 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3883 localLabel = newSymbol (buffer, NestLevel);
3885 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3887 /* if left is already a IFX then just change the if true label in that */
3888 if (!IS_IFX (tree->left))
3889 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3891 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3892 /* right is a IFX then just join */
3893 if (IS_IFX (tree->right))
3894 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3896 tree->right = createLabel (localLabel, tree->right);
3897 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3899 return newNode (NULLOP, tree->left, tree->right);
3905 int wasnot = IS_NOT (tree->left);
3906 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3908 /* if the left is already a IFX */
3909 if (!IS_IFX (tree->left))
3910 tree->left = newNode (IFX, tree->left, NULL);
3914 tree->left->trueLabel = trueLabel;
3915 tree->left->falseLabel = falseLabel;
3919 tree->left->trueLabel = falseLabel;
3920 tree->left->falseLabel = trueLabel;
3927 tree->trueLabel = trueLabel;
3928 tree->falseLabel = falseLabel;
3935 /*-----------------------------------------------------------------*/
3936 /* createBlock - create expression tree for block */
3937 /*-----------------------------------------------------------------*/
3939 createBlock (symbol * decl, ast * body)
3943 /* if the block has nothing */
3947 ex = newNode (BLOCK, NULL, body);
3948 ex->values.sym = decl;
3950 ex->right = ex->right;
3956 /*-----------------------------------------------------------------*/
3957 /* createLabel - creates the expression tree for labels */
3958 /*-----------------------------------------------------------------*/
3960 createLabel (symbol * label, ast * stmnt)
3963 char name[SDCC_NAME_MAX + 1];
3966 /* must create fresh symbol if the symbol name */
3967 /* exists in the symbol table, since there can */
3968 /* be a variable with the same name as the labl */
3969 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3970 (csym->level == label->level))
3971 label = newSymbol (label->name, label->level);
3973 /* change the name before putting it in add _ */
3974 SNPRINTF(name, sizeof(name), "%s", label->name);
3976 /* put the label in the LabelSymbol table */
3977 /* but first check if a label of the same */
3979 if ((csym = findSym (LabelTab, NULL, name)))
3980 werror (E_DUPLICATE_LABEL, label->name);
3982 addSym (LabelTab, label, name, label->level, 0, 0);
3985 label->key = labelKey++;
3986 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3992 /*-----------------------------------------------------------------*/
3993 /* createCase - generates the parsetree for a case statement */
3994 /*-----------------------------------------------------------------*/
3996 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3998 char caseLbl[SDCC_NAME_MAX + 1];
4002 /* if the switch statement does not exist */
4003 /* then case is out of context */
4006 werror (E_CASE_CONTEXT);
4010 caseVal = decorateType (resolveSymbols (caseVal));
4011 /* if not a constant then error */
4012 if (!IS_LITERAL (caseVal->ftype))
4014 werror (E_CASE_CONSTANT);
4018 /* if not a integer than error */
4019 if (!IS_INTEGRAL (caseVal->ftype))
4021 werror (E_CASE_NON_INTEGER);
4025 /* find the end of the switch values chain */
4026 if (!(val = swStat->values.switchVals.swVals))
4027 swStat->values.switchVals.swVals = caseVal->opval.val;
4030 /* also order the cases according to value */
4032 int cVal = (int) floatFromVal (caseVal->opval.val);
4033 while (val && (int) floatFromVal (val) < cVal)
4039 /* if we reached the end then */
4042 pval->next = caseVal->opval.val;
4046 /* we found a value greater than */
4047 /* the current value we must add this */
4048 /* before the value */
4049 caseVal->opval.val->next = val;
4051 /* if this was the first in chain */
4052 if (swStat->values.switchVals.swVals == val)
4053 swStat->values.switchVals.swVals =
4056 pval->next = caseVal->opval.val;
4061 /* create the case label */
4062 SNPRINTF(caseLbl, sizeof(caseLbl),
4064 swStat->values.switchVals.swNum,
4065 (int) floatFromVal (caseVal->opval.val));
4067 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4072 /*-----------------------------------------------------------------*/
4073 /* createDefault - creates the parse tree for the default statement */
4074 /*-----------------------------------------------------------------*/
4076 createDefault (ast * swStat, ast * stmnt)
4078 char defLbl[SDCC_NAME_MAX + 1];
4080 /* if the switch statement does not exist */
4081 /* then case is out of context */
4084 werror (E_CASE_CONTEXT);
4088 /* turn on the default flag */
4089 swStat->values.switchVals.swDefault = 1;
4091 /* create the label */
4092 SNPRINTF (defLbl, sizeof(defLbl),
4093 "_default_%d", swStat->values.switchVals.swNum);
4094 return createLabel (newSymbol (defLbl, 0), stmnt);
4097 /*-----------------------------------------------------------------*/
4098 /* createIf - creates the parsetree for the if statement */
4099 /*-----------------------------------------------------------------*/
4101 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4103 static int Lblnum = 0;
4105 symbol *ifTrue, *ifFalse, *ifEnd;
4107 /* if neither exists */
4108 if (!elseBody && !ifBody) {
4109 // if there are no side effects (i++, j() etc)
4110 if (!hasSEFcalls(condAst)) {
4115 /* create the labels */
4116 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4117 ifFalse = newSymbol (buffer, NestLevel);
4118 /* if no else body then end == false */
4123 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4124 ifEnd = newSymbol (buffer, NestLevel);
4127 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4128 ifTrue = newSymbol (buffer, NestLevel);
4132 /* attach the ifTrue label to the top of it body */
4133 ifBody = createLabel (ifTrue, ifBody);
4134 /* attach a goto end to the ifBody if else is present */
4137 ifBody = newNode (NULLOP, ifBody,
4139 newAst_VALUE (symbolVal (ifEnd)),
4141 /* put the elseLabel on the else body */
4142 elseBody = createLabel (ifFalse, elseBody);
4143 /* out the end at the end of the body */
4144 elseBody = newNode (NULLOP,
4146 createLabel (ifEnd, NULL));
4150 ifBody = newNode (NULLOP, ifBody,
4151 createLabel (ifFalse, NULL));
4153 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4154 if (IS_IFX (condAst))
4157 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4159 return newNode (NULLOP, ifTree,
4160 newNode (NULLOP, ifBody, elseBody));
4164 /*-----------------------------------------------------------------*/
4165 /* createDo - creates parse tree for do */
4168 /* _docontinue_n: */
4169 /* condition_expression +-> trueLabel -> _dobody_n */
4171 /* +-> falseLabel-> _dobreak_n */
4173 /*-----------------------------------------------------------------*/
4175 createDo (symbol * trueLabel, symbol * continueLabel,
4176 symbol * falseLabel, ast * condAst, ast * doBody)
4181 /* if the body does not exist then it is simple */
4184 condAst = backPatchLabels (condAst, continueLabel, NULL);
4185 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4186 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4187 doTree->trueLabel = continueLabel;
4188 doTree->falseLabel = NULL;
4192 /* otherwise we have a body */
4193 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4195 /* attach the body label to the top */
4196 doBody = createLabel (trueLabel, doBody);
4197 /* attach the continue label to end of body */
4198 doBody = newNode (NULLOP, doBody,
4199 createLabel (continueLabel, NULL));
4201 /* now put the break label at the end */
4202 if (IS_IFX (condAst))
4205 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4207 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4209 /* putting it together */
4210 return newNode (NULLOP, doBody, doTree);
4213 /*-----------------------------------------------------------------*/
4214 /* createFor - creates parse tree for 'for' statement */
4217 /* condExpr +-> trueLabel -> _forbody_n */
4219 /* +-> falseLabel-> _forbreak_n */
4222 /* _forcontinue_n: */
4224 /* goto _forcond_n ; */
4226 /*-----------------------------------------------------------------*/
4228 createFor (symbol * trueLabel, symbol * continueLabel,
4229 symbol * falseLabel, symbol * condLabel,
4230 ast * initExpr, ast * condExpr, ast * loopExpr,
4235 /* if loopexpression not present then we can generate it */
4236 /* the same way as a while */
4238 return newNode (NULLOP, initExpr,
4239 createWhile (trueLabel, continueLabel,
4240 falseLabel, condExpr, forBody));
4241 /* vanilla for statement */
4242 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4244 if (condExpr && !IS_IFX (condExpr))
4245 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4248 /* attach condition label to condition */
4249 condExpr = createLabel (condLabel, condExpr);
4251 /* attach body label to body */
4252 forBody = createLabel (trueLabel, forBody);
4254 /* attach continue to forLoop expression & attach */
4255 /* goto the forcond @ and of loopExpression */
4256 loopExpr = createLabel (continueLabel,
4260 newAst_VALUE (symbolVal (condLabel)),
4262 /* now start putting them together */
4263 forTree = newNode (NULLOP, initExpr, condExpr);
4264 forTree = newNode (NULLOP, forTree, forBody);
4265 forTree = newNode (NULLOP, forTree, loopExpr);
4266 /* finally add the break label */
4267 forTree = newNode (NULLOP, forTree,
4268 createLabel (falseLabel, NULL));
4272 /*-----------------------------------------------------------------*/
4273 /* createWhile - creates parse tree for while statement */
4274 /* the while statement will be created as follows */
4276 /* _while_continue_n: */
4277 /* condition_expression +-> trueLabel -> _while_boby_n */
4279 /* +-> falseLabel -> _while_break_n */
4280 /* _while_body_n: */
4282 /* goto _while_continue_n */
4283 /* _while_break_n: */
4284 /*-----------------------------------------------------------------*/
4286 createWhile (symbol * trueLabel, symbol * continueLabel,
4287 symbol * falseLabel, ast * condExpr, ast * whileBody)
4291 /* put the continue label */
4292 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4293 condExpr = createLabel (continueLabel, condExpr);
4294 condExpr->lineno = 0;
4296 /* put the body label in front of the body */
4297 whileBody = createLabel (trueLabel, whileBody);
4298 whileBody->lineno = 0;
4299 /* put a jump to continue at the end of the body */
4300 /* and put break label at the end of the body */
4301 whileBody = newNode (NULLOP,
4304 newAst_VALUE (symbolVal (continueLabel)),
4305 createLabel (falseLabel, NULL)));
4307 /* put it all together */
4308 if (IS_IFX (condExpr))
4309 whileTree = condExpr;
4312 whileTree = newNode (IFX, condExpr, NULL);
4313 /* put the true & false labels in place */
4314 whileTree->trueLabel = trueLabel;
4315 whileTree->falseLabel = falseLabel;
4318 return newNode (NULLOP, whileTree, whileBody);
4321 /*-----------------------------------------------------------------*/
4322 /* optimizeGetHbit - get highest order bit of the expression */
4323 /*-----------------------------------------------------------------*/
4325 optimizeGetHbit (ast * tree)
4328 /* if this is not a bit and */
4329 if (!IS_BITAND (tree))
4332 /* will look for tree of the form
4333 ( expr >> ((sizeof expr) -1) ) & 1 */
4334 if (!IS_AST_LIT_VALUE (tree->right))
4337 if (AST_LIT_VALUE (tree->right) != 1)
4340 if (!IS_RIGHT_OP (tree->left))
4343 if (!IS_AST_LIT_VALUE (tree->left->right))
4346 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4347 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4350 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4354 /*-----------------------------------------------------------------*/
4355 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4356 /*-----------------------------------------------------------------*/
4358 optimizeRRCRLC (ast * root)
4360 /* will look for trees of the form
4361 (?expr << 1) | (?expr >> 7) or
4362 (?expr >> 7) | (?expr << 1) will make that
4363 into a RLC : operation ..
4365 (?expr >> 1) | (?expr << 7) or
4366 (?expr << 7) | (?expr >> 1) will make that
4367 into a RRC operation
4368 note : by 7 I mean (number of bits required to hold the
4370 /* if the root operations is not a | operation the not */
4371 if (!IS_BITOR (root))
4374 /* I have to think of a better way to match patterns this sucks */
4375 /* that aside let start looking for the first case : I use a the
4376 negative check a lot to improve the efficiency */
4377 /* (?expr << 1) | (?expr >> 7) */
4378 if (IS_LEFT_OP (root->left) &&
4379 IS_RIGHT_OP (root->right))
4382 if (!SPEC_USIGN (TETYPE (root->left->left)))
4385 if (!IS_AST_LIT_VALUE (root->left->right) ||
4386 !IS_AST_LIT_VALUE (root->right->right))
4389 /* make sure it is the same expression */
4390 if (!isAstEqual (root->left->left,
4394 if (AST_LIT_VALUE (root->left->right) != 1)
4397 if (AST_LIT_VALUE (root->right->right) !=
4398 (getSize (TTYPE (root->left->left)) * 8 - 1))
4401 /* whew got the first case : create the AST */
4402 return newNode (RLC, root->left->left, NULL);
4406 /* check for second case */
4407 /* (?expr >> 7) | (?expr << 1) */
4408 if (IS_LEFT_OP (root->right) &&
4409 IS_RIGHT_OP (root->left))
4412 if (!SPEC_USIGN (TETYPE (root->left->left)))
4415 if (!IS_AST_LIT_VALUE (root->left->right) ||
4416 !IS_AST_LIT_VALUE (root->right->right))
4419 /* make sure it is the same symbol */
4420 if (!isAstEqual (root->left->left,
4424 if (AST_LIT_VALUE (root->right->right) != 1)
4427 if (AST_LIT_VALUE (root->left->right) !=
4428 (getSize (TTYPE (root->left->left)) * 8 - 1))
4431 /* whew got the first case : create the AST */
4432 return newNode (RLC, root->left->left, NULL);
4437 /* third case for RRC */
4438 /* (?symbol >> 1) | (?symbol << 7) */
4439 if (IS_LEFT_OP (root->right) &&
4440 IS_RIGHT_OP (root->left))
4443 if (!SPEC_USIGN (TETYPE (root->left->left)))
4446 if (!IS_AST_LIT_VALUE (root->left->right) ||
4447 !IS_AST_LIT_VALUE (root->right->right))
4450 /* make sure it is the same symbol */
4451 if (!isAstEqual (root->left->left,
4455 if (AST_LIT_VALUE (root->left->right) != 1)
4458 if (AST_LIT_VALUE (root->right->right) !=
4459 (getSize (TTYPE (root->left->left)) * 8 - 1))
4462 /* whew got the first case : create the AST */
4463 return newNode (RRC, root->left->left, NULL);
4467 /* fourth and last case for now */
4468 /* (?symbol << 7) | (?symbol >> 1) */
4469 if (IS_RIGHT_OP (root->right) &&
4470 IS_LEFT_OP (root->left))
4473 if (!SPEC_USIGN (TETYPE (root->left->left)))
4476 if (!IS_AST_LIT_VALUE (root->left->right) ||
4477 !IS_AST_LIT_VALUE (root->right->right))
4480 /* make sure it is the same symbol */
4481 if (!isAstEqual (root->left->left,
4485 if (AST_LIT_VALUE (root->right->right) != 1)
4488 if (AST_LIT_VALUE (root->left->right) !=
4489 (getSize (TTYPE (root->left->left)) * 8 - 1))
4492 /* whew got the first case : create the AST */
4493 return newNode (RRC, root->left->left, NULL);
4497 /* not found return root */
4501 /*-----------------------------------------------------------------*/
4502 /* optimizeCompare - otimizes compares for bit variables */
4503 /*-----------------------------------------------------------------*/
4505 optimizeCompare (ast * root)
4507 ast *optExpr = NULL;
4510 unsigned int litValue;
4512 /* if nothing then return nothing */
4516 /* if not a compare op then do leaves */
4517 if (!IS_COMPARE_OP (root))
4519 root->left = optimizeCompare (root->left);
4520 root->right = optimizeCompare (root->right);
4524 /* if left & right are the same then depending
4525 of the operation do */
4526 if (isAstEqual (root->left, root->right))
4528 switch (root->opval.op)
4533 optExpr = newAst_VALUE (constVal ("0"));
4538 optExpr = newAst_VALUE (constVal ("1"));
4542 return decorateType (optExpr);
4545 vleft = (root->left->type == EX_VALUE ?
4546 root->left->opval.val : NULL);
4548 vright = (root->right->type == EX_VALUE ?
4549 root->right->opval.val : NULL);
4551 /* if left is a BITVAR in BITSPACE */
4552 /* and right is a LITERAL then opt- */
4553 /* imize else do nothing */
4554 if (vleft && vright &&
4555 IS_BITVAR (vleft->etype) &&
4556 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4557 IS_LITERAL (vright->etype))
4560 /* if right side > 1 then comparison may never succeed */
4561 if ((litValue = (int) floatFromVal (vright)) > 1)
4563 werror (W_BAD_COMPARE);
4569 switch (root->opval.op)
4571 case '>': /* bit value greater than 1 cannot be */
4572 werror (W_BAD_COMPARE);
4576 case '<': /* bit value < 1 means 0 */
4578 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4581 case LE_OP: /* bit value <= 1 means no check */
4582 optExpr = newAst_VALUE (vright);
4585 case GE_OP: /* bit value >= 1 means only check for = */
4587 optExpr = newAst_VALUE (vleft);
4592 { /* literal is zero */
4593 switch (root->opval.op)
4595 case '<': /* bit value < 0 cannot be */
4596 werror (W_BAD_COMPARE);
4600 case '>': /* bit value > 0 means 1 */
4602 optExpr = newAst_VALUE (vleft);
4605 case LE_OP: /* bit value <= 0 means no check */
4606 case GE_OP: /* bit value >= 0 means no check */
4607 werror (W_BAD_COMPARE);
4611 case EQ_OP: /* bit == 0 means ! of bit */
4612 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4616 return decorateType (resolveSymbols (optExpr));
4617 } /* end-of-if of BITVAR */
4622 /*-----------------------------------------------------------------*/
4623 /* addSymToBlock : adds the symbol to the first block we find */
4624 /*-----------------------------------------------------------------*/
4626 addSymToBlock (symbol * sym, ast * tree)
4628 /* reached end of tree or a leaf */
4629 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4633 if (IS_AST_OP (tree) &&
4634 tree->opval.op == BLOCK)
4637 symbol *lsym = copySymbol (sym);
4639 lsym->next = AST_VALUES (tree, sym);
4640 AST_VALUES (tree, sym) = lsym;
4644 addSymToBlock (sym, tree->left);
4645 addSymToBlock (sym, tree->right);
4648 /*-----------------------------------------------------------------*/
4649 /* processRegParms - do processing for register parameters */
4650 /*-----------------------------------------------------------------*/
4652 processRegParms (value * args, ast * body)
4656 if (IS_REGPARM (args->etype))
4657 addSymToBlock (args->sym, body);
4662 /*-----------------------------------------------------------------*/
4663 /* resetParmKey - resets the operandkeys for the symbols */
4664 /*-----------------------------------------------------------------*/
4665 DEFSETFUNC (resetParmKey)
4676 /*-----------------------------------------------------------------*/
4677 /* createFunction - This is the key node that calls the iCode for */
4678 /* generating the code for a function. Note code */
4679 /* is generated function by function, later when */
4680 /* add inter-procedural analysis this will change */
4681 /*-----------------------------------------------------------------*/
4683 createFunction (symbol * name, ast * body)
4689 iCode *piCode = NULL;
4691 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4692 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4694 /* if check function return 0 then some problem */
4695 if (checkFunction (name, NULL) == 0)
4698 /* create a dummy block if none exists */
4700 body = newNode (BLOCK, NULL, NULL);
4704 /* check if the function name already in the symbol table */
4705 if ((csym = findSym (SymbolTab, NULL, name->name)))
4708 /* special case for compiler defined functions
4709 we need to add the name to the publics list : this
4710 actually means we are now compiling the compiler
4714 addSet (&publics, name);
4720 allocVariables (name);
4722 name->lastLine = mylineno;
4725 /* set the stack pointer */
4726 /* PENDING: check this for the mcs51 */
4727 stackPtr = -port->stack.direction * port->stack.call_overhead;
4728 if (IFFUNC_ISISR (name->type))
4729 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4730 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4731 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4733 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4735 fetype = getSpec (name->type); /* get the specifier for the function */
4736 /* if this is a reentrant function then */
4737 if (IFFUNC_ISREENT (name->type))
4740 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4742 /* do processing for parameters that are passed in registers */
4743 processRegParms (FUNC_ARGS(name->type), body);
4745 /* set the stack pointer */
4749 /* allocate & autoinit the block variables */
4750 processBlockVars (body, &stack, ALLOCATE);
4752 /* save the stack information */
4753 if (options.useXstack)
4754 name->xstack = SPEC_STAK (fetype) = stack;
4756 name->stack = SPEC_STAK (fetype) = stack;
4758 /* name needs to be mangled */
4759 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4761 body = resolveSymbols (body); /* resolve the symbols */
4762 body = decorateType (body); /* propagateType & do semantic checks */
4764 ex = newAst_VALUE (symbolVal (name)); /* create name */
4765 ex = newNode (FUNCTION, ex, body);
4766 ex->values.args = FUNC_ARGS(name->type);
4768 if (options.dump_tree) PA(ex);
4771 werror (E_FUNC_NO_CODE, name->name);
4775 /* create the node & generate intermediate code */
4777 codeOutFile = code->oFile;
4778 piCode = iCodeFromAst (ex);
4782 werror (E_FUNC_NO_CODE, name->name);
4786 eBBlockFromiCode (piCode);
4788 /* if there are any statics then do them */
4791 GcurMemmap = statsg;
4792 codeOutFile = statsg->oFile;
4793 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4799 /* dealloc the block variables */
4800 processBlockVars (body, &stack, DEALLOCATE);
4801 outputDebugStackSymbols();
4802 /* deallocate paramaters */
4803 deallocParms (FUNC_ARGS(name->type));
4805 if (IFFUNC_ISREENT (name->type))
4808 /* we are done freeup memory & cleanup */
4810 if (port->reset_labelKey) labelKey = 1;
4812 FUNC_HASBODY(name->type) = 1;
4813 addSet (&operKeyReset, name);
4814 applyToSet (operKeyReset, resetParmKey);
4819 cleanUpLevel (LabelTab, 0);
4820 cleanUpBlock (StructTab, 1);
4821 cleanUpBlock (TypedefTab, 1);
4823 xstack->syms = NULL;
4824 istack->syms = NULL;
4829 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4830 /*-----------------------------------------------------------------*/
4831 /* ast_print : prints the ast (for debugging purposes) */
4832 /*-----------------------------------------------------------------*/
4834 void ast_print (ast * tree, FILE *outfile, int indent)
4839 /* can print only decorated trees */
4840 if (!tree->decorated) return;
4842 /* if any child is an error | this one is an error do nothing */
4843 if (tree->isError ||
4844 (tree->left && tree->left->isError) ||
4845 (tree->right && tree->right->isError)) {
4846 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4850 /* print the line */
4851 /* if not block & function */
4852 if (tree->type == EX_OP &&
4853 (tree->opval.op != FUNCTION &&
4854 tree->opval.op != BLOCK &&
4855 tree->opval.op != NULLOP)) {
4858 if (tree->opval.op == FUNCTION) {
4860 value *args=FUNC_ARGS(tree->left->opval.val->type);
4861 fprintf(outfile,"FUNCTION (%s=%p) type (",
4862 tree->left->opval.val->name, tree);
4863 printTypeChain (tree->left->opval.val->type->next,outfile);
4864 fprintf(outfile,") args (");
4867 fprintf (outfile, ", ");
4869 printTypeChain (args ? args->type : NULL, outfile);
4871 args= args ? args->next : NULL;
4873 fprintf(outfile,")\n");
4874 ast_print(tree->left,outfile,indent);
4875 ast_print(tree->right,outfile,indent);
4878 if (tree->opval.op == BLOCK) {
4879 symbol *decls = tree->values.sym;
4880 INDENT(indent,outfile);
4881 fprintf(outfile,"{\n");
4883 INDENT(indent+2,outfile);
4884 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4885 decls->name, decls);
4886 printTypeChain(decls->type,outfile);
4887 fprintf(outfile,")\n");
4889 decls = decls->next;
4891 ast_print(tree->right,outfile,indent+2);
4892 INDENT(indent,outfile);
4893 fprintf(outfile,"}\n");
4896 if (tree->opval.op == NULLOP) {
4897 ast_print(tree->left,outfile,indent);
4898 ast_print(tree->right,outfile,indent);
4901 INDENT(indent,outfile);
4903 /*------------------------------------------------------------------*/
4904 /*----------------------------*/
4905 /* leaf has been reached */
4906 /*----------------------------*/
4907 /* if this is of type value */
4908 /* just get the type */
4909 if (tree->type == EX_VALUE) {
4911 if (IS_LITERAL (tree->opval.val->etype)) {
4912 fprintf(outfile,"CONSTANT (%p) value = ", tree);
4913 if (SPEC_USIGN (tree->opval.val->etype))
4914 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
4916 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
4917 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
4918 floatFromVal(tree->opval.val));
4919 } else if (tree->opval.val->sym) {
4920 /* if the undefined flag is set then give error message */
4921 if (tree->opval.val->sym->undefined) {
4922 fprintf(outfile,"UNDEFINED SYMBOL ");
4924 fprintf(outfile,"SYMBOL ");
4926 fprintf(outfile,"(%s=%p)",
4927 tree->opval.val->sym->name,tree);
4930 fprintf(outfile," type (");
4931 printTypeChain(tree->ftype,outfile);
4932 fprintf(outfile,")\n");
4934 fprintf(outfile,"\n");
4939 /* if type link for the case of cast */
4940 if (tree->type == EX_LINK) {
4941 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4942 printTypeChain(tree->opval.lnk,outfile);
4943 fprintf(outfile,")\n");
4948 /* depending on type of operator do */
4950 switch (tree->opval.op) {
4951 /*------------------------------------------------------------------*/
4952 /*----------------------------*/
4954 /*----------------------------*/
4956 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4957 printTypeChain(tree->ftype,outfile);
4958 fprintf(outfile,")\n");
4959 ast_print(tree->left,outfile,indent+2);
4960 ast_print(tree->right,outfile,indent+2);
4963 /*------------------------------------------------------------------*/
4964 /*----------------------------*/
4966 /*----------------------------*/
4968 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4969 printTypeChain(tree->ftype,outfile);
4970 fprintf(outfile,")\n");
4971 ast_print(tree->left,outfile,indent+2);
4972 ast_print(tree->right,outfile,indent+2);
4975 /*------------------------------------------------------------------*/
4976 /*----------------------------*/
4977 /* struct/union pointer */
4978 /*----------------------------*/
4980 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4981 printTypeChain(tree->ftype,outfile);
4982 fprintf(outfile,")\n");
4983 ast_print(tree->left,outfile,indent+2);
4984 ast_print(tree->right,outfile,indent+2);
4987 /*------------------------------------------------------------------*/
4988 /*----------------------------*/
4989 /* ++/-- operation */
4990 /*----------------------------*/
4993 fprintf(outfile,"post-");
4995 fprintf(outfile,"pre-");
4996 fprintf(outfile,"INC_OP (%p) type (",tree);
4997 printTypeChain(tree->ftype,outfile);
4998 fprintf(outfile,")\n");
4999 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5000 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5005 fprintf(outfile,"post-");
5007 fprintf(outfile,"pre-");
5008 fprintf(outfile,"DEC_OP (%p) type (",tree);
5009 printTypeChain(tree->ftype,outfile);
5010 fprintf(outfile,")\n");
5011 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5012 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5015 /*------------------------------------------------------------------*/
5016 /*----------------------------*/
5018 /*----------------------------*/
5021 fprintf(outfile,"& (%p) type (",tree);
5022 printTypeChain(tree->ftype,outfile);
5023 fprintf(outfile,")\n");
5024 ast_print(tree->left,outfile,indent+2);
5025 ast_print(tree->right,outfile,indent+2);
5027 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5028 printTypeChain(tree->ftype,outfile);
5029 fprintf(outfile,")\n");
5030 ast_print(tree->left,outfile,indent+2);
5031 ast_print(tree->right,outfile,indent+2);
5034 /*----------------------------*/
5036 /*----------------------------*/
5038 fprintf(outfile,"OR (%p) type (",tree);
5039 printTypeChain(tree->ftype,outfile);
5040 fprintf(outfile,")\n");
5041 ast_print(tree->left,outfile,indent+2);
5042 ast_print(tree->right,outfile,indent+2);
5044 /*------------------------------------------------------------------*/
5045 /*----------------------------*/
5047 /*----------------------------*/
5049 fprintf(outfile,"XOR (%p) type (",tree);
5050 printTypeChain(tree->ftype,outfile);
5051 fprintf(outfile,")\n");
5052 ast_print(tree->left,outfile,indent+2);
5053 ast_print(tree->right,outfile,indent+2);
5056 /*------------------------------------------------------------------*/
5057 /*----------------------------*/
5059 /*----------------------------*/
5061 fprintf(outfile,"DIV (%p) type (",tree);
5062 printTypeChain(tree->ftype,outfile);
5063 fprintf(outfile,")\n");
5064 ast_print(tree->left,outfile,indent+2);
5065 ast_print(tree->right,outfile,indent+2);
5067 /*------------------------------------------------------------------*/
5068 /*----------------------------*/
5070 /*----------------------------*/
5072 fprintf(outfile,"MOD (%p) type (",tree);
5073 printTypeChain(tree->ftype,outfile);
5074 fprintf(outfile,")\n");
5075 ast_print(tree->left,outfile,indent+2);
5076 ast_print(tree->right,outfile,indent+2);
5079 /*------------------------------------------------------------------*/
5080 /*----------------------------*/
5081 /* address dereference */
5082 /*----------------------------*/
5083 case '*': /* can be unary : if right is null then unary operation */
5085 fprintf(outfile,"DEREF (%p) type (",tree);
5086 printTypeChain(tree->ftype,outfile);
5087 fprintf(outfile,")\n");
5088 ast_print(tree->left,outfile,indent+2);
5091 /*------------------------------------------------------------------*/
5092 /*----------------------------*/
5093 /* multiplication */
5094 /*----------------------------*/
5095 fprintf(outfile,"MULT (%p) type (",tree);
5096 printTypeChain(tree->ftype,outfile);
5097 fprintf(outfile,")\n");
5098 ast_print(tree->left,outfile,indent+2);
5099 ast_print(tree->right,outfile,indent+2);
5103 /*------------------------------------------------------------------*/
5104 /*----------------------------*/
5105 /* unary '+' operator */
5106 /*----------------------------*/
5110 fprintf(outfile,"UPLUS (%p) type (",tree);
5111 printTypeChain(tree->ftype,outfile);
5112 fprintf(outfile,")\n");
5113 ast_print(tree->left,outfile,indent+2);
5115 /*------------------------------------------------------------------*/
5116 /*----------------------------*/
5118 /*----------------------------*/
5119 fprintf(outfile,"ADD (%p) type (",tree);
5120 printTypeChain(tree->ftype,outfile);
5121 fprintf(outfile,")\n");
5122 ast_print(tree->left,outfile,indent+2);
5123 ast_print(tree->right,outfile,indent+2);
5126 /*------------------------------------------------------------------*/
5127 /*----------------------------*/
5129 /*----------------------------*/
5130 case '-': /* can be unary */
5132 fprintf(outfile,"UMINUS (%p) type (",tree);
5133 printTypeChain(tree->ftype,outfile);
5134 fprintf(outfile,")\n");
5135 ast_print(tree->left,outfile,indent+2);
5137 /*------------------------------------------------------------------*/
5138 /*----------------------------*/
5140 /*----------------------------*/
5141 fprintf(outfile,"SUB (%p) type (",tree);
5142 printTypeChain(tree->ftype,outfile);
5143 fprintf(outfile,")\n");
5144 ast_print(tree->left,outfile,indent+2);
5145 ast_print(tree->right,outfile,indent+2);
5148 /*------------------------------------------------------------------*/
5149 /*----------------------------*/
5151 /*----------------------------*/
5153 fprintf(outfile,"COMPL (%p) type (",tree);
5154 printTypeChain(tree->ftype,outfile);
5155 fprintf(outfile,")\n");
5156 ast_print(tree->left,outfile,indent+2);
5158 /*------------------------------------------------------------------*/
5159 /*----------------------------*/
5161 /*----------------------------*/
5163 fprintf(outfile,"NOT (%p) type (",tree);
5164 printTypeChain(tree->ftype,outfile);
5165 fprintf(outfile,")\n");
5166 ast_print(tree->left,outfile,indent+2);
5168 /*------------------------------------------------------------------*/
5169 /*----------------------------*/
5171 /*----------------------------*/
5173 fprintf(outfile,"RRC (%p) type (",tree);
5174 printTypeChain(tree->ftype,outfile);
5175 fprintf(outfile,")\n");
5176 ast_print(tree->left,outfile,indent+2);
5180 fprintf(outfile,"RLC (%p) type (",tree);
5181 printTypeChain(tree->ftype,outfile);
5182 fprintf(outfile,")\n");
5183 ast_print(tree->left,outfile,indent+2);
5186 fprintf(outfile,"GETHBIT (%p) type (",tree);
5187 printTypeChain(tree->ftype,outfile);
5188 fprintf(outfile,")\n");
5189 ast_print(tree->left,outfile,indent+2);
5192 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5193 printTypeChain(tree->ftype,outfile);
5194 fprintf(outfile,")\n");
5195 ast_print(tree->left,outfile,indent+2);
5196 ast_print(tree->right,outfile,indent+2);
5199 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5200 printTypeChain(tree->ftype,outfile);
5201 fprintf(outfile,")\n");
5202 ast_print(tree->left,outfile,indent+2);
5203 ast_print(tree->right,outfile,indent+2);
5205 /*------------------------------------------------------------------*/
5206 /*----------------------------*/
5208 /*----------------------------*/
5209 case CAST: /* change the type */
5210 fprintf(outfile,"CAST (%p) from type (",tree);
5211 printTypeChain(tree->right->ftype,outfile);
5212 fprintf(outfile,") to type (");
5213 printTypeChain(tree->ftype,outfile);
5214 fprintf(outfile,")\n");
5215 ast_print(tree->right,outfile,indent+2);
5219 fprintf(outfile,"ANDAND (%p) type (",tree);
5220 printTypeChain(tree->ftype,outfile);
5221 fprintf(outfile,")\n");
5222 ast_print(tree->left,outfile,indent+2);
5223 ast_print(tree->right,outfile,indent+2);
5226 fprintf(outfile,"OROR (%p) type (",tree);
5227 printTypeChain(tree->ftype,outfile);
5228 fprintf(outfile,")\n");
5229 ast_print(tree->left,outfile,indent+2);
5230 ast_print(tree->right,outfile,indent+2);
5233 /*------------------------------------------------------------------*/
5234 /*----------------------------*/
5235 /* comparison operators */
5236 /*----------------------------*/
5238 fprintf(outfile,"GT(>) (%p) type (",tree);
5239 printTypeChain(tree->ftype,outfile);
5240 fprintf(outfile,")\n");
5241 ast_print(tree->left,outfile,indent+2);
5242 ast_print(tree->right,outfile,indent+2);
5245 fprintf(outfile,"LT(<) (%p) type (",tree);
5246 printTypeChain(tree->ftype,outfile);
5247 fprintf(outfile,")\n");
5248 ast_print(tree->left,outfile,indent+2);
5249 ast_print(tree->right,outfile,indent+2);
5252 fprintf(outfile,"LE(<=) (%p) type (",tree);
5253 printTypeChain(tree->ftype,outfile);
5254 fprintf(outfile,")\n");
5255 ast_print(tree->left,outfile,indent+2);
5256 ast_print(tree->right,outfile,indent+2);
5259 fprintf(outfile,"GE(>=) (%p) type (",tree);
5260 printTypeChain(tree->ftype,outfile);
5261 fprintf(outfile,")\n");
5262 ast_print(tree->left,outfile,indent+2);
5263 ast_print(tree->right,outfile,indent+2);
5266 fprintf(outfile,"EQ(==) (%p) type (",tree);
5267 printTypeChain(tree->ftype,outfile);
5268 fprintf(outfile,")\n");
5269 ast_print(tree->left,outfile,indent+2);
5270 ast_print(tree->right,outfile,indent+2);
5273 fprintf(outfile,"NE(!=) (%p) type (",tree);
5274 printTypeChain(tree->ftype,outfile);
5275 fprintf(outfile,")\n");
5276 ast_print(tree->left,outfile,indent+2);
5277 ast_print(tree->right,outfile,indent+2);
5278 /*------------------------------------------------------------------*/
5279 /*----------------------------*/
5281 /*----------------------------*/
5282 case SIZEOF: /* evaluate wihout code generation */
5283 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5286 /*------------------------------------------------------------------*/
5287 /*----------------------------*/
5288 /* conditional operator '?' */
5289 /*----------------------------*/
5291 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5292 printTypeChain(tree->ftype,outfile);
5293 fprintf(outfile,")\n");
5294 ast_print(tree->left,outfile,indent+2);
5295 ast_print(tree->right,outfile,indent+2);
5299 fprintf(outfile,"COLON(:) (%p) type (",tree);
5300 printTypeChain(tree->ftype,outfile);
5301 fprintf(outfile,")\n");
5302 ast_print(tree->left,outfile,indent+2);
5303 ast_print(tree->right,outfile,indent+2);
5306 /*------------------------------------------------------------------*/
5307 /*----------------------------*/
5308 /* assignment operators */
5309 /*----------------------------*/
5311 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5312 printTypeChain(tree->ftype,outfile);
5313 fprintf(outfile,")\n");
5314 ast_print(tree->left,outfile,indent+2);
5315 ast_print(tree->right,outfile,indent+2);
5318 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5319 printTypeChain(tree->ftype,outfile);
5320 fprintf(outfile,")\n");
5321 ast_print(tree->left,outfile,indent+2);
5322 ast_print(tree->right,outfile,indent+2);
5325 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5326 printTypeChain(tree->ftype,outfile);
5327 fprintf(outfile,")\n");
5328 ast_print(tree->left,outfile,indent+2);
5329 ast_print(tree->right,outfile,indent+2);
5332 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5333 printTypeChain(tree->ftype,outfile);
5334 fprintf(outfile,")\n");
5335 ast_print(tree->left,outfile,indent+2);
5336 ast_print(tree->right,outfile,indent+2);
5339 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5340 printTypeChain(tree->ftype,outfile);
5341 fprintf(outfile,")\n");
5342 ast_print(tree->left,outfile,indent+2);
5343 ast_print(tree->right,outfile,indent+2);
5346 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5347 printTypeChain(tree->ftype,outfile);
5348 fprintf(outfile,")\n");
5349 ast_print(tree->left,outfile,indent+2);
5350 ast_print(tree->right,outfile,indent+2);
5353 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5354 printTypeChain(tree->ftype,outfile);
5355 fprintf(outfile,")\n");
5356 ast_print(tree->left,outfile,indent+2);
5357 ast_print(tree->right,outfile,indent+2);
5359 /*------------------------------------------------------------------*/
5360 /*----------------------------*/
5362 /*----------------------------*/
5364 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5365 printTypeChain(tree->ftype,outfile);
5366 fprintf(outfile,")\n");
5367 ast_print(tree->left,outfile,indent+2);
5368 ast_print(tree->right,outfile,indent+2);
5370 /*------------------------------------------------------------------*/
5371 /*----------------------------*/
5373 /*----------------------------*/
5375 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5376 printTypeChain(tree->ftype,outfile);
5377 fprintf(outfile,")\n");
5378 ast_print(tree->left,outfile,indent+2);
5379 ast_print(tree->right,outfile,indent+2);
5381 /*------------------------------------------------------------------*/
5382 /*----------------------------*/
5383 /* straight assignemnt */
5384 /*----------------------------*/
5386 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5387 printTypeChain(tree->ftype,outfile);
5388 fprintf(outfile,")\n");
5389 ast_print(tree->left,outfile,indent+2);
5390 ast_print(tree->right,outfile,indent+2);
5392 /*------------------------------------------------------------------*/
5393 /*----------------------------*/
5394 /* comma operator */
5395 /*----------------------------*/
5397 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5398 printTypeChain(tree->ftype,outfile);
5399 fprintf(outfile,")\n");
5400 ast_print(tree->left,outfile,indent+2);
5401 ast_print(tree->right,outfile,indent+2);
5403 /*------------------------------------------------------------------*/
5404 /*----------------------------*/
5406 /*----------------------------*/
5409 fprintf(outfile,"CALL (%p) type (",tree);
5410 printTypeChain(tree->ftype,outfile);
5411 fprintf(outfile,")\n");
5412 ast_print(tree->left,outfile,indent+2);
5413 ast_print(tree->right,outfile,indent+2);
5416 fprintf(outfile,"PARMS\n");
5417 ast_print(tree->left,outfile,indent+2);
5418 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5419 ast_print(tree->right,outfile,indent+2);
5422 /*------------------------------------------------------------------*/
5423 /*----------------------------*/
5424 /* return statement */
5425 /*----------------------------*/
5427 fprintf(outfile,"RETURN (%p) type (",tree);
5429 printTypeChain(tree->right->ftype,outfile);
5431 fprintf(outfile,")\n");
5432 ast_print(tree->right,outfile,indent+2);
5434 /*------------------------------------------------------------------*/
5435 /*----------------------------*/
5436 /* label statement */
5437 /*----------------------------*/
5439 fprintf(outfile,"LABEL (%p)\n",tree);
5440 ast_print(tree->left,outfile,indent+2);
5441 ast_print(tree->right,outfile,indent);
5443 /*------------------------------------------------------------------*/
5444 /*----------------------------*/
5445 /* switch statement */
5446 /*----------------------------*/
5450 fprintf(outfile,"SWITCH (%p) ",tree);
5451 ast_print(tree->left,outfile,0);
5452 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5453 INDENT(indent+2,outfile);
5454 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5455 (int) floatFromVal(val),
5456 tree->values.switchVals.swNum,
5457 (int) floatFromVal(val));
5459 ast_print(tree->right,outfile,indent);
5462 /*------------------------------------------------------------------*/
5463 /*----------------------------*/
5465 /*----------------------------*/
5467 fprintf(outfile,"IF (%p) \n",tree);
5468 ast_print(tree->left,outfile,indent+2);
5469 if (tree->trueLabel) {
5470 INDENT(indent+2,outfile);
5471 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5473 if (tree->falseLabel) {
5474 INDENT(indent+2,outfile);
5475 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5477 ast_print(tree->right,outfile,indent+2);
5479 /*----------------------------*/
5480 /* goto Statement */
5481 /*----------------------------*/
5483 fprintf(outfile,"GOTO (%p) \n",tree);
5484 ast_print(tree->left,outfile,indent+2);
5485 fprintf(outfile,"\n");
5487 /*------------------------------------------------------------------*/
5488 /*----------------------------*/
5490 /*----------------------------*/
5492 fprintf(outfile,"FOR (%p) \n",tree);
5493 if (AST_FOR( tree, initExpr)) {
5494 INDENT(indent+2,outfile);
5495 fprintf(outfile,"INIT EXPR ");
5496 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5498 if (AST_FOR( tree, condExpr)) {
5499 INDENT(indent+2,outfile);
5500 fprintf(outfile,"COND EXPR ");
5501 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5503 if (AST_FOR( tree, loopExpr)) {
5504 INDENT(indent+2,outfile);
5505 fprintf(outfile,"LOOP EXPR ");
5506 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5508 fprintf(outfile,"FOR LOOP BODY \n");
5509 ast_print(tree->left,outfile,indent+2);
5512 fprintf(outfile,"CRITICAL (%p) \n",tree);
5513 ast_print(tree->left,outfile,indent+2);
5521 ast_print(t,stdout,0);