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) = GPOINTER;
720 if (IS_AGGREGATE (ftype))
722 newType = newAst_LINK (copyLinkChain (ftype));
723 DCL_TYPE (newType->opval.lnk) = GPOINTER;
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 /*-----------------------------------------------------------------*/
1061 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1063 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1067 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1069 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1070 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1071 "with -mmcs51 and --model-large\n");
1075 if (SPEC_OCLS(sym->etype)==xdata &&
1076 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1079 newSym=copySymbol (sym);
1080 SPEC_OCLS(newSym->etype)=code;
1081 sprintf (newSym->name, "%s_init__", sym->name);
1082 sprintf (newSym->rname,"%s_init__", sym->rname);
1083 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1085 // emit it in the static segment
1086 addSet(&statsg->syms, newSym);
1088 // now memcpy() the entire array from cseg
1089 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1090 newAst_VALUE (symbolVal (sym)),
1091 newAst_VALUE (symbolVal (newSym)));
1092 return decorateType(resolveSymbols(ast));
1096 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1099 /*-----------------------------------------------------------------*/
1100 /* gatherAutoInit - creates assignment expressions for initial */
1102 /*-----------------------------------------------------------------*/
1104 gatherAutoInit (symbol * autoChain)
1111 for (sym = autoChain; sym; sym = sym->next)
1114 /* resolve the symbols in the ival */
1116 resolveIvalSym (sym->ival);
1118 /* if this is a static variable & has an */
1119 /* initial value the code needs to be lifted */
1120 /* here to the main portion since they can be */
1121 /* initialised only once at the start */
1122 if (IS_STATIC (sym->etype) && sym->ival &&
1123 SPEC_SCLS (sym->etype) != S_CODE)
1127 // this can only be a constant
1128 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1129 werror (E_CONST_EXPECTED);
1132 /* insert the symbol into the symbol table */
1133 /* with level = 0 & name = rname */
1134 newSym = copySymbol (sym);
1135 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1137 /* now lift the code to main */
1138 if (IS_AGGREGATE (sym->type)) {
1139 work = initAggregates (sym, sym->ival, NULL);
1141 if (getNelements(sym->type, sym->ival)>1) {
1142 werror (W_EXCESS_INITIALIZERS, "scalar",
1143 sym->name, sym->lineDef);
1145 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1146 list2expr (sym->ival));
1149 setAstLineno (work, sym->lineDef);
1153 staticAutos = newNode (NULLOP, staticAutos, work);
1160 /* if there is an initial value */
1161 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1163 if (IS_AGGREGATE (sym->type)) {
1164 work = initAggregates (sym, sym->ival, NULL);
1166 if (getNelements(sym->type, sym->ival)>1) {
1167 werror (W_EXCESS_INITIALIZERS, "scalar",
1168 sym->name, sym->lineDef);
1170 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1171 list2expr (sym->ival));
1174 setAstLineno (work, sym->lineDef);
1177 init = newNode (NULLOP, init, work);
1186 /*-----------------------------------------------------------------*/
1187 /* stringToSymbol - creates a symbol from a literal string */
1188 /*-----------------------------------------------------------------*/
1190 stringToSymbol (value * val)
1192 char name[SDCC_NAME_MAX + 1];
1193 static int charLbl = 0;
1196 sprintf (name, "_str_%d", charLbl++);
1197 sym = newSymbol (name, 0); /* make it @ level 0 */
1198 strcpy (sym->rname, name);
1200 /* copy the type from the value passed */
1201 sym->type = copyLinkChain (val->type);
1202 sym->etype = getSpec (sym->type);
1203 /* change to storage class & output class */
1204 SPEC_SCLS (sym->etype) = S_CODE;
1205 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1206 SPEC_STAT (sym->etype) = 1;
1207 /* make the level & block = 0 */
1208 sym->block = sym->level = 0;
1210 /* create an ival */
1211 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1216 allocVariables (sym);
1219 return symbolVal (sym);
1223 /*-----------------------------------------------------------------*/
1224 /* processBlockVars - will go thru the ast looking for block if */
1225 /* a block is found then will allocate the syms */
1226 /* will also gather the auto inits present */
1227 /*-----------------------------------------------------------------*/
1229 processBlockVars (ast * tree, int *stack, int action)
1234 /* if this is a block */
1235 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1239 if (action == ALLOCATE)
1241 *stack += allocVariables (tree->values.sym);
1242 autoInit = gatherAutoInit (tree->values.sym);
1244 /* if there are auto inits then do them */
1246 tree->left = newNode (NULLOP, autoInit, tree->left);
1248 else /* action is deallocate */
1249 deallocLocal (tree->values.sym);
1252 processBlockVars (tree->left, stack, action);
1253 processBlockVars (tree->right, stack, action);
1257 /*-----------------------------------------------------------------*/
1258 /* constExprValue - returns the value of a constant expression */
1259 /* or NULL if it is not a constant expression */
1260 /*-----------------------------------------------------------------*/
1262 constExprValue (ast * cexpr, int check)
1264 cexpr = decorateType (resolveSymbols (cexpr));
1266 /* if this is not a constant then */
1267 if (!IS_LITERAL (cexpr->ftype))
1269 /* then check if this is a literal array
1271 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1272 SPEC_CVAL (cexpr->etype).v_char &&
1273 IS_ARRAY (cexpr->ftype))
1275 value *val = valFromType (cexpr->ftype);
1276 SPEC_SCLS (val->etype) = S_LITERAL;
1277 val->sym = cexpr->opval.val->sym;
1278 val->sym->type = copyLinkChain (cexpr->ftype);
1279 val->sym->etype = getSpec (val->sym->type);
1280 strcpy (val->name, cexpr->opval.val->sym->rname);
1284 /* if we are casting a literal value then */
1285 if (IS_AST_OP (cexpr) &&
1286 cexpr->opval.op == CAST &&
1287 IS_LITERAL (cexpr->left->ftype))
1288 return valCastLiteral (cexpr->ftype,
1289 floatFromVal (cexpr->left->opval.val));
1291 if (IS_AST_VALUE (cexpr))
1292 return cexpr->opval.val;
1295 werror (E_CONST_EXPECTED, "found expression");
1300 /* return the value */
1301 return cexpr->opval.val;
1305 /*-----------------------------------------------------------------*/
1306 /* isLabelInAst - will return true if a given label is found */
1307 /*-----------------------------------------------------------------*/
1309 isLabelInAst (symbol * label, ast * tree)
1311 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1314 if (IS_AST_OP (tree) &&
1315 tree->opval.op == LABEL &&
1316 isSymbolEqual (AST_SYMBOL (tree->left), label))
1319 return isLabelInAst (label, tree->right) &&
1320 isLabelInAst (label, tree->left);
1324 /*-----------------------------------------------------------------*/
1325 /* isLoopCountable - return true if the loop count can be determi- */
1326 /* -ned at compile time . */
1327 /*-----------------------------------------------------------------*/
1329 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1330 symbol ** sym, ast ** init, ast ** end)
1333 /* the loop is considered countable if the following
1334 conditions are true :-
1336 a) initExpr :- <sym> = <const>
1337 b) condExpr :- <sym> < <const1>
1338 c) loopExpr :- <sym> ++
1341 /* first check the initExpr */
1342 if (IS_AST_OP (initExpr) &&
1343 initExpr->opval.op == '=' && /* is assignment */
1344 IS_AST_SYM_VALUE (initExpr->left))
1345 { /* left is a symbol */
1347 *sym = AST_SYMBOL (initExpr->left);
1348 *init = initExpr->right;
1353 /* for now the symbol has to be of
1355 if (!IS_INTEGRAL ((*sym)->type))
1358 /* now check condExpr */
1359 if (IS_AST_OP (condExpr))
1362 switch (condExpr->opval.op)
1365 if (IS_AST_SYM_VALUE (condExpr->left) &&
1366 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1367 IS_AST_LIT_VALUE (condExpr->right))
1369 *end = condExpr->right;
1375 if (IS_AST_OP (condExpr->left) &&
1376 condExpr->left->opval.op == '>' &&
1377 IS_AST_LIT_VALUE (condExpr->left->right) &&
1378 IS_AST_SYM_VALUE (condExpr->left->left) &&
1379 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1382 *end = newNode ('+', condExpr->left->right,
1383 newAst_VALUE (constVal ("1")));
1394 /* check loop expression is of the form <sym>++ */
1395 if (!IS_AST_OP (loopExpr))
1398 /* check if <sym> ++ */
1399 if (loopExpr->opval.op == INC_OP)
1405 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1406 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1413 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1414 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1422 if (loopExpr->opval.op == ADD_ASSIGN)
1425 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1426 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1427 IS_AST_LIT_VALUE (loopExpr->right) &&
1428 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1436 /*-----------------------------------------------------------------*/
1437 /* astHasVolatile - returns true if ast contains any volatile */
1438 /*-----------------------------------------------------------------*/
1440 astHasVolatile (ast * tree)
1445 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1448 if (IS_AST_OP (tree))
1449 return astHasVolatile (tree->left) ||
1450 astHasVolatile (tree->right);
1455 /*-----------------------------------------------------------------*/
1456 /* astHasPointer - return true if the ast contains any ptr variable */
1457 /*-----------------------------------------------------------------*/
1459 astHasPointer (ast * tree)
1464 if (IS_AST_LINK (tree))
1467 /* if we hit an array expression then check
1468 only the left side */
1469 if (IS_AST_OP (tree) && tree->opval.op == '[')
1470 return astHasPointer (tree->left);
1472 if (IS_AST_VALUE (tree))
1473 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1475 return astHasPointer (tree->left) ||
1476 astHasPointer (tree->right);
1480 /*-----------------------------------------------------------------*/
1481 /* astHasSymbol - return true if the ast has the given symbol */
1482 /*-----------------------------------------------------------------*/
1484 astHasSymbol (ast * tree, symbol * sym)
1486 if (!tree || IS_AST_LINK (tree))
1489 if (IS_AST_VALUE (tree))
1491 if (IS_AST_SYM_VALUE (tree))
1492 return isSymbolEqual (AST_SYMBOL (tree), sym);
1497 return astHasSymbol (tree->left, sym) ||
1498 astHasSymbol (tree->right, sym);
1501 /*-----------------------------------------------------------------*/
1502 /* astHasDeref - return true if the ast has an indirect access */
1503 /*-----------------------------------------------------------------*/
1505 astHasDeref (ast * tree)
1507 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1510 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1512 return astHasDeref (tree->left) || astHasDeref (tree->right);
1515 /*-----------------------------------------------------------------*/
1516 /* isConformingBody - the loop body has to conform to a set of rules */
1517 /* for the loop to be considered reversible read on for rules */
1518 /*-----------------------------------------------------------------*/
1520 isConformingBody (ast * pbody, symbol * sym, ast * body)
1523 /* we are going to do a pre-order traversal of the
1524 tree && check for the following conditions. (essentially
1525 a set of very shallow tests )
1526 a) the sym passed does not participate in
1527 any arithmetic operation
1528 b) There are no function calls
1529 c) all jumps are within the body
1530 d) address of loop control variable not taken
1531 e) if an assignment has a pointer on the
1532 left hand side make sure right does not have
1533 loop control variable */
1535 /* if we reach the end or a leaf then true */
1536 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1540 /* if anything else is "volatile" */
1541 if (IS_VOLATILE (TETYPE (pbody)))
1544 /* we will walk the body in a pre-order traversal for
1546 switch (pbody->opval.op)
1548 /*------------------------------------------------------------------*/
1550 return isConformingBody (pbody->right, sym, body);
1552 /*------------------------------------------------------------------*/
1557 /*------------------------------------------------------------------*/
1558 case INC_OP: /* incerement operator unary so left only */
1561 /* sure we are not sym is not modified */
1563 IS_AST_SYM_VALUE (pbody->left) &&
1564 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1568 IS_AST_SYM_VALUE (pbody->right) &&
1569 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1574 /*------------------------------------------------------------------*/
1576 case '*': /* can be unary : if right is null then unary operation */
1581 /* if right is NULL then unary operation */
1582 /*------------------------------------------------------------------*/
1583 /*----------------------------*/
1585 /*----------------------------*/
1588 if (IS_AST_SYM_VALUE (pbody->left) &&
1589 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1592 return isConformingBody (pbody->left, sym, body);
1596 if (astHasSymbol (pbody->left, sym) ||
1597 astHasSymbol (pbody->right, sym))
1602 /*------------------------------------------------------------------*/
1610 if (IS_AST_SYM_VALUE (pbody->left) &&
1611 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1614 if (IS_AST_SYM_VALUE (pbody->right) &&
1615 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1618 return isConformingBody (pbody->left, sym, body) &&
1619 isConformingBody (pbody->right, sym, body);
1626 if (IS_AST_SYM_VALUE (pbody->left) &&
1627 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1629 return isConformingBody (pbody->left, sym, body);
1631 /*------------------------------------------------------------------*/
1643 case SIZEOF: /* evaluate wihout code generation */
1645 return isConformingBody (pbody->left, sym, body) &&
1646 isConformingBody (pbody->right, sym, body);
1648 /*------------------------------------------------------------------*/
1651 /* if left has a pointer & right has loop
1652 control variable then we cannot */
1653 if (astHasPointer (pbody->left) &&
1654 astHasSymbol (pbody->right, sym))
1656 if (astHasVolatile (pbody->left))
1659 if (IS_AST_SYM_VALUE (pbody->left) &&
1660 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1663 if (astHasVolatile (pbody->left))
1666 if (astHasDeref(pbody->right)) return FALSE;
1668 return isConformingBody (pbody->left, sym, body) &&
1669 isConformingBody (pbody->right, sym, body);
1680 assert ("Parser should not have generated this\n");
1682 /*------------------------------------------------------------------*/
1683 /*----------------------------*/
1684 /* comma operator */
1685 /*----------------------------*/
1687 return isConformingBody (pbody->left, sym, body) &&
1688 isConformingBody (pbody->right, sym, body);
1690 /*------------------------------------------------------------------*/
1691 /*----------------------------*/
1693 /*----------------------------*/
1697 /*------------------------------------------------------------------*/
1698 /*----------------------------*/
1699 /* return statement */
1700 /*----------------------------*/
1705 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1710 if (astHasSymbol (pbody->left, sym))
1717 return isConformingBody (pbody->left, sym, body) &&
1718 isConformingBody (pbody->right, sym, body);
1724 /*-----------------------------------------------------------------*/
1725 /* isLoopReversible - takes a for loop as input && returns true */
1726 /* if the for loop is reversible. If yes will set the value of */
1727 /* the loop control var & init value & termination value */
1728 /*-----------------------------------------------------------------*/
1730 isLoopReversible (ast * loop, symbol ** loopCntrl,
1731 ast ** init, ast ** end)
1733 /* if option says don't do it then don't */
1734 if (optimize.noLoopReverse)
1736 /* there are several tests to determine this */
1738 /* for loop has to be of the form
1739 for ( <sym> = <const1> ;
1740 [<sym> < <const2>] ;
1741 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1743 if (!isLoopCountable (AST_FOR (loop, initExpr),
1744 AST_FOR (loop, condExpr),
1745 AST_FOR (loop, loopExpr),
1746 loopCntrl, init, end))
1749 /* now do some serious checking on the body of the loop
1752 return isConformingBody (loop->left, *loopCntrl, loop->left);
1756 /*-----------------------------------------------------------------*/
1757 /* replLoopSym - replace the loop sym by loop sym -1 */
1758 /*-----------------------------------------------------------------*/
1760 replLoopSym (ast * body, symbol * sym)
1763 if (!body || IS_AST_LINK (body))
1766 if (IS_AST_SYM_VALUE (body))
1769 if (isSymbolEqual (AST_SYMBOL (body), sym))
1773 body->opval.op = '-';
1774 body->left = newAst_VALUE (symbolVal (sym));
1775 body->right = newAst_VALUE (constVal ("1"));
1783 replLoopSym (body->left, sym);
1784 replLoopSym (body->right, sym);
1788 /*-----------------------------------------------------------------*/
1789 /* reverseLoop - do the actual loop reversal */
1790 /*-----------------------------------------------------------------*/
1792 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1796 /* create the following tree
1801 if (sym) goto for_continue ;
1804 /* put it together piece by piece */
1805 rloop = newNode (NULLOP,
1806 createIf (newAst_VALUE (symbolVal (sym)),
1808 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1811 newAst_VALUE (symbolVal (sym)),
1814 replLoopSym (loop->left, sym);
1816 rloop = newNode (NULLOP,
1818 newAst_VALUE (symbolVal (sym)),
1819 newNode ('-', end, init)),
1820 createLabel (AST_FOR (loop, continueLabel),
1824 newNode (SUB_ASSIGN,
1825 newAst_VALUE (symbolVal (sym)),
1826 newAst_VALUE (constVal ("1"))),
1829 return decorateType (rloop);
1833 //#define DEMAND_INTEGER_PROMOTION
1835 #ifdef DEMAND_INTEGER_PROMOTION
1837 /*-----------------------------------------------------------------*/
1838 /* walk a tree looking for the leaves. Add a typecast to the given */
1839 /* type to each value leaf node. */
1840 /*-----------------------------------------------------------------*/
1842 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1844 if (!node || IS_CALLOP(node))
1846 /* WTF? We should never get here. */
1850 if (!node->left && !node->right)
1852 /* We're at a leaf; if it's a value, apply the typecast */
1853 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1855 *parentPtr = decorateType (newNode (CAST,
1856 newAst_LINK (copyLinkChain (type)),
1864 pushTypeCastToLeaves (type, node->left, &(node->left));
1868 pushTypeCastToLeaves (type, node->right, &(node->right));
1875 /*-----------------------------------------------------------------*/
1876 /* decorateType - compute type for this tree also does type cheking */
1877 /* this is done bottom up, since type have to flow upwards */
1878 /* it also does constant folding, and paramater checking */
1879 /*-----------------------------------------------------------------*/
1881 decorateType (ast * tree)
1889 /* if already has type then do nothing */
1890 if (tree->decorated)
1893 tree->decorated = 1;
1895 /* print the line */
1896 /* if not block & function */
1897 if (tree->type == EX_OP &&
1898 (tree->opval.op != FUNCTION &&
1899 tree->opval.op != BLOCK &&
1900 tree->opval.op != NULLOP))
1902 filename = tree->filename;
1903 lineno = tree->lineno;
1906 /* if any child is an error | this one is an error do nothing */
1907 if (tree->isError ||
1908 (tree->left && tree->left->isError) ||
1909 (tree->right && tree->right->isError))
1912 /*------------------------------------------------------------------*/
1913 /*----------------------------*/
1914 /* leaf has been reached */
1915 /*----------------------------*/
1916 /* if this is of type value */
1917 /* just get the type */
1918 if (tree->type == EX_VALUE)
1921 if (IS_LITERAL (tree->opval.val->etype))
1924 /* if this is a character array then declare it */
1925 if (IS_ARRAY (tree->opval.val->type))
1926 tree->opval.val = stringToSymbol (tree->opval.val);
1928 /* otherwise just copy the type information */
1929 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1933 if (tree->opval.val->sym)
1935 /* if the undefined flag is set then give error message */
1936 if (tree->opval.val->sym->undefined)
1938 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1940 TTYPE (tree) = TETYPE (tree) =
1941 tree->opval.val->type = tree->opval.val->sym->type =
1942 tree->opval.val->etype = tree->opval.val->sym->etype =
1943 copyLinkChain (INTTYPE);
1948 /* if impilicit i.e. struct/union member then no type */
1949 if (tree->opval.val->sym->implicit)
1950 TTYPE (tree) = TETYPE (tree) = NULL;
1955 /* else copy the type */
1956 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1958 /* and mark it as referenced */
1959 tree->opval.val->sym->isref = 1;
1967 /* if type link for the case of cast */
1968 if (tree->type == EX_LINK)
1970 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1977 dtl = decorateType (tree->left);
1978 dtr = decorateType (tree->right);
1980 /* this is to take care of situations
1981 when the tree gets rewritten */
1982 if (dtl != tree->left)
1984 if (dtr != tree->right)
1988 /* depending on type of operator do */
1990 switch (tree->opval.op)
1992 /*------------------------------------------------------------------*/
1993 /*----------------------------*/
1995 /*----------------------------*/
1998 /* determine which is the array & which the index */
1999 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2002 ast *tempTree = tree->left;
2003 tree->left = tree->right;
2004 tree->right = tempTree;
2007 /* first check if this is a array or a pointer */
2008 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2010 werror (E_NEED_ARRAY_PTR, "[]");
2011 goto errorTreeReturn;
2014 /* check if the type of the idx */
2015 if (!IS_INTEGRAL (RTYPE (tree)))
2017 werror (E_IDX_NOT_INT);
2018 goto errorTreeReturn;
2021 /* if the left is an rvalue then error */
2024 werror (E_LVALUE_REQUIRED, "array access");
2025 goto errorTreeReturn;
2028 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2029 if (IS_PTR(LTYPE(tree))) {
2030 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2034 /*------------------------------------------------------------------*/
2035 /*----------------------------*/
2037 /*----------------------------*/
2039 /* if this is not a structure */
2040 if (!IS_STRUCT (LTYPE (tree)))
2042 werror (E_STRUCT_UNION, ".");
2043 goto errorTreeReturn;
2045 TTYPE (tree) = structElemType (LTYPE (tree),
2046 (tree->right->type == EX_VALUE ?
2047 tree->right->opval.val : NULL));
2048 TETYPE (tree) = getSpec (TTYPE (tree));
2051 /*------------------------------------------------------------------*/
2052 /*----------------------------*/
2053 /* struct/union pointer */
2054 /*----------------------------*/
2056 /* if not pointer to a structure */
2057 if (!IS_PTR (LTYPE (tree)))
2059 werror (E_PTR_REQD);
2060 goto errorTreeReturn;
2063 if (!IS_STRUCT (LTYPE (tree)->next))
2065 werror (E_STRUCT_UNION, "->");
2066 goto errorTreeReturn;
2069 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2070 (tree->right->type == EX_VALUE ?
2071 tree->right->opval.val : NULL));
2072 TETYPE (tree) = getSpec (TTYPE (tree));
2075 /*------------------------------------------------------------------*/
2076 /*----------------------------*/
2077 /* ++/-- operation */
2078 /*----------------------------*/
2079 case INC_OP: /* incerement operator unary so left only */
2082 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2083 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2084 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2085 werror (E_CODE_WRITE, "++/--");
2094 /*------------------------------------------------------------------*/
2095 /*----------------------------*/
2097 /*----------------------------*/
2098 case '&': /* can be unary */
2099 /* if right is NULL then unary operation */
2100 if (tree->right) /* not an unary operation */
2103 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2105 werror (E_BITWISE_OP);
2106 werror (W_CONTINUE, "left & right types are ");
2107 printTypeChain (LTYPE (tree), stderr);
2108 fprintf (stderr, ",");
2109 printTypeChain (RTYPE (tree), stderr);
2110 fprintf (stderr, "\n");
2111 goto errorTreeReturn;
2114 /* if they are both literal */
2115 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2117 tree->type = EX_VALUE;
2118 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2119 valFromType (RETYPE (tree)), '&');
2121 tree->right = tree->left = NULL;
2122 TETYPE (tree) = tree->opval.val->etype;
2123 TTYPE (tree) = tree->opval.val->type;
2127 /* see if this is a GETHBIT operation if yes
2130 ast *otree = optimizeGetHbit (tree);
2133 return decorateType (otree);
2137 computeType (LTYPE (tree), RTYPE (tree));
2138 TETYPE (tree) = getSpec (TTYPE (tree));
2140 LRVAL (tree) = RRVAL (tree) = 1;
2144 /*------------------------------------------------------------------*/
2145 /*----------------------------*/
2147 /*----------------------------*/
2149 p->class = DECLARATOR;
2150 /* if bit field then error */
2151 if (IS_BITVAR (tree->left->etype))
2153 werror (E_ILLEGAL_ADDR, "address of bit variable");
2154 goto errorTreeReturn;
2157 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2159 werror (E_ILLEGAL_ADDR, "address of register variable");
2160 goto errorTreeReturn;
2163 if (IS_FUNC (LTYPE (tree)))
2165 werror (E_ILLEGAL_ADDR, "address of function");
2166 goto errorTreeReturn;
2169 if (IS_LITERAL(LTYPE(tree)))
2171 werror (E_ILLEGAL_ADDR, "address of literal");
2172 goto errorTreeReturn;
2177 werror (E_LVALUE_REQUIRED, "address of");
2178 goto errorTreeReturn;
2180 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2182 DCL_TYPE (p) = CPOINTER;
2183 DCL_PTR_CONST (p) = port->mem.code_ro;
2185 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2186 DCL_TYPE (p) = FPOINTER;
2187 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2188 DCL_TYPE (p) = PPOINTER;
2189 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2190 DCL_TYPE (p) = IPOINTER;
2191 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2192 DCL_TYPE (p) = EEPPOINTER;
2193 else if (SPEC_OCLS(tree->left->etype))
2194 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2196 DCL_TYPE (p) = POINTER;
2198 if (IS_AST_SYM_VALUE (tree->left))
2200 AST_SYMBOL (tree->left)->addrtaken = 1;
2201 AST_SYMBOL (tree->left)->allocreq = 1;
2204 p->next = LTYPE (tree);
2206 TETYPE (tree) = getSpec (TTYPE (tree));
2207 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2208 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2213 /*------------------------------------------------------------------*/
2214 /*----------------------------*/
2216 /*----------------------------*/
2218 /* if the rewrite succeeds then don't go any furthur */
2220 ast *wtree = optimizeRRCRLC (tree);
2222 return decorateType (wtree);
2224 /*------------------------------------------------------------------*/
2225 /*----------------------------*/
2227 /*----------------------------*/
2229 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2231 werror (E_BITWISE_OP);
2232 werror (W_CONTINUE, "left & right types are ");
2233 printTypeChain (LTYPE (tree), stderr);
2234 fprintf (stderr, ",");
2235 printTypeChain (RTYPE (tree), stderr);
2236 fprintf (stderr, "\n");
2237 goto errorTreeReturn;
2240 /* if they are both literal then */
2241 /* rewrite the tree */
2242 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2244 tree->type = EX_VALUE;
2245 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2246 valFromType (RETYPE (tree)),
2248 tree->right = tree->left = NULL;
2249 TETYPE (tree) = tree->opval.val->etype;
2250 TTYPE (tree) = tree->opval.val->type;
2253 LRVAL (tree) = RRVAL (tree) = 1;
2254 TETYPE (tree) = getSpec (TTYPE (tree) =
2255 computeType (LTYPE (tree),
2258 /*------------------------------------------------------------------*/
2259 /*----------------------------*/
2261 /*----------------------------*/
2263 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2265 werror (E_INVALID_OP, "divide");
2266 goto errorTreeReturn;
2268 /* if they are both literal then */
2269 /* rewrite the tree */
2270 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2272 tree->type = EX_VALUE;
2273 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2274 valFromType (RETYPE (tree)));
2275 tree->right = tree->left = NULL;
2276 TETYPE (tree) = getSpec (TTYPE (tree) =
2277 tree->opval.val->type);
2280 LRVAL (tree) = RRVAL (tree) = 1;
2281 TETYPE (tree) = getSpec (TTYPE (tree) =
2282 computeType (LTYPE (tree),
2286 /*------------------------------------------------------------------*/
2287 /*----------------------------*/
2289 /*----------------------------*/
2291 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2293 werror (E_BITWISE_OP);
2294 werror (W_CONTINUE, "left & right types are ");
2295 printTypeChain (LTYPE (tree), stderr);
2296 fprintf (stderr, ",");
2297 printTypeChain (RTYPE (tree), stderr);
2298 fprintf (stderr, "\n");
2299 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 = valMod (valFromType (LETYPE (tree)),
2307 valFromType (RETYPE (tree)));
2308 tree->right = tree->left = NULL;
2309 TETYPE (tree) = getSpec (TTYPE (tree) =
2310 tree->opval.val->type);
2313 LRVAL (tree) = RRVAL (tree) = 1;
2314 TETYPE (tree) = getSpec (TTYPE (tree) =
2315 computeType (LTYPE (tree),
2319 /*------------------------------------------------------------------*/
2320 /*----------------------------*/
2321 /* address dereference */
2322 /*----------------------------*/
2323 case '*': /* can be unary : if right is null then unary operation */
2326 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2328 werror (E_PTR_REQD);
2329 goto errorTreeReturn;
2334 werror (E_LVALUE_REQUIRED, "pointer deref");
2335 goto errorTreeReturn;
2337 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2338 LTYPE (tree)->next : NULL);
2339 TETYPE (tree) = getSpec (TTYPE (tree));
2340 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2344 /*------------------------------------------------------------------*/
2345 /*----------------------------*/
2346 /* multiplication */
2347 /*----------------------------*/
2348 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2350 werror (E_INVALID_OP, "multiplication");
2351 goto errorTreeReturn;
2354 /* if they are both literal then */
2355 /* rewrite the tree */
2356 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2358 tree->type = EX_VALUE;
2359 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2360 valFromType (RETYPE (tree)));
2361 tree->right = tree->left = NULL;
2362 TETYPE (tree) = getSpec (TTYPE (tree) =
2363 tree->opval.val->type);
2367 /* if left is a literal exchange left & right */
2368 if (IS_LITERAL (LTYPE (tree)))
2370 ast *tTree = tree->left;
2371 tree->left = tree->right;
2372 tree->right = tTree;
2375 LRVAL (tree) = RRVAL (tree) = 1;
2376 /* promote result to int if left & right are char
2377 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2378 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2379 TETYPE (tree) = getSpec (TTYPE (tree) =
2380 computeType (LTYPE (tree),
2382 SPEC_NOUN(TETYPE(tree)) = V_INT;
2384 TETYPE (tree) = getSpec (TTYPE (tree) =
2385 computeType (LTYPE (tree),
2390 /*------------------------------------------------------------------*/
2391 /*----------------------------*/
2392 /* unary '+' operator */
2393 /*----------------------------*/
2398 if (!IS_INTEGRAL (LTYPE (tree)))
2400 werror (E_UNARY_OP, '+');
2401 goto errorTreeReturn;
2404 /* if left is a literal then do it */
2405 if (IS_LITERAL (LTYPE (tree)))
2407 tree->type = EX_VALUE;
2408 tree->opval.val = valFromType (LETYPE (tree));
2410 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2414 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2418 /*------------------------------------------------------------------*/
2419 /*----------------------------*/
2421 /*----------------------------*/
2423 /* this is not a unary operation */
2424 /* if both pointers then problem */
2425 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2426 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2428 werror (E_PTR_PLUS_PTR);
2429 goto errorTreeReturn;
2432 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2433 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2435 werror (E_PLUS_INVALID, "+");
2436 goto errorTreeReturn;
2439 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2440 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2442 werror (E_PLUS_INVALID, "+");
2443 goto errorTreeReturn;
2445 /* if they are both literal then */
2446 /* rewrite the tree */
2447 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2449 tree->type = EX_VALUE;
2450 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2451 valFromType (RETYPE (tree)));
2452 tree->right = tree->left = NULL;
2453 TETYPE (tree) = getSpec (TTYPE (tree) =
2454 tree->opval.val->type);
2458 /* if the right is a pointer or left is a literal
2459 xchange left & right */
2460 if (IS_ARRAY (RTYPE (tree)) ||
2461 IS_PTR (RTYPE (tree)) ||
2462 IS_LITERAL (LTYPE (tree)))
2464 ast *tTree = tree->left;
2465 tree->left = tree->right;
2466 tree->right = tTree;
2469 LRVAL (tree) = RRVAL (tree) = 1;
2470 /* if the left is a pointer */
2471 if (IS_PTR (LTYPE (tree)))
2472 TETYPE (tree) = getSpec (TTYPE (tree) =
2475 TETYPE (tree) = getSpec (TTYPE (tree) =
2476 computeType (LTYPE (tree),
2480 /*------------------------------------------------------------------*/
2481 /*----------------------------*/
2483 /*----------------------------*/
2484 case '-': /* can be unary */
2485 /* if right is null then unary */
2489 if (!IS_ARITHMETIC (LTYPE (tree)))
2491 werror (E_UNARY_OP, tree->opval.op);
2492 goto errorTreeReturn;
2495 /* if left is a literal then do it */
2496 if (IS_LITERAL (LTYPE (tree)))
2498 tree->type = EX_VALUE;
2499 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2501 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2502 SPEC_USIGN(TETYPE(tree)) = 0;
2506 TTYPE (tree) = LTYPE (tree);
2510 /*------------------------------------------------------------------*/
2511 /*----------------------------*/
2513 /*----------------------------*/
2515 if (!(IS_PTR (LTYPE (tree)) ||
2516 IS_ARRAY (LTYPE (tree)) ||
2517 IS_ARITHMETIC (LTYPE (tree))))
2519 werror (E_PLUS_INVALID, "-");
2520 goto errorTreeReturn;
2523 if (!(IS_PTR (RTYPE (tree)) ||
2524 IS_ARRAY (RTYPE (tree)) ||
2525 IS_ARITHMETIC (RTYPE (tree))))
2527 werror (E_PLUS_INVALID, "-");
2528 goto errorTreeReturn;
2531 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2532 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2533 IS_INTEGRAL (RTYPE (tree))))
2535 werror (E_PLUS_INVALID, "-");
2536 goto errorTreeReturn;
2539 /* if they are both literal then */
2540 /* rewrite the tree */
2541 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2543 tree->type = EX_VALUE;
2544 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2545 valFromType (RETYPE (tree)));
2546 tree->right = tree->left = NULL;
2547 TETYPE (tree) = getSpec (TTYPE (tree) =
2548 tree->opval.val->type);
2552 /* if the left & right are equal then zero */
2553 if (isAstEqual (tree->left, tree->right))
2555 tree->type = EX_VALUE;
2556 tree->left = tree->right = NULL;
2557 tree->opval.val = constVal ("0");
2558 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2562 /* if both of them are pointers or arrays then */
2563 /* the result is going to be an integer */
2564 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2565 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2566 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2568 /* if only the left is a pointer */
2569 /* then result is a pointer */
2570 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2571 TETYPE (tree) = getSpec (TTYPE (tree) =
2574 TETYPE (tree) = getSpec (TTYPE (tree) =
2575 computeType (LTYPE (tree),
2577 LRVAL (tree) = RRVAL (tree) = 1;
2580 /*------------------------------------------------------------------*/
2581 /*----------------------------*/
2583 /*----------------------------*/
2585 /* can be only integral type */
2586 if (!IS_INTEGRAL (LTYPE (tree)))
2588 werror (E_UNARY_OP, tree->opval.op);
2589 goto errorTreeReturn;
2592 /* if left is a literal then do it */
2593 if (IS_LITERAL (LTYPE (tree)))
2595 tree->type = EX_VALUE;
2596 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2598 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2602 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2605 /*------------------------------------------------------------------*/
2606 /*----------------------------*/
2608 /*----------------------------*/
2610 /* can be pointer */
2611 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2612 !IS_PTR (LTYPE (tree)) &&
2613 !IS_ARRAY (LTYPE (tree)))
2615 werror (E_UNARY_OP, tree->opval.op);
2616 goto errorTreeReturn;
2619 /* if left is a literal then do it */
2620 if (IS_LITERAL (LTYPE (tree)))
2622 tree->type = EX_VALUE;
2623 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2625 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2629 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2632 /*------------------------------------------------------------------*/
2633 /*----------------------------*/
2635 /*----------------------------*/
2638 TTYPE (tree) = LTYPE (tree);
2639 TETYPE (tree) = LETYPE (tree);
2643 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2648 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2650 werror (E_SHIFT_OP_INVALID);
2651 werror (W_CONTINUE, "left & right types are ");
2652 printTypeChain (LTYPE (tree), stderr);
2653 fprintf (stderr, ",");
2654 printTypeChain (RTYPE (tree), stderr);
2655 fprintf (stderr, "\n");
2656 goto errorTreeReturn;
2659 /* if they are both literal then */
2660 /* rewrite the tree */
2661 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2663 tree->type = EX_VALUE;
2664 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2665 valFromType (RETYPE (tree)),
2666 (tree->opval.op == LEFT_OP ? 1 : 0));
2667 tree->right = tree->left = NULL;
2668 TETYPE (tree) = getSpec (TTYPE (tree) =
2669 tree->opval.val->type);
2672 /* if only the right side is a literal & we are
2673 shifting more than size of the left operand then zero */
2674 if (IS_LITERAL (RTYPE (tree)) &&
2675 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2676 (getSize (LTYPE (tree)) * 8))
2678 werror (W_SHIFT_CHANGED,
2679 (tree->opval.op == LEFT_OP ? "left" : "right"));
2680 tree->type = EX_VALUE;
2681 tree->left = tree->right = NULL;
2682 tree->opval.val = constVal ("0");
2683 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2686 LRVAL (tree) = RRVAL (tree) = 1;
2687 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2689 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2693 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2697 /*------------------------------------------------------------------*/
2698 /*----------------------------*/
2700 /*----------------------------*/
2701 case CAST: /* change the type */
2702 /* cannot cast to an aggregate type */
2703 if (IS_AGGREGATE (LTYPE (tree)))
2705 werror (E_CAST_ILLEGAL);
2706 goto errorTreeReturn;
2709 /* make sure the type is complete and sane */
2710 checkTypeSanity(LETYPE(tree), "(cast)");
2713 /* if the right is a literal replace the tree */
2714 if (IS_LITERAL (RETYPE (tree))) {
2715 if (!IS_PTR (LTYPE (tree))) {
2716 tree->type = EX_VALUE;
2718 valCastLiteral (LTYPE (tree),
2719 floatFromVal (valFromType (RETYPE (tree))));
2722 TTYPE (tree) = tree->opval.val->type;
2723 tree->values.literalFromCast = 1;
2724 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2725 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2726 sym_link *rest = LTYPE(tree)->next;
2727 werror(W_LITERAL_GENERIC);
2728 TTYPE(tree) = newLink();
2729 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2730 TTYPE(tree)->next = rest;
2731 tree->left->opval.lnk = TTYPE(tree);
2734 TTYPE (tree) = LTYPE (tree);
2738 TTYPE (tree) = LTYPE (tree);
2742 /* if pointer to struct then check names */
2743 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2744 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2745 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2746 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2748 /* if the right is a literal replace the tree */
2749 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2750 tree->type = EX_VALUE;
2752 valCastLiteral (LTYPE (tree),
2753 floatFromVal (valFromType (RETYPE (tree))));
2756 TTYPE (tree) = tree->opval.val->type;
2757 tree->values.literalFromCast = 1;
2759 TTYPE (tree) = LTYPE (tree);
2763 TETYPE (tree) = getSpec (TTYPE (tree));
2767 /*------------------------------------------------------------------*/
2768 /*----------------------------*/
2769 /* logical &&, || */
2770 /*----------------------------*/
2773 /* each must me arithmetic type or be a pointer */
2774 if (!IS_PTR (LTYPE (tree)) &&
2775 !IS_ARRAY (LTYPE (tree)) &&
2776 !IS_INTEGRAL (LTYPE (tree)))
2778 werror (E_COMPARE_OP);
2779 goto errorTreeReturn;
2782 if (!IS_PTR (RTYPE (tree)) &&
2783 !IS_ARRAY (RTYPE (tree)) &&
2784 !IS_INTEGRAL (RTYPE (tree)))
2786 werror (E_COMPARE_OP);
2787 goto errorTreeReturn;
2789 /* if they are both literal then */
2790 /* rewrite the tree */
2791 if (IS_LITERAL (RTYPE (tree)) &&
2792 IS_LITERAL (LTYPE (tree)))
2794 tree->type = EX_VALUE;
2795 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2796 valFromType (RETYPE (tree)),
2798 tree->right = tree->left = NULL;
2799 TETYPE (tree) = getSpec (TTYPE (tree) =
2800 tree->opval.val->type);
2803 LRVAL (tree) = RRVAL (tree) = 1;
2804 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2807 /*------------------------------------------------------------------*/
2808 /*----------------------------*/
2809 /* comparison operators */
2810 /*----------------------------*/
2818 ast *lt = optimizeCompare (tree);
2824 /* if they are pointers they must be castable */
2825 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2827 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2829 werror (E_COMPARE_OP);
2830 fprintf (stderr, "comparing type ");
2831 printTypeChain (LTYPE (tree), stderr);
2832 fprintf (stderr, "to type ");
2833 printTypeChain (RTYPE (tree), stderr);
2834 fprintf (stderr, "\n");
2835 goto errorTreeReturn;
2838 /* else they should be promotable to one another */
2841 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2842 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2844 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2846 werror (E_COMPARE_OP);
2847 fprintf (stderr, "comparing type ");
2848 printTypeChain (LTYPE (tree), stderr);
2849 fprintf (stderr, "to type ");
2850 printTypeChain (RTYPE (tree), stderr);
2851 fprintf (stderr, "\n");
2852 goto errorTreeReturn;
2856 /* if they are both literal then */
2857 /* rewrite the tree */
2858 if (IS_LITERAL (RTYPE (tree)) &&
2859 IS_LITERAL (LTYPE (tree)))
2861 tree->type = EX_VALUE;
2862 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2863 valFromType (RETYPE (tree)),
2865 tree->right = tree->left = NULL;
2866 TETYPE (tree) = getSpec (TTYPE (tree) =
2867 tree->opval.val->type);
2870 LRVAL (tree) = RRVAL (tree) = 1;
2871 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2874 /*------------------------------------------------------------------*/
2875 /*----------------------------*/
2877 /*----------------------------*/
2878 case SIZEOF: /* evaluate wihout code generation */
2879 /* change the type to a integer */
2880 tree->type = EX_VALUE;
2881 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2882 tree->opval.val = constVal (buffer);
2883 tree->right = tree->left = NULL;
2884 TETYPE (tree) = getSpec (TTYPE (tree) =
2885 tree->opval.val->type);
2888 /*------------------------------------------------------------------*/
2889 /*----------------------------*/
2890 /* conditional operator '?' */
2891 /*----------------------------*/
2893 /* the type is value of the colon operator (on the right) */
2894 assert(IS_COLON_OP(tree->right));
2895 /* if already known then replace the tree : optimizer will do it
2896 but faster to do it here */
2897 if (IS_LITERAL (LTYPE(tree))) {
2898 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2899 return tree->right->left ;
2901 return tree->right->right ;
2904 TTYPE (tree) = RTYPE(tree);
2905 TETYPE (tree) = getSpec (TTYPE (tree));
2910 /* if they don't match we have a problem */
2911 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2913 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2914 goto errorTreeReturn;
2917 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2918 TETYPE (tree) = getSpec (TTYPE (tree));
2922 /*------------------------------------------------------------------*/
2923 /*----------------------------*/
2924 /* assignment operators */
2925 /*----------------------------*/
2928 /* for these it must be both must be integral */
2929 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2930 !IS_ARITHMETIC (RTYPE (tree)))
2932 werror (E_OPS_INTEGRAL);
2933 goto errorTreeReturn;
2936 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2938 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2939 werror (E_CODE_WRITE, " ");
2943 werror (E_LVALUE_REQUIRED, "*= or /=");
2944 goto errorTreeReturn;
2955 /* for these it must be both must be integral */
2956 if (!IS_INTEGRAL (LTYPE (tree)) ||
2957 !IS_INTEGRAL (RTYPE (tree)))
2959 werror (E_OPS_INTEGRAL);
2960 goto errorTreeReturn;
2963 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2965 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2966 werror (E_CODE_WRITE, " ");
2970 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2971 goto errorTreeReturn;
2977 /*------------------------------------------------------------------*/
2978 /*----------------------------*/
2980 /*----------------------------*/
2982 if (!(IS_PTR (LTYPE (tree)) ||
2983 IS_ARITHMETIC (LTYPE (tree))))
2985 werror (E_PLUS_INVALID, "-=");
2986 goto errorTreeReturn;
2989 if (!(IS_PTR (RTYPE (tree)) ||
2990 IS_ARITHMETIC (RTYPE (tree))))
2992 werror (E_PLUS_INVALID, "-=");
2993 goto errorTreeReturn;
2996 TETYPE (tree) = getSpec (TTYPE (tree) =
2997 computeType (LTYPE (tree),
3000 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3001 werror (E_CODE_WRITE, " ");
3005 werror (E_LVALUE_REQUIRED, "-=");
3006 goto errorTreeReturn;
3012 /*------------------------------------------------------------------*/
3013 /*----------------------------*/
3015 /*----------------------------*/
3017 /* this is not a unary operation */
3018 /* if both pointers then problem */
3019 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3021 werror (E_PTR_PLUS_PTR);
3022 goto errorTreeReturn;
3025 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3027 werror (E_PLUS_INVALID, "+=");
3028 goto errorTreeReturn;
3031 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3033 werror (E_PLUS_INVALID, "+=");
3034 goto errorTreeReturn;
3037 TETYPE (tree) = getSpec (TTYPE (tree) =
3038 computeType (LTYPE (tree),
3041 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3042 werror (E_CODE_WRITE, " ");
3046 werror (E_LVALUE_REQUIRED, "+=");
3047 goto errorTreeReturn;
3050 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3051 tree->opval.op = '=';
3055 /*------------------------------------------------------------------*/
3056 /*----------------------------*/
3057 /* straight assignemnt */
3058 /*----------------------------*/
3060 /* cannot be an aggregate */
3061 if (IS_AGGREGATE (LTYPE (tree)))
3063 werror (E_AGGR_ASSIGN);
3064 goto errorTreeReturn;
3067 /* they should either match or be castable */
3068 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3070 werror (E_TYPE_MISMATCH, "assignment", " ");
3071 fprintf (stderr, "type --> '");
3072 printTypeChain (RTYPE (tree), stderr);
3073 fprintf (stderr, "' ");
3074 fprintf (stderr, "assigned to type --> '");
3075 printTypeChain (LTYPE (tree), stderr);
3076 fprintf (stderr, "'\n");
3077 goto errorTreeReturn;
3080 /* if the left side of the tree is of type void
3081 then report error */
3082 if (IS_VOID (LTYPE (tree)))
3084 werror (E_CAST_ZERO);
3085 printFromToType(RTYPE(tree), LTYPE(tree));
3088 TETYPE (tree) = getSpec (TTYPE (tree) =
3092 if (!tree->initMode ) {
3093 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3094 werror (E_CODE_WRITE, " ");
3098 werror (E_LVALUE_REQUIRED, "=");
3099 goto errorTreeReturn;
3104 /*------------------------------------------------------------------*/
3105 /*----------------------------*/
3106 /* comma operator */
3107 /*----------------------------*/
3109 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3112 /*------------------------------------------------------------------*/
3113 /*----------------------------*/
3115 /*----------------------------*/
3119 if (processParms (tree->left,
3120 FUNC_ARGS(tree->left->ftype),
3121 tree->right, &parmNumber, TRUE)) {
3122 goto errorTreeReturn;
3125 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3127 //FUNC_ARGS(tree->left->ftype) =
3128 //reverseVal (FUNC_ARGS(tree->left->ftype));
3129 reverseParms (tree->right);
3132 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3135 /*------------------------------------------------------------------*/
3136 /*----------------------------*/
3137 /* return statement */
3138 /*----------------------------*/
3143 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3145 werror (W_RETURN_MISMATCH);
3146 printFromToType (RTYPE(tree), currFunc->type->next);
3147 goto errorTreeReturn;
3150 if (IS_VOID (currFunc->type->next)
3152 !IS_VOID (RTYPE (tree)))
3154 werror (E_FUNC_VOID);
3155 goto errorTreeReturn;
3158 /* if there is going to be a casing required then add it */
3159 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3162 decorateType (newNode (CAST,
3163 newAst_LINK (copyLinkChain (currFunc->type->next)),
3172 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3174 werror (E_VOID_FUNC, currFunc->name);
3175 goto errorTreeReturn;
3178 TTYPE (tree) = TETYPE (tree) = NULL;
3181 /*------------------------------------------------------------------*/
3182 /*----------------------------*/
3183 /* switch statement */
3184 /*----------------------------*/
3186 /* the switch value must be an integer */
3187 if (!IS_INTEGRAL (LTYPE (tree)))
3189 werror (E_SWITCH_NON_INTEGER);
3190 goto errorTreeReturn;
3193 TTYPE (tree) = TETYPE (tree) = NULL;
3196 /*------------------------------------------------------------------*/
3197 /*----------------------------*/
3199 /*----------------------------*/
3201 tree->left = backPatchLabels (tree->left,
3204 TTYPE (tree) = TETYPE (tree) = NULL;
3207 /*------------------------------------------------------------------*/
3208 /*----------------------------*/
3210 /*----------------------------*/
3213 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3214 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3215 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3217 /* if the for loop is reversible then
3218 reverse it otherwise do what we normally
3224 if (isLoopReversible (tree, &sym, &init, &end))
3225 return reverseLoop (tree, sym, init, end);
3227 return decorateType (createFor (AST_FOR (tree, trueLabel),
3228 AST_FOR (tree, continueLabel),
3229 AST_FOR (tree, falseLabel),
3230 AST_FOR (tree, condLabel),
3231 AST_FOR (tree, initExpr),
3232 AST_FOR (tree, condExpr),
3233 AST_FOR (tree, loopExpr),
3237 TTYPE (tree) = TETYPE (tree) = NULL;
3241 /* some error found this tree will be killed */
3243 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3244 tree->opval.op = NULLOP;
3250 /*-----------------------------------------------------------------*/
3251 /* sizeofOp - processes size of operation */
3252 /*-----------------------------------------------------------------*/
3254 sizeofOp (sym_link * type)
3258 /* make sure the type is complete and sane */
3259 checkTypeSanity(type, "(sizeof)");
3261 /* get the size and convert it to character */
3262 sprintf (buff, "%d", getSize (type));
3264 /* now convert into value */
3265 return constVal (buff);
3269 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3270 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3271 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3272 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3273 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3274 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3275 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3277 /*-----------------------------------------------------------------*/
3278 /* backPatchLabels - change and or not operators to flow control */
3279 /*-----------------------------------------------------------------*/
3281 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3287 if (!(IS_ANDORNOT (tree)))
3290 /* if this an and */
3293 static int localLbl = 0;
3296 sprintf (buffer, "_and_%d", localLbl++);
3297 localLabel = newSymbol (buffer, NestLevel);
3299 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3301 /* if left is already a IFX then just change the if true label in that */
3302 if (!IS_IFX (tree->left))
3303 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3305 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3306 /* right is a IFX then just join */
3307 if (IS_IFX (tree->right))
3308 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3310 tree->right = createLabel (localLabel, tree->right);
3311 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3313 return newNode (NULLOP, tree->left, tree->right);
3316 /* if this is an or operation */
3319 static int localLbl = 0;
3322 sprintf (buffer, "_or_%d", localLbl++);
3323 localLabel = newSymbol (buffer, NestLevel);
3325 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3327 /* if left is already a IFX then just change the if true label in that */
3328 if (!IS_IFX (tree->left))
3329 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3331 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3332 /* right is a IFX then just join */
3333 if (IS_IFX (tree->right))
3334 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3336 tree->right = createLabel (localLabel, tree->right);
3337 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3339 return newNode (NULLOP, tree->left, tree->right);
3345 int wasnot = IS_NOT (tree->left);
3346 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3348 /* if the left is already a IFX */
3349 if (!IS_IFX (tree->left))
3350 tree->left = newNode (IFX, tree->left, NULL);
3354 tree->left->trueLabel = trueLabel;
3355 tree->left->falseLabel = falseLabel;
3359 tree->left->trueLabel = falseLabel;
3360 tree->left->falseLabel = trueLabel;
3367 tree->trueLabel = trueLabel;
3368 tree->falseLabel = falseLabel;
3375 /*-----------------------------------------------------------------*/
3376 /* createBlock - create expression tree for block */
3377 /*-----------------------------------------------------------------*/
3379 createBlock (symbol * decl, ast * body)
3383 /* if the block has nothing */
3387 ex = newNode (BLOCK, NULL, body);
3388 ex->values.sym = decl;
3390 ex->right = ex->right;
3396 /*-----------------------------------------------------------------*/
3397 /* createLabel - creates the expression tree for labels */
3398 /*-----------------------------------------------------------------*/
3400 createLabel (symbol * label, ast * stmnt)
3403 char name[SDCC_NAME_MAX + 1];
3406 /* must create fresh symbol if the symbol name */
3407 /* exists in the symbol table, since there can */
3408 /* be a variable with the same name as the labl */
3409 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3410 (csym->level == label->level))
3411 label = newSymbol (label->name, label->level);
3413 /* change the name before putting it in add _ */
3414 sprintf (name, "%s", label->name);
3416 /* put the label in the LabelSymbol table */
3417 /* but first check if a label of the same */
3419 if ((csym = findSym (LabelTab, NULL, name)))
3420 werror (E_DUPLICATE_LABEL, label->name);
3422 addSym (LabelTab, label, name, label->level, 0, 0);
3425 label->key = labelKey++;
3426 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3432 /*-----------------------------------------------------------------*/
3433 /* createCase - generates the parsetree for a case statement */
3434 /*-----------------------------------------------------------------*/
3436 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3438 char caseLbl[SDCC_NAME_MAX + 1];
3442 /* if the switch statement does not exist */
3443 /* then case is out of context */
3446 werror (E_CASE_CONTEXT);
3450 caseVal = decorateType (resolveSymbols (caseVal));
3451 /* if not a constant then error */
3452 if (!IS_LITERAL (caseVal->ftype))
3454 werror (E_CASE_CONSTANT);
3458 /* if not a integer than error */
3459 if (!IS_INTEGRAL (caseVal->ftype))
3461 werror (E_CASE_NON_INTEGER);
3465 /* find the end of the switch values chain */
3466 if (!(val = swStat->values.switchVals.swVals))
3467 swStat->values.switchVals.swVals = caseVal->opval.val;
3470 /* also order the cases according to value */
3472 int cVal = (int) floatFromVal (caseVal->opval.val);
3473 while (val && (int) floatFromVal (val) < cVal)
3479 /* if we reached the end then */
3482 pval->next = caseVal->opval.val;
3486 /* we found a value greater than */
3487 /* the current value we must add this */
3488 /* before the value */
3489 caseVal->opval.val->next = val;
3491 /* if this was the first in chain */
3492 if (swStat->values.switchVals.swVals == val)
3493 swStat->values.switchVals.swVals =
3496 pval->next = caseVal->opval.val;
3501 /* create the case label */
3502 sprintf (caseLbl, "_case_%d_%d",
3503 swStat->values.switchVals.swNum,
3504 (int) floatFromVal (caseVal->opval.val));
3506 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3511 /*-----------------------------------------------------------------*/
3512 /* createDefault - creates the parse tree for the default statement */
3513 /*-----------------------------------------------------------------*/
3515 createDefault (ast * swStat, ast * stmnt)
3517 char defLbl[SDCC_NAME_MAX + 1];
3519 /* if the switch statement does not exist */
3520 /* then case is out of context */
3523 werror (E_CASE_CONTEXT);
3527 /* turn on the default flag */
3528 swStat->values.switchVals.swDefault = 1;
3530 /* create the label */
3531 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3532 return createLabel (newSymbol (defLbl, 0), stmnt);
3535 /*-----------------------------------------------------------------*/
3536 /* createIf - creates the parsetree for the if statement */
3537 /*-----------------------------------------------------------------*/
3539 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3541 static int Lblnum = 0;
3543 symbol *ifTrue, *ifFalse, *ifEnd;
3545 /* if neither exists */
3546 if (!elseBody && !ifBody) {
3547 // if there are no side effects (i++, j() etc)
3548 if (!hasSEFcalls(condAst)) {
3553 /* create the labels */
3554 sprintf (buffer, "_iffalse_%d", Lblnum);
3555 ifFalse = newSymbol (buffer, NestLevel);
3556 /* if no else body then end == false */
3561 sprintf (buffer, "_ifend_%d", Lblnum);
3562 ifEnd = newSymbol (buffer, NestLevel);
3565 sprintf (buffer, "_iftrue_%d", Lblnum);
3566 ifTrue = newSymbol (buffer, NestLevel);
3570 /* attach the ifTrue label to the top of it body */
3571 ifBody = createLabel (ifTrue, ifBody);
3572 /* attach a goto end to the ifBody if else is present */
3575 ifBody = newNode (NULLOP, ifBody,
3577 newAst_VALUE (symbolVal (ifEnd)),
3579 /* put the elseLabel on the else body */
3580 elseBody = createLabel (ifFalse, elseBody);
3581 /* out the end at the end of the body */
3582 elseBody = newNode (NULLOP,
3584 createLabel (ifEnd, NULL));
3588 ifBody = newNode (NULLOP, ifBody,
3589 createLabel (ifFalse, NULL));
3591 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3592 if (IS_IFX (condAst))
3595 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3597 return newNode (NULLOP, ifTree,
3598 newNode (NULLOP, ifBody, elseBody));
3602 /*-----------------------------------------------------------------*/
3603 /* createDo - creates parse tree for do */
3606 /* _docontinue_n: */
3607 /* condition_expression +-> trueLabel -> _dobody_n */
3609 /* +-> falseLabel-> _dobreak_n */
3611 /*-----------------------------------------------------------------*/
3613 createDo (symbol * trueLabel, symbol * continueLabel,
3614 symbol * falseLabel, ast * condAst, ast * doBody)
3619 /* if the body does not exist then it is simple */
3622 condAst = backPatchLabels (condAst, continueLabel, NULL);
3623 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3624 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3625 doTree->trueLabel = continueLabel;
3626 doTree->falseLabel = NULL;
3630 /* otherwise we have a body */
3631 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3633 /* attach the body label to the top */
3634 doBody = createLabel (trueLabel, doBody);
3635 /* attach the continue label to end of body */
3636 doBody = newNode (NULLOP, doBody,
3637 createLabel (continueLabel, NULL));
3639 /* now put the break label at the end */
3640 if (IS_IFX (condAst))
3643 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3645 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3647 /* putting it together */
3648 return newNode (NULLOP, doBody, doTree);
3651 /*-----------------------------------------------------------------*/
3652 /* createFor - creates parse tree for 'for' statement */
3655 /* condExpr +-> trueLabel -> _forbody_n */
3657 /* +-> falseLabel-> _forbreak_n */
3660 /* _forcontinue_n: */
3662 /* goto _forcond_n ; */
3664 /*-----------------------------------------------------------------*/
3666 createFor (symbol * trueLabel, symbol * continueLabel,
3667 symbol * falseLabel, symbol * condLabel,
3668 ast * initExpr, ast * condExpr, ast * loopExpr,
3673 /* if loopexpression not present then we can generate it */
3674 /* the same way as a while */
3676 return newNode (NULLOP, initExpr,
3677 createWhile (trueLabel, continueLabel,
3678 falseLabel, condExpr, forBody));
3679 /* vanilla for statement */
3680 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3682 if (condExpr && !IS_IFX (condExpr))
3683 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3686 /* attach condition label to condition */
3687 condExpr = createLabel (condLabel, condExpr);
3689 /* attach body label to body */
3690 forBody = createLabel (trueLabel, forBody);
3692 /* attach continue to forLoop expression & attach */
3693 /* goto the forcond @ and of loopExpression */
3694 loopExpr = createLabel (continueLabel,
3698 newAst_VALUE (symbolVal (condLabel)),
3700 /* now start putting them together */
3701 forTree = newNode (NULLOP, initExpr, condExpr);
3702 forTree = newNode (NULLOP, forTree, forBody);
3703 forTree = newNode (NULLOP, forTree, loopExpr);
3704 /* finally add the break label */
3705 forTree = newNode (NULLOP, forTree,
3706 createLabel (falseLabel, NULL));
3710 /*-----------------------------------------------------------------*/
3711 /* createWhile - creates parse tree for while statement */
3712 /* the while statement will be created as follows */
3714 /* _while_continue_n: */
3715 /* condition_expression +-> trueLabel -> _while_boby_n */
3717 /* +-> falseLabel -> _while_break_n */
3718 /* _while_body_n: */
3720 /* goto _while_continue_n */
3721 /* _while_break_n: */
3722 /*-----------------------------------------------------------------*/
3724 createWhile (symbol * trueLabel, symbol * continueLabel,
3725 symbol * falseLabel, ast * condExpr, ast * whileBody)
3729 /* put the continue label */
3730 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3731 condExpr = createLabel (continueLabel, condExpr);
3732 condExpr->lineno = 0;
3734 /* put the body label in front of the body */
3735 whileBody = createLabel (trueLabel, whileBody);
3736 whileBody->lineno = 0;
3737 /* put a jump to continue at the end of the body */
3738 /* and put break label at the end of the body */
3739 whileBody = newNode (NULLOP,
3742 newAst_VALUE (symbolVal (continueLabel)),
3743 createLabel (falseLabel, NULL)));
3745 /* put it all together */
3746 if (IS_IFX (condExpr))
3747 whileTree = condExpr;
3750 whileTree = newNode (IFX, condExpr, NULL);
3751 /* put the true & false labels in place */
3752 whileTree->trueLabel = trueLabel;
3753 whileTree->falseLabel = falseLabel;
3756 return newNode (NULLOP, whileTree, whileBody);
3759 /*-----------------------------------------------------------------*/
3760 /* optimizeGetHbit - get highest order bit of the expression */
3761 /*-----------------------------------------------------------------*/
3763 optimizeGetHbit (ast * tree)
3766 /* if this is not a bit and */
3767 if (!IS_BITAND (tree))
3770 /* will look for tree of the form
3771 ( expr >> ((sizeof expr) -1) ) & 1 */
3772 if (!IS_AST_LIT_VALUE (tree->right))
3775 if (AST_LIT_VALUE (tree->right) != 1)
3778 if (!IS_RIGHT_OP (tree->left))
3781 if (!IS_AST_LIT_VALUE (tree->left->right))
3784 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3785 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3788 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3792 /*-----------------------------------------------------------------*/
3793 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3794 /*-----------------------------------------------------------------*/
3796 optimizeRRCRLC (ast * root)
3798 /* will look for trees of the form
3799 (?expr << 1) | (?expr >> 7) or
3800 (?expr >> 7) | (?expr << 1) will make that
3801 into a RLC : operation ..
3803 (?expr >> 1) | (?expr << 7) or
3804 (?expr << 7) | (?expr >> 1) will make that
3805 into a RRC operation
3806 note : by 7 I mean (number of bits required to hold the
3808 /* if the root operations is not a | operation the not */
3809 if (!IS_BITOR (root))
3812 /* I have to think of a better way to match patterns this sucks */
3813 /* that aside let start looking for the first case : I use a the
3814 negative check a lot to improve the efficiency */
3815 /* (?expr << 1) | (?expr >> 7) */
3816 if (IS_LEFT_OP (root->left) &&
3817 IS_RIGHT_OP (root->right))
3820 if (!SPEC_USIGN (TETYPE (root->left->left)))
3823 if (!IS_AST_LIT_VALUE (root->left->right) ||
3824 !IS_AST_LIT_VALUE (root->right->right))
3827 /* make sure it is the same expression */
3828 if (!isAstEqual (root->left->left,
3832 if (AST_LIT_VALUE (root->left->right) != 1)
3835 if (AST_LIT_VALUE (root->right->right) !=
3836 (getSize (TTYPE (root->left->left)) * 8 - 1))
3839 /* whew got the first case : create the AST */
3840 return newNode (RLC, root->left->left, NULL);
3844 /* check for second case */
3845 /* (?expr >> 7) | (?expr << 1) */
3846 if (IS_LEFT_OP (root->right) &&
3847 IS_RIGHT_OP (root->left))
3850 if (!SPEC_USIGN (TETYPE (root->left->left)))
3853 if (!IS_AST_LIT_VALUE (root->left->right) ||
3854 !IS_AST_LIT_VALUE (root->right->right))
3857 /* make sure it is the same symbol */
3858 if (!isAstEqual (root->left->left,
3862 if (AST_LIT_VALUE (root->right->right) != 1)
3865 if (AST_LIT_VALUE (root->left->right) !=
3866 (getSize (TTYPE (root->left->left)) * 8 - 1))
3869 /* whew got the first case : create the AST */
3870 return newNode (RLC, root->left->left, NULL);
3875 /* third case for RRC */
3876 /* (?symbol >> 1) | (?symbol << 7) */
3877 if (IS_LEFT_OP (root->right) &&
3878 IS_RIGHT_OP (root->left))
3881 if (!SPEC_USIGN (TETYPE (root->left->left)))
3884 if (!IS_AST_LIT_VALUE (root->left->right) ||
3885 !IS_AST_LIT_VALUE (root->right->right))
3888 /* make sure it is the same symbol */
3889 if (!isAstEqual (root->left->left,
3893 if (AST_LIT_VALUE (root->left->right) != 1)
3896 if (AST_LIT_VALUE (root->right->right) !=
3897 (getSize (TTYPE (root->left->left)) * 8 - 1))
3900 /* whew got the first case : create the AST */
3901 return newNode (RRC, root->left->left, NULL);
3905 /* fourth and last case for now */
3906 /* (?symbol << 7) | (?symbol >> 1) */
3907 if (IS_RIGHT_OP (root->right) &&
3908 IS_LEFT_OP (root->left))
3911 if (!SPEC_USIGN (TETYPE (root->left->left)))
3914 if (!IS_AST_LIT_VALUE (root->left->right) ||
3915 !IS_AST_LIT_VALUE (root->right->right))
3918 /* make sure it is the same symbol */
3919 if (!isAstEqual (root->left->left,
3923 if (AST_LIT_VALUE (root->right->right) != 1)
3926 if (AST_LIT_VALUE (root->left->right) !=
3927 (getSize (TTYPE (root->left->left)) * 8 - 1))
3930 /* whew got the first case : create the AST */
3931 return newNode (RRC, root->left->left, NULL);
3935 /* not found return root */
3939 /*-----------------------------------------------------------------*/
3940 /* optimizeCompare - otimizes compares for bit variables */
3941 /*-----------------------------------------------------------------*/
3943 optimizeCompare (ast * root)
3945 ast *optExpr = NULL;
3948 unsigned int litValue;
3950 /* if nothing then return nothing */
3954 /* if not a compare op then do leaves */
3955 if (!IS_COMPARE_OP (root))
3957 root->left = optimizeCompare (root->left);
3958 root->right = optimizeCompare (root->right);
3962 /* if left & right are the same then depending
3963 of the operation do */
3964 if (isAstEqual (root->left, root->right))
3966 switch (root->opval.op)
3971 optExpr = newAst_VALUE (constVal ("0"));
3976 optExpr = newAst_VALUE (constVal ("1"));
3980 return decorateType (optExpr);
3983 vleft = (root->left->type == EX_VALUE ?
3984 root->left->opval.val : NULL);
3986 vright = (root->right->type == EX_VALUE ?
3987 root->right->opval.val : NULL);
3989 //#define EXPERIMENTAL
3991 /* if left is unsigned and right is literal */
3992 if (vleft && vright &&
3993 IS_UNSIGNED(vleft->etype) &&
3994 IS_LITERAL(vright->etype)) {
3995 double dval=floatFromVal(vright);
3996 int op=root->opval.op;
3998 fprintf (stderr,"op: '");
4000 case LE_OP: fprintf (stderr, "<= '"); break;
4001 case EQ_OP: fprintf (stderr, "== '"); break;
4002 case GE_OP: fprintf (stderr, ">= '"); break;
4003 default: fprintf (stderr, "%c '", op); break;
4005 fprintf (stderr, "%f\n", dval);
4012 if (dval<0 || (op=='<' && dval==0)) {
4013 // unsigned is never < 0
4014 werror (W_IF_NEVER_TRUE);
4015 optExpr = newAst_VALUE (constVal("0"));
4016 return decorateType (optExpr);
4020 // change this into a cheaper EQ_OP
4021 fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
4022 root->opval.op=EQ_OP;
4029 if (dval>0 || (op==GE_OP && dval==0)) {
4030 // unsigned is never < 0
4031 werror (W_IF_ALWAYS_TRUE);
4032 optExpr = newAst_VALUE (constVal("1"));
4033 return decorateType (optExpr);
4037 // change this into a cheaper reversed EQ_OP
4038 fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
4039 root->opval.op=EQ_OP;
4046 /* if left is a BITVAR in BITSPACE */
4047 /* and right is a LITERAL then opt- */
4048 /* imize else do nothing */
4049 if (vleft && vright &&
4050 IS_BITVAR (vleft->etype) &&
4051 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4052 IS_LITERAL (vright->etype))
4055 /* if right side > 1 then comparison may never succeed */
4056 if ((litValue = (int) floatFromVal (vright)) > 1)
4058 werror (W_BAD_COMPARE);
4064 switch (root->opval.op)
4066 case '>': /* bit value greater than 1 cannot be */
4067 werror (W_BAD_COMPARE);
4071 case '<': /* bit value < 1 means 0 */
4073 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4076 case LE_OP: /* bit value <= 1 means no check */
4077 optExpr = newAst_VALUE (vright);
4080 case GE_OP: /* bit value >= 1 means only check for = */
4082 optExpr = newAst_VALUE (vleft);
4087 { /* literal is zero */
4088 switch (root->opval.op)
4090 case '<': /* bit value < 0 cannot be */
4091 werror (W_BAD_COMPARE);
4095 case '>': /* bit value > 0 means 1 */
4097 optExpr = newAst_VALUE (vleft);
4100 case LE_OP: /* bit value <= 0 means no check */
4101 case GE_OP: /* bit value >= 0 means no check */
4102 werror (W_BAD_COMPARE);
4106 case EQ_OP: /* bit == 0 means ! of bit */
4107 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4111 return decorateType (resolveSymbols (optExpr));
4112 } /* end-of-if of BITVAR */
4117 /*-----------------------------------------------------------------*/
4118 /* addSymToBlock : adds the symbol to the first block we find */
4119 /*-----------------------------------------------------------------*/
4121 addSymToBlock (symbol * sym, ast * tree)
4123 /* reached end of tree or a leaf */
4124 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4128 if (IS_AST_OP (tree) &&
4129 tree->opval.op == BLOCK)
4132 symbol *lsym = copySymbol (sym);
4134 lsym->next = AST_VALUES (tree, sym);
4135 AST_VALUES (tree, sym) = lsym;
4139 addSymToBlock (sym, tree->left);
4140 addSymToBlock (sym, tree->right);
4143 /*-----------------------------------------------------------------*/
4144 /* processRegParms - do processing for register parameters */
4145 /*-----------------------------------------------------------------*/
4147 processRegParms (value * args, ast * body)
4151 if (IS_REGPARM (args->etype))
4152 addSymToBlock (args->sym, body);
4157 /*-----------------------------------------------------------------*/
4158 /* resetParmKey - resets the operandkeys for the symbols */
4159 /*-----------------------------------------------------------------*/
4160 DEFSETFUNC (resetParmKey)
4171 /*-----------------------------------------------------------------*/
4172 /* createFunction - This is the key node that calls the iCode for */
4173 /* generating the code for a function. Note code */
4174 /* is generated function by function, later when */
4175 /* add inter-procedural analysis this will change */
4176 /*-----------------------------------------------------------------*/
4178 createFunction (symbol * name, ast * body)
4184 iCode *piCode = NULL;
4186 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4187 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4189 /* if check function return 0 then some problem */
4190 if (checkFunction (name, NULL) == 0)
4193 /* create a dummy block if none exists */
4195 body = newNode (BLOCK, NULL, NULL);
4199 /* check if the function name already in the symbol table */
4200 if ((csym = findSym (SymbolTab, NULL, name->name)))
4203 /* special case for compiler defined functions
4204 we need to add the name to the publics list : this
4205 actually means we are now compiling the compiler
4209 addSet (&publics, name);
4215 allocVariables (name);
4217 name->lastLine = yylineno;
4220 #if 0 // jwk: this is now done in addDecl()
4221 processFuncArgs (currFunc);
4224 /* set the stack pointer */
4225 /* PENDING: check this for the mcs51 */
4226 stackPtr = -port->stack.direction * port->stack.call_overhead;
4227 if (IFFUNC_ISISR (name->type))
4228 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4229 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4230 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4232 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4234 fetype = getSpec (name->type); /* get the specifier for the function */
4235 /* if this is a reentrant function then */
4236 if (IFFUNC_ISREENT (name->type))
4239 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4241 /* do processing for parameters that are passed in registers */
4242 processRegParms (FUNC_ARGS(name->type), body);
4244 /* set the stack pointer */
4248 /* allocate & autoinit the block variables */
4249 processBlockVars (body, &stack, ALLOCATE);
4251 /* save the stack information */
4252 if (options.useXstack)
4253 name->xstack = SPEC_STAK (fetype) = stack;
4255 name->stack = SPEC_STAK (fetype) = stack;
4257 /* name needs to be mangled */
4258 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4260 body = resolveSymbols (body); /* resolve the symbols */
4261 body = decorateType (body); /* propagateType & do semantic checks */
4263 ex = newAst_VALUE (symbolVal (name)); /* create name */
4264 ex = newNode (FUNCTION, ex, body);
4265 ex->values.args = FUNC_ARGS(name->type);
4267 if (options.dump_tree) PA(ex);
4270 werror (E_FUNC_NO_CODE, name->name);
4274 /* create the node & generate intermediate code */
4276 codeOutFile = code->oFile;
4277 piCode = iCodeFromAst (ex);
4281 werror (E_FUNC_NO_CODE, name->name);
4285 eBBlockFromiCode (piCode);
4287 /* if there are any statics then do them */
4290 GcurMemmap = statsg;
4291 codeOutFile = statsg->oFile;
4292 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4298 /* dealloc the block variables */
4299 processBlockVars (body, &stack, DEALLOCATE);
4300 /* deallocate paramaters */
4301 deallocParms (FUNC_ARGS(name->type));
4303 if (IFFUNC_ISREENT (name->type))
4306 /* we are done freeup memory & cleanup */
4310 FUNC_HASBODY(name->type) = 1;
4311 addSet (&operKeyReset, name);
4312 applyToSet (operKeyReset, resetParmKey);
4315 cdbStructBlock (1, cdbFile);
4317 cleanUpLevel (LabelTab, 0);
4318 cleanUpBlock (StructTab, 1);
4319 cleanUpBlock (TypedefTab, 1);
4321 xstack->syms = NULL;
4322 istack->syms = NULL;
4327 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4328 /*-----------------------------------------------------------------*/
4329 /* ast_print : prints the ast (for debugging purposes) */
4330 /*-----------------------------------------------------------------*/
4332 void ast_print (ast * tree, FILE *outfile, int indent)
4337 /* can print only decorated trees */
4338 if (!tree->decorated) return;
4340 /* if any child is an error | this one is an error do nothing */
4341 if (tree->isError ||
4342 (tree->left && tree->left->isError) ||
4343 (tree->right && tree->right->isError)) {
4344 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4348 /* print the line */
4349 /* if not block & function */
4350 if (tree->type == EX_OP &&
4351 (tree->opval.op != FUNCTION &&
4352 tree->opval.op != BLOCK &&
4353 tree->opval.op != NULLOP)) {
4356 if (tree->opval.op == FUNCTION) {
4358 value *args=FUNC_ARGS(tree->left->opval.val->type);
4359 fprintf(outfile,"FUNCTION (%s=%p) type (",
4360 tree->left->opval.val->name, tree);
4361 printTypeChain (tree->ftype,outfile);
4362 fprintf(outfile,") args (");
4365 fprintf (outfile, ", ");
4367 printTypeChain (args ? args->type : NULL, outfile);
4369 args= args ? args->next : NULL;
4371 fprintf(outfile,")\n");
4372 ast_print(tree->left,outfile,indent);
4373 ast_print(tree->right,outfile,indent);
4376 if (tree->opval.op == BLOCK) {
4377 symbol *decls = tree->values.sym;
4378 INDENT(indent,outfile);
4379 fprintf(outfile,"{\n");
4381 INDENT(indent+2,outfile);
4382 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4383 decls->name, decls);
4384 printTypeChain(decls->type,outfile);
4385 fprintf(outfile,")\n");
4387 decls = decls->next;
4389 ast_print(tree->right,outfile,indent+2);
4390 INDENT(indent,outfile);
4391 fprintf(outfile,"}\n");
4394 if (tree->opval.op == NULLOP) {
4395 fprintf(outfile,"\n");
4396 ast_print(tree->left,outfile,indent);
4397 fprintf(outfile,"\n");
4398 ast_print(tree->right,outfile,indent);
4401 INDENT(indent,outfile);
4403 /*------------------------------------------------------------------*/
4404 /*----------------------------*/
4405 /* leaf has been reached */
4406 /*----------------------------*/
4407 /* if this is of type value */
4408 /* just get the type */
4409 if (tree->type == EX_VALUE) {
4411 if (IS_LITERAL (tree->opval.val->etype)) {
4412 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4413 (int) floatFromVal(tree->opval.val),
4414 (int) floatFromVal(tree->opval.val),
4415 floatFromVal(tree->opval.val));
4416 } else if (tree->opval.val->sym) {
4417 /* if the undefined flag is set then give error message */
4418 if (tree->opval.val->sym->undefined) {
4419 fprintf(outfile,"UNDEFINED SYMBOL ");
4421 fprintf(outfile,"SYMBOL ");
4423 fprintf(outfile,"(%s=%p)",
4424 tree->opval.val->sym->name,tree);
4427 fprintf(outfile," type (");
4428 printTypeChain(tree->ftype,outfile);
4429 fprintf(outfile,")\n");
4431 fprintf(outfile,"\n");
4436 /* if type link for the case of cast */
4437 if (tree->type == EX_LINK) {
4438 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4439 printTypeChain(tree->opval.lnk,outfile);
4440 fprintf(outfile,")\n");
4445 /* depending on type of operator do */
4447 switch (tree->opval.op) {
4448 /*------------------------------------------------------------------*/
4449 /*----------------------------*/
4451 /*----------------------------*/
4453 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4454 printTypeChain(tree->ftype,outfile);
4455 fprintf(outfile,")\n");
4456 ast_print(tree->left,outfile,indent+2);
4457 ast_print(tree->right,outfile,indent+2);
4460 /*------------------------------------------------------------------*/
4461 /*----------------------------*/
4463 /*----------------------------*/
4465 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4466 printTypeChain(tree->ftype,outfile);
4467 fprintf(outfile,")\n");
4468 ast_print(tree->left,outfile,indent+2);
4469 ast_print(tree->right,outfile,indent+2);
4472 /*------------------------------------------------------------------*/
4473 /*----------------------------*/
4474 /* struct/union pointer */
4475 /*----------------------------*/
4477 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4478 printTypeChain(tree->ftype,outfile);
4479 fprintf(outfile,")\n");
4480 ast_print(tree->left,outfile,indent+2);
4481 ast_print(tree->right,outfile,indent+2);
4484 /*------------------------------------------------------------------*/
4485 /*----------------------------*/
4486 /* ++/-- operation */
4487 /*----------------------------*/
4488 case INC_OP: /* incerement operator unary so left only */
4489 fprintf(outfile,"INC_OP (%p) type (",tree);
4490 printTypeChain(tree->ftype,outfile);
4491 fprintf(outfile,")\n");
4492 ast_print(tree->left,outfile,indent+2);
4496 fprintf(outfile,"DEC_OP (%p) type (",tree);
4497 printTypeChain(tree->ftype,outfile);
4498 fprintf(outfile,")\n");
4499 ast_print(tree->left,outfile,indent+2);
4502 /*------------------------------------------------------------------*/
4503 /*----------------------------*/
4505 /*----------------------------*/
4508 fprintf(outfile,"& (%p) type (",tree);
4509 printTypeChain(tree->ftype,outfile);
4510 fprintf(outfile,")\n");
4511 ast_print(tree->left,outfile,indent+2);
4512 ast_print(tree->right,outfile,indent+2);
4514 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4515 printTypeChain(tree->ftype,outfile);
4516 fprintf(outfile,")\n");
4517 ast_print(tree->left,outfile,indent+2);
4518 ast_print(tree->right,outfile,indent+2);
4521 /*----------------------------*/
4523 /*----------------------------*/
4525 fprintf(outfile,"OR (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+2);
4529 ast_print(tree->right,outfile,indent+2);
4531 /*------------------------------------------------------------------*/
4532 /*----------------------------*/
4534 /*----------------------------*/
4536 fprintf(outfile,"XOR (%p) type (",tree);
4537 printTypeChain(tree->ftype,outfile);
4538 fprintf(outfile,")\n");
4539 ast_print(tree->left,outfile,indent+2);
4540 ast_print(tree->right,outfile,indent+2);
4543 /*------------------------------------------------------------------*/
4544 /*----------------------------*/
4546 /*----------------------------*/
4548 fprintf(outfile,"DIV (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+2);
4552 ast_print(tree->right,outfile,indent+2);
4554 /*------------------------------------------------------------------*/
4555 /*----------------------------*/
4557 /*----------------------------*/
4559 fprintf(outfile,"MOD (%p) type (",tree);
4560 printTypeChain(tree->ftype,outfile);
4561 fprintf(outfile,")\n");
4562 ast_print(tree->left,outfile,indent+2);
4563 ast_print(tree->right,outfile,indent+2);
4566 /*------------------------------------------------------------------*/
4567 /*----------------------------*/
4568 /* address dereference */
4569 /*----------------------------*/
4570 case '*': /* can be unary : if right is null then unary operation */
4572 fprintf(outfile,"DEREF (%p) type (",tree);
4573 printTypeChain(tree->ftype,outfile);
4574 fprintf(outfile,")\n");
4575 ast_print(tree->left,outfile,indent+2);
4578 /*------------------------------------------------------------------*/
4579 /*----------------------------*/
4580 /* multiplication */
4581 /*----------------------------*/
4582 fprintf(outfile,"MULT (%p) type (",tree);
4583 printTypeChain(tree->ftype,outfile);
4584 fprintf(outfile,")\n");
4585 ast_print(tree->left,outfile,indent+2);
4586 ast_print(tree->right,outfile,indent+2);
4590 /*------------------------------------------------------------------*/
4591 /*----------------------------*/
4592 /* unary '+' operator */
4593 /*----------------------------*/
4597 fprintf(outfile,"UPLUS (%p) type (",tree);
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->left,outfile,indent+2);
4602 /*------------------------------------------------------------------*/
4603 /*----------------------------*/
4605 /*----------------------------*/
4606 fprintf(outfile,"ADD (%p) type (",tree);
4607 printTypeChain(tree->ftype,outfile);
4608 fprintf(outfile,")\n");
4609 ast_print(tree->left,outfile,indent+2);
4610 ast_print(tree->right,outfile,indent+2);
4613 /*------------------------------------------------------------------*/
4614 /*----------------------------*/
4616 /*----------------------------*/
4617 case '-': /* can be unary */
4619 fprintf(outfile,"UMINUS (%p) type (",tree);
4620 printTypeChain(tree->ftype,outfile);
4621 fprintf(outfile,")\n");
4622 ast_print(tree->left,outfile,indent+2);
4624 /*------------------------------------------------------------------*/
4625 /*----------------------------*/
4627 /*----------------------------*/
4628 fprintf(outfile,"SUB (%p) type (",tree);
4629 printTypeChain(tree->ftype,outfile);
4630 fprintf(outfile,")\n");
4631 ast_print(tree->left,outfile,indent+2);
4632 ast_print(tree->right,outfile,indent+2);
4635 /*------------------------------------------------------------------*/
4636 /*----------------------------*/
4638 /*----------------------------*/
4640 fprintf(outfile,"COMPL (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+2);
4645 /*------------------------------------------------------------------*/
4646 /*----------------------------*/
4648 /*----------------------------*/
4650 fprintf(outfile,"NOT (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+2);
4655 /*------------------------------------------------------------------*/
4656 /*----------------------------*/
4658 /*----------------------------*/
4660 fprintf(outfile,"RRC (%p) type (",tree);
4661 printTypeChain(tree->ftype,outfile);
4662 fprintf(outfile,")\n");
4663 ast_print(tree->left,outfile,indent+2);
4667 fprintf(outfile,"RLC (%p) type (",tree);
4668 printTypeChain(tree->ftype,outfile);
4669 fprintf(outfile,")\n");
4670 ast_print(tree->left,outfile,indent+2);
4673 fprintf(outfile,"GETHBIT (%p) type (",tree);
4674 printTypeChain(tree->ftype,outfile);
4675 fprintf(outfile,")\n");
4676 ast_print(tree->left,outfile,indent+2);
4679 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4680 printTypeChain(tree->ftype,outfile);
4681 fprintf(outfile,")\n");
4682 ast_print(tree->left,outfile,indent+2);
4683 ast_print(tree->right,outfile,indent+2);
4686 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4687 printTypeChain(tree->ftype,outfile);
4688 fprintf(outfile,")\n");
4689 ast_print(tree->left,outfile,indent+2);
4690 ast_print(tree->right,outfile,indent+2);
4692 /*------------------------------------------------------------------*/
4693 /*----------------------------*/
4695 /*----------------------------*/
4696 case CAST: /* change the type */
4697 fprintf(outfile,"CAST (%p) from type (",tree);
4698 printTypeChain(tree->right->ftype,outfile);
4699 fprintf(outfile,") to type (");
4700 printTypeChain(tree->ftype,outfile);
4701 fprintf(outfile,")\n");
4702 ast_print(tree->right,outfile,indent+2);
4706 fprintf(outfile,"ANDAND (%p) type (",tree);
4707 printTypeChain(tree->ftype,outfile);
4708 fprintf(outfile,")\n");
4709 ast_print(tree->left,outfile,indent+2);
4710 ast_print(tree->right,outfile,indent+2);
4713 fprintf(outfile,"OROR (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+2);
4717 ast_print(tree->right,outfile,indent+2);
4720 /*------------------------------------------------------------------*/
4721 /*----------------------------*/
4722 /* comparison operators */
4723 /*----------------------------*/
4725 fprintf(outfile,"GT(>) (%p) type (",tree);
4726 printTypeChain(tree->ftype,outfile);
4727 fprintf(outfile,")\n");
4728 ast_print(tree->left,outfile,indent+2);
4729 ast_print(tree->right,outfile,indent+2);
4732 fprintf(outfile,"LT(<) (%p) type (",tree);
4733 printTypeChain(tree->ftype,outfile);
4734 fprintf(outfile,")\n");
4735 ast_print(tree->left,outfile,indent+2);
4736 ast_print(tree->right,outfile,indent+2);
4739 fprintf(outfile,"LE(<=) (%p) type (",tree);
4740 printTypeChain(tree->ftype,outfile);
4741 fprintf(outfile,")\n");
4742 ast_print(tree->left,outfile,indent+2);
4743 ast_print(tree->right,outfile,indent+2);
4746 fprintf(outfile,"GE(>=) (%p) type (",tree);
4747 printTypeChain(tree->ftype,outfile);
4748 fprintf(outfile,")\n");
4749 ast_print(tree->left,outfile,indent+2);
4750 ast_print(tree->right,outfile,indent+2);
4753 fprintf(outfile,"EQ(==) (%p) type (",tree);
4754 printTypeChain(tree->ftype,outfile);
4755 fprintf(outfile,")\n");
4756 ast_print(tree->left,outfile,indent+2);
4757 ast_print(tree->right,outfile,indent+2);
4760 fprintf(outfile,"NE(!=) (%p) type (",tree);
4761 printTypeChain(tree->ftype,outfile);
4762 fprintf(outfile,")\n");
4763 ast_print(tree->left,outfile,indent+2);
4764 ast_print(tree->right,outfile,indent+2);
4765 /*------------------------------------------------------------------*/
4766 /*----------------------------*/
4768 /*----------------------------*/
4769 case SIZEOF: /* evaluate wihout code generation */
4770 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4773 /*------------------------------------------------------------------*/
4774 /*----------------------------*/
4775 /* conditional operator '?' */
4776 /*----------------------------*/
4778 fprintf(outfile,"QUEST(?) (%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);
4786 fprintf(outfile,"COLON(:) (%p) type (",tree);
4787 printTypeChain(tree->ftype,outfile);
4788 fprintf(outfile,")\n");
4789 ast_print(tree->left,outfile,indent+2);
4790 ast_print(tree->right,outfile,indent+2);
4793 /*------------------------------------------------------------------*/
4794 /*----------------------------*/
4795 /* assignment operators */
4796 /*----------------------------*/
4798 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->left,outfile,indent+2);
4802 ast_print(tree->right,outfile,indent+2);
4805 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4806 printTypeChain(tree->ftype,outfile);
4807 fprintf(outfile,")\n");
4808 ast_print(tree->left,outfile,indent+2);
4809 ast_print(tree->right,outfile,indent+2);
4812 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4813 printTypeChain(tree->ftype,outfile);
4814 fprintf(outfile,")\n");
4815 ast_print(tree->left,outfile,indent+2);
4816 ast_print(tree->right,outfile,indent+2);
4819 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4820 printTypeChain(tree->ftype,outfile);
4821 fprintf(outfile,")\n");
4822 ast_print(tree->left,outfile,indent+2);
4823 ast_print(tree->right,outfile,indent+2);
4826 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4827 printTypeChain(tree->ftype,outfile);
4828 fprintf(outfile,")\n");
4829 ast_print(tree->left,outfile,indent+2);
4830 ast_print(tree->right,outfile,indent+2);
4833 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4834 printTypeChain(tree->ftype,outfile);
4835 fprintf(outfile,")\n");
4836 ast_print(tree->left,outfile,indent+2);
4837 ast_print(tree->right,outfile,indent+2);
4840 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4841 printTypeChain(tree->ftype,outfile);
4842 fprintf(outfile,")\n");
4843 ast_print(tree->left,outfile,indent+2);
4844 ast_print(tree->right,outfile,indent+2);
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4849 /*----------------------------*/
4851 fprintf(outfile,"SUBASS(-=) (%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);
4857 /*------------------------------------------------------------------*/
4858 /*----------------------------*/
4860 /*----------------------------*/
4862 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4863 printTypeChain(tree->ftype,outfile);
4864 fprintf(outfile,")\n");
4865 ast_print(tree->left,outfile,indent+2);
4866 ast_print(tree->right,outfile,indent+2);
4868 /*------------------------------------------------------------------*/
4869 /*----------------------------*/
4870 /* straight assignemnt */
4871 /*----------------------------*/
4873 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4874 printTypeChain(tree->ftype,outfile);
4875 fprintf(outfile,")\n");
4876 ast_print(tree->left,outfile,indent+2);
4877 ast_print(tree->right,outfile,indent+2);
4879 /*------------------------------------------------------------------*/
4880 /*----------------------------*/
4881 /* comma operator */
4882 /*----------------------------*/
4884 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4885 printTypeChain(tree->ftype,outfile);
4886 fprintf(outfile,")\n");
4887 ast_print(tree->left,outfile,indent+2);
4888 ast_print(tree->right,outfile,indent+2);
4890 /*------------------------------------------------------------------*/
4891 /*----------------------------*/
4893 /*----------------------------*/
4896 fprintf(outfile,"CALL (%p) type (",tree);
4897 printTypeChain(tree->ftype,outfile);
4898 fprintf(outfile,")\n");
4899 ast_print(tree->left,outfile,indent+2);
4900 ast_print(tree->right,outfile,indent+2);
4903 fprintf(outfile,"PARMS\n");
4904 ast_print(tree->left,outfile,indent+2);
4905 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4906 ast_print(tree->right,outfile,indent+2);
4909 /*------------------------------------------------------------------*/
4910 /*----------------------------*/
4911 /* return statement */
4912 /*----------------------------*/
4914 fprintf(outfile,"RETURN (%p) type (",tree);
4915 printTypeChain(tree->right->ftype,outfile);
4916 fprintf(outfile,")\n");
4917 ast_print(tree->right,outfile,indent+2);
4919 /*------------------------------------------------------------------*/
4920 /*----------------------------*/
4921 /* label statement */
4922 /*----------------------------*/
4924 fprintf(outfile,"LABEL (%p)\n",tree);
4925 ast_print(tree->left,outfile,indent+2);
4926 ast_print(tree->right,outfile,indent);
4928 /*------------------------------------------------------------------*/
4929 /*----------------------------*/
4930 /* switch statement */
4931 /*----------------------------*/
4935 fprintf(outfile,"SWITCH (%p) ",tree);
4936 ast_print(tree->left,outfile,0);
4937 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4938 INDENT(indent+2,outfile);
4939 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4940 (int) floatFromVal(val),
4941 tree->values.switchVals.swNum,
4942 (int) floatFromVal(val));
4944 ast_print(tree->right,outfile,indent);
4947 /*------------------------------------------------------------------*/
4948 /*----------------------------*/
4950 /*----------------------------*/
4952 fprintf(outfile,"IF (%p) \n",tree);
4953 ast_print(tree->left,outfile,indent+2);
4954 if (tree->trueLabel) {
4955 INDENT(indent,outfile);
4956 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4958 if (tree->falseLabel) {
4959 INDENT(indent,outfile);
4960 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4962 ast_print(tree->right,outfile,indent+2);
4964 /*------------------------------------------------------------------*/
4965 /*----------------------------*/
4967 /*----------------------------*/
4969 fprintf(outfile,"FOR (%p) \n",tree);
4970 if (AST_FOR( tree, initExpr)) {
4971 INDENT(indent+2,outfile);
4972 fprintf(outfile,"INIT EXPR ");
4973 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4975 if (AST_FOR( tree, condExpr)) {
4976 INDENT(indent+2,outfile);
4977 fprintf(outfile,"COND EXPR ");
4978 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4980 if (AST_FOR( tree, loopExpr)) {
4981 INDENT(indent+2,outfile);
4982 fprintf(outfile,"LOOP EXPR ");
4983 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4985 fprintf(outfile,"FOR LOOP BODY \n");
4986 ast_print(tree->left,outfile,indent+2);
4995 ast_print(t,stdout,0);