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 (LETYPE(tree) && 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;
2410 DCL_TYPE (p) = POINTER;
2411 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2412 DCL_TYPE (p) = CPOINTER;
2413 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2414 DCL_TYPE (p) = FPOINTER;
2415 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2416 DCL_TYPE (p) = PPOINTER;
2417 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2418 DCL_TYPE (p) = IPOINTER;
2419 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2420 DCL_TYPE (p) = EEPPOINTER;
2421 else if (SPEC_OCLS(tree->left->etype))
2422 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2424 DCL_TYPE (p) = POINTER;
2426 if (IS_AST_SYM_VALUE (tree->left))
2428 AST_SYMBOL (tree->left)->addrtaken = 1;
2429 AST_SYMBOL (tree->left)->allocreq = 1;
2432 p->next = LTYPE (tree);
2434 TETYPE (tree) = getSpec (TTYPE (tree));
2439 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2440 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2442 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2443 AST_SYMBOL(tree->left->right));
2444 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2445 valueFromLit(element->offset));
2448 tree->type = EX_VALUE;
2449 tree->values.literalFromCast = 1;
2455 /*------------------------------------------------------------------*/
2456 /*----------------------------*/
2458 /*----------------------------*/
2460 /* if the rewrite succeeds then don't go any furthur */
2462 ast *wtree = optimizeRRCRLC (tree);
2464 return decorateType (wtree);
2466 wtree = optimizeSWAP (tree);
2468 return decorateType (wtree);
2473 /* if left is a literal exchange left & right */
2474 if (IS_LITERAL (LTYPE (tree)))
2476 ast *tTree = tree->left;
2477 tree->left = tree->right;
2478 tree->right = tTree;
2481 /* if right is a literal and */
2482 /* we can find a 2nd literal in a or-tree then */
2483 /* rearrange the tree */
2484 if (IS_LITERAL (RTYPE (tree)))
2487 ast *litTree = searchLitOp (tree, &parent, "|");
2490 ast *tTree = litTree->left;
2491 litTree->left = tree->right;
2492 tree->right = tTree;
2493 /* both operands in tTree are literal now */
2494 decorateType (parent);
2497 /*------------------------------------------------------------------*/
2498 /*----------------------------*/
2500 /*----------------------------*/
2502 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2504 werror (E_BITWISE_OP);
2505 werror (W_CONTINUE, "left & right types are ");
2506 printTypeChain (LTYPE (tree), stderr);
2507 fprintf (stderr, ",");
2508 printTypeChain (RTYPE (tree), stderr);
2509 fprintf (stderr, "\n");
2510 goto errorTreeReturn;
2513 /* if they are both literal then */
2514 /* rewrite the tree */
2515 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2517 tree->type = EX_VALUE;
2518 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2519 valFromType (RETYPE (tree)),
2521 tree->right = tree->left = NULL;
2522 TETYPE (tree) = tree->opval.val->etype;
2523 TTYPE (tree) = tree->opval.val->type;
2527 /* if left is a literal exchange left & right */
2528 if (IS_LITERAL (LTYPE (tree)))
2530 ast *tTree = tree->left;
2531 tree->left = tree->right;
2532 tree->right = tTree;
2535 /* if right is a literal and */
2536 /* we can find a 2nd literal in a xor-tree then */
2537 /* rearrange the tree */
2538 if (IS_LITERAL (RTYPE (tree)))
2541 ast *litTree = searchLitOp (tree, &parent, "^");
2544 ast *tTree = litTree->left;
2545 litTree->left = tree->right;
2546 tree->right = tTree;
2547 /* both operands in litTree are literal now */
2548 decorateType (parent);
2552 LRVAL (tree) = RRVAL (tree) = 1;
2553 TETYPE (tree) = getSpec (TTYPE (tree) =
2554 computeType (LTYPE (tree),
2557 /*------------------------------------------------------------------*/
2558 /*----------------------------*/
2560 /*----------------------------*/
2562 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2564 werror (E_INVALID_OP, "divide");
2565 goto errorTreeReturn;
2567 /* if they are both literal then */
2568 /* rewrite the tree */
2569 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2571 tree->type = EX_VALUE;
2572 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2573 valFromType (RETYPE (tree)));
2574 tree->right = tree->left = NULL;
2575 TETYPE (tree) = getSpec (TTYPE (tree) =
2576 tree->opval.val->type);
2580 LRVAL (tree) = RRVAL (tree) = 1;
2581 TETYPE (tree) = getSpec (TTYPE (tree) =
2582 computeType (LTYPE (tree),
2585 /* if right is a literal and */
2586 /* left is also a division by a literal then */
2587 /* rearrange the tree */
2588 if (IS_LITERAL (RTYPE (tree))
2589 /* avoid infinite loop */
2590 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2593 ast *litTree = searchLitOp (tree, &parent, "/");
2596 if (IS_LITERAL (RTYPE (litTree)))
2599 litTree->right = newNode ('*', litTree->right, tree->right);
2600 litTree->right->lineno = tree->lineno;
2602 tree->right->opval.val = constVal ("1");
2603 decorateType (parent);
2607 /* litTree->left is literal: no gcse possible.
2608 We can't call decorateType(parent), because
2609 this would cause an infinit loop. */
2610 parent->decorated = 1;
2611 decorateType (litTree);
2618 /*------------------------------------------------------------------*/
2619 /*----------------------------*/
2621 /*----------------------------*/
2623 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2625 werror (E_BITWISE_OP);
2626 werror (W_CONTINUE, "left & right types are ");
2627 printTypeChain (LTYPE (tree), stderr);
2628 fprintf (stderr, ",");
2629 printTypeChain (RTYPE (tree), stderr);
2630 fprintf (stderr, "\n");
2631 goto errorTreeReturn;
2633 /* if they are both literal then */
2634 /* rewrite the tree */
2635 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2637 tree->type = EX_VALUE;
2638 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2639 valFromType (RETYPE (tree)));
2640 tree->right = tree->left = NULL;
2641 TETYPE (tree) = getSpec (TTYPE (tree) =
2642 tree->opval.val->type);
2645 LRVAL (tree) = RRVAL (tree) = 1;
2646 TETYPE (tree) = getSpec (TTYPE (tree) =
2647 computeType (LTYPE (tree),
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2653 /* address dereference */
2654 /*----------------------------*/
2655 case '*': /* can be unary : if right is null then unary operation */
2658 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2660 werror (E_PTR_REQD);
2661 goto errorTreeReturn;
2666 werror (E_LVALUE_REQUIRED, "pointer deref");
2667 goto errorTreeReturn;
2669 if (IS_ADDRESS_OF_OP(tree->left))
2671 /* replace *&obj with obj */
2672 return tree->left->left;
2674 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2675 TETYPE (tree) = getSpec (TTYPE (tree));
2676 /* adjust the storage class */
2677 switch (DCL_TYPE(tree->left->ftype)) {
2679 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2682 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2685 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2688 SPEC_SCLS (TETYPE (tree)) = 0;
2691 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2694 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2697 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2700 SPEC_SCLS (TETYPE (tree)) = 0;
2709 /*------------------------------------------------------------------*/
2710 /*----------------------------*/
2711 /* multiplication */
2712 /*----------------------------*/
2713 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2715 werror (E_INVALID_OP, "multiplication");
2716 goto errorTreeReturn;
2719 /* if they are both literal then */
2720 /* rewrite the tree */
2721 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2723 tree->type = EX_VALUE;
2724 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2725 valFromType (RETYPE (tree)));
2726 tree->right = tree->left = NULL;
2727 TETYPE (tree) = getSpec (TTYPE (tree) =
2728 tree->opval.val->type);
2732 /* if left is a literal exchange left & right */
2733 if (IS_LITERAL (LTYPE (tree)))
2735 ast *tTree = tree->left;
2736 tree->left = tree->right;
2737 tree->right = tTree;
2740 /* if right is a literal and */
2741 /* we can find a 2nd literal in a mul-tree then */
2742 /* rearrange the tree */
2743 if (IS_LITERAL (RTYPE (tree)))
2746 ast *litTree = searchLitOp (tree, &parent, "*");
2749 ast *tTree = litTree->left;
2750 litTree->left = tree->right;
2751 tree->right = tTree;
2752 /* both operands in litTree are literal now */
2753 decorateType (parent);
2757 LRVAL (tree) = RRVAL (tree) = 1;
2758 TETYPE (tree) = getSpec (TTYPE (tree) =
2759 computeType (LTYPE (tree),
2762 /* promote result to int if left & right are char
2763 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2764 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2765 SPEC_NOUN(TETYPE(tree)) = V_INT;
2770 /*------------------------------------------------------------------*/
2771 /*----------------------------*/
2772 /* unary '+' operator */
2773 /*----------------------------*/
2778 if (!IS_INTEGRAL (LTYPE (tree)))
2780 werror (E_UNARY_OP, '+');
2781 goto errorTreeReturn;
2784 /* if left is a literal then do it */
2785 if (IS_LITERAL (LTYPE (tree)))
2787 tree->type = EX_VALUE;
2788 tree->opval.val = valFromType (LETYPE (tree));
2790 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2794 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2798 /*------------------------------------------------------------------*/
2799 /*----------------------------*/
2801 /*----------------------------*/
2803 /* this is not a unary operation */
2804 /* if both pointers then problem */
2805 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2806 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2808 werror (E_PTR_PLUS_PTR);
2809 goto errorTreeReturn;
2812 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2813 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2815 werror (E_PLUS_INVALID, "+");
2816 goto errorTreeReturn;
2819 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2820 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2822 werror (E_PLUS_INVALID, "+");
2823 goto errorTreeReturn;
2825 /* if they are both literal then */
2826 /* rewrite the tree */
2827 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2829 tree->type = EX_VALUE;
2830 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2831 valFromType (RETYPE (tree)));
2832 tree->right = tree->left = NULL;
2833 TETYPE (tree) = getSpec (TTYPE (tree) =
2834 tree->opval.val->type);
2838 /* if the right is a pointer or left is a literal
2839 xchange left & right */
2840 if (IS_ARRAY (RTYPE (tree)) ||
2841 IS_PTR (RTYPE (tree)) ||
2842 IS_LITERAL (LTYPE (tree)))
2844 ast *tTree = tree->left;
2845 tree->left = tree->right;
2846 tree->right = tTree;
2849 /* if right is a literal and */
2850 /* left is also an addition/subtraction with a literal then */
2851 /* rearrange the tree */
2852 if (IS_LITERAL (RTYPE (tree)))
2854 ast *litTree, *parent;
2855 litTree = searchLitOp (tree, &parent, "+-");
2858 if (litTree->opval.op == '+')
2861 ast *tTree = litTree->left;
2862 litTree->left = tree->right;
2863 tree->right = tree->left;
2866 else if (litTree->opval.op == '-')
2868 if (IS_LITERAL (RTYPE (litTree)))
2871 ast *tTree = litTree->left;
2872 litTree->left = tree->right;
2873 tree->right = tTree;
2878 ast *tTree = litTree->right;
2879 litTree->right = tree->right;
2880 tree->right = tTree;
2881 litTree->opval.op = '+';
2882 tree->opval.op = '-';
2885 decorateType (parent);
2889 LRVAL (tree) = RRVAL (tree) = 1;
2890 /* if the left is a pointer */
2891 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2892 TETYPE (tree) = getSpec (TTYPE (tree) =
2895 TETYPE (tree) = getSpec (TTYPE (tree) =
2896 computeType (LTYPE (tree),
2900 /*------------------------------------------------------------------*/
2901 /*----------------------------*/
2903 /*----------------------------*/
2904 case '-': /* can be unary */
2905 /* if right is null then unary */
2909 if (!IS_ARITHMETIC (LTYPE (tree)))
2911 werror (E_UNARY_OP, tree->opval.op);
2912 goto errorTreeReturn;
2915 /* if left is a literal then do it */
2916 if (IS_LITERAL (LTYPE (tree)))
2918 tree->type = EX_VALUE;
2919 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2921 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2922 SPEC_USIGN(TETYPE(tree)) = 0;
2926 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2930 /*------------------------------------------------------------------*/
2931 /*----------------------------*/
2933 /*----------------------------*/
2935 if (!(IS_PTR (LTYPE (tree)) ||
2936 IS_ARRAY (LTYPE (tree)) ||
2937 IS_ARITHMETIC (LTYPE (tree))))
2939 werror (E_PLUS_INVALID, "-");
2940 goto errorTreeReturn;
2943 if (!(IS_PTR (RTYPE (tree)) ||
2944 IS_ARRAY (RTYPE (tree)) ||
2945 IS_ARITHMETIC (RTYPE (tree))))
2947 werror (E_PLUS_INVALID, "-");
2948 goto errorTreeReturn;
2951 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2952 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2953 IS_INTEGRAL (RTYPE (tree))))
2955 werror (E_PLUS_INVALID, "-");
2956 goto errorTreeReturn;
2959 /* if they are both literal then */
2960 /* rewrite the tree */
2961 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2963 tree->type = EX_VALUE;
2964 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2965 valFromType (RETYPE (tree)));
2966 tree->right = tree->left = NULL;
2967 TETYPE (tree) = getSpec (TTYPE (tree) =
2968 tree->opval.val->type);
2972 /* if the left & right are equal then zero */
2973 if (isAstEqual (tree->left, tree->right))
2975 tree->type = EX_VALUE;
2976 tree->left = tree->right = NULL;
2977 tree->opval.val = constVal ("0");
2978 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2982 /* if both of them are pointers or arrays then */
2983 /* the result is going to be an integer */
2984 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2985 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2986 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2988 /* if only the left is a pointer */
2989 /* then result is a pointer */
2990 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2991 TETYPE (tree) = getSpec (TTYPE (tree) =
2994 TETYPE (tree) = getSpec (TTYPE (tree) =
2995 computeType (LTYPE (tree),
2998 LRVAL (tree) = RRVAL (tree) = 1;
3000 /* if right is a literal and */
3001 /* left is also an addition/subtraction with a literal then */
3002 /* rearrange the tree */
3003 if (IS_LITERAL (RTYPE (tree))
3004 /* avoid infinite loop */
3005 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3007 ast *litTree, *litParent;
3008 litTree = searchLitOp (tree, &litParent, "+-");
3011 if (litTree->opval.op == '+')
3014 litTree->right = newNode ('-', litTree->right, tree->right);
3015 litTree->right->lineno = tree->lineno;
3017 tree->right->opval.val = constVal ("0");
3019 else if (litTree->opval.op == '-')
3021 if (IS_LITERAL (RTYPE (litTree)))
3024 litTree->right = newNode ('+', tree->right, litTree->right);
3025 litTree->right->lineno = tree->lineno;
3027 tree->right->opval.val = constVal ("0");
3032 ast *tTree = litTree->right;
3033 litTree->right = tree->right;
3034 tree->right = tTree;
3037 decorateType (litParent);
3042 /*------------------------------------------------------------------*/
3043 /*----------------------------*/
3045 /*----------------------------*/
3047 /* can be only integral type */
3048 if (!IS_INTEGRAL (LTYPE (tree)))
3050 werror (E_UNARY_OP, tree->opval.op);
3051 goto errorTreeReturn;
3054 /* if left is a literal then do it */
3055 if (IS_LITERAL (LTYPE (tree)))
3057 tree->type = EX_VALUE;
3058 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3060 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3064 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3067 /*------------------------------------------------------------------*/
3068 /*----------------------------*/
3070 /*----------------------------*/
3072 /* can be pointer */
3073 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3074 !IS_PTR (LTYPE (tree)) &&
3075 !IS_ARRAY (LTYPE (tree)))
3077 werror (E_UNARY_OP, tree->opval.op);
3078 goto errorTreeReturn;
3081 /* if left is a literal then do it */
3082 if (IS_LITERAL (LTYPE (tree)))
3084 tree->type = EX_VALUE;
3085 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3087 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3091 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3094 /*------------------------------------------------------------------*/
3095 /*----------------------------*/
3097 /*----------------------------*/
3101 TTYPE (tree) = LTYPE (tree);
3102 TETYPE (tree) = LETYPE (tree);
3106 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3111 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3113 werror (E_SHIFT_OP_INVALID);
3114 werror (W_CONTINUE, "left & right types are ");
3115 printTypeChain (LTYPE (tree), stderr);
3116 fprintf (stderr, ",");
3117 printTypeChain (RTYPE (tree), stderr);
3118 fprintf (stderr, "\n");
3119 goto errorTreeReturn;
3122 /* if they are both literal then */
3123 /* rewrite the tree */
3124 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3126 tree->type = EX_VALUE;
3127 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3128 valFromType (RETYPE (tree)),
3129 (tree->opval.op == LEFT_OP ? 1 : 0));
3130 tree->right = tree->left = NULL;
3131 TETYPE (tree) = getSpec (TTYPE (tree) =
3132 tree->opval.val->type);
3136 /* if only the right side is a literal & we are
3137 shifting more than size of the left operand then zero */
3138 if (IS_LITERAL (RTYPE (tree)) &&
3139 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3140 (getSize (LTYPE (tree)) * 8))
3142 if (tree->opval.op==LEFT_OP ||
3143 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3144 lineno=tree->lineno;
3145 werror (W_SHIFT_CHANGED,
3146 (tree->opval.op == LEFT_OP ? "left" : "right"));
3147 tree->type = EX_VALUE;
3148 tree->left = tree->right = NULL;
3149 tree->opval.val = constVal ("0");
3150 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3154 LRVAL (tree) = RRVAL (tree) = 1;
3155 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3156 if (IS_LITERAL (TTYPE (tree)))
3157 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3160 /*------------------------------------------------------------------*/
3161 /*----------------------------*/
3163 /*----------------------------*/
3164 case CAST: /* change the type */
3165 /* cannot cast to an aggregate type */
3166 if (IS_AGGREGATE (LTYPE (tree)))
3168 werror (E_CAST_ILLEGAL);
3169 goto errorTreeReturn;
3172 /* make sure the type is complete and sane */
3173 checkTypeSanity(LETYPE(tree), "(cast)");
3176 /* if the right is a literal replace the tree */
3177 if (IS_LITERAL (RETYPE (tree))) {
3178 if (!IS_PTR (LTYPE (tree))) {
3179 tree->type = EX_VALUE;
3181 valCastLiteral (LTYPE (tree),
3182 floatFromVal (valFromType (RETYPE (tree))));
3185 TTYPE (tree) = tree->opval.val->type;
3186 tree->values.literalFromCast = 1;
3187 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3188 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3189 sym_link *rest = LTYPE(tree)->next;
3190 werror(W_LITERAL_GENERIC);
3191 TTYPE(tree) = newLink(DECLARATOR);
3192 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3193 TTYPE(tree)->next = rest;
3194 tree->left->opval.lnk = TTYPE(tree);
3197 TTYPE (tree) = LTYPE (tree);
3201 TTYPE (tree) = LTYPE (tree);
3205 #if 0 // this is already checked, now this could be explicit
3206 /* if pointer to struct then check names */
3207 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3208 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3209 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3211 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3212 SPEC_STRUCT(LETYPE(tree))->tag);
3215 if (IS_ADDRESS_OF_OP(tree->right)
3216 && IS_AST_SYM_VALUE (tree->right->left)
3217 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3219 tree->type = EX_VALUE;
3221 valCastLiteral (LTYPE (tree),
3222 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3223 TTYPE (tree) = tree->opval.val->type;
3224 TETYPE (tree) = getSpec (TTYPE (tree));
3227 tree->values.literalFromCast = 1;
3231 /* handle offsetof macro: */
3232 /* #define offsetof(TYPE, MEMBER) \ */
3233 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3234 if (IS_ADDRESS_OF_OP(tree->right)
3235 && IS_AST_OP (tree->right->left)
3236 && tree->right->left->opval.op == PTR_OP
3237 && IS_AST_OP (tree->right->left->left)
3238 && tree->right->left->left->opval.op == CAST
3239 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3241 symbol *element = getStructElement (
3242 SPEC_STRUCT (LETYPE(tree->right->left)),
3243 AST_SYMBOL(tree->right->left->right)
3247 tree->type = EX_VALUE;
3248 tree->opval.val = valCastLiteral (
3251 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3254 TTYPE (tree) = tree->opval.val->type;
3255 TETYPE (tree) = getSpec (TTYPE (tree));
3262 /* if the right is a literal replace the tree */
3263 if (IS_LITERAL (RETYPE (tree))) {
3264 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3265 /* rewrite (type *)litaddr
3267 and define type at litaddr temp
3268 (but only if type's storage class is not generic)
3270 ast *newTree = newNode ('&', NULL, NULL);
3273 TTYPE (newTree) = LTYPE (tree);
3274 TETYPE (newTree) = getSpec(LTYPE (tree));
3276 /* define a global symbol at the casted address*/
3277 sym = newSymbol(genSymName (0), 0);
3278 sym->type = LTYPE (tree)->next;
3280 sym->type = newLink (V_VOID);
3281 sym->etype = getSpec(sym->type);
3282 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3283 sym->lineDef = tree->lineno;
3286 SPEC_STAT (sym->etype) = 1;
3287 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3288 SPEC_ABSA(sym->etype) = 1;
3289 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3292 newTree->left = newAst_VALUE(symbolVal(sym));
3293 newTree->left->lineno = tree->lineno;
3294 LTYPE (newTree) = sym->type;
3295 LETYPE (newTree) = sym->etype;
3296 LLVAL (newTree) = 1;
3297 LRVAL (newTree) = 0;
3298 TLVAL (newTree) = 1;
3301 if (!IS_PTR (LTYPE (tree))) {
3302 tree->type = EX_VALUE;
3304 valCastLiteral (LTYPE (tree),
3305 floatFromVal (valFromType (RETYPE (tree))));
3306 TTYPE (tree) = tree->opval.val->type;
3309 tree->values.literalFromCast = 1;
3310 TETYPE (tree) = getSpec (TTYPE (tree));
3314 TTYPE (tree) = LTYPE (tree);
3318 TETYPE (tree) = getSpec (TTYPE (tree));
3322 /*------------------------------------------------------------------*/
3323 /*----------------------------*/
3324 /* logical &&, || */
3325 /*----------------------------*/
3328 /* each must me arithmetic type or be a pointer */
3329 if (!IS_PTR (LTYPE (tree)) &&
3330 !IS_ARRAY (LTYPE (tree)) &&
3331 !IS_INTEGRAL (LTYPE (tree)))
3333 werror (E_COMPARE_OP);
3334 goto errorTreeReturn;
3337 if (!IS_PTR (RTYPE (tree)) &&
3338 !IS_ARRAY (RTYPE (tree)) &&
3339 !IS_INTEGRAL (RTYPE (tree)))
3341 werror (E_COMPARE_OP);
3342 goto errorTreeReturn;
3344 /* if they are both literal then */
3345 /* rewrite the tree */
3346 if (IS_LITERAL (RTYPE (tree)) &&
3347 IS_LITERAL (LTYPE (tree)))
3349 tree->type = EX_VALUE;
3350 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3351 valFromType (RETYPE (tree)),
3353 tree->right = tree->left = NULL;
3354 TETYPE (tree) = getSpec (TTYPE (tree) =
3355 tree->opval.val->type);
3358 LRVAL (tree) = RRVAL (tree) = 1;
3359 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3362 /*------------------------------------------------------------------*/
3363 /*----------------------------*/
3364 /* comparison operators */
3365 /*----------------------------*/
3373 ast *lt = optimizeCompare (tree);
3379 /* if they are pointers they must be castable */
3380 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3382 if (tree->opval.op==EQ_OP &&
3383 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3384 // we cannot cast a gptr to a !gptr: switch the leaves
3385 struct ast *s=tree->left;
3386 tree->left=tree->right;
3389 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3391 werror (E_COMPARE_OP);
3392 fprintf (stderr, "comparring type ");
3393 printTypeChain (LTYPE (tree), stderr);
3394 fprintf (stderr, "to type ");
3395 printTypeChain (RTYPE (tree), stderr);
3396 fprintf (stderr, "\n");
3397 goto errorTreeReturn;
3400 /* else they should be promotable to one another */
3403 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3404 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3406 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3408 werror (E_COMPARE_OP);
3409 fprintf (stderr, "comparing type ");
3410 printTypeChain (LTYPE (tree), stderr);
3411 fprintf (stderr, "to type ");
3412 printTypeChain (RTYPE (tree), stderr);
3413 fprintf (stderr, "\n");
3414 goto errorTreeReturn;
3417 /* if unsigned value < 0 then always false */
3418 /* if (unsigned value) > 0 then (unsigned value) */
3419 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3420 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3422 if (tree->opval.op == '<') {
3425 if (tree->opval.op == '>') {
3429 /* if they are both literal then */
3430 /* rewrite the tree */
3431 if (IS_LITERAL (RTYPE (tree)) &&
3432 IS_LITERAL (LTYPE (tree)))
3434 tree->type = EX_VALUE;
3435 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3436 valFromType (RETYPE (tree)),
3438 tree->right = tree->left = NULL;
3439 TETYPE (tree) = getSpec (TTYPE (tree) =
3440 tree->opval.val->type);
3443 LRVAL (tree) = RRVAL (tree) = 1;
3444 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3447 /*------------------------------------------------------------------*/
3448 /*----------------------------*/
3450 /*----------------------------*/
3451 case SIZEOF: /* evaluate wihout code generation */
3452 /* change the type to a integer */
3453 tree->type = EX_VALUE;
3454 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3455 tree->opval.val = constVal (buffer);
3456 tree->right = tree->left = NULL;
3457 TETYPE (tree) = getSpec (TTYPE (tree) =
3458 tree->opval.val->type);
3461 /*------------------------------------------------------------------*/
3462 /*----------------------------*/
3464 /*----------------------------*/
3466 /* return typeof enum value */
3467 tree->type = EX_VALUE;
3470 if (IS_SPEC(tree->right->ftype)) {
3471 switch (SPEC_NOUN(tree->right->ftype)) {
3473 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3474 else typeofv = TYPEOF_INT;
3477 typeofv = TYPEOF_FLOAT;
3480 typeofv = TYPEOF_CHAR;
3483 typeofv = TYPEOF_VOID;
3486 typeofv = TYPEOF_STRUCT;
3489 typeofv = TYPEOF_BITFIELD;
3492 typeofv = TYPEOF_BIT;
3495 typeofv = TYPEOF_SBIT;
3501 switch (DCL_TYPE(tree->right->ftype)) {
3503 typeofv = TYPEOF_POINTER;
3506 typeofv = TYPEOF_FPOINTER;
3509 typeofv = TYPEOF_CPOINTER;
3512 typeofv = TYPEOF_GPOINTER;
3515 typeofv = TYPEOF_PPOINTER;
3518 typeofv = TYPEOF_IPOINTER;
3521 typeofv = TYPEOF_ARRAY;
3524 typeofv = TYPEOF_FUNCTION;
3530 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3531 tree->opval.val = constVal (buffer);
3532 tree->right = tree->left = NULL;
3533 TETYPE (tree) = getSpec (TTYPE (tree) =
3534 tree->opval.val->type);
3537 /*------------------------------------------------------------------*/
3538 /*----------------------------*/
3539 /* conditional operator '?' */
3540 /*----------------------------*/
3542 /* the type is value of the colon operator (on the right) */
3543 assert(IS_COLON_OP(tree->right));
3544 /* if already known then replace the tree : optimizer will do it
3545 but faster to do it here */
3546 if (IS_LITERAL (LTYPE(tree))) {
3547 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3548 return decorateType(tree->right->left) ;
3550 return decorateType(tree->right->right) ;
3553 tree->right = decorateType(tree->right);
3554 TTYPE (tree) = RTYPE(tree);
3555 TETYPE (tree) = getSpec (TTYPE (tree));
3560 /* if they don't match we have a problem */
3561 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3563 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3564 goto errorTreeReturn;
3567 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3568 TETYPE (tree) = getSpec (TTYPE (tree));
3572 #if 0 // assignment operators are converted by the parser
3573 /*------------------------------------------------------------------*/
3574 /*----------------------------*/
3575 /* assignment operators */
3576 /*----------------------------*/
3579 /* for these it must be both must be integral */
3580 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3581 !IS_ARITHMETIC (RTYPE (tree)))
3583 werror (E_OPS_INTEGRAL);
3584 goto errorTreeReturn;
3587 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3589 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3590 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3594 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3595 goto errorTreeReturn;
3606 /* for these it must be both must be integral */
3607 if (!IS_INTEGRAL (LTYPE (tree)) ||
3608 !IS_INTEGRAL (RTYPE (tree)))
3610 werror (E_OPS_INTEGRAL);
3611 goto errorTreeReturn;
3614 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3616 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3617 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3621 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3622 goto errorTreeReturn;
3628 /*------------------------------------------------------------------*/
3629 /*----------------------------*/
3631 /*----------------------------*/
3633 if (!(IS_PTR (LTYPE (tree)) ||
3634 IS_ARITHMETIC (LTYPE (tree))))
3636 werror (E_PLUS_INVALID, "-=");
3637 goto errorTreeReturn;
3640 if (!(IS_PTR (RTYPE (tree)) ||
3641 IS_ARITHMETIC (RTYPE (tree))))
3643 werror (E_PLUS_INVALID, "-=");
3644 goto errorTreeReturn;
3647 TETYPE (tree) = getSpec (TTYPE (tree) =
3648 computeType (LTYPE (tree),
3651 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3652 werror (E_CODE_WRITE, "-=");
3656 werror (E_LVALUE_REQUIRED, "-=");
3657 goto errorTreeReturn;
3663 /*------------------------------------------------------------------*/
3664 /*----------------------------*/
3666 /*----------------------------*/
3668 /* this is not a unary operation */
3669 /* if both pointers then problem */
3670 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3672 werror (E_PTR_PLUS_PTR);
3673 goto errorTreeReturn;
3676 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3678 werror (E_PLUS_INVALID, "+=");
3679 goto errorTreeReturn;
3682 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3684 werror (E_PLUS_INVALID, "+=");
3685 goto errorTreeReturn;
3688 TETYPE (tree) = getSpec (TTYPE (tree) =
3689 computeType (LTYPE (tree),
3692 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3693 werror (E_CODE_WRITE, "+=");
3697 werror (E_LVALUE_REQUIRED, "+=");
3698 goto errorTreeReturn;
3701 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3702 tree->opval.op = '=';
3707 /*------------------------------------------------------------------*/
3708 /*----------------------------*/
3709 /* straight assignemnt */
3710 /*----------------------------*/
3712 /* cannot be an aggregate */
3713 if (IS_AGGREGATE (LTYPE (tree)))
3715 werror (E_AGGR_ASSIGN);
3716 goto errorTreeReturn;
3719 /* they should either match or be castable */
3720 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3722 werror (E_TYPE_MISMATCH, "assignment", " ");
3723 printFromToType(RTYPE(tree),LTYPE(tree));
3726 /* if the left side of the tree is of type void
3727 then report error */
3728 if (IS_VOID (LTYPE (tree)))
3730 werror (E_CAST_ZERO);
3731 printFromToType(RTYPE(tree), LTYPE(tree));
3734 TETYPE (tree) = getSpec (TTYPE (tree) =
3738 if (!tree->initMode ) {
3739 if (IS_CONSTANT(LTYPE(tree)))
3740 werror (E_CODE_WRITE, "=");
3744 werror (E_LVALUE_REQUIRED, "=");
3745 goto errorTreeReturn;
3750 /*------------------------------------------------------------------*/
3751 /*----------------------------*/
3752 /* comma operator */
3753 /*----------------------------*/
3755 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3758 /*------------------------------------------------------------------*/
3759 /*----------------------------*/
3761 /*----------------------------*/
3765 if (processParms (tree->left,
3766 FUNC_ARGS(tree->left->ftype),
3767 tree->right, &parmNumber, TRUE)) {
3768 goto errorTreeReturn;
3771 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3772 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3774 reverseParms (tree->right);
3777 if (IS_CODEPTR(LTYPE(tree))) {
3778 TTYPE(tree) = LTYPE(tree)->next->next;
3780 TTYPE(tree) = LTYPE(tree)->next;
3782 TETYPE (tree) = getSpec (TTYPE (tree));
3785 /*------------------------------------------------------------------*/
3786 /*----------------------------*/
3787 /* return statement */
3788 /*----------------------------*/
3793 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3795 werror (W_RETURN_MISMATCH);
3796 printFromToType (RTYPE(tree), currFunc->type->next);
3797 goto errorTreeReturn;
3800 if (IS_VOID (currFunc->type->next)
3802 !IS_VOID (RTYPE (tree)))
3804 werror (E_FUNC_VOID);
3805 goto errorTreeReturn;
3808 /* if there is going to be a casing required then add it */
3809 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3812 decorateType (newNode (CAST,
3813 newAst_LINK (copyLinkChain (currFunc->type->next)),
3822 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3824 werror (W_VOID_FUNC, currFunc->name);
3825 goto errorTreeReturn;
3828 TTYPE (tree) = TETYPE (tree) = NULL;
3831 /*------------------------------------------------------------------*/
3832 /*----------------------------*/
3833 /* switch statement */
3834 /*----------------------------*/
3836 /* the switch value must be an integer */
3837 if (!IS_INTEGRAL (LTYPE (tree)))
3839 werror (E_SWITCH_NON_INTEGER);
3840 goto errorTreeReturn;
3843 TTYPE (tree) = TETYPE (tree) = NULL;
3846 /*------------------------------------------------------------------*/
3847 /*----------------------------*/
3849 /*----------------------------*/
3851 tree->left = backPatchLabels (tree->left,
3854 TTYPE (tree) = TETYPE (tree) = NULL;
3857 /*------------------------------------------------------------------*/
3858 /*----------------------------*/
3860 /*----------------------------*/
3863 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3864 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3865 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3867 /* if the for loop is reversible then
3868 reverse it otherwise do what we normally
3874 if (isLoopReversible (tree, &sym, &init, &end))
3875 return reverseLoop (tree, sym, init, end);
3877 return decorateType (createFor (AST_FOR (tree, trueLabel),
3878 AST_FOR (tree, continueLabel),
3879 AST_FOR (tree, falseLabel),
3880 AST_FOR (tree, condLabel),
3881 AST_FOR (tree, initExpr),
3882 AST_FOR (tree, condExpr),
3883 AST_FOR (tree, loopExpr),
3887 TTYPE (tree) = TETYPE (tree) = NULL;
3891 /* some error found this tree will be killed */
3893 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3894 tree->opval.op = NULLOP;
3900 /*-----------------------------------------------------------------*/
3901 /* sizeofOp - processes size of operation */
3902 /*-----------------------------------------------------------------*/
3904 sizeofOp (sym_link * type)
3908 /* make sure the type is complete and sane */
3909 checkTypeSanity(type, "(sizeof)");
3911 /* get the size and convert it to character */
3912 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3914 /* now convert into value */
3915 return constVal (buff);
3919 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3920 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3921 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3922 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3923 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3924 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3925 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3927 /*-----------------------------------------------------------------*/
3928 /* backPatchLabels - change and or not operators to flow control */
3929 /*-----------------------------------------------------------------*/
3931 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3937 if (!(IS_ANDORNOT (tree)))
3940 /* if this an and */
3943 static int localLbl = 0;
3946 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3947 localLabel = newSymbol (buffer, NestLevel);
3949 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3951 /* if left is already a IFX then just change the if true label in that */
3952 if (!IS_IFX (tree->left))
3953 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3955 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3956 /* right is a IFX then just join */
3957 if (IS_IFX (tree->right))
3958 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3960 tree->right = createLabel (localLabel, tree->right);
3961 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3963 return newNode (NULLOP, tree->left, tree->right);
3966 /* if this is an or operation */
3969 static int localLbl = 0;
3972 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3973 localLabel = newSymbol (buffer, NestLevel);
3975 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3977 /* if left is already a IFX then just change the if true label in that */
3978 if (!IS_IFX (tree->left))
3979 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3981 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3982 /* right is a IFX then just join */
3983 if (IS_IFX (tree->right))
3984 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3986 tree->right = createLabel (localLabel, tree->right);
3987 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3989 return newNode (NULLOP, tree->left, tree->right);
3995 int wasnot = IS_NOT (tree->left);
3996 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3998 /* if the left is already a IFX */
3999 if (!IS_IFX (tree->left))
4000 tree->left = newNode (IFX, tree->left, NULL);
4004 tree->left->trueLabel = trueLabel;
4005 tree->left->falseLabel = falseLabel;
4009 tree->left->trueLabel = falseLabel;
4010 tree->left->falseLabel = trueLabel;
4017 tree->trueLabel = trueLabel;
4018 tree->falseLabel = falseLabel;
4025 /*-----------------------------------------------------------------*/
4026 /* createBlock - create expression tree for block */
4027 /*-----------------------------------------------------------------*/
4029 createBlock (symbol * decl, ast * body)
4033 /* if the block has nothing */
4037 ex = newNode (BLOCK, NULL, body);
4038 ex->values.sym = decl;
4040 ex->right = ex->right;
4046 /*-----------------------------------------------------------------*/
4047 /* createLabel - creates the expression tree for labels */
4048 /*-----------------------------------------------------------------*/
4050 createLabel (symbol * label, ast * stmnt)
4053 char name[SDCC_NAME_MAX + 1];
4056 /* must create fresh symbol if the symbol name */
4057 /* exists in the symbol table, since there can */
4058 /* be a variable with the same name as the labl */
4059 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4060 (csym->level == label->level))
4061 label = newSymbol (label->name, label->level);
4063 /* change the name before putting it in add _ */
4064 SNPRINTF(name, sizeof(name), "%s", label->name);
4066 /* put the label in the LabelSymbol table */
4067 /* but first check if a label of the same */
4069 if ((csym = findSym (LabelTab, NULL, name)))
4070 werror (E_DUPLICATE_LABEL, label->name);
4072 addSym (LabelTab, label, name, label->level, 0, 0);
4075 label->key = labelKey++;
4076 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4082 /*-----------------------------------------------------------------*/
4083 /* createCase - generates the parsetree for a case statement */
4084 /*-----------------------------------------------------------------*/
4086 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4088 char caseLbl[SDCC_NAME_MAX + 1];
4092 /* if the switch statement does not exist */
4093 /* then case is out of context */
4096 werror (E_CASE_CONTEXT);
4100 caseVal = decorateType (resolveSymbols (caseVal));
4101 /* if not a constant then error */
4102 if (!IS_LITERAL (caseVal->ftype))
4104 werror (E_CASE_CONSTANT);
4108 /* if not a integer than error */
4109 if (!IS_INTEGRAL (caseVal->ftype))
4111 werror (E_CASE_NON_INTEGER);
4115 /* find the end of the switch values chain */
4116 if (!(val = swStat->values.switchVals.swVals))
4117 swStat->values.switchVals.swVals = caseVal->opval.val;
4120 /* also order the cases according to value */
4122 int cVal = (int) floatFromVal (caseVal->opval.val);
4123 while (val && (int) floatFromVal (val) < cVal)
4129 /* if we reached the end then */
4132 pval->next = caseVal->opval.val;
4136 /* we found a value greater than */
4137 /* the current value we must add this */
4138 /* before the value */
4139 caseVal->opval.val->next = val;
4141 /* if this was the first in chain */
4142 if (swStat->values.switchVals.swVals == val)
4143 swStat->values.switchVals.swVals =
4146 pval->next = caseVal->opval.val;
4151 /* create the case label */
4152 SNPRINTF(caseLbl, sizeof(caseLbl),
4154 swStat->values.switchVals.swNum,
4155 (int) floatFromVal (caseVal->opval.val));
4157 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4162 /*-----------------------------------------------------------------*/
4163 /* createDefault - creates the parse tree for the default statement */
4164 /*-----------------------------------------------------------------*/
4166 createDefault (ast * swStat, ast * stmnt)
4168 char defLbl[SDCC_NAME_MAX + 1];
4170 /* if the switch statement does not exist */
4171 /* then case is out of context */
4174 werror (E_CASE_CONTEXT);
4178 /* turn on the default flag */
4179 swStat->values.switchVals.swDefault = 1;
4181 /* create the label */
4182 SNPRINTF (defLbl, sizeof(defLbl),
4183 "_default_%d", swStat->values.switchVals.swNum);
4184 return createLabel (newSymbol (defLbl, 0), stmnt);
4187 /*-----------------------------------------------------------------*/
4188 /* createIf - creates the parsetree for the if statement */
4189 /*-----------------------------------------------------------------*/
4191 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4193 static int Lblnum = 0;
4195 symbol *ifTrue, *ifFalse, *ifEnd;
4197 /* if neither exists */
4198 if (!elseBody && !ifBody) {
4199 // if there are no side effects (i++, j() etc)
4200 if (!hasSEFcalls(condAst)) {
4205 /* create the labels */
4206 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4207 ifFalse = newSymbol (buffer, NestLevel);
4208 /* if no else body then end == false */
4213 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4214 ifEnd = newSymbol (buffer, NestLevel);
4217 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4218 ifTrue = newSymbol (buffer, NestLevel);
4222 /* attach the ifTrue label to the top of it body */
4223 ifBody = createLabel (ifTrue, ifBody);
4224 /* attach a goto end to the ifBody if else is present */
4227 ifBody = newNode (NULLOP, ifBody,
4229 newAst_VALUE (symbolVal (ifEnd)),
4231 /* put the elseLabel on the else body */
4232 elseBody = createLabel (ifFalse, elseBody);
4233 /* out the end at the end of the body */
4234 elseBody = newNode (NULLOP,
4236 createLabel (ifEnd, NULL));
4240 ifBody = newNode (NULLOP, ifBody,
4241 createLabel (ifFalse, NULL));
4243 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4244 if (IS_IFX (condAst))
4247 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4249 return newNode (NULLOP, ifTree,
4250 newNode (NULLOP, ifBody, elseBody));
4254 /*-----------------------------------------------------------------*/
4255 /* createDo - creates parse tree for do */
4258 /* _docontinue_n: */
4259 /* condition_expression +-> trueLabel -> _dobody_n */
4261 /* +-> falseLabel-> _dobreak_n */
4263 /*-----------------------------------------------------------------*/
4265 createDo (symbol * trueLabel, symbol * continueLabel,
4266 symbol * falseLabel, ast * condAst, ast * doBody)
4271 /* if the body does not exist then it is simple */
4274 condAst = backPatchLabels (condAst, continueLabel, NULL);
4275 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4276 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4277 doTree->trueLabel = continueLabel;
4278 doTree->falseLabel = NULL;
4282 /* otherwise we have a body */
4283 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4285 /* attach the body label to the top */
4286 doBody = createLabel (trueLabel, doBody);
4287 /* attach the continue label to end of body */
4288 doBody = newNode (NULLOP, doBody,
4289 createLabel (continueLabel, NULL));
4291 /* now put the break label at the end */
4292 if (IS_IFX (condAst))
4295 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4297 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4299 /* putting it together */
4300 return newNode (NULLOP, doBody, doTree);
4303 /*-----------------------------------------------------------------*/
4304 /* createFor - creates parse tree for 'for' statement */
4307 /* condExpr +-> trueLabel -> _forbody_n */
4309 /* +-> falseLabel-> _forbreak_n */
4312 /* _forcontinue_n: */
4314 /* goto _forcond_n ; */
4316 /*-----------------------------------------------------------------*/
4318 createFor (symbol * trueLabel, symbol * continueLabel,
4319 symbol * falseLabel, symbol * condLabel,
4320 ast * initExpr, ast * condExpr, ast * loopExpr,
4325 /* if loopexpression not present then we can generate it */
4326 /* the same way as a while */
4328 return newNode (NULLOP, initExpr,
4329 createWhile (trueLabel, continueLabel,
4330 falseLabel, condExpr, forBody));
4331 /* vanilla for statement */
4332 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4334 if (condExpr && !IS_IFX (condExpr))
4335 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4338 /* attach condition label to condition */
4339 condExpr = createLabel (condLabel, condExpr);
4341 /* attach body label to body */
4342 forBody = createLabel (trueLabel, forBody);
4344 /* attach continue to forLoop expression & attach */
4345 /* goto the forcond @ and of loopExpression */
4346 loopExpr = createLabel (continueLabel,
4350 newAst_VALUE (symbolVal (condLabel)),
4352 /* now start putting them together */
4353 forTree = newNode (NULLOP, initExpr, condExpr);
4354 forTree = newNode (NULLOP, forTree, forBody);
4355 forTree = newNode (NULLOP, forTree, loopExpr);
4356 /* finally add the break label */
4357 forTree = newNode (NULLOP, forTree,
4358 createLabel (falseLabel, NULL));
4362 /*-----------------------------------------------------------------*/
4363 /* createWhile - creates parse tree for while statement */
4364 /* the while statement will be created as follows */
4366 /* _while_continue_n: */
4367 /* condition_expression +-> trueLabel -> _while_boby_n */
4369 /* +-> falseLabel -> _while_break_n */
4370 /* _while_body_n: */
4372 /* goto _while_continue_n */
4373 /* _while_break_n: */
4374 /*-----------------------------------------------------------------*/
4376 createWhile (symbol * trueLabel, symbol * continueLabel,
4377 symbol * falseLabel, ast * condExpr, ast * whileBody)
4381 /* put the continue label */
4382 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4383 condExpr = createLabel (continueLabel, condExpr);
4384 condExpr->lineno = 0;
4386 /* put the body label in front of the body */
4387 whileBody = createLabel (trueLabel, whileBody);
4388 whileBody->lineno = 0;
4389 /* put a jump to continue at the end of the body */
4390 /* and put break label at the end of the body */
4391 whileBody = newNode (NULLOP,
4394 newAst_VALUE (symbolVal (continueLabel)),
4395 createLabel (falseLabel, NULL)));
4397 /* put it all together */
4398 if (IS_IFX (condExpr))
4399 whileTree = condExpr;
4402 whileTree = newNode (IFX, condExpr, NULL);
4403 /* put the true & false labels in place */
4404 whileTree->trueLabel = trueLabel;
4405 whileTree->falseLabel = falseLabel;
4408 return newNode (NULLOP, whileTree, whileBody);
4411 /*-----------------------------------------------------------------*/
4412 /* optimizeGetHbit - get highest order bit of the expression */
4413 /*-----------------------------------------------------------------*/
4415 optimizeGetHbit (ast * tree)
4418 /* if this is not a bit and */
4419 if (!IS_BITAND (tree))
4422 /* will look for tree of the form
4423 ( expr >> ((sizeof expr) -1) ) & 1 */
4424 if (!IS_AST_LIT_VALUE (tree->right))
4427 if (AST_LIT_VALUE (tree->right) != 1)
4430 if (!IS_RIGHT_OP (tree->left))
4433 if (!IS_AST_LIT_VALUE (tree->left->right))
4436 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4437 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4440 /* make sure the port supports GETHBIT */
4441 if (port->hasExtBitOp
4442 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4445 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4449 /*-----------------------------------------------------------------*/
4450 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4451 /*-----------------------------------------------------------------*/
4453 optimizeRRCRLC (ast * root)
4455 /* will look for trees of the form
4456 (?expr << 1) | (?expr >> 7) or
4457 (?expr >> 7) | (?expr << 1) will make that
4458 into a RLC : operation ..
4460 (?expr >> 1) | (?expr << 7) or
4461 (?expr << 7) | (?expr >> 1) will make that
4462 into a RRC operation
4463 note : by 7 I mean (number of bits required to hold the
4465 /* if the root operations is not a | operation the not */
4466 if (!IS_BITOR (root))
4469 /* I have to think of a better way to match patterns this sucks */
4470 /* that aside let start looking for the first case : I use a the
4471 negative check a lot to improve the efficiency */
4472 /* (?expr << 1) | (?expr >> 7) */
4473 if (IS_LEFT_OP (root->left) &&
4474 IS_RIGHT_OP (root->right))
4477 if (!SPEC_USIGN (TETYPE (root->left->left)))
4480 if (!IS_AST_LIT_VALUE (root->left->right) ||
4481 !IS_AST_LIT_VALUE (root->right->right))
4484 /* make sure it is the same expression */
4485 if (!isAstEqual (root->left->left,
4489 if (AST_LIT_VALUE (root->left->right) != 1)
4492 if (AST_LIT_VALUE (root->right->right) !=
4493 (getSize (TTYPE (root->left->left)) * 8 - 1))
4496 /* make sure the port supports RLC */
4497 if (port->hasExtBitOp
4498 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4501 /* whew got the first case : create the AST */
4502 return newNode (RLC, root->left->left, NULL);
4506 /* check for second case */
4507 /* (?expr >> 7) | (?expr << 1) */
4508 if (IS_LEFT_OP (root->right) &&
4509 IS_RIGHT_OP (root->left))
4512 if (!SPEC_USIGN (TETYPE (root->left->left)))
4515 if (!IS_AST_LIT_VALUE (root->left->right) ||
4516 !IS_AST_LIT_VALUE (root->right->right))
4519 /* make sure it is the same symbol */
4520 if (!isAstEqual (root->left->left,
4524 if (AST_LIT_VALUE (root->right->right) != 1)
4527 if (AST_LIT_VALUE (root->left->right) !=
4528 (getSize (TTYPE (root->left->left)) * 8 - 1))
4531 /* make sure the port supports RLC */
4532 if (port->hasExtBitOp
4533 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4536 /* whew got the first case : create the AST */
4537 return newNode (RLC, root->left->left, NULL);
4542 /* third case for RRC */
4543 /* (?symbol >> 1) | (?symbol << 7) */
4544 if (IS_LEFT_OP (root->right) &&
4545 IS_RIGHT_OP (root->left))
4548 if (!SPEC_USIGN (TETYPE (root->left->left)))
4551 if (!IS_AST_LIT_VALUE (root->left->right) ||
4552 !IS_AST_LIT_VALUE (root->right->right))
4555 /* make sure it is the same symbol */
4556 if (!isAstEqual (root->left->left,
4560 if (AST_LIT_VALUE (root->left->right) != 1)
4563 if (AST_LIT_VALUE (root->right->right) !=
4564 (getSize (TTYPE (root->left->left)) * 8 - 1))
4567 /* make sure the port supports RRC */
4568 if (port->hasExtBitOp
4569 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4572 /* whew got the first case : create the AST */
4573 return newNode (RRC, root->left->left, NULL);
4577 /* fourth and last case for now */
4578 /* (?symbol << 7) | (?symbol >> 1) */
4579 if (IS_RIGHT_OP (root->right) &&
4580 IS_LEFT_OP (root->left))
4583 if (!SPEC_USIGN (TETYPE (root->left->left)))
4586 if (!IS_AST_LIT_VALUE (root->left->right) ||
4587 !IS_AST_LIT_VALUE (root->right->right))
4590 /* make sure it is the same symbol */
4591 if (!isAstEqual (root->left->left,
4595 if (AST_LIT_VALUE (root->right->right) != 1)
4598 if (AST_LIT_VALUE (root->left->right) !=
4599 (getSize (TTYPE (root->left->left)) * 8 - 1))
4602 /* make sure the port supports RRC */
4603 if (port->hasExtBitOp
4604 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4607 /* whew got the first case : create the AST */
4608 return newNode (RRC, root->left->left, NULL);
4612 /* not found return root */
4616 /*-----------------------------------------------------------------*/
4617 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4618 /*-----------------------------------------------------------------*/
4620 optimizeSWAP (ast * root)
4622 /* will look for trees of the form
4623 (?expr << 4) | (?expr >> 4) or
4624 (?expr >> 4) | (?expr << 4) will make that
4625 into a SWAP : operation ..
4626 note : by 4 I mean (number of bits required to hold the
4628 /* if the root operations is not a | operation the not */
4629 if (!IS_BITOR (root))
4632 /* (?expr << 4) | (?expr >> 4) */
4633 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4634 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4637 if (!SPEC_USIGN (TETYPE (root->left->left)))
4640 if (!IS_AST_LIT_VALUE (root->left->right) ||
4641 !IS_AST_LIT_VALUE (root->right->right))
4644 /* make sure it is the same expression */
4645 if (!isAstEqual (root->left->left,
4649 if (AST_LIT_VALUE (root->left->right) !=
4650 (getSize (TTYPE (root->left->left)) * 4))
4653 if (AST_LIT_VALUE (root->right->right) !=
4654 (getSize (TTYPE (root->left->left)) * 4))
4657 /* make sure the port supports SWAP */
4658 if (port->hasExtBitOp
4659 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4662 /* found it : create the AST */
4663 return newNode (SWAP, root->left->left, NULL);
4667 /* not found return root */
4671 /*-----------------------------------------------------------------*/
4672 /* optimizeCompare - otimizes compares for bit variables */
4673 /*-----------------------------------------------------------------*/
4675 optimizeCompare (ast * root)
4677 ast *optExpr = NULL;
4680 unsigned int litValue;
4682 /* if nothing then return nothing */
4686 /* if not a compare op then do leaves */
4687 if (!IS_COMPARE_OP (root))
4689 root->left = optimizeCompare (root->left);
4690 root->right = optimizeCompare (root->right);
4694 /* if left & right are the same then depending
4695 of the operation do */
4696 if (isAstEqual (root->left, root->right))
4698 switch (root->opval.op)
4703 optExpr = newAst_VALUE (constVal ("0"));
4708 optExpr = newAst_VALUE (constVal ("1"));
4712 return decorateType (optExpr);
4715 vleft = (root->left->type == EX_VALUE ?
4716 root->left->opval.val : NULL);
4718 vright = (root->right->type == EX_VALUE ?
4719 root->right->opval.val : NULL);
4721 /* if left is a BITVAR in BITSPACE */
4722 /* and right is a LITERAL then opt- */
4723 /* imize else do nothing */
4724 if (vleft && vright &&
4725 IS_BITVAR (vleft->etype) &&
4726 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4727 IS_LITERAL (vright->etype))
4730 /* if right side > 1 then comparison may never succeed */
4731 if ((litValue = (int) floatFromVal (vright)) > 1)
4733 werror (W_BAD_COMPARE);
4739 switch (root->opval.op)
4741 case '>': /* bit value greater than 1 cannot be */
4742 werror (W_BAD_COMPARE);
4746 case '<': /* bit value < 1 means 0 */
4748 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4751 case LE_OP: /* bit value <= 1 means no check */
4752 optExpr = newAst_VALUE (vright);
4755 case GE_OP: /* bit value >= 1 means only check for = */
4757 optExpr = newAst_VALUE (vleft);
4762 { /* literal is zero */
4763 switch (root->opval.op)
4765 case '<': /* bit value < 0 cannot be */
4766 werror (W_BAD_COMPARE);
4770 case '>': /* bit value > 0 means 1 */
4772 optExpr = newAst_VALUE (vleft);
4775 case LE_OP: /* bit value <= 0 means no check */
4776 case GE_OP: /* bit value >= 0 means no check */
4777 werror (W_BAD_COMPARE);
4781 case EQ_OP: /* bit == 0 means ! of bit */
4782 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4786 return decorateType (resolveSymbols (optExpr));
4787 } /* end-of-if of BITVAR */
4792 /*-----------------------------------------------------------------*/
4793 /* addSymToBlock : adds the symbol to the first block we find */
4794 /*-----------------------------------------------------------------*/
4796 addSymToBlock (symbol * sym, ast * tree)
4798 /* reached end of tree or a leaf */
4799 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4803 if (IS_AST_OP (tree) &&
4804 tree->opval.op == BLOCK)
4807 symbol *lsym = copySymbol (sym);
4809 lsym->next = AST_VALUES (tree, sym);
4810 AST_VALUES (tree, sym) = lsym;
4814 addSymToBlock (sym, tree->left);
4815 addSymToBlock (sym, tree->right);
4818 /*-----------------------------------------------------------------*/
4819 /* processRegParms - do processing for register parameters */
4820 /*-----------------------------------------------------------------*/
4822 processRegParms (value * args, ast * body)
4826 if (IS_REGPARM (args->etype))
4827 addSymToBlock (args->sym, body);
4832 /*-----------------------------------------------------------------*/
4833 /* resetParmKey - resets the operandkeys for the symbols */
4834 /*-----------------------------------------------------------------*/
4835 DEFSETFUNC (resetParmKey)
4846 /*-----------------------------------------------------------------*/
4847 /* createFunction - This is the key node that calls the iCode for */
4848 /* generating the code for a function. Note code */
4849 /* is generated function by function, later when */
4850 /* add inter-procedural analysis this will change */
4851 /*-----------------------------------------------------------------*/
4853 createFunction (symbol * name, ast * body)
4859 iCode *piCode = NULL;
4861 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4862 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4864 /* if check function return 0 then some problem */
4865 if (checkFunction (name, NULL) == 0)
4868 /* create a dummy block if none exists */
4870 body = newNode (BLOCK, NULL, NULL);
4874 /* check if the function name already in the symbol table */
4875 if ((csym = findSym (SymbolTab, NULL, name->name)))
4878 /* special case for compiler defined functions
4879 we need to add the name to the publics list : this
4880 actually means we are now compiling the compiler
4884 addSet (&publics, name);
4890 allocVariables (name);
4892 name->lastLine = mylineno;
4895 /* set the stack pointer */
4896 /* PENDING: check this for the mcs51 */
4897 stackPtr = -port->stack.direction * port->stack.call_overhead;
4898 if (IFFUNC_ISISR (name->type))
4899 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4900 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4901 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4903 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4905 fetype = getSpec (name->type); /* get the specifier for the function */
4906 /* if this is a reentrant function then */
4907 if (IFFUNC_ISREENT (name->type))
4910 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4912 /* do processing for parameters that are passed in registers */
4913 processRegParms (FUNC_ARGS(name->type), body);
4915 /* set the stack pointer */
4919 /* allocate & autoinit the block variables */
4920 processBlockVars (body, &stack, ALLOCATE);
4922 /* save the stack information */
4923 if (options.useXstack)
4924 name->xstack = SPEC_STAK (fetype) = stack;
4926 name->stack = SPEC_STAK (fetype) = stack;
4928 /* name needs to be mangled */
4929 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4931 body = resolveSymbols (body); /* resolve the symbols */
4932 body = decorateType (body); /* propagateType & do semantic checks */
4934 ex = newAst_VALUE (symbolVal (name)); /* create name */
4935 ex = newNode (FUNCTION, ex, body);
4936 ex->values.args = FUNC_ARGS(name->type);
4938 if (options.dump_tree) PA(ex);
4941 werror (E_FUNC_NO_CODE, name->name);
4945 /* create the node & generate intermediate code */
4947 codeOutFile = code->oFile;
4948 piCode = iCodeFromAst (ex);
4952 werror (E_FUNC_NO_CODE, name->name);
4956 eBBlockFromiCode (piCode);
4958 /* if there are any statics then do them */
4961 GcurMemmap = statsg;
4962 codeOutFile = statsg->oFile;
4963 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4969 /* dealloc the block variables */
4970 processBlockVars (body, &stack, DEALLOCATE);
4971 outputDebugStackSymbols();
4972 /* deallocate paramaters */
4973 deallocParms (FUNC_ARGS(name->type));
4975 if (IFFUNC_ISREENT (name->type))
4978 /* we are done freeup memory & cleanup */
4980 if (port->reset_labelKey) labelKey = 1;
4982 FUNC_HASBODY(name->type) = 1;
4983 addSet (&operKeyReset, name);
4984 applyToSet (operKeyReset, resetParmKey);
4989 cleanUpLevel (LabelTab, 0);
4990 cleanUpBlock (StructTab, 1);
4991 cleanUpBlock (TypedefTab, 1);
4993 xstack->syms = NULL;
4994 istack->syms = NULL;
4999 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5000 /*-----------------------------------------------------------------*/
5001 /* ast_print : prints the ast (for debugging purposes) */
5002 /*-----------------------------------------------------------------*/
5004 void ast_print (ast * tree, FILE *outfile, int indent)
5009 /* can print only decorated trees */
5010 if (!tree->decorated) return;
5012 /* if any child is an error | this one is an error do nothing */
5013 if (tree->isError ||
5014 (tree->left && tree->left->isError) ||
5015 (tree->right && tree->right->isError)) {
5016 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5020 /* print the line */
5021 /* if not block & function */
5022 if (tree->type == EX_OP &&
5023 (tree->opval.op != FUNCTION &&
5024 tree->opval.op != BLOCK &&
5025 tree->opval.op != NULLOP)) {
5028 if (tree->opval.op == FUNCTION) {
5030 value *args=FUNC_ARGS(tree->left->opval.val->type);
5031 fprintf(outfile,"FUNCTION (%s=%p) type (",
5032 tree->left->opval.val->name, tree);
5033 printTypeChain (tree->left->opval.val->type->next,outfile);
5034 fprintf(outfile,") args (");
5037 fprintf (outfile, ", ");
5039 printTypeChain (args ? args->type : NULL, outfile);
5041 args= args ? args->next : NULL;
5043 fprintf(outfile,")\n");
5044 ast_print(tree->left,outfile,indent);
5045 ast_print(tree->right,outfile,indent);
5048 if (tree->opval.op == BLOCK) {
5049 symbol *decls = tree->values.sym;
5050 INDENT(indent,outfile);
5051 fprintf(outfile,"{\n");
5053 INDENT(indent+2,outfile);
5054 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5055 decls->name, decls);
5056 printTypeChain(decls->type,outfile);
5057 fprintf(outfile,")\n");
5059 decls = decls->next;
5061 ast_print(tree->right,outfile,indent+2);
5062 INDENT(indent,outfile);
5063 fprintf(outfile,"}\n");
5066 if (tree->opval.op == NULLOP) {
5067 ast_print(tree->left,outfile,indent);
5068 ast_print(tree->right,outfile,indent);
5071 INDENT(indent,outfile);
5073 /*------------------------------------------------------------------*/
5074 /*----------------------------*/
5075 /* leaf has been reached */
5076 /*----------------------------*/
5077 /* if this is of type value */
5078 /* just get the type */
5079 if (tree->type == EX_VALUE) {
5081 if (IS_LITERAL (tree->opval.val->etype)) {
5082 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5083 if (SPEC_USIGN (tree->opval.val->etype))
5084 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5086 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5087 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5088 floatFromVal(tree->opval.val));
5089 } else if (tree->opval.val->sym) {
5090 /* if the undefined flag is set then give error message */
5091 if (tree->opval.val->sym->undefined) {
5092 fprintf(outfile,"UNDEFINED SYMBOL ");
5094 fprintf(outfile,"SYMBOL ");
5096 fprintf(outfile,"(%s=%p)",
5097 tree->opval.val->sym->name,tree);
5100 fprintf(outfile," type (");
5101 printTypeChain(tree->ftype,outfile);
5102 fprintf(outfile,")\n");
5104 fprintf(outfile,"\n");
5109 /* if type link for the case of cast */
5110 if (tree->type == EX_LINK) {
5111 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5112 printTypeChain(tree->opval.lnk,outfile);
5113 fprintf(outfile,")\n");
5118 /* depending on type of operator do */
5120 switch (tree->opval.op) {
5121 /*------------------------------------------------------------------*/
5122 /*----------------------------*/
5124 /*----------------------------*/
5126 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5127 printTypeChain(tree->ftype,outfile);
5128 fprintf(outfile,")\n");
5129 ast_print(tree->left,outfile,indent+2);
5130 ast_print(tree->right,outfile,indent+2);
5133 /*------------------------------------------------------------------*/
5134 /*----------------------------*/
5136 /*----------------------------*/
5138 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5139 printTypeChain(tree->ftype,outfile);
5140 fprintf(outfile,")\n");
5141 ast_print(tree->left,outfile,indent+2);
5142 ast_print(tree->right,outfile,indent+2);
5145 /*------------------------------------------------------------------*/
5146 /*----------------------------*/
5147 /* struct/union pointer */
5148 /*----------------------------*/
5150 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5151 printTypeChain(tree->ftype,outfile);
5152 fprintf(outfile,")\n");
5153 ast_print(tree->left,outfile,indent+2);
5154 ast_print(tree->right,outfile,indent+2);
5157 /*------------------------------------------------------------------*/
5158 /*----------------------------*/
5159 /* ++/-- operation */
5160 /*----------------------------*/
5163 fprintf(outfile,"post-");
5165 fprintf(outfile,"pre-");
5166 fprintf(outfile,"INC_OP (%p) type (",tree);
5167 printTypeChain(tree->ftype,outfile);
5168 fprintf(outfile,")\n");
5169 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5170 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5175 fprintf(outfile,"post-");
5177 fprintf(outfile,"pre-");
5178 fprintf(outfile,"DEC_OP (%p) type (",tree);
5179 printTypeChain(tree->ftype,outfile);
5180 fprintf(outfile,")\n");
5181 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5182 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5185 /*------------------------------------------------------------------*/
5186 /*----------------------------*/
5188 /*----------------------------*/
5191 fprintf(outfile,"& (%p) type (",tree);
5192 printTypeChain(tree->ftype,outfile);
5193 fprintf(outfile,")\n");
5194 ast_print(tree->left,outfile,indent+2);
5195 ast_print(tree->right,outfile,indent+2);
5197 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5198 printTypeChain(tree->ftype,outfile);
5199 fprintf(outfile,")\n");
5200 ast_print(tree->left,outfile,indent+2);
5201 ast_print(tree->right,outfile,indent+2);
5204 /*----------------------------*/
5206 /*----------------------------*/
5208 fprintf(outfile,"OR (%p) type (",tree);
5209 printTypeChain(tree->ftype,outfile);
5210 fprintf(outfile,")\n");
5211 ast_print(tree->left,outfile,indent+2);
5212 ast_print(tree->right,outfile,indent+2);
5214 /*------------------------------------------------------------------*/
5215 /*----------------------------*/
5217 /*----------------------------*/
5219 fprintf(outfile,"XOR (%p) type (",tree);
5220 printTypeChain(tree->ftype,outfile);
5221 fprintf(outfile,")\n");
5222 ast_print(tree->left,outfile,indent+2);
5223 ast_print(tree->right,outfile,indent+2);
5226 /*------------------------------------------------------------------*/
5227 /*----------------------------*/
5229 /*----------------------------*/
5231 fprintf(outfile,"DIV (%p) type (",tree);
5232 printTypeChain(tree->ftype,outfile);
5233 fprintf(outfile,")\n");
5234 ast_print(tree->left,outfile,indent+2);
5235 ast_print(tree->right,outfile,indent+2);
5237 /*------------------------------------------------------------------*/
5238 /*----------------------------*/
5240 /*----------------------------*/
5242 fprintf(outfile,"MOD (%p) type (",tree);
5243 printTypeChain(tree->ftype,outfile);
5244 fprintf(outfile,")\n");
5245 ast_print(tree->left,outfile,indent+2);
5246 ast_print(tree->right,outfile,indent+2);
5249 /*------------------------------------------------------------------*/
5250 /*----------------------------*/
5251 /* address dereference */
5252 /*----------------------------*/
5253 case '*': /* can be unary : if right is null then unary operation */
5255 fprintf(outfile,"DEREF (%p) type (",tree);
5256 printTypeChain(tree->ftype,outfile);
5257 fprintf(outfile,")\n");
5258 ast_print(tree->left,outfile,indent+2);
5261 /*------------------------------------------------------------------*/
5262 /*----------------------------*/
5263 /* multiplication */
5264 /*----------------------------*/
5265 fprintf(outfile,"MULT (%p) type (",tree);
5266 printTypeChain(tree->ftype,outfile);
5267 fprintf(outfile,")\n");
5268 ast_print(tree->left,outfile,indent+2);
5269 ast_print(tree->right,outfile,indent+2);
5273 /*------------------------------------------------------------------*/
5274 /*----------------------------*/
5275 /* unary '+' operator */
5276 /*----------------------------*/
5280 fprintf(outfile,"UPLUS (%p) type (",tree);
5281 printTypeChain(tree->ftype,outfile);
5282 fprintf(outfile,")\n");
5283 ast_print(tree->left,outfile,indent+2);
5285 /*------------------------------------------------------------------*/
5286 /*----------------------------*/
5288 /*----------------------------*/
5289 fprintf(outfile,"ADD (%p) type (",tree);
5290 printTypeChain(tree->ftype,outfile);
5291 fprintf(outfile,")\n");
5292 ast_print(tree->left,outfile,indent+2);
5293 ast_print(tree->right,outfile,indent+2);
5296 /*------------------------------------------------------------------*/
5297 /*----------------------------*/
5299 /*----------------------------*/
5300 case '-': /* can be unary */
5302 fprintf(outfile,"UMINUS (%p) type (",tree);
5303 printTypeChain(tree->ftype,outfile);
5304 fprintf(outfile,")\n");
5305 ast_print(tree->left,outfile,indent+2);
5307 /*------------------------------------------------------------------*/
5308 /*----------------------------*/
5310 /*----------------------------*/
5311 fprintf(outfile,"SUB (%p) type (",tree);
5312 printTypeChain(tree->ftype,outfile);
5313 fprintf(outfile,")\n");
5314 ast_print(tree->left,outfile,indent+2);
5315 ast_print(tree->right,outfile,indent+2);
5318 /*------------------------------------------------------------------*/
5319 /*----------------------------*/
5321 /*----------------------------*/
5323 fprintf(outfile,"COMPL (%p) type (",tree);
5324 printTypeChain(tree->ftype,outfile);
5325 fprintf(outfile,")\n");
5326 ast_print(tree->left,outfile,indent+2);
5328 /*------------------------------------------------------------------*/
5329 /*----------------------------*/
5331 /*----------------------------*/
5333 fprintf(outfile,"NOT (%p) type (",tree);
5334 printTypeChain(tree->ftype,outfile);
5335 fprintf(outfile,")\n");
5336 ast_print(tree->left,outfile,indent+2);
5338 /*------------------------------------------------------------------*/
5339 /*----------------------------*/
5341 /*----------------------------*/
5343 fprintf(outfile,"RRC (%p) type (",tree);
5344 printTypeChain(tree->ftype,outfile);
5345 fprintf(outfile,")\n");
5346 ast_print(tree->left,outfile,indent+2);
5350 fprintf(outfile,"RLC (%p) type (",tree);
5351 printTypeChain(tree->ftype,outfile);
5352 fprintf(outfile,")\n");
5353 ast_print(tree->left,outfile,indent+2);
5356 fprintf(outfile,"SWAP (%p) type (",tree);
5357 printTypeChain(tree->ftype,outfile);
5358 fprintf(outfile,")\n");
5359 ast_print(tree->left,outfile,indent+2);
5362 fprintf(outfile,"GETHBIT (%p) type (",tree);
5363 printTypeChain(tree->ftype,outfile);
5364 fprintf(outfile,")\n");
5365 ast_print(tree->left,outfile,indent+2);
5368 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5369 printTypeChain(tree->ftype,outfile);
5370 fprintf(outfile,")\n");
5371 ast_print(tree->left,outfile,indent+2);
5372 ast_print(tree->right,outfile,indent+2);
5375 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5376 printTypeChain(tree->ftype,outfile);
5377 fprintf(outfile,")\n");
5378 ast_print(tree->left,outfile,indent+2);
5379 ast_print(tree->right,outfile,indent+2);
5381 /*------------------------------------------------------------------*/
5382 /*----------------------------*/
5384 /*----------------------------*/
5385 case CAST: /* change the type */
5386 fprintf(outfile,"CAST (%p) from type (",tree);
5387 printTypeChain(tree->right->ftype,outfile);
5388 fprintf(outfile,") to type (");
5389 printTypeChain(tree->ftype,outfile);
5390 fprintf(outfile,")\n");
5391 ast_print(tree->right,outfile,indent+2);
5395 fprintf(outfile,"ANDAND (%p) type (",tree);
5396 printTypeChain(tree->ftype,outfile);
5397 fprintf(outfile,")\n");
5398 ast_print(tree->left,outfile,indent+2);
5399 ast_print(tree->right,outfile,indent+2);
5402 fprintf(outfile,"OROR (%p) type (",tree);
5403 printTypeChain(tree->ftype,outfile);
5404 fprintf(outfile,")\n");
5405 ast_print(tree->left,outfile,indent+2);
5406 ast_print(tree->right,outfile,indent+2);
5409 /*------------------------------------------------------------------*/
5410 /*----------------------------*/
5411 /* comparison operators */
5412 /*----------------------------*/
5414 fprintf(outfile,"GT(>) (%p) type (",tree);
5415 printTypeChain(tree->ftype,outfile);
5416 fprintf(outfile,")\n");
5417 ast_print(tree->left,outfile,indent+2);
5418 ast_print(tree->right,outfile,indent+2);
5421 fprintf(outfile,"LT(<) (%p) type (",tree);
5422 printTypeChain(tree->ftype,outfile);
5423 fprintf(outfile,")\n");
5424 ast_print(tree->left,outfile,indent+2);
5425 ast_print(tree->right,outfile,indent+2);
5428 fprintf(outfile,"LE(<=) (%p) type (",tree);
5429 printTypeChain(tree->ftype,outfile);
5430 fprintf(outfile,")\n");
5431 ast_print(tree->left,outfile,indent+2);
5432 ast_print(tree->right,outfile,indent+2);
5435 fprintf(outfile,"GE(>=) (%p) type (",tree);
5436 printTypeChain(tree->ftype,outfile);
5437 fprintf(outfile,")\n");
5438 ast_print(tree->left,outfile,indent+2);
5439 ast_print(tree->right,outfile,indent+2);
5442 fprintf(outfile,"EQ(==) (%p) type (",tree);
5443 printTypeChain(tree->ftype,outfile);
5444 fprintf(outfile,")\n");
5445 ast_print(tree->left,outfile,indent+2);
5446 ast_print(tree->right,outfile,indent+2);
5449 fprintf(outfile,"NE(!=) (%p) type (",tree);
5450 printTypeChain(tree->ftype,outfile);
5451 fprintf(outfile,")\n");
5452 ast_print(tree->left,outfile,indent+2);
5453 ast_print(tree->right,outfile,indent+2);
5454 /*------------------------------------------------------------------*/
5455 /*----------------------------*/
5457 /*----------------------------*/
5458 case SIZEOF: /* evaluate wihout code generation */
5459 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5462 /*------------------------------------------------------------------*/
5463 /*----------------------------*/
5464 /* conditional operator '?' */
5465 /*----------------------------*/
5467 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5468 printTypeChain(tree->ftype,outfile);
5469 fprintf(outfile,")\n");
5470 ast_print(tree->left,outfile,indent+2);
5471 ast_print(tree->right,outfile,indent+2);
5475 fprintf(outfile,"COLON(:) (%p) type (",tree);
5476 printTypeChain(tree->ftype,outfile);
5477 fprintf(outfile,")\n");
5478 ast_print(tree->left,outfile,indent+2);
5479 ast_print(tree->right,outfile,indent+2);
5482 /*------------------------------------------------------------------*/
5483 /*----------------------------*/
5484 /* assignment operators */
5485 /*----------------------------*/
5487 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5488 printTypeChain(tree->ftype,outfile);
5489 fprintf(outfile,")\n");
5490 ast_print(tree->left,outfile,indent+2);
5491 ast_print(tree->right,outfile,indent+2);
5494 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5495 printTypeChain(tree->ftype,outfile);
5496 fprintf(outfile,")\n");
5497 ast_print(tree->left,outfile,indent+2);
5498 ast_print(tree->right,outfile,indent+2);
5501 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5502 printTypeChain(tree->ftype,outfile);
5503 fprintf(outfile,")\n");
5504 ast_print(tree->left,outfile,indent+2);
5505 ast_print(tree->right,outfile,indent+2);
5508 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5509 printTypeChain(tree->ftype,outfile);
5510 fprintf(outfile,")\n");
5511 ast_print(tree->left,outfile,indent+2);
5512 ast_print(tree->right,outfile,indent+2);
5515 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5516 printTypeChain(tree->ftype,outfile);
5517 fprintf(outfile,")\n");
5518 ast_print(tree->left,outfile,indent+2);
5519 ast_print(tree->right,outfile,indent+2);
5522 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5523 printTypeChain(tree->ftype,outfile);
5524 fprintf(outfile,")\n");
5525 ast_print(tree->left,outfile,indent+2);
5526 ast_print(tree->right,outfile,indent+2);
5529 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5530 printTypeChain(tree->ftype,outfile);
5531 fprintf(outfile,")\n");
5532 ast_print(tree->left,outfile,indent+2);
5533 ast_print(tree->right,outfile,indent+2);
5535 /*------------------------------------------------------------------*/
5536 /*----------------------------*/
5538 /*----------------------------*/
5540 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5541 printTypeChain(tree->ftype,outfile);
5542 fprintf(outfile,")\n");
5543 ast_print(tree->left,outfile,indent+2);
5544 ast_print(tree->right,outfile,indent+2);
5546 /*------------------------------------------------------------------*/
5547 /*----------------------------*/
5549 /*----------------------------*/
5551 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5552 printTypeChain(tree->ftype,outfile);
5553 fprintf(outfile,")\n");
5554 ast_print(tree->left,outfile,indent+2);
5555 ast_print(tree->right,outfile,indent+2);
5557 /*------------------------------------------------------------------*/
5558 /*----------------------------*/
5559 /* straight assignemnt */
5560 /*----------------------------*/
5562 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5563 printTypeChain(tree->ftype,outfile);
5564 fprintf(outfile,")\n");
5565 ast_print(tree->left,outfile,indent+2);
5566 ast_print(tree->right,outfile,indent+2);
5568 /*------------------------------------------------------------------*/
5569 /*----------------------------*/
5570 /* comma operator */
5571 /*----------------------------*/
5573 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5574 printTypeChain(tree->ftype,outfile);
5575 fprintf(outfile,")\n");
5576 ast_print(tree->left,outfile,indent+2);
5577 ast_print(tree->right,outfile,indent+2);
5579 /*------------------------------------------------------------------*/
5580 /*----------------------------*/
5582 /*----------------------------*/
5585 fprintf(outfile,"CALL (%p) type (",tree);
5586 printTypeChain(tree->ftype,outfile);
5587 fprintf(outfile,")\n");
5588 ast_print(tree->left,outfile,indent+2);
5589 ast_print(tree->right,outfile,indent+2);
5592 fprintf(outfile,"PARMS\n");
5593 ast_print(tree->left,outfile,indent+2);
5594 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5595 ast_print(tree->right,outfile,indent+2);
5598 /*------------------------------------------------------------------*/
5599 /*----------------------------*/
5600 /* return statement */
5601 /*----------------------------*/
5603 fprintf(outfile,"RETURN (%p) type (",tree);
5605 printTypeChain(tree->right->ftype,outfile);
5607 fprintf(outfile,")\n");
5608 ast_print(tree->right,outfile,indent+2);
5610 /*------------------------------------------------------------------*/
5611 /*----------------------------*/
5612 /* label statement */
5613 /*----------------------------*/
5615 fprintf(outfile,"LABEL (%p)\n",tree);
5616 ast_print(tree->left,outfile,indent+2);
5617 ast_print(tree->right,outfile,indent);
5619 /*------------------------------------------------------------------*/
5620 /*----------------------------*/
5621 /* switch statement */
5622 /*----------------------------*/
5626 fprintf(outfile,"SWITCH (%p) ",tree);
5627 ast_print(tree->left,outfile,0);
5628 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5629 INDENT(indent+2,outfile);
5630 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5631 (int) floatFromVal(val),
5632 tree->values.switchVals.swNum,
5633 (int) floatFromVal(val));
5635 ast_print(tree->right,outfile,indent);
5638 /*------------------------------------------------------------------*/
5639 /*----------------------------*/
5641 /*----------------------------*/
5643 fprintf(outfile,"IF (%p) \n",tree);
5644 ast_print(tree->left,outfile,indent+2);
5645 if (tree->trueLabel) {
5646 INDENT(indent+2,outfile);
5647 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5649 if (tree->falseLabel) {
5650 INDENT(indent+2,outfile);
5651 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5653 ast_print(tree->right,outfile,indent+2);
5655 /*----------------------------*/
5656 /* goto Statement */
5657 /*----------------------------*/
5659 fprintf(outfile,"GOTO (%p) \n",tree);
5660 ast_print(tree->left,outfile,indent+2);
5661 fprintf(outfile,"\n");
5663 /*------------------------------------------------------------------*/
5664 /*----------------------------*/
5666 /*----------------------------*/
5668 fprintf(outfile,"FOR (%p) \n",tree);
5669 if (AST_FOR( tree, initExpr)) {
5670 INDENT(indent+2,outfile);
5671 fprintf(outfile,"INIT EXPR ");
5672 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5674 if (AST_FOR( tree, condExpr)) {
5675 INDENT(indent+2,outfile);
5676 fprintf(outfile,"COND EXPR ");
5677 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5679 if (AST_FOR( tree, loopExpr)) {
5680 INDENT(indent+2,outfile);
5681 fprintf(outfile,"LOOP EXPR ");
5682 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5684 fprintf(outfile,"FOR LOOP BODY \n");
5685 ast_print(tree->left,outfile,indent+2);
5688 fprintf(outfile,"CRITICAL (%p) \n",tree);
5689 ast_print(tree->left,outfile,indent+2);
5697 ast_print(t,stdout,0);