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 /* constExprTree - returns TRUE if this tree is a constant */
1152 /*-------------------------------------------------------------*/
1153 bool constExprTree (ast *cexpr) {
1159 cexpr = decorateType (resolveSymbols (cexpr));
1161 switch (cexpr->type)
1164 return (IS_AST_LIT_VALUE(cexpr));
1166 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1167 "unexpected link in expression tree\n");
1170 if (cexpr->opval.op==CAST) {
1171 // jwk: cast ignored, maybe we should throw a warning here
1172 return constExprTree(cexpr->right);
1174 if (cexpr->opval.op=='&') {
1177 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1180 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1187 /*-----------------------------------------------------------------*/
1188 /* constExprValue - returns the value of a constant expression */
1189 /* or NULL if it is not a constant expression */
1190 /*-----------------------------------------------------------------*/
1192 constExprValue (ast * cexpr, int check)
1194 cexpr = decorateType (resolveSymbols (cexpr));
1196 /* if this is not a constant then */
1197 if (!IS_LITERAL (cexpr->ftype))
1199 /* then check if this is a literal array
1201 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1202 SPEC_CVAL (cexpr->etype).v_char &&
1203 IS_ARRAY (cexpr->ftype))
1205 value *val = valFromType (cexpr->ftype);
1206 SPEC_SCLS (val->etype) = S_LITERAL;
1207 val->sym = cexpr->opval.val->sym;
1208 val->sym->type = copyLinkChain (cexpr->ftype);
1209 val->sym->etype = getSpec (val->sym->type);
1210 strcpy (val->name, cexpr->opval.val->sym->rname);
1214 /* if we are casting a literal value then */
1215 if (IS_AST_OP (cexpr) &&
1216 cexpr->opval.op == CAST &&
1217 IS_LITERAL (cexpr->left->ftype))
1218 return valCastLiteral (cexpr->ftype,
1219 floatFromVal (cexpr->left->opval.val));
1221 if (IS_AST_VALUE (cexpr))
1222 return cexpr->opval.val;
1225 werror (E_CONST_EXPECTED, "found expression");
1230 /* return the value */
1231 return cexpr->opval.val;
1235 /*-----------------------------------------------------------------*/
1236 /* isLabelInAst - will return true if a given label is found */
1237 /*-----------------------------------------------------------------*/
1239 isLabelInAst (symbol * label, ast * tree)
1241 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1244 if (IS_AST_OP (tree) &&
1245 tree->opval.op == LABEL &&
1246 isSymbolEqual (AST_SYMBOL (tree->left), label))
1249 return isLabelInAst (label, tree->right) &&
1250 isLabelInAst (label, tree->left);
1254 /*-----------------------------------------------------------------*/
1255 /* isLoopCountable - return true if the loop count can be determi- */
1256 /* -ned at compile time . */
1257 /*-----------------------------------------------------------------*/
1259 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1260 symbol ** sym, ast ** init, ast ** end)
1263 /* the loop is considered countable if the following
1264 conditions are true :-
1266 a) initExpr :- <sym> = <const>
1267 b) condExpr :- <sym> < <const1>
1268 c) loopExpr :- <sym> ++
1271 /* first check the initExpr */
1272 if (IS_AST_OP (initExpr) &&
1273 initExpr->opval.op == '=' && /* is assignment */
1274 IS_AST_SYM_VALUE (initExpr->left))
1275 { /* left is a symbol */
1277 *sym = AST_SYMBOL (initExpr->left);
1278 *init = initExpr->right;
1283 /* for now the symbol has to be of
1285 if (!IS_INTEGRAL ((*sym)->type))
1288 /* now check condExpr */
1289 if (IS_AST_OP (condExpr))
1292 switch (condExpr->opval.op)
1295 if (IS_AST_SYM_VALUE (condExpr->left) &&
1296 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1297 IS_AST_LIT_VALUE (condExpr->right))
1299 *end = condExpr->right;
1305 if (IS_AST_OP (condExpr->left) &&
1306 condExpr->left->opval.op == '>' &&
1307 IS_AST_LIT_VALUE (condExpr->left->right) &&
1308 IS_AST_SYM_VALUE (condExpr->left->left) &&
1309 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1312 *end = newNode ('+', condExpr->left->right,
1313 newAst_VALUE (constVal ("1")));
1324 /* check loop expression is of the form <sym>++ */
1325 if (!IS_AST_OP (loopExpr))
1328 /* check if <sym> ++ */
1329 if (loopExpr->opval.op == INC_OP)
1335 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1336 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1343 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1344 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1352 if (loopExpr->opval.op == ADD_ASSIGN)
1355 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1356 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1357 IS_AST_LIT_VALUE (loopExpr->right) &&
1358 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1366 /*-----------------------------------------------------------------*/
1367 /* astHasVolatile - returns true if ast contains any volatile */
1368 /*-----------------------------------------------------------------*/
1370 astHasVolatile (ast * tree)
1375 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1378 if (IS_AST_OP (tree))
1379 return astHasVolatile (tree->left) ||
1380 astHasVolatile (tree->right);
1385 /*-----------------------------------------------------------------*/
1386 /* astHasPointer - return true if the ast contains any ptr variable */
1387 /*-----------------------------------------------------------------*/
1389 astHasPointer (ast * tree)
1394 if (IS_AST_LINK (tree))
1397 /* if we hit an array expression then check
1398 only the left side */
1399 if (IS_AST_OP (tree) && tree->opval.op == '[')
1400 return astHasPointer (tree->left);
1402 if (IS_AST_VALUE (tree))
1403 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1405 return astHasPointer (tree->left) ||
1406 astHasPointer (tree->right);
1410 /*-----------------------------------------------------------------*/
1411 /* astHasSymbol - return true if the ast has the given symbol */
1412 /*-----------------------------------------------------------------*/
1414 astHasSymbol (ast * tree, symbol * sym)
1416 if (!tree || IS_AST_LINK (tree))
1419 if (IS_AST_VALUE (tree))
1421 if (IS_AST_SYM_VALUE (tree))
1422 return isSymbolEqual (AST_SYMBOL (tree), sym);
1427 return astHasSymbol (tree->left, sym) ||
1428 astHasSymbol (tree->right, sym);
1431 /*-----------------------------------------------------------------*/
1432 /* astHasDeref - return true if the ast has an indirect access */
1433 /*-----------------------------------------------------------------*/
1435 astHasDeref (ast * tree)
1437 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1440 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1442 return astHasDeref (tree->left) || astHasDeref (tree->right);
1445 /*-----------------------------------------------------------------*/
1446 /* isConformingBody - the loop body has to conform to a set of rules */
1447 /* for the loop to be considered reversible read on for rules */
1448 /*-----------------------------------------------------------------*/
1450 isConformingBody (ast * pbody, symbol * sym, ast * body)
1453 /* we are going to do a pre-order traversal of the
1454 tree && check for the following conditions. (essentially
1455 a set of very shallow tests )
1456 a) the sym passed does not participate in
1457 any arithmetic operation
1458 b) There are no function calls
1459 c) all jumps are within the body
1460 d) address of loop control variable not taken
1461 e) if an assignment has a pointer on the
1462 left hand side make sure right does not have
1463 loop control variable */
1465 /* if we reach the end or a leaf then true */
1466 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1470 /* if anything else is "volatile" */
1471 if (IS_VOLATILE (TETYPE (pbody)))
1474 /* we will walk the body in a pre-order traversal for
1476 switch (pbody->opval.op)
1478 /*------------------------------------------------------------------*/
1480 return isConformingBody (pbody->right, sym, body);
1482 /*------------------------------------------------------------------*/
1487 /*------------------------------------------------------------------*/
1488 case INC_OP: /* incerement operator unary so left only */
1491 /* sure we are not sym is not modified */
1493 IS_AST_SYM_VALUE (pbody->left) &&
1494 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1498 IS_AST_SYM_VALUE (pbody->right) &&
1499 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1504 /*------------------------------------------------------------------*/
1506 case '*': /* can be unary : if right is null then unary operation */
1511 /* if right is NULL then unary operation */
1512 /*------------------------------------------------------------------*/
1513 /*----------------------------*/
1515 /*----------------------------*/
1518 if (IS_AST_SYM_VALUE (pbody->left) &&
1519 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1522 return isConformingBody (pbody->left, sym, body);
1526 if (astHasSymbol (pbody->left, sym) ||
1527 astHasSymbol (pbody->right, sym))
1532 /*------------------------------------------------------------------*/
1540 if (IS_AST_SYM_VALUE (pbody->left) &&
1541 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1544 if (IS_AST_SYM_VALUE (pbody->right) &&
1545 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1548 return isConformingBody (pbody->left, sym, body) &&
1549 isConformingBody (pbody->right, sym, body);
1556 if (IS_AST_SYM_VALUE (pbody->left) &&
1557 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1559 return isConformingBody (pbody->left, sym, body);
1561 /*------------------------------------------------------------------*/
1573 case SIZEOF: /* evaluate wihout code generation */
1575 return isConformingBody (pbody->left, sym, body) &&
1576 isConformingBody (pbody->right, sym, body);
1578 /*------------------------------------------------------------------*/
1581 /* if left has a pointer & right has loop
1582 control variable then we cannot */
1583 if (astHasPointer (pbody->left) &&
1584 astHasSymbol (pbody->right, sym))
1586 if (astHasVolatile (pbody->left))
1589 if (IS_AST_SYM_VALUE (pbody->left) &&
1590 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1593 if (astHasVolatile (pbody->left))
1596 if (astHasDeref(pbody->right)) return FALSE;
1598 return isConformingBody (pbody->left, sym, body) &&
1599 isConformingBody (pbody->right, sym, body);
1610 assert ("Parser should not have generated this\n");
1612 /*------------------------------------------------------------------*/
1613 /*----------------------------*/
1614 /* comma operator */
1615 /*----------------------------*/
1617 return isConformingBody (pbody->left, sym, body) &&
1618 isConformingBody (pbody->right, sym, body);
1620 /*------------------------------------------------------------------*/
1621 /*----------------------------*/
1623 /*----------------------------*/
1627 /*------------------------------------------------------------------*/
1628 /*----------------------------*/
1629 /* return statement */
1630 /*----------------------------*/
1635 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1640 if (astHasSymbol (pbody->left, sym))
1647 return isConformingBody (pbody->left, sym, body) &&
1648 isConformingBody (pbody->right, sym, body);
1654 /*-----------------------------------------------------------------*/
1655 /* isLoopReversible - takes a for loop as input && returns true */
1656 /* if the for loop is reversible. If yes will set the value of */
1657 /* the loop control var & init value & termination value */
1658 /*-----------------------------------------------------------------*/
1660 isLoopReversible (ast * loop, symbol ** loopCntrl,
1661 ast ** init, ast ** end)
1663 /* if option says don't do it then don't */
1664 if (optimize.noLoopReverse)
1666 /* there are several tests to determine this */
1668 /* for loop has to be of the form
1669 for ( <sym> = <const1> ;
1670 [<sym> < <const2>] ;
1671 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1673 if (!isLoopCountable (AST_FOR (loop, initExpr),
1674 AST_FOR (loop, condExpr),
1675 AST_FOR (loop, loopExpr),
1676 loopCntrl, init, end))
1679 /* now do some serious checking on the body of the loop
1682 return isConformingBody (loop->left, *loopCntrl, loop->left);
1686 /*-----------------------------------------------------------------*/
1687 /* replLoopSym - replace the loop sym by loop sym -1 */
1688 /*-----------------------------------------------------------------*/
1690 replLoopSym (ast * body, symbol * sym)
1693 if (!body || IS_AST_LINK (body))
1696 if (IS_AST_SYM_VALUE (body))
1699 if (isSymbolEqual (AST_SYMBOL (body), sym))
1703 body->opval.op = '-';
1704 body->left = newAst_VALUE (symbolVal (sym));
1705 body->right = newAst_VALUE (constVal ("1"));
1713 replLoopSym (body->left, sym);
1714 replLoopSym (body->right, sym);
1718 /*-----------------------------------------------------------------*/
1719 /* reverseLoop - do the actual loop reversal */
1720 /*-----------------------------------------------------------------*/
1722 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1726 /* create the following tree
1731 if (sym) goto for_continue ;
1734 /* put it together piece by piece */
1735 rloop = newNode (NULLOP,
1736 createIf (newAst_VALUE (symbolVal (sym)),
1738 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1741 newAst_VALUE (symbolVal (sym)),
1744 replLoopSym (loop->left, sym);
1746 rloop = newNode (NULLOP,
1748 newAst_VALUE (symbolVal (sym)),
1749 newNode ('-', end, init)),
1750 createLabel (AST_FOR (loop, continueLabel),
1754 newNode (SUB_ASSIGN,
1755 newAst_VALUE (symbolVal (sym)),
1756 newAst_VALUE (constVal ("1"))),
1759 return decorateType (rloop);
1763 /*-----------------------------------------------------------------*/
1764 /* decorateType - compute type for this tree also does type cheking */
1765 /* this is done bottom up, since type have to flow upwards */
1766 /* it also does constant folding, and paramater checking */
1767 /*-----------------------------------------------------------------*/
1769 decorateType (ast * tree)
1777 /* if already has type then do nothing */
1778 if (tree->decorated)
1781 tree->decorated = 1;
1783 /* print the line */
1784 /* if not block & function */
1785 if (tree->type == EX_OP &&
1786 (tree->opval.op != FUNCTION &&
1787 tree->opval.op != BLOCK &&
1788 tree->opval.op != NULLOP))
1790 filename = tree->filename;
1791 lineno = tree->lineno;
1794 /* if any child is an error | this one is an error do nothing */
1795 if (tree->isError ||
1796 (tree->left && tree->left->isError) ||
1797 (tree->right && tree->right->isError))
1800 /*------------------------------------------------------------------*/
1801 /*----------------------------*/
1802 /* leaf has been reached */
1803 /*----------------------------*/
1804 /* if this is of type value */
1805 /* just get the type */
1806 if (tree->type == EX_VALUE)
1809 if (IS_LITERAL (tree->opval.val->etype))
1812 /* if this is a character array then declare it */
1813 if (IS_ARRAY (tree->opval.val->type))
1814 tree->opval.val = stringToSymbol (tree->opval.val);
1816 /* otherwise just copy the type information */
1817 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1821 if (tree->opval.val->sym)
1823 /* if the undefined flag is set then give error message */
1824 if (tree->opval.val->sym->undefined)
1826 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1828 TTYPE (tree) = TETYPE (tree) =
1829 tree->opval.val->type = tree->opval.val->sym->type =
1830 tree->opval.val->etype = tree->opval.val->sym->etype =
1831 copyLinkChain (INTTYPE);
1836 /* if impilicit i.e. struct/union member then no type */
1837 if (tree->opval.val->sym->implicit)
1838 TTYPE (tree) = TETYPE (tree) = NULL;
1843 /* else copy the type */
1844 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1846 /* and mark it as referenced */
1847 tree->opval.val->sym->isref = 1;
1855 /* if type link for the case of cast */
1856 if (tree->type == EX_LINK)
1858 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1865 dtl = decorateType (tree->left);
1866 /* delay right side for '?' operator since conditional macro expansions might
1868 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1870 /* this is to take care of situations
1871 when the tree gets rewritten */
1872 if (dtl != tree->left)
1874 if (dtr != tree->right)
1878 /* depending on type of operator do */
1880 switch (tree->opval.op)
1882 /*------------------------------------------------------------------*/
1883 /*----------------------------*/
1885 /*----------------------------*/
1888 /* determine which is the array & which the index */
1889 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1892 ast *tempTree = tree->left;
1893 tree->left = tree->right;
1894 tree->right = tempTree;
1897 /* first check if this is a array or a pointer */
1898 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1900 werror (E_NEED_ARRAY_PTR, "[]");
1901 goto errorTreeReturn;
1904 /* check if the type of the idx */
1905 if (!IS_INTEGRAL (RTYPE (tree)))
1907 werror (E_IDX_NOT_INT);
1908 goto errorTreeReturn;
1911 /* if the left is an rvalue then error */
1914 werror (E_LVALUE_REQUIRED, "array access");
1915 goto errorTreeReturn;
1918 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1919 if (IS_PTR(LTYPE(tree))) {
1920 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1924 /*------------------------------------------------------------------*/
1925 /*----------------------------*/
1927 /*----------------------------*/
1929 /* if this is not a structure */
1930 if (!IS_STRUCT (LTYPE (tree)))
1932 werror (E_STRUCT_UNION, ".");
1933 goto errorTreeReturn;
1935 TTYPE (tree) = structElemType (LTYPE (tree),
1936 (tree->right->type == EX_VALUE ?
1937 tree->right->opval.val : NULL));
1938 TETYPE (tree) = getSpec (TTYPE (tree));
1941 /*------------------------------------------------------------------*/
1942 /*----------------------------*/
1943 /* struct/union pointer */
1944 /*----------------------------*/
1946 /* if not pointer to a structure */
1947 if (!IS_PTR (LTYPE (tree)))
1949 werror (E_PTR_REQD);
1950 goto errorTreeReturn;
1953 if (!IS_STRUCT (LTYPE (tree)->next))
1955 werror (E_STRUCT_UNION, "->");
1956 goto errorTreeReturn;
1959 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1960 (tree->right->type == EX_VALUE ?
1961 tree->right->opval.val : NULL));
1962 TETYPE (tree) = getSpec (TTYPE (tree));
1964 /* adjust the storage class */
1965 switch (DCL_TYPE(tree->left->ftype)) {
1969 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
1972 SPEC_SCLS(TETYPE(tree)) = S_CODE;
1977 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
1980 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
1983 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
1992 /*------------------------------------------------------------------*/
1993 /*----------------------------*/
1994 /* ++/-- operation */
1995 /*----------------------------*/
1996 case INC_OP: /* incerement operator unary so left only */
1999 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2000 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2001 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2002 werror (E_CODE_WRITE, "++/--");
2011 /*------------------------------------------------------------------*/
2012 /*----------------------------*/
2014 /*----------------------------*/
2015 case '&': /* can be unary */
2016 /* if right is NULL then unary operation */
2017 if (tree->right) /* not an unary operation */
2020 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2022 werror (E_BITWISE_OP);
2023 werror (W_CONTINUE, "left & right types are ");
2024 printTypeChain (LTYPE (tree), stderr);
2025 fprintf (stderr, ",");
2026 printTypeChain (RTYPE (tree), stderr);
2027 fprintf (stderr, "\n");
2028 goto errorTreeReturn;
2031 /* if they are both literal */
2032 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2034 tree->type = EX_VALUE;
2035 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2036 valFromType (RETYPE (tree)), '&');
2038 tree->right = tree->left = NULL;
2039 TETYPE (tree) = tree->opval.val->etype;
2040 TTYPE (tree) = tree->opval.val->type;
2044 /* see if this is a GETHBIT operation if yes
2047 ast *otree = optimizeGetHbit (tree);
2050 return decorateType (otree);
2054 computeType (LTYPE (tree), RTYPE (tree));
2055 TETYPE (tree) = getSpec (TTYPE (tree));
2057 LRVAL (tree) = RRVAL (tree) = 1;
2061 /*------------------------------------------------------------------*/
2062 /*----------------------------*/
2064 /*----------------------------*/
2066 p->class = DECLARATOR;
2067 /* if bit field then error */
2068 if (IS_BITVAR (tree->left->etype))
2070 werror (E_ILLEGAL_ADDR, "address of bit variable");
2071 goto errorTreeReturn;
2074 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2076 werror (E_ILLEGAL_ADDR, "address of register variable");
2077 goto errorTreeReturn;
2080 if (IS_FUNC (LTYPE (tree)))
2082 werror (E_ILLEGAL_ADDR, "address of function");
2083 goto errorTreeReturn;
2086 if (IS_LITERAL(LTYPE(tree)))
2088 werror (E_ILLEGAL_ADDR, "address of literal");
2089 goto errorTreeReturn;
2094 werror (E_LVALUE_REQUIRED, "address of");
2095 goto errorTreeReturn;
2097 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2099 DCL_TYPE (p) = CPOINTER;
2100 DCL_PTR_CONST (p) = port->mem.code_ro;
2102 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2103 DCL_TYPE (p) = FPOINTER;
2104 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2105 DCL_TYPE (p) = PPOINTER;
2106 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2107 DCL_TYPE (p) = IPOINTER;
2108 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2109 DCL_TYPE (p) = EEPPOINTER;
2110 else if (SPEC_OCLS(tree->left->etype))
2111 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2113 DCL_TYPE (p) = POINTER;
2115 if (IS_AST_SYM_VALUE (tree->left))
2117 AST_SYMBOL (tree->left)->addrtaken = 1;
2118 AST_SYMBOL (tree->left)->allocreq = 1;
2121 p->next = LTYPE (tree);
2123 TETYPE (tree) = getSpec (TTYPE (tree));
2124 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2125 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2130 /*------------------------------------------------------------------*/
2131 /*----------------------------*/
2133 /*----------------------------*/
2135 /* if the rewrite succeeds then don't go any furthur */
2137 ast *wtree = optimizeRRCRLC (tree);
2139 return decorateType (wtree);
2141 /*------------------------------------------------------------------*/
2142 /*----------------------------*/
2144 /*----------------------------*/
2146 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2148 werror (E_BITWISE_OP);
2149 werror (W_CONTINUE, "left & right types are ");
2150 printTypeChain (LTYPE (tree), stderr);
2151 fprintf (stderr, ",");
2152 printTypeChain (RTYPE (tree), stderr);
2153 fprintf (stderr, "\n");
2154 goto errorTreeReturn;
2157 /* if they are both literal then */
2158 /* rewrite the tree */
2159 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2161 tree->type = EX_VALUE;
2162 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2163 valFromType (RETYPE (tree)),
2165 tree->right = tree->left = NULL;
2166 TETYPE (tree) = tree->opval.val->etype;
2167 TTYPE (tree) = tree->opval.val->type;
2170 LRVAL (tree) = RRVAL (tree) = 1;
2171 TETYPE (tree) = getSpec (TTYPE (tree) =
2172 computeType (LTYPE (tree),
2175 /*------------------------------------------------------------------*/
2176 /*----------------------------*/
2178 /*----------------------------*/
2180 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2182 werror (E_INVALID_OP, "divide");
2183 goto errorTreeReturn;
2185 /* if they are both literal then */
2186 /* rewrite the tree */
2187 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2189 tree->type = EX_VALUE;
2190 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2191 valFromType (RETYPE (tree)));
2192 tree->right = tree->left = NULL;
2193 TETYPE (tree) = getSpec (TTYPE (tree) =
2194 tree->opval.val->type);
2197 LRVAL (tree) = RRVAL (tree) = 1;
2198 TETYPE (tree) = getSpec (TTYPE (tree) =
2199 computeType (LTYPE (tree),
2203 /*------------------------------------------------------------------*/
2204 /*----------------------------*/
2206 /*----------------------------*/
2208 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2210 werror (E_BITWISE_OP);
2211 werror (W_CONTINUE, "left & right types are ");
2212 printTypeChain (LTYPE (tree), stderr);
2213 fprintf (stderr, ",");
2214 printTypeChain (RTYPE (tree), stderr);
2215 fprintf (stderr, "\n");
2216 goto errorTreeReturn;
2218 /* if they are both literal then */
2219 /* rewrite the tree */
2220 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2222 tree->type = EX_VALUE;
2223 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2224 valFromType (RETYPE (tree)));
2225 tree->right = tree->left = NULL;
2226 TETYPE (tree) = getSpec (TTYPE (tree) =
2227 tree->opval.val->type);
2230 LRVAL (tree) = RRVAL (tree) = 1;
2231 TETYPE (tree) = getSpec (TTYPE (tree) =
2232 computeType (LTYPE (tree),
2236 /*------------------------------------------------------------------*/
2237 /*----------------------------*/
2238 /* address dereference */
2239 /*----------------------------*/
2240 case '*': /* can be unary : if right is null then unary operation */
2243 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2245 werror (E_PTR_REQD);
2246 goto errorTreeReturn;
2251 werror (E_LVALUE_REQUIRED, "pointer deref");
2252 goto errorTreeReturn;
2254 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2255 LTYPE (tree)->next : NULL);
2256 TETYPE (tree) = getSpec (TTYPE (tree));
2257 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2261 /*------------------------------------------------------------------*/
2262 /*----------------------------*/
2263 /* multiplication */
2264 /*----------------------------*/
2265 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2267 werror (E_INVALID_OP, "multiplication");
2268 goto errorTreeReturn;
2271 /* if they are both literal then */
2272 /* rewrite the tree */
2273 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2275 tree->type = EX_VALUE;
2276 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2277 valFromType (RETYPE (tree)));
2278 tree->right = tree->left = NULL;
2279 TETYPE (tree) = getSpec (TTYPE (tree) =
2280 tree->opval.val->type);
2284 /* if left is a literal exchange left & right */
2285 if (IS_LITERAL (LTYPE (tree)))
2287 ast *tTree = tree->left;
2288 tree->left = tree->right;
2289 tree->right = tTree;
2292 LRVAL (tree) = RRVAL (tree) = 1;
2293 /* promote result to int if left & right are char
2294 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2295 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2296 TETYPE (tree) = getSpec (TTYPE (tree) =
2297 computeType (LTYPE (tree),
2299 SPEC_NOUN(TETYPE(tree)) = V_INT;
2301 TETYPE (tree) = getSpec (TTYPE (tree) =
2302 computeType (LTYPE (tree),
2307 /*------------------------------------------------------------------*/
2308 /*----------------------------*/
2309 /* unary '+' operator */
2310 /*----------------------------*/
2315 if (!IS_INTEGRAL (LTYPE (tree)))
2317 werror (E_UNARY_OP, '+');
2318 goto errorTreeReturn;
2321 /* if left is a literal then do it */
2322 if (IS_LITERAL (LTYPE (tree)))
2324 tree->type = EX_VALUE;
2325 tree->opval.val = valFromType (LETYPE (tree));
2327 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2331 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2335 /*------------------------------------------------------------------*/
2336 /*----------------------------*/
2338 /*----------------------------*/
2340 /* this is not a unary operation */
2341 /* if both pointers then problem */
2342 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2343 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2345 werror (E_PTR_PLUS_PTR);
2346 goto errorTreeReturn;
2349 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2350 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2352 werror (E_PLUS_INVALID, "+");
2353 goto errorTreeReturn;
2356 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2357 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2359 werror (E_PLUS_INVALID, "+");
2360 goto errorTreeReturn;
2362 /* if they are both literal then */
2363 /* rewrite the tree */
2364 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2366 tree->type = EX_VALUE;
2367 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2368 valFromType (RETYPE (tree)));
2369 tree->right = tree->left = NULL;
2370 TETYPE (tree) = getSpec (TTYPE (tree) =
2371 tree->opval.val->type);
2375 /* if the right is a pointer or left is a literal
2376 xchange left & right */
2377 if (IS_ARRAY (RTYPE (tree)) ||
2378 IS_PTR (RTYPE (tree)) ||
2379 IS_LITERAL (LTYPE (tree)))
2381 ast *tTree = tree->left;
2382 tree->left = tree->right;
2383 tree->right = tTree;
2386 LRVAL (tree) = RRVAL (tree) = 1;
2387 /* if the left is a pointer */
2388 if (IS_PTR (LTYPE (tree)))
2389 TETYPE (tree) = getSpec (TTYPE (tree) =
2392 TETYPE (tree) = getSpec (TTYPE (tree) =
2393 computeType (LTYPE (tree),
2397 /*------------------------------------------------------------------*/
2398 /*----------------------------*/
2400 /*----------------------------*/
2401 case '-': /* can be unary */
2402 /* if right is null then unary */
2406 if (!IS_ARITHMETIC (LTYPE (tree)))
2408 werror (E_UNARY_OP, tree->opval.op);
2409 goto errorTreeReturn;
2412 /* if left is a literal then do it */
2413 if (IS_LITERAL (LTYPE (tree)))
2415 tree->type = EX_VALUE;
2416 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2418 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2419 SPEC_USIGN(TETYPE(tree)) = 0;
2423 TTYPE (tree) = LTYPE (tree);
2427 /*------------------------------------------------------------------*/
2428 /*----------------------------*/
2430 /*----------------------------*/
2432 if (!(IS_PTR (LTYPE (tree)) ||
2433 IS_ARRAY (LTYPE (tree)) ||
2434 IS_ARITHMETIC (LTYPE (tree))))
2436 werror (E_PLUS_INVALID, "-");
2437 goto errorTreeReturn;
2440 if (!(IS_PTR (RTYPE (tree)) ||
2441 IS_ARRAY (RTYPE (tree)) ||
2442 IS_ARITHMETIC (RTYPE (tree))))
2444 werror (E_PLUS_INVALID, "-");
2445 goto errorTreeReturn;
2448 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2449 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2450 IS_INTEGRAL (RTYPE (tree))))
2452 werror (E_PLUS_INVALID, "-");
2453 goto errorTreeReturn;
2456 /* if they are both literal then */
2457 /* rewrite the tree */
2458 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2460 tree->type = EX_VALUE;
2461 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2462 valFromType (RETYPE (tree)));
2463 tree->right = tree->left = NULL;
2464 TETYPE (tree) = getSpec (TTYPE (tree) =
2465 tree->opval.val->type);
2469 /* if the left & right are equal then zero */
2470 if (isAstEqual (tree->left, tree->right))
2472 tree->type = EX_VALUE;
2473 tree->left = tree->right = NULL;
2474 tree->opval.val = constVal ("0");
2475 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2479 /* if both of them are pointers or arrays then */
2480 /* the result is going to be an integer */
2481 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2482 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2483 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2485 /* if only the left is a pointer */
2486 /* then result is a pointer */
2487 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2488 TETYPE (tree) = getSpec (TTYPE (tree) =
2491 TETYPE (tree) = getSpec (TTYPE (tree) =
2492 computeType (LTYPE (tree),
2494 LRVAL (tree) = RRVAL (tree) = 1;
2497 /*------------------------------------------------------------------*/
2498 /*----------------------------*/
2500 /*----------------------------*/
2502 /* can be only integral type */
2503 if (!IS_INTEGRAL (LTYPE (tree)))
2505 werror (E_UNARY_OP, tree->opval.op);
2506 goto errorTreeReturn;
2509 /* if left is a literal then do it */
2510 if (IS_LITERAL (LTYPE (tree)))
2512 tree->type = EX_VALUE;
2513 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2515 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2519 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2522 /*------------------------------------------------------------------*/
2523 /*----------------------------*/
2525 /*----------------------------*/
2527 /* can be pointer */
2528 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2529 !IS_PTR (LTYPE (tree)) &&
2530 !IS_ARRAY (LTYPE (tree)))
2532 werror (E_UNARY_OP, tree->opval.op);
2533 goto errorTreeReturn;
2536 /* if left is a literal then do it */
2537 if (IS_LITERAL (LTYPE (tree)))
2539 tree->type = EX_VALUE;
2540 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2542 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2546 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2549 /*------------------------------------------------------------------*/
2550 /*----------------------------*/
2552 /*----------------------------*/
2555 TTYPE (tree) = LTYPE (tree);
2556 TETYPE (tree) = LETYPE (tree);
2560 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2565 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2567 werror (E_SHIFT_OP_INVALID);
2568 werror (W_CONTINUE, "left & right types are ");
2569 printTypeChain (LTYPE (tree), stderr);
2570 fprintf (stderr, ",");
2571 printTypeChain (RTYPE (tree), stderr);
2572 fprintf (stderr, "\n");
2573 goto errorTreeReturn;
2576 /* if they are both literal then */
2577 /* rewrite the tree */
2578 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2580 tree->type = EX_VALUE;
2581 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2582 valFromType (RETYPE (tree)),
2583 (tree->opval.op == LEFT_OP ? 1 : 0));
2584 tree->right = tree->left = NULL;
2585 TETYPE (tree) = getSpec (TTYPE (tree) =
2586 tree->opval.val->type);
2589 /* if only the right side is a literal & we are
2590 shifting more than size of the left operand then zero */
2591 if (IS_LITERAL (RTYPE (tree)) &&
2592 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2593 (getSize (LTYPE (tree)) * 8))
2595 werror (W_SHIFT_CHANGED,
2596 (tree->opval.op == LEFT_OP ? "left" : "right"));
2597 tree->type = EX_VALUE;
2598 tree->left = tree->right = NULL;
2599 tree->opval.val = constVal ("0");
2600 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2603 LRVAL (tree) = RRVAL (tree) = 1;
2604 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2606 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2610 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2614 /*------------------------------------------------------------------*/
2615 /*----------------------------*/
2617 /*----------------------------*/
2618 case CAST: /* change the type */
2619 /* cannot cast to an aggregate type */
2620 if (IS_AGGREGATE (LTYPE (tree)))
2622 werror (E_CAST_ILLEGAL);
2623 goto errorTreeReturn;
2626 /* make sure the type is complete and sane */
2627 checkTypeSanity(LETYPE(tree), "(cast)");
2630 /* if the right is a literal replace the tree */
2631 if (IS_LITERAL (RETYPE (tree))) {
2632 if (!IS_PTR (LTYPE (tree))) {
2633 tree->type = EX_VALUE;
2635 valCastLiteral (LTYPE (tree),
2636 floatFromVal (valFromType (RETYPE (tree))));
2639 TTYPE (tree) = tree->opval.val->type;
2640 tree->values.literalFromCast = 1;
2641 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2642 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2643 sym_link *rest = LTYPE(tree)->next;
2644 werror(W_LITERAL_GENERIC);
2645 TTYPE(tree) = newLink();
2646 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2647 TTYPE(tree)->next = rest;
2648 tree->left->opval.lnk = TTYPE(tree);
2651 TTYPE (tree) = LTYPE (tree);
2655 TTYPE (tree) = LTYPE (tree);
2659 /* if pointer to struct then check names */
2660 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2661 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2662 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2663 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2665 /* if the right is a literal replace the tree */
2666 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2667 tree->type = EX_VALUE;
2669 valCastLiteral (LTYPE (tree),
2670 floatFromVal (valFromType (RETYPE (tree))));
2673 TTYPE (tree) = tree->opval.val->type;
2674 tree->values.literalFromCast = 1;
2676 TTYPE (tree) = LTYPE (tree);
2680 TETYPE (tree) = getSpec (TTYPE (tree));
2684 /*------------------------------------------------------------------*/
2685 /*----------------------------*/
2686 /* logical &&, || */
2687 /*----------------------------*/
2690 /* each must me arithmetic type or be a pointer */
2691 if (!IS_PTR (LTYPE (tree)) &&
2692 !IS_ARRAY (LTYPE (tree)) &&
2693 !IS_INTEGRAL (LTYPE (tree)))
2695 werror (E_COMPARE_OP);
2696 goto errorTreeReturn;
2699 if (!IS_PTR (RTYPE (tree)) &&
2700 !IS_ARRAY (RTYPE (tree)) &&
2701 !IS_INTEGRAL (RTYPE (tree)))
2703 werror (E_COMPARE_OP);
2704 goto errorTreeReturn;
2706 /* if they are both literal then */
2707 /* rewrite the tree */
2708 if (IS_LITERAL (RTYPE (tree)) &&
2709 IS_LITERAL (LTYPE (tree)))
2711 tree->type = EX_VALUE;
2712 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2713 valFromType (RETYPE (tree)),
2715 tree->right = tree->left = NULL;
2716 TETYPE (tree) = getSpec (TTYPE (tree) =
2717 tree->opval.val->type);
2720 LRVAL (tree) = RRVAL (tree) = 1;
2721 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2724 /*------------------------------------------------------------------*/
2725 /*----------------------------*/
2726 /* comparison operators */
2727 /*----------------------------*/
2735 ast *lt = optimizeCompare (tree);
2741 /* if they are pointers they must be castable */
2742 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2744 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2746 werror (E_COMPARE_OP);
2747 fprintf (stderr, "comparing type ");
2748 printTypeChain (LTYPE (tree), stderr);
2749 fprintf (stderr, "to type ");
2750 printTypeChain (RTYPE (tree), stderr);
2751 fprintf (stderr, "\n");
2752 goto errorTreeReturn;
2755 /* else they should be promotable to one another */
2758 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2759 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2761 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2763 werror (E_COMPARE_OP);
2764 fprintf (stderr, "comparing type ");
2765 printTypeChain (LTYPE (tree), stderr);
2766 fprintf (stderr, "to type ");
2767 printTypeChain (RTYPE (tree), stderr);
2768 fprintf (stderr, "\n");
2769 goto errorTreeReturn;
2772 /* if unsigned value < 0 then always false */
2773 /* if (unsigned value) > 0 then (unsigned value) */
2774 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2775 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2777 if (tree->opval.op == '<') {
2780 if (tree->opval.op == '>') {
2784 /* if they are both literal then */
2785 /* rewrite the tree */
2786 if (IS_LITERAL (RTYPE (tree)) &&
2787 IS_LITERAL (LTYPE (tree)))
2789 tree->type = EX_VALUE;
2790 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2791 valFromType (RETYPE (tree)),
2793 tree->right = tree->left = NULL;
2794 TETYPE (tree) = getSpec (TTYPE (tree) =
2795 tree->opval.val->type);
2798 LRVAL (tree) = RRVAL (tree) = 1;
2799 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2802 /*------------------------------------------------------------------*/
2803 /*----------------------------*/
2805 /*----------------------------*/
2806 case SIZEOF: /* evaluate wihout code generation */
2807 /* change the type to a integer */
2808 tree->type = EX_VALUE;
2809 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2810 tree->opval.val = constVal (buffer);
2811 tree->right = tree->left = NULL;
2812 TETYPE (tree) = getSpec (TTYPE (tree) =
2813 tree->opval.val->type);
2816 /*------------------------------------------------------------------*/
2817 /*----------------------------*/
2819 /*----------------------------*/
2821 /* return typeof enum value */
2822 tree->type = EX_VALUE;
2825 if (IS_SPEC(tree->right->ftype)) {
2826 switch (SPEC_NOUN(tree->right->ftype)) {
2828 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2829 else typeofv = TYPEOF_INT;
2832 typeofv = TYPEOF_FLOAT;
2835 typeofv = TYPEOF_CHAR;
2838 typeofv = TYPEOF_VOID;
2841 typeofv = TYPEOF_STRUCT;
2844 typeofv = TYPEOF_BIT;
2847 typeofv = TYPEOF_SBIT;
2853 switch (DCL_TYPE(tree->right->ftype)) {
2855 typeofv = TYPEOF_POINTER;
2858 typeofv = TYPEOF_FPOINTER;
2861 typeofv = TYPEOF_CPOINTER;
2864 typeofv = TYPEOF_GPOINTER;
2867 typeofv = TYPEOF_PPOINTER;
2870 typeofv = TYPEOF_IPOINTER;
2873 typeofv = TYPEOF_ARRAY;
2876 typeofv = TYPEOF_FUNCTION;
2882 sprintf (buffer, "%d", typeofv);
2883 tree->opval.val = constVal (buffer);
2884 tree->right = tree->left = NULL;
2885 TETYPE (tree) = getSpec (TTYPE (tree) =
2886 tree->opval.val->type);
2889 /*------------------------------------------------------------------*/
2890 /*----------------------------*/
2891 /* conditional operator '?' */
2892 /*----------------------------*/
2894 /* the type is value of the colon operator (on the right) */
2895 assert(IS_COLON_OP(tree->right));
2896 /* if already known then replace the tree : optimizer will do it
2897 but faster to do it here */
2898 if (IS_LITERAL (LTYPE(tree))) {
2899 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2900 return decorateType(tree->right->left) ;
2902 return decorateType(tree->right->right) ;
2905 tree->right = decorateType(tree->right);
2906 TTYPE (tree) = RTYPE(tree);
2907 TETYPE (tree) = getSpec (TTYPE (tree));
2912 /* if they don't match we have a problem */
2913 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2915 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2916 goto errorTreeReturn;
2919 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2920 TETYPE (tree) = getSpec (TTYPE (tree));
2924 /*------------------------------------------------------------------*/
2925 /*----------------------------*/
2926 /* assignment operators */
2927 /*----------------------------*/
2930 /* for these it must be both must be integral */
2931 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2932 !IS_ARITHMETIC (RTYPE (tree)))
2934 werror (E_OPS_INTEGRAL);
2935 goto errorTreeReturn;
2938 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2940 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2941 werror (E_CODE_WRITE, " ");
2945 werror (E_LVALUE_REQUIRED, "*= or /=");
2946 goto errorTreeReturn;
2957 /* for these it must be both must be integral */
2958 if (!IS_INTEGRAL (LTYPE (tree)) ||
2959 !IS_INTEGRAL (RTYPE (tree)))
2961 werror (E_OPS_INTEGRAL);
2962 goto errorTreeReturn;
2965 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2967 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2968 werror (E_CODE_WRITE, " ");
2972 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2973 goto errorTreeReturn;
2979 /*------------------------------------------------------------------*/
2980 /*----------------------------*/
2982 /*----------------------------*/
2984 if (!(IS_PTR (LTYPE (tree)) ||
2985 IS_ARITHMETIC (LTYPE (tree))))
2987 werror (E_PLUS_INVALID, "-=");
2988 goto errorTreeReturn;
2991 if (!(IS_PTR (RTYPE (tree)) ||
2992 IS_ARITHMETIC (RTYPE (tree))))
2994 werror (E_PLUS_INVALID, "-=");
2995 goto errorTreeReturn;
2998 TETYPE (tree) = getSpec (TTYPE (tree) =
2999 computeType (LTYPE (tree),
3002 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3003 werror (E_CODE_WRITE, " ");
3007 werror (E_LVALUE_REQUIRED, "-=");
3008 goto errorTreeReturn;
3014 /*------------------------------------------------------------------*/
3015 /*----------------------------*/
3017 /*----------------------------*/
3019 /* this is not a unary operation */
3020 /* if both pointers then problem */
3021 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3023 werror (E_PTR_PLUS_PTR);
3024 goto errorTreeReturn;
3027 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3029 werror (E_PLUS_INVALID, "+=");
3030 goto errorTreeReturn;
3033 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3035 werror (E_PLUS_INVALID, "+=");
3036 goto errorTreeReturn;
3039 TETYPE (tree) = getSpec (TTYPE (tree) =
3040 computeType (LTYPE (tree),
3043 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3044 werror (E_CODE_WRITE, " ");
3048 werror (E_LVALUE_REQUIRED, "+=");
3049 goto errorTreeReturn;
3052 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3053 tree->opval.op = '=';
3057 /*------------------------------------------------------------------*/
3058 /*----------------------------*/
3059 /* straight assignemnt */
3060 /*----------------------------*/
3062 /* cannot be an aggregate */
3063 if (IS_AGGREGATE (LTYPE (tree)))
3065 werror (E_AGGR_ASSIGN);
3066 goto errorTreeReturn;
3069 /* they should either match or be castable */
3070 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3072 werror (E_TYPE_MISMATCH, "assignment", " ");
3073 fprintf (stderr, "type --> '");
3074 printTypeChain (RTYPE (tree), stderr);
3075 fprintf (stderr, "' ");
3076 fprintf (stderr, "assigned to type --> '");
3077 printTypeChain (LTYPE (tree), stderr);
3078 fprintf (stderr, "'\n");
3079 goto errorTreeReturn;
3082 /* if the left side of the tree is of type void
3083 then report error */
3084 if (IS_VOID (LTYPE (tree)))
3086 werror (E_CAST_ZERO);
3087 printFromToType(RTYPE(tree), LTYPE(tree));
3090 TETYPE (tree) = getSpec (TTYPE (tree) =
3094 if (!tree->initMode ) {
3095 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3096 werror (E_CODE_WRITE, " ");
3100 werror (E_LVALUE_REQUIRED, "=");
3101 goto errorTreeReturn;
3106 /*------------------------------------------------------------------*/
3107 /*----------------------------*/
3108 /* comma operator */
3109 /*----------------------------*/
3111 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3114 /*------------------------------------------------------------------*/
3115 /*----------------------------*/
3117 /*----------------------------*/
3121 if (processParms (tree->left,
3122 FUNC_ARGS(tree->left->ftype),
3123 tree->right, &parmNumber, TRUE)) {
3124 goto errorTreeReturn;
3127 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3128 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3130 //FUNC_ARGS(tree->left->ftype) =
3131 //reverseVal (FUNC_ARGS(tree->left->ftype));
3132 reverseParms (tree->right);
3135 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3138 /*------------------------------------------------------------------*/
3139 /*----------------------------*/
3140 /* return statement */
3141 /*----------------------------*/
3146 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3148 werror (W_RETURN_MISMATCH);
3149 printFromToType (RTYPE(tree), currFunc->type->next);
3150 goto errorTreeReturn;
3153 if (IS_VOID (currFunc->type->next)
3155 !IS_VOID (RTYPE (tree)))
3157 werror (E_FUNC_VOID);
3158 goto errorTreeReturn;
3161 /* if there is going to be a casing required then add it */
3162 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3165 decorateType (newNode (CAST,
3166 newAst_LINK (copyLinkChain (currFunc->type->next)),
3175 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3177 werror (E_VOID_FUNC, currFunc->name);
3178 goto errorTreeReturn;
3181 TTYPE (tree) = TETYPE (tree) = NULL;
3184 /*------------------------------------------------------------------*/
3185 /*----------------------------*/
3186 /* switch statement */
3187 /*----------------------------*/
3189 /* the switch value must be an integer */
3190 if (!IS_INTEGRAL (LTYPE (tree)))
3192 werror (E_SWITCH_NON_INTEGER);
3193 goto errorTreeReturn;
3196 TTYPE (tree) = TETYPE (tree) = NULL;
3199 /*------------------------------------------------------------------*/
3200 /*----------------------------*/
3202 /*----------------------------*/
3204 tree->left = backPatchLabels (tree->left,
3207 TTYPE (tree) = TETYPE (tree) = NULL;
3210 /*------------------------------------------------------------------*/
3211 /*----------------------------*/
3213 /*----------------------------*/
3216 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3217 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3218 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3220 /* if the for loop is reversible then
3221 reverse it otherwise do what we normally
3227 if (isLoopReversible (tree, &sym, &init, &end))
3228 return reverseLoop (tree, sym, init, end);
3230 return decorateType (createFor (AST_FOR (tree, trueLabel),
3231 AST_FOR (tree, continueLabel),
3232 AST_FOR (tree, falseLabel),
3233 AST_FOR (tree, condLabel),
3234 AST_FOR (tree, initExpr),
3235 AST_FOR (tree, condExpr),
3236 AST_FOR (tree, loopExpr),
3240 TTYPE (tree) = TETYPE (tree) = NULL;
3244 /* some error found this tree will be killed */
3246 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3247 tree->opval.op = NULLOP;
3253 /*-----------------------------------------------------------------*/
3254 /* sizeofOp - processes size of operation */
3255 /*-----------------------------------------------------------------*/
3257 sizeofOp (sym_link * type)
3261 /* make sure the type is complete and sane */
3262 checkTypeSanity(type, "(sizeof)");
3264 /* get the size and convert it to character */
3265 sprintf (buff, "%d", getSize (type));
3267 /* now convert into value */
3268 return constVal (buff);
3272 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3273 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3274 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3275 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3276 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3277 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3278 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3280 /*-----------------------------------------------------------------*/
3281 /* backPatchLabels - change and or not operators to flow control */
3282 /*-----------------------------------------------------------------*/
3284 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3290 if (!(IS_ANDORNOT (tree)))
3293 /* if this an and */
3296 static int localLbl = 0;
3299 sprintf (buffer, "_and_%d", localLbl++);
3300 localLabel = newSymbol (buffer, NestLevel);
3302 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3304 /* if left is already a IFX then just change the if true label in that */
3305 if (!IS_IFX (tree->left))
3306 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3308 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3309 /* right is a IFX then just join */
3310 if (IS_IFX (tree->right))
3311 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3313 tree->right = createLabel (localLabel, tree->right);
3314 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3316 return newNode (NULLOP, tree->left, tree->right);
3319 /* if this is an or operation */
3322 static int localLbl = 0;
3325 sprintf (buffer, "_or_%d", localLbl++);
3326 localLabel = newSymbol (buffer, NestLevel);
3328 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3330 /* if left is already a IFX then just change the if true label in that */
3331 if (!IS_IFX (tree->left))
3332 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3334 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3335 /* right is a IFX then just join */
3336 if (IS_IFX (tree->right))
3337 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3339 tree->right = createLabel (localLabel, tree->right);
3340 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3342 return newNode (NULLOP, tree->left, tree->right);
3348 int wasnot = IS_NOT (tree->left);
3349 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3351 /* if the left is already a IFX */
3352 if (!IS_IFX (tree->left))
3353 tree->left = newNode (IFX, tree->left, NULL);
3357 tree->left->trueLabel = trueLabel;
3358 tree->left->falseLabel = falseLabel;
3362 tree->left->trueLabel = falseLabel;
3363 tree->left->falseLabel = trueLabel;
3370 tree->trueLabel = trueLabel;
3371 tree->falseLabel = falseLabel;
3378 /*-----------------------------------------------------------------*/
3379 /* createBlock - create expression tree for block */
3380 /*-----------------------------------------------------------------*/
3382 createBlock (symbol * decl, ast * body)
3386 /* if the block has nothing */
3390 ex = newNode (BLOCK, NULL, body);
3391 ex->values.sym = decl;
3393 ex->right = ex->right;
3399 /*-----------------------------------------------------------------*/
3400 /* createLabel - creates the expression tree for labels */
3401 /*-----------------------------------------------------------------*/
3403 createLabel (symbol * label, ast * stmnt)
3406 char name[SDCC_NAME_MAX + 1];
3409 /* must create fresh symbol if the symbol name */
3410 /* exists in the symbol table, since there can */
3411 /* be a variable with the same name as the labl */
3412 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3413 (csym->level == label->level))
3414 label = newSymbol (label->name, label->level);
3416 /* change the name before putting it in add _ */
3417 sprintf (name, "%s", label->name);
3419 /* put the label in the LabelSymbol table */
3420 /* but first check if a label of the same */
3422 if ((csym = findSym (LabelTab, NULL, name)))
3423 werror (E_DUPLICATE_LABEL, label->name);
3425 addSym (LabelTab, label, name, label->level, 0, 0);
3428 label->key = labelKey++;
3429 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3435 /*-----------------------------------------------------------------*/
3436 /* createCase - generates the parsetree for a case statement */
3437 /*-----------------------------------------------------------------*/
3439 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3441 char caseLbl[SDCC_NAME_MAX + 1];
3445 /* if the switch statement does not exist */
3446 /* then case is out of context */
3449 werror (E_CASE_CONTEXT);
3453 caseVal = decorateType (resolveSymbols (caseVal));
3454 /* if not a constant then error */
3455 if (!IS_LITERAL (caseVal->ftype))
3457 werror (E_CASE_CONSTANT);
3461 /* if not a integer than error */
3462 if (!IS_INTEGRAL (caseVal->ftype))
3464 werror (E_CASE_NON_INTEGER);
3468 /* find the end of the switch values chain */
3469 if (!(val = swStat->values.switchVals.swVals))
3470 swStat->values.switchVals.swVals = caseVal->opval.val;
3473 /* also order the cases according to value */
3475 int cVal = (int) floatFromVal (caseVal->opval.val);
3476 while (val && (int) floatFromVal (val) < cVal)
3482 /* if we reached the end then */
3485 pval->next = caseVal->opval.val;
3489 /* we found a value greater than */
3490 /* the current value we must add this */
3491 /* before the value */
3492 caseVal->opval.val->next = val;
3494 /* if this was the first in chain */
3495 if (swStat->values.switchVals.swVals == val)
3496 swStat->values.switchVals.swVals =
3499 pval->next = caseVal->opval.val;
3504 /* create the case label */
3505 sprintf (caseLbl, "_case_%d_%d",
3506 swStat->values.switchVals.swNum,
3507 (int) floatFromVal (caseVal->opval.val));
3509 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3514 /*-----------------------------------------------------------------*/
3515 /* createDefault - creates the parse tree for the default statement */
3516 /*-----------------------------------------------------------------*/
3518 createDefault (ast * swStat, ast * stmnt)
3520 char defLbl[SDCC_NAME_MAX + 1];
3522 /* if the switch statement does not exist */
3523 /* then case is out of context */
3526 werror (E_CASE_CONTEXT);
3530 /* turn on the default flag */
3531 swStat->values.switchVals.swDefault = 1;
3533 /* create the label */
3534 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3535 return createLabel (newSymbol (defLbl, 0), stmnt);
3538 /*-----------------------------------------------------------------*/
3539 /* createIf - creates the parsetree for the if statement */
3540 /*-----------------------------------------------------------------*/
3542 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3544 static int Lblnum = 0;
3546 symbol *ifTrue, *ifFalse, *ifEnd;
3548 /* if neither exists */
3549 if (!elseBody && !ifBody) {
3550 // if there are no side effects (i++, j() etc)
3551 if (!hasSEFcalls(condAst)) {
3556 /* create the labels */
3557 sprintf (buffer, "_iffalse_%d", Lblnum);
3558 ifFalse = newSymbol (buffer, NestLevel);
3559 /* if no else body then end == false */
3564 sprintf (buffer, "_ifend_%d", Lblnum);
3565 ifEnd = newSymbol (buffer, NestLevel);
3568 sprintf (buffer, "_iftrue_%d", Lblnum);
3569 ifTrue = newSymbol (buffer, NestLevel);
3573 /* attach the ifTrue label to the top of it body */
3574 ifBody = createLabel (ifTrue, ifBody);
3575 /* attach a goto end to the ifBody if else is present */
3578 ifBody = newNode (NULLOP, ifBody,
3580 newAst_VALUE (symbolVal (ifEnd)),
3582 /* put the elseLabel on the else body */
3583 elseBody = createLabel (ifFalse, elseBody);
3584 /* out the end at the end of the body */
3585 elseBody = newNode (NULLOP,
3587 createLabel (ifEnd, NULL));
3591 ifBody = newNode (NULLOP, ifBody,
3592 createLabel (ifFalse, NULL));
3594 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3595 if (IS_IFX (condAst))
3598 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3600 return newNode (NULLOP, ifTree,
3601 newNode (NULLOP, ifBody, elseBody));
3605 /*-----------------------------------------------------------------*/
3606 /* createDo - creates parse tree for do */
3609 /* _docontinue_n: */
3610 /* condition_expression +-> trueLabel -> _dobody_n */
3612 /* +-> falseLabel-> _dobreak_n */
3614 /*-----------------------------------------------------------------*/
3616 createDo (symbol * trueLabel, symbol * continueLabel,
3617 symbol * falseLabel, ast * condAst, ast * doBody)
3622 /* if the body does not exist then it is simple */
3625 condAst = backPatchLabels (condAst, continueLabel, NULL);
3626 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3627 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3628 doTree->trueLabel = continueLabel;
3629 doTree->falseLabel = NULL;
3633 /* otherwise we have a body */
3634 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3636 /* attach the body label to the top */
3637 doBody = createLabel (trueLabel, doBody);
3638 /* attach the continue label to end of body */
3639 doBody = newNode (NULLOP, doBody,
3640 createLabel (continueLabel, NULL));
3642 /* now put the break label at the end */
3643 if (IS_IFX (condAst))
3646 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3648 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3650 /* putting it together */
3651 return newNode (NULLOP, doBody, doTree);
3654 /*-----------------------------------------------------------------*/
3655 /* createFor - creates parse tree for 'for' statement */
3658 /* condExpr +-> trueLabel -> _forbody_n */
3660 /* +-> falseLabel-> _forbreak_n */
3663 /* _forcontinue_n: */
3665 /* goto _forcond_n ; */
3667 /*-----------------------------------------------------------------*/
3669 createFor (symbol * trueLabel, symbol * continueLabel,
3670 symbol * falseLabel, symbol * condLabel,
3671 ast * initExpr, ast * condExpr, ast * loopExpr,
3676 /* if loopexpression not present then we can generate it */
3677 /* the same way as a while */
3679 return newNode (NULLOP, initExpr,
3680 createWhile (trueLabel, continueLabel,
3681 falseLabel, condExpr, forBody));
3682 /* vanilla for statement */
3683 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3685 if (condExpr && !IS_IFX (condExpr))
3686 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3689 /* attach condition label to condition */
3690 condExpr = createLabel (condLabel, condExpr);
3692 /* attach body label to body */
3693 forBody = createLabel (trueLabel, forBody);
3695 /* attach continue to forLoop expression & attach */
3696 /* goto the forcond @ and of loopExpression */
3697 loopExpr = createLabel (continueLabel,
3701 newAst_VALUE (symbolVal (condLabel)),
3703 /* now start putting them together */
3704 forTree = newNode (NULLOP, initExpr, condExpr);
3705 forTree = newNode (NULLOP, forTree, forBody);
3706 forTree = newNode (NULLOP, forTree, loopExpr);
3707 /* finally add the break label */
3708 forTree = newNode (NULLOP, forTree,
3709 createLabel (falseLabel, NULL));
3713 /*-----------------------------------------------------------------*/
3714 /* createWhile - creates parse tree for while statement */
3715 /* the while statement will be created as follows */
3717 /* _while_continue_n: */
3718 /* condition_expression +-> trueLabel -> _while_boby_n */
3720 /* +-> falseLabel -> _while_break_n */
3721 /* _while_body_n: */
3723 /* goto _while_continue_n */
3724 /* _while_break_n: */
3725 /*-----------------------------------------------------------------*/
3727 createWhile (symbol * trueLabel, symbol * continueLabel,
3728 symbol * falseLabel, ast * condExpr, ast * whileBody)
3732 /* put the continue label */
3733 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3734 condExpr = createLabel (continueLabel, condExpr);
3735 condExpr->lineno = 0;
3737 /* put the body label in front of the body */
3738 whileBody = createLabel (trueLabel, whileBody);
3739 whileBody->lineno = 0;
3740 /* put a jump to continue at the end of the body */
3741 /* and put break label at the end of the body */
3742 whileBody = newNode (NULLOP,
3745 newAst_VALUE (symbolVal (continueLabel)),
3746 createLabel (falseLabel, NULL)));
3748 /* put it all together */
3749 if (IS_IFX (condExpr))
3750 whileTree = condExpr;
3753 whileTree = newNode (IFX, condExpr, NULL);
3754 /* put the true & false labels in place */
3755 whileTree->trueLabel = trueLabel;
3756 whileTree->falseLabel = falseLabel;
3759 return newNode (NULLOP, whileTree, whileBody);
3762 /*-----------------------------------------------------------------*/
3763 /* optimizeGetHbit - get highest order bit of the expression */
3764 /*-----------------------------------------------------------------*/
3766 optimizeGetHbit (ast * tree)
3769 /* if this is not a bit and */
3770 if (!IS_BITAND (tree))
3773 /* will look for tree of the form
3774 ( expr >> ((sizeof expr) -1) ) & 1 */
3775 if (!IS_AST_LIT_VALUE (tree->right))
3778 if (AST_LIT_VALUE (tree->right) != 1)
3781 if (!IS_RIGHT_OP (tree->left))
3784 if (!IS_AST_LIT_VALUE (tree->left->right))
3787 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3788 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3791 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3795 /*-----------------------------------------------------------------*/
3796 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3797 /*-----------------------------------------------------------------*/
3799 optimizeRRCRLC (ast * root)
3801 /* will look for trees of the form
3802 (?expr << 1) | (?expr >> 7) or
3803 (?expr >> 7) | (?expr << 1) will make that
3804 into a RLC : operation ..
3806 (?expr >> 1) | (?expr << 7) or
3807 (?expr << 7) | (?expr >> 1) will make that
3808 into a RRC operation
3809 note : by 7 I mean (number of bits required to hold the
3811 /* if the root operations is not a | operation the not */
3812 if (!IS_BITOR (root))
3815 /* I have to think of a better way to match patterns this sucks */
3816 /* that aside let start looking for the first case : I use a the
3817 negative check a lot to improve the efficiency */
3818 /* (?expr << 1) | (?expr >> 7) */
3819 if (IS_LEFT_OP (root->left) &&
3820 IS_RIGHT_OP (root->right))
3823 if (!SPEC_USIGN (TETYPE (root->left->left)))
3826 if (!IS_AST_LIT_VALUE (root->left->right) ||
3827 !IS_AST_LIT_VALUE (root->right->right))
3830 /* make sure it is the same expression */
3831 if (!isAstEqual (root->left->left,
3835 if (AST_LIT_VALUE (root->left->right) != 1)
3838 if (AST_LIT_VALUE (root->right->right) !=
3839 (getSize (TTYPE (root->left->left)) * 8 - 1))
3842 /* whew got the first case : create the AST */
3843 return newNode (RLC, root->left->left, NULL);
3847 /* check for second case */
3848 /* (?expr >> 7) | (?expr << 1) */
3849 if (IS_LEFT_OP (root->right) &&
3850 IS_RIGHT_OP (root->left))
3853 if (!SPEC_USIGN (TETYPE (root->left->left)))
3856 if (!IS_AST_LIT_VALUE (root->left->right) ||
3857 !IS_AST_LIT_VALUE (root->right->right))
3860 /* make sure it is the same symbol */
3861 if (!isAstEqual (root->left->left,
3865 if (AST_LIT_VALUE (root->right->right) != 1)
3868 if (AST_LIT_VALUE (root->left->right) !=
3869 (getSize (TTYPE (root->left->left)) * 8 - 1))
3872 /* whew got the first case : create the AST */
3873 return newNode (RLC, root->left->left, NULL);
3878 /* third case for RRC */
3879 /* (?symbol >> 1) | (?symbol << 7) */
3880 if (IS_LEFT_OP (root->right) &&
3881 IS_RIGHT_OP (root->left))
3884 if (!SPEC_USIGN (TETYPE (root->left->left)))
3887 if (!IS_AST_LIT_VALUE (root->left->right) ||
3888 !IS_AST_LIT_VALUE (root->right->right))
3891 /* make sure it is the same symbol */
3892 if (!isAstEqual (root->left->left,
3896 if (AST_LIT_VALUE (root->left->right) != 1)
3899 if (AST_LIT_VALUE (root->right->right) !=
3900 (getSize (TTYPE (root->left->left)) * 8 - 1))
3903 /* whew got the first case : create the AST */
3904 return newNode (RRC, root->left->left, NULL);
3908 /* fourth and last case for now */
3909 /* (?symbol << 7) | (?symbol >> 1) */
3910 if (IS_RIGHT_OP (root->right) &&
3911 IS_LEFT_OP (root->left))
3914 if (!SPEC_USIGN (TETYPE (root->left->left)))
3917 if (!IS_AST_LIT_VALUE (root->left->right) ||
3918 !IS_AST_LIT_VALUE (root->right->right))
3921 /* make sure it is the same symbol */
3922 if (!isAstEqual (root->left->left,
3926 if (AST_LIT_VALUE (root->right->right) != 1)
3929 if (AST_LIT_VALUE (root->left->right) !=
3930 (getSize (TTYPE (root->left->left)) * 8 - 1))
3933 /* whew got the first case : create the AST */
3934 return newNode (RRC, root->left->left, NULL);
3938 /* not found return root */
3942 /*-----------------------------------------------------------------*/
3943 /* optimizeCompare - otimizes compares for bit variables */
3944 /*-----------------------------------------------------------------*/
3946 optimizeCompare (ast * root)
3948 ast *optExpr = NULL;
3951 unsigned int litValue;
3953 /* if nothing then return nothing */
3957 /* if not a compare op then do leaves */
3958 if (!IS_COMPARE_OP (root))
3960 root->left = optimizeCompare (root->left);
3961 root->right = optimizeCompare (root->right);
3965 /* if left & right are the same then depending
3966 of the operation do */
3967 if (isAstEqual (root->left, root->right))
3969 switch (root->opval.op)
3974 optExpr = newAst_VALUE (constVal ("0"));
3979 optExpr = newAst_VALUE (constVal ("1"));
3983 return decorateType (optExpr);
3986 vleft = (root->left->type == EX_VALUE ?
3987 root->left->opval.val : NULL);
3989 vright = (root->right->type == EX_VALUE ?
3990 root->right->opval.val : NULL);
3992 /* if left is a BITVAR in BITSPACE */
3993 /* and right is a LITERAL then opt- */
3994 /* imize else do nothing */
3995 if (vleft && vright &&
3996 IS_BITVAR (vleft->etype) &&
3997 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3998 IS_LITERAL (vright->etype))
4001 /* if right side > 1 then comparison may never succeed */
4002 if ((litValue = (int) floatFromVal (vright)) > 1)
4004 werror (W_BAD_COMPARE);
4010 switch (root->opval.op)
4012 case '>': /* bit value greater than 1 cannot be */
4013 werror (W_BAD_COMPARE);
4017 case '<': /* bit value < 1 means 0 */
4019 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4022 case LE_OP: /* bit value <= 1 means no check */
4023 optExpr = newAst_VALUE (vright);
4026 case GE_OP: /* bit value >= 1 means only check for = */
4028 optExpr = newAst_VALUE (vleft);
4033 { /* literal is zero */
4034 switch (root->opval.op)
4036 case '<': /* bit value < 0 cannot be */
4037 werror (W_BAD_COMPARE);
4041 case '>': /* bit value > 0 means 1 */
4043 optExpr = newAst_VALUE (vleft);
4046 case LE_OP: /* bit value <= 0 means no check */
4047 case GE_OP: /* bit value >= 0 means no check */
4048 werror (W_BAD_COMPARE);
4052 case EQ_OP: /* bit == 0 means ! of bit */
4053 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4057 return decorateType (resolveSymbols (optExpr));
4058 } /* end-of-if of BITVAR */
4063 /*-----------------------------------------------------------------*/
4064 /* addSymToBlock : adds the symbol to the first block we find */
4065 /*-----------------------------------------------------------------*/
4067 addSymToBlock (symbol * sym, ast * tree)
4069 /* reached end of tree or a leaf */
4070 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4074 if (IS_AST_OP (tree) &&
4075 tree->opval.op == BLOCK)
4078 symbol *lsym = copySymbol (sym);
4080 lsym->next = AST_VALUES (tree, sym);
4081 AST_VALUES (tree, sym) = lsym;
4085 addSymToBlock (sym, tree->left);
4086 addSymToBlock (sym, tree->right);
4089 /*-----------------------------------------------------------------*/
4090 /* processRegParms - do processing for register parameters */
4091 /*-----------------------------------------------------------------*/
4093 processRegParms (value * args, ast * body)
4097 if (IS_REGPARM (args->etype))
4098 addSymToBlock (args->sym, body);
4103 /*-----------------------------------------------------------------*/
4104 /* resetParmKey - resets the operandkeys for the symbols */
4105 /*-----------------------------------------------------------------*/
4106 DEFSETFUNC (resetParmKey)
4117 /*-----------------------------------------------------------------*/
4118 /* createFunction - This is the key node that calls the iCode for */
4119 /* generating the code for a function. Note code */
4120 /* is generated function by function, later when */
4121 /* add inter-procedural analysis this will change */
4122 /*-----------------------------------------------------------------*/
4124 createFunction (symbol * name, ast * body)
4130 iCode *piCode = NULL;
4132 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4133 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4135 /* if check function return 0 then some problem */
4136 if (checkFunction (name, NULL) == 0)
4139 /* create a dummy block if none exists */
4141 body = newNode (BLOCK, NULL, NULL);
4145 /* check if the function name already in the symbol table */
4146 if ((csym = findSym (SymbolTab, NULL, name->name)))
4149 /* special case for compiler defined functions
4150 we need to add the name to the publics list : this
4151 actually means we are now compiling the compiler
4155 addSet (&publics, name);
4161 allocVariables (name);
4163 name->lastLine = yylineno;
4166 /* set the stack pointer */
4167 /* PENDING: check this for the mcs51 */
4168 stackPtr = -port->stack.direction * port->stack.call_overhead;
4169 if (IFFUNC_ISISR (name->type))
4170 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4171 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4172 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4174 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4176 fetype = getSpec (name->type); /* get the specifier for the function */
4177 /* if this is a reentrant function then */
4178 if (IFFUNC_ISREENT (name->type))
4181 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4183 /* do processing for parameters that are passed in registers */
4184 processRegParms (FUNC_ARGS(name->type), body);
4186 /* set the stack pointer */
4190 /* allocate & autoinit the block variables */
4191 processBlockVars (body, &stack, ALLOCATE);
4193 /* save the stack information */
4194 if (options.useXstack)
4195 name->xstack = SPEC_STAK (fetype) = stack;
4197 name->stack = SPEC_STAK (fetype) = stack;
4199 /* name needs to be mangled */
4200 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4202 body = resolveSymbols (body); /* resolve the symbols */
4203 body = decorateType (body); /* propagateType & do semantic checks */
4205 ex = newAst_VALUE (symbolVal (name)); /* create name */
4206 ex = newNode (FUNCTION, ex, body);
4207 ex->values.args = FUNC_ARGS(name->type);
4209 if (options.dump_tree) PA(ex);
4212 werror (E_FUNC_NO_CODE, name->name);
4216 /* create the node & generate intermediate code */
4218 codeOutFile = code->oFile;
4219 piCode = iCodeFromAst (ex);
4223 werror (E_FUNC_NO_CODE, name->name);
4227 eBBlockFromiCode (piCode);
4229 /* if there are any statics then do them */
4232 GcurMemmap = statsg;
4233 codeOutFile = statsg->oFile;
4234 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4240 /* dealloc the block variables */
4241 processBlockVars (body, &stack, DEALLOCATE);
4242 /* deallocate paramaters */
4243 deallocParms (FUNC_ARGS(name->type));
4245 if (IFFUNC_ISREENT (name->type))
4248 /* we are done freeup memory & cleanup */
4250 if (port->reset_labelKey) labelKey = 1;
4252 FUNC_HASBODY(name->type) = 1;
4253 addSet (&operKeyReset, name);
4254 applyToSet (operKeyReset, resetParmKey);
4257 cdbStructBlock (1, cdbFile);
4259 cleanUpLevel (LabelTab, 0);
4260 cleanUpBlock (StructTab, 1);
4261 cleanUpBlock (TypedefTab, 1);
4263 xstack->syms = NULL;
4264 istack->syms = NULL;
4269 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4270 /*-----------------------------------------------------------------*/
4271 /* ast_print : prints the ast (for debugging purposes) */
4272 /*-----------------------------------------------------------------*/
4274 void ast_print (ast * tree, FILE *outfile, int indent)
4279 /* can print only decorated trees */
4280 if (!tree->decorated) return;
4282 /* if any child is an error | this one is an error do nothing */
4283 if (tree->isError ||
4284 (tree->left && tree->left->isError) ||
4285 (tree->right && tree->right->isError)) {
4286 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4290 /* print the line */
4291 /* if not block & function */
4292 if (tree->type == EX_OP &&
4293 (tree->opval.op != FUNCTION &&
4294 tree->opval.op != BLOCK &&
4295 tree->opval.op != NULLOP)) {
4298 if (tree->opval.op == FUNCTION) {
4300 value *args=FUNC_ARGS(tree->left->opval.val->type);
4301 fprintf(outfile,"FUNCTION (%s=%p) type (",
4302 tree->left->opval.val->name, tree);
4303 printTypeChain (tree->ftype,outfile);
4304 fprintf(outfile,") args (");
4307 fprintf (outfile, ", ");
4309 printTypeChain (args ? args->type : NULL, outfile);
4311 args= args ? args->next : NULL;
4313 fprintf(outfile,")\n");
4314 ast_print(tree->left,outfile,indent);
4315 ast_print(tree->right,outfile,indent);
4318 if (tree->opval.op == BLOCK) {
4319 symbol *decls = tree->values.sym;
4320 INDENT(indent,outfile);
4321 fprintf(outfile,"{\n");
4323 INDENT(indent+2,outfile);
4324 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4325 decls->name, decls);
4326 printTypeChain(decls->type,outfile);
4327 fprintf(outfile,")\n");
4329 decls = decls->next;
4331 ast_print(tree->right,outfile,indent+2);
4332 INDENT(indent,outfile);
4333 fprintf(outfile,"}\n");
4336 if (tree->opval.op == NULLOP) {
4337 fprintf(outfile,"\n");
4338 ast_print(tree->left,outfile,indent);
4339 fprintf(outfile,"\n");
4340 ast_print(tree->right,outfile,indent);
4343 INDENT(indent,outfile);
4345 /*------------------------------------------------------------------*/
4346 /*----------------------------*/
4347 /* leaf has been reached */
4348 /*----------------------------*/
4349 /* if this is of type value */
4350 /* just get the type */
4351 if (tree->type == EX_VALUE) {
4353 if (IS_LITERAL (tree->opval.val->etype)) {
4354 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4355 (int) floatFromVal(tree->opval.val),
4356 (int) floatFromVal(tree->opval.val),
4357 floatFromVal(tree->opval.val));
4358 } else if (tree->opval.val->sym) {
4359 /* if the undefined flag is set then give error message */
4360 if (tree->opval.val->sym->undefined) {
4361 fprintf(outfile,"UNDEFINED SYMBOL ");
4363 fprintf(outfile,"SYMBOL ");
4365 fprintf(outfile,"(%s=%p)",
4366 tree->opval.val->sym->name,tree);
4369 fprintf(outfile," type (");
4370 printTypeChain(tree->ftype,outfile);
4371 fprintf(outfile,")\n");
4373 fprintf(outfile,"\n");
4378 /* if type link for the case of cast */
4379 if (tree->type == EX_LINK) {
4380 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4381 printTypeChain(tree->opval.lnk,outfile);
4382 fprintf(outfile,")\n");
4387 /* depending on type of operator do */
4389 switch (tree->opval.op) {
4390 /*------------------------------------------------------------------*/
4391 /*----------------------------*/
4393 /*----------------------------*/
4395 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4396 printTypeChain(tree->ftype,outfile);
4397 fprintf(outfile,")\n");
4398 ast_print(tree->left,outfile,indent+2);
4399 ast_print(tree->right,outfile,indent+2);
4402 /*------------------------------------------------------------------*/
4403 /*----------------------------*/
4405 /*----------------------------*/
4407 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4408 printTypeChain(tree->ftype,outfile);
4409 fprintf(outfile,")\n");
4410 ast_print(tree->left,outfile,indent+2);
4411 ast_print(tree->right,outfile,indent+2);
4414 /*------------------------------------------------------------------*/
4415 /*----------------------------*/
4416 /* struct/union pointer */
4417 /*----------------------------*/
4419 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4420 printTypeChain(tree->ftype,outfile);
4421 fprintf(outfile,")\n");
4422 ast_print(tree->left,outfile,indent+2);
4423 ast_print(tree->right,outfile,indent+2);
4426 /*------------------------------------------------------------------*/
4427 /*----------------------------*/
4428 /* ++/-- operation */
4429 /*----------------------------*/
4430 case INC_OP: /* incerement operator unary so left only */
4431 fprintf(outfile,"INC_OP (%p) type (",tree);
4432 printTypeChain(tree->ftype,outfile);
4433 fprintf(outfile,")\n");
4434 ast_print(tree->left,outfile,indent+2);
4438 fprintf(outfile,"DEC_OP (%p) type (",tree);
4439 printTypeChain(tree->ftype,outfile);
4440 fprintf(outfile,")\n");
4441 ast_print(tree->left,outfile,indent+2);
4444 /*------------------------------------------------------------------*/
4445 /*----------------------------*/
4447 /*----------------------------*/
4450 fprintf(outfile,"& (%p) type (",tree);
4451 printTypeChain(tree->ftype,outfile);
4452 fprintf(outfile,")\n");
4453 ast_print(tree->left,outfile,indent+2);
4454 ast_print(tree->right,outfile,indent+2);
4456 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+2);
4460 ast_print(tree->right,outfile,indent+2);
4463 /*----------------------------*/
4465 /*----------------------------*/
4467 fprintf(outfile,"OR (%p) type (",tree);
4468 printTypeChain(tree->ftype,outfile);
4469 fprintf(outfile,")\n");
4470 ast_print(tree->left,outfile,indent+2);
4471 ast_print(tree->right,outfile,indent+2);
4473 /*------------------------------------------------------------------*/
4474 /*----------------------------*/
4476 /*----------------------------*/
4478 fprintf(outfile,"XOR (%p) type (",tree);
4479 printTypeChain(tree->ftype,outfile);
4480 fprintf(outfile,")\n");
4481 ast_print(tree->left,outfile,indent+2);
4482 ast_print(tree->right,outfile,indent+2);
4485 /*------------------------------------------------------------------*/
4486 /*----------------------------*/
4488 /*----------------------------*/
4490 fprintf(outfile,"DIV (%p) type (",tree);
4491 printTypeChain(tree->ftype,outfile);
4492 fprintf(outfile,")\n");
4493 ast_print(tree->left,outfile,indent+2);
4494 ast_print(tree->right,outfile,indent+2);
4496 /*------------------------------------------------------------------*/
4497 /*----------------------------*/
4499 /*----------------------------*/
4501 fprintf(outfile,"MOD (%p) type (",tree);
4502 printTypeChain(tree->ftype,outfile);
4503 fprintf(outfile,")\n");
4504 ast_print(tree->left,outfile,indent+2);
4505 ast_print(tree->right,outfile,indent+2);
4508 /*------------------------------------------------------------------*/
4509 /*----------------------------*/
4510 /* address dereference */
4511 /*----------------------------*/
4512 case '*': /* can be unary : if right is null then unary operation */
4514 fprintf(outfile,"DEREF (%p) type (",tree);
4515 printTypeChain(tree->ftype,outfile);
4516 fprintf(outfile,")\n");
4517 ast_print(tree->left,outfile,indent+2);
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4522 /* multiplication */
4523 /*----------------------------*/
4524 fprintf(outfile,"MULT (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+2);
4528 ast_print(tree->right,outfile,indent+2);
4532 /*------------------------------------------------------------------*/
4533 /*----------------------------*/
4534 /* unary '+' operator */
4535 /*----------------------------*/
4539 fprintf(outfile,"UPLUS (%p) type (",tree);
4540 printTypeChain(tree->ftype,outfile);
4541 fprintf(outfile,")\n");
4542 ast_print(tree->left,outfile,indent+2);
4544 /*------------------------------------------------------------------*/
4545 /*----------------------------*/
4547 /*----------------------------*/
4548 fprintf(outfile,"ADD (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+2);
4552 ast_print(tree->right,outfile,indent+2);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4558 /*----------------------------*/
4559 case '-': /* can be unary */
4561 fprintf(outfile,"UMINUS (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+2);
4566 /*------------------------------------------------------------------*/
4567 /*----------------------------*/
4569 /*----------------------------*/
4570 fprintf(outfile,"SUB (%p) type (",tree);
4571 printTypeChain(tree->ftype,outfile);
4572 fprintf(outfile,")\n");
4573 ast_print(tree->left,outfile,indent+2);
4574 ast_print(tree->right,outfile,indent+2);
4577 /*------------------------------------------------------------------*/
4578 /*----------------------------*/
4580 /*----------------------------*/
4582 fprintf(outfile,"COMPL (%p) type (",tree);
4583 printTypeChain(tree->ftype,outfile);
4584 fprintf(outfile,")\n");
4585 ast_print(tree->left,outfile,indent+2);
4587 /*------------------------------------------------------------------*/
4588 /*----------------------------*/
4590 /*----------------------------*/
4592 fprintf(outfile,"NOT (%p) type (",tree);
4593 printTypeChain(tree->ftype,outfile);
4594 fprintf(outfile,")\n");
4595 ast_print(tree->left,outfile,indent+2);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4600 /*----------------------------*/
4602 fprintf(outfile,"RRC (%p) type (",tree);
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->left,outfile,indent+2);
4609 fprintf(outfile,"RLC (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+2);
4615 fprintf(outfile,"GETHBIT (%p) type (",tree);
4616 printTypeChain(tree->ftype,outfile);
4617 fprintf(outfile,")\n");
4618 ast_print(tree->left,outfile,indent+2);
4621 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4622 printTypeChain(tree->ftype,outfile);
4623 fprintf(outfile,")\n");
4624 ast_print(tree->left,outfile,indent+2);
4625 ast_print(tree->right,outfile,indent+2);
4628 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4629 printTypeChain(tree->ftype,outfile);
4630 fprintf(outfile,")\n");
4631 ast_print(tree->left,outfile,indent+2);
4632 ast_print(tree->right,outfile,indent+2);
4634 /*------------------------------------------------------------------*/
4635 /*----------------------------*/
4637 /*----------------------------*/
4638 case CAST: /* change the type */
4639 fprintf(outfile,"CAST (%p) from type (",tree);
4640 printTypeChain(tree->right->ftype,outfile);
4641 fprintf(outfile,") to type (");
4642 printTypeChain(tree->ftype,outfile);
4643 fprintf(outfile,")\n");
4644 ast_print(tree->right,outfile,indent+2);
4648 fprintf(outfile,"ANDAND (%p) type (",tree);
4649 printTypeChain(tree->ftype,outfile);
4650 fprintf(outfile,")\n");
4651 ast_print(tree->left,outfile,indent+2);
4652 ast_print(tree->right,outfile,indent+2);
4655 fprintf(outfile,"OROR (%p) type (",tree);
4656 printTypeChain(tree->ftype,outfile);
4657 fprintf(outfile,")\n");
4658 ast_print(tree->left,outfile,indent+2);
4659 ast_print(tree->right,outfile,indent+2);
4662 /*------------------------------------------------------------------*/
4663 /*----------------------------*/
4664 /* comparison operators */
4665 /*----------------------------*/
4667 fprintf(outfile,"GT(>) (%p) type (",tree);
4668 printTypeChain(tree->ftype,outfile);
4669 fprintf(outfile,")\n");
4670 ast_print(tree->left,outfile,indent+2);
4671 ast_print(tree->right,outfile,indent+2);
4674 fprintf(outfile,"LT(<) (%p) type (",tree);
4675 printTypeChain(tree->ftype,outfile);
4676 fprintf(outfile,")\n");
4677 ast_print(tree->left,outfile,indent+2);
4678 ast_print(tree->right,outfile,indent+2);
4681 fprintf(outfile,"LE(<=) (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->left,outfile,indent+2);
4685 ast_print(tree->right,outfile,indent+2);
4688 fprintf(outfile,"GE(>=) (%p) type (",tree);
4689 printTypeChain(tree->ftype,outfile);
4690 fprintf(outfile,")\n");
4691 ast_print(tree->left,outfile,indent+2);
4692 ast_print(tree->right,outfile,indent+2);
4695 fprintf(outfile,"EQ(==) (%p) type (",tree);
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->left,outfile,indent+2);
4699 ast_print(tree->right,outfile,indent+2);
4702 fprintf(outfile,"NE(!=) (%p) type (",tree);
4703 printTypeChain(tree->ftype,outfile);
4704 fprintf(outfile,")\n");
4705 ast_print(tree->left,outfile,indent+2);
4706 ast_print(tree->right,outfile,indent+2);
4707 /*------------------------------------------------------------------*/
4708 /*----------------------------*/
4710 /*----------------------------*/
4711 case SIZEOF: /* evaluate wihout code generation */
4712 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4715 /*------------------------------------------------------------------*/
4716 /*----------------------------*/
4717 /* conditional operator '?' */
4718 /*----------------------------*/
4720 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4721 printTypeChain(tree->ftype,outfile);
4722 fprintf(outfile,")\n");
4723 ast_print(tree->left,outfile,indent+2);
4724 ast_print(tree->right,outfile,indent+2);
4728 fprintf(outfile,"COLON(:) (%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);
4735 /*------------------------------------------------------------------*/
4736 /*----------------------------*/
4737 /* assignment operators */
4738 /*----------------------------*/
4740 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4741 printTypeChain(tree->ftype,outfile);
4742 fprintf(outfile,")\n");
4743 ast_print(tree->left,outfile,indent+2);
4744 ast_print(tree->right,outfile,indent+2);
4747 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4748 printTypeChain(tree->ftype,outfile);
4749 fprintf(outfile,")\n");
4750 ast_print(tree->left,outfile,indent+2);
4751 ast_print(tree->right,outfile,indent+2);
4754 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4755 printTypeChain(tree->ftype,outfile);
4756 fprintf(outfile,")\n");
4757 ast_print(tree->left,outfile,indent+2);
4758 ast_print(tree->right,outfile,indent+2);
4761 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4762 printTypeChain(tree->ftype,outfile);
4763 fprintf(outfile,")\n");
4764 ast_print(tree->left,outfile,indent+2);
4765 ast_print(tree->right,outfile,indent+2);
4768 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+2);
4772 ast_print(tree->right,outfile,indent+2);
4775 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4776 printTypeChain(tree->ftype,outfile);
4777 fprintf(outfile,")\n");
4778 ast_print(tree->left,outfile,indent+2);
4779 ast_print(tree->right,outfile,indent+2);
4782 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4783 printTypeChain(tree->ftype,outfile);
4784 fprintf(outfile,")\n");
4785 ast_print(tree->left,outfile,indent+2);
4786 ast_print(tree->right,outfile,indent+2);
4788 /*------------------------------------------------------------------*/
4789 /*----------------------------*/
4791 /*----------------------------*/
4793 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4794 printTypeChain(tree->ftype,outfile);
4795 fprintf(outfile,")\n");
4796 ast_print(tree->left,outfile,indent+2);
4797 ast_print(tree->right,outfile,indent+2);
4799 /*------------------------------------------------------------------*/
4800 /*----------------------------*/
4802 /*----------------------------*/
4804 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4805 printTypeChain(tree->ftype,outfile);
4806 fprintf(outfile,")\n");
4807 ast_print(tree->left,outfile,indent+2);
4808 ast_print(tree->right,outfile,indent+2);
4810 /*------------------------------------------------------------------*/
4811 /*----------------------------*/
4812 /* straight assignemnt */
4813 /*----------------------------*/
4815 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4816 printTypeChain(tree->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->left,outfile,indent+2);
4819 ast_print(tree->right,outfile,indent+2);
4821 /*------------------------------------------------------------------*/
4822 /*----------------------------*/
4823 /* comma operator */
4824 /*----------------------------*/
4826 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4827 printTypeChain(tree->ftype,outfile);
4828 fprintf(outfile,")\n");
4829 ast_print(tree->left,outfile,indent+2);
4830 ast_print(tree->right,outfile,indent+2);
4832 /*------------------------------------------------------------------*/
4833 /*----------------------------*/
4835 /*----------------------------*/
4838 fprintf(outfile,"CALL (%p) type (",tree);
4839 printTypeChain(tree->ftype,outfile);
4840 fprintf(outfile,")\n");
4841 ast_print(tree->left,outfile,indent+2);
4842 ast_print(tree->right,outfile,indent+2);
4845 fprintf(outfile,"PARMS\n");
4846 ast_print(tree->left,outfile,indent+2);
4847 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4848 ast_print(tree->right,outfile,indent+2);
4851 /*------------------------------------------------------------------*/
4852 /*----------------------------*/
4853 /* return statement */
4854 /*----------------------------*/
4856 fprintf(outfile,"RETURN (%p) type (",tree);
4857 printTypeChain(tree->right->ftype,outfile);
4858 fprintf(outfile,")\n");
4859 ast_print(tree->right,outfile,indent+2);
4861 /*------------------------------------------------------------------*/
4862 /*----------------------------*/
4863 /* label statement */
4864 /*----------------------------*/
4866 fprintf(outfile,"LABEL (%p)\n",tree);
4867 ast_print(tree->left,outfile,indent+2);
4868 ast_print(tree->right,outfile,indent);
4870 /*------------------------------------------------------------------*/
4871 /*----------------------------*/
4872 /* switch statement */
4873 /*----------------------------*/
4877 fprintf(outfile,"SWITCH (%p) ",tree);
4878 ast_print(tree->left,outfile,0);
4879 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4880 INDENT(indent+2,outfile);
4881 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4882 (int) floatFromVal(val),
4883 tree->values.switchVals.swNum,
4884 (int) floatFromVal(val));
4886 ast_print(tree->right,outfile,indent);
4889 /*------------------------------------------------------------------*/
4890 /*----------------------------*/
4892 /*----------------------------*/
4894 fprintf(outfile,"IF (%p) \n",tree);
4895 ast_print(tree->left,outfile,indent+2);
4896 if (tree->trueLabel) {
4897 INDENT(indent,outfile);
4898 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4900 if (tree->falseLabel) {
4901 INDENT(indent,outfile);
4902 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4904 ast_print(tree->right,outfile,indent+2);
4906 /*------------------------------------------------------------------*/
4907 /*----------------------------*/
4909 /*----------------------------*/
4911 fprintf(outfile,"FOR (%p) \n",tree);
4912 if (AST_FOR( tree, initExpr)) {
4913 INDENT(indent+2,outfile);
4914 fprintf(outfile,"INIT EXPR ");
4915 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4917 if (AST_FOR( tree, condExpr)) {
4918 INDENT(indent+2,outfile);
4919 fprintf(outfile,"COND EXPR ");
4920 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4922 if (AST_FOR( tree, loopExpr)) {
4923 INDENT(indent+2,outfile);
4924 fprintf(outfile,"LOOP EXPR ");
4925 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4927 fprintf(outfile,"FOR LOOP BODY \n");
4928 ast_print(tree->left,outfile,indent+2);
4937 ast_print(t,stdout,0);