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 ast *createIval (ast *, sym_link *, initList *, ast *);
52 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 /*-----------------------------------------------------------------*/
73 newAst (int type, void *op)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
87 /* depending on the type */
91 ex->opval.val = (value *) op;
94 ex->opval.op = (long) op;
97 ex->opval.lnk = (sym_link *) op;
100 ex->opval.stmnt = (unsigned) op;
108 newAst_ (unsigned type)
111 static int oldLineno = 0;
113 ex = Safe_alloc ( sizeof (ast));
116 ex->lineno = (noLineno ? oldLineno : yylineno);
117 ex->filename = currFname;
118 ex->level = NestLevel;
119 ex->block = currBlockno;
120 ex->initMode = inInitMode;
125 newAst_VALUE (value * val)
127 ast *ex = newAst_ (EX_VALUE);
133 newAst_OP (unsigned op)
135 ast *ex = newAst_ (EX_OP);
141 newAst_LINK (sym_link * val)
143 ast *ex = newAst_ (EX_LINK);
149 newAst_STMNT (unsigned val)
151 ast *ex = newAst_ (EX_STMNT);
152 ex->opval.stmnt = val;
156 /*-----------------------------------------------------------------*/
157 /* newNode - creates a new node */
158 /*-----------------------------------------------------------------*/
160 newNode (long op, ast * left, ast * right)
171 /*-----------------------------------------------------------------*/
172 /* newIfxNode - creates a new Ifx Node */
173 /*-----------------------------------------------------------------*/
175 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
179 /* if this is a literal then we already know the result */
180 if (condAst->etype && IS_LITERAL (condAst->etype))
182 /* then depending on the expression value */
183 if (floatFromVal (condAst->opval.val))
184 ifxNode = newNode (GOTO,
185 newAst_VALUE (symbolVal (trueLabel)),
188 ifxNode = newNode (GOTO,
189 newAst_VALUE (symbolVal (falseLabel)),
194 ifxNode = newNode (IFX, condAst, NULL);
195 ifxNode->trueLabel = trueLabel;
196 ifxNode->falseLabel = falseLabel;
202 /*-----------------------------------------------------------------*/
203 /* copyAstValues - copies value portion of ast if needed */
204 /*-----------------------------------------------------------------*/
206 copyAstValues (ast * dest, ast * src)
208 switch (src->opval.op)
211 dest->values.sym = copySymbolChain (src->values.sym);
215 dest->values.switchVals.swVals =
216 copyValue (src->values.switchVals.swVals);
217 dest->values.switchVals.swDefault =
218 src->values.switchVals.swDefault;
219 dest->values.switchVals.swNum =
220 src->values.switchVals.swNum;
224 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
225 strcpy (dest->values.inlineasm, src->values.inlineasm);
229 dest->values.constlist = copyLiteralList(src->values.constlist);
233 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
234 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
235 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
236 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
237 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
238 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
239 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
244 /*-----------------------------------------------------------------*/
245 /* copyAst - makes a copy of a given astession */
246 /*-----------------------------------------------------------------*/
255 dest = Safe_alloc ( sizeof (ast));
257 dest->type = src->type;
258 dest->lineno = src->lineno;
259 dest->level = src->level;
260 dest->funcName = src->funcName;
263 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
265 /* if this is a leaf */
267 if (src->type == EX_VALUE)
269 dest->opval.val = copyValue (src->opval.val);
274 if (src->type == EX_LINK)
276 dest->opval.lnk = copyLinkChain (src->opval.lnk);
280 dest->opval.op = src->opval.op;
282 /* if this is a node that has special values */
283 copyAstValues (dest, src);
285 dest->trueLabel = copySymbol (src->trueLabel);
286 dest->falseLabel = copySymbol (src->falseLabel);
287 dest->left = copyAst (src->left);
288 dest->right = copyAst (src->right);
294 /*-----------------------------------------------------------------*/
295 /* hasSEFcalls - returns TRUE if tree has a function call */
296 /*-----------------------------------------------------------------*/
298 hasSEFcalls (ast * tree)
303 if (tree->type == EX_OP &&
304 (tree->opval.op == CALL ||
305 tree->opval.op == PCALL ||
306 tree->opval.op == '=' ||
307 tree->opval.op == INC_OP ||
308 tree->opval.op == DEC_OP))
311 return (hasSEFcalls (tree->left) |
312 hasSEFcalls (tree->right));
315 /*-----------------------------------------------------------------*/
316 /* isAstEqual - compares two asts & returns 1 if they are equal */
317 /*-----------------------------------------------------------------*/
319 isAstEqual (ast * t1, ast * t2)
328 if (t1->type != t2->type)
334 if (t1->opval.op != t2->opval.op)
336 return (isAstEqual (t1->left, t2->left) &&
337 isAstEqual (t1->right, t2->right));
341 if (t1->opval.val->sym)
343 if (!t2->opval.val->sym)
346 return isSymbolEqual (t1->opval.val->sym,
351 if (t2->opval.val->sym)
354 return (floatFromVal (t1->opval.val) ==
355 floatFromVal (t2->opval.val));
359 /* only compare these two types */
367 /*-----------------------------------------------------------------*/
368 /* resolveSymbols - resolve symbols from the symbol table */
369 /*-----------------------------------------------------------------*/
371 resolveSymbols (ast * tree)
373 /* walk the entire tree and check for values */
374 /* with symbols if we find one then replace */
375 /* symbol with that from the symbol table */
381 /* if not block & function */
382 if (tree->type == EX_OP &&
383 (tree->opval.op != FUNCTION &&
384 tree->opval.op != BLOCK &&
385 tree->opval.op != NULLOP))
387 filename = tree->filename;
388 lineno = tree->lineno;
391 /* make sure we resolve the true & false labels for ifx */
392 if (tree->type == EX_OP && tree->opval.op == IFX)
398 if ((csym = findSym (LabelTab, tree->trueLabel,
399 tree->trueLabel->name)))
400 tree->trueLabel = csym;
402 werror (E_LABEL_UNDEF, tree->trueLabel->name);
405 if (tree->falseLabel)
407 if ((csym = findSym (LabelTab,
409 tree->falseLabel->name)))
410 tree->falseLabel = csym;
412 werror (E_LABEL_UNDEF, tree->falseLabel->name);
417 /* if this is a label resolve it from the labelTab */
418 if (IS_AST_VALUE (tree) &&
419 tree->opval.val->sym &&
420 tree->opval.val->sym->islbl)
423 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
424 tree->opval.val->sym->name);
427 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
429 tree->opval.val->sym = csym;
431 goto resolveChildren;
434 /* do only for leafs */
435 if (IS_AST_VALUE (tree) &&
436 tree->opval.val->sym &&
437 !tree->opval.val->sym->implicit)
440 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
442 /* if found in the symbol table & they r not the same */
443 if (csym && tree->opval.val->sym != csym)
445 tree->opval.val->sym = csym;
446 tree->opval.val->type = csym->type;
447 tree->opval.val->etype = csym->etype;
450 /* if not found in the symbol table */
451 /* mark it as undefined assume it is */
452 /* an integer in data space */
453 if (!csym && !tree->opval.val->sym->implicit)
456 /* if this is a function name then */
457 /* mark it as returning an int */
460 tree->opval.val->sym->type = newLink ();
461 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
462 tree->opval.val->sym->type->next =
463 tree->opval.val->sym->etype = newIntLink ();
464 tree->opval.val->etype = tree->opval.val->etype;
465 tree->opval.val->type = tree->opval.val->sym->type;
466 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
467 allocVariables (tree->opval.val->sym);
471 tree->opval.val->sym->undefined = 1;
472 tree->opval.val->type =
473 tree->opval.val->etype = newIntLink ();
474 tree->opval.val->sym->type =
475 tree->opval.val->sym->etype = newIntLink ();
481 resolveSymbols (tree->left);
482 resolveSymbols (tree->right);
487 /*-----------------------------------------------------------------*/
488 /* setAstLineno - walks a ast tree & sets the line number */
489 /*-----------------------------------------------------------------*/
491 setAstLineno (ast * tree, int lineno)
496 tree->lineno = lineno;
497 setAstLineno (tree->left, lineno);
498 setAstLineno (tree->right, lineno);
503 /* this functions seems to be superfluous?! kmh */
505 /*-----------------------------------------------------------------*/
506 /* resolveFromTable - will return the symbal table value */
507 /*-----------------------------------------------------------------*/
509 resolveFromTable (value * val)
516 csym = findSymWithLevel (SymbolTab, val->sym);
518 /* if found in the symbol table & they r not the same */
519 if (csym && val->sym != csym &&
520 csym->level == val->sym->level &&
526 val->type = csym->type;
527 val->etype = csym->etype;
534 /*-----------------------------------------------------------------*/
535 /* funcOfType :- function of type with name */
536 /*-----------------------------------------------------------------*/
538 funcOfType (char *name, sym_link * type, sym_link * argType,
542 /* create the symbol */
543 sym = newSymbol (name, 0);
545 /* setup return value */
546 sym->type = newLink ();
547 DCL_TYPE (sym->type) = FUNCTION;
548 sym->type->next = copyLinkChain (type);
549 sym->etype = getSpec (sym->type);
550 FUNC_ISREENT(sym->type) = rent;
552 /* if arguments required */
556 args = FUNC_ARGS(sym->type) = newValue ();
560 args->type = copyLinkChain (argType);
561 args->etype = getSpec (args->type);
562 SPEC_EXTR(args->etype)=1;
565 args = args->next = newValue ();
572 allocVariables (sym);
577 /*-----------------------------------------------------------------*/
578 /* funcOfTypeVarg :- function of type with name and argtype */
579 /*-----------------------------------------------------------------*/
581 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
586 /* create the symbol */
587 sym = newSymbol (name, 0);
589 /* setup return value */
590 sym->type = newLink ();
591 DCL_TYPE (sym->type) = FUNCTION;
592 sym->type->next = typeFromStr(rtype);
593 sym->etype = getSpec (sym->type);
595 /* if arguments required */
598 args = FUNC_ARGS(sym->type) = newValue ();
600 for ( i = 0 ; i < nArgs ; i++ ) {
601 args->type = typeFromStr(atypes[i]);
602 args->etype = getSpec (args->type);
603 SPEC_EXTR(args->etype)=1;
604 if ((i + 1) == nArgs) break;
605 args = args->next = newValue ();
612 allocVariables (sym);
617 /*-----------------------------------------------------------------*/
618 /* reverseParms - will reverse a parameter tree */
619 /*-----------------------------------------------------------------*/
621 reverseParms (ast * ptree)
627 /* top down if we find a nonParm tree then quit */
628 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
631 ptree->left = ptree->right;
632 ptree->right = ttree;
633 reverseParms (ptree->left);
634 reverseParms (ptree->right);
640 /*-----------------------------------------------------------------*/
641 /* processParms - makes sure the parameters are okay and do some */
642 /* processing with them */
643 /*-----------------------------------------------------------------*/
645 processParms (ast * func,
648 int *parmNumber, // unused, although updated
651 /* if none of them exist */
652 if (!defParm && !actParm)
656 if (getenv("DEBUG_SANITY")) {
657 fprintf (stderr, "processParms: %s ", defParm->name);
659 /* make sure the type is complete and sane */
660 checkTypeSanity(defParm->etype, defParm->name);
663 /* if the function is being called via a pointer & */
664 /* it has not been defined a reentrant then we cannot */
665 /* have parameters */
666 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
668 werror (W_NONRENT_ARGS);
672 /* if defined parameters ended but actual parameters */
673 /* exist and this is not defined as a variable arg */
674 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
676 werror (E_TOO_MANY_PARMS);
680 /* if defined parameters present but no actual parameters */
681 if (defParm && !actParm)
683 werror (E_TOO_FEW_PARMS);
687 if (IS_VOID(actParm->ftype)) {
688 werror (E_VOID_VALUE_USED);
692 /* If this is a varargs function... */
693 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
698 if (IS_CAST_OP (actParm)
699 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
701 /* Parameter was explicitly typecast; don't touch it. */
705 ftype = actParm->ftype;
707 /* If it's a small integer, upcast to int. */
708 if (IS_INTEGRAL (ftype)
709 && (getSize (ftype) < (unsigned) INTSIZE))
711 newType = newAst_LINK(INTTYPE);
714 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
716 newType = newAst_LINK (copyLinkChain(ftype));
717 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
720 if (IS_AGGREGATE (ftype))
722 newType = newAst_LINK (copyLinkChain (ftype));
723 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
727 /* cast required; change this op to a cast. */
728 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
730 actParm->type = EX_OP;
731 actParm->opval.op = CAST;
732 actParm->left = newType;
733 actParm->right = parmCopy;
734 decorateType (actParm);
736 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
738 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
739 processParms (func, NULL, actParm->right, parmNumber, rightmost));
744 /* if defined parameters ended but actual has not & */
746 if (!defParm && actParm &&
747 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
750 resolveSymbols (actParm);
751 /* if this is a PARAM node then match left & right */
752 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
754 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
755 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
759 /* If we have found a value node by following only right-hand links,
760 * then we know that there are no more values after us.
762 * Therefore, if there are more defined parameters, the caller didn't
765 if (rightmost && defParm->next)
767 werror (E_TOO_FEW_PARMS);
772 /* the parameter type must be at least castable */
773 if (compareType (defParm->type, actParm->ftype) == 0) {
774 werror (E_INCOMPAT_TYPES);
775 printFromToType (actParm->ftype, defParm->type);
779 /* if the parameter is castable then add the cast */
780 if (compareType (defParm->type, actParm->ftype) < 0)
782 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
784 /* now change the current one to a cast */
785 actParm->type = EX_OP;
786 actParm->opval.op = CAST;
787 actParm->left = newAst_LINK (defParm->type);
788 actParm->right = pTree;
789 actParm->etype = defParm->etype;
790 actParm->ftype = defParm->type;
791 actParm->decorated=0; /* force typechecking */
792 decorateType (actParm);
795 /* make a copy and change the regparm type to the defined parm */
796 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
797 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
801 /*-----------------------------------------------------------------*/
802 /* createIvalType - generates ival for basic types */
803 /*-----------------------------------------------------------------*/
805 createIvalType (ast * sym, sym_link * type, initList * ilist)
809 /* if initList is deep */
810 if (ilist->type == INIT_DEEP)
811 ilist = ilist->init.deep;
813 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
814 return decorateType (newNode ('=', sym, iExpr));
817 /*-----------------------------------------------------------------*/
818 /* createIvalStruct - generates initial value for structures */
819 /*-----------------------------------------------------------------*/
821 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
828 sflds = SPEC_STRUCT (type)->fields;
829 if (ilist->type != INIT_DEEP)
831 werror (E_INIT_STRUCT, "");
835 iloop = ilist->init.deep;
837 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
839 /* if we have come to end */
843 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
844 lAst = decorateType (resolveSymbols (lAst));
845 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
849 werror (W_EXCESS_INITIALIZERS, "struct",
850 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
857 /*-----------------------------------------------------------------*/
858 /* createIvalArray - generates code for array initialization */
859 /*-----------------------------------------------------------------*/
861 createIvalArray (ast * sym, sym_link * type, initList * ilist)
865 int lcnt = 0, size = 0;
866 literalList *literalL;
868 /* take care of the special case */
869 /* array of characters can be init */
871 if (IS_CHAR (type->next))
872 if ((rast = createIvalCharPtr (sym,
874 decorateType (resolveSymbols (list2expr (ilist))))))
876 return decorateType (resolveSymbols (rast));
878 /* not the special case */
879 if (ilist->type != INIT_DEEP)
881 werror (E_INIT_STRUCT, "");
885 iloop = ilist->init.deep;
886 lcnt = DCL_ELEM (type);
888 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
892 aSym = decorateType (resolveSymbols(sym));
894 rast = newNode(ARRAYINIT, aSym, NULL);
895 rast->values.constlist = literalL;
897 // Make sure size is set to length of initializer list.
904 if (lcnt && size > lcnt)
906 // Array size was specified, and we have more initializers than needed.
907 char *name=sym->opval.val->sym->name;
908 int lineno=sym->opval.val->sym->lineDef;
910 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
919 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
920 aSym = decorateType (resolveSymbols (aSym));
921 rast = createIval (aSym, type->next, iloop, rast);
922 iloop = (iloop ? iloop->next : NULL);
928 /* no of elements given and we */
929 /* have generated for all of them */
932 // there has to be a better way
933 char *name=sym->opval.val->sym->name;
934 int lineno=sym->opval.val->sym->lineDef;
935 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
942 /* if we have not been given a size */
943 if (!DCL_ELEM (type))
945 DCL_ELEM (type) = size;
948 return decorateType (resolveSymbols (rast));
952 /*-----------------------------------------------------------------*/
953 /* createIvalCharPtr - generates initial values for char pointers */
954 /*-----------------------------------------------------------------*/
956 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
960 /* if this is a pointer & right is a literal array then */
961 /* just assignment will do */
962 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
963 SPEC_SCLS (iexpr->etype) == S_CODE)
964 && IS_ARRAY (iexpr->ftype)))
965 return newNode ('=', sym, iexpr);
967 /* left side is an array so we have to assign each */
969 if ((IS_LITERAL (iexpr->etype) ||
970 SPEC_SCLS (iexpr->etype) == S_CODE)
971 && IS_ARRAY (iexpr->ftype))
973 /* for each character generate an assignment */
974 /* to the array element */
975 char *s = SPEC_CVAL (iexpr->etype).v_char;
980 rast = newNode (NULLOP,
984 newAst_VALUE (valueFromLit ((float) i))),
985 newAst_VALUE (valueFromLit (*s))));
989 rast = newNode (NULLOP,
993 newAst_VALUE (valueFromLit ((float) i))),
994 newAst_VALUE (valueFromLit (*s))));
995 return decorateType (resolveSymbols (rast));
1001 /*-----------------------------------------------------------------*/
1002 /* createIvalPtr - generates initial value for pointers */
1003 /*-----------------------------------------------------------------*/
1005 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1011 if (ilist->type == INIT_DEEP)
1012 ilist = ilist->init.deep;
1014 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1016 /* if character pointer */
1017 if (IS_CHAR (type->next))
1018 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1021 return newNode ('=', sym, iexpr);
1024 /*-----------------------------------------------------------------*/
1025 /* createIval - generates code for initial value */
1026 /*-----------------------------------------------------------------*/
1028 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1035 /* if structure then */
1036 if (IS_STRUCT (type))
1037 rast = createIvalStruct (sym, type, ilist);
1039 /* if this is a pointer */
1041 rast = createIvalPtr (sym, type, ilist);
1043 /* if this is an array */
1044 if (IS_ARRAY (type))
1045 rast = createIvalArray (sym, type, ilist);
1047 /* if type is SPECIFIER */
1049 rast = createIvalType (sym, type, ilist);
1052 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1054 return decorateType (resolveSymbols (rast));
1057 /*-----------------------------------------------------------------*/
1058 /* initAggregates - initialises aggregate variables with initv */
1059 /*-----------------------------------------------------------------*/
1060 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1061 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1064 /*-----------------------------------------------------------------*/
1065 /* gatherAutoInit - creates assignment expressions for initial */
1067 /*-----------------------------------------------------------------*/
1069 gatherAutoInit (symbol * autoChain)
1076 for (sym = autoChain; sym; sym = sym->next)
1079 /* resolve the symbols in the ival */
1081 resolveIvalSym (sym->ival);
1083 /* if this is a static variable & has an */
1084 /* initial value the code needs to be lifted */
1085 /* here to the main portion since they can be */
1086 /* initialised only once at the start */
1087 if (IS_STATIC (sym->etype) && sym->ival &&
1088 SPEC_SCLS (sym->etype) != S_CODE)
1092 /* insert the symbol into the symbol table */
1093 /* with level = 0 & name = rname */
1094 newSym = copySymbol (sym);
1095 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1097 /* now lift the code to main */
1098 if (IS_AGGREGATE (sym->type)) {
1099 work = initAggregates (sym, sym->ival, NULL);
1101 if (getNelements(sym->type, sym->ival)>1) {
1102 werror (W_EXCESS_INITIALIZERS, "scalar",
1103 sym->name, sym->lineDef);
1105 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1106 list2expr (sym->ival));
1109 setAstLineno (work, sym->lineDef);
1113 staticAutos = newNode (NULLOP, staticAutos, work);
1120 /* if there is an initial value */
1121 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1123 if (IS_AGGREGATE (sym->type)) {
1124 work = initAggregates (sym, sym->ival, NULL);
1126 if (getNelements(sym->type, sym->ival)>1) {
1127 werror (W_EXCESS_INITIALIZERS, "scalar",
1128 sym->name, sym->lineDef);
1130 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1131 list2expr (sym->ival));
1134 setAstLineno (work, sym->lineDef);
1137 init = newNode (NULLOP, init, work);
1146 /*-----------------------------------------------------------------*/
1147 /* stringToSymbol - creates a symbol from a literal string */
1148 /*-----------------------------------------------------------------*/
1150 stringToSymbol (value * val)
1152 char name[SDCC_NAME_MAX + 1];
1153 static int charLbl = 0;
1156 sprintf (name, "_str_%d", charLbl++);
1157 sym = newSymbol (name, 0); /* make it @ level 0 */
1158 strcpy (sym->rname, name);
1160 /* copy the type from the value passed */
1161 sym->type = copyLinkChain (val->type);
1162 sym->etype = getSpec (sym->type);
1163 /* change to storage class & output class */
1164 SPEC_SCLS (sym->etype) = S_CODE;
1165 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1166 SPEC_STAT (sym->etype) = 1;
1167 /* make the level & block = 0 */
1168 sym->block = sym->level = 0;
1170 /* create an ival */
1171 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1176 allocVariables (sym);
1179 return symbolVal (sym);
1183 /*-----------------------------------------------------------------*/
1184 /* processBlockVars - will go thru the ast looking for block if */
1185 /* a block is found then will allocate the syms */
1186 /* will also gather the auto inits present */
1187 /*-----------------------------------------------------------------*/
1189 processBlockVars (ast * tree, int *stack, int action)
1194 /* if this is a block */
1195 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1199 if (action == ALLOCATE)
1201 *stack += allocVariables (tree->values.sym);
1202 autoInit = gatherAutoInit (tree->values.sym);
1204 /* if there are auto inits then do them */
1206 tree->left = newNode (NULLOP, autoInit, tree->left);
1208 else /* action is deallocate */
1209 deallocLocal (tree->values.sym);
1212 processBlockVars (tree->left, stack, action);
1213 processBlockVars (tree->right, stack, action);
1217 /*-----------------------------------------------------------------*/
1218 /* constExprValue - returns the value of a constant expression */
1219 /* or NULL if it is not a constant expression */
1220 /*-----------------------------------------------------------------*/
1222 constExprValue (ast * cexpr, int check)
1224 cexpr = decorateType (resolveSymbols (cexpr));
1226 /* if this is not a constant then */
1227 if (!IS_LITERAL (cexpr->ftype))
1229 /* then check if this is a literal array
1231 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1232 SPEC_CVAL (cexpr->etype).v_char &&
1233 IS_ARRAY (cexpr->ftype))
1235 value *val = valFromType (cexpr->ftype);
1236 SPEC_SCLS (val->etype) = S_LITERAL;
1237 val->sym = cexpr->opval.val->sym;
1238 val->sym->type = copyLinkChain (cexpr->ftype);
1239 val->sym->etype = getSpec (val->sym->type);
1240 strcpy (val->name, cexpr->opval.val->sym->rname);
1244 /* if we are casting a literal value then */
1245 if (IS_AST_OP (cexpr) &&
1246 cexpr->opval.op == CAST &&
1247 IS_LITERAL (cexpr->left->ftype))
1248 return valCastLiteral (cexpr->ftype,
1249 floatFromVal (cexpr->left->opval.val));
1251 if (IS_AST_VALUE (cexpr))
1252 return cexpr->opval.val;
1255 werror (E_CONST_EXPECTED, "found expression");
1260 /* return the value */
1261 return cexpr->opval.val;
1265 /*-----------------------------------------------------------------*/
1266 /* isLabelInAst - will return true if a given label is found */
1267 /*-----------------------------------------------------------------*/
1269 isLabelInAst (symbol * label, ast * tree)
1271 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1274 if (IS_AST_OP (tree) &&
1275 tree->opval.op == LABEL &&
1276 isSymbolEqual (AST_SYMBOL (tree->left), label))
1279 return isLabelInAst (label, tree->right) &&
1280 isLabelInAst (label, tree->left);
1284 /*-----------------------------------------------------------------*/
1285 /* isLoopCountable - return true if the loop count can be determi- */
1286 /* -ned at compile time . */
1287 /*-----------------------------------------------------------------*/
1289 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1290 symbol ** sym, ast ** init, ast ** end)
1293 /* the loop is considered countable if the following
1294 conditions are true :-
1296 a) initExpr :- <sym> = <const>
1297 b) condExpr :- <sym> < <const1>
1298 c) loopExpr :- <sym> ++
1301 /* first check the initExpr */
1302 if (IS_AST_OP (initExpr) &&
1303 initExpr->opval.op == '=' && /* is assignment */
1304 IS_AST_SYM_VALUE (initExpr->left))
1305 { /* left is a symbol */
1307 *sym = AST_SYMBOL (initExpr->left);
1308 *init = initExpr->right;
1313 /* for now the symbol has to be of
1315 if (!IS_INTEGRAL ((*sym)->type))
1318 /* now check condExpr */
1319 if (IS_AST_OP (condExpr))
1322 switch (condExpr->opval.op)
1325 if (IS_AST_SYM_VALUE (condExpr->left) &&
1326 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1327 IS_AST_LIT_VALUE (condExpr->right))
1329 *end = condExpr->right;
1335 if (IS_AST_OP (condExpr->left) &&
1336 condExpr->left->opval.op == '>' &&
1337 IS_AST_LIT_VALUE (condExpr->left->right) &&
1338 IS_AST_SYM_VALUE (condExpr->left->left) &&
1339 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1342 *end = newNode ('+', condExpr->left->right,
1343 newAst_VALUE (constVal ("1")));
1354 /* check loop expression is of the form <sym>++ */
1355 if (!IS_AST_OP (loopExpr))
1358 /* check if <sym> ++ */
1359 if (loopExpr->opval.op == INC_OP)
1365 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1366 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1373 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1374 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1382 if (loopExpr->opval.op == ADD_ASSIGN)
1385 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1386 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1387 IS_AST_LIT_VALUE (loopExpr->right) &&
1388 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1396 /*-----------------------------------------------------------------*/
1397 /* astHasVolatile - returns true if ast contains any volatile */
1398 /*-----------------------------------------------------------------*/
1400 astHasVolatile (ast * tree)
1405 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1408 if (IS_AST_OP (tree))
1409 return astHasVolatile (tree->left) ||
1410 astHasVolatile (tree->right);
1415 /*-----------------------------------------------------------------*/
1416 /* astHasPointer - return true if the ast contains any ptr variable */
1417 /*-----------------------------------------------------------------*/
1419 astHasPointer (ast * tree)
1424 if (IS_AST_LINK (tree))
1427 /* if we hit an array expression then check
1428 only the left side */
1429 if (IS_AST_OP (tree) && tree->opval.op == '[')
1430 return astHasPointer (tree->left);
1432 if (IS_AST_VALUE (tree))
1433 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1435 return astHasPointer (tree->left) ||
1436 astHasPointer (tree->right);
1440 /*-----------------------------------------------------------------*/
1441 /* astHasSymbol - return true if the ast has the given symbol */
1442 /*-----------------------------------------------------------------*/
1444 astHasSymbol (ast * tree, symbol * sym)
1446 if (!tree || IS_AST_LINK (tree))
1449 if (IS_AST_VALUE (tree))
1451 if (IS_AST_SYM_VALUE (tree))
1452 return isSymbolEqual (AST_SYMBOL (tree), sym);
1457 return astHasSymbol (tree->left, sym) ||
1458 astHasSymbol (tree->right, sym);
1461 /*-----------------------------------------------------------------*/
1462 /* astHasDeref - return true if the ast has an indirect access */
1463 /*-----------------------------------------------------------------*/
1465 astHasDeref (ast * tree)
1467 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1470 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1472 return astHasDeref (tree->left) || astHasDeref (tree->right);
1475 /*-----------------------------------------------------------------*/
1476 /* isConformingBody - the loop body has to conform to a set of rules */
1477 /* for the loop to be considered reversible read on for rules */
1478 /*-----------------------------------------------------------------*/
1480 isConformingBody (ast * pbody, symbol * sym, ast * body)
1483 /* we are going to do a pre-order traversal of the
1484 tree && check for the following conditions. (essentially
1485 a set of very shallow tests )
1486 a) the sym passed does not participate in
1487 any arithmetic operation
1488 b) There are no function calls
1489 c) all jumps are within the body
1490 d) address of loop control variable not taken
1491 e) if an assignment has a pointer on the
1492 left hand side make sure right does not have
1493 loop control variable */
1495 /* if we reach the end or a leaf then true */
1496 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1500 /* if anything else is "volatile" */
1501 if (IS_VOLATILE (TETYPE (pbody)))
1504 /* we will walk the body in a pre-order traversal for
1506 switch (pbody->opval.op)
1508 /*------------------------------------------------------------------*/
1510 return isConformingBody (pbody->right, sym, body);
1512 /*------------------------------------------------------------------*/
1517 /*------------------------------------------------------------------*/
1518 case INC_OP: /* incerement operator unary so left only */
1521 /* sure we are not sym is not modified */
1523 IS_AST_SYM_VALUE (pbody->left) &&
1524 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1528 IS_AST_SYM_VALUE (pbody->right) &&
1529 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1534 /*------------------------------------------------------------------*/
1536 case '*': /* can be unary : if right is null then unary operation */
1541 /* if right is NULL then unary operation */
1542 /*------------------------------------------------------------------*/
1543 /*----------------------------*/
1545 /*----------------------------*/
1548 if (IS_AST_SYM_VALUE (pbody->left) &&
1549 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1552 return isConformingBody (pbody->left, sym, body);
1556 if (astHasSymbol (pbody->left, sym) ||
1557 astHasSymbol (pbody->right, sym))
1562 /*------------------------------------------------------------------*/
1570 if (IS_AST_SYM_VALUE (pbody->left) &&
1571 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1574 if (IS_AST_SYM_VALUE (pbody->right) &&
1575 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1578 return isConformingBody (pbody->left, sym, body) &&
1579 isConformingBody (pbody->right, sym, body);
1586 if (IS_AST_SYM_VALUE (pbody->left) &&
1587 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1589 return isConformingBody (pbody->left, sym, body);
1591 /*------------------------------------------------------------------*/
1603 case SIZEOF: /* evaluate wihout code generation */
1605 return isConformingBody (pbody->left, sym, body) &&
1606 isConformingBody (pbody->right, sym, body);
1608 /*------------------------------------------------------------------*/
1611 /* if left has a pointer & right has loop
1612 control variable then we cannot */
1613 if (astHasPointer (pbody->left) &&
1614 astHasSymbol (pbody->right, sym))
1616 if (astHasVolatile (pbody->left))
1619 if (IS_AST_SYM_VALUE (pbody->left) &&
1620 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1623 if (astHasVolatile (pbody->left))
1626 if (astHasDeref(pbody->right)) return FALSE;
1628 return isConformingBody (pbody->left, sym, body) &&
1629 isConformingBody (pbody->right, sym, body);
1640 assert ("Parser should not have generated this\n");
1642 /*------------------------------------------------------------------*/
1643 /*----------------------------*/
1644 /* comma operator */
1645 /*----------------------------*/
1647 return isConformingBody (pbody->left, sym, body) &&
1648 isConformingBody (pbody->right, sym, body);
1650 /*------------------------------------------------------------------*/
1651 /*----------------------------*/
1653 /*----------------------------*/
1657 /*------------------------------------------------------------------*/
1658 /*----------------------------*/
1659 /* return statement */
1660 /*----------------------------*/
1665 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1670 if (astHasSymbol (pbody->left, sym))
1677 return isConformingBody (pbody->left, sym, body) &&
1678 isConformingBody (pbody->right, sym, body);
1684 /*-----------------------------------------------------------------*/
1685 /* isLoopReversible - takes a for loop as input && returns true */
1686 /* if the for loop is reversible. If yes will set the value of */
1687 /* the loop control var & init value & termination value */
1688 /*-----------------------------------------------------------------*/
1690 isLoopReversible (ast * loop, symbol ** loopCntrl,
1691 ast ** init, ast ** end)
1693 /* if option says don't do it then don't */
1694 if (optimize.noLoopReverse)
1696 /* there are several tests to determine this */
1698 /* for loop has to be of the form
1699 for ( <sym> = <const1> ;
1700 [<sym> < <const2>] ;
1701 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1703 if (!isLoopCountable (AST_FOR (loop, initExpr),
1704 AST_FOR (loop, condExpr),
1705 AST_FOR (loop, loopExpr),
1706 loopCntrl, init, end))
1709 /* now do some serious checking on the body of the loop
1712 return isConformingBody (loop->left, *loopCntrl, loop->left);
1716 /*-----------------------------------------------------------------*/
1717 /* replLoopSym - replace the loop sym by loop sym -1 */
1718 /*-----------------------------------------------------------------*/
1720 replLoopSym (ast * body, symbol * sym)
1723 if (!body || IS_AST_LINK (body))
1726 if (IS_AST_SYM_VALUE (body))
1729 if (isSymbolEqual (AST_SYMBOL (body), sym))
1733 body->opval.op = '-';
1734 body->left = newAst_VALUE (symbolVal (sym));
1735 body->right = newAst_VALUE (constVal ("1"));
1743 replLoopSym (body->left, sym);
1744 replLoopSym (body->right, sym);
1748 /*-----------------------------------------------------------------*/
1749 /* reverseLoop - do the actual loop reversal */
1750 /*-----------------------------------------------------------------*/
1752 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1756 /* create the following tree
1761 if (sym) goto for_continue ;
1764 /* put it together piece by piece */
1765 rloop = newNode (NULLOP,
1766 createIf (newAst_VALUE (symbolVal (sym)),
1768 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1771 newAst_VALUE (symbolVal (sym)),
1774 replLoopSym (loop->left, sym);
1776 rloop = newNode (NULLOP,
1778 newAst_VALUE (symbolVal (sym)),
1779 newNode ('-', end, init)),
1780 createLabel (AST_FOR (loop, continueLabel),
1784 newNode (SUB_ASSIGN,
1785 newAst_VALUE (symbolVal (sym)),
1786 newAst_VALUE (constVal ("1"))),
1789 return decorateType (rloop);
1793 /*-----------------------------------------------------------------*/
1794 /* decorateType - compute type for this tree also does type cheking */
1795 /* this is done bottom up, since type have to flow upwards */
1796 /* it also does constant folding, and paramater checking */
1797 /*-----------------------------------------------------------------*/
1799 decorateType (ast * tree)
1807 /* if already has type then do nothing */
1808 if (tree->decorated)
1811 tree->decorated = 1;
1813 /* print the line */
1814 /* if not block & function */
1815 if (tree->type == EX_OP &&
1816 (tree->opval.op != FUNCTION &&
1817 tree->opval.op != BLOCK &&
1818 tree->opval.op != NULLOP))
1820 filename = tree->filename;
1821 lineno = tree->lineno;
1824 /* if any child is an error | this one is an error do nothing */
1825 if (tree->isError ||
1826 (tree->left && tree->left->isError) ||
1827 (tree->right && tree->right->isError))
1830 /*------------------------------------------------------------------*/
1831 /*----------------------------*/
1832 /* leaf has been reached */
1833 /*----------------------------*/
1834 /* if this is of type value */
1835 /* just get the type */
1836 if (tree->type == EX_VALUE)
1839 if (IS_LITERAL (tree->opval.val->etype))
1842 /* if this is a character array then declare it */
1843 if (IS_ARRAY (tree->opval.val->type))
1844 tree->opval.val = stringToSymbol (tree->opval.val);
1846 /* otherwise just copy the type information */
1847 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1851 if (tree->opval.val->sym)
1853 /* if the undefined flag is set then give error message */
1854 if (tree->opval.val->sym->undefined)
1856 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1858 TTYPE (tree) = TETYPE (tree) =
1859 tree->opval.val->type = tree->opval.val->sym->type =
1860 tree->opval.val->etype = tree->opval.val->sym->etype =
1861 copyLinkChain (INTTYPE);
1866 /* if impilicit i.e. struct/union member then no type */
1867 if (tree->opval.val->sym->implicit)
1868 TTYPE (tree) = TETYPE (tree) = NULL;
1873 /* else copy the type */
1874 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1876 /* and mark it as referenced */
1877 tree->opval.val->sym->isref = 1;
1885 /* if type link for the case of cast */
1886 if (tree->type == EX_LINK)
1888 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1895 dtl = decorateType (tree->left);
1896 /* delay right side for '?' operator since conditional macro expansions might
1898 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1900 /* this is to take care of situations
1901 when the tree gets rewritten */
1902 if (dtl != tree->left)
1904 if (dtr != tree->right)
1908 /* depending on type of operator do */
1910 switch (tree->opval.op)
1912 /*------------------------------------------------------------------*/
1913 /*----------------------------*/
1915 /*----------------------------*/
1918 /* determine which is the array & which the index */
1919 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1922 ast *tempTree = tree->left;
1923 tree->left = tree->right;
1924 tree->right = tempTree;
1927 /* first check if this is a array or a pointer */
1928 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1930 werror (E_NEED_ARRAY_PTR, "[]");
1931 goto errorTreeReturn;
1934 /* check if the type of the idx */
1935 if (!IS_INTEGRAL (RTYPE (tree)))
1937 werror (E_IDX_NOT_INT);
1938 goto errorTreeReturn;
1941 /* if the left is an rvalue then error */
1944 werror (E_LVALUE_REQUIRED, "array access");
1945 goto errorTreeReturn;
1948 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1949 if (IS_PTR(LTYPE(tree))) {
1950 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1954 /*------------------------------------------------------------------*/
1955 /*----------------------------*/
1957 /*----------------------------*/
1959 /* if this is not a structure */
1960 if (!IS_STRUCT (LTYPE (tree)))
1962 werror (E_STRUCT_UNION, ".");
1963 goto errorTreeReturn;
1965 TTYPE (tree) = structElemType (LTYPE (tree),
1966 (tree->right->type == EX_VALUE ?
1967 tree->right->opval.val : NULL));
1968 TETYPE (tree) = getSpec (TTYPE (tree));
1971 /*------------------------------------------------------------------*/
1972 /*----------------------------*/
1973 /* struct/union pointer */
1974 /*----------------------------*/
1976 /* if not pointer to a structure */
1977 if (!IS_PTR (LTYPE (tree)))
1979 werror (E_PTR_REQD);
1980 goto errorTreeReturn;
1983 if (!IS_STRUCT (LTYPE (tree)->next))
1985 werror (E_STRUCT_UNION, "->");
1986 goto errorTreeReturn;
1989 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1990 (tree->right->type == EX_VALUE ?
1991 tree->right->opval.val : NULL));
1992 TETYPE (tree) = getSpec (TTYPE (tree));
1994 /* adjust the storage class */
1995 switch (DCL_TYPE(tree->left->ftype)) {
1999 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2002 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2007 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2010 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2013 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2022 /*------------------------------------------------------------------*/
2023 /*----------------------------*/
2024 /* ++/-- operation */
2025 /*----------------------------*/
2026 case INC_OP: /* incerement operator unary so left only */
2029 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2030 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2031 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2032 werror (E_CODE_WRITE, "++/--");
2041 /*------------------------------------------------------------------*/
2042 /*----------------------------*/
2044 /*----------------------------*/
2045 case '&': /* can be unary */
2046 /* if right is NULL then unary operation */
2047 if (tree->right) /* not an unary operation */
2050 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2052 werror (E_BITWISE_OP);
2053 werror (W_CONTINUE, "left & right types are ");
2054 printTypeChain (LTYPE (tree), stderr);
2055 fprintf (stderr, ",");
2056 printTypeChain (RTYPE (tree), stderr);
2057 fprintf (stderr, "\n");
2058 goto errorTreeReturn;
2061 /* if they are both literal */
2062 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2064 tree->type = EX_VALUE;
2065 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2066 valFromType (RETYPE (tree)), '&');
2068 tree->right = tree->left = NULL;
2069 TETYPE (tree) = tree->opval.val->etype;
2070 TTYPE (tree) = tree->opval.val->type;
2074 /* see if this is a GETHBIT operation if yes
2077 ast *otree = optimizeGetHbit (tree);
2080 return decorateType (otree);
2084 computeType (LTYPE (tree), RTYPE (tree));
2085 TETYPE (tree) = getSpec (TTYPE (tree));
2087 LRVAL (tree) = RRVAL (tree) = 1;
2091 /*------------------------------------------------------------------*/
2092 /*----------------------------*/
2094 /*----------------------------*/
2096 p->class = DECLARATOR;
2097 /* if bit field then error */
2098 if (IS_BITVAR (tree->left->etype))
2100 werror (E_ILLEGAL_ADDR, "address of bit variable");
2101 goto errorTreeReturn;
2104 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2106 werror (E_ILLEGAL_ADDR, "address of register variable");
2107 goto errorTreeReturn;
2110 if (IS_FUNC (LTYPE (tree)))
2112 werror (E_ILLEGAL_ADDR, "address of function");
2113 goto errorTreeReturn;
2116 if (IS_LITERAL(LTYPE(tree)))
2118 werror (E_ILLEGAL_ADDR, "address of literal");
2119 goto errorTreeReturn;
2124 werror (E_LVALUE_REQUIRED, "address of");
2125 goto errorTreeReturn;
2127 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2129 DCL_TYPE (p) = CPOINTER;
2130 DCL_PTR_CONST (p) = port->mem.code_ro;
2132 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2133 DCL_TYPE (p) = FPOINTER;
2134 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2135 DCL_TYPE (p) = PPOINTER;
2136 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2137 DCL_TYPE (p) = IPOINTER;
2138 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2139 DCL_TYPE (p) = EEPPOINTER;
2140 else if (SPEC_OCLS(tree->left->etype))
2141 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2143 DCL_TYPE (p) = POINTER;
2145 if (IS_AST_SYM_VALUE (tree->left))
2147 AST_SYMBOL (tree->left)->addrtaken = 1;
2148 AST_SYMBOL (tree->left)->allocreq = 1;
2151 p->next = LTYPE (tree);
2153 TETYPE (tree) = getSpec (TTYPE (tree));
2154 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2155 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2160 /*------------------------------------------------------------------*/
2161 /*----------------------------*/
2163 /*----------------------------*/
2165 /* if the rewrite succeeds then don't go any furthur */
2167 ast *wtree = optimizeRRCRLC (tree);
2169 return decorateType (wtree);
2171 /*------------------------------------------------------------------*/
2172 /*----------------------------*/
2174 /*----------------------------*/
2176 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2178 werror (E_BITWISE_OP);
2179 werror (W_CONTINUE, "left & right types are ");
2180 printTypeChain (LTYPE (tree), stderr);
2181 fprintf (stderr, ",");
2182 printTypeChain (RTYPE (tree), stderr);
2183 fprintf (stderr, "\n");
2184 goto errorTreeReturn;
2187 /* if they are both literal then */
2188 /* rewrite the tree */
2189 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2191 tree->type = EX_VALUE;
2192 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2193 valFromType (RETYPE (tree)),
2195 tree->right = tree->left = NULL;
2196 TETYPE (tree) = tree->opval.val->etype;
2197 TTYPE (tree) = tree->opval.val->type;
2200 LRVAL (tree) = RRVAL (tree) = 1;
2201 TETYPE (tree) = getSpec (TTYPE (tree) =
2202 computeType (LTYPE (tree),
2205 /*------------------------------------------------------------------*/
2206 /*----------------------------*/
2208 /*----------------------------*/
2210 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2212 werror (E_INVALID_OP, "divide");
2213 goto errorTreeReturn;
2215 /* if they are both literal then */
2216 /* rewrite the tree */
2217 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2219 tree->type = EX_VALUE;
2220 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2221 valFromType (RETYPE (tree)));
2222 tree->right = tree->left = NULL;
2223 TETYPE (tree) = getSpec (TTYPE (tree) =
2224 tree->opval.val->type);
2227 LRVAL (tree) = RRVAL (tree) = 1;
2228 TETYPE (tree) = getSpec (TTYPE (tree) =
2229 computeType (LTYPE (tree),
2233 /*------------------------------------------------------------------*/
2234 /*----------------------------*/
2236 /*----------------------------*/
2238 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2240 werror (E_BITWISE_OP);
2241 werror (W_CONTINUE, "left & right types are ");
2242 printTypeChain (LTYPE (tree), stderr);
2243 fprintf (stderr, ",");
2244 printTypeChain (RTYPE (tree), stderr);
2245 fprintf (stderr, "\n");
2246 goto errorTreeReturn;
2248 /* if they are both literal then */
2249 /* rewrite the tree */
2250 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2252 tree->type = EX_VALUE;
2253 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2254 valFromType (RETYPE (tree)));
2255 tree->right = tree->left = NULL;
2256 TETYPE (tree) = getSpec (TTYPE (tree) =
2257 tree->opval.val->type);
2260 LRVAL (tree) = RRVAL (tree) = 1;
2261 TETYPE (tree) = getSpec (TTYPE (tree) =
2262 computeType (LTYPE (tree),
2266 /*------------------------------------------------------------------*/
2267 /*----------------------------*/
2268 /* address dereference */
2269 /*----------------------------*/
2270 case '*': /* can be unary : if right is null then unary operation */
2273 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2275 werror (E_PTR_REQD);
2276 goto errorTreeReturn;
2281 werror (E_LVALUE_REQUIRED, "pointer deref");
2282 goto errorTreeReturn;
2284 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2285 LTYPE (tree)->next : NULL);
2286 TETYPE (tree) = getSpec (TTYPE (tree));
2287 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2291 /*------------------------------------------------------------------*/
2292 /*----------------------------*/
2293 /* multiplication */
2294 /*----------------------------*/
2295 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2297 werror (E_INVALID_OP, "multiplication");
2298 goto errorTreeReturn;
2301 /* if they are both literal then */
2302 /* rewrite the tree */
2303 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2305 tree->type = EX_VALUE;
2306 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2307 valFromType (RETYPE (tree)));
2308 tree->right = tree->left = NULL;
2309 TETYPE (tree) = getSpec (TTYPE (tree) =
2310 tree->opval.val->type);
2314 /* if left is a literal exchange left & right */
2315 if (IS_LITERAL (LTYPE (tree)))
2317 ast *tTree = tree->left;
2318 tree->left = tree->right;
2319 tree->right = tTree;
2322 LRVAL (tree) = RRVAL (tree) = 1;
2323 /* promote result to int if left & right are char
2324 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2325 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2326 TETYPE (tree) = getSpec (TTYPE (tree) =
2327 computeType (LTYPE (tree),
2329 SPEC_NOUN(TETYPE(tree)) = V_INT;
2331 TETYPE (tree) = getSpec (TTYPE (tree) =
2332 computeType (LTYPE (tree),
2337 /*------------------------------------------------------------------*/
2338 /*----------------------------*/
2339 /* unary '+' operator */
2340 /*----------------------------*/
2345 if (!IS_INTEGRAL (LTYPE (tree)))
2347 werror (E_UNARY_OP, '+');
2348 goto errorTreeReturn;
2351 /* if left is a literal then do it */
2352 if (IS_LITERAL (LTYPE (tree)))
2354 tree->type = EX_VALUE;
2355 tree->opval.val = valFromType (LETYPE (tree));
2357 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2361 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2365 /*------------------------------------------------------------------*/
2366 /*----------------------------*/
2368 /*----------------------------*/
2370 /* this is not a unary operation */
2371 /* if both pointers then problem */
2372 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2373 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2375 werror (E_PTR_PLUS_PTR);
2376 goto errorTreeReturn;
2379 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2380 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2382 werror (E_PLUS_INVALID, "+");
2383 goto errorTreeReturn;
2386 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2387 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2389 werror (E_PLUS_INVALID, "+");
2390 goto errorTreeReturn;
2392 /* if they are both literal then */
2393 /* rewrite the tree */
2394 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2396 tree->type = EX_VALUE;
2397 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2398 valFromType (RETYPE (tree)));
2399 tree->right = tree->left = NULL;
2400 TETYPE (tree) = getSpec (TTYPE (tree) =
2401 tree->opval.val->type);
2405 /* if the right is a pointer or left is a literal
2406 xchange left & right */
2407 if (IS_ARRAY (RTYPE (tree)) ||
2408 IS_PTR (RTYPE (tree)) ||
2409 IS_LITERAL (LTYPE (tree)))
2411 ast *tTree = tree->left;
2412 tree->left = tree->right;
2413 tree->right = tTree;
2416 LRVAL (tree) = RRVAL (tree) = 1;
2417 /* if the left is a pointer */
2418 if (IS_PTR (LTYPE (tree)))
2419 TETYPE (tree) = getSpec (TTYPE (tree) =
2422 TETYPE (tree) = getSpec (TTYPE (tree) =
2423 computeType (LTYPE (tree),
2427 /*------------------------------------------------------------------*/
2428 /*----------------------------*/
2430 /*----------------------------*/
2431 case '-': /* can be unary */
2432 /* if right is null then unary */
2436 if (!IS_ARITHMETIC (LTYPE (tree)))
2438 werror (E_UNARY_OP, tree->opval.op);
2439 goto errorTreeReturn;
2442 /* if left is a literal then do it */
2443 if (IS_LITERAL (LTYPE (tree)))
2445 tree->type = EX_VALUE;
2446 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2448 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2449 SPEC_USIGN(TETYPE(tree)) = 0;
2453 TTYPE (tree) = LTYPE (tree);
2457 /*------------------------------------------------------------------*/
2458 /*----------------------------*/
2460 /*----------------------------*/
2462 if (!(IS_PTR (LTYPE (tree)) ||
2463 IS_ARRAY (LTYPE (tree)) ||
2464 IS_ARITHMETIC (LTYPE (tree))))
2466 werror (E_PLUS_INVALID, "-");
2467 goto errorTreeReturn;
2470 if (!(IS_PTR (RTYPE (tree)) ||
2471 IS_ARRAY (RTYPE (tree)) ||
2472 IS_ARITHMETIC (RTYPE (tree))))
2474 werror (E_PLUS_INVALID, "-");
2475 goto errorTreeReturn;
2478 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2479 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2480 IS_INTEGRAL (RTYPE (tree))))
2482 werror (E_PLUS_INVALID, "-");
2483 goto errorTreeReturn;
2486 /* if they are both literal then */
2487 /* rewrite the tree */
2488 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2490 tree->type = EX_VALUE;
2491 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2492 valFromType (RETYPE (tree)));
2493 tree->right = tree->left = NULL;
2494 TETYPE (tree) = getSpec (TTYPE (tree) =
2495 tree->opval.val->type);
2499 /* if the left & right are equal then zero */
2500 if (isAstEqual (tree->left, tree->right))
2502 tree->type = EX_VALUE;
2503 tree->left = tree->right = NULL;
2504 tree->opval.val = constVal ("0");
2505 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2509 /* if both of them are pointers or arrays then */
2510 /* the result is going to be an integer */
2511 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2512 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2513 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2515 /* if only the left is a pointer */
2516 /* then result is a pointer */
2517 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2518 TETYPE (tree) = getSpec (TTYPE (tree) =
2521 TETYPE (tree) = getSpec (TTYPE (tree) =
2522 computeType (LTYPE (tree),
2524 LRVAL (tree) = RRVAL (tree) = 1;
2527 /*------------------------------------------------------------------*/
2528 /*----------------------------*/
2530 /*----------------------------*/
2532 /* can be only integral type */
2533 if (!IS_INTEGRAL (LTYPE (tree)))
2535 werror (E_UNARY_OP, tree->opval.op);
2536 goto errorTreeReturn;
2539 /* if left is a literal then do it */
2540 if (IS_LITERAL (LTYPE (tree)))
2542 tree->type = EX_VALUE;
2543 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2545 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2549 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2552 /*------------------------------------------------------------------*/
2553 /*----------------------------*/
2555 /*----------------------------*/
2557 /* can be pointer */
2558 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2559 !IS_PTR (LTYPE (tree)) &&
2560 !IS_ARRAY (LTYPE (tree)))
2562 werror (E_UNARY_OP, tree->opval.op);
2563 goto errorTreeReturn;
2566 /* if left is a literal then do it */
2567 if (IS_LITERAL (LTYPE (tree)))
2569 tree->type = EX_VALUE;
2570 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2572 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2576 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2579 /*------------------------------------------------------------------*/
2580 /*----------------------------*/
2582 /*----------------------------*/
2585 TTYPE (tree) = LTYPE (tree);
2586 TETYPE (tree) = LETYPE (tree);
2590 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2595 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2597 werror (E_SHIFT_OP_INVALID);
2598 werror (W_CONTINUE, "left & right types are ");
2599 printTypeChain (LTYPE (tree), stderr);
2600 fprintf (stderr, ",");
2601 printTypeChain (RTYPE (tree), stderr);
2602 fprintf (stderr, "\n");
2603 goto errorTreeReturn;
2606 /* if they are both literal then */
2607 /* rewrite the tree */
2608 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2610 tree->type = EX_VALUE;
2611 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2612 valFromType (RETYPE (tree)),
2613 (tree->opval.op == LEFT_OP ? 1 : 0));
2614 tree->right = tree->left = NULL;
2615 TETYPE (tree) = getSpec (TTYPE (tree) =
2616 tree->opval.val->type);
2619 /* if only the right side is a literal & we are
2620 shifting more than size of the left operand then zero */
2621 if (IS_LITERAL (RTYPE (tree)) &&
2622 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2623 (getSize (LTYPE (tree)) * 8))
2625 werror (W_SHIFT_CHANGED,
2626 (tree->opval.op == LEFT_OP ? "left" : "right"));
2627 tree->type = EX_VALUE;
2628 tree->left = tree->right = NULL;
2629 tree->opval.val = constVal ("0");
2630 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2633 LRVAL (tree) = RRVAL (tree) = 1;
2634 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2636 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2640 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2644 /*------------------------------------------------------------------*/
2645 /*----------------------------*/
2647 /*----------------------------*/
2648 case CAST: /* change the type */
2649 /* cannot cast to an aggregate type */
2650 if (IS_AGGREGATE (LTYPE (tree)))
2652 werror (E_CAST_ILLEGAL);
2653 goto errorTreeReturn;
2656 /* make sure the type is complete and sane */
2657 checkTypeSanity(LETYPE(tree), "(cast)");
2660 /* if the right is a literal replace the tree */
2661 if (IS_LITERAL (RETYPE (tree))) {
2662 if (!IS_PTR (LTYPE (tree))) {
2663 tree->type = EX_VALUE;
2665 valCastLiteral (LTYPE (tree),
2666 floatFromVal (valFromType (RETYPE (tree))));
2669 TTYPE (tree) = tree->opval.val->type;
2670 tree->values.literalFromCast = 1;
2671 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2672 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2673 sym_link *rest = LTYPE(tree)->next;
2674 werror(W_LITERAL_GENERIC);
2675 TTYPE(tree) = newLink();
2676 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2677 TTYPE(tree)->next = rest;
2678 tree->left->opval.lnk = TTYPE(tree);
2681 TTYPE (tree) = LTYPE (tree);
2685 TTYPE (tree) = LTYPE (tree);
2689 /* if pointer to struct then check names */
2690 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2691 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2692 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2693 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2695 /* if the right is a literal replace the tree */
2696 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2697 tree->type = EX_VALUE;
2699 valCastLiteral (LTYPE (tree),
2700 floatFromVal (valFromType (RETYPE (tree))));
2703 TTYPE (tree) = tree->opval.val->type;
2704 tree->values.literalFromCast = 1;
2706 TTYPE (tree) = LTYPE (tree);
2710 TETYPE (tree) = getSpec (TTYPE (tree));
2714 /*------------------------------------------------------------------*/
2715 /*----------------------------*/
2716 /* logical &&, || */
2717 /*----------------------------*/
2720 /* each must me arithmetic type or be a pointer */
2721 if (!IS_PTR (LTYPE (tree)) &&
2722 !IS_ARRAY (LTYPE (tree)) &&
2723 !IS_INTEGRAL (LTYPE (tree)))
2725 werror (E_COMPARE_OP);
2726 goto errorTreeReturn;
2729 if (!IS_PTR (RTYPE (tree)) &&
2730 !IS_ARRAY (RTYPE (tree)) &&
2731 !IS_INTEGRAL (RTYPE (tree)))
2733 werror (E_COMPARE_OP);
2734 goto errorTreeReturn;
2736 /* if they are both literal then */
2737 /* rewrite the tree */
2738 if (IS_LITERAL (RTYPE (tree)) &&
2739 IS_LITERAL (LTYPE (tree)))
2741 tree->type = EX_VALUE;
2742 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2743 valFromType (RETYPE (tree)),
2745 tree->right = tree->left = NULL;
2746 TETYPE (tree) = getSpec (TTYPE (tree) =
2747 tree->opval.val->type);
2750 LRVAL (tree) = RRVAL (tree) = 1;
2751 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2754 /*------------------------------------------------------------------*/
2755 /*----------------------------*/
2756 /* comparison operators */
2757 /*----------------------------*/
2765 ast *lt = optimizeCompare (tree);
2771 /* if they are pointers they must be castable */
2772 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2774 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2776 werror (E_COMPARE_OP);
2777 fprintf (stderr, "comparing type ");
2778 printTypeChain (LTYPE (tree), stderr);
2779 fprintf (stderr, "to type ");
2780 printTypeChain (RTYPE (tree), stderr);
2781 fprintf (stderr, "\n");
2782 goto errorTreeReturn;
2785 /* else they should be promotable to one another */
2788 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2789 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2791 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2793 werror (E_COMPARE_OP);
2794 fprintf (stderr, "comparing type ");
2795 printTypeChain (LTYPE (tree), stderr);
2796 fprintf (stderr, "to type ");
2797 printTypeChain (RTYPE (tree), stderr);
2798 fprintf (stderr, "\n");
2799 goto errorTreeReturn;
2803 /* if they are both literal then */
2804 /* rewrite the tree */
2805 if (IS_LITERAL (RTYPE (tree)) &&
2806 IS_LITERAL (LTYPE (tree)))
2808 tree->type = EX_VALUE;
2809 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2810 valFromType (RETYPE (tree)),
2812 tree->right = tree->left = NULL;
2813 TETYPE (tree) = getSpec (TTYPE (tree) =
2814 tree->opval.val->type);
2817 LRVAL (tree) = RRVAL (tree) = 1;
2818 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2821 /*------------------------------------------------------------------*/
2822 /*----------------------------*/
2824 /*----------------------------*/
2825 case SIZEOF: /* evaluate wihout code generation */
2826 /* change the type to a integer */
2827 tree->type = EX_VALUE;
2828 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2829 tree->opval.val = constVal (buffer);
2830 tree->right = tree->left = NULL;
2831 TETYPE (tree) = getSpec (TTYPE (tree) =
2832 tree->opval.val->type);
2835 /*------------------------------------------------------------------*/
2836 /*----------------------------*/
2838 /*----------------------------*/
2840 /* return typeof enum value */
2841 tree->type = EX_VALUE;
2844 if (IS_SPEC(tree->right->ftype)) {
2845 switch (SPEC_NOUN(tree->right->ftype)) {
2847 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2848 else typeofv = TYPEOF_INT;
2851 typeofv = TYPEOF_FLOAT;
2854 typeofv = TYPEOF_CHAR;
2857 typeofv = TYPEOF_VOID;
2860 typeofv = TYPEOF_STRUCT;
2863 typeofv = TYPEOF_BIT;
2866 typeofv = TYPEOF_SBIT;
2872 switch (DCL_TYPE(tree->right->ftype)) {
2874 typeofv = TYPEOF_POINTER;
2877 typeofv = TYPEOF_FPOINTER;
2880 typeofv = TYPEOF_CPOINTER;
2883 typeofv = TYPEOF_GPOINTER;
2886 typeofv = TYPEOF_PPOINTER;
2889 typeofv = TYPEOF_IPOINTER;
2892 typeofv = TYPEOF_ARRAY;
2895 typeofv = TYPEOF_FUNCTION;
2901 sprintf (buffer, "%d", typeofv);
2902 tree->opval.val = constVal (buffer);
2903 tree->right = tree->left = NULL;
2904 TETYPE (tree) = getSpec (TTYPE (tree) =
2905 tree->opval.val->type);
2908 /*------------------------------------------------------------------*/
2909 /*----------------------------*/
2910 /* conditional operator '?' */
2911 /*----------------------------*/
2913 /* the type is value of the colon operator (on the right) */
2914 assert(IS_COLON_OP(tree->right));
2915 /* if already known then replace the tree : optimizer will do it
2916 but faster to do it here */
2917 if (IS_LITERAL (LTYPE(tree))) {
2918 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2919 return decorateType(tree->right->left) ;
2921 return decorateType(tree->right->right) ;
2924 tree->right = decorateType(tree->right);
2925 TTYPE (tree) = RTYPE(tree);
2926 TETYPE (tree) = getSpec (TTYPE (tree));
2931 /* if they don't match we have a problem */
2932 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2934 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2935 goto errorTreeReturn;
2938 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2939 TETYPE (tree) = getSpec (TTYPE (tree));
2943 /*------------------------------------------------------------------*/
2944 /*----------------------------*/
2945 /* assignment operators */
2946 /*----------------------------*/
2949 /* for these it must be both must be integral */
2950 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2951 !IS_ARITHMETIC (RTYPE (tree)))
2953 werror (E_OPS_INTEGRAL);
2954 goto errorTreeReturn;
2957 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2959 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2960 werror (E_CODE_WRITE, " ");
2964 werror (E_LVALUE_REQUIRED, "*= or /=");
2965 goto errorTreeReturn;
2976 /* for these it must be both must be integral */
2977 if (!IS_INTEGRAL (LTYPE (tree)) ||
2978 !IS_INTEGRAL (RTYPE (tree)))
2980 werror (E_OPS_INTEGRAL);
2981 goto errorTreeReturn;
2984 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2986 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2987 werror (E_CODE_WRITE, " ");
2991 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2992 goto errorTreeReturn;
2998 /*------------------------------------------------------------------*/
2999 /*----------------------------*/
3001 /*----------------------------*/
3003 if (!(IS_PTR (LTYPE (tree)) ||
3004 IS_ARITHMETIC (LTYPE (tree))))
3006 werror (E_PLUS_INVALID, "-=");
3007 goto errorTreeReturn;
3010 if (!(IS_PTR (RTYPE (tree)) ||
3011 IS_ARITHMETIC (RTYPE (tree))))
3013 werror (E_PLUS_INVALID, "-=");
3014 goto errorTreeReturn;
3017 TETYPE (tree) = getSpec (TTYPE (tree) =
3018 computeType (LTYPE (tree),
3021 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3022 werror (E_CODE_WRITE, " ");
3026 werror (E_LVALUE_REQUIRED, "-=");
3027 goto errorTreeReturn;
3033 /*------------------------------------------------------------------*/
3034 /*----------------------------*/
3036 /*----------------------------*/
3038 /* this is not a unary operation */
3039 /* if both pointers then problem */
3040 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3042 werror (E_PTR_PLUS_PTR);
3043 goto errorTreeReturn;
3046 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3048 werror (E_PLUS_INVALID, "+=");
3049 goto errorTreeReturn;
3052 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3054 werror (E_PLUS_INVALID, "+=");
3055 goto errorTreeReturn;
3058 TETYPE (tree) = getSpec (TTYPE (tree) =
3059 computeType (LTYPE (tree),
3062 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3063 werror (E_CODE_WRITE, " ");
3067 werror (E_LVALUE_REQUIRED, "+=");
3068 goto errorTreeReturn;
3071 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3072 tree->opval.op = '=';
3076 /*------------------------------------------------------------------*/
3077 /*----------------------------*/
3078 /* straight assignemnt */
3079 /*----------------------------*/
3081 /* cannot be an aggregate */
3082 if (IS_AGGREGATE (LTYPE (tree)))
3084 werror (E_AGGR_ASSIGN);
3085 goto errorTreeReturn;
3088 /* they should either match or be castable */
3089 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3091 werror (E_TYPE_MISMATCH, "assignment", " ");
3092 fprintf (stderr, "type --> '");
3093 printTypeChain (RTYPE (tree), stderr);
3094 fprintf (stderr, "' ");
3095 fprintf (stderr, "assigned to type --> '");
3096 printTypeChain (LTYPE (tree), stderr);
3097 fprintf (stderr, "'\n");
3098 goto errorTreeReturn;
3101 /* if the left side of the tree is of type void
3102 then report error */
3103 if (IS_VOID (LTYPE (tree)))
3105 werror (E_CAST_ZERO);
3106 printFromToType(RTYPE(tree), LTYPE(tree));
3109 TETYPE (tree) = getSpec (TTYPE (tree) =
3113 if (!tree->initMode ) {
3114 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3115 werror (E_CODE_WRITE, " ");
3119 werror (E_LVALUE_REQUIRED, "=");
3120 goto errorTreeReturn;
3125 /*------------------------------------------------------------------*/
3126 /*----------------------------*/
3127 /* comma operator */
3128 /*----------------------------*/
3130 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3133 /*------------------------------------------------------------------*/
3134 /*----------------------------*/
3136 /*----------------------------*/
3140 if (processParms (tree->left,
3141 FUNC_ARGS(tree->left->ftype),
3142 tree->right, &parmNumber, TRUE)) {
3143 goto errorTreeReturn;
3146 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3147 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3149 //FUNC_ARGS(tree->left->ftype) =
3150 //reverseVal (FUNC_ARGS(tree->left->ftype));
3151 reverseParms (tree->right);
3154 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3157 /*------------------------------------------------------------------*/
3158 /*----------------------------*/
3159 /* return statement */
3160 /*----------------------------*/
3165 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3167 werror (W_RETURN_MISMATCH);
3168 printFromToType (RTYPE(tree), currFunc->type->next);
3169 goto errorTreeReturn;
3172 if (IS_VOID (currFunc->type->next)
3174 !IS_VOID (RTYPE (tree)))
3176 werror (E_FUNC_VOID);
3177 goto errorTreeReturn;
3180 /* if there is going to be a casing required then add it */
3181 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3184 decorateType (newNode (CAST,
3185 newAst_LINK (copyLinkChain (currFunc->type->next)),
3194 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3196 werror (E_VOID_FUNC, currFunc->name);
3197 goto errorTreeReturn;
3200 TTYPE (tree) = TETYPE (tree) = NULL;
3203 /*------------------------------------------------------------------*/
3204 /*----------------------------*/
3205 /* switch statement */
3206 /*----------------------------*/
3208 /* the switch value must be an integer */
3209 if (!IS_INTEGRAL (LTYPE (tree)))
3211 werror (E_SWITCH_NON_INTEGER);
3212 goto errorTreeReturn;
3215 TTYPE (tree) = TETYPE (tree) = NULL;
3218 /*------------------------------------------------------------------*/
3219 /*----------------------------*/
3221 /*----------------------------*/
3223 tree->left = backPatchLabels (tree->left,
3226 TTYPE (tree) = TETYPE (tree) = NULL;
3229 /*------------------------------------------------------------------*/
3230 /*----------------------------*/
3232 /*----------------------------*/
3235 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3236 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3237 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3239 /* if the for loop is reversible then
3240 reverse it otherwise do what we normally
3246 if (isLoopReversible (tree, &sym, &init, &end))
3247 return reverseLoop (tree, sym, init, end);
3249 return decorateType (createFor (AST_FOR (tree, trueLabel),
3250 AST_FOR (tree, continueLabel),
3251 AST_FOR (tree, falseLabel),
3252 AST_FOR (tree, condLabel),
3253 AST_FOR (tree, initExpr),
3254 AST_FOR (tree, condExpr),
3255 AST_FOR (tree, loopExpr),
3259 TTYPE (tree) = TETYPE (tree) = NULL;
3263 /* some error found this tree will be killed */
3265 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3266 tree->opval.op = NULLOP;
3272 /*-----------------------------------------------------------------*/
3273 /* sizeofOp - processes size of operation */
3274 /*-----------------------------------------------------------------*/
3276 sizeofOp (sym_link * type)
3280 /* make sure the type is complete and sane */
3281 checkTypeSanity(type, "(sizeof)");
3283 /* get the size and convert it to character */
3284 sprintf (buff, "%d", getSize (type));
3286 /* now convert into value */
3287 return constVal (buff);
3291 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3292 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3293 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3294 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3295 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3296 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3297 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3299 /*-----------------------------------------------------------------*/
3300 /* backPatchLabels - change and or not operators to flow control */
3301 /*-----------------------------------------------------------------*/
3303 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3309 if (!(IS_ANDORNOT (tree)))
3312 /* if this an and */
3315 static int localLbl = 0;
3318 sprintf (buffer, "_and_%d", localLbl++);
3319 localLabel = newSymbol (buffer, NestLevel);
3321 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3323 /* if left is already a IFX then just change the if true label in that */
3324 if (!IS_IFX (tree->left))
3325 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3327 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3328 /* right is a IFX then just join */
3329 if (IS_IFX (tree->right))
3330 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3332 tree->right = createLabel (localLabel, tree->right);
3333 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3335 return newNode (NULLOP, tree->left, tree->right);
3338 /* if this is an or operation */
3341 static int localLbl = 0;
3344 sprintf (buffer, "_or_%d", localLbl++);
3345 localLabel = newSymbol (buffer, NestLevel);
3347 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3349 /* if left is already a IFX then just change the if true label in that */
3350 if (!IS_IFX (tree->left))
3351 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3353 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3354 /* right is a IFX then just join */
3355 if (IS_IFX (tree->right))
3356 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3358 tree->right = createLabel (localLabel, tree->right);
3359 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3361 return newNode (NULLOP, tree->left, tree->right);
3367 int wasnot = IS_NOT (tree->left);
3368 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3370 /* if the left is already a IFX */
3371 if (!IS_IFX (tree->left))
3372 tree->left = newNode (IFX, tree->left, NULL);
3376 tree->left->trueLabel = trueLabel;
3377 tree->left->falseLabel = falseLabel;
3381 tree->left->trueLabel = falseLabel;
3382 tree->left->falseLabel = trueLabel;
3389 tree->trueLabel = trueLabel;
3390 tree->falseLabel = falseLabel;
3397 /*-----------------------------------------------------------------*/
3398 /* createBlock - create expression tree for block */
3399 /*-----------------------------------------------------------------*/
3401 createBlock (symbol * decl, ast * body)
3405 /* if the block has nothing */
3409 ex = newNode (BLOCK, NULL, body);
3410 ex->values.sym = decl;
3412 ex->right = ex->right;
3418 /*-----------------------------------------------------------------*/
3419 /* createLabel - creates the expression tree for labels */
3420 /*-----------------------------------------------------------------*/
3422 createLabel (symbol * label, ast * stmnt)
3425 char name[SDCC_NAME_MAX + 1];
3428 /* must create fresh symbol if the symbol name */
3429 /* exists in the symbol table, since there can */
3430 /* be a variable with the same name as the labl */
3431 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3432 (csym->level == label->level))
3433 label = newSymbol (label->name, label->level);
3435 /* change the name before putting it in add _ */
3436 sprintf (name, "%s", label->name);
3438 /* put the label in the LabelSymbol table */
3439 /* but first check if a label of the same */
3441 if ((csym = findSym (LabelTab, NULL, name)))
3442 werror (E_DUPLICATE_LABEL, label->name);
3444 addSym (LabelTab, label, name, label->level, 0, 0);
3447 label->key = labelKey++;
3448 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3454 /*-----------------------------------------------------------------*/
3455 /* createCase - generates the parsetree for a case statement */
3456 /*-----------------------------------------------------------------*/
3458 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3460 char caseLbl[SDCC_NAME_MAX + 1];
3464 /* if the switch statement does not exist */
3465 /* then case is out of context */
3468 werror (E_CASE_CONTEXT);
3472 caseVal = decorateType (resolveSymbols (caseVal));
3473 /* if not a constant then error */
3474 if (!IS_LITERAL (caseVal->ftype))
3476 werror (E_CASE_CONSTANT);
3480 /* if not a integer than error */
3481 if (!IS_INTEGRAL (caseVal->ftype))
3483 werror (E_CASE_NON_INTEGER);
3487 /* find the end of the switch values chain */
3488 if (!(val = swStat->values.switchVals.swVals))
3489 swStat->values.switchVals.swVals = caseVal->opval.val;
3492 /* also order the cases according to value */
3494 int cVal = (int) floatFromVal (caseVal->opval.val);
3495 while (val && (int) floatFromVal (val) < cVal)
3501 /* if we reached the end then */
3504 pval->next = caseVal->opval.val;
3508 /* we found a value greater than */
3509 /* the current value we must add this */
3510 /* before the value */
3511 caseVal->opval.val->next = val;
3513 /* if this was the first in chain */
3514 if (swStat->values.switchVals.swVals == val)
3515 swStat->values.switchVals.swVals =
3518 pval->next = caseVal->opval.val;
3523 /* create the case label */
3524 sprintf (caseLbl, "_case_%d_%d",
3525 swStat->values.switchVals.swNum,
3526 (int) floatFromVal (caseVal->opval.val));
3528 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3533 /*-----------------------------------------------------------------*/
3534 /* createDefault - creates the parse tree for the default statement */
3535 /*-----------------------------------------------------------------*/
3537 createDefault (ast * swStat, ast * stmnt)
3539 char defLbl[SDCC_NAME_MAX + 1];
3541 /* if the switch statement does not exist */
3542 /* then case is out of context */
3545 werror (E_CASE_CONTEXT);
3549 /* turn on the default flag */
3550 swStat->values.switchVals.swDefault = 1;
3552 /* create the label */
3553 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3554 return createLabel (newSymbol (defLbl, 0), stmnt);
3557 /*-----------------------------------------------------------------*/
3558 /* createIf - creates the parsetree for the if statement */
3559 /*-----------------------------------------------------------------*/
3561 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3563 static int Lblnum = 0;
3565 symbol *ifTrue, *ifFalse, *ifEnd;
3567 /* if neither exists */
3568 if (!elseBody && !ifBody) {
3569 // if there are no side effects (i++, j() etc)
3570 if (!hasSEFcalls(condAst)) {
3575 /* create the labels */
3576 sprintf (buffer, "_iffalse_%d", Lblnum);
3577 ifFalse = newSymbol (buffer, NestLevel);
3578 /* if no else body then end == false */
3583 sprintf (buffer, "_ifend_%d", Lblnum);
3584 ifEnd = newSymbol (buffer, NestLevel);
3587 sprintf (buffer, "_iftrue_%d", Lblnum);
3588 ifTrue = newSymbol (buffer, NestLevel);
3592 /* attach the ifTrue label to the top of it body */
3593 ifBody = createLabel (ifTrue, ifBody);
3594 /* attach a goto end to the ifBody if else is present */
3597 ifBody = newNode (NULLOP, ifBody,
3599 newAst_VALUE (symbolVal (ifEnd)),
3601 /* put the elseLabel on the else body */
3602 elseBody = createLabel (ifFalse, elseBody);
3603 /* out the end at the end of the body */
3604 elseBody = newNode (NULLOP,
3606 createLabel (ifEnd, NULL));
3610 ifBody = newNode (NULLOP, ifBody,
3611 createLabel (ifFalse, NULL));
3613 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3614 if (IS_IFX (condAst))
3617 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3619 return newNode (NULLOP, ifTree,
3620 newNode (NULLOP, ifBody, elseBody));
3624 /*-----------------------------------------------------------------*/
3625 /* createDo - creates parse tree for do */
3628 /* _docontinue_n: */
3629 /* condition_expression +-> trueLabel -> _dobody_n */
3631 /* +-> falseLabel-> _dobreak_n */
3633 /*-----------------------------------------------------------------*/
3635 createDo (symbol * trueLabel, symbol * continueLabel,
3636 symbol * falseLabel, ast * condAst, ast * doBody)
3641 /* if the body does not exist then it is simple */
3644 condAst = backPatchLabels (condAst, continueLabel, NULL);
3645 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3646 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3647 doTree->trueLabel = continueLabel;
3648 doTree->falseLabel = NULL;
3652 /* otherwise we have a body */
3653 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3655 /* attach the body label to the top */
3656 doBody = createLabel (trueLabel, doBody);
3657 /* attach the continue label to end of body */
3658 doBody = newNode (NULLOP, doBody,
3659 createLabel (continueLabel, NULL));
3661 /* now put the break label at the end */
3662 if (IS_IFX (condAst))
3665 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3667 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3669 /* putting it together */
3670 return newNode (NULLOP, doBody, doTree);
3673 /*-----------------------------------------------------------------*/
3674 /* createFor - creates parse tree for 'for' statement */
3677 /* condExpr +-> trueLabel -> _forbody_n */
3679 /* +-> falseLabel-> _forbreak_n */
3682 /* _forcontinue_n: */
3684 /* goto _forcond_n ; */
3686 /*-----------------------------------------------------------------*/
3688 createFor (symbol * trueLabel, symbol * continueLabel,
3689 symbol * falseLabel, symbol * condLabel,
3690 ast * initExpr, ast * condExpr, ast * loopExpr,
3695 /* if loopexpression not present then we can generate it */
3696 /* the same way as a while */
3698 return newNode (NULLOP, initExpr,
3699 createWhile (trueLabel, continueLabel,
3700 falseLabel, condExpr, forBody));
3701 /* vanilla for statement */
3702 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3704 if (condExpr && !IS_IFX (condExpr))
3705 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3708 /* attach condition label to condition */
3709 condExpr = createLabel (condLabel, condExpr);
3711 /* attach body label to body */
3712 forBody = createLabel (trueLabel, forBody);
3714 /* attach continue to forLoop expression & attach */
3715 /* goto the forcond @ and of loopExpression */
3716 loopExpr = createLabel (continueLabel,
3720 newAst_VALUE (symbolVal (condLabel)),
3722 /* now start putting them together */
3723 forTree = newNode (NULLOP, initExpr, condExpr);
3724 forTree = newNode (NULLOP, forTree, forBody);
3725 forTree = newNode (NULLOP, forTree, loopExpr);
3726 /* finally add the break label */
3727 forTree = newNode (NULLOP, forTree,
3728 createLabel (falseLabel, NULL));
3732 /*-----------------------------------------------------------------*/
3733 /* createWhile - creates parse tree for while statement */
3734 /* the while statement will be created as follows */
3736 /* _while_continue_n: */
3737 /* condition_expression +-> trueLabel -> _while_boby_n */
3739 /* +-> falseLabel -> _while_break_n */
3740 /* _while_body_n: */
3742 /* goto _while_continue_n */
3743 /* _while_break_n: */
3744 /*-----------------------------------------------------------------*/
3746 createWhile (symbol * trueLabel, symbol * continueLabel,
3747 symbol * falseLabel, ast * condExpr, ast * whileBody)
3751 /* put the continue label */
3752 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3753 condExpr = createLabel (continueLabel, condExpr);
3754 condExpr->lineno = 0;
3756 /* put the body label in front of the body */
3757 whileBody = createLabel (trueLabel, whileBody);
3758 whileBody->lineno = 0;
3759 /* put a jump to continue at the end of the body */
3760 /* and put break label at the end of the body */
3761 whileBody = newNode (NULLOP,
3764 newAst_VALUE (symbolVal (continueLabel)),
3765 createLabel (falseLabel, NULL)));
3767 /* put it all together */
3768 if (IS_IFX (condExpr))
3769 whileTree = condExpr;
3772 whileTree = newNode (IFX, condExpr, NULL);
3773 /* put the true & false labels in place */
3774 whileTree->trueLabel = trueLabel;
3775 whileTree->falseLabel = falseLabel;
3778 return newNode (NULLOP, whileTree, whileBody);
3781 /*-----------------------------------------------------------------*/
3782 /* optimizeGetHbit - get highest order bit of the expression */
3783 /*-----------------------------------------------------------------*/
3785 optimizeGetHbit (ast * tree)
3788 /* if this is not a bit and */
3789 if (!IS_BITAND (tree))
3792 /* will look for tree of the form
3793 ( expr >> ((sizeof expr) -1) ) & 1 */
3794 if (!IS_AST_LIT_VALUE (tree->right))
3797 if (AST_LIT_VALUE (tree->right) != 1)
3800 if (!IS_RIGHT_OP (tree->left))
3803 if (!IS_AST_LIT_VALUE (tree->left->right))
3806 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3807 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3810 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3814 /*-----------------------------------------------------------------*/
3815 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3816 /*-----------------------------------------------------------------*/
3818 optimizeRRCRLC (ast * root)
3820 /* will look for trees of the form
3821 (?expr << 1) | (?expr >> 7) or
3822 (?expr >> 7) | (?expr << 1) will make that
3823 into a RLC : operation ..
3825 (?expr >> 1) | (?expr << 7) or
3826 (?expr << 7) | (?expr >> 1) will make that
3827 into a RRC operation
3828 note : by 7 I mean (number of bits required to hold the
3830 /* if the root operations is not a | operation the not */
3831 if (!IS_BITOR (root))
3834 /* I have to think of a better way to match patterns this sucks */
3835 /* that aside let start looking for the first case : I use a the
3836 negative check a lot to improve the efficiency */
3837 /* (?expr << 1) | (?expr >> 7) */
3838 if (IS_LEFT_OP (root->left) &&
3839 IS_RIGHT_OP (root->right))
3842 if (!SPEC_USIGN (TETYPE (root->left->left)))
3845 if (!IS_AST_LIT_VALUE (root->left->right) ||
3846 !IS_AST_LIT_VALUE (root->right->right))
3849 /* make sure it is the same expression */
3850 if (!isAstEqual (root->left->left,
3854 if (AST_LIT_VALUE (root->left->right) != 1)
3857 if (AST_LIT_VALUE (root->right->right) !=
3858 (getSize (TTYPE (root->left->left)) * 8 - 1))
3861 /* whew got the first case : create the AST */
3862 return newNode (RLC, root->left->left, NULL);
3866 /* check for second case */
3867 /* (?expr >> 7) | (?expr << 1) */
3868 if (IS_LEFT_OP (root->right) &&
3869 IS_RIGHT_OP (root->left))
3872 if (!SPEC_USIGN (TETYPE (root->left->left)))
3875 if (!IS_AST_LIT_VALUE (root->left->right) ||
3876 !IS_AST_LIT_VALUE (root->right->right))
3879 /* make sure it is the same symbol */
3880 if (!isAstEqual (root->left->left,
3884 if (AST_LIT_VALUE (root->right->right) != 1)
3887 if (AST_LIT_VALUE (root->left->right) !=
3888 (getSize (TTYPE (root->left->left)) * 8 - 1))
3891 /* whew got the first case : create the AST */
3892 return newNode (RLC, root->left->left, NULL);
3897 /* third case for RRC */
3898 /* (?symbol >> 1) | (?symbol << 7) */
3899 if (IS_LEFT_OP (root->right) &&
3900 IS_RIGHT_OP (root->left))
3903 if (!SPEC_USIGN (TETYPE (root->left->left)))
3906 if (!IS_AST_LIT_VALUE (root->left->right) ||
3907 !IS_AST_LIT_VALUE (root->right->right))
3910 /* make sure it is the same symbol */
3911 if (!isAstEqual (root->left->left,
3915 if (AST_LIT_VALUE (root->left->right) != 1)
3918 if (AST_LIT_VALUE (root->right->right) !=
3919 (getSize (TTYPE (root->left->left)) * 8 - 1))
3922 /* whew got the first case : create the AST */
3923 return newNode (RRC, root->left->left, NULL);
3927 /* fourth and last case for now */
3928 /* (?symbol << 7) | (?symbol >> 1) */
3929 if (IS_RIGHT_OP (root->right) &&
3930 IS_LEFT_OP (root->left))
3933 if (!SPEC_USIGN (TETYPE (root->left->left)))
3936 if (!IS_AST_LIT_VALUE (root->left->right) ||
3937 !IS_AST_LIT_VALUE (root->right->right))
3940 /* make sure it is the same symbol */
3941 if (!isAstEqual (root->left->left,
3945 if (AST_LIT_VALUE (root->right->right) != 1)
3948 if (AST_LIT_VALUE (root->left->right) !=
3949 (getSize (TTYPE (root->left->left)) * 8 - 1))
3952 /* whew got the first case : create the AST */
3953 return newNode (RRC, root->left->left, NULL);
3957 /* not found return root */
3961 /*-----------------------------------------------------------------*/
3962 /* optimizeCompare - otimizes compares for bit variables */
3963 /*-----------------------------------------------------------------*/
3965 optimizeCompare (ast * root)
3967 ast *optExpr = NULL;
3970 unsigned int litValue;
3972 /* if nothing then return nothing */
3976 /* if not a compare op then do leaves */
3977 if (!IS_COMPARE_OP (root))
3979 root->left = optimizeCompare (root->left);
3980 root->right = optimizeCompare (root->right);
3984 /* if left & right are the same then depending
3985 of the operation do */
3986 if (isAstEqual (root->left, root->right))
3988 switch (root->opval.op)
3993 optExpr = newAst_VALUE (constVal ("0"));
3998 optExpr = newAst_VALUE (constVal ("1"));
4002 return decorateType (optExpr);
4005 vleft = (root->left->type == EX_VALUE ?
4006 root->left->opval.val : NULL);
4008 vright = (root->right->type == EX_VALUE ?
4009 root->right->opval.val : NULL);
4011 //#define EXPERIMENTAL
4013 /* if left is unsigned and right is literal */
4014 if (vleft && vright &&
4015 IS_UNSIGNED(vleft->etype) &&
4016 IS_LITERAL(vright->etype)) {
4017 double dval=floatFromVal(vright);
4018 int op=root->opval.op;
4020 fprintf (stderr,"op: '");
4022 case LE_OP: fprintf (stderr, "<= '"); break;
4023 case EQ_OP: fprintf (stderr, "== '"); break;
4024 case GE_OP: fprintf (stderr, ">= '"); break;
4025 default: fprintf (stderr, "%c '", op); break;
4027 fprintf (stderr, "%f\n", dval);
4034 if (dval<0 || (op=='<' && dval==0)) {
4035 // unsigned is never < 0
4036 werror (W_IF_NEVER_TRUE);
4037 optExpr = newAst_VALUE (constVal("0"));
4038 return decorateType (optExpr);
4042 // change this into a cheaper EQ_OP
4043 fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
4044 root->opval.op=EQ_OP;
4051 if (dval>0 || (op==GE_OP && dval==0)) {
4052 // unsigned is never < 0
4053 werror (W_IF_ALWAYS_TRUE);
4054 optExpr = newAst_VALUE (constVal("1"));
4055 return decorateType (optExpr);
4059 // change this into a cheaper reversed EQ_OP
4060 fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
4061 root->opval.op=EQ_OP;
4068 /* if left is a BITVAR in BITSPACE */
4069 /* and right is a LITERAL then opt- */
4070 /* imize else do nothing */
4071 if (vleft && vright &&
4072 IS_BITVAR (vleft->etype) &&
4073 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4074 IS_LITERAL (vright->etype))
4077 /* if right side > 1 then comparison may never succeed */
4078 if ((litValue = (int) floatFromVal (vright)) > 1)
4080 werror (W_BAD_COMPARE);
4086 switch (root->opval.op)
4088 case '>': /* bit value greater than 1 cannot be */
4089 werror (W_BAD_COMPARE);
4093 case '<': /* bit value < 1 means 0 */
4095 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4098 case LE_OP: /* bit value <= 1 means no check */
4099 optExpr = newAst_VALUE (vright);
4102 case GE_OP: /* bit value >= 1 means only check for = */
4104 optExpr = newAst_VALUE (vleft);
4109 { /* literal is zero */
4110 switch (root->opval.op)
4112 case '<': /* bit value < 0 cannot be */
4113 werror (W_BAD_COMPARE);
4117 case '>': /* bit value > 0 means 1 */
4119 optExpr = newAst_VALUE (vleft);
4122 case LE_OP: /* bit value <= 0 means no check */
4123 case GE_OP: /* bit value >= 0 means no check */
4124 werror (W_BAD_COMPARE);
4128 case EQ_OP: /* bit == 0 means ! of bit */
4129 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4133 return decorateType (resolveSymbols (optExpr));
4134 } /* end-of-if of BITVAR */
4139 /*-----------------------------------------------------------------*/
4140 /* addSymToBlock : adds the symbol to the first block we find */
4141 /*-----------------------------------------------------------------*/
4143 addSymToBlock (symbol * sym, ast * tree)
4145 /* reached end of tree or a leaf */
4146 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4150 if (IS_AST_OP (tree) &&
4151 tree->opval.op == BLOCK)
4154 symbol *lsym = copySymbol (sym);
4156 lsym->next = AST_VALUES (tree, sym);
4157 AST_VALUES (tree, sym) = lsym;
4161 addSymToBlock (sym, tree->left);
4162 addSymToBlock (sym, tree->right);
4165 /*-----------------------------------------------------------------*/
4166 /* processRegParms - do processing for register parameters */
4167 /*-----------------------------------------------------------------*/
4169 processRegParms (value * args, ast * body)
4173 if (IS_REGPARM (args->etype))
4174 addSymToBlock (args->sym, body);
4179 /*-----------------------------------------------------------------*/
4180 /* resetParmKey - resets the operandkeys for the symbols */
4181 /*-----------------------------------------------------------------*/
4182 DEFSETFUNC (resetParmKey)
4193 /*-----------------------------------------------------------------*/
4194 /* createFunction - This is the key node that calls the iCode for */
4195 /* generating the code for a function. Note code */
4196 /* is generated function by function, later when */
4197 /* add inter-procedural analysis this will change */
4198 /*-----------------------------------------------------------------*/
4200 createFunction (symbol * name, ast * body)
4206 iCode *piCode = NULL;
4208 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4209 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4211 /* if check function return 0 then some problem */
4212 if (checkFunction (name, NULL) == 0)
4215 /* create a dummy block if none exists */
4217 body = newNode (BLOCK, NULL, NULL);
4221 /* check if the function name already in the symbol table */
4222 if ((csym = findSym (SymbolTab, NULL, name->name)))
4225 /* special case for compiler defined functions
4226 we need to add the name to the publics list : this
4227 actually means we are now compiling the compiler
4231 addSet (&publics, name);
4237 allocVariables (name);
4239 name->lastLine = yylineno;
4242 /* set the stack pointer */
4243 /* PENDING: check this for the mcs51 */
4244 stackPtr = -port->stack.direction * port->stack.call_overhead;
4245 if (IFFUNC_ISISR (name->type))
4246 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4247 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4248 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4250 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4252 fetype = getSpec (name->type); /* get the specifier for the function */
4253 /* if this is a reentrant function then */
4254 if (IFFUNC_ISREENT (name->type))
4257 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4259 /* do processing for parameters that are passed in registers */
4260 processRegParms (FUNC_ARGS(name->type), body);
4262 /* set the stack pointer */
4266 /* allocate & autoinit the block variables */
4267 processBlockVars (body, &stack, ALLOCATE);
4269 /* save the stack information */
4270 if (options.useXstack)
4271 name->xstack = SPEC_STAK (fetype) = stack;
4273 name->stack = SPEC_STAK (fetype) = stack;
4275 /* name needs to be mangled */
4276 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4278 body = resolveSymbols (body); /* resolve the symbols */
4279 body = decorateType (body); /* propagateType & do semantic checks */
4281 ex = newAst_VALUE (symbolVal (name)); /* create name */
4282 ex = newNode (FUNCTION, ex, body);
4283 ex->values.args = FUNC_ARGS(name->type);
4285 if (options.dump_tree) PA(ex);
4288 werror (E_FUNC_NO_CODE, name->name);
4292 /* create the node & generate intermediate code */
4294 codeOutFile = code->oFile;
4295 piCode = iCodeFromAst (ex);
4299 werror (E_FUNC_NO_CODE, name->name);
4303 eBBlockFromiCode (piCode);
4305 /* if there are any statics then do them */
4308 GcurMemmap = statsg;
4309 codeOutFile = statsg->oFile;
4310 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4316 /* dealloc the block variables */
4317 processBlockVars (body, &stack, DEALLOCATE);
4318 /* deallocate paramaters */
4319 deallocParms (FUNC_ARGS(name->type));
4321 if (IFFUNC_ISREENT (name->type))
4324 /* we are done freeup memory & cleanup */
4326 if (port->reset_labelKey) labelKey = 1;
4328 FUNC_HASBODY(name->type) = 1;
4329 addSet (&operKeyReset, name);
4330 applyToSet (operKeyReset, resetParmKey);
4333 cdbStructBlock (1, cdbFile);
4335 cleanUpLevel (LabelTab, 0);
4336 cleanUpBlock (StructTab, 1);
4337 cleanUpBlock (TypedefTab, 1);
4339 xstack->syms = NULL;
4340 istack->syms = NULL;
4345 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4346 /*-----------------------------------------------------------------*/
4347 /* ast_print : prints the ast (for debugging purposes) */
4348 /*-----------------------------------------------------------------*/
4350 void ast_print (ast * tree, FILE *outfile, int indent)
4355 /* can print only decorated trees */
4356 if (!tree->decorated) return;
4358 /* if any child is an error | this one is an error do nothing */
4359 if (tree->isError ||
4360 (tree->left && tree->left->isError) ||
4361 (tree->right && tree->right->isError)) {
4362 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4366 /* print the line */
4367 /* if not block & function */
4368 if (tree->type == EX_OP &&
4369 (tree->opval.op != FUNCTION &&
4370 tree->opval.op != BLOCK &&
4371 tree->opval.op != NULLOP)) {
4374 if (tree->opval.op == FUNCTION) {
4376 value *args=FUNC_ARGS(tree->left->opval.val->type);
4377 fprintf(outfile,"FUNCTION (%s=%p) type (",
4378 tree->left->opval.val->name, tree);
4379 printTypeChain (tree->ftype,outfile);
4380 fprintf(outfile,") args (");
4383 fprintf (outfile, ", ");
4385 printTypeChain (args ? args->type : NULL, outfile);
4387 args= args ? args->next : NULL;
4389 fprintf(outfile,")\n");
4390 ast_print(tree->left,outfile,indent);
4391 ast_print(tree->right,outfile,indent);
4394 if (tree->opval.op == BLOCK) {
4395 symbol *decls = tree->values.sym;
4396 INDENT(indent,outfile);
4397 fprintf(outfile,"{\n");
4399 INDENT(indent+2,outfile);
4400 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4401 decls->name, decls);
4402 printTypeChain(decls->type,outfile);
4403 fprintf(outfile,")\n");
4405 decls = decls->next;
4407 ast_print(tree->right,outfile,indent+2);
4408 INDENT(indent,outfile);
4409 fprintf(outfile,"}\n");
4412 if (tree->opval.op == NULLOP) {
4413 fprintf(outfile,"\n");
4414 ast_print(tree->left,outfile,indent);
4415 fprintf(outfile,"\n");
4416 ast_print(tree->right,outfile,indent);
4419 INDENT(indent,outfile);
4421 /*------------------------------------------------------------------*/
4422 /*----------------------------*/
4423 /* leaf has been reached */
4424 /*----------------------------*/
4425 /* if this is of type value */
4426 /* just get the type */
4427 if (tree->type == EX_VALUE) {
4429 if (IS_LITERAL (tree->opval.val->etype)) {
4430 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4431 (int) floatFromVal(tree->opval.val),
4432 (int) floatFromVal(tree->opval.val),
4433 floatFromVal(tree->opval.val));
4434 } else if (tree->opval.val->sym) {
4435 /* if the undefined flag is set then give error message */
4436 if (tree->opval.val->sym->undefined) {
4437 fprintf(outfile,"UNDEFINED SYMBOL ");
4439 fprintf(outfile,"SYMBOL ");
4441 fprintf(outfile,"(%s=%p)",
4442 tree->opval.val->sym->name,tree);
4445 fprintf(outfile," type (");
4446 printTypeChain(tree->ftype,outfile);
4447 fprintf(outfile,")\n");
4449 fprintf(outfile,"\n");
4454 /* if type link for the case of cast */
4455 if (tree->type == EX_LINK) {
4456 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4457 printTypeChain(tree->opval.lnk,outfile);
4458 fprintf(outfile,")\n");
4463 /* depending on type of operator do */
4465 switch (tree->opval.op) {
4466 /*------------------------------------------------------------------*/
4467 /*----------------------------*/
4469 /*----------------------------*/
4471 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4472 printTypeChain(tree->ftype,outfile);
4473 fprintf(outfile,")\n");
4474 ast_print(tree->left,outfile,indent+2);
4475 ast_print(tree->right,outfile,indent+2);
4478 /*------------------------------------------------------------------*/
4479 /*----------------------------*/
4481 /*----------------------------*/
4483 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4484 printTypeChain(tree->ftype,outfile);
4485 fprintf(outfile,")\n");
4486 ast_print(tree->left,outfile,indent+2);
4487 ast_print(tree->right,outfile,indent+2);
4490 /*------------------------------------------------------------------*/
4491 /*----------------------------*/
4492 /* struct/union pointer */
4493 /*----------------------------*/
4495 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4496 printTypeChain(tree->ftype,outfile);
4497 fprintf(outfile,")\n");
4498 ast_print(tree->left,outfile,indent+2);
4499 ast_print(tree->right,outfile,indent+2);
4502 /*------------------------------------------------------------------*/
4503 /*----------------------------*/
4504 /* ++/-- operation */
4505 /*----------------------------*/
4506 case INC_OP: /* incerement operator unary so left only */
4507 fprintf(outfile,"INC_OP (%p) type (",tree);
4508 printTypeChain(tree->ftype,outfile);
4509 fprintf(outfile,")\n");
4510 ast_print(tree->left,outfile,indent+2);
4514 fprintf(outfile,"DEC_OP (%p) type (",tree);
4515 printTypeChain(tree->ftype,outfile);
4516 fprintf(outfile,")\n");
4517 ast_print(tree->left,outfile,indent+2);
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4523 /*----------------------------*/
4526 fprintf(outfile,"& (%p) type (",tree);
4527 printTypeChain(tree->ftype,outfile);
4528 fprintf(outfile,")\n");
4529 ast_print(tree->left,outfile,indent+2);
4530 ast_print(tree->right,outfile,indent+2);
4532 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+2);
4536 ast_print(tree->right,outfile,indent+2);
4539 /*----------------------------*/
4541 /*----------------------------*/
4543 fprintf(outfile,"OR (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+2);
4547 ast_print(tree->right,outfile,indent+2);
4549 /*------------------------------------------------------------------*/
4550 /*----------------------------*/
4552 /*----------------------------*/
4554 fprintf(outfile,"XOR (%p) type (",tree);
4555 printTypeChain(tree->ftype,outfile);
4556 fprintf(outfile,")\n");
4557 ast_print(tree->left,outfile,indent+2);
4558 ast_print(tree->right,outfile,indent+2);
4561 /*------------------------------------------------------------------*/
4562 /*----------------------------*/
4564 /*----------------------------*/
4566 fprintf(outfile,"DIV (%p) type (",tree);
4567 printTypeChain(tree->ftype,outfile);
4568 fprintf(outfile,")\n");
4569 ast_print(tree->left,outfile,indent+2);
4570 ast_print(tree->right,outfile,indent+2);
4572 /*------------------------------------------------------------------*/
4573 /*----------------------------*/
4575 /*----------------------------*/
4577 fprintf(outfile,"MOD (%p) type (",tree);
4578 printTypeChain(tree->ftype,outfile);
4579 fprintf(outfile,")\n");
4580 ast_print(tree->left,outfile,indent+2);
4581 ast_print(tree->right,outfile,indent+2);
4584 /*------------------------------------------------------------------*/
4585 /*----------------------------*/
4586 /* address dereference */
4587 /*----------------------------*/
4588 case '*': /* can be unary : if right is null then unary operation */
4590 fprintf(outfile,"DEREF (%p) type (",tree);
4591 printTypeChain(tree->ftype,outfile);
4592 fprintf(outfile,")\n");
4593 ast_print(tree->left,outfile,indent+2);
4596 /*------------------------------------------------------------------*/
4597 /*----------------------------*/
4598 /* multiplication */
4599 /*----------------------------*/
4600 fprintf(outfile,"MULT (%p) type (",tree);
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->left,outfile,indent+2);
4604 ast_print(tree->right,outfile,indent+2);
4608 /*------------------------------------------------------------------*/
4609 /*----------------------------*/
4610 /* unary '+' operator */
4611 /*----------------------------*/
4615 fprintf(outfile,"UPLUS (%p) type (",tree);
4616 printTypeChain(tree->ftype,outfile);
4617 fprintf(outfile,")\n");
4618 ast_print(tree->left,outfile,indent+2);
4620 /*------------------------------------------------------------------*/
4621 /*----------------------------*/
4623 /*----------------------------*/
4624 fprintf(outfile,"ADD (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+2);
4628 ast_print(tree->right,outfile,indent+2);
4631 /*------------------------------------------------------------------*/
4632 /*----------------------------*/
4634 /*----------------------------*/
4635 case '-': /* can be unary */
4637 fprintf(outfile,"UMINUS (%p) type (",tree);
4638 printTypeChain(tree->ftype,outfile);
4639 fprintf(outfile,")\n");
4640 ast_print(tree->left,outfile,indent+2);
4642 /*------------------------------------------------------------------*/
4643 /*----------------------------*/
4645 /*----------------------------*/
4646 fprintf(outfile,"SUB (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+2);
4650 ast_print(tree->right,outfile,indent+2);
4653 /*------------------------------------------------------------------*/
4654 /*----------------------------*/
4656 /*----------------------------*/
4658 fprintf(outfile,"COMPL (%p) type (",tree);
4659 printTypeChain(tree->ftype,outfile);
4660 fprintf(outfile,")\n");
4661 ast_print(tree->left,outfile,indent+2);
4663 /*------------------------------------------------------------------*/
4664 /*----------------------------*/
4666 /*----------------------------*/
4668 fprintf(outfile,"NOT (%p) type (",tree);
4669 printTypeChain(tree->ftype,outfile);
4670 fprintf(outfile,")\n");
4671 ast_print(tree->left,outfile,indent+2);
4673 /*------------------------------------------------------------------*/
4674 /*----------------------------*/
4676 /*----------------------------*/
4678 fprintf(outfile,"RRC (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+2);
4685 fprintf(outfile,"RLC (%p) type (",tree);
4686 printTypeChain(tree->ftype,outfile);
4687 fprintf(outfile,")\n");
4688 ast_print(tree->left,outfile,indent+2);
4691 fprintf(outfile,"GETHBIT (%p) type (",tree);
4692 printTypeChain(tree->ftype,outfile);
4693 fprintf(outfile,")\n");
4694 ast_print(tree->left,outfile,indent+2);
4697 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4698 printTypeChain(tree->ftype,outfile);
4699 fprintf(outfile,")\n");
4700 ast_print(tree->left,outfile,indent+2);
4701 ast_print(tree->right,outfile,indent+2);
4704 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+2);
4708 ast_print(tree->right,outfile,indent+2);
4710 /*------------------------------------------------------------------*/
4711 /*----------------------------*/
4713 /*----------------------------*/
4714 case CAST: /* change the type */
4715 fprintf(outfile,"CAST (%p) from type (",tree);
4716 printTypeChain(tree->right->ftype,outfile);
4717 fprintf(outfile,") to type (");
4718 printTypeChain(tree->ftype,outfile);
4719 fprintf(outfile,")\n");
4720 ast_print(tree->right,outfile,indent+2);
4724 fprintf(outfile,"ANDAND (%p) type (",tree);
4725 printTypeChain(tree->ftype,outfile);
4726 fprintf(outfile,")\n");
4727 ast_print(tree->left,outfile,indent+2);
4728 ast_print(tree->right,outfile,indent+2);
4731 fprintf(outfile,"OROR (%p) type (",tree);
4732 printTypeChain(tree->ftype,outfile);
4733 fprintf(outfile,")\n");
4734 ast_print(tree->left,outfile,indent+2);
4735 ast_print(tree->right,outfile,indent+2);
4738 /*------------------------------------------------------------------*/
4739 /*----------------------------*/
4740 /* comparison operators */
4741 /*----------------------------*/
4743 fprintf(outfile,"GT(>) (%p) type (",tree);
4744 printTypeChain(tree->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->left,outfile,indent+2);
4747 ast_print(tree->right,outfile,indent+2);
4750 fprintf(outfile,"LT(<) (%p) type (",tree);
4751 printTypeChain(tree->ftype,outfile);
4752 fprintf(outfile,")\n");
4753 ast_print(tree->left,outfile,indent+2);
4754 ast_print(tree->right,outfile,indent+2);
4757 fprintf(outfile,"LE(<=) (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+2);
4761 ast_print(tree->right,outfile,indent+2);
4764 fprintf(outfile,"GE(>=) (%p) type (",tree);
4765 printTypeChain(tree->ftype,outfile);
4766 fprintf(outfile,")\n");
4767 ast_print(tree->left,outfile,indent+2);
4768 ast_print(tree->right,outfile,indent+2);
4771 fprintf(outfile,"EQ(==) (%p) type (",tree);
4772 printTypeChain(tree->ftype,outfile);
4773 fprintf(outfile,")\n");
4774 ast_print(tree->left,outfile,indent+2);
4775 ast_print(tree->right,outfile,indent+2);
4778 fprintf(outfile,"NE(!=) (%p) type (",tree);
4779 printTypeChain(tree->ftype,outfile);
4780 fprintf(outfile,")\n");
4781 ast_print(tree->left,outfile,indent+2);
4782 ast_print(tree->right,outfile,indent+2);
4783 /*------------------------------------------------------------------*/
4784 /*----------------------------*/
4786 /*----------------------------*/
4787 case SIZEOF: /* evaluate wihout code generation */
4788 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4791 /*------------------------------------------------------------------*/
4792 /*----------------------------*/
4793 /* conditional operator '?' */
4794 /*----------------------------*/
4796 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4797 printTypeChain(tree->ftype,outfile);
4798 fprintf(outfile,")\n");
4799 ast_print(tree->left,outfile,indent+2);
4800 ast_print(tree->right,outfile,indent+2);
4804 fprintf(outfile,"COLON(:) (%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);
4811 /*------------------------------------------------------------------*/
4812 /*----------------------------*/
4813 /* assignment operators */
4814 /*----------------------------*/
4816 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4817 printTypeChain(tree->ftype,outfile);
4818 fprintf(outfile,")\n");
4819 ast_print(tree->left,outfile,indent+2);
4820 ast_print(tree->right,outfile,indent+2);
4823 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4824 printTypeChain(tree->ftype,outfile);
4825 fprintf(outfile,")\n");
4826 ast_print(tree->left,outfile,indent+2);
4827 ast_print(tree->right,outfile,indent+2);
4830 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4831 printTypeChain(tree->ftype,outfile);
4832 fprintf(outfile,")\n");
4833 ast_print(tree->left,outfile,indent+2);
4834 ast_print(tree->right,outfile,indent+2);
4837 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4838 printTypeChain(tree->ftype,outfile);
4839 fprintf(outfile,")\n");
4840 ast_print(tree->left,outfile,indent+2);
4841 ast_print(tree->right,outfile,indent+2);
4844 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4845 printTypeChain(tree->ftype,outfile);
4846 fprintf(outfile,")\n");
4847 ast_print(tree->left,outfile,indent+2);
4848 ast_print(tree->right,outfile,indent+2);
4851 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4852 printTypeChain(tree->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 ast_print(tree->right,outfile,indent+2);
4858 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4859 printTypeChain(tree->ftype,outfile);
4860 fprintf(outfile,")\n");
4861 ast_print(tree->left,outfile,indent+2);
4862 ast_print(tree->right,outfile,indent+2);
4864 /*------------------------------------------------------------------*/
4865 /*----------------------------*/
4867 /*----------------------------*/
4869 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4870 printTypeChain(tree->ftype,outfile);
4871 fprintf(outfile,")\n");
4872 ast_print(tree->left,outfile,indent+2);
4873 ast_print(tree->right,outfile,indent+2);
4875 /*------------------------------------------------------------------*/
4876 /*----------------------------*/
4878 /*----------------------------*/
4880 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4881 printTypeChain(tree->ftype,outfile);
4882 fprintf(outfile,")\n");
4883 ast_print(tree->left,outfile,indent+2);
4884 ast_print(tree->right,outfile,indent+2);
4886 /*------------------------------------------------------------------*/
4887 /*----------------------------*/
4888 /* straight assignemnt */
4889 /*----------------------------*/
4891 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4892 printTypeChain(tree->ftype,outfile);
4893 fprintf(outfile,")\n");
4894 ast_print(tree->left,outfile,indent+2);
4895 ast_print(tree->right,outfile,indent+2);
4897 /*------------------------------------------------------------------*/
4898 /*----------------------------*/
4899 /* comma operator */
4900 /*----------------------------*/
4902 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4903 printTypeChain(tree->ftype,outfile);
4904 fprintf(outfile,")\n");
4905 ast_print(tree->left,outfile,indent+2);
4906 ast_print(tree->right,outfile,indent+2);
4908 /*------------------------------------------------------------------*/
4909 /*----------------------------*/
4911 /*----------------------------*/
4914 fprintf(outfile,"CALL (%p) type (",tree);
4915 printTypeChain(tree->ftype,outfile);
4916 fprintf(outfile,")\n");
4917 ast_print(tree->left,outfile,indent+2);
4918 ast_print(tree->right,outfile,indent+2);
4921 fprintf(outfile,"PARMS\n");
4922 ast_print(tree->left,outfile,indent+2);
4923 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4924 ast_print(tree->right,outfile,indent+2);
4927 /*------------------------------------------------------------------*/
4928 /*----------------------------*/
4929 /* return statement */
4930 /*----------------------------*/
4932 fprintf(outfile,"RETURN (%p) type (",tree);
4933 printTypeChain(tree->right->ftype,outfile);
4934 fprintf(outfile,")\n");
4935 ast_print(tree->right,outfile,indent+2);
4937 /*------------------------------------------------------------------*/
4938 /*----------------------------*/
4939 /* label statement */
4940 /*----------------------------*/
4942 fprintf(outfile,"LABEL (%p)\n",tree);
4943 ast_print(tree->left,outfile,indent+2);
4944 ast_print(tree->right,outfile,indent);
4946 /*------------------------------------------------------------------*/
4947 /*----------------------------*/
4948 /* switch statement */
4949 /*----------------------------*/
4953 fprintf(outfile,"SWITCH (%p) ",tree);
4954 ast_print(tree->left,outfile,0);
4955 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4956 INDENT(indent+2,outfile);
4957 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4958 (int) floatFromVal(val),
4959 tree->values.switchVals.swNum,
4960 (int) floatFromVal(val));
4962 ast_print(tree->right,outfile,indent);
4965 /*------------------------------------------------------------------*/
4966 /*----------------------------*/
4968 /*----------------------------*/
4970 fprintf(outfile,"IF (%p) \n",tree);
4971 ast_print(tree->left,outfile,indent+2);
4972 if (tree->trueLabel) {
4973 INDENT(indent,outfile);
4974 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4976 if (tree->falseLabel) {
4977 INDENT(indent,outfile);
4978 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4980 ast_print(tree->right,outfile,indent+2);
4982 /*------------------------------------------------------------------*/
4983 /*----------------------------*/
4985 /*----------------------------*/
4987 fprintf(outfile,"FOR (%p) \n",tree);
4988 if (AST_FOR( tree, initExpr)) {
4989 INDENT(indent+2,outfile);
4990 fprintf(outfile,"INIT EXPR ");
4991 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4993 if (AST_FOR( tree, condExpr)) {
4994 INDENT(indent+2,outfile);
4995 fprintf(outfile,"COND EXPR ");
4996 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4998 if (AST_FOR( tree, loopExpr)) {
4999 INDENT(indent+2,outfile);
5000 fprintf(outfile,"LOOP EXPR ");
5001 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5003 fprintf(outfile,"FOR LOOP BODY \n");
5004 ast_print(tree->left,outfile,indent+2);
5013 ast_print(t,stdout,0);