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
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 ast *optimizeRRCRLC (ast *);
54 ast *optimizeGetHbit (ast *);
55 ast *backPatchLabels (ast *, symbol *, symbol *);
58 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
63 printTypeChain (tree->ftype, stdout);
68 /*-----------------------------------------------------------------*/
69 /* newAst - creates a fresh node for an expression tree */
70 /*-----------------------------------------------------------------*/
72 newAst_ (unsigned type)
75 static int oldLineno = 0;
77 ex = Safe_alloc ( sizeof (ast));
80 ex->lineno = (noLineno ? oldLineno : yylineno);
81 ex->filename = currFname;
82 ex->level = NestLevel;
83 ex->block = currBlockno;
84 ex->initMode = inInitMode;
89 newAst_VALUE (value * val)
91 ast *ex = newAst_ (EX_VALUE);
97 newAst_OP (unsigned op)
99 ast *ex = newAst_ (EX_OP);
105 newAst_LINK (sym_link * val)
107 ast *ex = newAst_ (EX_LINK);
113 newAst_STMNT (unsigned val)
115 ast *ex = newAst_ (EX_STMNT);
116 ex->opval.stmnt = val;
120 /*-----------------------------------------------------------------*/
121 /* newNode - creates a new node */
122 /*-----------------------------------------------------------------*/
124 newNode (long op, ast * left, ast * right)
135 /*-----------------------------------------------------------------*/
136 /* newIfxNode - creates a new Ifx Node */
137 /*-----------------------------------------------------------------*/
139 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
143 /* if this is a literal then we already know the result */
144 if (condAst->etype && IS_LITERAL (condAst->etype))
146 /* then depending on the expression value */
147 if (floatFromVal (condAst->opval.val))
148 ifxNode = newNode (GOTO,
149 newAst_VALUE (symbolVal (trueLabel)),
152 ifxNode = newNode (GOTO,
153 newAst_VALUE (symbolVal (falseLabel)),
158 ifxNode = newNode (IFX, condAst, NULL);
159 ifxNode->trueLabel = trueLabel;
160 ifxNode->falseLabel = falseLabel;
166 /*-----------------------------------------------------------------*/
167 /* copyAstValues - copies value portion of ast if needed */
168 /*-----------------------------------------------------------------*/
170 copyAstValues (ast * dest, ast * src)
172 switch (src->opval.op)
175 dest->values.sym = copySymbolChain (src->values.sym);
179 dest->values.switchVals.swVals =
180 copyValue (src->values.switchVals.swVals);
181 dest->values.switchVals.swDefault =
182 src->values.switchVals.swDefault;
183 dest->values.switchVals.swNum =
184 src->values.switchVals.swNum;
188 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
189 strcpy (dest->values.inlineasm, src->values.inlineasm);
193 dest->values.constlist = copyLiteralList(src->values.constlist);
197 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
198 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
199 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
200 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
201 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
202 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
203 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
208 /*-----------------------------------------------------------------*/
209 /* copyAst - makes a copy of a given astession */
210 /*-----------------------------------------------------------------*/
219 dest = Safe_alloc ( sizeof (ast));
221 dest->type = src->type;
222 dest->lineno = src->lineno;
223 dest->level = src->level;
224 dest->funcName = src->funcName;
227 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
229 /* if this is a leaf */
231 if (src->type == EX_VALUE)
233 dest->opval.val = copyValue (src->opval.val);
238 if (src->type == EX_LINK)
240 dest->opval.lnk = copyLinkChain (src->opval.lnk);
244 dest->opval.op = src->opval.op;
246 /* if this is a node that has special values */
247 copyAstValues (dest, src);
249 dest->trueLabel = copySymbol (src->trueLabel);
250 dest->falseLabel = copySymbol (src->falseLabel);
251 dest->left = copyAst (src->left);
252 dest->right = copyAst (src->right);
258 /*-----------------------------------------------------------------*/
259 /* hasSEFcalls - returns TRUE if tree has a function call */
260 /*-----------------------------------------------------------------*/
262 hasSEFcalls (ast * tree)
267 if (tree->type == EX_OP &&
268 (tree->opval.op == CALL ||
269 tree->opval.op == PCALL ||
270 tree->opval.op == '=' ||
271 tree->opval.op == INC_OP ||
272 tree->opval.op == DEC_OP))
275 return (hasSEFcalls (tree->left) |
276 hasSEFcalls (tree->right));
279 /*-----------------------------------------------------------------*/
280 /* isAstEqual - compares two asts & returns 1 if they are equal */
281 /*-----------------------------------------------------------------*/
283 isAstEqual (ast * t1, ast * t2)
292 if (t1->type != t2->type)
298 if (t1->opval.op != t2->opval.op)
300 return (isAstEqual (t1->left, t2->left) &&
301 isAstEqual (t1->right, t2->right));
305 if (t1->opval.val->sym)
307 if (!t2->opval.val->sym)
310 return isSymbolEqual (t1->opval.val->sym,
315 if (t2->opval.val->sym)
318 return (floatFromVal (t1->opval.val) ==
319 floatFromVal (t2->opval.val));
323 /* only compare these two types */
331 /*-----------------------------------------------------------------*/
332 /* resolveSymbols - resolve symbols from the symbol table */
333 /*-----------------------------------------------------------------*/
335 resolveSymbols (ast * tree)
337 /* walk the entire tree and check for values */
338 /* with symbols if we find one then replace */
339 /* symbol with that from the symbol table */
345 /* if not block & function */
346 if (tree->type == EX_OP &&
347 (tree->opval.op != FUNCTION &&
348 tree->opval.op != BLOCK &&
349 tree->opval.op != NULLOP))
351 filename = tree->filename;
352 lineno = tree->lineno;
355 /* make sure we resolve the true & false labels for ifx */
356 if (tree->type == EX_OP && tree->opval.op == IFX)
362 if ((csym = findSym (LabelTab, tree->trueLabel,
363 tree->trueLabel->name)))
364 tree->trueLabel = csym;
366 werror (E_LABEL_UNDEF, tree->trueLabel->name);
369 if (tree->falseLabel)
371 if ((csym = findSym (LabelTab,
373 tree->falseLabel->name)))
374 tree->falseLabel = csym;
376 werror (E_LABEL_UNDEF, tree->falseLabel->name);
381 /* if this is a label resolve it from the labelTab */
382 if (IS_AST_VALUE (tree) &&
383 tree->opval.val->sym &&
384 tree->opval.val->sym->islbl)
387 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
388 tree->opval.val->sym->name);
391 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
393 tree->opval.val->sym = csym;
395 goto resolveChildren;
398 /* do only for leafs */
399 if (IS_AST_VALUE (tree) &&
400 tree->opval.val->sym &&
401 !tree->opval.val->sym->implicit)
404 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
406 /* if found in the symbol table & they r not the same */
407 if (csym && tree->opval.val->sym != csym)
409 tree->opval.val->sym = csym;
410 tree->opval.val->type = csym->type;
411 tree->opval.val->etype = csym->etype;
414 /* if not found in the symbol table */
415 /* mark it as undefined assume it is */
416 /* an integer in data space */
417 if (!csym && !tree->opval.val->sym->implicit)
420 /* if this is a function name then */
421 /* mark it as returning an int */
424 tree->opval.val->sym->type = newLink ();
425 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
426 tree->opval.val->sym->type->next =
427 tree->opval.val->sym->etype = newIntLink ();
428 tree->opval.val->etype = tree->opval.val->etype;
429 tree->opval.val->type = tree->opval.val->sym->type;
430 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
431 allocVariables (tree->opval.val->sym);
435 tree->opval.val->sym->undefined = 1;
436 tree->opval.val->type =
437 tree->opval.val->etype = newIntLink ();
438 tree->opval.val->sym->type =
439 tree->opval.val->sym->etype = newIntLink ();
445 resolveSymbols (tree->left);
446 resolveSymbols (tree->right);
451 /*-----------------------------------------------------------------*/
452 /* setAstLineno - walks a ast tree & sets the line number */
453 /*-----------------------------------------------------------------*/
455 setAstLineno (ast * tree, int lineno)
460 tree->lineno = lineno;
461 setAstLineno (tree->left, lineno);
462 setAstLineno (tree->right, lineno);
466 /*-----------------------------------------------------------------*/
467 /* funcOfType :- function of type with name */
468 /*-----------------------------------------------------------------*/
470 funcOfType (char *name, sym_link * type, sym_link * argType,
474 /* create the symbol */
475 sym = newSymbol (name, 0);
477 /* setup return value */
478 sym->type = newLink ();
479 DCL_TYPE (sym->type) = FUNCTION;
480 sym->type->next = copyLinkChain (type);
481 sym->etype = getSpec (sym->type);
482 FUNC_ISREENT(sym->type) = rent;
484 /* if arguments required */
488 args = FUNC_ARGS(sym->type) = newValue ();
492 args->type = copyLinkChain (argType);
493 args->etype = getSpec (args->type);
494 SPEC_EXTR(args->etype)=1;
497 args = args->next = newValue ();
504 allocVariables (sym);
509 /*-----------------------------------------------------------------*/
510 /* funcOfTypeVarg :- function of type with name and argtype */
511 /*-----------------------------------------------------------------*/
513 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
518 /* create the symbol */
519 sym = newSymbol (name, 0);
521 /* setup return value */
522 sym->type = newLink ();
523 DCL_TYPE (sym->type) = FUNCTION;
524 sym->type->next = typeFromStr(rtype);
525 sym->etype = getSpec (sym->type);
527 /* if arguments required */
530 args = FUNC_ARGS(sym->type) = newValue ();
532 for ( i = 0 ; i < nArgs ; i++ ) {
533 args->type = typeFromStr(atypes[i]);
534 args->etype = getSpec (args->type);
535 SPEC_EXTR(args->etype)=1;
536 if ((i + 1) == nArgs) break;
537 args = args->next = newValue ();
544 allocVariables (sym);
549 /*-----------------------------------------------------------------*/
550 /* reverseParms - will reverse a parameter tree */
551 /*-----------------------------------------------------------------*/
553 reverseParms (ast * ptree)
559 /* top down if we find a nonParm tree then quit */
560 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
563 ptree->left = ptree->right;
564 ptree->right = ttree;
565 reverseParms (ptree->left);
566 reverseParms (ptree->right);
572 /*-----------------------------------------------------------------*/
573 /* processParms - makes sure the parameters are okay and do some */
574 /* processing with them */
575 /*-----------------------------------------------------------------*/
577 processParms (ast * func,
580 int *parmNumber, // unused, although updated
583 /* if none of them exist */
584 if (!defParm && !actParm)
588 if (getenv("DEBUG_SANITY")) {
589 fprintf (stderr, "processParms: %s ", defParm->name);
591 /* make sure the type is complete and sane */
592 checkTypeSanity(defParm->etype, defParm->name);
595 /* if the function is being called via a pointer & */
596 /* it has not been defined a reentrant then we cannot */
597 /* have parameters */
598 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
600 werror (W_NONRENT_ARGS);
604 /* if defined parameters ended but actual parameters */
605 /* exist and this is not defined as a variable arg */
606 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
608 werror (E_TOO_MANY_PARMS);
612 /* if defined parameters present but no actual parameters */
613 if (defParm && !actParm)
615 werror (E_TOO_FEW_PARMS);
619 if (IS_VOID(actParm->ftype)) {
620 werror (E_VOID_VALUE_USED);
624 /* If this is a varargs function... */
625 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
630 if (IS_CAST_OP (actParm)
631 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
633 /* Parameter was explicitly typecast; don't touch it. */
637 ftype = actParm->ftype;
639 /* If it's a small integer, upcast to int. */
640 if (IS_INTEGRAL (ftype)
641 && (getSize (ftype) < (unsigned) INTSIZE))
643 newType = newAst_LINK(INTTYPE);
646 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
648 newType = newAst_LINK (copyLinkChain(ftype));
649 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
652 if (IS_AGGREGATE (ftype))
654 newType = newAst_LINK (copyLinkChain (ftype));
655 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
659 /* cast required; change this op to a cast. */
660 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
662 actParm->type = EX_OP;
663 actParm->opval.op = CAST;
664 actParm->left = newType;
665 actParm->right = parmCopy;
666 decorateType (actParm);
668 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
670 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
671 processParms (func, NULL, actParm->right, parmNumber, rightmost));
676 /* if defined parameters ended but actual has not & */
678 if (!defParm && actParm &&
679 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
682 resolveSymbols (actParm);
683 /* if this is a PARAM node then match left & right */
684 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
686 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
687 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
691 /* If we have found a value node by following only right-hand links,
692 * then we know that there are no more values after us.
694 * Therefore, if there are more defined parameters, the caller didn't
697 if (rightmost && defParm->next)
699 werror (E_TOO_FEW_PARMS);
704 /* the parameter type must be at least castable */
705 if (compareType (defParm->type, actParm->ftype) == 0) {
706 werror (E_INCOMPAT_TYPES);
707 printFromToType (actParm->ftype, defParm->type);
711 /* if the parameter is castable then add the cast */
712 if (compareType (defParm->type, actParm->ftype) < 0)
714 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
716 /* now change the current one to a cast */
717 actParm->type = EX_OP;
718 actParm->opval.op = CAST;
719 actParm->left = newAst_LINK (defParm->type);
720 actParm->right = pTree;
721 actParm->etype = defParm->etype;
722 actParm->ftype = defParm->type;
723 actParm->decorated=0; /* force typechecking */
724 decorateType (actParm);
727 /* make a copy and change the regparm type to the defined parm */
728 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
729 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
733 /*-----------------------------------------------------------------*/
734 /* createIvalType - generates ival for basic types */
735 /*-----------------------------------------------------------------*/
737 createIvalType (ast * sym, sym_link * type, initList * ilist)
741 /* if initList is deep */
742 if (ilist->type == INIT_DEEP)
743 ilist = ilist->init.deep;
745 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
746 return decorateType (newNode ('=', sym, iExpr));
749 /*-----------------------------------------------------------------*/
750 /* createIvalStruct - generates initial value for structures */
751 /*-----------------------------------------------------------------*/
753 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
760 sflds = SPEC_STRUCT (type)->fields;
761 if (ilist->type != INIT_DEEP)
763 werror (E_INIT_STRUCT, "");
767 iloop = ilist->init.deep;
769 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
771 /* if we have come to end */
775 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
776 lAst = decorateType (resolveSymbols (lAst));
777 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
781 werror (W_EXCESS_INITIALIZERS, "struct",
782 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
789 /*-----------------------------------------------------------------*/
790 /* createIvalArray - generates code for array initialization */
791 /*-----------------------------------------------------------------*/
793 createIvalArray (ast * sym, sym_link * type, initList * ilist)
797 int lcnt = 0, size = 0;
798 literalList *literalL;
800 /* take care of the special case */
801 /* array of characters can be init */
803 if (IS_CHAR (type->next))
804 if ((rast = createIvalCharPtr (sym,
806 decorateType (resolveSymbols (list2expr (ilist))))))
808 return decorateType (resolveSymbols (rast));
810 /* not the special case */
811 if (ilist->type != INIT_DEEP)
813 werror (E_INIT_STRUCT, "");
817 iloop = ilist->init.deep;
818 lcnt = DCL_ELEM (type);
820 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
824 aSym = decorateType (resolveSymbols(sym));
826 rast = newNode(ARRAYINIT, aSym, NULL);
827 rast->values.constlist = literalL;
829 // Make sure size is set to length of initializer list.
836 if (lcnt && size > lcnt)
838 // Array size was specified, and we have more initializers than needed.
839 char *name=sym->opval.val->sym->name;
840 int lineno=sym->opval.val->sym->lineDef;
842 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
851 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
852 aSym = decorateType (resolveSymbols (aSym));
853 rast = createIval (aSym, type->next, iloop, rast);
854 iloop = (iloop ? iloop->next : NULL);
860 /* no of elements given and we */
861 /* have generated for all of them */
864 // there has to be a better way
865 char *name=sym->opval.val->sym->name;
866 int lineno=sym->opval.val->sym->lineDef;
867 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
874 /* if we have not been given a size */
875 if (!DCL_ELEM (type))
877 DCL_ELEM (type) = size;
880 return decorateType (resolveSymbols (rast));
884 /*-----------------------------------------------------------------*/
885 /* createIvalCharPtr - generates initial values for char pointers */
886 /*-----------------------------------------------------------------*/
888 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
892 /* if this is a pointer & right is a literal array then */
893 /* just assignment will do */
894 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
895 SPEC_SCLS (iexpr->etype) == S_CODE)
896 && IS_ARRAY (iexpr->ftype)))
897 return newNode ('=', sym, iexpr);
899 /* left side is an array so we have to assign each */
901 if ((IS_LITERAL (iexpr->etype) ||
902 SPEC_SCLS (iexpr->etype) == S_CODE)
903 && IS_ARRAY (iexpr->ftype))
905 /* for each character generate an assignment */
906 /* to the array element */
907 char *s = SPEC_CVAL (iexpr->etype).v_char;
912 rast = newNode (NULLOP,
916 newAst_VALUE (valueFromLit ((float) i))),
917 newAst_VALUE (valueFromLit (*s))));
921 rast = newNode (NULLOP,
925 newAst_VALUE (valueFromLit ((float) i))),
926 newAst_VALUE (valueFromLit (*s))));
927 return decorateType (resolveSymbols (rast));
933 /*-----------------------------------------------------------------*/
934 /* createIvalPtr - generates initial value for pointers */
935 /*-----------------------------------------------------------------*/
937 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
943 if (ilist->type == INIT_DEEP)
944 ilist = ilist->init.deep;
946 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
948 /* if character pointer */
949 if (IS_CHAR (type->next))
950 if ((rast = createIvalCharPtr (sym, type, iexpr)))
953 return newNode ('=', sym, iexpr);
956 /*-----------------------------------------------------------------*/
957 /* createIval - generates code for initial value */
958 /*-----------------------------------------------------------------*/
960 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
967 /* if structure then */
968 if (IS_STRUCT (type))
969 rast = createIvalStruct (sym, type, ilist);
971 /* if this is a pointer */
973 rast = createIvalPtr (sym, type, ilist);
975 /* if this is an array */
977 rast = createIvalArray (sym, type, ilist);
979 /* if type is SPECIFIER */
981 rast = createIvalType (sym, type, ilist);
984 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
986 return decorateType (resolveSymbols (rast));
989 /*-----------------------------------------------------------------*/
990 /* initAggregates - initialises aggregate variables with initv */
991 /*-----------------------------------------------------------------*/
992 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
993 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
996 /*-----------------------------------------------------------------*/
997 /* gatherAutoInit - creates assignment expressions for initial */
999 /*-----------------------------------------------------------------*/
1001 gatherAutoInit (symbol * autoChain)
1008 for (sym = autoChain; sym; sym = sym->next)
1011 /* resolve the symbols in the ival */
1013 resolveIvalSym (sym->ival);
1015 /* if this is a static variable & has an */
1016 /* initial value the code needs to be lifted */
1017 /* here to the main portion since they can be */
1018 /* initialised only once at the start */
1019 if (IS_STATIC (sym->etype) && sym->ival &&
1020 SPEC_SCLS (sym->etype) != S_CODE)
1024 /* insert the symbol into the symbol table */
1025 /* with level = 0 & name = rname */
1026 newSym = copySymbol (sym);
1027 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1029 /* now lift the code to main */
1030 if (IS_AGGREGATE (sym->type)) {
1031 work = initAggregates (sym, sym->ival, NULL);
1033 if (getNelements(sym->type, sym->ival)>1) {
1034 werror (W_EXCESS_INITIALIZERS, "scalar",
1035 sym->name, sym->lineDef);
1037 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1038 list2expr (sym->ival));
1041 setAstLineno (work, sym->lineDef);
1045 staticAutos = newNode (NULLOP, staticAutos, work);
1052 /* if there is an initial value */
1053 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1055 if (IS_AGGREGATE (sym->type)) {
1056 work = initAggregates (sym, sym->ival, NULL);
1058 if (getNelements(sym->type, sym->ival)>1) {
1059 werror (W_EXCESS_INITIALIZERS, "scalar",
1060 sym->name, sym->lineDef);
1062 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1063 list2expr (sym->ival));
1066 setAstLineno (work, sym->lineDef);
1069 init = newNode (NULLOP, init, work);
1078 /*-----------------------------------------------------------------*/
1079 /* stringToSymbol - creates a symbol from a literal string */
1080 /*-----------------------------------------------------------------*/
1082 stringToSymbol (value * val)
1084 char name[SDCC_NAME_MAX + 1];
1085 static int charLbl = 0;
1088 sprintf (name, "_str_%d", charLbl++);
1089 sym = newSymbol (name, 0); /* make it @ level 0 */
1090 strcpy (sym->rname, name);
1092 /* copy the type from the value passed */
1093 sym->type = copyLinkChain (val->type);
1094 sym->etype = getSpec (sym->type);
1095 /* change to storage class & output class */
1096 SPEC_SCLS (sym->etype) = S_CODE;
1097 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1098 SPEC_STAT (sym->etype) = 1;
1099 /* make the level & block = 0 */
1100 sym->block = sym->level = 0;
1102 /* create an ival */
1103 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1108 allocVariables (sym);
1111 return symbolVal (sym);
1115 /*-----------------------------------------------------------------*/
1116 /* processBlockVars - will go thru the ast looking for block if */
1117 /* a block is found then will allocate the syms */
1118 /* will also gather the auto inits present */
1119 /*-----------------------------------------------------------------*/
1121 processBlockVars (ast * tree, int *stack, int action)
1126 /* if this is a block */
1127 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1131 if (action == ALLOCATE)
1133 *stack += allocVariables (tree->values.sym);
1134 autoInit = gatherAutoInit (tree->values.sym);
1136 /* if there are auto inits then do them */
1138 tree->left = newNode (NULLOP, autoInit, tree->left);
1140 else /* action is deallocate */
1141 deallocLocal (tree->values.sym);
1144 processBlockVars (tree->left, stack, action);
1145 processBlockVars (tree->right, stack, action);
1149 /*-----------------------------------------------------------------*/
1150 /* constExprValue - returns the value of a constant expression */
1151 /* or NULL if it is not a constant expression */
1152 /*-----------------------------------------------------------------*/
1154 constExprValue (ast * cexpr, int check)
1156 cexpr = decorateType (resolveSymbols (cexpr));
1158 /* if this is not a constant then */
1159 if (!IS_LITERAL (cexpr->ftype))
1161 /* then check if this is a literal array
1163 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1164 SPEC_CVAL (cexpr->etype).v_char &&
1165 IS_ARRAY (cexpr->ftype))
1167 value *val = valFromType (cexpr->ftype);
1168 SPEC_SCLS (val->etype) = S_LITERAL;
1169 val->sym = cexpr->opval.val->sym;
1170 val->sym->type = copyLinkChain (cexpr->ftype);
1171 val->sym->etype = getSpec (val->sym->type);
1172 strcpy (val->name, cexpr->opval.val->sym->rname);
1176 /* if we are casting a literal value then */
1177 if (IS_AST_OP (cexpr) &&
1178 cexpr->opval.op == CAST &&
1179 IS_LITERAL (cexpr->left->ftype))
1180 return valCastLiteral (cexpr->ftype,
1181 floatFromVal (cexpr->left->opval.val));
1183 if (IS_AST_VALUE (cexpr))
1184 return cexpr->opval.val;
1187 werror (E_CONST_EXPECTED, "found expression");
1192 /* return the value */
1193 return cexpr->opval.val;
1197 /*-----------------------------------------------------------------*/
1198 /* isLabelInAst - will return true if a given label is found */
1199 /*-----------------------------------------------------------------*/
1201 isLabelInAst (symbol * label, ast * tree)
1203 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1206 if (IS_AST_OP (tree) &&
1207 tree->opval.op == LABEL &&
1208 isSymbolEqual (AST_SYMBOL (tree->left), label))
1211 return isLabelInAst (label, tree->right) &&
1212 isLabelInAst (label, tree->left);
1216 /*-----------------------------------------------------------------*/
1217 /* isLoopCountable - return true if the loop count can be determi- */
1218 /* -ned at compile time . */
1219 /*-----------------------------------------------------------------*/
1221 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1222 symbol ** sym, ast ** init, ast ** end)
1225 /* the loop is considered countable if the following
1226 conditions are true :-
1228 a) initExpr :- <sym> = <const>
1229 b) condExpr :- <sym> < <const1>
1230 c) loopExpr :- <sym> ++
1233 /* first check the initExpr */
1234 if (IS_AST_OP (initExpr) &&
1235 initExpr->opval.op == '=' && /* is assignment */
1236 IS_AST_SYM_VALUE (initExpr->left))
1237 { /* left is a symbol */
1239 *sym = AST_SYMBOL (initExpr->left);
1240 *init = initExpr->right;
1245 /* for now the symbol has to be of
1247 if (!IS_INTEGRAL ((*sym)->type))
1250 /* now check condExpr */
1251 if (IS_AST_OP (condExpr))
1254 switch (condExpr->opval.op)
1257 if (IS_AST_SYM_VALUE (condExpr->left) &&
1258 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1259 IS_AST_LIT_VALUE (condExpr->right))
1261 *end = condExpr->right;
1267 if (IS_AST_OP (condExpr->left) &&
1268 condExpr->left->opval.op == '>' &&
1269 IS_AST_LIT_VALUE (condExpr->left->right) &&
1270 IS_AST_SYM_VALUE (condExpr->left->left) &&
1271 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1274 *end = newNode ('+', condExpr->left->right,
1275 newAst_VALUE (constVal ("1")));
1286 /* check loop expression is of the form <sym>++ */
1287 if (!IS_AST_OP (loopExpr))
1290 /* check if <sym> ++ */
1291 if (loopExpr->opval.op == INC_OP)
1297 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1298 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1305 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1306 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1314 if (loopExpr->opval.op == ADD_ASSIGN)
1317 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1318 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1319 IS_AST_LIT_VALUE (loopExpr->right) &&
1320 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1328 /*-----------------------------------------------------------------*/
1329 /* astHasVolatile - returns true if ast contains any volatile */
1330 /*-----------------------------------------------------------------*/
1332 astHasVolatile (ast * tree)
1337 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1340 if (IS_AST_OP (tree))
1341 return astHasVolatile (tree->left) ||
1342 astHasVolatile (tree->right);
1347 /*-----------------------------------------------------------------*/
1348 /* astHasPointer - return true if the ast contains any ptr variable */
1349 /*-----------------------------------------------------------------*/
1351 astHasPointer (ast * tree)
1356 if (IS_AST_LINK (tree))
1359 /* if we hit an array expression then check
1360 only the left side */
1361 if (IS_AST_OP (tree) && tree->opval.op == '[')
1362 return astHasPointer (tree->left);
1364 if (IS_AST_VALUE (tree))
1365 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1367 return astHasPointer (tree->left) ||
1368 astHasPointer (tree->right);
1372 /*-----------------------------------------------------------------*/
1373 /* astHasSymbol - return true if the ast has the given symbol */
1374 /*-----------------------------------------------------------------*/
1376 astHasSymbol (ast * tree, symbol * sym)
1378 if (!tree || IS_AST_LINK (tree))
1381 if (IS_AST_VALUE (tree))
1383 if (IS_AST_SYM_VALUE (tree))
1384 return isSymbolEqual (AST_SYMBOL (tree), sym);
1389 return astHasSymbol (tree->left, sym) ||
1390 astHasSymbol (tree->right, sym);
1393 /*-----------------------------------------------------------------*/
1394 /* astHasDeref - return true if the ast has an indirect access */
1395 /*-----------------------------------------------------------------*/
1397 astHasDeref (ast * tree)
1399 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1402 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1404 return astHasDeref (tree->left) || astHasDeref (tree->right);
1407 /*-----------------------------------------------------------------*/
1408 /* isConformingBody - the loop body has to conform to a set of rules */
1409 /* for the loop to be considered reversible read on for rules */
1410 /*-----------------------------------------------------------------*/
1412 isConformingBody (ast * pbody, symbol * sym, ast * body)
1415 /* we are going to do a pre-order traversal of the
1416 tree && check for the following conditions. (essentially
1417 a set of very shallow tests )
1418 a) the sym passed does not participate in
1419 any arithmetic operation
1420 b) There are no function calls
1421 c) all jumps are within the body
1422 d) address of loop control variable not taken
1423 e) if an assignment has a pointer on the
1424 left hand side make sure right does not have
1425 loop control variable */
1427 /* if we reach the end or a leaf then true */
1428 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1432 /* if anything else is "volatile" */
1433 if (IS_VOLATILE (TETYPE (pbody)))
1436 /* we will walk the body in a pre-order traversal for
1438 switch (pbody->opval.op)
1440 /*------------------------------------------------------------------*/
1442 return isConformingBody (pbody->right, sym, body);
1444 /*------------------------------------------------------------------*/
1449 /*------------------------------------------------------------------*/
1450 case INC_OP: /* incerement operator unary so left only */
1453 /* sure we are not sym is not modified */
1455 IS_AST_SYM_VALUE (pbody->left) &&
1456 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1460 IS_AST_SYM_VALUE (pbody->right) &&
1461 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1466 /*------------------------------------------------------------------*/
1468 case '*': /* can be unary : if right is null then unary operation */
1473 /* if right is NULL then unary operation */
1474 /*------------------------------------------------------------------*/
1475 /*----------------------------*/
1477 /*----------------------------*/
1480 if (IS_AST_SYM_VALUE (pbody->left) &&
1481 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1484 return isConformingBody (pbody->left, sym, body);
1488 if (astHasSymbol (pbody->left, sym) ||
1489 astHasSymbol (pbody->right, sym))
1494 /*------------------------------------------------------------------*/
1502 if (IS_AST_SYM_VALUE (pbody->left) &&
1503 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1506 if (IS_AST_SYM_VALUE (pbody->right) &&
1507 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1510 return isConformingBody (pbody->left, sym, body) &&
1511 isConformingBody (pbody->right, sym, body);
1518 if (IS_AST_SYM_VALUE (pbody->left) &&
1519 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1521 return isConformingBody (pbody->left, sym, body);
1523 /*------------------------------------------------------------------*/
1535 case SIZEOF: /* evaluate wihout code generation */
1537 return isConformingBody (pbody->left, sym, body) &&
1538 isConformingBody (pbody->right, sym, body);
1540 /*------------------------------------------------------------------*/
1543 /* if left has a pointer & right has loop
1544 control variable then we cannot */
1545 if (astHasPointer (pbody->left) &&
1546 astHasSymbol (pbody->right, sym))
1548 if (astHasVolatile (pbody->left))
1551 if (IS_AST_SYM_VALUE (pbody->left) &&
1552 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1555 if (astHasVolatile (pbody->left))
1558 if (astHasDeref(pbody->right)) return FALSE;
1560 return isConformingBody (pbody->left, sym, body) &&
1561 isConformingBody (pbody->right, sym, body);
1572 assert ("Parser should not have generated this\n");
1574 /*------------------------------------------------------------------*/
1575 /*----------------------------*/
1576 /* comma operator */
1577 /*----------------------------*/
1579 return isConformingBody (pbody->left, sym, body) &&
1580 isConformingBody (pbody->right, sym, body);
1582 /*------------------------------------------------------------------*/
1583 /*----------------------------*/
1585 /*----------------------------*/
1589 /*------------------------------------------------------------------*/
1590 /*----------------------------*/
1591 /* return statement */
1592 /*----------------------------*/
1597 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1602 if (astHasSymbol (pbody->left, sym))
1609 return isConformingBody (pbody->left, sym, body) &&
1610 isConformingBody (pbody->right, sym, body);
1616 /*-----------------------------------------------------------------*/
1617 /* isLoopReversible - takes a for loop as input && returns true */
1618 /* if the for loop is reversible. If yes will set the value of */
1619 /* the loop control var & init value & termination value */
1620 /*-----------------------------------------------------------------*/
1622 isLoopReversible (ast * loop, symbol ** loopCntrl,
1623 ast ** init, ast ** end)
1625 /* if option says don't do it then don't */
1626 if (optimize.noLoopReverse)
1628 /* there are several tests to determine this */
1630 /* for loop has to be of the form
1631 for ( <sym> = <const1> ;
1632 [<sym> < <const2>] ;
1633 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1635 if (!isLoopCountable (AST_FOR (loop, initExpr),
1636 AST_FOR (loop, condExpr),
1637 AST_FOR (loop, loopExpr),
1638 loopCntrl, init, end))
1641 /* now do some serious checking on the body of the loop
1644 return isConformingBody (loop->left, *loopCntrl, loop->left);
1648 /*-----------------------------------------------------------------*/
1649 /* replLoopSym - replace the loop sym by loop sym -1 */
1650 /*-----------------------------------------------------------------*/
1652 replLoopSym (ast * body, symbol * sym)
1655 if (!body || IS_AST_LINK (body))
1658 if (IS_AST_SYM_VALUE (body))
1661 if (isSymbolEqual (AST_SYMBOL (body), sym))
1665 body->opval.op = '-';
1666 body->left = newAst_VALUE (symbolVal (sym));
1667 body->right = newAst_VALUE (constVal ("1"));
1675 replLoopSym (body->left, sym);
1676 replLoopSym (body->right, sym);
1680 /*-----------------------------------------------------------------*/
1681 /* reverseLoop - do the actual loop reversal */
1682 /*-----------------------------------------------------------------*/
1684 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1688 /* create the following tree
1693 if (sym) goto for_continue ;
1696 /* put it together piece by piece */
1697 rloop = newNode (NULLOP,
1698 createIf (newAst_VALUE (symbolVal (sym)),
1700 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1703 newAst_VALUE (symbolVal (sym)),
1706 replLoopSym (loop->left, sym);
1708 rloop = newNode (NULLOP,
1710 newAst_VALUE (symbolVal (sym)),
1711 newNode ('-', end, init)),
1712 createLabel (AST_FOR (loop, continueLabel),
1716 newNode (SUB_ASSIGN,
1717 newAst_VALUE (symbolVal (sym)),
1718 newAst_VALUE (constVal ("1"))),
1721 return decorateType (rloop);
1725 /*-----------------------------------------------------------------*/
1726 /* decorateType - compute type for this tree also does type cheking */
1727 /* this is done bottom up, since type have to flow upwards */
1728 /* it also does constant folding, and paramater checking */
1729 /*-----------------------------------------------------------------*/
1731 decorateType (ast * tree)
1739 /* if already has type then do nothing */
1740 if (tree->decorated)
1743 tree->decorated = 1;
1745 /* print the line */
1746 /* if not block & function */
1747 if (tree->type == EX_OP &&
1748 (tree->opval.op != FUNCTION &&
1749 tree->opval.op != BLOCK &&
1750 tree->opval.op != NULLOP))
1752 filename = tree->filename;
1753 lineno = tree->lineno;
1756 /* if any child is an error | this one is an error do nothing */
1757 if (tree->isError ||
1758 (tree->left && tree->left->isError) ||
1759 (tree->right && tree->right->isError))
1762 /*------------------------------------------------------------------*/
1763 /*----------------------------*/
1764 /* leaf has been reached */
1765 /*----------------------------*/
1766 /* if this is of type value */
1767 /* just get the type */
1768 if (tree->type == EX_VALUE)
1771 if (IS_LITERAL (tree->opval.val->etype))
1774 /* if this is a character array then declare it */
1775 if (IS_ARRAY (tree->opval.val->type))
1776 tree->opval.val = stringToSymbol (tree->opval.val);
1778 /* otherwise just copy the type information */
1779 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1783 if (tree->opval.val->sym)
1785 /* if the undefined flag is set then give error message */
1786 if (tree->opval.val->sym->undefined)
1788 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1790 TTYPE (tree) = TETYPE (tree) =
1791 tree->opval.val->type = tree->opval.val->sym->type =
1792 tree->opval.val->etype = tree->opval.val->sym->etype =
1793 copyLinkChain (INTTYPE);
1798 /* if impilicit i.e. struct/union member then no type */
1799 if (tree->opval.val->sym->implicit)
1800 TTYPE (tree) = TETYPE (tree) = NULL;
1805 /* else copy the type */
1806 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1808 /* and mark it as referenced */
1809 tree->opval.val->sym->isref = 1;
1817 /* if type link for the case of cast */
1818 if (tree->type == EX_LINK)
1820 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1827 dtl = decorateType (tree->left);
1828 /* delay right side for '?' operator since conditional macro expansions might
1830 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1832 /* this is to take care of situations
1833 when the tree gets rewritten */
1834 if (dtl != tree->left)
1836 if (dtr != tree->right)
1840 /* depending on type of operator do */
1842 switch (tree->opval.op)
1844 /*------------------------------------------------------------------*/
1845 /*----------------------------*/
1847 /*----------------------------*/
1850 /* determine which is the array & which the index */
1851 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1854 ast *tempTree = tree->left;
1855 tree->left = tree->right;
1856 tree->right = tempTree;
1859 /* first check if this is a array or a pointer */
1860 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1862 werror (E_NEED_ARRAY_PTR, "[]");
1863 goto errorTreeReturn;
1866 /* check if the type of the idx */
1867 if (!IS_INTEGRAL (RTYPE (tree)))
1869 werror (E_IDX_NOT_INT);
1870 goto errorTreeReturn;
1873 /* if the left is an rvalue then error */
1876 werror (E_LVALUE_REQUIRED, "array access");
1877 goto errorTreeReturn;
1880 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1881 if (IS_PTR(LTYPE(tree))) {
1882 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1886 /*------------------------------------------------------------------*/
1887 /*----------------------------*/
1889 /*----------------------------*/
1891 /* if this is not a structure */
1892 if (!IS_STRUCT (LTYPE (tree)))
1894 werror (E_STRUCT_UNION, ".");
1895 goto errorTreeReturn;
1897 TTYPE (tree) = structElemType (LTYPE (tree),
1898 (tree->right->type == EX_VALUE ?
1899 tree->right->opval.val : NULL));
1900 TETYPE (tree) = getSpec (TTYPE (tree));
1903 /*------------------------------------------------------------------*/
1904 /*----------------------------*/
1905 /* struct/union pointer */
1906 /*----------------------------*/
1908 /* if not pointer to a structure */
1909 if (!IS_PTR (LTYPE (tree)))
1911 werror (E_PTR_REQD);
1912 goto errorTreeReturn;
1915 if (!IS_STRUCT (LTYPE (tree)->next))
1917 werror (E_STRUCT_UNION, "->");
1918 goto errorTreeReturn;
1921 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1922 (tree->right->type == EX_VALUE ?
1923 tree->right->opval.val : NULL));
1924 TETYPE (tree) = getSpec (TTYPE (tree));
1926 /* adjust the storage class */
1927 switch (DCL_TYPE(tree->left->ftype)) {
1931 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
1934 SPEC_SCLS(TETYPE(tree)) = S_CODE;
1939 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
1942 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
1945 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
1954 /*------------------------------------------------------------------*/
1955 /*----------------------------*/
1956 /* ++/-- operation */
1957 /*----------------------------*/
1958 case INC_OP: /* incerement operator unary so left only */
1961 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1962 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1963 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
1964 werror (E_CODE_WRITE, "++/--");
1973 /*------------------------------------------------------------------*/
1974 /*----------------------------*/
1976 /*----------------------------*/
1977 case '&': /* can be unary */
1978 /* if right is NULL then unary operation */
1979 if (tree->right) /* not an unary operation */
1982 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1984 werror (E_BITWISE_OP);
1985 werror (W_CONTINUE, "left & right types are ");
1986 printTypeChain (LTYPE (tree), stderr);
1987 fprintf (stderr, ",");
1988 printTypeChain (RTYPE (tree), stderr);
1989 fprintf (stderr, "\n");
1990 goto errorTreeReturn;
1993 /* if they are both literal */
1994 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
1996 tree->type = EX_VALUE;
1997 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
1998 valFromType (RETYPE (tree)), '&');
2000 tree->right = tree->left = NULL;
2001 TETYPE (tree) = tree->opval.val->etype;
2002 TTYPE (tree) = tree->opval.val->type;
2006 /* see if this is a GETHBIT operation if yes
2009 ast *otree = optimizeGetHbit (tree);
2012 return decorateType (otree);
2016 computeType (LTYPE (tree), RTYPE (tree));
2017 TETYPE (tree) = getSpec (TTYPE (tree));
2019 LRVAL (tree) = RRVAL (tree) = 1;
2023 /*------------------------------------------------------------------*/
2024 /*----------------------------*/
2026 /*----------------------------*/
2028 p->class = DECLARATOR;
2029 /* if bit field then error */
2030 if (IS_BITVAR (tree->left->etype))
2032 werror (E_ILLEGAL_ADDR, "address of bit variable");
2033 goto errorTreeReturn;
2036 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2038 werror (E_ILLEGAL_ADDR, "address of register variable");
2039 goto errorTreeReturn;
2042 if (IS_FUNC (LTYPE (tree)))
2044 werror (E_ILLEGAL_ADDR, "address of function");
2045 goto errorTreeReturn;
2048 if (IS_LITERAL(LTYPE(tree)))
2050 werror (E_ILLEGAL_ADDR, "address of literal");
2051 goto errorTreeReturn;
2056 werror (E_LVALUE_REQUIRED, "address of");
2057 goto errorTreeReturn;
2059 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2061 DCL_TYPE (p) = CPOINTER;
2062 DCL_PTR_CONST (p) = port->mem.code_ro;
2064 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2065 DCL_TYPE (p) = FPOINTER;
2066 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2067 DCL_TYPE (p) = PPOINTER;
2068 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2069 DCL_TYPE (p) = IPOINTER;
2070 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2071 DCL_TYPE (p) = EEPPOINTER;
2072 else if (SPEC_OCLS(tree->left->etype))
2073 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2075 DCL_TYPE (p) = POINTER;
2077 if (IS_AST_SYM_VALUE (tree->left))
2079 AST_SYMBOL (tree->left)->addrtaken = 1;
2080 AST_SYMBOL (tree->left)->allocreq = 1;
2083 p->next = LTYPE (tree);
2085 TETYPE (tree) = getSpec (TTYPE (tree));
2086 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2087 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2092 /*------------------------------------------------------------------*/
2093 /*----------------------------*/
2095 /*----------------------------*/
2097 /* if the rewrite succeeds then don't go any furthur */
2099 ast *wtree = optimizeRRCRLC (tree);
2101 return decorateType (wtree);
2103 /*------------------------------------------------------------------*/
2104 /*----------------------------*/
2106 /*----------------------------*/
2108 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2110 werror (E_BITWISE_OP);
2111 werror (W_CONTINUE, "left & right types are ");
2112 printTypeChain (LTYPE (tree), stderr);
2113 fprintf (stderr, ",");
2114 printTypeChain (RTYPE (tree), stderr);
2115 fprintf (stderr, "\n");
2116 goto errorTreeReturn;
2119 /* if they are both literal then */
2120 /* rewrite the tree */
2121 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2123 tree->type = EX_VALUE;
2124 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2125 valFromType (RETYPE (tree)),
2127 tree->right = tree->left = NULL;
2128 TETYPE (tree) = tree->opval.val->etype;
2129 TTYPE (tree) = tree->opval.val->type;
2132 LRVAL (tree) = RRVAL (tree) = 1;
2133 TETYPE (tree) = getSpec (TTYPE (tree) =
2134 computeType (LTYPE (tree),
2137 /*------------------------------------------------------------------*/
2138 /*----------------------------*/
2140 /*----------------------------*/
2142 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2144 werror (E_INVALID_OP, "divide");
2145 goto errorTreeReturn;
2147 /* if they are both literal then */
2148 /* rewrite the tree */
2149 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2151 tree->type = EX_VALUE;
2152 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2153 valFromType (RETYPE (tree)));
2154 tree->right = tree->left = NULL;
2155 TETYPE (tree) = getSpec (TTYPE (tree) =
2156 tree->opval.val->type);
2159 LRVAL (tree) = RRVAL (tree) = 1;
2160 TETYPE (tree) = getSpec (TTYPE (tree) =
2161 computeType (LTYPE (tree),
2165 /*------------------------------------------------------------------*/
2166 /*----------------------------*/
2168 /*----------------------------*/
2170 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2172 werror (E_BITWISE_OP);
2173 werror (W_CONTINUE, "left & right types are ");
2174 printTypeChain (LTYPE (tree), stderr);
2175 fprintf (stderr, ",");
2176 printTypeChain (RTYPE (tree), stderr);
2177 fprintf (stderr, "\n");
2178 goto errorTreeReturn;
2180 /* if they are both literal then */
2181 /* rewrite the tree */
2182 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2184 tree->type = EX_VALUE;
2185 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2186 valFromType (RETYPE (tree)));
2187 tree->right = tree->left = NULL;
2188 TETYPE (tree) = getSpec (TTYPE (tree) =
2189 tree->opval.val->type);
2192 LRVAL (tree) = RRVAL (tree) = 1;
2193 TETYPE (tree) = getSpec (TTYPE (tree) =
2194 computeType (LTYPE (tree),
2198 /*------------------------------------------------------------------*/
2199 /*----------------------------*/
2200 /* address dereference */
2201 /*----------------------------*/
2202 case '*': /* can be unary : if right is null then unary operation */
2205 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2207 werror (E_PTR_REQD);
2208 goto errorTreeReturn;
2213 werror (E_LVALUE_REQUIRED, "pointer deref");
2214 goto errorTreeReturn;
2216 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2217 LTYPE (tree)->next : NULL);
2218 TETYPE (tree) = getSpec (TTYPE (tree));
2219 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2223 /*------------------------------------------------------------------*/
2224 /*----------------------------*/
2225 /* multiplication */
2226 /*----------------------------*/
2227 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2229 werror (E_INVALID_OP, "multiplication");
2230 goto errorTreeReturn;
2233 /* if they are both literal then */
2234 /* rewrite the tree */
2235 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2237 tree->type = EX_VALUE;
2238 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2239 valFromType (RETYPE (tree)));
2240 tree->right = tree->left = NULL;
2241 TETYPE (tree) = getSpec (TTYPE (tree) =
2242 tree->opval.val->type);
2246 /* if left is a literal exchange left & right */
2247 if (IS_LITERAL (LTYPE (tree)))
2249 ast *tTree = tree->left;
2250 tree->left = tree->right;
2251 tree->right = tTree;
2254 LRVAL (tree) = RRVAL (tree) = 1;
2255 /* promote result to int if left & right are char
2256 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2257 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2258 TETYPE (tree) = getSpec (TTYPE (tree) =
2259 computeType (LTYPE (tree),
2261 SPEC_NOUN(TETYPE(tree)) = V_INT;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 computeType (LTYPE (tree),
2269 /*------------------------------------------------------------------*/
2270 /*----------------------------*/
2271 /* unary '+' operator */
2272 /*----------------------------*/
2277 if (!IS_INTEGRAL (LTYPE (tree)))
2279 werror (E_UNARY_OP, '+');
2280 goto errorTreeReturn;
2283 /* if left is a literal then do it */
2284 if (IS_LITERAL (LTYPE (tree)))
2286 tree->type = EX_VALUE;
2287 tree->opval.val = valFromType (LETYPE (tree));
2289 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2293 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2297 /*------------------------------------------------------------------*/
2298 /*----------------------------*/
2300 /*----------------------------*/
2302 /* this is not a unary operation */
2303 /* if both pointers then problem */
2304 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2305 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2307 werror (E_PTR_PLUS_PTR);
2308 goto errorTreeReturn;
2311 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2312 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2314 werror (E_PLUS_INVALID, "+");
2315 goto errorTreeReturn;
2318 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2319 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2321 werror (E_PLUS_INVALID, "+");
2322 goto errorTreeReturn;
2324 /* if they are both literal then */
2325 /* rewrite the tree */
2326 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2328 tree->type = EX_VALUE;
2329 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2330 valFromType (RETYPE (tree)));
2331 tree->right = tree->left = NULL;
2332 TETYPE (tree) = getSpec (TTYPE (tree) =
2333 tree->opval.val->type);
2337 /* if the right is a pointer or left is a literal
2338 xchange left & right */
2339 if (IS_ARRAY (RTYPE (tree)) ||
2340 IS_PTR (RTYPE (tree)) ||
2341 IS_LITERAL (LTYPE (tree)))
2343 ast *tTree = tree->left;
2344 tree->left = tree->right;
2345 tree->right = tTree;
2348 LRVAL (tree) = RRVAL (tree) = 1;
2349 /* if the left is a pointer */
2350 if (IS_PTR (LTYPE (tree)))
2351 TETYPE (tree) = getSpec (TTYPE (tree) =
2354 TETYPE (tree) = getSpec (TTYPE (tree) =
2355 computeType (LTYPE (tree),
2359 /*------------------------------------------------------------------*/
2360 /*----------------------------*/
2362 /*----------------------------*/
2363 case '-': /* can be unary */
2364 /* if right is null then unary */
2368 if (!IS_ARITHMETIC (LTYPE (tree)))
2370 werror (E_UNARY_OP, tree->opval.op);
2371 goto errorTreeReturn;
2374 /* if left is a literal then do it */
2375 if (IS_LITERAL (LTYPE (tree)))
2377 tree->type = EX_VALUE;
2378 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2380 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2381 SPEC_USIGN(TETYPE(tree)) = 0;
2385 TTYPE (tree) = LTYPE (tree);
2389 /*------------------------------------------------------------------*/
2390 /*----------------------------*/
2392 /*----------------------------*/
2394 if (!(IS_PTR (LTYPE (tree)) ||
2395 IS_ARRAY (LTYPE (tree)) ||
2396 IS_ARITHMETIC (LTYPE (tree))))
2398 werror (E_PLUS_INVALID, "-");
2399 goto errorTreeReturn;
2402 if (!(IS_PTR (RTYPE (tree)) ||
2403 IS_ARRAY (RTYPE (tree)) ||
2404 IS_ARITHMETIC (RTYPE (tree))))
2406 werror (E_PLUS_INVALID, "-");
2407 goto errorTreeReturn;
2410 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2411 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2412 IS_INTEGRAL (RTYPE (tree))))
2414 werror (E_PLUS_INVALID, "-");
2415 goto errorTreeReturn;
2418 /* if they are both literal then */
2419 /* rewrite the tree */
2420 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2422 tree->type = EX_VALUE;
2423 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2424 valFromType (RETYPE (tree)));
2425 tree->right = tree->left = NULL;
2426 TETYPE (tree) = getSpec (TTYPE (tree) =
2427 tree->opval.val->type);
2431 /* if the left & right are equal then zero */
2432 if (isAstEqual (tree->left, tree->right))
2434 tree->type = EX_VALUE;
2435 tree->left = tree->right = NULL;
2436 tree->opval.val = constVal ("0");
2437 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2441 /* if both of them are pointers or arrays then */
2442 /* the result is going to be an integer */
2443 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2444 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2445 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2447 /* if only the left is a pointer */
2448 /* then result is a pointer */
2449 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2450 TETYPE (tree) = getSpec (TTYPE (tree) =
2453 TETYPE (tree) = getSpec (TTYPE (tree) =
2454 computeType (LTYPE (tree),
2456 LRVAL (tree) = RRVAL (tree) = 1;
2459 /*------------------------------------------------------------------*/
2460 /*----------------------------*/
2462 /*----------------------------*/
2464 /* can be only integral type */
2465 if (!IS_INTEGRAL (LTYPE (tree)))
2467 werror (E_UNARY_OP, tree->opval.op);
2468 goto errorTreeReturn;
2471 /* if left is a literal then do it */
2472 if (IS_LITERAL (LTYPE (tree)))
2474 tree->type = EX_VALUE;
2475 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2477 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2481 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2484 /*------------------------------------------------------------------*/
2485 /*----------------------------*/
2487 /*----------------------------*/
2489 /* can be pointer */
2490 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2491 !IS_PTR (LTYPE (tree)) &&
2492 !IS_ARRAY (LTYPE (tree)))
2494 werror (E_UNARY_OP, tree->opval.op);
2495 goto errorTreeReturn;
2498 /* if left is a literal then do it */
2499 if (IS_LITERAL (LTYPE (tree)))
2501 tree->type = EX_VALUE;
2502 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2504 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2508 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2511 /*------------------------------------------------------------------*/
2512 /*----------------------------*/
2514 /*----------------------------*/
2517 TTYPE (tree) = LTYPE (tree);
2518 TETYPE (tree) = LETYPE (tree);
2522 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2527 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2529 werror (E_SHIFT_OP_INVALID);
2530 werror (W_CONTINUE, "left & right types are ");
2531 printTypeChain (LTYPE (tree), stderr);
2532 fprintf (stderr, ",");
2533 printTypeChain (RTYPE (tree), stderr);
2534 fprintf (stderr, "\n");
2535 goto errorTreeReturn;
2538 /* if they are both literal then */
2539 /* rewrite the tree */
2540 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2542 tree->type = EX_VALUE;
2543 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2544 valFromType (RETYPE (tree)),
2545 (tree->opval.op == LEFT_OP ? 1 : 0));
2546 tree->right = tree->left = NULL;
2547 TETYPE (tree) = getSpec (TTYPE (tree) =
2548 tree->opval.val->type);
2551 /* if only the right side is a literal & we are
2552 shifting more than size of the left operand then zero */
2553 if (IS_LITERAL (RTYPE (tree)) &&
2554 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2555 (getSize (LTYPE (tree)) * 8))
2557 werror (W_SHIFT_CHANGED,
2558 (tree->opval.op == LEFT_OP ? "left" : "right"));
2559 tree->type = EX_VALUE;
2560 tree->left = tree->right = NULL;
2561 tree->opval.val = constVal ("0");
2562 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2565 LRVAL (tree) = RRVAL (tree) = 1;
2566 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2568 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2572 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2576 /*------------------------------------------------------------------*/
2577 /*----------------------------*/
2579 /*----------------------------*/
2580 case CAST: /* change the type */
2581 /* cannot cast to an aggregate type */
2582 if (IS_AGGREGATE (LTYPE (tree)))
2584 werror (E_CAST_ILLEGAL);
2585 goto errorTreeReturn;
2588 /* make sure the type is complete and sane */
2589 checkTypeSanity(LETYPE(tree), "(cast)");
2592 /* if the right is a literal replace the tree */
2593 if (IS_LITERAL (RETYPE (tree))) {
2594 if (!IS_PTR (LTYPE (tree))) {
2595 tree->type = EX_VALUE;
2597 valCastLiteral (LTYPE (tree),
2598 floatFromVal (valFromType (RETYPE (tree))));
2601 TTYPE (tree) = tree->opval.val->type;
2602 tree->values.literalFromCast = 1;
2603 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2604 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2605 sym_link *rest = LTYPE(tree)->next;
2606 werror(W_LITERAL_GENERIC);
2607 TTYPE(tree) = newLink();
2608 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2609 TTYPE(tree)->next = rest;
2610 tree->left->opval.lnk = TTYPE(tree);
2613 TTYPE (tree) = LTYPE (tree);
2617 TTYPE (tree) = LTYPE (tree);
2621 /* if pointer to struct then check names */
2622 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2623 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2624 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2625 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2627 /* if the right is a literal replace the tree */
2628 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2629 tree->type = EX_VALUE;
2631 valCastLiteral (LTYPE (tree),
2632 floatFromVal (valFromType (RETYPE (tree))));
2635 TTYPE (tree) = tree->opval.val->type;
2636 tree->values.literalFromCast = 1;
2638 TTYPE (tree) = LTYPE (tree);
2642 TETYPE (tree) = getSpec (TTYPE (tree));
2646 /*------------------------------------------------------------------*/
2647 /*----------------------------*/
2648 /* logical &&, || */
2649 /*----------------------------*/
2652 /* each must me arithmetic type or be a pointer */
2653 if (!IS_PTR (LTYPE (tree)) &&
2654 !IS_ARRAY (LTYPE (tree)) &&
2655 !IS_INTEGRAL (LTYPE (tree)))
2657 werror (E_COMPARE_OP);
2658 goto errorTreeReturn;
2661 if (!IS_PTR (RTYPE (tree)) &&
2662 !IS_ARRAY (RTYPE (tree)) &&
2663 !IS_INTEGRAL (RTYPE (tree)))
2665 werror (E_COMPARE_OP);
2666 goto errorTreeReturn;
2668 /* if they are both literal then */
2669 /* rewrite the tree */
2670 if (IS_LITERAL (RTYPE (tree)) &&
2671 IS_LITERAL (LTYPE (tree)))
2673 tree->type = EX_VALUE;
2674 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2675 valFromType (RETYPE (tree)),
2677 tree->right = tree->left = NULL;
2678 TETYPE (tree) = getSpec (TTYPE (tree) =
2679 tree->opval.val->type);
2682 LRVAL (tree) = RRVAL (tree) = 1;
2683 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2686 /*------------------------------------------------------------------*/
2687 /*----------------------------*/
2688 /* comparison operators */
2689 /*----------------------------*/
2697 ast *lt = optimizeCompare (tree);
2703 /* if they are pointers they must be castable */
2704 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2706 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2708 werror (E_COMPARE_OP);
2709 fprintf (stderr, "comparing type ");
2710 printTypeChain (LTYPE (tree), stderr);
2711 fprintf (stderr, "to type ");
2712 printTypeChain (RTYPE (tree), stderr);
2713 fprintf (stderr, "\n");
2714 goto errorTreeReturn;
2717 /* else they should be promotable to one another */
2720 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2721 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2723 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2725 werror (E_COMPARE_OP);
2726 fprintf (stderr, "comparing type ");
2727 printTypeChain (LTYPE (tree), stderr);
2728 fprintf (stderr, "to type ");
2729 printTypeChain (RTYPE (tree), stderr);
2730 fprintf (stderr, "\n");
2731 goto errorTreeReturn;
2734 /* if unsigned value < 0 then always false */
2735 /* if (unsigned value) > 0 then (unsigned value) */
2736 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2737 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2739 if (tree->opval.op == '<') {
2742 if (tree->opval.op == '>') {
2746 /* if they are both literal then */
2747 /* rewrite the tree */
2748 if (IS_LITERAL (RTYPE (tree)) &&
2749 IS_LITERAL (LTYPE (tree)))
2751 tree->type = EX_VALUE;
2752 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2753 valFromType (RETYPE (tree)),
2755 tree->right = tree->left = NULL;
2756 TETYPE (tree) = getSpec (TTYPE (tree) =
2757 tree->opval.val->type);
2760 LRVAL (tree) = RRVAL (tree) = 1;
2761 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2767 /*----------------------------*/
2768 case SIZEOF: /* evaluate wihout code generation */
2769 /* change the type to a integer */
2770 tree->type = EX_VALUE;
2771 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2772 tree->opval.val = constVal (buffer);
2773 tree->right = tree->left = NULL;
2774 TETYPE (tree) = getSpec (TTYPE (tree) =
2775 tree->opval.val->type);
2778 /*------------------------------------------------------------------*/
2779 /*----------------------------*/
2781 /*----------------------------*/
2783 /* return typeof enum value */
2784 tree->type = EX_VALUE;
2787 if (IS_SPEC(tree->right->ftype)) {
2788 switch (SPEC_NOUN(tree->right->ftype)) {
2790 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2791 else typeofv = TYPEOF_INT;
2794 typeofv = TYPEOF_FLOAT;
2797 typeofv = TYPEOF_CHAR;
2800 typeofv = TYPEOF_VOID;
2803 typeofv = TYPEOF_STRUCT;
2806 typeofv = TYPEOF_BIT;
2809 typeofv = TYPEOF_SBIT;
2815 switch (DCL_TYPE(tree->right->ftype)) {
2817 typeofv = TYPEOF_POINTER;
2820 typeofv = TYPEOF_FPOINTER;
2823 typeofv = TYPEOF_CPOINTER;
2826 typeofv = TYPEOF_GPOINTER;
2829 typeofv = TYPEOF_PPOINTER;
2832 typeofv = TYPEOF_IPOINTER;
2835 typeofv = TYPEOF_ARRAY;
2838 typeofv = TYPEOF_FUNCTION;
2844 sprintf (buffer, "%d", typeofv);
2845 tree->opval.val = constVal (buffer);
2846 tree->right = tree->left = NULL;
2847 TETYPE (tree) = getSpec (TTYPE (tree) =
2848 tree->opval.val->type);
2851 /*------------------------------------------------------------------*/
2852 /*----------------------------*/
2853 /* conditional operator '?' */
2854 /*----------------------------*/
2856 /* the type is value of the colon operator (on the right) */
2857 assert(IS_COLON_OP(tree->right));
2858 /* if already known then replace the tree : optimizer will do it
2859 but faster to do it here */
2860 if (IS_LITERAL (LTYPE(tree))) {
2861 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2862 return decorateType(tree->right->left) ;
2864 return decorateType(tree->right->right) ;
2867 tree->right = decorateType(tree->right);
2868 TTYPE (tree) = RTYPE(tree);
2869 TETYPE (tree) = getSpec (TTYPE (tree));
2874 /* if they don't match we have a problem */
2875 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2877 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2878 goto errorTreeReturn;
2881 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2882 TETYPE (tree) = getSpec (TTYPE (tree));
2886 /*------------------------------------------------------------------*/
2887 /*----------------------------*/
2888 /* assignment operators */
2889 /*----------------------------*/
2892 /* for these it must be both must be integral */
2893 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2894 !IS_ARITHMETIC (RTYPE (tree)))
2896 werror (E_OPS_INTEGRAL);
2897 goto errorTreeReturn;
2900 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2902 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2903 werror (E_CODE_WRITE, " ");
2907 werror (E_LVALUE_REQUIRED, "*= or /=");
2908 goto errorTreeReturn;
2919 /* for these it must be both must be integral */
2920 if (!IS_INTEGRAL (LTYPE (tree)) ||
2921 !IS_INTEGRAL (RTYPE (tree)))
2923 werror (E_OPS_INTEGRAL);
2924 goto errorTreeReturn;
2927 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2929 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2930 werror (E_CODE_WRITE, " ");
2934 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2935 goto errorTreeReturn;
2941 /*------------------------------------------------------------------*/
2942 /*----------------------------*/
2944 /*----------------------------*/
2946 if (!(IS_PTR (LTYPE (tree)) ||
2947 IS_ARITHMETIC (LTYPE (tree))))
2949 werror (E_PLUS_INVALID, "-=");
2950 goto errorTreeReturn;
2953 if (!(IS_PTR (RTYPE (tree)) ||
2954 IS_ARITHMETIC (RTYPE (tree))))
2956 werror (E_PLUS_INVALID, "-=");
2957 goto errorTreeReturn;
2960 TETYPE (tree) = getSpec (TTYPE (tree) =
2961 computeType (LTYPE (tree),
2964 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2965 werror (E_CODE_WRITE, " ");
2969 werror (E_LVALUE_REQUIRED, "-=");
2970 goto errorTreeReturn;
2976 /*------------------------------------------------------------------*/
2977 /*----------------------------*/
2979 /*----------------------------*/
2981 /* this is not a unary operation */
2982 /* if both pointers then problem */
2983 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2985 werror (E_PTR_PLUS_PTR);
2986 goto errorTreeReturn;
2989 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2991 werror (E_PLUS_INVALID, "+=");
2992 goto errorTreeReturn;
2995 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2997 werror (E_PLUS_INVALID, "+=");
2998 goto errorTreeReturn;
3001 TETYPE (tree) = getSpec (TTYPE (tree) =
3002 computeType (LTYPE (tree),
3005 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3006 werror (E_CODE_WRITE, " ");
3010 werror (E_LVALUE_REQUIRED, "+=");
3011 goto errorTreeReturn;
3014 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3015 tree->opval.op = '=';
3019 /*------------------------------------------------------------------*/
3020 /*----------------------------*/
3021 /* straight assignemnt */
3022 /*----------------------------*/
3024 /* cannot be an aggregate */
3025 if (IS_AGGREGATE (LTYPE (tree)))
3027 werror (E_AGGR_ASSIGN);
3028 goto errorTreeReturn;
3031 /* they should either match or be castable */
3032 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3034 werror (E_TYPE_MISMATCH, "assignment", " ");
3035 fprintf (stderr, "type --> '");
3036 printTypeChain (RTYPE (tree), stderr);
3037 fprintf (stderr, "' ");
3038 fprintf (stderr, "assigned to type --> '");
3039 printTypeChain (LTYPE (tree), stderr);
3040 fprintf (stderr, "'\n");
3041 goto errorTreeReturn;
3044 /* if the left side of the tree is of type void
3045 then report error */
3046 if (IS_VOID (LTYPE (tree)))
3048 werror (E_CAST_ZERO);
3049 printFromToType(RTYPE(tree), LTYPE(tree));
3052 TETYPE (tree) = getSpec (TTYPE (tree) =
3056 if (!tree->initMode ) {
3057 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3058 werror (E_CODE_WRITE, " ");
3062 werror (E_LVALUE_REQUIRED, "=");
3063 goto errorTreeReturn;
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3070 /* comma operator */
3071 /*----------------------------*/
3073 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3076 /*------------------------------------------------------------------*/
3077 /*----------------------------*/
3079 /*----------------------------*/
3083 if (processParms (tree->left,
3084 FUNC_ARGS(tree->left->ftype),
3085 tree->right, &parmNumber, TRUE)) {
3086 goto errorTreeReturn;
3089 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3090 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3092 //FUNC_ARGS(tree->left->ftype) =
3093 //reverseVal (FUNC_ARGS(tree->left->ftype));
3094 reverseParms (tree->right);
3097 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3100 /*------------------------------------------------------------------*/
3101 /*----------------------------*/
3102 /* return statement */
3103 /*----------------------------*/
3108 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3110 werror (W_RETURN_MISMATCH);
3111 printFromToType (RTYPE(tree), currFunc->type->next);
3112 goto errorTreeReturn;
3115 if (IS_VOID (currFunc->type->next)
3117 !IS_VOID (RTYPE (tree)))
3119 werror (E_FUNC_VOID);
3120 goto errorTreeReturn;
3123 /* if there is going to be a casing required then add it */
3124 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3127 decorateType (newNode (CAST,
3128 newAst_LINK (copyLinkChain (currFunc->type->next)),
3137 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3139 werror (E_VOID_FUNC, currFunc->name);
3140 goto errorTreeReturn;
3143 TTYPE (tree) = TETYPE (tree) = NULL;
3146 /*------------------------------------------------------------------*/
3147 /*----------------------------*/
3148 /* switch statement */
3149 /*----------------------------*/
3151 /* the switch value must be an integer */
3152 if (!IS_INTEGRAL (LTYPE (tree)))
3154 werror (E_SWITCH_NON_INTEGER);
3155 goto errorTreeReturn;
3158 TTYPE (tree) = TETYPE (tree) = NULL;
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3164 /*----------------------------*/
3166 tree->left = backPatchLabels (tree->left,
3169 TTYPE (tree) = TETYPE (tree) = NULL;
3172 /*------------------------------------------------------------------*/
3173 /*----------------------------*/
3175 /*----------------------------*/
3178 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3179 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3180 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3182 /* if the for loop is reversible then
3183 reverse it otherwise do what we normally
3189 if (isLoopReversible (tree, &sym, &init, &end))
3190 return reverseLoop (tree, sym, init, end);
3192 return decorateType (createFor (AST_FOR (tree, trueLabel),
3193 AST_FOR (tree, continueLabel),
3194 AST_FOR (tree, falseLabel),
3195 AST_FOR (tree, condLabel),
3196 AST_FOR (tree, initExpr),
3197 AST_FOR (tree, condExpr),
3198 AST_FOR (tree, loopExpr),
3202 TTYPE (tree) = TETYPE (tree) = NULL;
3206 /* some error found this tree will be killed */
3208 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3209 tree->opval.op = NULLOP;
3215 /*-----------------------------------------------------------------*/
3216 /* sizeofOp - processes size of operation */
3217 /*-----------------------------------------------------------------*/
3219 sizeofOp (sym_link * type)
3223 /* make sure the type is complete and sane */
3224 checkTypeSanity(type, "(sizeof)");
3226 /* get the size and convert it to character */
3227 sprintf (buff, "%d", getSize (type));
3229 /* now convert into value */
3230 return constVal (buff);
3234 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3235 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3236 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3237 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3238 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3239 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3240 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3242 /*-----------------------------------------------------------------*/
3243 /* backPatchLabels - change and or not operators to flow control */
3244 /*-----------------------------------------------------------------*/
3246 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3252 if (!(IS_ANDORNOT (tree)))
3255 /* if this an and */
3258 static int localLbl = 0;
3261 sprintf (buffer, "_and_%d", localLbl++);
3262 localLabel = newSymbol (buffer, NestLevel);
3264 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3266 /* if left is already a IFX then just change the if true label in that */
3267 if (!IS_IFX (tree->left))
3268 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3270 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3271 /* right is a IFX then just join */
3272 if (IS_IFX (tree->right))
3273 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3275 tree->right = createLabel (localLabel, tree->right);
3276 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3278 return newNode (NULLOP, tree->left, tree->right);
3281 /* if this is an or operation */
3284 static int localLbl = 0;
3287 sprintf (buffer, "_or_%d", localLbl++);
3288 localLabel = newSymbol (buffer, NestLevel);
3290 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3292 /* if left is already a IFX then just change the if true label in that */
3293 if (!IS_IFX (tree->left))
3294 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3296 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3297 /* right is a IFX then just join */
3298 if (IS_IFX (tree->right))
3299 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3301 tree->right = createLabel (localLabel, tree->right);
3302 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3304 return newNode (NULLOP, tree->left, tree->right);
3310 int wasnot = IS_NOT (tree->left);
3311 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3313 /* if the left is already a IFX */
3314 if (!IS_IFX (tree->left))
3315 tree->left = newNode (IFX, tree->left, NULL);
3319 tree->left->trueLabel = trueLabel;
3320 tree->left->falseLabel = falseLabel;
3324 tree->left->trueLabel = falseLabel;
3325 tree->left->falseLabel = trueLabel;
3332 tree->trueLabel = trueLabel;
3333 tree->falseLabel = falseLabel;
3340 /*-----------------------------------------------------------------*/
3341 /* createBlock - create expression tree for block */
3342 /*-----------------------------------------------------------------*/
3344 createBlock (symbol * decl, ast * body)
3348 /* if the block has nothing */
3352 ex = newNode (BLOCK, NULL, body);
3353 ex->values.sym = decl;
3355 ex->right = ex->right;
3361 /*-----------------------------------------------------------------*/
3362 /* createLabel - creates the expression tree for labels */
3363 /*-----------------------------------------------------------------*/
3365 createLabel (symbol * label, ast * stmnt)
3368 char name[SDCC_NAME_MAX + 1];
3371 /* must create fresh symbol if the symbol name */
3372 /* exists in the symbol table, since there can */
3373 /* be a variable with the same name as the labl */
3374 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3375 (csym->level == label->level))
3376 label = newSymbol (label->name, label->level);
3378 /* change the name before putting it in add _ */
3379 sprintf (name, "%s", label->name);
3381 /* put the label in the LabelSymbol table */
3382 /* but first check if a label of the same */
3384 if ((csym = findSym (LabelTab, NULL, name)))
3385 werror (E_DUPLICATE_LABEL, label->name);
3387 addSym (LabelTab, label, name, label->level, 0, 0);
3390 label->key = labelKey++;
3391 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3397 /*-----------------------------------------------------------------*/
3398 /* createCase - generates the parsetree for a case statement */
3399 /*-----------------------------------------------------------------*/
3401 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3403 char caseLbl[SDCC_NAME_MAX + 1];
3407 /* if the switch statement does not exist */
3408 /* then case is out of context */
3411 werror (E_CASE_CONTEXT);
3415 caseVal = decorateType (resolveSymbols (caseVal));
3416 /* if not a constant then error */
3417 if (!IS_LITERAL (caseVal->ftype))
3419 werror (E_CASE_CONSTANT);
3423 /* if not a integer than error */
3424 if (!IS_INTEGRAL (caseVal->ftype))
3426 werror (E_CASE_NON_INTEGER);
3430 /* find the end of the switch values chain */
3431 if (!(val = swStat->values.switchVals.swVals))
3432 swStat->values.switchVals.swVals = caseVal->opval.val;
3435 /* also order the cases according to value */
3437 int cVal = (int) floatFromVal (caseVal->opval.val);
3438 while (val && (int) floatFromVal (val) < cVal)
3444 /* if we reached the end then */
3447 pval->next = caseVal->opval.val;
3451 /* we found a value greater than */
3452 /* the current value we must add this */
3453 /* before the value */
3454 caseVal->opval.val->next = val;
3456 /* if this was the first in chain */
3457 if (swStat->values.switchVals.swVals == val)
3458 swStat->values.switchVals.swVals =
3461 pval->next = caseVal->opval.val;
3466 /* create the case label */
3467 sprintf (caseLbl, "_case_%d_%d",
3468 swStat->values.switchVals.swNum,
3469 (int) floatFromVal (caseVal->opval.val));
3471 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3476 /*-----------------------------------------------------------------*/
3477 /* createDefault - creates the parse tree for the default statement */
3478 /*-----------------------------------------------------------------*/
3480 createDefault (ast * swStat, ast * stmnt)
3482 char defLbl[SDCC_NAME_MAX + 1];
3484 /* if the switch statement does not exist */
3485 /* then case is out of context */
3488 werror (E_CASE_CONTEXT);
3492 /* turn on the default flag */
3493 swStat->values.switchVals.swDefault = 1;
3495 /* create the label */
3496 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3497 return createLabel (newSymbol (defLbl, 0), stmnt);
3500 /*-----------------------------------------------------------------*/
3501 /* createIf - creates the parsetree for the if statement */
3502 /*-----------------------------------------------------------------*/
3504 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3506 static int Lblnum = 0;
3508 symbol *ifTrue, *ifFalse, *ifEnd;
3510 /* if neither exists */
3511 if (!elseBody && !ifBody) {
3512 // if there are no side effects (i++, j() etc)
3513 if (!hasSEFcalls(condAst)) {
3518 /* create the labels */
3519 sprintf (buffer, "_iffalse_%d", Lblnum);
3520 ifFalse = newSymbol (buffer, NestLevel);
3521 /* if no else body then end == false */
3526 sprintf (buffer, "_ifend_%d", Lblnum);
3527 ifEnd = newSymbol (buffer, NestLevel);
3530 sprintf (buffer, "_iftrue_%d", Lblnum);
3531 ifTrue = newSymbol (buffer, NestLevel);
3535 /* attach the ifTrue label to the top of it body */
3536 ifBody = createLabel (ifTrue, ifBody);
3537 /* attach a goto end to the ifBody if else is present */
3540 ifBody = newNode (NULLOP, ifBody,
3542 newAst_VALUE (symbolVal (ifEnd)),
3544 /* put the elseLabel on the else body */
3545 elseBody = createLabel (ifFalse, elseBody);
3546 /* out the end at the end of the body */
3547 elseBody = newNode (NULLOP,
3549 createLabel (ifEnd, NULL));
3553 ifBody = newNode (NULLOP, ifBody,
3554 createLabel (ifFalse, NULL));
3556 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3557 if (IS_IFX (condAst))
3560 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3562 return newNode (NULLOP, ifTree,
3563 newNode (NULLOP, ifBody, elseBody));
3567 /*-----------------------------------------------------------------*/
3568 /* createDo - creates parse tree for do */
3571 /* _docontinue_n: */
3572 /* condition_expression +-> trueLabel -> _dobody_n */
3574 /* +-> falseLabel-> _dobreak_n */
3576 /*-----------------------------------------------------------------*/
3578 createDo (symbol * trueLabel, symbol * continueLabel,
3579 symbol * falseLabel, ast * condAst, ast * doBody)
3584 /* if the body does not exist then it is simple */
3587 condAst = backPatchLabels (condAst, continueLabel, NULL);
3588 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3589 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3590 doTree->trueLabel = continueLabel;
3591 doTree->falseLabel = NULL;
3595 /* otherwise we have a body */
3596 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3598 /* attach the body label to the top */
3599 doBody = createLabel (trueLabel, doBody);
3600 /* attach the continue label to end of body */
3601 doBody = newNode (NULLOP, doBody,
3602 createLabel (continueLabel, NULL));
3604 /* now put the break label at the end */
3605 if (IS_IFX (condAst))
3608 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3610 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3612 /* putting it together */
3613 return newNode (NULLOP, doBody, doTree);
3616 /*-----------------------------------------------------------------*/
3617 /* createFor - creates parse tree for 'for' statement */
3620 /* condExpr +-> trueLabel -> _forbody_n */
3622 /* +-> falseLabel-> _forbreak_n */
3625 /* _forcontinue_n: */
3627 /* goto _forcond_n ; */
3629 /*-----------------------------------------------------------------*/
3631 createFor (symbol * trueLabel, symbol * continueLabel,
3632 symbol * falseLabel, symbol * condLabel,
3633 ast * initExpr, ast * condExpr, ast * loopExpr,
3638 /* if loopexpression not present then we can generate it */
3639 /* the same way as a while */
3641 return newNode (NULLOP, initExpr,
3642 createWhile (trueLabel, continueLabel,
3643 falseLabel, condExpr, forBody));
3644 /* vanilla for statement */
3645 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3647 if (condExpr && !IS_IFX (condExpr))
3648 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3651 /* attach condition label to condition */
3652 condExpr = createLabel (condLabel, condExpr);
3654 /* attach body label to body */
3655 forBody = createLabel (trueLabel, forBody);
3657 /* attach continue to forLoop expression & attach */
3658 /* goto the forcond @ and of loopExpression */
3659 loopExpr = createLabel (continueLabel,
3663 newAst_VALUE (symbolVal (condLabel)),
3665 /* now start putting them together */
3666 forTree = newNode (NULLOP, initExpr, condExpr);
3667 forTree = newNode (NULLOP, forTree, forBody);
3668 forTree = newNode (NULLOP, forTree, loopExpr);
3669 /* finally add the break label */
3670 forTree = newNode (NULLOP, forTree,
3671 createLabel (falseLabel, NULL));
3675 /*-----------------------------------------------------------------*/
3676 /* createWhile - creates parse tree for while statement */
3677 /* the while statement will be created as follows */
3679 /* _while_continue_n: */
3680 /* condition_expression +-> trueLabel -> _while_boby_n */
3682 /* +-> falseLabel -> _while_break_n */
3683 /* _while_body_n: */
3685 /* goto _while_continue_n */
3686 /* _while_break_n: */
3687 /*-----------------------------------------------------------------*/
3689 createWhile (symbol * trueLabel, symbol * continueLabel,
3690 symbol * falseLabel, ast * condExpr, ast * whileBody)
3694 /* put the continue label */
3695 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3696 condExpr = createLabel (continueLabel, condExpr);
3697 condExpr->lineno = 0;
3699 /* put the body label in front of the body */
3700 whileBody = createLabel (trueLabel, whileBody);
3701 whileBody->lineno = 0;
3702 /* put a jump to continue at the end of the body */
3703 /* and put break label at the end of the body */
3704 whileBody = newNode (NULLOP,
3707 newAst_VALUE (symbolVal (continueLabel)),
3708 createLabel (falseLabel, NULL)));
3710 /* put it all together */
3711 if (IS_IFX (condExpr))
3712 whileTree = condExpr;
3715 whileTree = newNode (IFX, condExpr, NULL);
3716 /* put the true & false labels in place */
3717 whileTree->trueLabel = trueLabel;
3718 whileTree->falseLabel = falseLabel;
3721 return newNode (NULLOP, whileTree, whileBody);
3724 /*-----------------------------------------------------------------*/
3725 /* optimizeGetHbit - get highest order bit of the expression */
3726 /*-----------------------------------------------------------------*/
3728 optimizeGetHbit (ast * tree)
3731 /* if this is not a bit and */
3732 if (!IS_BITAND (tree))
3735 /* will look for tree of the form
3736 ( expr >> ((sizeof expr) -1) ) & 1 */
3737 if (!IS_AST_LIT_VALUE (tree->right))
3740 if (AST_LIT_VALUE (tree->right) != 1)
3743 if (!IS_RIGHT_OP (tree->left))
3746 if (!IS_AST_LIT_VALUE (tree->left->right))
3749 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3750 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3753 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3757 /*-----------------------------------------------------------------*/
3758 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3759 /*-----------------------------------------------------------------*/
3761 optimizeRRCRLC (ast * root)
3763 /* will look for trees of the form
3764 (?expr << 1) | (?expr >> 7) or
3765 (?expr >> 7) | (?expr << 1) will make that
3766 into a RLC : operation ..
3768 (?expr >> 1) | (?expr << 7) or
3769 (?expr << 7) | (?expr >> 1) will make that
3770 into a RRC operation
3771 note : by 7 I mean (number of bits required to hold the
3773 /* if the root operations is not a | operation the not */
3774 if (!IS_BITOR (root))
3777 /* I have to think of a better way to match patterns this sucks */
3778 /* that aside let start looking for the first case : I use a the
3779 negative check a lot to improve the efficiency */
3780 /* (?expr << 1) | (?expr >> 7) */
3781 if (IS_LEFT_OP (root->left) &&
3782 IS_RIGHT_OP (root->right))
3785 if (!SPEC_USIGN (TETYPE (root->left->left)))
3788 if (!IS_AST_LIT_VALUE (root->left->right) ||
3789 !IS_AST_LIT_VALUE (root->right->right))
3792 /* make sure it is the same expression */
3793 if (!isAstEqual (root->left->left,
3797 if (AST_LIT_VALUE (root->left->right) != 1)
3800 if (AST_LIT_VALUE (root->right->right) !=
3801 (getSize (TTYPE (root->left->left)) * 8 - 1))
3804 /* whew got the first case : create the AST */
3805 return newNode (RLC, root->left->left, NULL);
3809 /* check for second case */
3810 /* (?expr >> 7) | (?expr << 1) */
3811 if (IS_LEFT_OP (root->right) &&
3812 IS_RIGHT_OP (root->left))
3815 if (!SPEC_USIGN (TETYPE (root->left->left)))
3818 if (!IS_AST_LIT_VALUE (root->left->right) ||
3819 !IS_AST_LIT_VALUE (root->right->right))
3822 /* make sure it is the same symbol */
3823 if (!isAstEqual (root->left->left,
3827 if (AST_LIT_VALUE (root->right->right) != 1)
3830 if (AST_LIT_VALUE (root->left->right) !=
3831 (getSize (TTYPE (root->left->left)) * 8 - 1))
3834 /* whew got the first case : create the AST */
3835 return newNode (RLC, root->left->left, NULL);
3840 /* third case for RRC */
3841 /* (?symbol >> 1) | (?symbol << 7) */
3842 if (IS_LEFT_OP (root->right) &&
3843 IS_RIGHT_OP (root->left))
3846 if (!SPEC_USIGN (TETYPE (root->left->left)))
3849 if (!IS_AST_LIT_VALUE (root->left->right) ||
3850 !IS_AST_LIT_VALUE (root->right->right))
3853 /* make sure it is the same symbol */
3854 if (!isAstEqual (root->left->left,
3858 if (AST_LIT_VALUE (root->left->right) != 1)
3861 if (AST_LIT_VALUE (root->right->right) !=
3862 (getSize (TTYPE (root->left->left)) * 8 - 1))
3865 /* whew got the first case : create the AST */
3866 return newNode (RRC, root->left->left, NULL);
3870 /* fourth and last case for now */
3871 /* (?symbol << 7) | (?symbol >> 1) */
3872 if (IS_RIGHT_OP (root->right) &&
3873 IS_LEFT_OP (root->left))
3876 if (!SPEC_USIGN (TETYPE (root->left->left)))
3879 if (!IS_AST_LIT_VALUE (root->left->right) ||
3880 !IS_AST_LIT_VALUE (root->right->right))
3883 /* make sure it is the same symbol */
3884 if (!isAstEqual (root->left->left,
3888 if (AST_LIT_VALUE (root->right->right) != 1)
3891 if (AST_LIT_VALUE (root->left->right) !=
3892 (getSize (TTYPE (root->left->left)) * 8 - 1))
3895 /* whew got the first case : create the AST */
3896 return newNode (RRC, root->left->left, NULL);
3900 /* not found return root */
3904 /*-----------------------------------------------------------------*/
3905 /* optimizeCompare - otimizes compares for bit variables */
3906 /*-----------------------------------------------------------------*/
3908 optimizeCompare (ast * root)
3910 ast *optExpr = NULL;
3913 unsigned int litValue;
3915 /* if nothing then return nothing */
3919 /* if not a compare op then do leaves */
3920 if (!IS_COMPARE_OP (root))
3922 root->left = optimizeCompare (root->left);
3923 root->right = optimizeCompare (root->right);
3927 /* if left & right are the same then depending
3928 of the operation do */
3929 if (isAstEqual (root->left, root->right))
3931 switch (root->opval.op)
3936 optExpr = newAst_VALUE (constVal ("0"));
3941 optExpr = newAst_VALUE (constVal ("1"));
3945 return decorateType (optExpr);
3948 vleft = (root->left->type == EX_VALUE ?
3949 root->left->opval.val : NULL);
3951 vright = (root->right->type == EX_VALUE ?
3952 root->right->opval.val : NULL);
3954 //#define EXPERIMENTAL
3956 /* if left is unsigned and right is literal */
3957 if (vleft && vright &&
3958 IS_UNSIGNED(vleft->etype) &&
3959 IS_LITERAL(vright->etype)) {
3960 double dval=floatFromVal(vright);
3961 int op=root->opval.op;
3963 fprintf (stderr,"op: '");
3965 case LE_OP: fprintf (stderr, "<= '"); break;
3966 case EQ_OP: fprintf (stderr, "== '"); break;
3967 case GE_OP: fprintf (stderr, ">= '"); break;
3968 default: fprintf (stderr, "%c '", op); break;
3970 fprintf (stderr, "%f\n", dval);
3977 if (dval<0 || (op=='<' && dval==0)) {
3978 // unsigned is never < 0
3979 werror (W_IF_NEVER_TRUE);
3980 optExpr = newAst_VALUE (constVal("0"));
3981 return decorateType (optExpr);
3985 // change this into a cheaper EQ_OP
3986 fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
3987 root->opval.op=EQ_OP;
3994 if (dval>0 || (op==GE_OP && dval==0)) {
3995 // unsigned is never < 0
3996 werror (W_IF_ALWAYS_TRUE);
3997 optExpr = newAst_VALUE (constVal("1"));
3998 return decorateType (optExpr);
4002 // change this into a cheaper reversed EQ_OP
4003 fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
4004 root->opval.op=EQ_OP;
4011 /* if left is a BITVAR in BITSPACE */
4012 /* and right is a LITERAL then opt- */
4013 /* imize else do nothing */
4014 if (vleft && vright &&
4015 IS_BITVAR (vleft->etype) &&
4016 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4017 IS_LITERAL (vright->etype))
4020 /* if right side > 1 then comparison may never succeed */
4021 if ((litValue = (int) floatFromVal (vright)) > 1)
4023 werror (W_BAD_COMPARE);
4029 switch (root->opval.op)
4031 case '>': /* bit value greater than 1 cannot be */
4032 werror (W_BAD_COMPARE);
4036 case '<': /* bit value < 1 means 0 */
4038 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4041 case LE_OP: /* bit value <= 1 means no check */
4042 optExpr = newAst_VALUE (vright);
4045 case GE_OP: /* bit value >= 1 means only check for = */
4047 optExpr = newAst_VALUE (vleft);
4052 { /* literal is zero */
4053 switch (root->opval.op)
4055 case '<': /* bit value < 0 cannot be */
4056 werror (W_BAD_COMPARE);
4060 case '>': /* bit value > 0 means 1 */
4062 optExpr = newAst_VALUE (vleft);
4065 case LE_OP: /* bit value <= 0 means no check */
4066 case GE_OP: /* bit value >= 0 means no check */
4067 werror (W_BAD_COMPARE);
4071 case EQ_OP: /* bit == 0 means ! of bit */
4072 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4076 return decorateType (resolveSymbols (optExpr));
4077 } /* end-of-if of BITVAR */
4082 /*-----------------------------------------------------------------*/
4083 /* addSymToBlock : adds the symbol to the first block we find */
4084 /*-----------------------------------------------------------------*/
4086 addSymToBlock (symbol * sym, ast * tree)
4088 /* reached end of tree or a leaf */
4089 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4093 if (IS_AST_OP (tree) &&
4094 tree->opval.op == BLOCK)
4097 symbol *lsym = copySymbol (sym);
4099 lsym->next = AST_VALUES (tree, sym);
4100 AST_VALUES (tree, sym) = lsym;
4104 addSymToBlock (sym, tree->left);
4105 addSymToBlock (sym, tree->right);
4108 /*-----------------------------------------------------------------*/
4109 /* processRegParms - do processing for register parameters */
4110 /*-----------------------------------------------------------------*/
4112 processRegParms (value * args, ast * body)
4116 if (IS_REGPARM (args->etype))
4117 addSymToBlock (args->sym, body);
4122 /*-----------------------------------------------------------------*/
4123 /* resetParmKey - resets the operandkeys for the symbols */
4124 /*-----------------------------------------------------------------*/
4125 DEFSETFUNC (resetParmKey)
4136 /*-----------------------------------------------------------------*/
4137 /* createFunction - This is the key node that calls the iCode for */
4138 /* generating the code for a function. Note code */
4139 /* is generated function by function, later when */
4140 /* add inter-procedural analysis this will change */
4141 /*-----------------------------------------------------------------*/
4143 createFunction (symbol * name, ast * body)
4149 iCode *piCode = NULL;
4151 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4152 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4154 /* if check function return 0 then some problem */
4155 if (checkFunction (name, NULL) == 0)
4158 /* create a dummy block if none exists */
4160 body = newNode (BLOCK, NULL, NULL);
4164 /* check if the function name already in the symbol table */
4165 if ((csym = findSym (SymbolTab, NULL, name->name)))
4168 /* special case for compiler defined functions
4169 we need to add the name to the publics list : this
4170 actually means we are now compiling the compiler
4174 addSet (&publics, name);
4180 allocVariables (name);
4182 name->lastLine = yylineno;
4185 /* set the stack pointer */
4186 /* PENDING: check this for the mcs51 */
4187 stackPtr = -port->stack.direction * port->stack.call_overhead;
4188 if (IFFUNC_ISISR (name->type))
4189 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4190 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4191 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4193 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4195 fetype = getSpec (name->type); /* get the specifier for the function */
4196 /* if this is a reentrant function then */
4197 if (IFFUNC_ISREENT (name->type))
4200 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4202 /* do processing for parameters that are passed in registers */
4203 processRegParms (FUNC_ARGS(name->type), body);
4205 /* set the stack pointer */
4209 /* allocate & autoinit the block variables */
4210 processBlockVars (body, &stack, ALLOCATE);
4212 /* save the stack information */
4213 if (options.useXstack)
4214 name->xstack = SPEC_STAK (fetype) = stack;
4216 name->stack = SPEC_STAK (fetype) = stack;
4218 /* name needs to be mangled */
4219 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4221 body = resolveSymbols (body); /* resolve the symbols */
4222 body = decorateType (body); /* propagateType & do semantic checks */
4224 ex = newAst_VALUE (symbolVal (name)); /* create name */
4225 ex = newNode (FUNCTION, ex, body);
4226 ex->values.args = FUNC_ARGS(name->type);
4228 if (options.dump_tree) PA(ex);
4231 werror (E_FUNC_NO_CODE, name->name);
4235 /* create the node & generate intermediate code */
4237 codeOutFile = code->oFile;
4238 piCode = iCodeFromAst (ex);
4242 werror (E_FUNC_NO_CODE, name->name);
4246 eBBlockFromiCode (piCode);
4248 /* if there are any statics then do them */
4251 GcurMemmap = statsg;
4252 codeOutFile = statsg->oFile;
4253 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4259 /* dealloc the block variables */
4260 processBlockVars (body, &stack, DEALLOCATE);
4261 /* deallocate paramaters */
4262 deallocParms (FUNC_ARGS(name->type));
4264 if (IFFUNC_ISREENT (name->type))
4267 /* we are done freeup memory & cleanup */
4269 if (port->reset_labelKey) labelKey = 1;
4271 FUNC_HASBODY(name->type) = 1;
4272 addSet (&operKeyReset, name);
4273 applyToSet (operKeyReset, resetParmKey);
4276 cdbStructBlock (1, cdbFile);
4278 cleanUpLevel (LabelTab, 0);
4279 cleanUpBlock (StructTab, 1);
4280 cleanUpBlock (TypedefTab, 1);
4282 xstack->syms = NULL;
4283 istack->syms = NULL;
4288 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4289 /*-----------------------------------------------------------------*/
4290 /* ast_print : prints the ast (for debugging purposes) */
4291 /*-----------------------------------------------------------------*/
4293 void ast_print (ast * tree, FILE *outfile, int indent)
4298 /* can print only decorated trees */
4299 if (!tree->decorated) return;
4301 /* if any child is an error | this one is an error do nothing */
4302 if (tree->isError ||
4303 (tree->left && tree->left->isError) ||
4304 (tree->right && tree->right->isError)) {
4305 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4309 /* print the line */
4310 /* if not block & function */
4311 if (tree->type == EX_OP &&
4312 (tree->opval.op != FUNCTION &&
4313 tree->opval.op != BLOCK &&
4314 tree->opval.op != NULLOP)) {
4317 if (tree->opval.op == FUNCTION) {
4319 value *args=FUNC_ARGS(tree->left->opval.val->type);
4320 fprintf(outfile,"FUNCTION (%s=%p) type (",
4321 tree->left->opval.val->name, tree);
4322 printTypeChain (tree->ftype,outfile);
4323 fprintf(outfile,") args (");
4326 fprintf (outfile, ", ");
4328 printTypeChain (args ? args->type : NULL, outfile);
4330 args= args ? args->next : NULL;
4332 fprintf(outfile,")\n");
4333 ast_print(tree->left,outfile,indent);
4334 ast_print(tree->right,outfile,indent);
4337 if (tree->opval.op == BLOCK) {
4338 symbol *decls = tree->values.sym;
4339 INDENT(indent,outfile);
4340 fprintf(outfile,"{\n");
4342 INDENT(indent+2,outfile);
4343 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4344 decls->name, decls);
4345 printTypeChain(decls->type,outfile);
4346 fprintf(outfile,")\n");
4348 decls = decls->next;
4350 ast_print(tree->right,outfile,indent+2);
4351 INDENT(indent,outfile);
4352 fprintf(outfile,"}\n");
4355 if (tree->opval.op == NULLOP) {
4356 fprintf(outfile,"\n");
4357 ast_print(tree->left,outfile,indent);
4358 fprintf(outfile,"\n");
4359 ast_print(tree->right,outfile,indent);
4362 INDENT(indent,outfile);
4364 /*------------------------------------------------------------------*/
4365 /*----------------------------*/
4366 /* leaf has been reached */
4367 /*----------------------------*/
4368 /* if this is of type value */
4369 /* just get the type */
4370 if (tree->type == EX_VALUE) {
4372 if (IS_LITERAL (tree->opval.val->etype)) {
4373 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4374 (int) floatFromVal(tree->opval.val),
4375 (int) floatFromVal(tree->opval.val),
4376 floatFromVal(tree->opval.val));
4377 } else if (tree->opval.val->sym) {
4378 /* if the undefined flag is set then give error message */
4379 if (tree->opval.val->sym->undefined) {
4380 fprintf(outfile,"UNDEFINED SYMBOL ");
4382 fprintf(outfile,"SYMBOL ");
4384 fprintf(outfile,"(%s=%p)",
4385 tree->opval.val->sym->name,tree);
4388 fprintf(outfile," type (");
4389 printTypeChain(tree->ftype,outfile);
4390 fprintf(outfile,")\n");
4392 fprintf(outfile,"\n");
4397 /* if type link for the case of cast */
4398 if (tree->type == EX_LINK) {
4399 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4400 printTypeChain(tree->opval.lnk,outfile);
4401 fprintf(outfile,")\n");
4406 /* depending on type of operator do */
4408 switch (tree->opval.op) {
4409 /*------------------------------------------------------------------*/
4410 /*----------------------------*/
4412 /*----------------------------*/
4414 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4415 printTypeChain(tree->ftype,outfile);
4416 fprintf(outfile,")\n");
4417 ast_print(tree->left,outfile,indent+2);
4418 ast_print(tree->right,outfile,indent+2);
4421 /*------------------------------------------------------------------*/
4422 /*----------------------------*/
4424 /*----------------------------*/
4426 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4427 printTypeChain(tree->ftype,outfile);
4428 fprintf(outfile,")\n");
4429 ast_print(tree->left,outfile,indent+2);
4430 ast_print(tree->right,outfile,indent+2);
4433 /*------------------------------------------------------------------*/
4434 /*----------------------------*/
4435 /* struct/union pointer */
4436 /*----------------------------*/
4438 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4439 printTypeChain(tree->ftype,outfile);
4440 fprintf(outfile,")\n");
4441 ast_print(tree->left,outfile,indent+2);
4442 ast_print(tree->right,outfile,indent+2);
4445 /*------------------------------------------------------------------*/
4446 /*----------------------------*/
4447 /* ++/-- operation */
4448 /*----------------------------*/
4449 case INC_OP: /* incerement operator unary so left only */
4450 fprintf(outfile,"INC_OP (%p) type (",tree);
4451 printTypeChain(tree->ftype,outfile);
4452 fprintf(outfile,")\n");
4453 ast_print(tree->left,outfile,indent+2);
4457 fprintf(outfile,"DEC_OP (%p) type (",tree);
4458 printTypeChain(tree->ftype,outfile);
4459 fprintf(outfile,")\n");
4460 ast_print(tree->left,outfile,indent+2);
4463 /*------------------------------------------------------------------*/
4464 /*----------------------------*/
4466 /*----------------------------*/
4469 fprintf(outfile,"& (%p) type (",tree);
4470 printTypeChain(tree->ftype,outfile);
4471 fprintf(outfile,")\n");
4472 ast_print(tree->left,outfile,indent+2);
4473 ast_print(tree->right,outfile,indent+2);
4475 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4476 printTypeChain(tree->ftype,outfile);
4477 fprintf(outfile,")\n");
4478 ast_print(tree->left,outfile,indent+2);
4479 ast_print(tree->right,outfile,indent+2);
4482 /*----------------------------*/
4484 /*----------------------------*/
4486 fprintf(outfile,"OR (%p) type (",tree);
4487 printTypeChain(tree->ftype,outfile);
4488 fprintf(outfile,")\n");
4489 ast_print(tree->left,outfile,indent+2);
4490 ast_print(tree->right,outfile,indent+2);
4492 /*------------------------------------------------------------------*/
4493 /*----------------------------*/
4495 /*----------------------------*/
4497 fprintf(outfile,"XOR (%p) type (",tree);
4498 printTypeChain(tree->ftype,outfile);
4499 fprintf(outfile,")\n");
4500 ast_print(tree->left,outfile,indent+2);
4501 ast_print(tree->right,outfile,indent+2);
4504 /*------------------------------------------------------------------*/
4505 /*----------------------------*/
4507 /*----------------------------*/
4509 fprintf(outfile,"DIV (%p) type (",tree);
4510 printTypeChain(tree->ftype,outfile);
4511 fprintf(outfile,")\n");
4512 ast_print(tree->left,outfile,indent+2);
4513 ast_print(tree->right,outfile,indent+2);
4515 /*------------------------------------------------------------------*/
4516 /*----------------------------*/
4518 /*----------------------------*/
4520 fprintf(outfile,"MOD (%p) type (",tree);
4521 printTypeChain(tree->ftype,outfile);
4522 fprintf(outfile,")\n");
4523 ast_print(tree->left,outfile,indent+2);
4524 ast_print(tree->right,outfile,indent+2);
4527 /*------------------------------------------------------------------*/
4528 /*----------------------------*/
4529 /* address dereference */
4530 /*----------------------------*/
4531 case '*': /* can be unary : if right is null then unary operation */
4533 fprintf(outfile,"DEREF (%p) type (",tree);
4534 printTypeChain(tree->ftype,outfile);
4535 fprintf(outfile,")\n");
4536 ast_print(tree->left,outfile,indent+2);
4539 /*------------------------------------------------------------------*/
4540 /*----------------------------*/
4541 /* multiplication */
4542 /*----------------------------*/
4543 fprintf(outfile,"MULT (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+2);
4547 ast_print(tree->right,outfile,indent+2);
4551 /*------------------------------------------------------------------*/
4552 /*----------------------------*/
4553 /* unary '+' operator */
4554 /*----------------------------*/
4558 fprintf(outfile,"UPLUS (%p) type (",tree);
4559 printTypeChain(tree->ftype,outfile);
4560 fprintf(outfile,")\n");
4561 ast_print(tree->left,outfile,indent+2);
4563 /*------------------------------------------------------------------*/
4564 /*----------------------------*/
4566 /*----------------------------*/
4567 fprintf(outfile,"ADD (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+2);
4571 ast_print(tree->right,outfile,indent+2);
4574 /*------------------------------------------------------------------*/
4575 /*----------------------------*/
4577 /*----------------------------*/
4578 case '-': /* can be unary */
4580 fprintf(outfile,"UMINUS (%p) type (",tree);
4581 printTypeChain(tree->ftype,outfile);
4582 fprintf(outfile,")\n");
4583 ast_print(tree->left,outfile,indent+2);
4585 /*------------------------------------------------------------------*/
4586 /*----------------------------*/
4588 /*----------------------------*/
4589 fprintf(outfile,"SUB (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->left,outfile,indent+2);
4593 ast_print(tree->right,outfile,indent+2);
4596 /*------------------------------------------------------------------*/
4597 /*----------------------------*/
4599 /*----------------------------*/
4601 fprintf(outfile,"COMPL (%p) type (",tree);
4602 printTypeChain(tree->ftype,outfile);
4603 fprintf(outfile,")\n");
4604 ast_print(tree->left,outfile,indent+2);
4606 /*------------------------------------------------------------------*/
4607 /*----------------------------*/
4609 /*----------------------------*/
4611 fprintf(outfile,"NOT (%p) type (",tree);
4612 printTypeChain(tree->ftype,outfile);
4613 fprintf(outfile,")\n");
4614 ast_print(tree->left,outfile,indent+2);
4616 /*------------------------------------------------------------------*/
4617 /*----------------------------*/
4619 /*----------------------------*/
4621 fprintf(outfile,"RRC (%p) type (",tree);
4622 printTypeChain(tree->ftype,outfile);
4623 fprintf(outfile,")\n");
4624 ast_print(tree->left,outfile,indent+2);
4628 fprintf(outfile,"RLC (%p) type (",tree);
4629 printTypeChain(tree->ftype,outfile);
4630 fprintf(outfile,")\n");
4631 ast_print(tree->left,outfile,indent+2);
4634 fprintf(outfile,"GETHBIT (%p) type (",tree);
4635 printTypeChain(tree->ftype,outfile);
4636 fprintf(outfile,")\n");
4637 ast_print(tree->left,outfile,indent+2);
4640 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+2);
4644 ast_print(tree->right,outfile,indent+2);
4647 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+2);
4651 ast_print(tree->right,outfile,indent+2);
4653 /*------------------------------------------------------------------*/
4654 /*----------------------------*/
4656 /*----------------------------*/
4657 case CAST: /* change the type */
4658 fprintf(outfile,"CAST (%p) from type (",tree);
4659 printTypeChain(tree->right->ftype,outfile);
4660 fprintf(outfile,") to type (");
4661 printTypeChain(tree->ftype,outfile);
4662 fprintf(outfile,")\n");
4663 ast_print(tree->right,outfile,indent+2);
4667 fprintf(outfile,"ANDAND (%p) type (",tree);
4668 printTypeChain(tree->ftype,outfile);
4669 fprintf(outfile,")\n");
4670 ast_print(tree->left,outfile,indent+2);
4671 ast_print(tree->right,outfile,indent+2);
4674 fprintf(outfile,"OROR (%p) type (",tree);
4675 printTypeChain(tree->ftype,outfile);
4676 fprintf(outfile,")\n");
4677 ast_print(tree->left,outfile,indent+2);
4678 ast_print(tree->right,outfile,indent+2);
4681 /*------------------------------------------------------------------*/
4682 /*----------------------------*/
4683 /* comparison operators */
4684 /*----------------------------*/
4686 fprintf(outfile,"GT(>) (%p) type (",tree);
4687 printTypeChain(tree->ftype,outfile);
4688 fprintf(outfile,")\n");
4689 ast_print(tree->left,outfile,indent+2);
4690 ast_print(tree->right,outfile,indent+2);
4693 fprintf(outfile,"LT(<) (%p) type (",tree);
4694 printTypeChain(tree->ftype,outfile);
4695 fprintf(outfile,")\n");
4696 ast_print(tree->left,outfile,indent+2);
4697 ast_print(tree->right,outfile,indent+2);
4700 fprintf(outfile,"LE(<=) (%p) type (",tree);
4701 printTypeChain(tree->ftype,outfile);
4702 fprintf(outfile,")\n");
4703 ast_print(tree->left,outfile,indent+2);
4704 ast_print(tree->right,outfile,indent+2);
4707 fprintf(outfile,"GE(>=) (%p) type (",tree);
4708 printTypeChain(tree->ftype,outfile);
4709 fprintf(outfile,")\n");
4710 ast_print(tree->left,outfile,indent+2);
4711 ast_print(tree->right,outfile,indent+2);
4714 fprintf(outfile,"EQ(==) (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+2);
4718 ast_print(tree->right,outfile,indent+2);
4721 fprintf(outfile,"NE(!=) (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+2);
4725 ast_print(tree->right,outfile,indent+2);
4726 /*------------------------------------------------------------------*/
4727 /*----------------------------*/
4729 /*----------------------------*/
4730 case SIZEOF: /* evaluate wihout code generation */
4731 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4734 /*------------------------------------------------------------------*/
4735 /*----------------------------*/
4736 /* conditional operator '?' */
4737 /*----------------------------*/
4739 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4740 printTypeChain(tree->ftype,outfile);
4741 fprintf(outfile,")\n");
4742 ast_print(tree->left,outfile,indent+2);
4743 ast_print(tree->right,outfile,indent+2);
4747 fprintf(outfile,"COLON(:) (%p) type (",tree);
4748 printTypeChain(tree->ftype,outfile);
4749 fprintf(outfile,")\n");
4750 ast_print(tree->left,outfile,indent+2);
4751 ast_print(tree->right,outfile,indent+2);
4754 /*------------------------------------------------------------------*/
4755 /*----------------------------*/
4756 /* assignment operators */
4757 /*----------------------------*/
4759 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4760 printTypeChain(tree->ftype,outfile);
4761 fprintf(outfile,")\n");
4762 ast_print(tree->left,outfile,indent+2);
4763 ast_print(tree->right,outfile,indent+2);
4766 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4767 printTypeChain(tree->ftype,outfile);
4768 fprintf(outfile,")\n");
4769 ast_print(tree->left,outfile,indent+2);
4770 ast_print(tree->right,outfile,indent+2);
4773 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4774 printTypeChain(tree->ftype,outfile);
4775 fprintf(outfile,")\n");
4776 ast_print(tree->left,outfile,indent+2);
4777 ast_print(tree->right,outfile,indent+2);
4780 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4781 printTypeChain(tree->ftype,outfile);
4782 fprintf(outfile,")\n");
4783 ast_print(tree->left,outfile,indent+2);
4784 ast_print(tree->right,outfile,indent+2);
4787 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4788 printTypeChain(tree->ftype,outfile);
4789 fprintf(outfile,")\n");
4790 ast_print(tree->left,outfile,indent+2);
4791 ast_print(tree->right,outfile,indent+2);
4794 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->left,outfile,indent+2);
4798 ast_print(tree->right,outfile,indent+2);
4801 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4802 printTypeChain(tree->ftype,outfile);
4803 fprintf(outfile,")\n");
4804 ast_print(tree->left,outfile,indent+2);
4805 ast_print(tree->right,outfile,indent+2);
4807 /*------------------------------------------------------------------*/
4808 /*----------------------------*/
4810 /*----------------------------*/
4812 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4813 printTypeChain(tree->ftype,outfile);
4814 fprintf(outfile,")\n");
4815 ast_print(tree->left,outfile,indent+2);
4816 ast_print(tree->right,outfile,indent+2);
4818 /*------------------------------------------------------------------*/
4819 /*----------------------------*/
4821 /*----------------------------*/
4823 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4824 printTypeChain(tree->ftype,outfile);
4825 fprintf(outfile,")\n");
4826 ast_print(tree->left,outfile,indent+2);
4827 ast_print(tree->right,outfile,indent+2);
4829 /*------------------------------------------------------------------*/
4830 /*----------------------------*/
4831 /* straight assignemnt */
4832 /*----------------------------*/
4834 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4835 printTypeChain(tree->ftype,outfile);
4836 fprintf(outfile,")\n");
4837 ast_print(tree->left,outfile,indent+2);
4838 ast_print(tree->right,outfile,indent+2);
4840 /*------------------------------------------------------------------*/
4841 /*----------------------------*/
4842 /* comma operator */
4843 /*----------------------------*/
4845 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4846 printTypeChain(tree->ftype,outfile);
4847 fprintf(outfile,")\n");
4848 ast_print(tree->left,outfile,indent+2);
4849 ast_print(tree->right,outfile,indent+2);
4851 /*------------------------------------------------------------------*/
4852 /*----------------------------*/
4854 /*----------------------------*/
4857 fprintf(outfile,"CALL (%p) type (",tree);
4858 printTypeChain(tree->ftype,outfile);
4859 fprintf(outfile,")\n");
4860 ast_print(tree->left,outfile,indent+2);
4861 ast_print(tree->right,outfile,indent+2);
4864 fprintf(outfile,"PARMS\n");
4865 ast_print(tree->left,outfile,indent+2);
4866 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4867 ast_print(tree->right,outfile,indent+2);
4870 /*------------------------------------------------------------------*/
4871 /*----------------------------*/
4872 /* return statement */
4873 /*----------------------------*/
4875 fprintf(outfile,"RETURN (%p) type (",tree);
4876 printTypeChain(tree->right->ftype,outfile);
4877 fprintf(outfile,")\n");
4878 ast_print(tree->right,outfile,indent+2);
4880 /*------------------------------------------------------------------*/
4881 /*----------------------------*/
4882 /* label statement */
4883 /*----------------------------*/
4885 fprintf(outfile,"LABEL (%p)\n",tree);
4886 ast_print(tree->left,outfile,indent+2);
4887 ast_print(tree->right,outfile,indent);
4889 /*------------------------------------------------------------------*/
4890 /*----------------------------*/
4891 /* switch statement */
4892 /*----------------------------*/
4896 fprintf(outfile,"SWITCH (%p) ",tree);
4897 ast_print(tree->left,outfile,0);
4898 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4899 INDENT(indent+2,outfile);
4900 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4901 (int) floatFromVal(val),
4902 tree->values.switchVals.swNum,
4903 (int) floatFromVal(val));
4905 ast_print(tree->right,outfile,indent);
4908 /*------------------------------------------------------------------*/
4909 /*----------------------------*/
4911 /*----------------------------*/
4913 fprintf(outfile,"IF (%p) \n",tree);
4914 ast_print(tree->left,outfile,indent+2);
4915 if (tree->trueLabel) {
4916 INDENT(indent,outfile);
4917 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4919 if (tree->falseLabel) {
4920 INDENT(indent,outfile);
4921 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4923 ast_print(tree->right,outfile,indent+2);
4925 /*------------------------------------------------------------------*/
4926 /*----------------------------*/
4928 /*----------------------------*/
4930 fprintf(outfile,"FOR (%p) \n",tree);
4931 if (AST_FOR( tree, initExpr)) {
4932 INDENT(indent+2,outfile);
4933 fprintf(outfile,"INIT EXPR ");
4934 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4936 if (AST_FOR( tree, condExpr)) {
4937 INDENT(indent+2,outfile);
4938 fprintf(outfile,"COND EXPR ");
4939 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4941 if (AST_FOR( tree, loopExpr)) {
4942 INDENT(indent+2,outfile);
4943 fprintf(outfile,"LOOP EXPR ");
4944 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4946 fprintf(outfile,"FOR LOOP BODY \n");
4947 ast_print(tree->left,outfile,indent+2);
4956 ast_print(t,stdout,0);