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 *optimizeSWAP (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
60 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
65 printTypeChain (tree->ftype, stdout);
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree */
72 /*-----------------------------------------------------------------*/
74 newAst_ (unsigned type)
77 static int oldLineno = 0;
79 ex = Safe_alloc ( sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : mylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
91 newAst_VALUE (value * val)
93 ast *ex = newAst_ (EX_VALUE);
99 newAst_OP (unsigned op)
101 ast *ex = newAst_ (EX_OP);
107 newAst_LINK (sym_link * val)
109 ast *ex = newAst_ (EX_LINK);
114 /*-----------------------------------------------------------------*/
115 /* newNode - creates a new node */
116 /*-----------------------------------------------------------------*/
118 newNode (long op, ast * left, ast * right)
129 /*-----------------------------------------------------------------*/
130 /* newIfxNode - creates a new Ifx Node */
131 /*-----------------------------------------------------------------*/
133 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
137 /* if this is a literal then we already know the result */
138 if (condAst->etype && IS_LITERAL (condAst->etype))
140 /* then depending on the expression value */
141 if (floatFromVal (condAst->opval.val))
142 ifxNode = newNode (GOTO,
143 newAst_VALUE (symbolVal (trueLabel)),
146 ifxNode = newNode (GOTO,
147 newAst_VALUE (symbolVal (falseLabel)),
152 ifxNode = newNode (IFX, condAst, NULL);
153 ifxNode->trueLabel = trueLabel;
154 ifxNode->falseLabel = falseLabel;
160 /*-----------------------------------------------------------------*/
161 /* copyAstValues - copies value portion of ast if needed */
162 /*-----------------------------------------------------------------*/
164 copyAstValues (ast * dest, ast * src)
166 switch (src->opval.op)
169 dest->values.sym = copySymbolChain (src->values.sym);
173 dest->values.switchVals.swVals =
174 copyValue (src->values.switchVals.swVals);
175 dest->values.switchVals.swDefault =
176 src->values.switchVals.swDefault;
177 dest->values.switchVals.swNum =
178 src->values.switchVals.swNum;
182 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
186 dest->values.constlist = copyLiteralList(src->values.constlist);
190 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
191 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
192 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
193 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
194 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
195 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
196 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
201 /*-----------------------------------------------------------------*/
202 /* copyAst - makes a copy of a given astession */
203 /*-----------------------------------------------------------------*/
212 dest = Safe_alloc ( sizeof (ast));
214 dest->type = src->type;
215 dest->lineno = src->lineno;
216 dest->level = src->level;
217 dest->funcName = src->funcName;
220 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
222 /* if this is a leaf */
224 if (src->type == EX_VALUE)
226 dest->opval.val = copyValue (src->opval.val);
231 if (src->type == EX_LINK)
233 dest->opval.lnk = copyLinkChain (src->opval.lnk);
237 dest->opval.op = src->opval.op;
239 /* if this is a node that has special values */
240 copyAstValues (dest, src);
242 dest->trueLabel = copySymbol (src->trueLabel);
243 dest->falseLabel = copySymbol (src->falseLabel);
244 dest->left = copyAst (src->left);
245 dest->right = copyAst (src->right);
251 /*-----------------------------------------------------------------*/
252 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
253 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
254 /*-----------------------------------------------------------------*/
255 ast *removeIncDecOps (ast * tree) {
257 // traverse the tree and remove inc/dec ops
262 if (tree->type == EX_OP &&
263 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
270 tree->left=removeIncDecOps(tree->left);
271 tree->right=removeIncDecOps(tree->right);
276 /*-----------------------------------------------------------------*/
277 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
278 /* "*++s += 3" -> "*++s = *++s + 3" */
279 /*-----------------------------------------------------------------*/
280 ast *removePreIncDecOps (ast * tree) {
282 // traverse the tree and remove pre-inc/dec ops
287 if (tree->type == EX_OP &&
288 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
293 tree->left=removePreIncDecOps(tree->left);
294 tree->right=removePreIncDecOps(tree->right);
299 /*-----------------------------------------------------------------*/
300 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
301 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
302 /*-----------------------------------------------------------------*/
303 ast *removePostIncDecOps (ast * tree) {
305 // traverse the tree and remove pre-inc/dec ops
310 if (tree->type == EX_OP &&
311 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
316 tree->left=removePostIncDecOps(tree->left);
317 tree->right=removePostIncDecOps(tree->right);
322 /*-----------------------------------------------------------------*/
323 /* hasSEFcalls - returns TRUE if tree has a function call */
324 /*-----------------------------------------------------------------*/
326 hasSEFcalls (ast * tree)
331 if (tree->type == EX_OP &&
332 (tree->opval.op == CALL ||
333 tree->opval.op == PCALL ||
334 tree->opval.op == '=' ||
335 tree->opval.op == INC_OP ||
336 tree->opval.op == DEC_OP))
339 return (hasSEFcalls (tree->left) |
340 hasSEFcalls (tree->right));
343 /*-----------------------------------------------------------------*/
344 /* isAstEqual - compares two asts & returns 1 if they are equal */
345 /*-----------------------------------------------------------------*/
347 isAstEqual (ast * t1, ast * t2)
356 if (t1->type != t2->type)
362 if (t1->opval.op != t2->opval.op)
364 return (isAstEqual (t1->left, t2->left) &&
365 isAstEqual (t1->right, t2->right));
369 if (t1->opval.val->sym)
371 if (!t2->opval.val->sym)
374 return isSymbolEqual (t1->opval.val->sym,
379 if (t2->opval.val->sym)
382 return (floatFromVal (t1->opval.val) ==
383 floatFromVal (t2->opval.val));
387 /* only compare these two types */
395 /*-----------------------------------------------------------------*/
396 /* resolveSymbols - resolve symbols from the symbol table */
397 /*-----------------------------------------------------------------*/
399 resolveSymbols (ast * tree)
401 /* walk the entire tree and check for values */
402 /* with symbols if we find one then replace */
403 /* symbol with that from the symbol table */
410 /* if not block & function */
411 if (tree->type == EX_OP &&
412 (tree->opval.op != FUNCTION &&
413 tree->opval.op != BLOCK &&
414 tree->opval.op != NULLOP))
416 filename = tree->filename;
417 lineno = tree->lineno;
421 /* make sure we resolve the true & false labels for ifx */
422 if (tree->type == EX_OP && tree->opval.op == IFX)
428 if ((csym = findSym (LabelTab, tree->trueLabel,
429 tree->trueLabel->name)))
430 tree->trueLabel = csym;
432 werror (E_LABEL_UNDEF, tree->trueLabel->name);
435 if (tree->falseLabel)
437 if ((csym = findSym (LabelTab,
439 tree->falseLabel->name)))
440 tree->falseLabel = csym;
442 werror (E_LABEL_UNDEF, tree->falseLabel->name);
447 /* if this is a label resolve it from the labelTab */
448 if (IS_AST_VALUE (tree) &&
449 tree->opval.val->sym &&
450 tree->opval.val->sym->islbl)
453 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
454 tree->opval.val->sym->name);
457 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
459 tree->opval.val->sym = csym;
461 goto resolveChildren;
464 /* do only for leafs */
465 if (IS_AST_VALUE (tree) &&
466 tree->opval.val->sym &&
467 !tree->opval.val->sym->implicit)
470 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
472 /* if found in the symbol table & they r not the same */
473 if (csym && tree->opval.val->sym != csym)
475 tree->opval.val->sym = csym;
476 tree->opval.val->type = csym->type;
477 tree->opval.val->etype = csym->etype;
480 /* if not found in the symbol table */
481 /* mark it as undefined assume it is */
482 /* an integer in data space */
483 if (!csym && !tree->opval.val->sym->implicit)
486 /* if this is a function name then */
487 /* mark it as returning an int */
490 tree->opval.val->sym->type = newLink (DECLARATOR);
491 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
492 tree->opval.val->sym->type->next =
493 tree->opval.val->sym->etype = newIntLink ();
494 tree->opval.val->etype = tree->opval.val->etype;
495 tree->opval.val->type = tree->opval.val->sym->type;
496 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
497 allocVariables (tree->opval.val->sym);
501 tree->opval.val->sym->undefined = 1;
502 tree->opval.val->type =
503 tree->opval.val->etype = newIntLink ();
504 tree->opval.val->sym->type =
505 tree->opval.val->sym->etype = newIntLink ();
511 resolveSymbols (tree->left);
512 resolveSymbols (tree->right);
517 /*-----------------------------------------------------------------*/
518 /* setAstLineno - walks a ast tree & sets the line number */
519 /*-----------------------------------------------------------------*/
520 int setAstLineno (ast * tree, int lineno)
525 tree->lineno = lineno;
526 setAstLineno (tree->left, lineno);
527 setAstLineno (tree->right, lineno);
531 /*-----------------------------------------------------------------*/
532 /* funcOfType :- function of type with name */
533 /*-----------------------------------------------------------------*/
535 funcOfType (char *name, sym_link * type, sym_link * argType,
539 /* create the symbol */
540 sym = newSymbol (name, 0);
542 /* setup return value */
543 sym->type = newLink (DECLARATOR);
544 DCL_TYPE (sym->type) = FUNCTION;
545 sym->type->next = copyLinkChain (type);
546 sym->etype = getSpec (sym->type);
547 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
549 /* if arguments required */
553 args = FUNC_ARGS(sym->type) = newValue ();
557 args->type = copyLinkChain (argType);
558 args->etype = getSpec (args->type);
559 SPEC_EXTR(args->etype)=1;
562 args = args->next = newValue ();
569 allocVariables (sym);
574 /*-----------------------------------------------------------------*/
575 /* funcOfTypeVarg :- function of type with name and argtype */
576 /*-----------------------------------------------------------------*/
578 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
583 /* create the symbol */
584 sym = newSymbol (name, 0);
586 /* setup return value */
587 sym->type = newLink (DECLARATOR);
588 DCL_TYPE (sym->type) = FUNCTION;
589 sym->type->next = typeFromStr(rtype);
590 sym->etype = getSpec (sym->type);
592 /* if arguments required */
595 args = FUNC_ARGS(sym->type) = newValue ();
597 for ( i = 0 ; i < nArgs ; i++ ) {
598 args->type = typeFromStr(atypes[i]);
599 args->etype = getSpec (args->type);
600 SPEC_EXTR(args->etype)=1;
601 if ((i + 1) == nArgs) break;
602 args = args->next = newValue ();
609 allocVariables (sym);
614 /*-----------------------------------------------------------------*/
615 /* reverseParms - will reverse a parameter tree */
616 /*-----------------------------------------------------------------*/
618 reverseParms (ast * ptree)
624 /* top down if we find a nonParm tree then quit */
625 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
628 ptree->left = ptree->right;
629 ptree->right = ttree;
630 reverseParms (ptree->left);
631 reverseParms (ptree->right);
637 /*-----------------------------------------------------------------*/
638 /* processParms - makes sure the parameters are okay and do some */
639 /* processing with them */
640 /*-----------------------------------------------------------------*/
642 processParms (ast * func,
645 int *parmNumber, // unused, although updated
648 /* if none of them exist */
649 if (!defParm && !actParm)
653 if (getenv("DEBUG_SANITY")) {
654 fprintf (stderr, "processParms: %s ", defParm->name);
656 /* make sure the type is complete and sane */
657 checkTypeSanity(defParm->etype, defParm->name);
660 /* if the function is being called via a pointer & */
661 /* it has not been defined a reentrant then we cannot */
662 /* have parameters */
663 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
665 werror (W_NONRENT_ARGS);
669 /* if defined parameters ended but actual parameters */
670 /* exist and this is not defined as a variable arg */
671 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
673 werror (E_TOO_MANY_PARMS);
677 /* if defined parameters present but no actual parameters */
678 if (defParm && !actParm)
680 werror (E_TOO_FEW_PARMS);
684 if (IS_VOID(actParm->ftype)) {
685 werror (E_VOID_VALUE_USED);
689 /* If this is a varargs function... */
690 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
695 if (IS_CAST_OP (actParm)
696 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
698 /* Parameter was explicitly typecast; don't touch it. */
702 ftype = actParm->ftype;
704 /* If it's a small integer, upcast to int. */
705 if (IS_INTEGRAL (ftype)
706 && (getSize (ftype) < (unsigned) INTSIZE))
708 if (IS_AST_OP(actParm) &&
709 (actParm->opval.op == LEFT_OP ||
710 actParm->opval.op == '*' ||
711 actParm->opval.op == '+' ||
712 actParm->opval.op == '-') &&
714 // we should cast an operand instead of the result
715 actParm->decorated = 0;
716 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
718 actParm = decorateType(actParm);
720 newType = newAst_LINK(INTTYPE);
724 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
726 newType = newAst_LINK (copyLinkChain(ftype));
727 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
730 if (IS_AGGREGATE (ftype))
732 newType = newAst_LINK (copyLinkChain (ftype));
733 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
737 /* cast required; change this op to a cast. */
738 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
740 actParm->type = EX_OP;
741 actParm->opval.op = CAST;
742 actParm->left = newType;
743 actParm->right = parmCopy;
744 decorateType (actParm);
746 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
748 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
749 processParms (func, NULL, actParm->right, parmNumber, rightmost));
754 /* if defined parameters ended but actual has not & */
756 if (!defParm && actParm &&
757 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
760 resolveSymbols (actParm);
761 /* if this is a PARAM node then match left & right */
762 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
764 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
765 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
769 /* If we have found a value node by following only right-hand links,
770 * then we know that there are no more values after us.
772 * Therefore, if there are more defined parameters, the caller didn't
775 if (rightmost && defParm->next)
777 werror (E_TOO_FEW_PARMS);
782 /* the parameter type must be at least castable */
783 if (compareType (defParm->type, actParm->ftype) == 0) {
784 werror (E_INCOMPAT_TYPES);
785 printFromToType (actParm->ftype, defParm->type);
789 /* if the parameter is castable then add the cast */
790 if (compareType (defParm->type, actParm->ftype) < 0)
792 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
794 /* now change the current one to a cast */
795 actParm->type = EX_OP;
796 actParm->opval.op = CAST;
797 actParm->left = newAst_LINK (defParm->type);
798 actParm->right = pTree;
799 actParm->etype = defParm->etype;
800 actParm->ftype = defParm->type;
801 actParm->decorated=0; /* force typechecking */
802 decorateType (actParm);
805 /* make a copy and change the regparm type to the defined parm */
806 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
807 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
808 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
812 /*-----------------------------------------------------------------*/
813 /* createIvalType - generates ival for basic types */
814 /*-----------------------------------------------------------------*/
816 createIvalType (ast * sym, sym_link * type, initList * ilist)
820 /* if initList is deep */
821 if (ilist->type == INIT_DEEP)
822 ilist = ilist->init.deep;
824 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
825 return decorateType (newNode ('=', sym, iExpr));
828 /*-----------------------------------------------------------------*/
829 /* createIvalStruct - generates initial value for structures */
830 /*-----------------------------------------------------------------*/
832 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
839 sflds = SPEC_STRUCT (type)->fields;
840 if (ilist->type != INIT_DEEP)
842 werror (E_INIT_STRUCT, "");
846 iloop = ilist->init.deep;
848 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
850 /* if we have come to end */
854 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
855 lAst = decorateType (resolveSymbols (lAst));
856 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
860 werror (W_EXCESS_INITIALIZERS, "struct",
861 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
868 /*-----------------------------------------------------------------*/
869 /* createIvalArray - generates code for array initialization */
870 /*-----------------------------------------------------------------*/
872 createIvalArray (ast * sym, sym_link * type, initList * ilist)
876 int lcnt = 0, size = 0;
877 literalList *literalL;
879 /* take care of the special case */
880 /* array of characters can be init */
882 if (IS_CHAR (type->next))
883 if ((rast = createIvalCharPtr (sym,
885 decorateType (resolveSymbols (list2expr (ilist))))))
887 return decorateType (resolveSymbols (rast));
889 /* not the special case */
890 if (ilist->type != INIT_DEEP)
892 werror (E_INIT_STRUCT, "");
896 iloop = ilist->init.deep;
897 lcnt = DCL_ELEM (type);
899 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
903 aSym = decorateType (resolveSymbols(sym));
905 rast = newNode(ARRAYINIT, aSym, NULL);
906 rast->values.constlist = literalL;
908 // Make sure size is set to length of initializer list.
915 if (lcnt && size > lcnt)
917 // Array size was specified, and we have more initializers than needed.
918 char *name=sym->opval.val->sym->name;
919 int lineno=sym->opval.val->sym->lineDef;
921 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
930 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
931 aSym = decorateType (resolveSymbols (aSym));
932 rast = createIval (aSym, type->next, iloop, rast);
933 iloop = (iloop ? iloop->next : NULL);
939 /* no of elements given and we */
940 /* have generated for all of them */
943 // there has to be a better way
944 char *name=sym->opval.val->sym->name;
945 int lineno=sym->opval.val->sym->lineDef;
946 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
953 /* if we have not been given a size */
954 if (!DCL_ELEM (type))
956 DCL_ELEM (type) = size;
959 return decorateType (resolveSymbols (rast));
963 /*-----------------------------------------------------------------*/
964 /* createIvalCharPtr - generates initial values for char pointers */
965 /*-----------------------------------------------------------------*/
967 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
971 /* if this is a pointer & right is a literal array then */
972 /* just assignment will do */
973 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
974 SPEC_SCLS (iexpr->etype) == S_CODE)
975 && IS_ARRAY (iexpr->ftype)))
976 return newNode ('=', sym, iexpr);
978 /* left side is an array so we have to assign each */
980 if ((IS_LITERAL (iexpr->etype) ||
981 SPEC_SCLS (iexpr->etype) == S_CODE)
982 && IS_ARRAY (iexpr->ftype))
984 /* for each character generate an assignment */
985 /* to the array element */
986 char *s = SPEC_CVAL (iexpr->etype).v_char;
991 rast = newNode (NULLOP,
995 newAst_VALUE (valueFromLit ((float) i))),
996 newAst_VALUE (valueFromLit (*s))));
1000 rast = newNode (NULLOP,
1004 newAst_VALUE (valueFromLit ((float) i))),
1005 newAst_VALUE (valueFromLit (*s))));
1007 // now WE don't need iexpr's symbol anymore
1008 freeStringSymbol(AST_SYMBOL(iexpr));
1010 return decorateType (resolveSymbols (rast));
1016 /*-----------------------------------------------------------------*/
1017 /* createIvalPtr - generates initial value for pointers */
1018 /*-----------------------------------------------------------------*/
1020 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1026 if (ilist->type == INIT_DEEP)
1027 ilist = ilist->init.deep;
1029 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1031 /* if character pointer */
1032 if (IS_CHAR (type->next))
1033 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1036 return newNode ('=', sym, iexpr);
1039 /*-----------------------------------------------------------------*/
1040 /* createIval - generates code for initial value */
1041 /*-----------------------------------------------------------------*/
1043 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1050 /* if structure then */
1051 if (IS_STRUCT (type))
1052 rast = createIvalStruct (sym, type, ilist);
1054 /* if this is a pointer */
1056 rast = createIvalPtr (sym, type, ilist);
1058 /* if this is an array */
1059 if (IS_ARRAY (type))
1060 rast = createIvalArray (sym, type, ilist);
1062 /* if type is SPECIFIER */
1064 rast = createIvalType (sym, type, ilist);
1067 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1069 return decorateType (resolveSymbols (rast));
1072 /*-----------------------------------------------------------------*/
1073 /* initAggregates - initialises aggregate variables with initv */
1074 /*-----------------------------------------------------------------*/
1075 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1076 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1079 /*-----------------------------------------------------------------*/
1080 /* gatherAutoInit - creates assignment expressions for initial */
1082 /*-----------------------------------------------------------------*/
1084 gatherAutoInit (symbol * autoChain)
1091 for (sym = autoChain; sym; sym = sym->next)
1094 /* resolve the symbols in the ival */
1096 resolveIvalSym (sym->ival);
1098 /* if this is a static variable & has an */
1099 /* initial value the code needs to be lifted */
1100 /* here to the main portion since they can be */
1101 /* initialised only once at the start */
1102 if (IS_STATIC (sym->etype) && sym->ival &&
1103 SPEC_SCLS (sym->etype) != S_CODE)
1107 /* insert the symbol into the symbol table */
1108 /* with level = 0 & name = rname */
1109 newSym = copySymbol (sym);
1110 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1112 /* now lift the code to main */
1113 if (IS_AGGREGATE (sym->type)) {
1114 work = initAggregates (sym, sym->ival, NULL);
1116 if (getNelements(sym->type, sym->ival)>1) {
1117 werror (W_EXCESS_INITIALIZERS, "scalar",
1118 sym->name, sym->lineDef);
1120 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1121 list2expr (sym->ival));
1124 setAstLineno (work, sym->lineDef);
1128 staticAutos = newNode (NULLOP, staticAutos, work);
1135 /* if there is an initial value */
1136 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1138 initList *ilist=sym->ival;
1140 while (ilist->type == INIT_DEEP) {
1141 ilist = ilist->init.deep;
1144 /* update lineno for error msg */
1145 lineno=sym->lineDef;
1146 setAstLineno (ilist->init.node, lineno);
1148 if (IS_AGGREGATE (sym->type)) {
1149 work = initAggregates (sym, sym->ival, NULL);
1151 if (getNelements(sym->type, sym->ival)>1) {
1152 werror (W_EXCESS_INITIALIZERS, "scalar",
1153 sym->name, sym->lineDef);
1155 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1156 list2expr (sym->ival));
1160 setAstLineno (work, sym->lineDef);
1164 init = newNode (NULLOP, init, work);
1173 /*-----------------------------------------------------------------*/
1174 /* freeStringSymbol - delete a literal string if no more usage */
1175 /*-----------------------------------------------------------------*/
1176 void freeStringSymbol(symbol *sym) {
1177 /* make sure this is a literal string */
1178 assert (sym->isstrlit);
1179 if (--sym->isstrlit == 0) { // lower the usage count
1180 memmap *segment=SPEC_OCLS(sym->etype);
1182 deleteSetItem(&segment->syms, sym);
1187 /*-----------------------------------------------------------------*/
1188 /* stringToSymbol - creates a symbol from a literal string */
1189 /*-----------------------------------------------------------------*/
1191 stringToSymbol (value * val)
1193 char name[SDCC_NAME_MAX + 1];
1194 static int charLbl = 0;
1198 // have we heard this before?
1199 for (sp=statsg->syms; sp; sp=sp->next) {
1201 if (sym->isstrlit &&
1202 !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
1203 // yes, this is old news. Don't publish it again.
1204 sym->isstrlit++; // but raise the usage count
1205 return symbolVal(sym);
1209 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1210 sym = newSymbol (name, 0); /* make it @ level 0 */
1211 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1213 /* copy the type from the value passed */
1214 sym->type = copyLinkChain (val->type);
1215 sym->etype = getSpec (sym->type);
1216 /* change to storage class & output class */
1217 SPEC_SCLS (sym->etype) = S_CODE;
1218 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1219 SPEC_STAT (sym->etype) = 1;
1220 /* make the level & block = 0 */
1221 sym->block = sym->level = 0;
1223 /* create an ival */
1224 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1229 allocVariables (sym);
1232 return symbolVal (sym);
1236 /*-----------------------------------------------------------------*/
1237 /* processBlockVars - will go thru the ast looking for block if */
1238 /* a block is found then will allocate the syms */
1239 /* will also gather the auto inits present */
1240 /*-----------------------------------------------------------------*/
1242 processBlockVars (ast * tree, int *stack, int action)
1247 /* if this is a block */
1248 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1252 if (action == ALLOCATE)
1254 *stack += allocVariables (tree->values.sym);
1255 autoInit = gatherAutoInit (tree->values.sym);
1257 /* if there are auto inits then do them */
1259 tree->left = newNode (NULLOP, autoInit, tree->left);
1261 else /* action is deallocate */
1262 deallocLocal (tree->values.sym);
1265 processBlockVars (tree->left, stack, action);
1266 processBlockVars (tree->right, stack, action);
1271 /*-------------------------------------------------------------*/
1272 /* constExprTree - returns TRUE if this tree is a constant */
1274 /*-------------------------------------------------------------*/
1275 bool constExprTree (ast *cexpr) {
1281 cexpr = decorateType (resolveSymbols (cexpr));
1283 switch (cexpr->type)
1286 if (IS_AST_LIT_VALUE(cexpr)) {
1287 // this is a literal
1290 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1291 // a function's address will never change
1294 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1295 // an array's address will never change
1298 if (IS_AST_SYM_VALUE(cexpr) &&
1299 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1300 // a symbol in code space will never change
1301 // This is only for the 'char *s="hallo"' case and will have to leave
1302 //printf(" code space symbol");
1307 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1308 "unexpected link in expression tree\n");
1311 if (cexpr->opval.op==ARRAYINIT) {
1312 // this is a list of literals
1315 if (cexpr->opval.op=='=') {
1316 return constExprTree(cexpr->right);
1318 if (cexpr->opval.op==CAST) {
1319 // cast ignored, maybe we should throw a warning here?
1320 return constExprTree(cexpr->right);
1322 if (cexpr->opval.op=='&') {
1325 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1328 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1333 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1338 /*-----------------------------------------------------------------*/
1339 /* constExprValue - returns the value of a constant expression */
1340 /* or NULL if it is not a constant expression */
1341 /*-----------------------------------------------------------------*/
1343 constExprValue (ast * cexpr, int check)
1345 cexpr = decorateType (resolveSymbols (cexpr));
1347 /* if this is not a constant then */
1348 if (!IS_LITERAL (cexpr->ftype))
1350 /* then check if this is a literal array
1352 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1353 SPEC_CVAL (cexpr->etype).v_char &&
1354 IS_ARRAY (cexpr->ftype))
1356 value *val = valFromType (cexpr->ftype);
1357 SPEC_SCLS (val->etype) = S_LITERAL;
1358 val->sym = cexpr->opval.val->sym;
1359 val->sym->type = copyLinkChain (cexpr->ftype);
1360 val->sym->etype = getSpec (val->sym->type);
1361 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1365 /* if we are casting a literal value then */
1366 if (IS_AST_OP (cexpr) &&
1367 cexpr->opval.op == CAST &&
1368 IS_LITERAL (cexpr->right->ftype))
1370 return valCastLiteral (cexpr->ftype,
1371 floatFromVal (cexpr->right->opval.val));
1374 if (IS_AST_VALUE (cexpr))
1376 return cexpr->opval.val;
1380 werror (E_CONST_EXPECTED, "found expression");
1385 /* return the value */
1386 return cexpr->opval.val;
1390 /*-----------------------------------------------------------------*/
1391 /* isLabelInAst - will return true if a given label is found */
1392 /*-----------------------------------------------------------------*/
1394 isLabelInAst (symbol * label, ast * tree)
1396 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1399 if (IS_AST_OP (tree) &&
1400 tree->opval.op == LABEL &&
1401 isSymbolEqual (AST_SYMBOL (tree->left), label))
1404 return isLabelInAst (label, tree->right) &&
1405 isLabelInAst (label, tree->left);
1409 /*-----------------------------------------------------------------*/
1410 /* isLoopCountable - return true if the loop count can be determi- */
1411 /* -ned at compile time . */
1412 /*-----------------------------------------------------------------*/
1414 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1415 symbol ** sym, ast ** init, ast ** end)
1418 /* the loop is considered countable if the following
1419 conditions are true :-
1421 a) initExpr :- <sym> = <const>
1422 b) condExpr :- <sym> < <const1>
1423 c) loopExpr :- <sym> ++
1426 /* first check the initExpr */
1427 if (IS_AST_OP (initExpr) &&
1428 initExpr->opval.op == '=' && /* is assignment */
1429 IS_AST_SYM_VALUE (initExpr->left))
1430 { /* left is a symbol */
1432 *sym = AST_SYMBOL (initExpr->left);
1433 *init = initExpr->right;
1438 /* for now the symbol has to be of
1440 if (!IS_INTEGRAL ((*sym)->type))
1443 /* now check condExpr */
1444 if (IS_AST_OP (condExpr))
1447 switch (condExpr->opval.op)
1450 if (IS_AST_SYM_VALUE (condExpr->left) &&
1451 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1452 IS_AST_LIT_VALUE (condExpr->right))
1454 *end = condExpr->right;
1460 if (IS_AST_OP (condExpr->left) &&
1461 condExpr->left->opval.op == '>' &&
1462 IS_AST_LIT_VALUE (condExpr->left->right) &&
1463 IS_AST_SYM_VALUE (condExpr->left->left) &&
1464 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1467 *end = newNode ('+', condExpr->left->right,
1468 newAst_VALUE (constVal ("1")));
1479 /* check loop expression is of the form <sym>++ */
1480 if (!IS_AST_OP (loopExpr))
1483 /* check if <sym> ++ */
1484 if (loopExpr->opval.op == INC_OP)
1490 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1491 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1498 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1499 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1507 if (loopExpr->opval.op == ADD_ASSIGN)
1510 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1511 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1512 IS_AST_LIT_VALUE (loopExpr->right) &&
1513 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1521 /*-----------------------------------------------------------------*/
1522 /* astHasVolatile - returns true if ast contains any volatile */
1523 /*-----------------------------------------------------------------*/
1525 astHasVolatile (ast * tree)
1530 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1533 if (IS_AST_OP (tree))
1534 return astHasVolatile (tree->left) ||
1535 astHasVolatile (tree->right);
1540 /*-----------------------------------------------------------------*/
1541 /* astHasPointer - return true if the ast contains any ptr variable */
1542 /*-----------------------------------------------------------------*/
1544 astHasPointer (ast * tree)
1549 if (IS_AST_LINK (tree))
1552 /* if we hit an array expression then check
1553 only the left side */
1554 if (IS_AST_OP (tree) && tree->opval.op == '[')
1555 return astHasPointer (tree->left);
1557 if (IS_AST_VALUE (tree))
1558 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1560 return astHasPointer (tree->left) ||
1561 astHasPointer (tree->right);
1565 /*-----------------------------------------------------------------*/
1566 /* astHasSymbol - return true if the ast has the given symbol */
1567 /*-----------------------------------------------------------------*/
1569 astHasSymbol (ast * tree, symbol * sym)
1571 if (!tree || IS_AST_LINK (tree))
1574 if (IS_AST_VALUE (tree))
1576 if (IS_AST_SYM_VALUE (tree))
1577 return isSymbolEqual (AST_SYMBOL (tree), sym);
1582 return astHasSymbol (tree->left, sym) ||
1583 astHasSymbol (tree->right, sym);
1586 /*-----------------------------------------------------------------*/
1587 /* astHasDeref - return true if the ast has an indirect access */
1588 /*-----------------------------------------------------------------*/
1590 astHasDeref (ast * tree)
1592 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1595 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1597 return astHasDeref (tree->left) || astHasDeref (tree->right);
1600 /*-----------------------------------------------------------------*/
1601 /* isConformingBody - the loop body has to conform to a set of rules */
1602 /* for the loop to be considered reversible read on for rules */
1603 /*-----------------------------------------------------------------*/
1605 isConformingBody (ast * pbody, symbol * sym, ast * body)
1608 /* we are going to do a pre-order traversal of the
1609 tree && check for the following conditions. (essentially
1610 a set of very shallow tests )
1611 a) the sym passed does not participate in
1612 any arithmetic operation
1613 b) There are no function calls
1614 c) all jumps are within the body
1615 d) address of loop control variable not taken
1616 e) if an assignment has a pointer on the
1617 left hand side make sure right does not have
1618 loop control variable */
1620 /* if we reach the end or a leaf then true */
1621 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1624 /* if anything else is "volatile" */
1625 if (IS_VOLATILE (TETYPE (pbody)))
1628 /* we will walk the body in a pre-order traversal for
1630 switch (pbody->opval.op)
1632 /*------------------------------------------------------------------*/
1634 // if the loopvar is used as an index
1635 if (astHasSymbol(pbody->right, sym)) {
1638 return isConformingBody (pbody->right, sym, body);
1640 /*------------------------------------------------------------------*/
1645 /*------------------------------------------------------------------*/
1649 /* sure we are not sym is not modified */
1651 IS_AST_SYM_VALUE (pbody->left) &&
1652 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1656 IS_AST_SYM_VALUE (pbody->right) &&
1657 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1662 /*------------------------------------------------------------------*/
1664 case '*': /* can be unary : if right is null then unary operation */
1669 /* if right is NULL then unary operation */
1670 /*------------------------------------------------------------------*/
1671 /*----------------------------*/
1673 /*----------------------------*/
1676 if (IS_AST_SYM_VALUE (pbody->left) &&
1677 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1680 return isConformingBody (pbody->left, sym, body);
1684 if (astHasSymbol (pbody->left, sym) ||
1685 astHasSymbol (pbody->right, sym))
1690 /*------------------------------------------------------------------*/
1698 if (IS_AST_SYM_VALUE (pbody->left) &&
1699 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1702 if (IS_AST_SYM_VALUE (pbody->right) &&
1703 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1706 return isConformingBody (pbody->left, sym, body) &&
1707 isConformingBody (pbody->right, sym, body);
1715 if (IS_AST_SYM_VALUE (pbody->left) &&
1716 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1718 return isConformingBody (pbody->left, sym, body);
1720 /*------------------------------------------------------------------*/
1732 case SIZEOF: /* evaluate wihout code generation */
1734 if (IS_AST_SYM_VALUE (pbody->left) &&
1735 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1738 if (IS_AST_SYM_VALUE (pbody->right) &&
1739 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1742 return isConformingBody (pbody->left, sym, body) &&
1743 isConformingBody (pbody->right, sym, body);
1745 /*------------------------------------------------------------------*/
1748 /* if left has a pointer & right has loop
1749 control variable then we cannot */
1750 if (astHasPointer (pbody->left) &&
1751 astHasSymbol (pbody->right, sym))
1753 if (astHasVolatile (pbody->left))
1756 if (IS_AST_SYM_VALUE (pbody->left)) {
1757 // if the loopvar has an assignment
1758 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1760 // if the loopvar is used in another (maybe conditional) block
1761 if (astHasSymbol (pbody->right, sym) &&
1762 (pbody->level >= body->level)) {
1767 if (astHasVolatile (pbody->left))
1770 if (astHasDeref(pbody->right)) return FALSE;
1772 return isConformingBody (pbody->left, sym, body) &&
1773 isConformingBody (pbody->right, sym, body);
1784 assert ("Parser should not have generated this\n");
1786 /*------------------------------------------------------------------*/
1787 /*----------------------------*/
1788 /* comma operator */
1789 /*----------------------------*/
1791 return isConformingBody (pbody->left, sym, body) &&
1792 isConformingBody (pbody->right, sym, body);
1794 /*------------------------------------------------------------------*/
1795 /*----------------------------*/
1797 /*----------------------------*/
1799 /* if local & not passed as paramater then ok */
1800 if (sym->level && !astHasSymbol(pbody->right,sym))
1804 /*------------------------------------------------------------------*/
1805 /*----------------------------*/
1806 /* return statement */
1807 /*----------------------------*/
1812 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1817 if (astHasSymbol (pbody->left, sym))
1824 return isConformingBody (pbody->left, sym, body) &&
1825 isConformingBody (pbody->right, sym, body);
1831 /*-----------------------------------------------------------------*/
1832 /* isLoopReversible - takes a for loop as input && returns true */
1833 /* if the for loop is reversible. If yes will set the value of */
1834 /* the loop control var & init value & termination value */
1835 /*-----------------------------------------------------------------*/
1837 isLoopReversible (ast * loop, symbol ** loopCntrl,
1838 ast ** init, ast ** end)
1840 /* if option says don't do it then don't */
1841 if (optimize.noLoopReverse)
1843 /* there are several tests to determine this */
1845 /* for loop has to be of the form
1846 for ( <sym> = <const1> ;
1847 [<sym> < <const2>] ;
1848 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1850 if (!isLoopCountable (AST_FOR (loop, initExpr),
1851 AST_FOR (loop, condExpr),
1852 AST_FOR (loop, loopExpr),
1853 loopCntrl, init, end))
1856 /* now do some serious checking on the body of the loop
1859 return isConformingBody (loop->left, *loopCntrl, loop->left);
1863 /*-----------------------------------------------------------------*/
1864 /* replLoopSym - replace the loop sym by loop sym -1 */
1865 /*-----------------------------------------------------------------*/
1867 replLoopSym (ast * body, symbol * sym)
1870 if (!body || IS_AST_LINK (body))
1873 if (IS_AST_SYM_VALUE (body))
1876 if (isSymbolEqual (AST_SYMBOL (body), sym))
1880 body->opval.op = '-';
1881 body->left = newAst_VALUE (symbolVal (sym));
1882 body->right = newAst_VALUE (constVal ("1"));
1890 replLoopSym (body->left, sym);
1891 replLoopSym (body->right, sym);
1895 /*-----------------------------------------------------------------*/
1896 /* reverseLoop - do the actual loop reversal */
1897 /*-----------------------------------------------------------------*/
1899 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1903 /* create the following tree
1908 if (sym) goto for_continue ;
1911 /* put it together piece by piece */
1912 rloop = newNode (NULLOP,
1913 createIf (newAst_VALUE (symbolVal (sym)),
1915 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1918 newAst_VALUE (symbolVal (sym)),
1921 replLoopSym (loop->left, sym);
1922 setAstLineno (rloop, init->lineno);
1924 rloop = newNode (NULLOP,
1926 newAst_VALUE (symbolVal (sym)),
1927 newNode ('-', end, init)),
1928 createLabel (AST_FOR (loop, continueLabel),
1932 newNode (SUB_ASSIGN,
1933 newAst_VALUE (symbolVal (sym)),
1934 newAst_VALUE (constVal ("1"))),
1937 rloop->lineno=init->lineno;
1938 return decorateType (rloop);
1942 /*-----------------------------------------------------------------*/
1943 /* searchLitOp - search tree (*ops only) for an ast with literal */
1944 /*-----------------------------------------------------------------*/
1946 searchLitOp (ast *tree, ast **parent, const char *ops)
1950 if (tree && optimize.global_cse)
1952 /* is there a literal operand? */
1954 IS_AST_OP(tree->right) &&
1955 tree->right->right &&
1956 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1958 if (IS_LITERAL (RTYPE (tree->right)) ^
1959 IS_LITERAL (LTYPE (tree->right)))
1961 tree->right->decorated = 0;
1962 tree->decorated = 0;
1966 ret = searchLitOp (tree->right, parent, ops);
1971 IS_AST_OP(tree->left) &&
1972 tree->left->right &&
1973 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1975 if (IS_LITERAL (RTYPE (tree->left)) ^
1976 IS_LITERAL (LTYPE (tree->left)))
1978 tree->left->decorated = 0;
1979 tree->decorated = 0;
1983 ret = searchLitOp (tree->left, parent, ops);
1991 /*-----------------------------------------------------------------*/
1992 /* decorateType - compute type for this tree also does type checking */
1993 /* this is done bottom up, since type have to flow upwards */
1994 /* it also does constant folding, and paramater checking */
1995 /*-----------------------------------------------------------------*/
1997 decorateType (ast * tree)
2005 /* if already has type then do nothing */
2006 if (tree->decorated)
2009 tree->decorated = 1;
2012 /* print the line */
2013 /* if not block & function */
2014 if (tree->type == EX_OP &&
2015 (tree->opval.op != FUNCTION &&
2016 tree->opval.op != BLOCK &&
2017 tree->opval.op != NULLOP))
2019 filename = tree->filename;
2020 lineno = tree->lineno;
2024 /* if any child is an error | this one is an error do nothing */
2025 if (tree->isError ||
2026 (tree->left && tree->left->isError) ||
2027 (tree->right && tree->right->isError))
2030 /*------------------------------------------------------------------*/
2031 /*----------------------------*/
2032 /* leaf has been reached */
2033 /*----------------------------*/
2034 lineno=tree->lineno;
2035 /* if this is of type value */
2036 /* just get the type */
2037 if (tree->type == EX_VALUE)
2040 if (IS_LITERAL (tree->opval.val->etype))
2043 /* if this is a character array then declare it */
2044 if (IS_ARRAY (tree->opval.val->type))
2045 tree->opval.val = stringToSymbol (tree->opval.val);
2047 /* otherwise just copy the type information */
2048 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2052 if (tree->opval.val->sym)
2054 /* if the undefined flag is set then give error message */
2055 if (tree->opval.val->sym->undefined)
2057 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2059 TTYPE (tree) = TETYPE (tree) =
2060 tree->opval.val->type = tree->opval.val->sym->type =
2061 tree->opval.val->etype = tree->opval.val->sym->etype =
2062 copyLinkChain (INTTYPE);
2067 /* if impilicit i.e. struct/union member then no type */
2068 if (tree->opval.val->sym->implicit)
2069 TTYPE (tree) = TETYPE (tree) = NULL;
2074 /* else copy the type */
2075 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2077 /* and mark it as referenced */
2078 tree->opval.val->sym->isref = 1;
2086 /* if type link for the case of cast */
2087 if (tree->type == EX_LINK)
2089 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2096 dtl = decorateType (tree->left);
2097 /* delay right side for '?' operator since conditional macro expansions might
2099 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2101 /* this is to take care of situations
2102 when the tree gets rewritten */
2103 if (dtl != tree->left)
2105 if (dtr != tree->right)
2107 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2110 if (IS_AST_OP(tree) &&
2111 (tree->opval.op == CAST || tree->opval.op == '=') &&
2112 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2113 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2114 // this is a cast/assign to a bigger type
2115 if (IS_AST_OP(tree->right) &&
2116 IS_INTEGRAL(tree->right->ftype) &&
2117 (tree->right->opval.op == LEFT_OP ||
2118 tree->right->opval.op == '*' ||
2119 tree->right->opval.op == '+' ||
2120 tree->right->opval.op == '-') &&
2121 tree->right->right) {
2122 // we should cast an operand instead of the result
2123 tree->right->decorated = 0;
2124 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2126 tree->right = decorateType(tree->right);
2131 /* depending on type of operator do */
2133 switch (tree->opval.op)
2135 /*------------------------------------------------------------------*/
2136 /*----------------------------*/
2138 /*----------------------------*/
2141 /* determine which is the array & which the index */
2142 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2145 ast *tempTree = tree->left;
2146 tree->left = tree->right;
2147 tree->right = tempTree;
2150 /* first check if this is a array or a pointer */
2151 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2153 werror (E_NEED_ARRAY_PTR, "[]");
2154 goto errorTreeReturn;
2157 /* check if the type of the idx */
2158 if (!IS_INTEGRAL (RTYPE (tree)))
2160 werror (E_IDX_NOT_INT);
2161 goto errorTreeReturn;
2164 /* if the left is an rvalue then error */
2167 werror (E_LVALUE_REQUIRED, "array access");
2168 goto errorTreeReturn;
2171 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2174 /*------------------------------------------------------------------*/
2175 /*----------------------------*/
2177 /*----------------------------*/
2179 /* if this is not a structure */
2180 if (!IS_STRUCT (LTYPE (tree)))
2182 werror (E_STRUCT_UNION, ".");
2183 goto errorTreeReturn;
2185 TTYPE (tree) = structElemType (LTYPE (tree),
2186 (tree->right->type == EX_VALUE ?
2187 tree->right->opval.val : NULL));
2188 TETYPE (tree) = getSpec (TTYPE (tree));
2191 /*------------------------------------------------------------------*/
2192 /*----------------------------*/
2193 /* struct/union pointer */
2194 /*----------------------------*/
2196 /* if not pointer to a structure */
2197 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2199 werror (E_PTR_REQD);
2200 goto errorTreeReturn;
2203 if (!IS_STRUCT (LTYPE (tree)->next))
2205 werror (E_STRUCT_UNION, "->");
2206 goto errorTreeReturn;
2209 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2210 (tree->right->type == EX_VALUE ?
2211 tree->right->opval.val : NULL));
2212 TETYPE (tree) = getSpec (TTYPE (tree));
2214 /* adjust the storage class */
2215 switch (DCL_TYPE(tree->left->ftype)) {
2217 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2220 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2223 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2226 SPEC_SCLS (TETYPE (tree)) = 0;
2229 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2232 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2235 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2238 SPEC_SCLS (TETYPE (tree)) = 0;
2245 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2246 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2248 /* If defined struct type at addr var
2249 then rewrite (&struct var)->member
2251 and define membertype at (addr+offsetof(struct var,member)) temp
2254 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2255 AST_SYMBOL(tree->right));
2257 sym = newSymbol(genSymName (0), 0);
2258 sym->type = TTYPE (tree);
2259 sym->etype = getSpec(sym->type);
2260 sym->lineDef = tree->lineno;
2263 SPEC_STAT (sym->etype) = 1;
2264 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2266 SPEC_ABSA(sym->etype) = 1;
2267 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2270 AST_VALUE (tree) = symbolVal(sym);
2273 tree->type = EX_VALUE;
2280 /*------------------------------------------------------------------*/
2281 /*----------------------------*/
2282 /* ++/-- operation */
2283 /*----------------------------*/
2287 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2288 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2289 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2290 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2299 /*------------------------------------------------------------------*/
2300 /*----------------------------*/
2302 /*----------------------------*/
2303 case '&': /* can be unary */
2304 /* if right is NULL then unary operation */
2305 if (tree->right) /* not an unary operation */
2308 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2310 werror (E_BITWISE_OP);
2311 werror (W_CONTINUE, "left & right types are ");
2312 printTypeChain (LTYPE (tree), stderr);
2313 fprintf (stderr, ",");
2314 printTypeChain (RTYPE (tree), stderr);
2315 fprintf (stderr, "\n");
2316 goto errorTreeReturn;
2319 /* if they are both literal */
2320 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2322 tree->type = EX_VALUE;
2323 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2324 valFromType (RETYPE (tree)), '&');
2326 tree->right = tree->left = NULL;
2327 TETYPE (tree) = tree->opval.val->etype;
2328 TTYPE (tree) = tree->opval.val->type;
2332 /* see if this is a GETHBIT operation if yes
2335 ast *otree = optimizeGetHbit (tree);
2338 return decorateType (otree);
2342 computeType (LTYPE (tree), RTYPE (tree));
2343 TETYPE (tree) = getSpec (TTYPE (tree));
2345 /* if left is a literal exchange left & right */
2346 if (IS_LITERAL (LTYPE (tree)))
2348 ast *tTree = tree->left;
2349 tree->left = tree->right;
2350 tree->right = tTree;
2353 /* if right is a literal and */
2354 /* we can find a 2nd literal in a and-tree then */
2355 /* rearrange the tree */
2356 if (IS_LITERAL (RTYPE (tree)))
2359 ast *litTree = searchLitOp (tree, &parent, "&");
2362 ast *tTree = litTree->left;
2363 litTree->left = tree->right;
2364 tree->right = tTree;
2365 /* both operands in tTree are literal now */
2366 decorateType (parent);
2370 LRVAL (tree) = RRVAL (tree) = 1;
2374 /*------------------------------------------------------------------*/
2375 /*----------------------------*/
2377 /*----------------------------*/
2378 p = newLink (DECLARATOR);
2379 /* if bit field then error */
2380 if (IS_BITVAR (tree->left->etype))
2382 werror (E_ILLEGAL_ADDR, "address of bit variable");
2383 goto errorTreeReturn;
2386 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2388 werror (E_ILLEGAL_ADDR, "address of register variable");
2389 goto errorTreeReturn;
2392 if (IS_FUNC (LTYPE (tree)))
2394 // this ought to be ignored
2395 return (tree->left);
2398 if (IS_LITERAL(LTYPE(tree)))
2400 werror (E_ILLEGAL_ADDR, "address of literal");
2401 goto errorTreeReturn;
2406 werror (E_LVALUE_REQUIRED, "address of");
2407 goto errorTreeReturn;
2409 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2410 DCL_TYPE (p) = CPOINTER;
2411 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2412 DCL_TYPE (p) = FPOINTER;
2413 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2414 DCL_TYPE (p) = PPOINTER;
2415 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2416 DCL_TYPE (p) = IPOINTER;
2417 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2418 DCL_TYPE (p) = EEPPOINTER;
2419 else if (SPEC_OCLS(tree->left->etype))
2420 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2422 DCL_TYPE (p) = POINTER;
2424 if (IS_AST_SYM_VALUE (tree->left))
2426 AST_SYMBOL (tree->left)->addrtaken = 1;
2427 AST_SYMBOL (tree->left)->allocreq = 1;
2430 p->next = LTYPE (tree);
2432 TETYPE (tree) = getSpec (TTYPE (tree));
2437 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2438 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2440 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2441 AST_SYMBOL(tree->left->right));
2442 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2443 valueFromLit(element->offset));
2446 tree->type = EX_VALUE;
2447 tree->values.literalFromCast = 1;
2453 /*------------------------------------------------------------------*/
2454 /*----------------------------*/
2456 /*----------------------------*/
2458 /* if the rewrite succeeds then don't go any furthur */
2460 ast *wtree = optimizeRRCRLC (tree);
2462 return decorateType (wtree);
2464 wtree = optimizeSWAP (tree);
2466 return decorateType (wtree);
2471 /* if left is a literal exchange left & right */
2472 if (IS_LITERAL (LTYPE (tree)))
2474 ast *tTree = tree->left;
2475 tree->left = tree->right;
2476 tree->right = tTree;
2479 /* if right is a literal and */
2480 /* we can find a 2nd literal in a or-tree then */
2481 /* rearrange the tree */
2482 if (IS_LITERAL (RTYPE (tree)))
2485 ast *litTree = searchLitOp (tree, &parent, "|");
2488 ast *tTree = litTree->left;
2489 litTree->left = tree->right;
2490 tree->right = tTree;
2491 /* both operands in tTree are literal now */
2492 decorateType (parent);
2495 /*------------------------------------------------------------------*/
2496 /*----------------------------*/
2498 /*----------------------------*/
2500 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2502 werror (E_BITWISE_OP);
2503 werror (W_CONTINUE, "left & right types are ");
2504 printTypeChain (LTYPE (tree), stderr);
2505 fprintf (stderr, ",");
2506 printTypeChain (RTYPE (tree), stderr);
2507 fprintf (stderr, "\n");
2508 goto errorTreeReturn;
2511 /* if they are both literal then */
2512 /* rewrite the tree */
2513 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2515 tree->type = EX_VALUE;
2516 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2517 valFromType (RETYPE (tree)),
2519 tree->right = tree->left = NULL;
2520 TETYPE (tree) = tree->opval.val->etype;
2521 TTYPE (tree) = tree->opval.val->type;
2525 /* if left is a literal exchange left & right */
2526 if (IS_LITERAL (LTYPE (tree)))
2528 ast *tTree = tree->left;
2529 tree->left = tree->right;
2530 tree->right = tTree;
2533 /* if right is a literal and */
2534 /* we can find a 2nd literal in a xor-tree then */
2535 /* rearrange the tree */
2536 if (IS_LITERAL (RTYPE (tree)))
2539 ast *litTree = searchLitOp (tree, &parent, "^");
2542 ast *tTree = litTree->left;
2543 litTree->left = tree->right;
2544 tree->right = tTree;
2545 /* both operands in litTree are literal now */
2546 decorateType (parent);
2550 LRVAL (tree) = RRVAL (tree) = 1;
2551 TETYPE (tree) = getSpec (TTYPE (tree) =
2552 computeType (LTYPE (tree),
2555 /*------------------------------------------------------------------*/
2556 /*----------------------------*/
2558 /*----------------------------*/
2560 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2562 werror (E_INVALID_OP, "divide");
2563 goto errorTreeReturn;
2565 /* if they are both literal then */
2566 /* rewrite the tree */
2567 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2569 tree->type = EX_VALUE;
2570 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2571 valFromType (RETYPE (tree)));
2572 tree->right = tree->left = NULL;
2573 TETYPE (tree) = getSpec (TTYPE (tree) =
2574 tree->opval.val->type);
2578 LRVAL (tree) = RRVAL (tree) = 1;
2579 TETYPE (tree) = getSpec (TTYPE (tree) =
2580 computeType (LTYPE (tree),
2583 /* if right is a literal and */
2584 /* left is also a division by a literal then */
2585 /* rearrange the tree */
2586 if (IS_LITERAL (RTYPE (tree))
2587 /* avoid infinite loop */
2588 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2591 ast *litTree = searchLitOp (tree, &parent, "/");
2594 if (IS_LITERAL (RTYPE (litTree)))
2597 litTree->right = newNode ('*', litTree->right, tree->right);
2598 litTree->right->lineno = tree->lineno;
2600 tree->right->opval.val = constVal ("1");
2601 decorateType (parent);
2605 /* litTree->left is literal: no gcse possible.
2606 We can't call decorateType(parent), because
2607 this would cause an infinit loop. */
2608 parent->decorated = 1;
2609 decorateType (litTree);
2616 /*------------------------------------------------------------------*/
2617 /*----------------------------*/
2619 /*----------------------------*/
2621 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2623 werror (E_BITWISE_OP);
2624 werror (W_CONTINUE, "left & right types are ");
2625 printTypeChain (LTYPE (tree), stderr);
2626 fprintf (stderr, ",");
2627 printTypeChain (RTYPE (tree), stderr);
2628 fprintf (stderr, "\n");
2629 goto errorTreeReturn;
2631 /* if they are both literal then */
2632 /* rewrite the tree */
2633 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2635 tree->type = EX_VALUE;
2636 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2637 valFromType (RETYPE (tree)));
2638 tree->right = tree->left = NULL;
2639 TETYPE (tree) = getSpec (TTYPE (tree) =
2640 tree->opval.val->type);
2643 LRVAL (tree) = RRVAL (tree) = 1;
2644 TETYPE (tree) = getSpec (TTYPE (tree) =
2645 computeType (LTYPE (tree),
2649 /*------------------------------------------------------------------*/
2650 /*----------------------------*/
2651 /* address dereference */
2652 /*----------------------------*/
2653 case '*': /* can be unary : if right is null then unary operation */
2656 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2658 werror (E_PTR_REQD);
2659 goto errorTreeReturn;
2664 werror (E_LVALUE_REQUIRED, "pointer deref");
2665 goto errorTreeReturn;
2667 if (IS_ADDRESS_OF_OP(tree->left))
2669 /* replace *&obj with obj */
2670 return tree->left->left;
2672 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2673 TETYPE (tree) = getSpec (TTYPE (tree));
2674 /* adjust the storage class */
2675 switch (DCL_TYPE(tree->left->ftype)) {
2677 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2680 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2683 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2686 SPEC_SCLS (TETYPE (tree)) = 0;
2689 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2692 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2695 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2698 SPEC_SCLS (TETYPE (tree)) = 0;
2707 /*------------------------------------------------------------------*/
2708 /*----------------------------*/
2709 /* multiplication */
2710 /*----------------------------*/
2711 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2713 werror (E_INVALID_OP, "multiplication");
2714 goto errorTreeReturn;
2717 /* if they are both literal then */
2718 /* rewrite the tree */
2719 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2721 tree->type = EX_VALUE;
2722 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2723 valFromType (RETYPE (tree)));
2724 tree->right = tree->left = NULL;
2725 TETYPE (tree) = getSpec (TTYPE (tree) =
2726 tree->opval.val->type);
2730 /* if left is a literal exchange left & right */
2731 if (IS_LITERAL (LTYPE (tree)))
2733 ast *tTree = tree->left;
2734 tree->left = tree->right;
2735 tree->right = tTree;
2738 /* if right is a literal and */
2739 /* we can find a 2nd literal in a mul-tree then */
2740 /* rearrange the tree */
2741 if (IS_LITERAL (RTYPE (tree)))
2744 ast *litTree = searchLitOp (tree, &parent, "*");
2747 ast *tTree = litTree->left;
2748 litTree->left = tree->right;
2749 tree->right = tTree;
2750 /* both operands in litTree are literal now */
2751 decorateType (parent);
2755 LRVAL (tree) = RRVAL (tree) = 1;
2756 TETYPE (tree) = getSpec (TTYPE (tree) =
2757 computeType (LTYPE (tree),
2760 /* promote result to int if left & right are char
2761 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2762 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2763 SPEC_NOUN(TETYPE(tree)) = V_INT;
2768 /*------------------------------------------------------------------*/
2769 /*----------------------------*/
2770 /* unary '+' operator */
2771 /*----------------------------*/
2776 if (!IS_INTEGRAL (LTYPE (tree)))
2778 werror (E_UNARY_OP, '+');
2779 goto errorTreeReturn;
2782 /* if left is a literal then do it */
2783 if (IS_LITERAL (LTYPE (tree)))
2785 tree->type = EX_VALUE;
2786 tree->opval.val = valFromType (LETYPE (tree));
2788 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2792 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2796 /*------------------------------------------------------------------*/
2797 /*----------------------------*/
2799 /*----------------------------*/
2801 /* this is not a unary operation */
2802 /* if both pointers then problem */
2803 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2804 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2806 werror (E_PTR_PLUS_PTR);
2807 goto errorTreeReturn;
2810 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2811 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2813 werror (E_PLUS_INVALID, "+");
2814 goto errorTreeReturn;
2817 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2818 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2820 werror (E_PLUS_INVALID, "+");
2821 goto errorTreeReturn;
2823 /* if they are both literal then */
2824 /* rewrite the tree */
2825 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2827 tree->type = EX_VALUE;
2828 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2829 valFromType (RETYPE (tree)));
2830 tree->right = tree->left = NULL;
2831 TETYPE (tree) = getSpec (TTYPE (tree) =
2832 tree->opval.val->type);
2836 /* if the right is a pointer or left is a literal
2837 xchange left & right */
2838 if (IS_ARRAY (RTYPE (tree)) ||
2839 IS_PTR (RTYPE (tree)) ||
2840 IS_LITERAL (LTYPE (tree)))
2842 ast *tTree = tree->left;
2843 tree->left = tree->right;
2844 tree->right = tTree;
2847 /* if right is a literal and */
2848 /* left is also an addition/subtraction with a literal then */
2849 /* rearrange the tree */
2850 if (IS_LITERAL (RTYPE (tree)))
2852 ast *litTree, *parent;
2853 litTree = searchLitOp (tree, &parent, "+-");
2856 if (litTree->opval.op == '+')
2859 ast *tTree = litTree->left;
2860 litTree->left = tree->right;
2861 tree->right = tree->left;
2864 else if (litTree->opval.op == '-')
2866 if (IS_LITERAL (RTYPE (litTree)))
2869 ast *tTree = litTree->left;
2870 litTree->left = tree->right;
2871 tree->right = tTree;
2876 ast *tTree = litTree->right;
2877 litTree->right = tree->right;
2878 tree->right = tTree;
2879 litTree->opval.op = '+';
2880 tree->opval.op = '-';
2883 decorateType (parent);
2887 LRVAL (tree) = RRVAL (tree) = 1;
2888 /* if the left is a pointer */
2889 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2890 TETYPE (tree) = getSpec (TTYPE (tree) =
2893 TETYPE (tree) = getSpec (TTYPE (tree) =
2894 computeType (LTYPE (tree),
2898 /*------------------------------------------------------------------*/
2899 /*----------------------------*/
2901 /*----------------------------*/
2902 case '-': /* can be unary */
2903 /* if right is null then unary */
2907 if (!IS_ARITHMETIC (LTYPE (tree)))
2909 werror (E_UNARY_OP, tree->opval.op);
2910 goto errorTreeReturn;
2913 /* if left is a literal then do it */
2914 if (IS_LITERAL (LTYPE (tree)))
2916 tree->type = EX_VALUE;
2917 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2919 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2920 SPEC_USIGN(TETYPE(tree)) = 0;
2924 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2928 /*------------------------------------------------------------------*/
2929 /*----------------------------*/
2931 /*----------------------------*/
2933 if (!(IS_PTR (LTYPE (tree)) ||
2934 IS_ARRAY (LTYPE (tree)) ||
2935 IS_ARITHMETIC (LTYPE (tree))))
2937 werror (E_PLUS_INVALID, "-");
2938 goto errorTreeReturn;
2941 if (!(IS_PTR (RTYPE (tree)) ||
2942 IS_ARRAY (RTYPE (tree)) ||
2943 IS_ARITHMETIC (RTYPE (tree))))
2945 werror (E_PLUS_INVALID, "-");
2946 goto errorTreeReturn;
2949 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2950 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2951 IS_INTEGRAL (RTYPE (tree))))
2953 werror (E_PLUS_INVALID, "-");
2954 goto errorTreeReturn;
2957 /* if they are both literal then */
2958 /* rewrite the tree */
2959 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2961 tree->type = EX_VALUE;
2962 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2963 valFromType (RETYPE (tree)));
2964 tree->right = tree->left = NULL;
2965 TETYPE (tree) = getSpec (TTYPE (tree) =
2966 tree->opval.val->type);
2970 /* if the left & right are equal then zero */
2971 if (isAstEqual (tree->left, tree->right))
2973 tree->type = EX_VALUE;
2974 tree->left = tree->right = NULL;
2975 tree->opval.val = constVal ("0");
2976 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2980 /* if both of them are pointers or arrays then */
2981 /* the result is going to be an integer */
2982 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2983 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2984 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2986 /* if only the left is a pointer */
2987 /* then result is a pointer */
2988 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2989 TETYPE (tree) = getSpec (TTYPE (tree) =
2992 TETYPE (tree) = getSpec (TTYPE (tree) =
2993 computeType (LTYPE (tree),
2996 LRVAL (tree) = RRVAL (tree) = 1;
2998 /* if right is a literal and */
2999 /* left is also an addition/subtraction with a literal then */
3000 /* rearrange the tree */
3001 if (IS_LITERAL (RTYPE (tree))
3002 /* avoid infinite loop */
3003 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3005 ast *litTree, *litParent;
3006 litTree = searchLitOp (tree, &litParent, "+-");
3009 if (litTree->opval.op == '+')
3012 litTree->right = newNode ('-', litTree->right, tree->right);
3013 litTree->right->lineno = tree->lineno;
3015 tree->right->opval.val = constVal ("0");
3017 else if (litTree->opval.op == '-')
3019 if (IS_LITERAL (RTYPE (litTree)))
3022 litTree->right = newNode ('+', tree->right, litTree->right);
3023 litTree->right->lineno = tree->lineno;
3025 tree->right->opval.val = constVal ("0");
3030 ast *tTree = litTree->right;
3031 litTree->right = tree->right;
3032 tree->right = tTree;
3035 decorateType (litParent);
3040 /*------------------------------------------------------------------*/
3041 /*----------------------------*/
3043 /*----------------------------*/
3045 /* can be only integral type */
3046 if (!IS_INTEGRAL (LTYPE (tree)))
3048 werror (E_UNARY_OP, tree->opval.op);
3049 goto errorTreeReturn;
3052 /* if left is a literal then do it */
3053 if (IS_LITERAL (LTYPE (tree)))
3055 tree->type = EX_VALUE;
3056 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3058 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3062 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3068 /*----------------------------*/
3070 /* can be pointer */
3071 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3072 !IS_PTR (LTYPE (tree)) &&
3073 !IS_ARRAY (LTYPE (tree)))
3075 werror (E_UNARY_OP, tree->opval.op);
3076 goto errorTreeReturn;
3079 /* if left is a literal then do it */
3080 if (IS_LITERAL (LTYPE (tree)))
3082 tree->type = EX_VALUE;
3083 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3085 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3089 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3092 /*------------------------------------------------------------------*/
3093 /*----------------------------*/
3095 /*----------------------------*/
3099 TTYPE (tree) = LTYPE (tree);
3100 TETYPE (tree) = LETYPE (tree);
3104 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3109 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3111 werror (E_SHIFT_OP_INVALID);
3112 werror (W_CONTINUE, "left & right types are ");
3113 printTypeChain (LTYPE (tree), stderr);
3114 fprintf (stderr, ",");
3115 printTypeChain (RTYPE (tree), stderr);
3116 fprintf (stderr, "\n");
3117 goto errorTreeReturn;
3120 /* if they are both literal then */
3121 /* rewrite the tree */
3122 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3124 tree->type = EX_VALUE;
3125 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3126 valFromType (RETYPE (tree)),
3127 (tree->opval.op == LEFT_OP ? 1 : 0));
3128 tree->right = tree->left = NULL;
3129 TETYPE (tree) = getSpec (TTYPE (tree) =
3130 tree->opval.val->type);
3134 /* if only the right side is a literal & we are
3135 shifting more than size of the left operand then zero */
3136 if (IS_LITERAL (RTYPE (tree)) &&
3137 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3138 (getSize (LTYPE (tree)) * 8))
3140 if (tree->opval.op==LEFT_OP ||
3141 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3142 lineno=tree->lineno;
3143 werror (W_SHIFT_CHANGED,
3144 (tree->opval.op == LEFT_OP ? "left" : "right"));
3145 tree->type = EX_VALUE;
3146 tree->left = tree->right = NULL;
3147 tree->opval.val = constVal ("0");
3148 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3152 LRVAL (tree) = RRVAL (tree) = 1;
3153 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3154 if (IS_LITERAL (TTYPE (tree)))
3155 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3158 /*------------------------------------------------------------------*/
3159 /*----------------------------*/
3161 /*----------------------------*/
3162 case CAST: /* change the type */
3163 /* cannot cast to an aggregate type */
3164 if (IS_AGGREGATE (LTYPE (tree)))
3166 werror (E_CAST_ILLEGAL);
3167 goto errorTreeReturn;
3170 /* make sure the type is complete and sane */
3171 checkTypeSanity(LETYPE(tree), "(cast)");
3174 /* if the right is a literal replace the tree */
3175 if (IS_LITERAL (RETYPE (tree))) {
3176 if (!IS_PTR (LTYPE (tree))) {
3177 tree->type = EX_VALUE;
3179 valCastLiteral (LTYPE (tree),
3180 floatFromVal (valFromType (RETYPE (tree))));
3183 TTYPE (tree) = tree->opval.val->type;
3184 tree->values.literalFromCast = 1;
3185 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3186 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3187 sym_link *rest = LTYPE(tree)->next;
3188 werror(W_LITERAL_GENERIC);
3189 TTYPE(tree) = newLink(DECLARATOR);
3190 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3191 TTYPE(tree)->next = rest;
3192 tree->left->opval.lnk = TTYPE(tree);
3195 TTYPE (tree) = LTYPE (tree);
3199 TTYPE (tree) = LTYPE (tree);
3203 #if 0 // this is already checked, now this could be explicit
3204 /* if pointer to struct then check names */
3205 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3206 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3207 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3209 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3210 SPEC_STRUCT(LETYPE(tree))->tag);
3213 if (IS_ADDRESS_OF_OP(tree->right)
3214 && IS_AST_SYM_VALUE (tree->right->left)
3215 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3217 tree->type = EX_VALUE;
3219 valCastLiteral (LTYPE (tree),
3220 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3221 TTYPE (tree) = tree->opval.val->type;
3222 TETYPE (tree) = getSpec (TTYPE (tree));
3225 tree->values.literalFromCast = 1;
3229 /* handle offsetof macro: */
3230 /* #define offsetof(TYPE, MEMBER) \ */
3231 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3232 if (IS_ADDRESS_OF_OP(tree->right)
3233 && IS_AST_OP (tree->right->left)
3234 && tree->right->left->opval.op == PTR_OP
3235 && IS_AST_OP (tree->right->left->left)
3236 && tree->right->left->left->opval.op == CAST
3237 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3239 symbol *element = getStructElement (
3240 SPEC_STRUCT (LETYPE(tree->right->left)),
3241 AST_SYMBOL(tree->right->left->right)
3245 tree->type = EX_VALUE;
3246 tree->opval.val = valCastLiteral (
3249 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3252 TTYPE (tree) = tree->opval.val->type;
3253 TETYPE (tree) = getSpec (TTYPE (tree));
3260 /* if the right is a literal replace the tree */
3261 if (IS_LITERAL (RETYPE (tree))) {
3262 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3263 /* rewrite (type *)litaddr
3265 and define type at litaddr temp
3266 (but only if type's storage class is not generic)
3268 ast *newTree = newNode ('&', NULL, NULL);
3271 TTYPE (newTree) = LTYPE (tree);
3272 TETYPE (newTree) = getSpec(LTYPE (tree));
3274 /* define a global symbol at the casted address*/
3275 sym = newSymbol(genSymName (0), 0);
3276 sym->type = LTYPE (tree)->next;
3278 sym->type = newLink (V_VOID);
3279 sym->etype = getSpec(sym->type);
3280 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3281 sym->lineDef = tree->lineno;
3284 SPEC_STAT (sym->etype) = 1;
3285 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3286 SPEC_ABSA(sym->etype) = 1;
3287 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3290 newTree->left = newAst_VALUE(symbolVal(sym));
3291 newTree->left->lineno = tree->lineno;
3292 LTYPE (newTree) = sym->type;
3293 LETYPE (newTree) = sym->etype;
3294 LLVAL (newTree) = 1;
3295 LRVAL (newTree) = 0;
3296 TLVAL (newTree) = 1;
3299 if (!IS_PTR (LTYPE (tree))) {
3300 tree->type = EX_VALUE;
3302 valCastLiteral (LTYPE (tree),
3303 floatFromVal (valFromType (RETYPE (tree))));
3304 TTYPE (tree) = tree->opval.val->type;
3307 tree->values.literalFromCast = 1;
3308 TETYPE (tree) = getSpec (TTYPE (tree));
3312 TTYPE (tree) = LTYPE (tree);
3316 TETYPE (tree) = getSpec (TTYPE (tree));
3320 /*------------------------------------------------------------------*/
3321 /*----------------------------*/
3322 /* logical &&, || */
3323 /*----------------------------*/
3326 /* each must me arithmetic type or be a pointer */
3327 if (!IS_PTR (LTYPE (tree)) &&
3328 !IS_ARRAY (LTYPE (tree)) &&
3329 !IS_INTEGRAL (LTYPE (tree)))
3331 werror (E_COMPARE_OP);
3332 goto errorTreeReturn;
3335 if (!IS_PTR (RTYPE (tree)) &&
3336 !IS_ARRAY (RTYPE (tree)) &&
3337 !IS_INTEGRAL (RTYPE (tree)))
3339 werror (E_COMPARE_OP);
3340 goto errorTreeReturn;
3342 /* if they are both literal then */
3343 /* rewrite the tree */
3344 if (IS_LITERAL (RTYPE (tree)) &&
3345 IS_LITERAL (LTYPE (tree)))
3347 tree->type = EX_VALUE;
3348 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3349 valFromType (RETYPE (tree)),
3351 tree->right = tree->left = NULL;
3352 TETYPE (tree) = getSpec (TTYPE (tree) =
3353 tree->opval.val->type);
3356 LRVAL (tree) = RRVAL (tree) = 1;
3357 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3360 /*------------------------------------------------------------------*/
3361 /*----------------------------*/
3362 /* comparison operators */
3363 /*----------------------------*/
3371 ast *lt = optimizeCompare (tree);
3377 /* if they are pointers they must be castable */
3378 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3380 if (tree->opval.op==EQ_OP &&
3381 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3382 // we cannot cast a gptr to a !gptr: switch the leaves
3383 struct ast *s=tree->left;
3384 tree->left=tree->right;
3387 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3389 werror (E_COMPARE_OP);
3390 fprintf (stderr, "comparring type ");
3391 printTypeChain (LTYPE (tree), stderr);
3392 fprintf (stderr, "to type ");
3393 printTypeChain (RTYPE (tree), stderr);
3394 fprintf (stderr, "\n");
3395 goto errorTreeReturn;
3398 /* else they should be promotable to one another */
3401 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3402 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3404 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3406 werror (E_COMPARE_OP);
3407 fprintf (stderr, "comparing type ");
3408 printTypeChain (LTYPE (tree), stderr);
3409 fprintf (stderr, "to type ");
3410 printTypeChain (RTYPE (tree), stderr);
3411 fprintf (stderr, "\n");
3412 goto errorTreeReturn;
3415 /* if unsigned value < 0 then always false */
3416 /* if (unsigned value) > 0 then (unsigned value) */
3417 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3418 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3420 if (tree->opval.op == '<') {
3423 if (tree->opval.op == '>') {
3427 /* if they are both literal then */
3428 /* rewrite the tree */
3429 if (IS_LITERAL (RTYPE (tree)) &&
3430 IS_LITERAL (LTYPE (tree)))
3432 tree->type = EX_VALUE;
3433 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3434 valFromType (RETYPE (tree)),
3436 tree->right = tree->left = NULL;
3437 TETYPE (tree) = getSpec (TTYPE (tree) =
3438 tree->opval.val->type);
3441 LRVAL (tree) = RRVAL (tree) = 1;
3442 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3445 /*------------------------------------------------------------------*/
3446 /*----------------------------*/
3448 /*----------------------------*/
3449 case SIZEOF: /* evaluate wihout code generation */
3450 /* change the type to a integer */
3451 tree->type = EX_VALUE;
3452 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3453 tree->opval.val = constVal (buffer);
3454 tree->right = tree->left = NULL;
3455 TETYPE (tree) = getSpec (TTYPE (tree) =
3456 tree->opval.val->type);
3459 /*------------------------------------------------------------------*/
3460 /*----------------------------*/
3462 /*----------------------------*/
3464 /* return typeof enum value */
3465 tree->type = EX_VALUE;
3468 if (IS_SPEC(tree->right->ftype)) {
3469 switch (SPEC_NOUN(tree->right->ftype)) {
3471 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3472 else typeofv = TYPEOF_INT;
3475 typeofv = TYPEOF_FLOAT;
3478 typeofv = TYPEOF_CHAR;
3481 typeofv = TYPEOF_VOID;
3484 typeofv = TYPEOF_STRUCT;
3487 typeofv = TYPEOF_BITFIELD;
3490 typeofv = TYPEOF_BIT;
3493 typeofv = TYPEOF_SBIT;
3499 switch (DCL_TYPE(tree->right->ftype)) {
3501 typeofv = TYPEOF_POINTER;
3504 typeofv = TYPEOF_FPOINTER;
3507 typeofv = TYPEOF_CPOINTER;
3510 typeofv = TYPEOF_GPOINTER;
3513 typeofv = TYPEOF_PPOINTER;
3516 typeofv = TYPEOF_IPOINTER;
3519 typeofv = TYPEOF_ARRAY;
3522 typeofv = TYPEOF_FUNCTION;
3528 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3529 tree->opval.val = constVal (buffer);
3530 tree->right = tree->left = NULL;
3531 TETYPE (tree) = getSpec (TTYPE (tree) =
3532 tree->opval.val->type);
3535 /*------------------------------------------------------------------*/
3536 /*----------------------------*/
3537 /* conditional operator '?' */
3538 /*----------------------------*/
3540 /* the type is value of the colon operator (on the right) */
3541 assert(IS_COLON_OP(tree->right));
3542 /* if already known then replace the tree : optimizer will do it
3543 but faster to do it here */
3544 if (IS_LITERAL (LTYPE(tree))) {
3545 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3546 return decorateType(tree->right->left) ;
3548 return decorateType(tree->right->right) ;
3551 tree->right = decorateType(tree->right);
3552 TTYPE (tree) = RTYPE(tree);
3553 TETYPE (tree) = getSpec (TTYPE (tree));
3558 /* if they don't match we have a problem */
3559 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3561 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3562 goto errorTreeReturn;
3565 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3566 TETYPE (tree) = getSpec (TTYPE (tree));
3570 #if 0 // assignment operators are converted by the parser
3571 /*------------------------------------------------------------------*/
3572 /*----------------------------*/
3573 /* assignment operators */
3574 /*----------------------------*/
3577 /* for these it must be both must be integral */
3578 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3579 !IS_ARITHMETIC (RTYPE (tree)))
3581 werror (E_OPS_INTEGRAL);
3582 goto errorTreeReturn;
3585 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3587 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3588 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3592 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3593 goto errorTreeReturn;
3604 /* for these it must be both must be integral */
3605 if (!IS_INTEGRAL (LTYPE (tree)) ||
3606 !IS_INTEGRAL (RTYPE (tree)))
3608 werror (E_OPS_INTEGRAL);
3609 goto errorTreeReturn;
3612 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3614 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3615 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3619 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3620 goto errorTreeReturn;
3626 /*------------------------------------------------------------------*/
3627 /*----------------------------*/
3629 /*----------------------------*/
3631 if (!(IS_PTR (LTYPE (tree)) ||
3632 IS_ARITHMETIC (LTYPE (tree))))
3634 werror (E_PLUS_INVALID, "-=");
3635 goto errorTreeReturn;
3638 if (!(IS_PTR (RTYPE (tree)) ||
3639 IS_ARITHMETIC (RTYPE (tree))))
3641 werror (E_PLUS_INVALID, "-=");
3642 goto errorTreeReturn;
3645 TETYPE (tree) = getSpec (TTYPE (tree) =
3646 computeType (LTYPE (tree),
3649 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3650 werror (E_CODE_WRITE, "-=");
3654 werror (E_LVALUE_REQUIRED, "-=");
3655 goto errorTreeReturn;
3661 /*------------------------------------------------------------------*/
3662 /*----------------------------*/
3664 /*----------------------------*/
3666 /* this is not a unary operation */
3667 /* if both pointers then problem */
3668 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3670 werror (E_PTR_PLUS_PTR);
3671 goto errorTreeReturn;
3674 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3676 werror (E_PLUS_INVALID, "+=");
3677 goto errorTreeReturn;
3680 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3682 werror (E_PLUS_INVALID, "+=");
3683 goto errorTreeReturn;
3686 TETYPE (tree) = getSpec (TTYPE (tree) =
3687 computeType (LTYPE (tree),
3690 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3691 werror (E_CODE_WRITE, "+=");
3695 werror (E_LVALUE_REQUIRED, "+=");
3696 goto errorTreeReturn;
3699 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3700 tree->opval.op = '=';
3705 /*------------------------------------------------------------------*/
3706 /*----------------------------*/
3707 /* straight assignemnt */
3708 /*----------------------------*/
3710 /* cannot be an aggregate */
3711 if (IS_AGGREGATE (LTYPE (tree)))
3713 werror (E_AGGR_ASSIGN);
3714 goto errorTreeReturn;
3717 /* they should either match or be castable */
3718 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3720 werror (E_TYPE_MISMATCH, "assignment", " ");
3721 printFromToType(RTYPE(tree),LTYPE(tree));
3724 /* if the left side of the tree is of type void
3725 then report error */
3726 if (IS_VOID (LTYPE (tree)))
3728 werror (E_CAST_ZERO);
3729 printFromToType(RTYPE(tree), LTYPE(tree));
3732 TETYPE (tree) = getSpec (TTYPE (tree) =
3736 if (!tree->initMode ) {
3737 if (IS_CONSTANT(LTYPE(tree)))
3738 werror (E_CODE_WRITE, "=");
3742 werror (E_LVALUE_REQUIRED, "=");
3743 goto errorTreeReturn;
3748 /*------------------------------------------------------------------*/
3749 /*----------------------------*/
3750 /* comma operator */
3751 /*----------------------------*/
3753 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3756 /*------------------------------------------------------------------*/
3757 /*----------------------------*/
3759 /*----------------------------*/
3763 if (processParms (tree->left,
3764 FUNC_ARGS(tree->left->ftype),
3765 tree->right, &parmNumber, TRUE)) {
3766 goto errorTreeReturn;
3769 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3770 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3772 reverseParms (tree->right);
3775 if (IS_CODEPTR(LTYPE(tree))) {
3776 TTYPE(tree) = LTYPE(tree)->next->next;
3778 TTYPE(tree) = LTYPE(tree)->next;
3780 TETYPE (tree) = getSpec (TTYPE (tree));
3783 /*------------------------------------------------------------------*/
3784 /*----------------------------*/
3785 /* return statement */
3786 /*----------------------------*/
3791 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3793 werror (W_RETURN_MISMATCH);
3794 printFromToType (RTYPE(tree), currFunc->type->next);
3795 goto errorTreeReturn;
3798 if (IS_VOID (currFunc->type->next)
3800 !IS_VOID (RTYPE (tree)))
3802 werror (E_FUNC_VOID);
3803 goto errorTreeReturn;
3806 /* if there is going to be a casing required then add it */
3807 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3810 decorateType (newNode (CAST,
3811 newAst_LINK (copyLinkChain (currFunc->type->next)),
3820 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3822 werror (W_VOID_FUNC, currFunc->name);
3823 goto errorTreeReturn;
3826 TTYPE (tree) = TETYPE (tree) = NULL;
3829 /*------------------------------------------------------------------*/
3830 /*----------------------------*/
3831 /* switch statement */
3832 /*----------------------------*/
3834 /* the switch value must be an integer */
3835 if (!IS_INTEGRAL (LTYPE (tree)))
3837 werror (E_SWITCH_NON_INTEGER);
3838 goto errorTreeReturn;
3841 TTYPE (tree) = TETYPE (tree) = NULL;
3844 /*------------------------------------------------------------------*/
3845 /*----------------------------*/
3847 /*----------------------------*/
3849 tree->left = backPatchLabels (tree->left,
3852 TTYPE (tree) = TETYPE (tree) = NULL;
3855 /*------------------------------------------------------------------*/
3856 /*----------------------------*/
3858 /*----------------------------*/
3861 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3862 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3863 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3865 /* if the for loop is reversible then
3866 reverse it otherwise do what we normally
3872 if (isLoopReversible (tree, &sym, &init, &end))
3873 return reverseLoop (tree, sym, init, end);
3875 return decorateType (createFor (AST_FOR (tree, trueLabel),
3876 AST_FOR (tree, continueLabel),
3877 AST_FOR (tree, falseLabel),
3878 AST_FOR (tree, condLabel),
3879 AST_FOR (tree, initExpr),
3880 AST_FOR (tree, condExpr),
3881 AST_FOR (tree, loopExpr),
3885 TTYPE (tree) = TETYPE (tree) = NULL;
3889 /* some error found this tree will be killed */
3891 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3892 tree->opval.op = NULLOP;
3898 /*-----------------------------------------------------------------*/
3899 /* sizeofOp - processes size of operation */
3900 /*-----------------------------------------------------------------*/
3902 sizeofOp (sym_link * type)
3906 /* make sure the type is complete and sane */
3907 checkTypeSanity(type, "(sizeof)");
3909 /* get the size and convert it to character */
3910 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3912 /* now convert into value */
3913 return constVal (buff);
3917 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3918 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3919 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3920 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3921 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3922 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3923 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3925 /*-----------------------------------------------------------------*/
3926 /* backPatchLabels - change and or not operators to flow control */
3927 /*-----------------------------------------------------------------*/
3929 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3935 if (!(IS_ANDORNOT (tree)))
3938 /* if this an and */
3941 static int localLbl = 0;
3944 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3945 localLabel = newSymbol (buffer, NestLevel);
3947 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3949 /* if left is already a IFX then just change the if true label in that */
3950 if (!IS_IFX (tree->left))
3951 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3953 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3954 /* right is a IFX then just join */
3955 if (IS_IFX (tree->right))
3956 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3958 tree->right = createLabel (localLabel, tree->right);
3959 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3961 return newNode (NULLOP, tree->left, tree->right);
3964 /* if this is an or operation */
3967 static int localLbl = 0;
3970 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3971 localLabel = newSymbol (buffer, NestLevel);
3973 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3975 /* if left is already a IFX then just change the if true label in that */
3976 if (!IS_IFX (tree->left))
3977 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3979 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3980 /* right is a IFX then just join */
3981 if (IS_IFX (tree->right))
3982 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3984 tree->right = createLabel (localLabel, tree->right);
3985 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3987 return newNode (NULLOP, tree->left, tree->right);
3993 int wasnot = IS_NOT (tree->left);
3994 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3996 /* if the left is already a IFX */
3997 if (!IS_IFX (tree->left))
3998 tree->left = newNode (IFX, tree->left, NULL);
4002 tree->left->trueLabel = trueLabel;
4003 tree->left->falseLabel = falseLabel;
4007 tree->left->trueLabel = falseLabel;
4008 tree->left->falseLabel = trueLabel;
4015 tree->trueLabel = trueLabel;
4016 tree->falseLabel = falseLabel;
4023 /*-----------------------------------------------------------------*/
4024 /* createBlock - create expression tree for block */
4025 /*-----------------------------------------------------------------*/
4027 createBlock (symbol * decl, ast * body)
4031 /* if the block has nothing */
4035 ex = newNode (BLOCK, NULL, body);
4036 ex->values.sym = decl;
4038 ex->right = ex->right;
4044 /*-----------------------------------------------------------------*/
4045 /* createLabel - creates the expression tree for labels */
4046 /*-----------------------------------------------------------------*/
4048 createLabel (symbol * label, ast * stmnt)
4051 char name[SDCC_NAME_MAX + 1];
4054 /* must create fresh symbol if the symbol name */
4055 /* exists in the symbol table, since there can */
4056 /* be a variable with the same name as the labl */
4057 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4058 (csym->level == label->level))
4059 label = newSymbol (label->name, label->level);
4061 /* change the name before putting it in add _ */
4062 SNPRINTF(name, sizeof(name), "%s", label->name);
4064 /* put the label in the LabelSymbol table */
4065 /* but first check if a label of the same */
4067 if ((csym = findSym (LabelTab, NULL, name)))
4068 werror (E_DUPLICATE_LABEL, label->name);
4070 addSym (LabelTab, label, name, label->level, 0, 0);
4073 label->key = labelKey++;
4074 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4080 /*-----------------------------------------------------------------*/
4081 /* createCase - generates the parsetree for a case statement */
4082 /*-----------------------------------------------------------------*/
4084 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4086 char caseLbl[SDCC_NAME_MAX + 1];
4090 /* if the switch statement does not exist */
4091 /* then case is out of context */
4094 werror (E_CASE_CONTEXT);
4098 caseVal = decorateType (resolveSymbols (caseVal));
4099 /* if not a constant then error */
4100 if (!IS_LITERAL (caseVal->ftype))
4102 werror (E_CASE_CONSTANT);
4106 /* if not a integer than error */
4107 if (!IS_INTEGRAL (caseVal->ftype))
4109 werror (E_CASE_NON_INTEGER);
4113 /* find the end of the switch values chain */
4114 if (!(val = swStat->values.switchVals.swVals))
4115 swStat->values.switchVals.swVals = caseVal->opval.val;
4118 /* also order the cases according to value */
4120 int cVal = (int) floatFromVal (caseVal->opval.val);
4121 while (val && (int) floatFromVal (val) < cVal)
4127 /* if we reached the end then */
4130 pval->next = caseVal->opval.val;
4134 /* we found a value greater than */
4135 /* the current value we must add this */
4136 /* before the value */
4137 caseVal->opval.val->next = val;
4139 /* if this was the first in chain */
4140 if (swStat->values.switchVals.swVals == val)
4141 swStat->values.switchVals.swVals =
4144 pval->next = caseVal->opval.val;
4149 /* create the case label */
4150 SNPRINTF(caseLbl, sizeof(caseLbl),
4152 swStat->values.switchVals.swNum,
4153 (int) floatFromVal (caseVal->opval.val));
4155 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4160 /*-----------------------------------------------------------------*/
4161 /* createDefault - creates the parse tree for the default statement */
4162 /*-----------------------------------------------------------------*/
4164 createDefault (ast * swStat, ast * stmnt)
4166 char defLbl[SDCC_NAME_MAX + 1];
4168 /* if the switch statement does not exist */
4169 /* then case is out of context */
4172 werror (E_CASE_CONTEXT);
4176 /* turn on the default flag */
4177 swStat->values.switchVals.swDefault = 1;
4179 /* create the label */
4180 SNPRINTF (defLbl, sizeof(defLbl),
4181 "_default_%d", swStat->values.switchVals.swNum);
4182 return createLabel (newSymbol (defLbl, 0), stmnt);
4185 /*-----------------------------------------------------------------*/
4186 /* createIf - creates the parsetree for the if statement */
4187 /*-----------------------------------------------------------------*/
4189 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4191 static int Lblnum = 0;
4193 symbol *ifTrue, *ifFalse, *ifEnd;
4195 /* if neither exists */
4196 if (!elseBody && !ifBody) {
4197 // if there are no side effects (i++, j() etc)
4198 if (!hasSEFcalls(condAst)) {
4203 /* create the labels */
4204 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4205 ifFalse = newSymbol (buffer, NestLevel);
4206 /* if no else body then end == false */
4211 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4212 ifEnd = newSymbol (buffer, NestLevel);
4215 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4216 ifTrue = newSymbol (buffer, NestLevel);
4220 /* attach the ifTrue label to the top of it body */
4221 ifBody = createLabel (ifTrue, ifBody);
4222 /* attach a goto end to the ifBody if else is present */
4225 ifBody = newNode (NULLOP, ifBody,
4227 newAst_VALUE (symbolVal (ifEnd)),
4229 /* put the elseLabel on the else body */
4230 elseBody = createLabel (ifFalse, elseBody);
4231 /* out the end at the end of the body */
4232 elseBody = newNode (NULLOP,
4234 createLabel (ifEnd, NULL));
4238 ifBody = newNode (NULLOP, ifBody,
4239 createLabel (ifFalse, NULL));
4241 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4242 if (IS_IFX (condAst))
4245 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4247 return newNode (NULLOP, ifTree,
4248 newNode (NULLOP, ifBody, elseBody));
4252 /*-----------------------------------------------------------------*/
4253 /* createDo - creates parse tree for do */
4256 /* _docontinue_n: */
4257 /* condition_expression +-> trueLabel -> _dobody_n */
4259 /* +-> falseLabel-> _dobreak_n */
4261 /*-----------------------------------------------------------------*/
4263 createDo (symbol * trueLabel, symbol * continueLabel,
4264 symbol * falseLabel, ast * condAst, ast * doBody)
4269 /* if the body does not exist then it is simple */
4272 condAst = backPatchLabels (condAst, continueLabel, NULL);
4273 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4274 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4275 doTree->trueLabel = continueLabel;
4276 doTree->falseLabel = NULL;
4280 /* otherwise we have a body */
4281 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4283 /* attach the body label to the top */
4284 doBody = createLabel (trueLabel, doBody);
4285 /* attach the continue label to end of body */
4286 doBody = newNode (NULLOP, doBody,
4287 createLabel (continueLabel, NULL));
4289 /* now put the break label at the end */
4290 if (IS_IFX (condAst))
4293 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4295 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4297 /* putting it together */
4298 return newNode (NULLOP, doBody, doTree);
4301 /*-----------------------------------------------------------------*/
4302 /* createFor - creates parse tree for 'for' statement */
4305 /* condExpr +-> trueLabel -> _forbody_n */
4307 /* +-> falseLabel-> _forbreak_n */
4310 /* _forcontinue_n: */
4312 /* goto _forcond_n ; */
4314 /*-----------------------------------------------------------------*/
4316 createFor (symbol * trueLabel, symbol * continueLabel,
4317 symbol * falseLabel, symbol * condLabel,
4318 ast * initExpr, ast * condExpr, ast * loopExpr,
4323 /* if loopexpression not present then we can generate it */
4324 /* the same way as a while */
4326 return newNode (NULLOP, initExpr,
4327 createWhile (trueLabel, continueLabel,
4328 falseLabel, condExpr, forBody));
4329 /* vanilla for statement */
4330 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4332 if (condExpr && !IS_IFX (condExpr))
4333 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4336 /* attach condition label to condition */
4337 condExpr = createLabel (condLabel, condExpr);
4339 /* attach body label to body */
4340 forBody = createLabel (trueLabel, forBody);
4342 /* attach continue to forLoop expression & attach */
4343 /* goto the forcond @ and of loopExpression */
4344 loopExpr = createLabel (continueLabel,
4348 newAst_VALUE (symbolVal (condLabel)),
4350 /* now start putting them together */
4351 forTree = newNode (NULLOP, initExpr, condExpr);
4352 forTree = newNode (NULLOP, forTree, forBody);
4353 forTree = newNode (NULLOP, forTree, loopExpr);
4354 /* finally add the break label */
4355 forTree = newNode (NULLOP, forTree,
4356 createLabel (falseLabel, NULL));
4360 /*-----------------------------------------------------------------*/
4361 /* createWhile - creates parse tree for while statement */
4362 /* the while statement will be created as follows */
4364 /* _while_continue_n: */
4365 /* condition_expression +-> trueLabel -> _while_boby_n */
4367 /* +-> falseLabel -> _while_break_n */
4368 /* _while_body_n: */
4370 /* goto _while_continue_n */
4371 /* _while_break_n: */
4372 /*-----------------------------------------------------------------*/
4374 createWhile (symbol * trueLabel, symbol * continueLabel,
4375 symbol * falseLabel, ast * condExpr, ast * whileBody)
4379 /* put the continue label */
4380 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4381 condExpr = createLabel (continueLabel, condExpr);
4382 condExpr->lineno = 0;
4384 /* put the body label in front of the body */
4385 whileBody = createLabel (trueLabel, whileBody);
4386 whileBody->lineno = 0;
4387 /* put a jump to continue at the end of the body */
4388 /* and put break label at the end of the body */
4389 whileBody = newNode (NULLOP,
4392 newAst_VALUE (symbolVal (continueLabel)),
4393 createLabel (falseLabel, NULL)));
4395 /* put it all together */
4396 if (IS_IFX (condExpr))
4397 whileTree = condExpr;
4400 whileTree = newNode (IFX, condExpr, NULL);
4401 /* put the true & false labels in place */
4402 whileTree->trueLabel = trueLabel;
4403 whileTree->falseLabel = falseLabel;
4406 return newNode (NULLOP, whileTree, whileBody);
4409 /*-----------------------------------------------------------------*/
4410 /* optimizeGetHbit - get highest order bit of the expression */
4411 /*-----------------------------------------------------------------*/
4413 optimizeGetHbit (ast * tree)
4416 /* if this is not a bit and */
4417 if (!IS_BITAND (tree))
4420 /* will look for tree of the form
4421 ( expr >> ((sizeof expr) -1) ) & 1 */
4422 if (!IS_AST_LIT_VALUE (tree->right))
4425 if (AST_LIT_VALUE (tree->right) != 1)
4428 if (!IS_RIGHT_OP (tree->left))
4431 if (!IS_AST_LIT_VALUE (tree->left->right))
4434 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4435 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4438 /* make sure the port supports GETHBIT */
4439 if (port->hasExtBitOp
4440 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4443 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4447 /*-----------------------------------------------------------------*/
4448 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4449 /*-----------------------------------------------------------------*/
4451 optimizeRRCRLC (ast * root)
4453 /* will look for trees of the form
4454 (?expr << 1) | (?expr >> 7) or
4455 (?expr >> 7) | (?expr << 1) will make that
4456 into a RLC : operation ..
4458 (?expr >> 1) | (?expr << 7) or
4459 (?expr << 7) | (?expr >> 1) will make that
4460 into a RRC operation
4461 note : by 7 I mean (number of bits required to hold the
4463 /* if the root operations is not a | operation the not */
4464 if (!IS_BITOR (root))
4467 /* I have to think of a better way to match patterns this sucks */
4468 /* that aside let start looking for the first case : I use a the
4469 negative check a lot to improve the efficiency */
4470 /* (?expr << 1) | (?expr >> 7) */
4471 if (IS_LEFT_OP (root->left) &&
4472 IS_RIGHT_OP (root->right))
4475 if (!SPEC_USIGN (TETYPE (root->left->left)))
4478 if (!IS_AST_LIT_VALUE (root->left->right) ||
4479 !IS_AST_LIT_VALUE (root->right->right))
4482 /* make sure it is the same expression */
4483 if (!isAstEqual (root->left->left,
4487 if (AST_LIT_VALUE (root->left->right) != 1)
4490 if (AST_LIT_VALUE (root->right->right) !=
4491 (getSize (TTYPE (root->left->left)) * 8 - 1))
4494 /* make sure the port supports RLC */
4495 if (port->hasExtBitOp
4496 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4499 /* whew got the first case : create the AST */
4500 return newNode (RLC, root->left->left, NULL);
4504 /* check for second case */
4505 /* (?expr >> 7) | (?expr << 1) */
4506 if (IS_LEFT_OP (root->right) &&
4507 IS_RIGHT_OP (root->left))
4510 if (!SPEC_USIGN (TETYPE (root->left->left)))
4513 if (!IS_AST_LIT_VALUE (root->left->right) ||
4514 !IS_AST_LIT_VALUE (root->right->right))
4517 /* make sure it is the same symbol */
4518 if (!isAstEqual (root->left->left,
4522 if (AST_LIT_VALUE (root->right->right) != 1)
4525 if (AST_LIT_VALUE (root->left->right) !=
4526 (getSize (TTYPE (root->left->left)) * 8 - 1))
4529 /* make sure the port supports RLC */
4530 if (port->hasExtBitOp
4531 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4534 /* whew got the first case : create the AST */
4535 return newNode (RLC, root->left->left, NULL);
4540 /* third case for RRC */
4541 /* (?symbol >> 1) | (?symbol << 7) */
4542 if (IS_LEFT_OP (root->right) &&
4543 IS_RIGHT_OP (root->left))
4546 if (!SPEC_USIGN (TETYPE (root->left->left)))
4549 if (!IS_AST_LIT_VALUE (root->left->right) ||
4550 !IS_AST_LIT_VALUE (root->right->right))
4553 /* make sure it is the same symbol */
4554 if (!isAstEqual (root->left->left,
4558 if (AST_LIT_VALUE (root->left->right) != 1)
4561 if (AST_LIT_VALUE (root->right->right) !=
4562 (getSize (TTYPE (root->left->left)) * 8 - 1))
4565 /* make sure the port supports RRC */
4566 if (port->hasExtBitOp
4567 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4570 /* whew got the first case : create the AST */
4571 return newNode (RRC, root->left->left, NULL);
4575 /* fourth and last case for now */
4576 /* (?symbol << 7) | (?symbol >> 1) */
4577 if (IS_RIGHT_OP (root->right) &&
4578 IS_LEFT_OP (root->left))
4581 if (!SPEC_USIGN (TETYPE (root->left->left)))
4584 if (!IS_AST_LIT_VALUE (root->left->right) ||
4585 !IS_AST_LIT_VALUE (root->right->right))
4588 /* make sure it is the same symbol */
4589 if (!isAstEqual (root->left->left,
4593 if (AST_LIT_VALUE (root->right->right) != 1)
4596 if (AST_LIT_VALUE (root->left->right) !=
4597 (getSize (TTYPE (root->left->left)) * 8 - 1))
4600 /* make sure the port supports RRC */
4601 if (port->hasExtBitOp
4602 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4605 /* whew got the first case : create the AST */
4606 return newNode (RRC, root->left->left, NULL);
4610 /* not found return root */
4614 /*-----------------------------------------------------------------*/
4615 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4616 /*-----------------------------------------------------------------*/
4618 optimizeSWAP (ast * root)
4620 /* will look for trees of the form
4621 (?expr << 4) | (?expr >> 4) or
4622 (?expr >> 4) | (?expr << 4) will make that
4623 into a SWAP : operation ..
4624 note : by 4 I mean (number of bits required to hold the
4626 /* if the root operations is not a | operation the not */
4627 if (!IS_BITOR (root))
4630 /* (?expr << 4) | (?expr >> 4) */
4631 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4632 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4635 if (!SPEC_USIGN (TETYPE (root->left->left)))
4638 if (!IS_AST_LIT_VALUE (root->left->right) ||
4639 !IS_AST_LIT_VALUE (root->right->right))
4642 /* make sure it is the same expression */
4643 if (!isAstEqual (root->left->left,
4647 if (AST_LIT_VALUE (root->left->right) !=
4648 (getSize (TTYPE (root->left->left)) * 4))
4651 if (AST_LIT_VALUE (root->right->right) !=
4652 (getSize (TTYPE (root->left->left)) * 4))
4655 /* make sure the port supports SWAP */
4656 if (port->hasExtBitOp
4657 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4660 /* found it : create the AST */
4661 return newNode (SWAP, root->left->left, NULL);
4665 /* not found return root */
4669 /*-----------------------------------------------------------------*/
4670 /* optimizeCompare - otimizes compares for bit variables */
4671 /*-----------------------------------------------------------------*/
4673 optimizeCompare (ast * root)
4675 ast *optExpr = NULL;
4678 unsigned int litValue;
4680 /* if nothing then return nothing */
4684 /* if not a compare op then do leaves */
4685 if (!IS_COMPARE_OP (root))
4687 root->left = optimizeCompare (root->left);
4688 root->right = optimizeCompare (root->right);
4692 /* if left & right are the same then depending
4693 of the operation do */
4694 if (isAstEqual (root->left, root->right))
4696 switch (root->opval.op)
4701 optExpr = newAst_VALUE (constVal ("0"));
4706 optExpr = newAst_VALUE (constVal ("1"));
4710 return decorateType (optExpr);
4713 vleft = (root->left->type == EX_VALUE ?
4714 root->left->opval.val : NULL);
4716 vright = (root->right->type == EX_VALUE ?
4717 root->right->opval.val : NULL);
4719 /* if left is a BITVAR in BITSPACE */
4720 /* and right is a LITERAL then opt- */
4721 /* imize else do nothing */
4722 if (vleft && vright &&
4723 IS_BITVAR (vleft->etype) &&
4724 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4725 IS_LITERAL (vright->etype))
4728 /* if right side > 1 then comparison may never succeed */
4729 if ((litValue = (int) floatFromVal (vright)) > 1)
4731 werror (W_BAD_COMPARE);
4737 switch (root->opval.op)
4739 case '>': /* bit value greater than 1 cannot be */
4740 werror (W_BAD_COMPARE);
4744 case '<': /* bit value < 1 means 0 */
4746 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4749 case LE_OP: /* bit value <= 1 means no check */
4750 optExpr = newAst_VALUE (vright);
4753 case GE_OP: /* bit value >= 1 means only check for = */
4755 optExpr = newAst_VALUE (vleft);
4760 { /* literal is zero */
4761 switch (root->opval.op)
4763 case '<': /* bit value < 0 cannot be */
4764 werror (W_BAD_COMPARE);
4768 case '>': /* bit value > 0 means 1 */
4770 optExpr = newAst_VALUE (vleft);
4773 case LE_OP: /* bit value <= 0 means no check */
4774 case GE_OP: /* bit value >= 0 means no check */
4775 werror (W_BAD_COMPARE);
4779 case EQ_OP: /* bit == 0 means ! of bit */
4780 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4784 return decorateType (resolveSymbols (optExpr));
4785 } /* end-of-if of BITVAR */
4790 /*-----------------------------------------------------------------*/
4791 /* addSymToBlock : adds the symbol to the first block we find */
4792 /*-----------------------------------------------------------------*/
4794 addSymToBlock (symbol * sym, ast * tree)
4796 /* reached end of tree or a leaf */
4797 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4801 if (IS_AST_OP (tree) &&
4802 tree->opval.op == BLOCK)
4805 symbol *lsym = copySymbol (sym);
4807 lsym->next = AST_VALUES (tree, sym);
4808 AST_VALUES (tree, sym) = lsym;
4812 addSymToBlock (sym, tree->left);
4813 addSymToBlock (sym, tree->right);
4816 /*-----------------------------------------------------------------*/
4817 /* processRegParms - do processing for register parameters */
4818 /*-----------------------------------------------------------------*/
4820 processRegParms (value * args, ast * body)
4824 if (IS_REGPARM (args->etype))
4825 addSymToBlock (args->sym, body);
4830 /*-----------------------------------------------------------------*/
4831 /* resetParmKey - resets the operandkeys for the symbols */
4832 /*-----------------------------------------------------------------*/
4833 DEFSETFUNC (resetParmKey)
4844 /*-----------------------------------------------------------------*/
4845 /* createFunction - This is the key node that calls the iCode for */
4846 /* generating the code for a function. Note code */
4847 /* is generated function by function, later when */
4848 /* add inter-procedural analysis this will change */
4849 /*-----------------------------------------------------------------*/
4851 createFunction (symbol * name, ast * body)
4857 iCode *piCode = NULL;
4859 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4860 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4862 /* if check function return 0 then some problem */
4863 if (checkFunction (name, NULL) == 0)
4866 /* create a dummy block if none exists */
4868 body = newNode (BLOCK, NULL, NULL);
4872 /* check if the function name already in the symbol table */
4873 if ((csym = findSym (SymbolTab, NULL, name->name)))
4876 /* special case for compiler defined functions
4877 we need to add the name to the publics list : this
4878 actually means we are now compiling the compiler
4882 addSet (&publics, name);
4888 allocVariables (name);
4890 name->lastLine = mylineno;
4893 /* set the stack pointer */
4894 /* PENDING: check this for the mcs51 */
4895 stackPtr = -port->stack.direction * port->stack.call_overhead;
4896 if (IFFUNC_ISISR (name->type))
4897 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4898 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4899 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4901 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4903 fetype = getSpec (name->type); /* get the specifier for the function */
4904 /* if this is a reentrant function then */
4905 if (IFFUNC_ISREENT (name->type))
4908 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4910 /* do processing for parameters that are passed in registers */
4911 processRegParms (FUNC_ARGS(name->type), body);
4913 /* set the stack pointer */
4917 /* allocate & autoinit the block variables */
4918 processBlockVars (body, &stack, ALLOCATE);
4920 /* save the stack information */
4921 if (options.useXstack)
4922 name->xstack = SPEC_STAK (fetype) = stack;
4924 name->stack = SPEC_STAK (fetype) = stack;
4926 /* name needs to be mangled */
4927 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4929 body = resolveSymbols (body); /* resolve the symbols */
4930 body = decorateType (body); /* propagateType & do semantic checks */
4932 ex = newAst_VALUE (symbolVal (name)); /* create name */
4933 ex = newNode (FUNCTION, ex, body);
4934 ex->values.args = FUNC_ARGS(name->type);
4936 if (options.dump_tree) PA(ex);
4939 werror (E_FUNC_NO_CODE, name->name);
4943 /* create the node & generate intermediate code */
4945 codeOutFile = code->oFile;
4946 piCode = iCodeFromAst (ex);
4950 werror (E_FUNC_NO_CODE, name->name);
4954 eBBlockFromiCode (piCode);
4956 /* if there are any statics then do them */
4959 GcurMemmap = statsg;
4960 codeOutFile = statsg->oFile;
4961 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4967 /* dealloc the block variables */
4968 processBlockVars (body, &stack, DEALLOCATE);
4969 outputDebugStackSymbols();
4970 /* deallocate paramaters */
4971 deallocParms (FUNC_ARGS(name->type));
4973 if (IFFUNC_ISREENT (name->type))
4976 /* we are done freeup memory & cleanup */
4978 if (port->reset_labelKey) labelKey = 1;
4980 FUNC_HASBODY(name->type) = 1;
4981 addSet (&operKeyReset, name);
4982 applyToSet (operKeyReset, resetParmKey);
4987 cleanUpLevel (LabelTab, 0);
4988 cleanUpBlock (StructTab, 1);
4989 cleanUpBlock (TypedefTab, 1);
4991 xstack->syms = NULL;
4992 istack->syms = NULL;
4997 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4998 /*-----------------------------------------------------------------*/
4999 /* ast_print : prints the ast (for debugging purposes) */
5000 /*-----------------------------------------------------------------*/
5002 void ast_print (ast * tree, FILE *outfile, int indent)
5007 /* can print only decorated trees */
5008 if (!tree->decorated) return;
5010 /* if any child is an error | this one is an error do nothing */
5011 if (tree->isError ||
5012 (tree->left && tree->left->isError) ||
5013 (tree->right && tree->right->isError)) {
5014 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5018 /* print the line */
5019 /* if not block & function */
5020 if (tree->type == EX_OP &&
5021 (tree->opval.op != FUNCTION &&
5022 tree->opval.op != BLOCK &&
5023 tree->opval.op != NULLOP)) {
5026 if (tree->opval.op == FUNCTION) {
5028 value *args=FUNC_ARGS(tree->left->opval.val->type);
5029 fprintf(outfile,"FUNCTION (%s=%p) type (",
5030 tree->left->opval.val->name, tree);
5031 printTypeChain (tree->left->opval.val->type->next,outfile);
5032 fprintf(outfile,") args (");
5035 fprintf (outfile, ", ");
5037 printTypeChain (args ? args->type : NULL, outfile);
5039 args= args ? args->next : NULL;
5041 fprintf(outfile,")\n");
5042 ast_print(tree->left,outfile,indent);
5043 ast_print(tree->right,outfile,indent);
5046 if (tree->opval.op == BLOCK) {
5047 symbol *decls = tree->values.sym;
5048 INDENT(indent,outfile);
5049 fprintf(outfile,"{\n");
5051 INDENT(indent+2,outfile);
5052 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5053 decls->name, decls);
5054 printTypeChain(decls->type,outfile);
5055 fprintf(outfile,")\n");
5057 decls = decls->next;
5059 ast_print(tree->right,outfile,indent+2);
5060 INDENT(indent,outfile);
5061 fprintf(outfile,"}\n");
5064 if (tree->opval.op == NULLOP) {
5065 ast_print(tree->left,outfile,indent);
5066 ast_print(tree->right,outfile,indent);
5069 INDENT(indent,outfile);
5071 /*------------------------------------------------------------------*/
5072 /*----------------------------*/
5073 /* leaf has been reached */
5074 /*----------------------------*/
5075 /* if this is of type value */
5076 /* just get the type */
5077 if (tree->type == EX_VALUE) {
5079 if (IS_LITERAL (tree->opval.val->etype)) {
5080 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5081 if (SPEC_USIGN (tree->opval.val->etype))
5082 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5084 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5085 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5086 floatFromVal(tree->opval.val));
5087 } else if (tree->opval.val->sym) {
5088 /* if the undefined flag is set then give error message */
5089 if (tree->opval.val->sym->undefined) {
5090 fprintf(outfile,"UNDEFINED SYMBOL ");
5092 fprintf(outfile,"SYMBOL ");
5094 fprintf(outfile,"(%s=%p)",
5095 tree->opval.val->sym->name,tree);
5098 fprintf(outfile," type (");
5099 printTypeChain(tree->ftype,outfile);
5100 fprintf(outfile,")\n");
5102 fprintf(outfile,"\n");
5107 /* if type link for the case of cast */
5108 if (tree->type == EX_LINK) {
5109 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5110 printTypeChain(tree->opval.lnk,outfile);
5111 fprintf(outfile,")\n");
5116 /* depending on type of operator do */
5118 switch (tree->opval.op) {
5119 /*------------------------------------------------------------------*/
5120 /*----------------------------*/
5122 /*----------------------------*/
5124 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5125 printTypeChain(tree->ftype,outfile);
5126 fprintf(outfile,")\n");
5127 ast_print(tree->left,outfile,indent+2);
5128 ast_print(tree->right,outfile,indent+2);
5131 /*------------------------------------------------------------------*/
5132 /*----------------------------*/
5134 /*----------------------------*/
5136 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5137 printTypeChain(tree->ftype,outfile);
5138 fprintf(outfile,")\n");
5139 ast_print(tree->left,outfile,indent+2);
5140 ast_print(tree->right,outfile,indent+2);
5143 /*------------------------------------------------------------------*/
5144 /*----------------------------*/
5145 /* struct/union pointer */
5146 /*----------------------------*/
5148 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5149 printTypeChain(tree->ftype,outfile);
5150 fprintf(outfile,")\n");
5151 ast_print(tree->left,outfile,indent+2);
5152 ast_print(tree->right,outfile,indent+2);
5155 /*------------------------------------------------------------------*/
5156 /*----------------------------*/
5157 /* ++/-- operation */
5158 /*----------------------------*/
5161 fprintf(outfile,"post-");
5163 fprintf(outfile,"pre-");
5164 fprintf(outfile,"INC_OP (%p) type (",tree);
5165 printTypeChain(tree->ftype,outfile);
5166 fprintf(outfile,")\n");
5167 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5168 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5173 fprintf(outfile,"post-");
5175 fprintf(outfile,"pre-");
5176 fprintf(outfile,"DEC_OP (%p) type (",tree);
5177 printTypeChain(tree->ftype,outfile);
5178 fprintf(outfile,")\n");
5179 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5180 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5183 /*------------------------------------------------------------------*/
5184 /*----------------------------*/
5186 /*----------------------------*/
5189 fprintf(outfile,"& (%p) type (",tree);
5190 printTypeChain(tree->ftype,outfile);
5191 fprintf(outfile,")\n");
5192 ast_print(tree->left,outfile,indent+2);
5193 ast_print(tree->right,outfile,indent+2);
5195 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5196 printTypeChain(tree->ftype,outfile);
5197 fprintf(outfile,")\n");
5198 ast_print(tree->left,outfile,indent+2);
5199 ast_print(tree->right,outfile,indent+2);
5202 /*----------------------------*/
5204 /*----------------------------*/
5206 fprintf(outfile,"OR (%p) type (",tree);
5207 printTypeChain(tree->ftype,outfile);
5208 fprintf(outfile,")\n");
5209 ast_print(tree->left,outfile,indent+2);
5210 ast_print(tree->right,outfile,indent+2);
5212 /*------------------------------------------------------------------*/
5213 /*----------------------------*/
5215 /*----------------------------*/
5217 fprintf(outfile,"XOR (%p) type (",tree);
5218 printTypeChain(tree->ftype,outfile);
5219 fprintf(outfile,")\n");
5220 ast_print(tree->left,outfile,indent+2);
5221 ast_print(tree->right,outfile,indent+2);
5224 /*------------------------------------------------------------------*/
5225 /*----------------------------*/
5227 /*----------------------------*/
5229 fprintf(outfile,"DIV (%p) type (",tree);
5230 printTypeChain(tree->ftype,outfile);
5231 fprintf(outfile,")\n");
5232 ast_print(tree->left,outfile,indent+2);
5233 ast_print(tree->right,outfile,indent+2);
5235 /*------------------------------------------------------------------*/
5236 /*----------------------------*/
5238 /*----------------------------*/
5240 fprintf(outfile,"MOD (%p) type (",tree);
5241 printTypeChain(tree->ftype,outfile);
5242 fprintf(outfile,")\n");
5243 ast_print(tree->left,outfile,indent+2);
5244 ast_print(tree->right,outfile,indent+2);
5247 /*------------------------------------------------------------------*/
5248 /*----------------------------*/
5249 /* address dereference */
5250 /*----------------------------*/
5251 case '*': /* can be unary : if right is null then unary operation */
5253 fprintf(outfile,"DEREF (%p) type (",tree);
5254 printTypeChain(tree->ftype,outfile);
5255 fprintf(outfile,")\n");
5256 ast_print(tree->left,outfile,indent+2);
5259 /*------------------------------------------------------------------*/
5260 /*----------------------------*/
5261 /* multiplication */
5262 /*----------------------------*/
5263 fprintf(outfile,"MULT (%p) type (",tree);
5264 printTypeChain(tree->ftype,outfile);
5265 fprintf(outfile,")\n");
5266 ast_print(tree->left,outfile,indent+2);
5267 ast_print(tree->right,outfile,indent+2);
5271 /*------------------------------------------------------------------*/
5272 /*----------------------------*/
5273 /* unary '+' operator */
5274 /*----------------------------*/
5278 fprintf(outfile,"UPLUS (%p) type (",tree);
5279 printTypeChain(tree->ftype,outfile);
5280 fprintf(outfile,")\n");
5281 ast_print(tree->left,outfile,indent+2);
5283 /*------------------------------------------------------------------*/
5284 /*----------------------------*/
5286 /*----------------------------*/
5287 fprintf(outfile,"ADD (%p) type (",tree);
5288 printTypeChain(tree->ftype,outfile);
5289 fprintf(outfile,")\n");
5290 ast_print(tree->left,outfile,indent+2);
5291 ast_print(tree->right,outfile,indent+2);
5294 /*------------------------------------------------------------------*/
5295 /*----------------------------*/
5297 /*----------------------------*/
5298 case '-': /* can be unary */
5300 fprintf(outfile,"UMINUS (%p) type (",tree);
5301 printTypeChain(tree->ftype,outfile);
5302 fprintf(outfile,")\n");
5303 ast_print(tree->left,outfile,indent+2);
5305 /*------------------------------------------------------------------*/
5306 /*----------------------------*/
5308 /*----------------------------*/
5309 fprintf(outfile,"SUB (%p) type (",tree);
5310 printTypeChain(tree->ftype,outfile);
5311 fprintf(outfile,")\n");
5312 ast_print(tree->left,outfile,indent+2);
5313 ast_print(tree->right,outfile,indent+2);
5316 /*------------------------------------------------------------------*/
5317 /*----------------------------*/
5319 /*----------------------------*/
5321 fprintf(outfile,"COMPL (%p) type (",tree);
5322 printTypeChain(tree->ftype,outfile);
5323 fprintf(outfile,")\n");
5324 ast_print(tree->left,outfile,indent+2);
5326 /*------------------------------------------------------------------*/
5327 /*----------------------------*/
5329 /*----------------------------*/
5331 fprintf(outfile,"NOT (%p) type (",tree);
5332 printTypeChain(tree->ftype,outfile);
5333 fprintf(outfile,")\n");
5334 ast_print(tree->left,outfile,indent+2);
5336 /*------------------------------------------------------------------*/
5337 /*----------------------------*/
5339 /*----------------------------*/
5341 fprintf(outfile,"RRC (%p) type (",tree);
5342 printTypeChain(tree->ftype,outfile);
5343 fprintf(outfile,")\n");
5344 ast_print(tree->left,outfile,indent+2);
5348 fprintf(outfile,"RLC (%p) type (",tree);
5349 printTypeChain(tree->ftype,outfile);
5350 fprintf(outfile,")\n");
5351 ast_print(tree->left,outfile,indent+2);
5354 fprintf(outfile,"SWAP (%p) type (",tree);
5355 printTypeChain(tree->ftype,outfile);
5356 fprintf(outfile,")\n");
5357 ast_print(tree->left,outfile,indent+2);
5360 fprintf(outfile,"GETHBIT (%p) type (",tree);
5361 printTypeChain(tree->ftype,outfile);
5362 fprintf(outfile,")\n");
5363 ast_print(tree->left,outfile,indent+2);
5366 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5367 printTypeChain(tree->ftype,outfile);
5368 fprintf(outfile,")\n");
5369 ast_print(tree->left,outfile,indent+2);
5370 ast_print(tree->right,outfile,indent+2);
5373 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5374 printTypeChain(tree->ftype,outfile);
5375 fprintf(outfile,")\n");
5376 ast_print(tree->left,outfile,indent+2);
5377 ast_print(tree->right,outfile,indent+2);
5379 /*------------------------------------------------------------------*/
5380 /*----------------------------*/
5382 /*----------------------------*/
5383 case CAST: /* change the type */
5384 fprintf(outfile,"CAST (%p) from type (",tree);
5385 printTypeChain(tree->right->ftype,outfile);
5386 fprintf(outfile,") to type (");
5387 printTypeChain(tree->ftype,outfile);
5388 fprintf(outfile,")\n");
5389 ast_print(tree->right,outfile,indent+2);
5393 fprintf(outfile,"ANDAND (%p) type (",tree);
5394 printTypeChain(tree->ftype,outfile);
5395 fprintf(outfile,")\n");
5396 ast_print(tree->left,outfile,indent+2);
5397 ast_print(tree->right,outfile,indent+2);
5400 fprintf(outfile,"OROR (%p) type (",tree);
5401 printTypeChain(tree->ftype,outfile);
5402 fprintf(outfile,")\n");
5403 ast_print(tree->left,outfile,indent+2);
5404 ast_print(tree->right,outfile,indent+2);
5407 /*------------------------------------------------------------------*/
5408 /*----------------------------*/
5409 /* comparison operators */
5410 /*----------------------------*/
5412 fprintf(outfile,"GT(>) (%p) type (",tree);
5413 printTypeChain(tree->ftype,outfile);
5414 fprintf(outfile,")\n");
5415 ast_print(tree->left,outfile,indent+2);
5416 ast_print(tree->right,outfile,indent+2);
5419 fprintf(outfile,"LT(<) (%p) type (",tree);
5420 printTypeChain(tree->ftype,outfile);
5421 fprintf(outfile,")\n");
5422 ast_print(tree->left,outfile,indent+2);
5423 ast_print(tree->right,outfile,indent+2);
5426 fprintf(outfile,"LE(<=) (%p) type (",tree);
5427 printTypeChain(tree->ftype,outfile);
5428 fprintf(outfile,")\n");
5429 ast_print(tree->left,outfile,indent+2);
5430 ast_print(tree->right,outfile,indent+2);
5433 fprintf(outfile,"GE(>=) (%p) type (",tree);
5434 printTypeChain(tree->ftype,outfile);
5435 fprintf(outfile,")\n");
5436 ast_print(tree->left,outfile,indent+2);
5437 ast_print(tree->right,outfile,indent+2);
5440 fprintf(outfile,"EQ(==) (%p) type (",tree);
5441 printTypeChain(tree->ftype,outfile);
5442 fprintf(outfile,")\n");
5443 ast_print(tree->left,outfile,indent+2);
5444 ast_print(tree->right,outfile,indent+2);
5447 fprintf(outfile,"NE(!=) (%p) type (",tree);
5448 printTypeChain(tree->ftype,outfile);
5449 fprintf(outfile,")\n");
5450 ast_print(tree->left,outfile,indent+2);
5451 ast_print(tree->right,outfile,indent+2);
5452 /*------------------------------------------------------------------*/
5453 /*----------------------------*/
5455 /*----------------------------*/
5456 case SIZEOF: /* evaluate wihout code generation */
5457 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5460 /*------------------------------------------------------------------*/
5461 /*----------------------------*/
5462 /* conditional operator '?' */
5463 /*----------------------------*/
5465 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5466 printTypeChain(tree->ftype,outfile);
5467 fprintf(outfile,")\n");
5468 ast_print(tree->left,outfile,indent+2);
5469 ast_print(tree->right,outfile,indent+2);
5473 fprintf(outfile,"COLON(:) (%p) type (",tree);
5474 printTypeChain(tree->ftype,outfile);
5475 fprintf(outfile,")\n");
5476 ast_print(tree->left,outfile,indent+2);
5477 ast_print(tree->right,outfile,indent+2);
5480 /*------------------------------------------------------------------*/
5481 /*----------------------------*/
5482 /* assignment operators */
5483 /*----------------------------*/
5485 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5486 printTypeChain(tree->ftype,outfile);
5487 fprintf(outfile,")\n");
5488 ast_print(tree->left,outfile,indent+2);
5489 ast_print(tree->right,outfile,indent+2);
5492 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5493 printTypeChain(tree->ftype,outfile);
5494 fprintf(outfile,")\n");
5495 ast_print(tree->left,outfile,indent+2);
5496 ast_print(tree->right,outfile,indent+2);
5499 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5500 printTypeChain(tree->ftype,outfile);
5501 fprintf(outfile,")\n");
5502 ast_print(tree->left,outfile,indent+2);
5503 ast_print(tree->right,outfile,indent+2);
5506 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5507 printTypeChain(tree->ftype,outfile);
5508 fprintf(outfile,")\n");
5509 ast_print(tree->left,outfile,indent+2);
5510 ast_print(tree->right,outfile,indent+2);
5513 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5514 printTypeChain(tree->ftype,outfile);
5515 fprintf(outfile,")\n");
5516 ast_print(tree->left,outfile,indent+2);
5517 ast_print(tree->right,outfile,indent+2);
5520 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5521 printTypeChain(tree->ftype,outfile);
5522 fprintf(outfile,")\n");
5523 ast_print(tree->left,outfile,indent+2);
5524 ast_print(tree->right,outfile,indent+2);
5527 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5528 printTypeChain(tree->ftype,outfile);
5529 fprintf(outfile,")\n");
5530 ast_print(tree->left,outfile,indent+2);
5531 ast_print(tree->right,outfile,indent+2);
5533 /*------------------------------------------------------------------*/
5534 /*----------------------------*/
5536 /*----------------------------*/
5538 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5539 printTypeChain(tree->ftype,outfile);
5540 fprintf(outfile,")\n");
5541 ast_print(tree->left,outfile,indent+2);
5542 ast_print(tree->right,outfile,indent+2);
5544 /*------------------------------------------------------------------*/
5545 /*----------------------------*/
5547 /*----------------------------*/
5549 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5550 printTypeChain(tree->ftype,outfile);
5551 fprintf(outfile,")\n");
5552 ast_print(tree->left,outfile,indent+2);
5553 ast_print(tree->right,outfile,indent+2);
5555 /*------------------------------------------------------------------*/
5556 /*----------------------------*/
5557 /* straight assignemnt */
5558 /*----------------------------*/
5560 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5561 printTypeChain(tree->ftype,outfile);
5562 fprintf(outfile,")\n");
5563 ast_print(tree->left,outfile,indent+2);
5564 ast_print(tree->right,outfile,indent+2);
5566 /*------------------------------------------------------------------*/
5567 /*----------------------------*/
5568 /* comma operator */
5569 /*----------------------------*/
5571 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5572 printTypeChain(tree->ftype,outfile);
5573 fprintf(outfile,")\n");
5574 ast_print(tree->left,outfile,indent+2);
5575 ast_print(tree->right,outfile,indent+2);
5577 /*------------------------------------------------------------------*/
5578 /*----------------------------*/
5580 /*----------------------------*/
5583 fprintf(outfile,"CALL (%p) type (",tree);
5584 printTypeChain(tree->ftype,outfile);
5585 fprintf(outfile,")\n");
5586 ast_print(tree->left,outfile,indent+2);
5587 ast_print(tree->right,outfile,indent+2);
5590 fprintf(outfile,"PARMS\n");
5591 ast_print(tree->left,outfile,indent+2);
5592 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5593 ast_print(tree->right,outfile,indent+2);
5596 /*------------------------------------------------------------------*/
5597 /*----------------------------*/
5598 /* return statement */
5599 /*----------------------------*/
5601 fprintf(outfile,"RETURN (%p) type (",tree);
5603 printTypeChain(tree->right->ftype,outfile);
5605 fprintf(outfile,")\n");
5606 ast_print(tree->right,outfile,indent+2);
5608 /*------------------------------------------------------------------*/
5609 /*----------------------------*/
5610 /* label statement */
5611 /*----------------------------*/
5613 fprintf(outfile,"LABEL (%p)\n",tree);
5614 ast_print(tree->left,outfile,indent+2);
5615 ast_print(tree->right,outfile,indent);
5617 /*------------------------------------------------------------------*/
5618 /*----------------------------*/
5619 /* switch statement */
5620 /*----------------------------*/
5624 fprintf(outfile,"SWITCH (%p) ",tree);
5625 ast_print(tree->left,outfile,0);
5626 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5627 INDENT(indent+2,outfile);
5628 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5629 (int) floatFromVal(val),
5630 tree->values.switchVals.swNum,
5631 (int) floatFromVal(val));
5633 ast_print(tree->right,outfile,indent);
5636 /*------------------------------------------------------------------*/
5637 /*----------------------------*/
5639 /*----------------------------*/
5641 fprintf(outfile,"IF (%p) \n",tree);
5642 ast_print(tree->left,outfile,indent+2);
5643 if (tree->trueLabel) {
5644 INDENT(indent+2,outfile);
5645 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5647 if (tree->falseLabel) {
5648 INDENT(indent+2,outfile);
5649 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5651 ast_print(tree->right,outfile,indent+2);
5653 /*----------------------------*/
5654 /* goto Statement */
5655 /*----------------------------*/
5657 fprintf(outfile,"GOTO (%p) \n",tree);
5658 ast_print(tree->left,outfile,indent+2);
5659 fprintf(outfile,"\n");
5661 /*------------------------------------------------------------------*/
5662 /*----------------------------*/
5664 /*----------------------------*/
5666 fprintf(outfile,"FOR (%p) \n",tree);
5667 if (AST_FOR( tree, initExpr)) {
5668 INDENT(indent+2,outfile);
5669 fprintf(outfile,"INIT EXPR ");
5670 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5672 if (AST_FOR( tree, condExpr)) {
5673 INDENT(indent+2,outfile);
5674 fprintf(outfile,"COND EXPR ");
5675 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5677 if (AST_FOR( tree, loopExpr)) {
5678 INDENT(indent+2,outfile);
5679 fprintf(outfile,"LOOP EXPR ");
5680 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5682 fprintf(outfile,"FOR LOOP BODY \n");
5683 ast_print(tree->left,outfile,indent+2);
5686 fprintf(outfile,"CRITICAL (%p) \n",tree);
5687 ast_print(tree->left,outfile,indent+2);
5695 ast_print(t,stdout,0);