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;
2735 /* if they are both literal then */
2736 /* rewrite the tree */
2737 if (IS_LITERAL (RTYPE (tree)) &&
2738 IS_LITERAL (LTYPE (tree)))
2740 tree->type = EX_VALUE;
2741 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2742 valFromType (RETYPE (tree)),
2744 tree->right = tree->left = NULL;
2745 TETYPE (tree) = getSpec (TTYPE (tree) =
2746 tree->opval.val->type);
2749 LRVAL (tree) = RRVAL (tree) = 1;
2750 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2753 /*------------------------------------------------------------------*/
2754 /*----------------------------*/
2756 /*----------------------------*/
2757 case SIZEOF: /* evaluate wihout code generation */
2758 /* change the type to a integer */
2759 tree->type = EX_VALUE;
2760 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2761 tree->opval.val = constVal (buffer);
2762 tree->right = tree->left = NULL;
2763 TETYPE (tree) = getSpec (TTYPE (tree) =
2764 tree->opval.val->type);
2767 /*------------------------------------------------------------------*/
2768 /*----------------------------*/
2770 /*----------------------------*/
2772 /* return typeof enum value */
2773 tree->type = EX_VALUE;
2776 if (IS_SPEC(tree->right->ftype)) {
2777 switch (SPEC_NOUN(tree->right->ftype)) {
2779 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2780 else typeofv = TYPEOF_INT;
2783 typeofv = TYPEOF_FLOAT;
2786 typeofv = TYPEOF_CHAR;
2789 typeofv = TYPEOF_VOID;
2792 typeofv = TYPEOF_STRUCT;
2795 typeofv = TYPEOF_BIT;
2798 typeofv = TYPEOF_SBIT;
2804 switch (DCL_TYPE(tree->right->ftype)) {
2806 typeofv = TYPEOF_POINTER;
2809 typeofv = TYPEOF_FPOINTER;
2812 typeofv = TYPEOF_CPOINTER;
2815 typeofv = TYPEOF_GPOINTER;
2818 typeofv = TYPEOF_PPOINTER;
2821 typeofv = TYPEOF_IPOINTER;
2824 typeofv = TYPEOF_ARRAY;
2827 typeofv = TYPEOF_FUNCTION;
2833 sprintf (buffer, "%d", typeofv);
2834 tree->opval.val = constVal (buffer);
2835 tree->right = tree->left = NULL;
2836 TETYPE (tree) = getSpec (TTYPE (tree) =
2837 tree->opval.val->type);
2840 /*------------------------------------------------------------------*/
2841 /*----------------------------*/
2842 /* conditional operator '?' */
2843 /*----------------------------*/
2845 /* the type is value of the colon operator (on the right) */
2846 assert(IS_COLON_OP(tree->right));
2847 /* if already known then replace the tree : optimizer will do it
2848 but faster to do it here */
2849 if (IS_LITERAL (LTYPE(tree))) {
2850 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2851 return decorateType(tree->right->left) ;
2853 return decorateType(tree->right->right) ;
2856 tree->right = decorateType(tree->right);
2857 TTYPE (tree) = RTYPE(tree);
2858 TETYPE (tree) = getSpec (TTYPE (tree));
2863 /* if they don't match we have a problem */
2864 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2866 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2867 goto errorTreeReturn;
2870 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2871 TETYPE (tree) = getSpec (TTYPE (tree));
2875 /*------------------------------------------------------------------*/
2876 /*----------------------------*/
2877 /* assignment operators */
2878 /*----------------------------*/
2881 /* for these it must be both must be integral */
2882 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2883 !IS_ARITHMETIC (RTYPE (tree)))
2885 werror (E_OPS_INTEGRAL);
2886 goto errorTreeReturn;
2889 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2891 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2892 werror (E_CODE_WRITE, " ");
2896 werror (E_LVALUE_REQUIRED, "*= or /=");
2897 goto errorTreeReturn;
2908 /* for these it must be both must be integral */
2909 if (!IS_INTEGRAL (LTYPE (tree)) ||
2910 !IS_INTEGRAL (RTYPE (tree)))
2912 werror (E_OPS_INTEGRAL);
2913 goto errorTreeReturn;
2916 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2918 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2919 werror (E_CODE_WRITE, " ");
2923 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2924 goto errorTreeReturn;
2930 /*------------------------------------------------------------------*/
2931 /*----------------------------*/
2933 /*----------------------------*/
2935 if (!(IS_PTR (LTYPE (tree)) ||
2936 IS_ARITHMETIC (LTYPE (tree))))
2938 werror (E_PLUS_INVALID, "-=");
2939 goto errorTreeReturn;
2942 if (!(IS_PTR (RTYPE (tree)) ||
2943 IS_ARITHMETIC (RTYPE (tree))))
2945 werror (E_PLUS_INVALID, "-=");
2946 goto errorTreeReturn;
2949 TETYPE (tree) = getSpec (TTYPE (tree) =
2950 computeType (LTYPE (tree),
2953 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2954 werror (E_CODE_WRITE, " ");
2958 werror (E_LVALUE_REQUIRED, "-=");
2959 goto errorTreeReturn;
2965 /*------------------------------------------------------------------*/
2966 /*----------------------------*/
2968 /*----------------------------*/
2970 /* this is not a unary operation */
2971 /* if both pointers then problem */
2972 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2974 werror (E_PTR_PLUS_PTR);
2975 goto errorTreeReturn;
2978 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2980 werror (E_PLUS_INVALID, "+=");
2981 goto errorTreeReturn;
2984 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2986 werror (E_PLUS_INVALID, "+=");
2987 goto errorTreeReturn;
2990 TETYPE (tree) = getSpec (TTYPE (tree) =
2991 computeType (LTYPE (tree),
2994 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2995 werror (E_CODE_WRITE, " ");
2999 werror (E_LVALUE_REQUIRED, "+=");
3000 goto errorTreeReturn;
3003 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3004 tree->opval.op = '=';
3008 /*------------------------------------------------------------------*/
3009 /*----------------------------*/
3010 /* straight assignemnt */
3011 /*----------------------------*/
3013 /* cannot be an aggregate */
3014 if (IS_AGGREGATE (LTYPE (tree)))
3016 werror (E_AGGR_ASSIGN);
3017 goto errorTreeReturn;
3020 /* they should either match or be castable */
3021 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3023 werror (E_TYPE_MISMATCH, "assignment", " ");
3024 fprintf (stderr, "type --> '");
3025 printTypeChain (RTYPE (tree), stderr);
3026 fprintf (stderr, "' ");
3027 fprintf (stderr, "assigned to type --> '");
3028 printTypeChain (LTYPE (tree), stderr);
3029 fprintf (stderr, "'\n");
3030 goto errorTreeReturn;
3033 /* if the left side of the tree is of type void
3034 then report error */
3035 if (IS_VOID (LTYPE (tree)))
3037 werror (E_CAST_ZERO);
3038 printFromToType(RTYPE(tree), LTYPE(tree));
3041 TETYPE (tree) = getSpec (TTYPE (tree) =
3045 if (!tree->initMode ) {
3046 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3047 werror (E_CODE_WRITE, " ");
3051 werror (E_LVALUE_REQUIRED, "=");
3052 goto errorTreeReturn;
3057 /*------------------------------------------------------------------*/
3058 /*----------------------------*/
3059 /* comma operator */
3060 /*----------------------------*/
3062 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3068 /*----------------------------*/
3072 if (processParms (tree->left,
3073 FUNC_ARGS(tree->left->ftype),
3074 tree->right, &parmNumber, TRUE)) {
3075 goto errorTreeReturn;
3078 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3079 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3081 //FUNC_ARGS(tree->left->ftype) =
3082 //reverseVal (FUNC_ARGS(tree->left->ftype));
3083 reverseParms (tree->right);
3086 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3089 /*------------------------------------------------------------------*/
3090 /*----------------------------*/
3091 /* return statement */
3092 /*----------------------------*/
3097 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3099 werror (W_RETURN_MISMATCH);
3100 printFromToType (RTYPE(tree), currFunc->type->next);
3101 goto errorTreeReturn;
3104 if (IS_VOID (currFunc->type->next)
3106 !IS_VOID (RTYPE (tree)))
3108 werror (E_FUNC_VOID);
3109 goto errorTreeReturn;
3112 /* if there is going to be a casing required then add it */
3113 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3116 decorateType (newNode (CAST,
3117 newAst_LINK (copyLinkChain (currFunc->type->next)),
3126 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3128 werror (E_VOID_FUNC, currFunc->name);
3129 goto errorTreeReturn;
3132 TTYPE (tree) = TETYPE (tree) = NULL;
3135 /*------------------------------------------------------------------*/
3136 /*----------------------------*/
3137 /* switch statement */
3138 /*----------------------------*/
3140 /* the switch value must be an integer */
3141 if (!IS_INTEGRAL (LTYPE (tree)))
3143 werror (E_SWITCH_NON_INTEGER);
3144 goto errorTreeReturn;
3147 TTYPE (tree) = TETYPE (tree) = NULL;
3150 /*------------------------------------------------------------------*/
3151 /*----------------------------*/
3153 /*----------------------------*/
3155 tree->left = backPatchLabels (tree->left,
3158 TTYPE (tree) = TETYPE (tree) = NULL;
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3164 /*----------------------------*/
3167 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3168 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3169 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3171 /* if the for loop is reversible then
3172 reverse it otherwise do what we normally
3178 if (isLoopReversible (tree, &sym, &init, &end))
3179 return reverseLoop (tree, sym, init, end);
3181 return decorateType (createFor (AST_FOR (tree, trueLabel),
3182 AST_FOR (tree, continueLabel),
3183 AST_FOR (tree, falseLabel),
3184 AST_FOR (tree, condLabel),
3185 AST_FOR (tree, initExpr),
3186 AST_FOR (tree, condExpr),
3187 AST_FOR (tree, loopExpr),
3191 TTYPE (tree) = TETYPE (tree) = NULL;
3195 /* some error found this tree will be killed */
3197 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3198 tree->opval.op = NULLOP;
3204 /*-----------------------------------------------------------------*/
3205 /* sizeofOp - processes size of operation */
3206 /*-----------------------------------------------------------------*/
3208 sizeofOp (sym_link * type)
3212 /* make sure the type is complete and sane */
3213 checkTypeSanity(type, "(sizeof)");
3215 /* get the size and convert it to character */
3216 sprintf (buff, "%d", getSize (type));
3218 /* now convert into value */
3219 return constVal (buff);
3223 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3224 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3225 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3226 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3227 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3228 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3229 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3231 /*-----------------------------------------------------------------*/
3232 /* backPatchLabels - change and or not operators to flow control */
3233 /*-----------------------------------------------------------------*/
3235 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3241 if (!(IS_ANDORNOT (tree)))
3244 /* if this an and */
3247 static int localLbl = 0;
3250 sprintf (buffer, "_and_%d", localLbl++);
3251 localLabel = newSymbol (buffer, NestLevel);
3253 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3255 /* if left is already a IFX then just change the if true label in that */
3256 if (!IS_IFX (tree->left))
3257 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3259 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3260 /* right is a IFX then just join */
3261 if (IS_IFX (tree->right))
3262 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3264 tree->right = createLabel (localLabel, tree->right);
3265 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3267 return newNode (NULLOP, tree->left, tree->right);
3270 /* if this is an or operation */
3273 static int localLbl = 0;
3276 sprintf (buffer, "_or_%d", localLbl++);
3277 localLabel = newSymbol (buffer, NestLevel);
3279 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3281 /* if left is already a IFX then just change the if true label in that */
3282 if (!IS_IFX (tree->left))
3283 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3285 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3286 /* right is a IFX then just join */
3287 if (IS_IFX (tree->right))
3288 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3290 tree->right = createLabel (localLabel, tree->right);
3291 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3293 return newNode (NULLOP, tree->left, tree->right);
3299 int wasnot = IS_NOT (tree->left);
3300 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3302 /* if the left is already a IFX */
3303 if (!IS_IFX (tree->left))
3304 tree->left = newNode (IFX, tree->left, NULL);
3308 tree->left->trueLabel = trueLabel;
3309 tree->left->falseLabel = falseLabel;
3313 tree->left->trueLabel = falseLabel;
3314 tree->left->falseLabel = trueLabel;
3321 tree->trueLabel = trueLabel;
3322 tree->falseLabel = falseLabel;
3329 /*-----------------------------------------------------------------*/
3330 /* createBlock - create expression tree for block */
3331 /*-----------------------------------------------------------------*/
3333 createBlock (symbol * decl, ast * body)
3337 /* if the block has nothing */
3341 ex = newNode (BLOCK, NULL, body);
3342 ex->values.sym = decl;
3344 ex->right = ex->right;
3350 /*-----------------------------------------------------------------*/
3351 /* createLabel - creates the expression tree for labels */
3352 /*-----------------------------------------------------------------*/
3354 createLabel (symbol * label, ast * stmnt)
3357 char name[SDCC_NAME_MAX + 1];
3360 /* must create fresh symbol if the symbol name */
3361 /* exists in the symbol table, since there can */
3362 /* be a variable with the same name as the labl */
3363 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3364 (csym->level == label->level))
3365 label = newSymbol (label->name, label->level);
3367 /* change the name before putting it in add _ */
3368 sprintf (name, "%s", label->name);
3370 /* put the label in the LabelSymbol table */
3371 /* but first check if a label of the same */
3373 if ((csym = findSym (LabelTab, NULL, name)))
3374 werror (E_DUPLICATE_LABEL, label->name);
3376 addSym (LabelTab, label, name, label->level, 0, 0);
3379 label->key = labelKey++;
3380 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3386 /*-----------------------------------------------------------------*/
3387 /* createCase - generates the parsetree for a case statement */
3388 /*-----------------------------------------------------------------*/
3390 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3392 char caseLbl[SDCC_NAME_MAX + 1];
3396 /* if the switch statement does not exist */
3397 /* then case is out of context */
3400 werror (E_CASE_CONTEXT);
3404 caseVal = decorateType (resolveSymbols (caseVal));
3405 /* if not a constant then error */
3406 if (!IS_LITERAL (caseVal->ftype))
3408 werror (E_CASE_CONSTANT);
3412 /* if not a integer than error */
3413 if (!IS_INTEGRAL (caseVal->ftype))
3415 werror (E_CASE_NON_INTEGER);
3419 /* find the end of the switch values chain */
3420 if (!(val = swStat->values.switchVals.swVals))
3421 swStat->values.switchVals.swVals = caseVal->opval.val;
3424 /* also order the cases according to value */
3426 int cVal = (int) floatFromVal (caseVal->opval.val);
3427 while (val && (int) floatFromVal (val) < cVal)
3433 /* if we reached the end then */
3436 pval->next = caseVal->opval.val;
3440 /* we found a value greater than */
3441 /* the current value we must add this */
3442 /* before the value */
3443 caseVal->opval.val->next = val;
3445 /* if this was the first in chain */
3446 if (swStat->values.switchVals.swVals == val)
3447 swStat->values.switchVals.swVals =
3450 pval->next = caseVal->opval.val;
3455 /* create the case label */
3456 sprintf (caseLbl, "_case_%d_%d",
3457 swStat->values.switchVals.swNum,
3458 (int) floatFromVal (caseVal->opval.val));
3460 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3465 /*-----------------------------------------------------------------*/
3466 /* createDefault - creates the parse tree for the default statement */
3467 /*-----------------------------------------------------------------*/
3469 createDefault (ast * swStat, ast * stmnt)
3471 char defLbl[SDCC_NAME_MAX + 1];
3473 /* if the switch statement does not exist */
3474 /* then case is out of context */
3477 werror (E_CASE_CONTEXT);
3481 /* turn on the default flag */
3482 swStat->values.switchVals.swDefault = 1;
3484 /* create the label */
3485 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3486 return createLabel (newSymbol (defLbl, 0), stmnt);
3489 /*-----------------------------------------------------------------*/
3490 /* createIf - creates the parsetree for the if statement */
3491 /*-----------------------------------------------------------------*/
3493 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3495 static int Lblnum = 0;
3497 symbol *ifTrue, *ifFalse, *ifEnd;
3499 /* if neither exists */
3500 if (!elseBody && !ifBody) {
3501 // if there are no side effects (i++, j() etc)
3502 if (!hasSEFcalls(condAst)) {
3507 /* create the labels */
3508 sprintf (buffer, "_iffalse_%d", Lblnum);
3509 ifFalse = newSymbol (buffer, NestLevel);
3510 /* if no else body then end == false */
3515 sprintf (buffer, "_ifend_%d", Lblnum);
3516 ifEnd = newSymbol (buffer, NestLevel);
3519 sprintf (buffer, "_iftrue_%d", Lblnum);
3520 ifTrue = newSymbol (buffer, NestLevel);
3524 /* attach the ifTrue label to the top of it body */
3525 ifBody = createLabel (ifTrue, ifBody);
3526 /* attach a goto end to the ifBody if else is present */
3529 ifBody = newNode (NULLOP, ifBody,
3531 newAst_VALUE (symbolVal (ifEnd)),
3533 /* put the elseLabel on the else body */
3534 elseBody = createLabel (ifFalse, elseBody);
3535 /* out the end at the end of the body */
3536 elseBody = newNode (NULLOP,
3538 createLabel (ifEnd, NULL));
3542 ifBody = newNode (NULLOP, ifBody,
3543 createLabel (ifFalse, NULL));
3545 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3546 if (IS_IFX (condAst))
3549 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3551 return newNode (NULLOP, ifTree,
3552 newNode (NULLOP, ifBody, elseBody));
3556 /*-----------------------------------------------------------------*/
3557 /* createDo - creates parse tree for do */
3560 /* _docontinue_n: */
3561 /* condition_expression +-> trueLabel -> _dobody_n */
3563 /* +-> falseLabel-> _dobreak_n */
3565 /*-----------------------------------------------------------------*/
3567 createDo (symbol * trueLabel, symbol * continueLabel,
3568 symbol * falseLabel, ast * condAst, ast * doBody)
3573 /* if the body does not exist then it is simple */
3576 condAst = backPatchLabels (condAst, continueLabel, NULL);
3577 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3578 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3579 doTree->trueLabel = continueLabel;
3580 doTree->falseLabel = NULL;
3584 /* otherwise we have a body */
3585 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3587 /* attach the body label to the top */
3588 doBody = createLabel (trueLabel, doBody);
3589 /* attach the continue label to end of body */
3590 doBody = newNode (NULLOP, doBody,
3591 createLabel (continueLabel, NULL));
3593 /* now put the break label at the end */
3594 if (IS_IFX (condAst))
3597 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3599 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3601 /* putting it together */
3602 return newNode (NULLOP, doBody, doTree);
3605 /*-----------------------------------------------------------------*/
3606 /* createFor - creates parse tree for 'for' statement */
3609 /* condExpr +-> trueLabel -> _forbody_n */
3611 /* +-> falseLabel-> _forbreak_n */
3614 /* _forcontinue_n: */
3616 /* goto _forcond_n ; */
3618 /*-----------------------------------------------------------------*/
3620 createFor (symbol * trueLabel, symbol * continueLabel,
3621 symbol * falseLabel, symbol * condLabel,
3622 ast * initExpr, ast * condExpr, ast * loopExpr,
3627 /* if loopexpression not present then we can generate it */
3628 /* the same way as a while */
3630 return newNode (NULLOP, initExpr,
3631 createWhile (trueLabel, continueLabel,
3632 falseLabel, condExpr, forBody));
3633 /* vanilla for statement */
3634 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3636 if (condExpr && !IS_IFX (condExpr))
3637 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3640 /* attach condition label to condition */
3641 condExpr = createLabel (condLabel, condExpr);
3643 /* attach body label to body */
3644 forBody = createLabel (trueLabel, forBody);
3646 /* attach continue to forLoop expression & attach */
3647 /* goto the forcond @ and of loopExpression */
3648 loopExpr = createLabel (continueLabel,
3652 newAst_VALUE (symbolVal (condLabel)),
3654 /* now start putting them together */
3655 forTree = newNode (NULLOP, initExpr, condExpr);
3656 forTree = newNode (NULLOP, forTree, forBody);
3657 forTree = newNode (NULLOP, forTree, loopExpr);
3658 /* finally add the break label */
3659 forTree = newNode (NULLOP, forTree,
3660 createLabel (falseLabel, NULL));
3664 /*-----------------------------------------------------------------*/
3665 /* createWhile - creates parse tree for while statement */
3666 /* the while statement will be created as follows */
3668 /* _while_continue_n: */
3669 /* condition_expression +-> trueLabel -> _while_boby_n */
3671 /* +-> falseLabel -> _while_break_n */
3672 /* _while_body_n: */
3674 /* goto _while_continue_n */
3675 /* _while_break_n: */
3676 /*-----------------------------------------------------------------*/
3678 createWhile (symbol * trueLabel, symbol * continueLabel,
3679 symbol * falseLabel, ast * condExpr, ast * whileBody)
3683 /* put the continue label */
3684 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3685 condExpr = createLabel (continueLabel, condExpr);
3686 condExpr->lineno = 0;
3688 /* put the body label in front of the body */
3689 whileBody = createLabel (trueLabel, whileBody);
3690 whileBody->lineno = 0;
3691 /* put a jump to continue at the end of the body */
3692 /* and put break label at the end of the body */
3693 whileBody = newNode (NULLOP,
3696 newAst_VALUE (symbolVal (continueLabel)),
3697 createLabel (falseLabel, NULL)));
3699 /* put it all together */
3700 if (IS_IFX (condExpr))
3701 whileTree = condExpr;
3704 whileTree = newNode (IFX, condExpr, NULL);
3705 /* put the true & false labels in place */
3706 whileTree->trueLabel = trueLabel;
3707 whileTree->falseLabel = falseLabel;
3710 return newNode (NULLOP, whileTree, whileBody);
3713 /*-----------------------------------------------------------------*/
3714 /* optimizeGetHbit - get highest order bit of the expression */
3715 /*-----------------------------------------------------------------*/
3717 optimizeGetHbit (ast * tree)
3720 /* if this is not a bit and */
3721 if (!IS_BITAND (tree))
3724 /* will look for tree of the form
3725 ( expr >> ((sizeof expr) -1) ) & 1 */
3726 if (!IS_AST_LIT_VALUE (tree->right))
3729 if (AST_LIT_VALUE (tree->right) != 1)
3732 if (!IS_RIGHT_OP (tree->left))
3735 if (!IS_AST_LIT_VALUE (tree->left->right))
3738 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3739 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3742 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3746 /*-----------------------------------------------------------------*/
3747 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3748 /*-----------------------------------------------------------------*/
3750 optimizeRRCRLC (ast * root)
3752 /* will look for trees of the form
3753 (?expr << 1) | (?expr >> 7) or
3754 (?expr >> 7) | (?expr << 1) will make that
3755 into a RLC : operation ..
3757 (?expr >> 1) | (?expr << 7) or
3758 (?expr << 7) | (?expr >> 1) will make that
3759 into a RRC operation
3760 note : by 7 I mean (number of bits required to hold the
3762 /* if the root operations is not a | operation the not */
3763 if (!IS_BITOR (root))
3766 /* I have to think of a better way to match patterns this sucks */
3767 /* that aside let start looking for the first case : I use a the
3768 negative check a lot to improve the efficiency */
3769 /* (?expr << 1) | (?expr >> 7) */
3770 if (IS_LEFT_OP (root->left) &&
3771 IS_RIGHT_OP (root->right))
3774 if (!SPEC_USIGN (TETYPE (root->left->left)))
3777 if (!IS_AST_LIT_VALUE (root->left->right) ||
3778 !IS_AST_LIT_VALUE (root->right->right))
3781 /* make sure it is the same expression */
3782 if (!isAstEqual (root->left->left,
3786 if (AST_LIT_VALUE (root->left->right) != 1)
3789 if (AST_LIT_VALUE (root->right->right) !=
3790 (getSize (TTYPE (root->left->left)) * 8 - 1))
3793 /* whew got the first case : create the AST */
3794 return newNode (RLC, root->left->left, NULL);
3798 /* check for second case */
3799 /* (?expr >> 7) | (?expr << 1) */
3800 if (IS_LEFT_OP (root->right) &&
3801 IS_RIGHT_OP (root->left))
3804 if (!SPEC_USIGN (TETYPE (root->left->left)))
3807 if (!IS_AST_LIT_VALUE (root->left->right) ||
3808 !IS_AST_LIT_VALUE (root->right->right))
3811 /* make sure it is the same symbol */
3812 if (!isAstEqual (root->left->left,
3816 if (AST_LIT_VALUE (root->right->right) != 1)
3819 if (AST_LIT_VALUE (root->left->right) !=
3820 (getSize (TTYPE (root->left->left)) * 8 - 1))
3823 /* whew got the first case : create the AST */
3824 return newNode (RLC, root->left->left, NULL);
3829 /* third case for RRC */
3830 /* (?symbol >> 1) | (?symbol << 7) */
3831 if (IS_LEFT_OP (root->right) &&
3832 IS_RIGHT_OP (root->left))
3835 if (!SPEC_USIGN (TETYPE (root->left->left)))
3838 if (!IS_AST_LIT_VALUE (root->left->right) ||
3839 !IS_AST_LIT_VALUE (root->right->right))
3842 /* make sure it is the same symbol */
3843 if (!isAstEqual (root->left->left,
3847 if (AST_LIT_VALUE (root->left->right) != 1)
3850 if (AST_LIT_VALUE (root->right->right) !=
3851 (getSize (TTYPE (root->left->left)) * 8 - 1))
3854 /* whew got the first case : create the AST */
3855 return newNode (RRC, root->left->left, NULL);
3859 /* fourth and last case for now */
3860 /* (?symbol << 7) | (?symbol >> 1) */
3861 if (IS_RIGHT_OP (root->right) &&
3862 IS_LEFT_OP (root->left))
3865 if (!SPEC_USIGN (TETYPE (root->left->left)))
3868 if (!IS_AST_LIT_VALUE (root->left->right) ||
3869 !IS_AST_LIT_VALUE (root->right->right))
3872 /* make sure it is the same symbol */
3873 if (!isAstEqual (root->left->left,
3877 if (AST_LIT_VALUE (root->right->right) != 1)
3880 if (AST_LIT_VALUE (root->left->right) !=
3881 (getSize (TTYPE (root->left->left)) * 8 - 1))
3884 /* whew got the first case : create the AST */
3885 return newNode (RRC, root->left->left, NULL);
3889 /* not found return root */
3893 /*-----------------------------------------------------------------*/
3894 /* optimizeCompare - otimizes compares for bit variables */
3895 /*-----------------------------------------------------------------*/
3897 optimizeCompare (ast * root)
3899 ast *optExpr = NULL;
3902 unsigned int litValue;
3904 /* if nothing then return nothing */
3908 /* if not a compare op then do leaves */
3909 if (!IS_COMPARE_OP (root))
3911 root->left = optimizeCompare (root->left);
3912 root->right = optimizeCompare (root->right);
3916 /* if left & right are the same then depending
3917 of the operation do */
3918 if (isAstEqual (root->left, root->right))
3920 switch (root->opval.op)
3925 optExpr = newAst_VALUE (constVal ("0"));
3930 optExpr = newAst_VALUE (constVal ("1"));
3934 return decorateType (optExpr);
3937 vleft = (root->left->type == EX_VALUE ?
3938 root->left->opval.val : NULL);
3940 vright = (root->right->type == EX_VALUE ?
3941 root->right->opval.val : NULL);
3943 //#define EXPERIMENTAL
3945 /* if left is unsigned and right is literal */
3946 if (vleft && vright &&
3947 IS_UNSIGNED(vleft->etype) &&
3948 IS_LITERAL(vright->etype)) {
3949 double dval=floatFromVal(vright);
3950 int op=root->opval.op;
3952 fprintf (stderr,"op: '");
3954 case LE_OP: fprintf (stderr, "<= '"); break;
3955 case EQ_OP: fprintf (stderr, "== '"); break;
3956 case GE_OP: fprintf (stderr, ">= '"); break;
3957 default: fprintf (stderr, "%c '", op); break;
3959 fprintf (stderr, "%f\n", dval);
3966 if (dval<0 || (op=='<' && dval==0)) {
3967 // unsigned is never < 0
3968 werror (W_IF_NEVER_TRUE);
3969 optExpr = newAst_VALUE (constVal("0"));
3970 return decorateType (optExpr);
3974 // change this into a cheaper EQ_OP
3975 fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
3976 root->opval.op=EQ_OP;
3983 if (dval>0 || (op==GE_OP && dval==0)) {
3984 // unsigned is never < 0
3985 werror (W_IF_ALWAYS_TRUE);
3986 optExpr = newAst_VALUE (constVal("1"));
3987 return decorateType (optExpr);
3991 // change this into a cheaper reversed EQ_OP
3992 fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
3993 root->opval.op=EQ_OP;
4000 /* if left is a BITVAR in BITSPACE */
4001 /* and right is a LITERAL then opt- */
4002 /* imize else do nothing */
4003 if (vleft && vright &&
4004 IS_BITVAR (vleft->etype) &&
4005 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4006 IS_LITERAL (vright->etype))
4009 /* if right side > 1 then comparison may never succeed */
4010 if ((litValue = (int) floatFromVal (vright)) > 1)
4012 werror (W_BAD_COMPARE);
4018 switch (root->opval.op)
4020 case '>': /* bit value greater than 1 cannot be */
4021 werror (W_BAD_COMPARE);
4025 case '<': /* bit value < 1 means 0 */
4027 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4030 case LE_OP: /* bit value <= 1 means no check */
4031 optExpr = newAst_VALUE (vright);
4034 case GE_OP: /* bit value >= 1 means only check for = */
4036 optExpr = newAst_VALUE (vleft);
4041 { /* literal is zero */
4042 switch (root->opval.op)
4044 case '<': /* bit value < 0 cannot be */
4045 werror (W_BAD_COMPARE);
4049 case '>': /* bit value > 0 means 1 */
4051 optExpr = newAst_VALUE (vleft);
4054 case LE_OP: /* bit value <= 0 means no check */
4055 case GE_OP: /* bit value >= 0 means no check */
4056 werror (W_BAD_COMPARE);
4060 case EQ_OP: /* bit == 0 means ! of bit */
4061 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4065 return decorateType (resolveSymbols (optExpr));
4066 } /* end-of-if of BITVAR */
4071 /*-----------------------------------------------------------------*/
4072 /* addSymToBlock : adds the symbol to the first block we find */
4073 /*-----------------------------------------------------------------*/
4075 addSymToBlock (symbol * sym, ast * tree)
4077 /* reached end of tree or a leaf */
4078 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4082 if (IS_AST_OP (tree) &&
4083 tree->opval.op == BLOCK)
4086 symbol *lsym = copySymbol (sym);
4088 lsym->next = AST_VALUES (tree, sym);
4089 AST_VALUES (tree, sym) = lsym;
4093 addSymToBlock (sym, tree->left);
4094 addSymToBlock (sym, tree->right);
4097 /*-----------------------------------------------------------------*/
4098 /* processRegParms - do processing for register parameters */
4099 /*-----------------------------------------------------------------*/
4101 processRegParms (value * args, ast * body)
4105 if (IS_REGPARM (args->etype))
4106 addSymToBlock (args->sym, body);
4111 /*-----------------------------------------------------------------*/
4112 /* resetParmKey - resets the operandkeys for the symbols */
4113 /*-----------------------------------------------------------------*/
4114 DEFSETFUNC (resetParmKey)
4125 /*-----------------------------------------------------------------*/
4126 /* createFunction - This is the key node that calls the iCode for */
4127 /* generating the code for a function. Note code */
4128 /* is generated function by function, later when */
4129 /* add inter-procedural analysis this will change */
4130 /*-----------------------------------------------------------------*/
4132 createFunction (symbol * name, ast * body)
4138 iCode *piCode = NULL;
4140 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4141 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4143 /* if check function return 0 then some problem */
4144 if (checkFunction (name, NULL) == 0)
4147 /* create a dummy block if none exists */
4149 body = newNode (BLOCK, NULL, NULL);
4153 /* check if the function name already in the symbol table */
4154 if ((csym = findSym (SymbolTab, NULL, name->name)))
4157 /* special case for compiler defined functions
4158 we need to add the name to the publics list : this
4159 actually means we are now compiling the compiler
4163 addSet (&publics, name);
4169 allocVariables (name);
4171 name->lastLine = yylineno;
4174 /* set the stack pointer */
4175 /* PENDING: check this for the mcs51 */
4176 stackPtr = -port->stack.direction * port->stack.call_overhead;
4177 if (IFFUNC_ISISR (name->type))
4178 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4179 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4180 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4182 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4184 fetype = getSpec (name->type); /* get the specifier for the function */
4185 /* if this is a reentrant function then */
4186 if (IFFUNC_ISREENT (name->type))
4189 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4191 /* do processing for parameters that are passed in registers */
4192 processRegParms (FUNC_ARGS(name->type), body);
4194 /* set the stack pointer */
4198 /* allocate & autoinit the block variables */
4199 processBlockVars (body, &stack, ALLOCATE);
4201 /* save the stack information */
4202 if (options.useXstack)
4203 name->xstack = SPEC_STAK (fetype) = stack;
4205 name->stack = SPEC_STAK (fetype) = stack;
4207 /* name needs to be mangled */
4208 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4210 body = resolveSymbols (body); /* resolve the symbols */
4211 body = decorateType (body); /* propagateType & do semantic checks */
4213 ex = newAst_VALUE (symbolVal (name)); /* create name */
4214 ex = newNode (FUNCTION, ex, body);
4215 ex->values.args = FUNC_ARGS(name->type);
4217 if (options.dump_tree) PA(ex);
4220 werror (E_FUNC_NO_CODE, name->name);
4224 /* create the node & generate intermediate code */
4226 codeOutFile = code->oFile;
4227 piCode = iCodeFromAst (ex);
4231 werror (E_FUNC_NO_CODE, name->name);
4235 eBBlockFromiCode (piCode);
4237 /* if there are any statics then do them */
4240 GcurMemmap = statsg;
4241 codeOutFile = statsg->oFile;
4242 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4248 /* dealloc the block variables */
4249 processBlockVars (body, &stack, DEALLOCATE);
4250 /* deallocate paramaters */
4251 deallocParms (FUNC_ARGS(name->type));
4253 if (IFFUNC_ISREENT (name->type))
4256 /* we are done freeup memory & cleanup */
4258 if (port->reset_labelKey) labelKey = 1;
4260 FUNC_HASBODY(name->type) = 1;
4261 addSet (&operKeyReset, name);
4262 applyToSet (operKeyReset, resetParmKey);
4265 cdbStructBlock (1, cdbFile);
4267 cleanUpLevel (LabelTab, 0);
4268 cleanUpBlock (StructTab, 1);
4269 cleanUpBlock (TypedefTab, 1);
4271 xstack->syms = NULL;
4272 istack->syms = NULL;
4277 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4278 /*-----------------------------------------------------------------*/
4279 /* ast_print : prints the ast (for debugging purposes) */
4280 /*-----------------------------------------------------------------*/
4282 void ast_print (ast * tree, FILE *outfile, int indent)
4287 /* can print only decorated trees */
4288 if (!tree->decorated) return;
4290 /* if any child is an error | this one is an error do nothing */
4291 if (tree->isError ||
4292 (tree->left && tree->left->isError) ||
4293 (tree->right && tree->right->isError)) {
4294 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4298 /* print the line */
4299 /* if not block & function */
4300 if (tree->type == EX_OP &&
4301 (tree->opval.op != FUNCTION &&
4302 tree->opval.op != BLOCK &&
4303 tree->opval.op != NULLOP)) {
4306 if (tree->opval.op == FUNCTION) {
4308 value *args=FUNC_ARGS(tree->left->opval.val->type);
4309 fprintf(outfile,"FUNCTION (%s=%p) type (",
4310 tree->left->opval.val->name, tree);
4311 printTypeChain (tree->ftype,outfile);
4312 fprintf(outfile,") args (");
4315 fprintf (outfile, ", ");
4317 printTypeChain (args ? args->type : NULL, outfile);
4319 args= args ? args->next : NULL;
4321 fprintf(outfile,")\n");
4322 ast_print(tree->left,outfile,indent);
4323 ast_print(tree->right,outfile,indent);
4326 if (tree->opval.op == BLOCK) {
4327 symbol *decls = tree->values.sym;
4328 INDENT(indent,outfile);
4329 fprintf(outfile,"{\n");
4331 INDENT(indent+2,outfile);
4332 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4333 decls->name, decls);
4334 printTypeChain(decls->type,outfile);
4335 fprintf(outfile,")\n");
4337 decls = decls->next;
4339 ast_print(tree->right,outfile,indent+2);
4340 INDENT(indent,outfile);
4341 fprintf(outfile,"}\n");
4344 if (tree->opval.op == NULLOP) {
4345 fprintf(outfile,"\n");
4346 ast_print(tree->left,outfile,indent);
4347 fprintf(outfile,"\n");
4348 ast_print(tree->right,outfile,indent);
4351 INDENT(indent,outfile);
4353 /*------------------------------------------------------------------*/
4354 /*----------------------------*/
4355 /* leaf has been reached */
4356 /*----------------------------*/
4357 /* if this is of type value */
4358 /* just get the type */
4359 if (tree->type == EX_VALUE) {
4361 if (IS_LITERAL (tree->opval.val->etype)) {
4362 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4363 (int) floatFromVal(tree->opval.val),
4364 (int) floatFromVal(tree->opval.val),
4365 floatFromVal(tree->opval.val));
4366 } else if (tree->opval.val->sym) {
4367 /* if the undefined flag is set then give error message */
4368 if (tree->opval.val->sym->undefined) {
4369 fprintf(outfile,"UNDEFINED SYMBOL ");
4371 fprintf(outfile,"SYMBOL ");
4373 fprintf(outfile,"(%s=%p)",
4374 tree->opval.val->sym->name,tree);
4377 fprintf(outfile," type (");
4378 printTypeChain(tree->ftype,outfile);
4379 fprintf(outfile,")\n");
4381 fprintf(outfile,"\n");
4386 /* if type link for the case of cast */
4387 if (tree->type == EX_LINK) {
4388 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4389 printTypeChain(tree->opval.lnk,outfile);
4390 fprintf(outfile,")\n");
4395 /* depending on type of operator do */
4397 switch (tree->opval.op) {
4398 /*------------------------------------------------------------------*/
4399 /*----------------------------*/
4401 /*----------------------------*/
4403 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4404 printTypeChain(tree->ftype,outfile);
4405 fprintf(outfile,")\n");
4406 ast_print(tree->left,outfile,indent+2);
4407 ast_print(tree->right,outfile,indent+2);
4410 /*------------------------------------------------------------------*/
4411 /*----------------------------*/
4413 /*----------------------------*/
4415 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4416 printTypeChain(tree->ftype,outfile);
4417 fprintf(outfile,")\n");
4418 ast_print(tree->left,outfile,indent+2);
4419 ast_print(tree->right,outfile,indent+2);
4422 /*------------------------------------------------------------------*/
4423 /*----------------------------*/
4424 /* struct/union pointer */
4425 /*----------------------------*/
4427 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4428 printTypeChain(tree->ftype,outfile);
4429 fprintf(outfile,")\n");
4430 ast_print(tree->left,outfile,indent+2);
4431 ast_print(tree->right,outfile,indent+2);
4434 /*------------------------------------------------------------------*/
4435 /*----------------------------*/
4436 /* ++/-- operation */
4437 /*----------------------------*/
4438 case INC_OP: /* incerement operator unary so left only */
4439 fprintf(outfile,"INC_OP (%p) type (",tree);
4440 printTypeChain(tree->ftype,outfile);
4441 fprintf(outfile,")\n");
4442 ast_print(tree->left,outfile,indent+2);
4446 fprintf(outfile,"DEC_OP (%p) type (",tree);
4447 printTypeChain(tree->ftype,outfile);
4448 fprintf(outfile,")\n");
4449 ast_print(tree->left,outfile,indent+2);
4452 /*------------------------------------------------------------------*/
4453 /*----------------------------*/
4455 /*----------------------------*/
4458 fprintf(outfile,"& (%p) type (",tree);
4459 printTypeChain(tree->ftype,outfile);
4460 fprintf(outfile,")\n");
4461 ast_print(tree->left,outfile,indent+2);
4462 ast_print(tree->right,outfile,indent+2);
4464 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4465 printTypeChain(tree->ftype,outfile);
4466 fprintf(outfile,")\n");
4467 ast_print(tree->left,outfile,indent+2);
4468 ast_print(tree->right,outfile,indent+2);
4471 /*----------------------------*/
4473 /*----------------------------*/
4475 fprintf(outfile,"OR (%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);
4481 /*------------------------------------------------------------------*/
4482 /*----------------------------*/
4484 /*----------------------------*/
4486 fprintf(outfile,"XOR (%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);
4493 /*------------------------------------------------------------------*/
4494 /*----------------------------*/
4496 /*----------------------------*/
4498 fprintf(outfile,"DIV (%p) type (",tree);
4499 printTypeChain(tree->ftype,outfile);
4500 fprintf(outfile,")\n");
4501 ast_print(tree->left,outfile,indent+2);
4502 ast_print(tree->right,outfile,indent+2);
4504 /*------------------------------------------------------------------*/
4505 /*----------------------------*/
4507 /*----------------------------*/
4509 fprintf(outfile,"MOD (%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);
4516 /*------------------------------------------------------------------*/
4517 /*----------------------------*/
4518 /* address dereference */
4519 /*----------------------------*/
4520 case '*': /* can be unary : if right is null then unary operation */
4522 fprintf(outfile,"DEREF (%p) type (",tree);
4523 printTypeChain(tree->ftype,outfile);
4524 fprintf(outfile,")\n");
4525 ast_print(tree->left,outfile,indent+2);
4528 /*------------------------------------------------------------------*/
4529 /*----------------------------*/
4530 /* multiplication */
4531 /*----------------------------*/
4532 fprintf(outfile,"MULT (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+2);
4536 ast_print(tree->right,outfile,indent+2);
4540 /*------------------------------------------------------------------*/
4541 /*----------------------------*/
4542 /* unary '+' operator */
4543 /*----------------------------*/
4547 fprintf(outfile,"UPLUS (%p) type (",tree);
4548 printTypeChain(tree->ftype,outfile);
4549 fprintf(outfile,")\n");
4550 ast_print(tree->left,outfile,indent+2);
4552 /*------------------------------------------------------------------*/
4553 /*----------------------------*/
4555 /*----------------------------*/
4556 fprintf(outfile,"ADD (%p) type (",tree);
4557 printTypeChain(tree->ftype,outfile);
4558 fprintf(outfile,")\n");
4559 ast_print(tree->left,outfile,indent+2);
4560 ast_print(tree->right,outfile,indent+2);
4563 /*------------------------------------------------------------------*/
4564 /*----------------------------*/
4566 /*----------------------------*/
4567 case '-': /* can be unary */
4569 fprintf(outfile,"UMINUS (%p) type (",tree);
4570 printTypeChain(tree->ftype,outfile);
4571 fprintf(outfile,")\n");
4572 ast_print(tree->left,outfile,indent+2);
4574 /*------------------------------------------------------------------*/
4575 /*----------------------------*/
4577 /*----------------------------*/
4578 fprintf(outfile,"SUB (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+2);
4582 ast_print(tree->right,outfile,indent+2);
4585 /*------------------------------------------------------------------*/
4586 /*----------------------------*/
4588 /*----------------------------*/
4590 fprintf(outfile,"COMPL (%p) type (",tree);
4591 printTypeChain(tree->ftype,outfile);
4592 fprintf(outfile,")\n");
4593 ast_print(tree->left,outfile,indent+2);
4595 /*------------------------------------------------------------------*/
4596 /*----------------------------*/
4598 /*----------------------------*/
4600 fprintf(outfile,"NOT (%p) type (",tree);
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->left,outfile,indent+2);
4605 /*------------------------------------------------------------------*/
4606 /*----------------------------*/
4608 /*----------------------------*/
4610 fprintf(outfile,"RRC (%p) type (",tree);
4611 printTypeChain(tree->ftype,outfile);
4612 fprintf(outfile,")\n");
4613 ast_print(tree->left,outfile,indent+2);
4617 fprintf(outfile,"RLC (%p) type (",tree);
4618 printTypeChain(tree->ftype,outfile);
4619 fprintf(outfile,")\n");
4620 ast_print(tree->left,outfile,indent+2);
4623 fprintf(outfile,"GETHBIT (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+2);
4629 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4630 printTypeChain(tree->ftype,outfile);
4631 fprintf(outfile,")\n");
4632 ast_print(tree->left,outfile,indent+2);
4633 ast_print(tree->right,outfile,indent+2);
4636 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4637 printTypeChain(tree->ftype,outfile);
4638 fprintf(outfile,")\n");
4639 ast_print(tree->left,outfile,indent+2);
4640 ast_print(tree->right,outfile,indent+2);
4642 /*------------------------------------------------------------------*/
4643 /*----------------------------*/
4645 /*----------------------------*/
4646 case CAST: /* change the type */
4647 fprintf(outfile,"CAST (%p) from type (",tree);
4648 printTypeChain(tree->right->ftype,outfile);
4649 fprintf(outfile,") to type (");
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->right,outfile,indent+2);
4656 fprintf(outfile,"ANDAND (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->left,outfile,indent+2);
4660 ast_print(tree->right,outfile,indent+2);
4663 fprintf(outfile,"OROR (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+2);
4667 ast_print(tree->right,outfile,indent+2);
4670 /*------------------------------------------------------------------*/
4671 /*----------------------------*/
4672 /* comparison operators */
4673 /*----------------------------*/
4675 fprintf(outfile,"GT(>) (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+2);
4679 ast_print(tree->right,outfile,indent+2);
4682 fprintf(outfile,"LT(<) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+2);
4686 ast_print(tree->right,outfile,indent+2);
4689 fprintf(outfile,"LE(<=) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+2);
4693 ast_print(tree->right,outfile,indent+2);
4696 fprintf(outfile,"GE(>=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+2);
4700 ast_print(tree->right,outfile,indent+2);
4703 fprintf(outfile,"EQ(==) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+2);
4707 ast_print(tree->right,outfile,indent+2);
4710 fprintf(outfile,"NE(!=) (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+2);
4714 ast_print(tree->right,outfile,indent+2);
4715 /*------------------------------------------------------------------*/
4716 /*----------------------------*/
4718 /*----------------------------*/
4719 case SIZEOF: /* evaluate wihout code generation */
4720 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4723 /*------------------------------------------------------------------*/
4724 /*----------------------------*/
4725 /* conditional operator '?' */
4726 /*----------------------------*/
4728 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+2);
4732 ast_print(tree->right,outfile,indent+2);
4736 fprintf(outfile,"COLON(:) (%p) type (",tree);
4737 printTypeChain(tree->ftype,outfile);
4738 fprintf(outfile,")\n");
4739 ast_print(tree->left,outfile,indent+2);
4740 ast_print(tree->right,outfile,indent+2);
4743 /*------------------------------------------------------------------*/
4744 /*----------------------------*/
4745 /* assignment operators */
4746 /*----------------------------*/
4748 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4749 printTypeChain(tree->ftype,outfile);
4750 fprintf(outfile,")\n");
4751 ast_print(tree->left,outfile,indent+2);
4752 ast_print(tree->right,outfile,indent+2);
4755 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4756 printTypeChain(tree->ftype,outfile);
4757 fprintf(outfile,")\n");
4758 ast_print(tree->left,outfile,indent+2);
4759 ast_print(tree->right,outfile,indent+2);
4762 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+2);
4766 ast_print(tree->right,outfile,indent+2);
4769 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+2);
4773 ast_print(tree->right,outfile,indent+2);
4776 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+2);
4780 ast_print(tree->right,outfile,indent+2);
4783 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4784 printTypeChain(tree->ftype,outfile);
4785 fprintf(outfile,")\n");
4786 ast_print(tree->left,outfile,indent+2);
4787 ast_print(tree->right,outfile,indent+2);
4790 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4791 printTypeChain(tree->ftype,outfile);
4792 fprintf(outfile,")\n");
4793 ast_print(tree->left,outfile,indent+2);
4794 ast_print(tree->right,outfile,indent+2);
4796 /*------------------------------------------------------------------*/
4797 /*----------------------------*/
4799 /*----------------------------*/
4801 fprintf(outfile,"SUBASS(-=) (%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,"ADDASS(+=) (%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 /*----------------------------*/
4820 /* straight assignemnt */
4821 /*----------------------------*/
4823 fprintf(outfile,"ASSIGN(=) (%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 /* comma operator */
4832 /*----------------------------*/
4834 fprintf(outfile,"COMMA(,) (%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 /*----------------------------*/
4843 /*----------------------------*/
4846 fprintf(outfile,"CALL (%p) type (",tree);
4847 printTypeChain(tree->ftype,outfile);
4848 fprintf(outfile,")\n");
4849 ast_print(tree->left,outfile,indent+2);
4850 ast_print(tree->right,outfile,indent+2);
4853 fprintf(outfile,"PARMS\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4856 ast_print(tree->right,outfile,indent+2);
4859 /*------------------------------------------------------------------*/
4860 /*----------------------------*/
4861 /* return statement */
4862 /*----------------------------*/
4864 fprintf(outfile,"RETURN (%p) type (",tree);
4865 printTypeChain(tree->right->ftype,outfile);
4866 fprintf(outfile,")\n");
4867 ast_print(tree->right,outfile,indent+2);
4869 /*------------------------------------------------------------------*/
4870 /*----------------------------*/
4871 /* label statement */
4872 /*----------------------------*/
4874 fprintf(outfile,"LABEL (%p)\n",tree);
4875 ast_print(tree->left,outfile,indent+2);
4876 ast_print(tree->right,outfile,indent);
4878 /*------------------------------------------------------------------*/
4879 /*----------------------------*/
4880 /* switch statement */
4881 /*----------------------------*/
4885 fprintf(outfile,"SWITCH (%p) ",tree);
4886 ast_print(tree->left,outfile,0);
4887 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4888 INDENT(indent+2,outfile);
4889 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4890 (int) floatFromVal(val),
4891 tree->values.switchVals.swNum,
4892 (int) floatFromVal(val));
4894 ast_print(tree->right,outfile,indent);
4897 /*------------------------------------------------------------------*/
4898 /*----------------------------*/
4900 /*----------------------------*/
4902 fprintf(outfile,"IF (%p) \n",tree);
4903 ast_print(tree->left,outfile,indent+2);
4904 if (tree->trueLabel) {
4905 INDENT(indent,outfile);
4906 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4908 if (tree->falseLabel) {
4909 INDENT(indent,outfile);
4910 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4912 ast_print(tree->right,outfile,indent+2);
4914 /*------------------------------------------------------------------*/
4915 /*----------------------------*/
4917 /*----------------------------*/
4919 fprintf(outfile,"FOR (%p) \n",tree);
4920 if (AST_FOR( tree, initExpr)) {
4921 INDENT(indent+2,outfile);
4922 fprintf(outfile,"INIT EXPR ");
4923 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4925 if (AST_FOR( tree, condExpr)) {
4926 INDENT(indent+2,outfile);
4927 fprintf(outfile,"COND EXPR ");
4928 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4930 if (AST_FOR( tree, loopExpr)) {
4931 INDENT(indent+2,outfile);
4932 fprintf(outfile,"LOOP EXPR ");
4933 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4935 fprintf(outfile,"FOR LOOP BODY \n");
4936 ast_print(tree->left,outfile,indent+2);
4945 ast_print(t,stdout,0);