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 /* delay right side for '?' operator since conditional macro expansions might
1980 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1982 /* this is to take care of situations
1983 when the tree gets rewritten */
1984 if (dtl != tree->left)
1986 if (dtr != tree->right)
1990 /* depending on type of operator do */
1992 switch (tree->opval.op)
1994 /*------------------------------------------------------------------*/
1995 /*----------------------------*/
1997 /*----------------------------*/
2000 /* determine which is the array & which the index */
2001 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2004 ast *tempTree = tree->left;
2005 tree->left = tree->right;
2006 tree->right = tempTree;
2009 /* first check if this is a array or a pointer */
2010 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2012 werror (E_NEED_ARRAY_PTR, "[]");
2013 goto errorTreeReturn;
2016 /* check if the type of the idx */
2017 if (!IS_INTEGRAL (RTYPE (tree)))
2019 werror (E_IDX_NOT_INT);
2020 goto errorTreeReturn;
2023 /* if the left is an rvalue then error */
2026 werror (E_LVALUE_REQUIRED, "array access");
2027 goto errorTreeReturn;
2030 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2031 if (IS_PTR(LTYPE(tree))) {
2032 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2036 /*------------------------------------------------------------------*/
2037 /*----------------------------*/
2039 /*----------------------------*/
2041 /* if this is not a structure */
2042 if (!IS_STRUCT (LTYPE (tree)))
2044 werror (E_STRUCT_UNION, ".");
2045 goto errorTreeReturn;
2047 TTYPE (tree) = structElemType (LTYPE (tree),
2048 (tree->right->type == EX_VALUE ?
2049 tree->right->opval.val : NULL));
2050 TETYPE (tree) = getSpec (TTYPE (tree));
2053 /*------------------------------------------------------------------*/
2054 /*----------------------------*/
2055 /* struct/union pointer */
2056 /*----------------------------*/
2058 /* if not pointer to a structure */
2059 if (!IS_PTR (LTYPE (tree)))
2061 werror (E_PTR_REQD);
2062 goto errorTreeReturn;
2065 if (!IS_STRUCT (LTYPE (tree)->next))
2067 werror (E_STRUCT_UNION, "->");
2068 goto errorTreeReturn;
2071 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2072 (tree->right->type == EX_VALUE ?
2073 tree->right->opval.val : NULL));
2074 TETYPE (tree) = getSpec (TTYPE (tree));
2077 /*------------------------------------------------------------------*/
2078 /*----------------------------*/
2079 /* ++/-- operation */
2080 /*----------------------------*/
2081 case INC_OP: /* incerement operator unary so left only */
2084 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2085 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2086 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2087 werror (E_CODE_WRITE, "++/--");
2096 /*------------------------------------------------------------------*/
2097 /*----------------------------*/
2099 /*----------------------------*/
2100 case '&': /* can be unary */
2101 /* if right is NULL then unary operation */
2102 if (tree->right) /* not an unary operation */
2105 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2107 werror (E_BITWISE_OP);
2108 werror (W_CONTINUE, "left & right types are ");
2109 printTypeChain (LTYPE (tree), stderr);
2110 fprintf (stderr, ",");
2111 printTypeChain (RTYPE (tree), stderr);
2112 fprintf (stderr, "\n");
2113 goto errorTreeReturn;
2116 /* if they are both literal */
2117 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2119 tree->type = EX_VALUE;
2120 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2121 valFromType (RETYPE (tree)), '&');
2123 tree->right = tree->left = NULL;
2124 TETYPE (tree) = tree->opval.val->etype;
2125 TTYPE (tree) = tree->opval.val->type;
2129 /* see if this is a GETHBIT operation if yes
2132 ast *otree = optimizeGetHbit (tree);
2135 return decorateType (otree);
2139 computeType (LTYPE (tree), RTYPE (tree));
2140 TETYPE (tree) = getSpec (TTYPE (tree));
2142 LRVAL (tree) = RRVAL (tree) = 1;
2146 /*------------------------------------------------------------------*/
2147 /*----------------------------*/
2149 /*----------------------------*/
2151 p->class = DECLARATOR;
2152 /* if bit field then error */
2153 if (IS_BITVAR (tree->left->etype))
2155 werror (E_ILLEGAL_ADDR, "address of bit variable");
2156 goto errorTreeReturn;
2159 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2161 werror (E_ILLEGAL_ADDR, "address of register variable");
2162 goto errorTreeReturn;
2165 if (IS_FUNC (LTYPE (tree)))
2167 werror (E_ILLEGAL_ADDR, "address of function");
2168 goto errorTreeReturn;
2171 if (IS_LITERAL(LTYPE(tree)))
2173 werror (E_ILLEGAL_ADDR, "address of literal");
2174 goto errorTreeReturn;
2179 werror (E_LVALUE_REQUIRED, "address of");
2180 goto errorTreeReturn;
2182 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2184 DCL_TYPE (p) = CPOINTER;
2185 DCL_PTR_CONST (p) = port->mem.code_ro;
2187 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2188 DCL_TYPE (p) = FPOINTER;
2189 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2190 DCL_TYPE (p) = PPOINTER;
2191 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2192 DCL_TYPE (p) = IPOINTER;
2193 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2194 DCL_TYPE (p) = EEPPOINTER;
2195 else if (SPEC_OCLS(tree->left->etype))
2196 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2198 DCL_TYPE (p) = POINTER;
2200 if (IS_AST_SYM_VALUE (tree->left))
2202 AST_SYMBOL (tree->left)->addrtaken = 1;
2203 AST_SYMBOL (tree->left)->allocreq = 1;
2206 p->next = LTYPE (tree);
2208 TETYPE (tree) = getSpec (TTYPE (tree));
2209 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2210 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2215 /*------------------------------------------------------------------*/
2216 /*----------------------------*/
2218 /*----------------------------*/
2220 /* if the rewrite succeeds then don't go any furthur */
2222 ast *wtree = optimizeRRCRLC (tree);
2224 return decorateType (wtree);
2226 /*------------------------------------------------------------------*/
2227 /*----------------------------*/
2229 /*----------------------------*/
2231 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2233 werror (E_BITWISE_OP);
2234 werror (W_CONTINUE, "left & right types are ");
2235 printTypeChain (LTYPE (tree), stderr);
2236 fprintf (stderr, ",");
2237 printTypeChain (RTYPE (tree), stderr);
2238 fprintf (stderr, "\n");
2239 goto errorTreeReturn;
2242 /* if they are both literal then */
2243 /* rewrite the tree */
2244 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2246 tree->type = EX_VALUE;
2247 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2248 valFromType (RETYPE (tree)),
2250 tree->right = tree->left = NULL;
2251 TETYPE (tree) = tree->opval.val->etype;
2252 TTYPE (tree) = tree->opval.val->type;
2255 LRVAL (tree) = RRVAL (tree) = 1;
2256 TETYPE (tree) = getSpec (TTYPE (tree) =
2257 computeType (LTYPE (tree),
2260 /*------------------------------------------------------------------*/
2261 /*----------------------------*/
2263 /*----------------------------*/
2265 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2267 werror (E_INVALID_OP, "divide");
2268 goto errorTreeReturn;
2270 /* if they are both literal then */
2271 /* rewrite the tree */
2272 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2274 tree->type = EX_VALUE;
2275 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2276 valFromType (RETYPE (tree)));
2277 tree->right = tree->left = NULL;
2278 TETYPE (tree) = getSpec (TTYPE (tree) =
2279 tree->opval.val->type);
2282 LRVAL (tree) = RRVAL (tree) = 1;
2283 TETYPE (tree) = getSpec (TTYPE (tree) =
2284 computeType (LTYPE (tree),
2288 /*------------------------------------------------------------------*/
2289 /*----------------------------*/
2291 /*----------------------------*/
2293 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2295 werror (E_BITWISE_OP);
2296 werror (W_CONTINUE, "left & right types are ");
2297 printTypeChain (LTYPE (tree), stderr);
2298 fprintf (stderr, ",");
2299 printTypeChain (RTYPE (tree), stderr);
2300 fprintf (stderr, "\n");
2301 goto errorTreeReturn;
2303 /* if they are both literal then */
2304 /* rewrite the tree */
2305 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2307 tree->type = EX_VALUE;
2308 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2309 valFromType (RETYPE (tree)));
2310 tree->right = tree->left = NULL;
2311 TETYPE (tree) = getSpec (TTYPE (tree) =
2312 tree->opval.val->type);
2315 LRVAL (tree) = RRVAL (tree) = 1;
2316 TETYPE (tree) = getSpec (TTYPE (tree) =
2317 computeType (LTYPE (tree),
2321 /*------------------------------------------------------------------*/
2322 /*----------------------------*/
2323 /* address dereference */
2324 /*----------------------------*/
2325 case '*': /* can be unary : if right is null then unary operation */
2328 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2330 werror (E_PTR_REQD);
2331 goto errorTreeReturn;
2336 werror (E_LVALUE_REQUIRED, "pointer deref");
2337 goto errorTreeReturn;
2339 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2340 LTYPE (tree)->next : NULL);
2341 TETYPE (tree) = getSpec (TTYPE (tree));
2342 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2346 /*------------------------------------------------------------------*/
2347 /*----------------------------*/
2348 /* multiplication */
2349 /*----------------------------*/
2350 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2352 werror (E_INVALID_OP, "multiplication");
2353 goto errorTreeReturn;
2356 /* if they are both literal then */
2357 /* rewrite the tree */
2358 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2360 tree->type = EX_VALUE;
2361 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2362 valFromType (RETYPE (tree)));
2363 tree->right = tree->left = NULL;
2364 TETYPE (tree) = getSpec (TTYPE (tree) =
2365 tree->opval.val->type);
2369 /* if left is a literal exchange left & right */
2370 if (IS_LITERAL (LTYPE (tree)))
2372 ast *tTree = tree->left;
2373 tree->left = tree->right;
2374 tree->right = tTree;
2377 LRVAL (tree) = RRVAL (tree) = 1;
2378 /* promote result to int if left & right are char
2379 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2380 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2381 TETYPE (tree) = getSpec (TTYPE (tree) =
2382 computeType (LTYPE (tree),
2384 SPEC_NOUN(TETYPE(tree)) = V_INT;
2386 TETYPE (tree) = getSpec (TTYPE (tree) =
2387 computeType (LTYPE (tree),
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2394 /* unary '+' operator */
2395 /*----------------------------*/
2400 if (!IS_INTEGRAL (LTYPE (tree)))
2402 werror (E_UNARY_OP, '+');
2403 goto errorTreeReturn;
2406 /* if left is a literal then do it */
2407 if (IS_LITERAL (LTYPE (tree)))
2409 tree->type = EX_VALUE;
2410 tree->opval.val = valFromType (LETYPE (tree));
2412 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2416 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2420 /*------------------------------------------------------------------*/
2421 /*----------------------------*/
2423 /*----------------------------*/
2425 /* this is not a unary operation */
2426 /* if both pointers then problem */
2427 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2428 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2430 werror (E_PTR_PLUS_PTR);
2431 goto errorTreeReturn;
2434 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2435 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2437 werror (E_PLUS_INVALID, "+");
2438 goto errorTreeReturn;
2441 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2442 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2444 werror (E_PLUS_INVALID, "+");
2445 goto errorTreeReturn;
2447 /* if they are both literal then */
2448 /* rewrite the tree */
2449 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2451 tree->type = EX_VALUE;
2452 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2453 valFromType (RETYPE (tree)));
2454 tree->right = tree->left = NULL;
2455 TETYPE (tree) = getSpec (TTYPE (tree) =
2456 tree->opval.val->type);
2460 /* if the right is a pointer or left is a literal
2461 xchange left & right */
2462 if (IS_ARRAY (RTYPE (tree)) ||
2463 IS_PTR (RTYPE (tree)) ||
2464 IS_LITERAL (LTYPE (tree)))
2466 ast *tTree = tree->left;
2467 tree->left = tree->right;
2468 tree->right = tTree;
2471 LRVAL (tree) = RRVAL (tree) = 1;
2472 /* if the left is a pointer */
2473 if (IS_PTR (LTYPE (tree)))
2474 TETYPE (tree) = getSpec (TTYPE (tree) =
2477 TETYPE (tree) = getSpec (TTYPE (tree) =
2478 computeType (LTYPE (tree),
2482 /*------------------------------------------------------------------*/
2483 /*----------------------------*/
2485 /*----------------------------*/
2486 case '-': /* can be unary */
2487 /* if right is null then unary */
2491 if (!IS_ARITHMETIC (LTYPE (tree)))
2493 werror (E_UNARY_OP, tree->opval.op);
2494 goto errorTreeReturn;
2497 /* if left is a literal then do it */
2498 if (IS_LITERAL (LTYPE (tree)))
2500 tree->type = EX_VALUE;
2501 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2503 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2504 SPEC_USIGN(TETYPE(tree)) = 0;
2508 TTYPE (tree) = LTYPE (tree);
2512 /*------------------------------------------------------------------*/
2513 /*----------------------------*/
2515 /*----------------------------*/
2517 if (!(IS_PTR (LTYPE (tree)) ||
2518 IS_ARRAY (LTYPE (tree)) ||
2519 IS_ARITHMETIC (LTYPE (tree))))
2521 werror (E_PLUS_INVALID, "-");
2522 goto errorTreeReturn;
2525 if (!(IS_PTR (RTYPE (tree)) ||
2526 IS_ARRAY (RTYPE (tree)) ||
2527 IS_ARITHMETIC (RTYPE (tree))))
2529 werror (E_PLUS_INVALID, "-");
2530 goto errorTreeReturn;
2533 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2534 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2535 IS_INTEGRAL (RTYPE (tree))))
2537 werror (E_PLUS_INVALID, "-");
2538 goto errorTreeReturn;
2541 /* if they are both literal then */
2542 /* rewrite the tree */
2543 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2545 tree->type = EX_VALUE;
2546 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2547 valFromType (RETYPE (tree)));
2548 tree->right = tree->left = NULL;
2549 TETYPE (tree) = getSpec (TTYPE (tree) =
2550 tree->opval.val->type);
2554 /* if the left & right are equal then zero */
2555 if (isAstEqual (tree->left, tree->right))
2557 tree->type = EX_VALUE;
2558 tree->left = tree->right = NULL;
2559 tree->opval.val = constVal ("0");
2560 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2564 /* if both of them are pointers or arrays then */
2565 /* the result is going to be an integer */
2566 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2567 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2568 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2570 /* if only the left is a pointer */
2571 /* then result is a pointer */
2572 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2573 TETYPE (tree) = getSpec (TTYPE (tree) =
2576 TETYPE (tree) = getSpec (TTYPE (tree) =
2577 computeType (LTYPE (tree),
2579 LRVAL (tree) = RRVAL (tree) = 1;
2582 /*------------------------------------------------------------------*/
2583 /*----------------------------*/
2585 /*----------------------------*/
2587 /* can be only integral type */
2588 if (!IS_INTEGRAL (LTYPE (tree)))
2590 werror (E_UNARY_OP, tree->opval.op);
2591 goto errorTreeReturn;
2594 /* if left is a literal then do it */
2595 if (IS_LITERAL (LTYPE (tree)))
2597 tree->type = EX_VALUE;
2598 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2600 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2604 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2607 /*------------------------------------------------------------------*/
2608 /*----------------------------*/
2610 /*----------------------------*/
2612 /* can be pointer */
2613 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2614 !IS_PTR (LTYPE (tree)) &&
2615 !IS_ARRAY (LTYPE (tree)))
2617 werror (E_UNARY_OP, tree->opval.op);
2618 goto errorTreeReturn;
2621 /* if left is a literal then do it */
2622 if (IS_LITERAL (LTYPE (tree)))
2624 tree->type = EX_VALUE;
2625 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2627 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2631 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2634 /*------------------------------------------------------------------*/
2635 /*----------------------------*/
2637 /*----------------------------*/
2640 TTYPE (tree) = LTYPE (tree);
2641 TETYPE (tree) = LETYPE (tree);
2645 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2650 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2652 werror (E_SHIFT_OP_INVALID);
2653 werror (W_CONTINUE, "left & right types are ");
2654 printTypeChain (LTYPE (tree), stderr);
2655 fprintf (stderr, ",");
2656 printTypeChain (RTYPE (tree), stderr);
2657 fprintf (stderr, "\n");
2658 goto errorTreeReturn;
2661 /* if they are both literal then */
2662 /* rewrite the tree */
2663 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2665 tree->type = EX_VALUE;
2666 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2667 valFromType (RETYPE (tree)),
2668 (tree->opval.op == LEFT_OP ? 1 : 0));
2669 tree->right = tree->left = NULL;
2670 TETYPE (tree) = getSpec (TTYPE (tree) =
2671 tree->opval.val->type);
2674 /* if only the right side is a literal & we are
2675 shifting more than size of the left operand then zero */
2676 if (IS_LITERAL (RTYPE (tree)) &&
2677 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2678 (getSize (LTYPE (tree)) * 8))
2680 werror (W_SHIFT_CHANGED,
2681 (tree->opval.op == LEFT_OP ? "left" : "right"));
2682 tree->type = EX_VALUE;
2683 tree->left = tree->right = NULL;
2684 tree->opval.val = constVal ("0");
2685 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2688 LRVAL (tree) = RRVAL (tree) = 1;
2689 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2691 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2695 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2699 /*------------------------------------------------------------------*/
2700 /*----------------------------*/
2702 /*----------------------------*/
2703 case CAST: /* change the type */
2704 /* cannot cast to an aggregate type */
2705 if (IS_AGGREGATE (LTYPE (tree)))
2707 werror (E_CAST_ILLEGAL);
2708 goto errorTreeReturn;
2711 /* make sure the type is complete and sane */
2712 checkTypeSanity(LETYPE(tree), "(cast)");
2715 /* if the right is a literal replace the tree */
2716 if (IS_LITERAL (RETYPE (tree))) {
2717 if (!IS_PTR (LTYPE (tree))) {
2718 tree->type = EX_VALUE;
2720 valCastLiteral (LTYPE (tree),
2721 floatFromVal (valFromType (RETYPE (tree))));
2724 TTYPE (tree) = tree->opval.val->type;
2725 tree->values.literalFromCast = 1;
2726 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2727 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2728 sym_link *rest = LTYPE(tree)->next;
2729 werror(W_LITERAL_GENERIC);
2730 TTYPE(tree) = newLink();
2731 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2732 TTYPE(tree)->next = rest;
2733 tree->left->opval.lnk = TTYPE(tree);
2736 TTYPE (tree) = LTYPE (tree);
2740 TTYPE (tree) = LTYPE (tree);
2744 /* if pointer to struct then check names */
2745 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2746 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2747 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2748 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2750 /* if the right is a literal replace the tree */
2751 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2752 tree->type = EX_VALUE;
2754 valCastLiteral (LTYPE (tree),
2755 floatFromVal (valFromType (RETYPE (tree))));
2758 TTYPE (tree) = tree->opval.val->type;
2759 tree->values.literalFromCast = 1;
2761 TTYPE (tree) = LTYPE (tree);
2765 TETYPE (tree) = getSpec (TTYPE (tree));
2769 /*------------------------------------------------------------------*/
2770 /*----------------------------*/
2771 /* logical &&, || */
2772 /*----------------------------*/
2775 /* each must me arithmetic type or be a pointer */
2776 if (!IS_PTR (LTYPE (tree)) &&
2777 !IS_ARRAY (LTYPE (tree)) &&
2778 !IS_INTEGRAL (LTYPE (tree)))
2780 werror (E_COMPARE_OP);
2781 goto errorTreeReturn;
2784 if (!IS_PTR (RTYPE (tree)) &&
2785 !IS_ARRAY (RTYPE (tree)) &&
2786 !IS_INTEGRAL (RTYPE (tree)))
2788 werror (E_COMPARE_OP);
2789 goto errorTreeReturn;
2791 /* if they are both literal then */
2792 /* rewrite the tree */
2793 if (IS_LITERAL (RTYPE (tree)) &&
2794 IS_LITERAL (LTYPE (tree)))
2796 tree->type = EX_VALUE;
2797 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2798 valFromType (RETYPE (tree)),
2800 tree->right = tree->left = NULL;
2801 TETYPE (tree) = getSpec (TTYPE (tree) =
2802 tree->opval.val->type);
2805 LRVAL (tree) = RRVAL (tree) = 1;
2806 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2809 /*------------------------------------------------------------------*/
2810 /*----------------------------*/
2811 /* comparison operators */
2812 /*----------------------------*/
2820 ast *lt = optimizeCompare (tree);
2826 /* if they are pointers they must be castable */
2827 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2829 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2831 werror (E_COMPARE_OP);
2832 fprintf (stderr, "comparing type ");
2833 printTypeChain (LTYPE (tree), stderr);
2834 fprintf (stderr, "to type ");
2835 printTypeChain (RTYPE (tree), stderr);
2836 fprintf (stderr, "\n");
2837 goto errorTreeReturn;
2840 /* else they should be promotable to one another */
2843 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2844 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2846 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2848 werror (E_COMPARE_OP);
2849 fprintf (stderr, "comparing type ");
2850 printTypeChain (LTYPE (tree), stderr);
2851 fprintf (stderr, "to type ");
2852 printTypeChain (RTYPE (tree), stderr);
2853 fprintf (stderr, "\n");
2854 goto errorTreeReturn;
2858 /* if they are both literal then */
2859 /* rewrite the tree */
2860 if (IS_LITERAL (RTYPE (tree)) &&
2861 IS_LITERAL (LTYPE (tree)))
2863 tree->type = EX_VALUE;
2864 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2865 valFromType (RETYPE (tree)),
2867 tree->right = tree->left = NULL;
2868 TETYPE (tree) = getSpec (TTYPE (tree) =
2869 tree->opval.val->type);
2872 LRVAL (tree) = RRVAL (tree) = 1;
2873 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2876 /*------------------------------------------------------------------*/
2877 /*----------------------------*/
2879 /*----------------------------*/
2880 case SIZEOF: /* evaluate wihout code generation */
2881 /* change the type to a integer */
2882 tree->type = EX_VALUE;
2883 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2884 tree->opval.val = constVal (buffer);
2885 tree->right = tree->left = NULL;
2886 TETYPE (tree) = getSpec (TTYPE (tree) =
2887 tree->opval.val->type);
2890 /*------------------------------------------------------------------*/
2891 /*----------------------------*/
2893 /*----------------------------*/
2895 /* return typeof enum value */
2896 tree->type = EX_VALUE;
2899 if (IS_SPEC(tree->right->ftype)) {
2900 switch (SPEC_NOUN(tree->right->ftype)) {
2902 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2903 else typeofv = TYPEOF_INT;
2906 typeofv = TYPEOF_FLOAT;
2909 typeofv = TYPEOF_CHAR;
2912 typeofv = TYPEOF_VOID;
2915 typeofv = TYPEOF_STRUCT;
2918 typeofv = TYPEOF_BIT;
2921 typeofv = TYPEOF_SBIT;
2927 switch (DCL_TYPE(tree->right->ftype)) {
2929 typeofv = TYPEOF_POINTER;
2932 typeofv = TYPEOF_FPOINTER;
2935 typeofv = TYPEOF_CPOINTER;
2938 typeofv = TYPEOF_GPOINTER;
2941 typeofv = TYPEOF_PPOINTER;
2944 typeofv = TYPEOF_IPOINTER;
2947 typeofv = TYPEOF_ARRAY;
2950 typeofv = TYPEOF_FUNCTION;
2956 sprintf (buffer, "%d", typeofv);
2957 tree->opval.val = constVal (buffer);
2958 tree->right = tree->left = NULL;
2959 TETYPE (tree) = getSpec (TTYPE (tree) =
2960 tree->opval.val->type);
2963 /*------------------------------------------------------------------*/
2964 /*----------------------------*/
2965 /* conditional operator '?' */
2966 /*----------------------------*/
2968 /* the type is value of the colon operator (on the right) */
2969 assert(IS_COLON_OP(tree->right));
2970 /* if already known then replace the tree : optimizer will do it
2971 but faster to do it here */
2972 if (IS_LITERAL (LTYPE(tree))) {
2973 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2974 return decorateType(tree->right->left) ;
2976 return decorateType(tree->right->right) ;
2979 tree->right = decorateType(tree->right);
2980 TTYPE (tree) = RTYPE(tree);
2981 TETYPE (tree) = getSpec (TTYPE (tree));
2986 /* if they don't match we have a problem */
2987 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2989 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2990 goto errorTreeReturn;
2993 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2994 TETYPE (tree) = getSpec (TTYPE (tree));
2998 /*------------------------------------------------------------------*/
2999 /*----------------------------*/
3000 /* assignment operators */
3001 /*----------------------------*/
3004 /* for these it must be both must be integral */
3005 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3006 !IS_ARITHMETIC (RTYPE (tree)))
3008 werror (E_OPS_INTEGRAL);
3009 goto errorTreeReturn;
3012 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3014 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3015 werror (E_CODE_WRITE, " ");
3019 werror (E_LVALUE_REQUIRED, "*= or /=");
3020 goto errorTreeReturn;
3031 /* for these it must be both must be integral */
3032 if (!IS_INTEGRAL (LTYPE (tree)) ||
3033 !IS_INTEGRAL (RTYPE (tree)))
3035 werror (E_OPS_INTEGRAL);
3036 goto errorTreeReturn;
3039 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3041 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3042 werror (E_CODE_WRITE, " ");
3046 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3047 goto errorTreeReturn;
3053 /*------------------------------------------------------------------*/
3054 /*----------------------------*/
3056 /*----------------------------*/
3058 if (!(IS_PTR (LTYPE (tree)) ||
3059 IS_ARITHMETIC (LTYPE (tree))))
3061 werror (E_PLUS_INVALID, "-=");
3062 goto errorTreeReturn;
3065 if (!(IS_PTR (RTYPE (tree)) ||
3066 IS_ARITHMETIC (RTYPE (tree))))
3068 werror (E_PLUS_INVALID, "-=");
3069 goto errorTreeReturn;
3072 TETYPE (tree) = getSpec (TTYPE (tree) =
3073 computeType (LTYPE (tree),
3076 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3077 werror (E_CODE_WRITE, " ");
3081 werror (E_LVALUE_REQUIRED, "-=");
3082 goto errorTreeReturn;
3088 /*------------------------------------------------------------------*/
3089 /*----------------------------*/
3091 /*----------------------------*/
3093 /* this is not a unary operation */
3094 /* if both pointers then problem */
3095 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3097 werror (E_PTR_PLUS_PTR);
3098 goto errorTreeReturn;
3101 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3103 werror (E_PLUS_INVALID, "+=");
3104 goto errorTreeReturn;
3107 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3109 werror (E_PLUS_INVALID, "+=");
3110 goto errorTreeReturn;
3113 TETYPE (tree) = getSpec (TTYPE (tree) =
3114 computeType (LTYPE (tree),
3117 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3118 werror (E_CODE_WRITE, " ");
3122 werror (E_LVALUE_REQUIRED, "+=");
3123 goto errorTreeReturn;
3126 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3127 tree->opval.op = '=';
3131 /*------------------------------------------------------------------*/
3132 /*----------------------------*/
3133 /* straight assignemnt */
3134 /*----------------------------*/
3136 /* cannot be an aggregate */
3137 if (IS_AGGREGATE (LTYPE (tree)))
3139 werror (E_AGGR_ASSIGN);
3140 goto errorTreeReturn;
3143 /* they should either match or be castable */
3144 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3146 werror (E_TYPE_MISMATCH, "assignment", " ");
3147 fprintf (stderr, "type --> '");
3148 printTypeChain (RTYPE (tree), stderr);
3149 fprintf (stderr, "' ");
3150 fprintf (stderr, "assigned to type --> '");
3151 printTypeChain (LTYPE (tree), stderr);
3152 fprintf (stderr, "'\n");
3153 goto errorTreeReturn;
3156 /* if the left side of the tree is of type void
3157 then report error */
3158 if (IS_VOID (LTYPE (tree)))
3160 werror (E_CAST_ZERO);
3161 printFromToType(RTYPE(tree), LTYPE(tree));
3164 TETYPE (tree) = getSpec (TTYPE (tree) =
3168 if (!tree->initMode ) {
3169 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3170 werror (E_CODE_WRITE, " ");
3174 werror (E_LVALUE_REQUIRED, "=");
3175 goto errorTreeReturn;
3180 /*------------------------------------------------------------------*/
3181 /*----------------------------*/
3182 /* comma operator */
3183 /*----------------------------*/
3185 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3188 /*------------------------------------------------------------------*/
3189 /*----------------------------*/
3191 /*----------------------------*/
3195 if (processParms (tree->left,
3196 FUNC_ARGS(tree->left->ftype),
3197 tree->right, &parmNumber, TRUE)) {
3198 goto errorTreeReturn;
3201 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3202 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3204 //FUNC_ARGS(tree->left->ftype) =
3205 //reverseVal (FUNC_ARGS(tree->left->ftype));
3206 reverseParms (tree->right);
3209 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3212 /*------------------------------------------------------------------*/
3213 /*----------------------------*/
3214 /* return statement */
3215 /*----------------------------*/
3220 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3222 werror (W_RETURN_MISMATCH);
3223 printFromToType (RTYPE(tree), currFunc->type->next);
3224 goto errorTreeReturn;
3227 if (IS_VOID (currFunc->type->next)
3229 !IS_VOID (RTYPE (tree)))
3231 werror (E_FUNC_VOID);
3232 goto errorTreeReturn;
3235 /* if there is going to be a casing required then add it */
3236 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3239 decorateType (newNode (CAST,
3240 newAst_LINK (copyLinkChain (currFunc->type->next)),
3249 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3251 werror (E_VOID_FUNC, currFunc->name);
3252 goto errorTreeReturn;
3255 TTYPE (tree) = TETYPE (tree) = NULL;
3258 /*------------------------------------------------------------------*/
3259 /*----------------------------*/
3260 /* switch statement */
3261 /*----------------------------*/
3263 /* the switch value must be an integer */
3264 if (!IS_INTEGRAL (LTYPE (tree)))
3266 werror (E_SWITCH_NON_INTEGER);
3267 goto errorTreeReturn;
3270 TTYPE (tree) = TETYPE (tree) = NULL;
3273 /*------------------------------------------------------------------*/
3274 /*----------------------------*/
3276 /*----------------------------*/
3278 tree->left = backPatchLabels (tree->left,
3281 TTYPE (tree) = TETYPE (tree) = NULL;
3284 /*------------------------------------------------------------------*/
3285 /*----------------------------*/
3287 /*----------------------------*/
3290 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3291 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3292 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3294 /* if the for loop is reversible then
3295 reverse it otherwise do what we normally
3301 if (isLoopReversible (tree, &sym, &init, &end))
3302 return reverseLoop (tree, sym, init, end);
3304 return decorateType (createFor (AST_FOR (tree, trueLabel),
3305 AST_FOR (tree, continueLabel),
3306 AST_FOR (tree, falseLabel),
3307 AST_FOR (tree, condLabel),
3308 AST_FOR (tree, initExpr),
3309 AST_FOR (tree, condExpr),
3310 AST_FOR (tree, loopExpr),
3314 TTYPE (tree) = TETYPE (tree) = NULL;
3318 /* some error found this tree will be killed */
3320 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3321 tree->opval.op = NULLOP;
3327 /*-----------------------------------------------------------------*/
3328 /* sizeofOp - processes size of operation */
3329 /*-----------------------------------------------------------------*/
3331 sizeofOp (sym_link * type)
3335 /* make sure the type is complete and sane */
3336 checkTypeSanity(type, "(sizeof)");
3338 /* get the size and convert it to character */
3339 sprintf (buff, "%d", getSize (type));
3341 /* now convert into value */
3342 return constVal (buff);
3346 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3347 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3348 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3349 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3350 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3351 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3352 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3354 /*-----------------------------------------------------------------*/
3355 /* backPatchLabels - change and or not operators to flow control */
3356 /*-----------------------------------------------------------------*/
3358 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3364 if (!(IS_ANDORNOT (tree)))
3367 /* if this an and */
3370 static int localLbl = 0;
3373 sprintf (buffer, "_and_%d", localLbl++);
3374 localLabel = newSymbol (buffer, NestLevel);
3376 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3378 /* if left is already a IFX then just change the if true label in that */
3379 if (!IS_IFX (tree->left))
3380 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3382 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3383 /* right is a IFX then just join */
3384 if (IS_IFX (tree->right))
3385 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3387 tree->right = createLabel (localLabel, tree->right);
3388 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3390 return newNode (NULLOP, tree->left, tree->right);
3393 /* if this is an or operation */
3396 static int localLbl = 0;
3399 sprintf (buffer, "_or_%d", localLbl++);
3400 localLabel = newSymbol (buffer, NestLevel);
3402 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3404 /* if left is already a IFX then just change the if true label in that */
3405 if (!IS_IFX (tree->left))
3406 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3408 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3409 /* right is a IFX then just join */
3410 if (IS_IFX (tree->right))
3411 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3413 tree->right = createLabel (localLabel, tree->right);
3414 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3416 return newNode (NULLOP, tree->left, tree->right);
3422 int wasnot = IS_NOT (tree->left);
3423 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3425 /* if the left is already a IFX */
3426 if (!IS_IFX (tree->left))
3427 tree->left = newNode (IFX, tree->left, NULL);
3431 tree->left->trueLabel = trueLabel;
3432 tree->left->falseLabel = falseLabel;
3436 tree->left->trueLabel = falseLabel;
3437 tree->left->falseLabel = trueLabel;
3444 tree->trueLabel = trueLabel;
3445 tree->falseLabel = falseLabel;
3452 /*-----------------------------------------------------------------*/
3453 /* createBlock - create expression tree for block */
3454 /*-----------------------------------------------------------------*/
3456 createBlock (symbol * decl, ast * body)
3460 /* if the block has nothing */
3464 ex = newNode (BLOCK, NULL, body);
3465 ex->values.sym = decl;
3467 ex->right = ex->right;
3473 /*-----------------------------------------------------------------*/
3474 /* createLabel - creates the expression tree for labels */
3475 /*-----------------------------------------------------------------*/
3477 createLabel (symbol * label, ast * stmnt)
3480 char name[SDCC_NAME_MAX + 1];
3483 /* must create fresh symbol if the symbol name */
3484 /* exists in the symbol table, since there can */
3485 /* be a variable with the same name as the labl */
3486 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3487 (csym->level == label->level))
3488 label = newSymbol (label->name, label->level);
3490 /* change the name before putting it in add _ */
3491 sprintf (name, "%s", label->name);
3493 /* put the label in the LabelSymbol table */
3494 /* but first check if a label of the same */
3496 if ((csym = findSym (LabelTab, NULL, name)))
3497 werror (E_DUPLICATE_LABEL, label->name);
3499 addSym (LabelTab, label, name, label->level, 0, 0);
3502 label->key = labelKey++;
3503 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3509 /*-----------------------------------------------------------------*/
3510 /* createCase - generates the parsetree for a case statement */
3511 /*-----------------------------------------------------------------*/
3513 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3515 char caseLbl[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 caseVal = decorateType (resolveSymbols (caseVal));
3528 /* if not a constant then error */
3529 if (!IS_LITERAL (caseVal->ftype))
3531 werror (E_CASE_CONSTANT);
3535 /* if not a integer than error */
3536 if (!IS_INTEGRAL (caseVal->ftype))
3538 werror (E_CASE_NON_INTEGER);
3542 /* find the end of the switch values chain */
3543 if (!(val = swStat->values.switchVals.swVals))
3544 swStat->values.switchVals.swVals = caseVal->opval.val;
3547 /* also order the cases according to value */
3549 int cVal = (int) floatFromVal (caseVal->opval.val);
3550 while (val && (int) floatFromVal (val) < cVal)
3556 /* if we reached the end then */
3559 pval->next = caseVal->opval.val;
3563 /* we found a value greater than */
3564 /* the current value we must add this */
3565 /* before the value */
3566 caseVal->opval.val->next = val;
3568 /* if this was the first in chain */
3569 if (swStat->values.switchVals.swVals == val)
3570 swStat->values.switchVals.swVals =
3573 pval->next = caseVal->opval.val;
3578 /* create the case label */
3579 sprintf (caseLbl, "_case_%d_%d",
3580 swStat->values.switchVals.swNum,
3581 (int) floatFromVal (caseVal->opval.val));
3583 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3588 /*-----------------------------------------------------------------*/
3589 /* createDefault - creates the parse tree for the default statement */
3590 /*-----------------------------------------------------------------*/
3592 createDefault (ast * swStat, ast * stmnt)
3594 char defLbl[SDCC_NAME_MAX + 1];
3596 /* if the switch statement does not exist */
3597 /* then case is out of context */
3600 werror (E_CASE_CONTEXT);
3604 /* turn on the default flag */
3605 swStat->values.switchVals.swDefault = 1;
3607 /* create the label */
3608 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3609 return createLabel (newSymbol (defLbl, 0), stmnt);
3612 /*-----------------------------------------------------------------*/
3613 /* createIf - creates the parsetree for the if statement */
3614 /*-----------------------------------------------------------------*/
3616 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3618 static int Lblnum = 0;
3620 symbol *ifTrue, *ifFalse, *ifEnd;
3622 /* if neither exists */
3623 if (!elseBody && !ifBody) {
3624 // if there are no side effects (i++, j() etc)
3625 if (!hasSEFcalls(condAst)) {
3630 /* create the labels */
3631 sprintf (buffer, "_iffalse_%d", Lblnum);
3632 ifFalse = newSymbol (buffer, NestLevel);
3633 /* if no else body then end == false */
3638 sprintf (buffer, "_ifend_%d", Lblnum);
3639 ifEnd = newSymbol (buffer, NestLevel);
3642 sprintf (buffer, "_iftrue_%d", Lblnum);
3643 ifTrue = newSymbol (buffer, NestLevel);
3647 /* attach the ifTrue label to the top of it body */
3648 ifBody = createLabel (ifTrue, ifBody);
3649 /* attach a goto end to the ifBody if else is present */
3652 ifBody = newNode (NULLOP, ifBody,
3654 newAst_VALUE (symbolVal (ifEnd)),
3656 /* put the elseLabel on the else body */
3657 elseBody = createLabel (ifFalse, elseBody);
3658 /* out the end at the end of the body */
3659 elseBody = newNode (NULLOP,
3661 createLabel (ifEnd, NULL));
3665 ifBody = newNode (NULLOP, ifBody,
3666 createLabel (ifFalse, NULL));
3668 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3669 if (IS_IFX (condAst))
3672 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3674 return newNode (NULLOP, ifTree,
3675 newNode (NULLOP, ifBody, elseBody));
3679 /*-----------------------------------------------------------------*/
3680 /* createDo - creates parse tree for do */
3683 /* _docontinue_n: */
3684 /* condition_expression +-> trueLabel -> _dobody_n */
3686 /* +-> falseLabel-> _dobreak_n */
3688 /*-----------------------------------------------------------------*/
3690 createDo (symbol * trueLabel, symbol * continueLabel,
3691 symbol * falseLabel, ast * condAst, ast * doBody)
3696 /* if the body does not exist then it is simple */
3699 condAst = backPatchLabels (condAst, continueLabel, NULL);
3700 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3701 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3702 doTree->trueLabel = continueLabel;
3703 doTree->falseLabel = NULL;
3707 /* otherwise we have a body */
3708 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3710 /* attach the body label to the top */
3711 doBody = createLabel (trueLabel, doBody);
3712 /* attach the continue label to end of body */
3713 doBody = newNode (NULLOP, doBody,
3714 createLabel (continueLabel, NULL));
3716 /* now put the break label at the end */
3717 if (IS_IFX (condAst))
3720 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3722 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3724 /* putting it together */
3725 return newNode (NULLOP, doBody, doTree);
3728 /*-----------------------------------------------------------------*/
3729 /* createFor - creates parse tree for 'for' statement */
3732 /* condExpr +-> trueLabel -> _forbody_n */
3734 /* +-> falseLabel-> _forbreak_n */
3737 /* _forcontinue_n: */
3739 /* goto _forcond_n ; */
3741 /*-----------------------------------------------------------------*/
3743 createFor (symbol * trueLabel, symbol * continueLabel,
3744 symbol * falseLabel, symbol * condLabel,
3745 ast * initExpr, ast * condExpr, ast * loopExpr,
3750 /* if loopexpression not present then we can generate it */
3751 /* the same way as a while */
3753 return newNode (NULLOP, initExpr,
3754 createWhile (trueLabel, continueLabel,
3755 falseLabel, condExpr, forBody));
3756 /* vanilla for statement */
3757 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3759 if (condExpr && !IS_IFX (condExpr))
3760 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3763 /* attach condition label to condition */
3764 condExpr = createLabel (condLabel, condExpr);
3766 /* attach body label to body */
3767 forBody = createLabel (trueLabel, forBody);
3769 /* attach continue to forLoop expression & attach */
3770 /* goto the forcond @ and of loopExpression */
3771 loopExpr = createLabel (continueLabel,
3775 newAst_VALUE (symbolVal (condLabel)),
3777 /* now start putting them together */
3778 forTree = newNode (NULLOP, initExpr, condExpr);
3779 forTree = newNode (NULLOP, forTree, forBody);
3780 forTree = newNode (NULLOP, forTree, loopExpr);
3781 /* finally add the break label */
3782 forTree = newNode (NULLOP, forTree,
3783 createLabel (falseLabel, NULL));
3787 /*-----------------------------------------------------------------*/
3788 /* createWhile - creates parse tree for while statement */
3789 /* the while statement will be created as follows */
3791 /* _while_continue_n: */
3792 /* condition_expression +-> trueLabel -> _while_boby_n */
3794 /* +-> falseLabel -> _while_break_n */
3795 /* _while_body_n: */
3797 /* goto _while_continue_n */
3798 /* _while_break_n: */
3799 /*-----------------------------------------------------------------*/
3801 createWhile (symbol * trueLabel, symbol * continueLabel,
3802 symbol * falseLabel, ast * condExpr, ast * whileBody)
3806 /* put the continue label */
3807 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3808 condExpr = createLabel (continueLabel, condExpr);
3809 condExpr->lineno = 0;
3811 /* put the body label in front of the body */
3812 whileBody = createLabel (trueLabel, whileBody);
3813 whileBody->lineno = 0;
3814 /* put a jump to continue at the end of the body */
3815 /* and put break label at the end of the body */
3816 whileBody = newNode (NULLOP,
3819 newAst_VALUE (symbolVal (continueLabel)),
3820 createLabel (falseLabel, NULL)));
3822 /* put it all together */
3823 if (IS_IFX (condExpr))
3824 whileTree = condExpr;
3827 whileTree = newNode (IFX, condExpr, NULL);
3828 /* put the true & false labels in place */
3829 whileTree->trueLabel = trueLabel;
3830 whileTree->falseLabel = falseLabel;
3833 return newNode (NULLOP, whileTree, whileBody);
3836 /*-----------------------------------------------------------------*/
3837 /* optimizeGetHbit - get highest order bit of the expression */
3838 /*-----------------------------------------------------------------*/
3840 optimizeGetHbit (ast * tree)
3843 /* if this is not a bit and */
3844 if (!IS_BITAND (tree))
3847 /* will look for tree of the form
3848 ( expr >> ((sizeof expr) -1) ) & 1 */
3849 if (!IS_AST_LIT_VALUE (tree->right))
3852 if (AST_LIT_VALUE (tree->right) != 1)
3855 if (!IS_RIGHT_OP (tree->left))
3858 if (!IS_AST_LIT_VALUE (tree->left->right))
3861 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3862 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3865 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3869 /*-----------------------------------------------------------------*/
3870 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3871 /*-----------------------------------------------------------------*/
3873 optimizeRRCRLC (ast * root)
3875 /* will look for trees of the form
3876 (?expr << 1) | (?expr >> 7) or
3877 (?expr >> 7) | (?expr << 1) will make that
3878 into a RLC : operation ..
3880 (?expr >> 1) | (?expr << 7) or
3881 (?expr << 7) | (?expr >> 1) will make that
3882 into a RRC operation
3883 note : by 7 I mean (number of bits required to hold the
3885 /* if the root operations is not a | operation the not */
3886 if (!IS_BITOR (root))
3889 /* I have to think of a better way to match patterns this sucks */
3890 /* that aside let start looking for the first case : I use a the
3891 negative check a lot to improve the efficiency */
3892 /* (?expr << 1) | (?expr >> 7) */
3893 if (IS_LEFT_OP (root->left) &&
3894 IS_RIGHT_OP (root->right))
3897 if (!SPEC_USIGN (TETYPE (root->left->left)))
3900 if (!IS_AST_LIT_VALUE (root->left->right) ||
3901 !IS_AST_LIT_VALUE (root->right->right))
3904 /* make sure it is the same expression */
3905 if (!isAstEqual (root->left->left,
3909 if (AST_LIT_VALUE (root->left->right) != 1)
3912 if (AST_LIT_VALUE (root->right->right) !=
3913 (getSize (TTYPE (root->left->left)) * 8 - 1))
3916 /* whew got the first case : create the AST */
3917 return newNode (RLC, root->left->left, NULL);
3921 /* check for second case */
3922 /* (?expr >> 7) | (?expr << 1) */
3923 if (IS_LEFT_OP (root->right) &&
3924 IS_RIGHT_OP (root->left))
3927 if (!SPEC_USIGN (TETYPE (root->left->left)))
3930 if (!IS_AST_LIT_VALUE (root->left->right) ||
3931 !IS_AST_LIT_VALUE (root->right->right))
3934 /* make sure it is the same symbol */
3935 if (!isAstEqual (root->left->left,
3939 if (AST_LIT_VALUE (root->right->right) != 1)
3942 if (AST_LIT_VALUE (root->left->right) !=
3943 (getSize (TTYPE (root->left->left)) * 8 - 1))
3946 /* whew got the first case : create the AST */
3947 return newNode (RLC, root->left->left, NULL);
3952 /* third case for RRC */
3953 /* (?symbol >> 1) | (?symbol << 7) */
3954 if (IS_LEFT_OP (root->right) &&
3955 IS_RIGHT_OP (root->left))
3958 if (!SPEC_USIGN (TETYPE (root->left->left)))
3961 if (!IS_AST_LIT_VALUE (root->left->right) ||
3962 !IS_AST_LIT_VALUE (root->right->right))
3965 /* make sure it is the same symbol */
3966 if (!isAstEqual (root->left->left,
3970 if (AST_LIT_VALUE (root->left->right) != 1)
3973 if (AST_LIT_VALUE (root->right->right) !=
3974 (getSize (TTYPE (root->left->left)) * 8 - 1))
3977 /* whew got the first case : create the AST */
3978 return newNode (RRC, root->left->left, NULL);
3982 /* fourth and last case for now */
3983 /* (?symbol << 7) | (?symbol >> 1) */
3984 if (IS_RIGHT_OP (root->right) &&
3985 IS_LEFT_OP (root->left))
3988 if (!SPEC_USIGN (TETYPE (root->left->left)))
3991 if (!IS_AST_LIT_VALUE (root->left->right) ||
3992 !IS_AST_LIT_VALUE (root->right->right))
3995 /* make sure it is the same symbol */
3996 if (!isAstEqual (root->left->left,
4000 if (AST_LIT_VALUE (root->right->right) != 1)
4003 if (AST_LIT_VALUE (root->left->right) !=
4004 (getSize (TTYPE (root->left->left)) * 8 - 1))
4007 /* whew got the first case : create the AST */
4008 return newNode (RRC, root->left->left, NULL);
4012 /* not found return root */
4016 /*-----------------------------------------------------------------*/
4017 /* optimizeCompare - otimizes compares for bit variables */
4018 /*-----------------------------------------------------------------*/
4020 optimizeCompare (ast * root)
4022 ast *optExpr = NULL;
4025 unsigned int litValue;
4027 /* if nothing then return nothing */
4031 /* if not a compare op then do leaves */
4032 if (!IS_COMPARE_OP (root))
4034 root->left = optimizeCompare (root->left);
4035 root->right = optimizeCompare (root->right);
4039 /* if left & right are the same then depending
4040 of the operation do */
4041 if (isAstEqual (root->left, root->right))
4043 switch (root->opval.op)
4048 optExpr = newAst_VALUE (constVal ("0"));
4053 optExpr = newAst_VALUE (constVal ("1"));
4057 return decorateType (optExpr);
4060 vleft = (root->left->type == EX_VALUE ?
4061 root->left->opval.val : NULL);
4063 vright = (root->right->type == EX_VALUE ?
4064 root->right->opval.val : NULL);
4066 //#define EXPERIMENTAL
4068 /* if left is unsigned and right is literal */
4069 if (vleft && vright &&
4070 IS_UNSIGNED(vleft->etype) &&
4071 IS_LITERAL(vright->etype)) {
4072 double dval=floatFromVal(vright);
4073 int op=root->opval.op;
4075 fprintf (stderr,"op: '");
4077 case LE_OP: fprintf (stderr, "<= '"); break;
4078 case EQ_OP: fprintf (stderr, "== '"); break;
4079 case GE_OP: fprintf (stderr, ">= '"); break;
4080 default: fprintf (stderr, "%c '", op); break;
4082 fprintf (stderr, "%f\n", dval);
4089 if (dval<0 || (op=='<' && dval==0)) {
4090 // unsigned is never < 0
4091 werror (W_IF_NEVER_TRUE);
4092 optExpr = newAst_VALUE (constVal("0"));
4093 return decorateType (optExpr);
4097 // change this into a cheaper EQ_OP
4098 fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
4099 root->opval.op=EQ_OP;
4106 if (dval>0 || (op==GE_OP && dval==0)) {
4107 // unsigned is never < 0
4108 werror (W_IF_ALWAYS_TRUE);
4109 optExpr = newAst_VALUE (constVal("1"));
4110 return decorateType (optExpr);
4114 // change this into a cheaper reversed EQ_OP
4115 fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
4116 root->opval.op=EQ_OP;
4123 /* if left is a BITVAR in BITSPACE */
4124 /* and right is a LITERAL then opt- */
4125 /* imize else do nothing */
4126 if (vleft && vright &&
4127 IS_BITVAR (vleft->etype) &&
4128 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4129 IS_LITERAL (vright->etype))
4132 /* if right side > 1 then comparison may never succeed */
4133 if ((litValue = (int) floatFromVal (vright)) > 1)
4135 werror (W_BAD_COMPARE);
4141 switch (root->opval.op)
4143 case '>': /* bit value greater than 1 cannot be */
4144 werror (W_BAD_COMPARE);
4148 case '<': /* bit value < 1 means 0 */
4150 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4153 case LE_OP: /* bit value <= 1 means no check */
4154 optExpr = newAst_VALUE (vright);
4157 case GE_OP: /* bit value >= 1 means only check for = */
4159 optExpr = newAst_VALUE (vleft);
4164 { /* literal is zero */
4165 switch (root->opval.op)
4167 case '<': /* bit value < 0 cannot be */
4168 werror (W_BAD_COMPARE);
4172 case '>': /* bit value > 0 means 1 */
4174 optExpr = newAst_VALUE (vleft);
4177 case LE_OP: /* bit value <= 0 means no check */
4178 case GE_OP: /* bit value >= 0 means no check */
4179 werror (W_BAD_COMPARE);
4183 case EQ_OP: /* bit == 0 means ! of bit */
4184 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4188 return decorateType (resolveSymbols (optExpr));
4189 } /* end-of-if of BITVAR */
4194 /*-----------------------------------------------------------------*/
4195 /* addSymToBlock : adds the symbol to the first block we find */
4196 /*-----------------------------------------------------------------*/
4198 addSymToBlock (symbol * sym, ast * tree)
4200 /* reached end of tree or a leaf */
4201 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4205 if (IS_AST_OP (tree) &&
4206 tree->opval.op == BLOCK)
4209 symbol *lsym = copySymbol (sym);
4211 lsym->next = AST_VALUES (tree, sym);
4212 AST_VALUES (tree, sym) = lsym;
4216 addSymToBlock (sym, tree->left);
4217 addSymToBlock (sym, tree->right);
4220 /*-----------------------------------------------------------------*/
4221 /* processRegParms - do processing for register parameters */
4222 /*-----------------------------------------------------------------*/
4224 processRegParms (value * args, ast * body)
4228 if (IS_REGPARM (args->etype))
4229 addSymToBlock (args->sym, body);
4234 /*-----------------------------------------------------------------*/
4235 /* resetParmKey - resets the operandkeys for the symbols */
4236 /*-----------------------------------------------------------------*/
4237 DEFSETFUNC (resetParmKey)
4248 /*-----------------------------------------------------------------*/
4249 /* createFunction - This is the key node that calls the iCode for */
4250 /* generating the code for a function. Note code */
4251 /* is generated function by function, later when */
4252 /* add inter-procedural analysis this will change */
4253 /*-----------------------------------------------------------------*/
4255 createFunction (symbol * name, ast * body)
4261 iCode *piCode = NULL;
4263 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4264 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4266 /* if check function return 0 then some problem */
4267 if (checkFunction (name, NULL) == 0)
4270 /* create a dummy block if none exists */
4272 body = newNode (BLOCK, NULL, NULL);
4276 /* check if the function name already in the symbol table */
4277 if ((csym = findSym (SymbolTab, NULL, name->name)))
4280 /* special case for compiler defined functions
4281 we need to add the name to the publics list : this
4282 actually means we are now compiling the compiler
4286 addSet (&publics, name);
4292 allocVariables (name);
4294 name->lastLine = yylineno;
4297 #if 0 // jwk: this is now done in addDecl()
4298 processFuncArgs (currFunc);
4301 /* set the stack pointer */
4302 /* PENDING: check this for the mcs51 */
4303 stackPtr = -port->stack.direction * port->stack.call_overhead;
4304 if (IFFUNC_ISISR (name->type))
4305 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4306 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4307 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4309 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4311 fetype = getSpec (name->type); /* get the specifier for the function */
4312 /* if this is a reentrant function then */
4313 if (IFFUNC_ISREENT (name->type))
4316 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4318 /* do processing for parameters that are passed in registers */
4319 processRegParms (FUNC_ARGS(name->type), body);
4321 /* set the stack pointer */
4325 /* allocate & autoinit the block variables */
4326 processBlockVars (body, &stack, ALLOCATE);
4328 /* save the stack information */
4329 if (options.useXstack)
4330 name->xstack = SPEC_STAK (fetype) = stack;
4332 name->stack = SPEC_STAK (fetype) = stack;
4334 /* name needs to be mangled */
4335 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4337 body = resolveSymbols (body); /* resolve the symbols */
4338 body = decorateType (body); /* propagateType & do semantic checks */
4340 ex = newAst_VALUE (symbolVal (name)); /* create name */
4341 ex = newNode (FUNCTION, ex, body);
4342 ex->values.args = FUNC_ARGS(name->type);
4344 if (options.dump_tree) PA(ex);
4347 werror (E_FUNC_NO_CODE, name->name);
4351 /* create the node & generate intermediate code */
4353 codeOutFile = code->oFile;
4354 piCode = iCodeFromAst (ex);
4358 werror (E_FUNC_NO_CODE, name->name);
4362 eBBlockFromiCode (piCode);
4364 /* if there are any statics then do them */
4367 GcurMemmap = statsg;
4368 codeOutFile = statsg->oFile;
4369 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4375 /* dealloc the block variables */
4376 processBlockVars (body, &stack, DEALLOCATE);
4377 /* deallocate paramaters */
4378 deallocParms (FUNC_ARGS(name->type));
4380 if (IFFUNC_ISREENT (name->type))
4383 /* we are done freeup memory & cleanup */
4387 FUNC_HASBODY(name->type) = 1;
4388 addSet (&operKeyReset, name);
4389 applyToSet (operKeyReset, resetParmKey);
4392 cdbStructBlock (1, cdbFile);
4394 cleanUpLevel (LabelTab, 0);
4395 cleanUpBlock (StructTab, 1);
4396 cleanUpBlock (TypedefTab, 1);
4398 xstack->syms = NULL;
4399 istack->syms = NULL;
4404 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4405 /*-----------------------------------------------------------------*/
4406 /* ast_print : prints the ast (for debugging purposes) */
4407 /*-----------------------------------------------------------------*/
4409 void ast_print (ast * tree, FILE *outfile, int indent)
4414 /* can print only decorated trees */
4415 if (!tree->decorated) return;
4417 /* if any child is an error | this one is an error do nothing */
4418 if (tree->isError ||
4419 (tree->left && tree->left->isError) ||
4420 (tree->right && tree->right->isError)) {
4421 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4425 /* print the line */
4426 /* if not block & function */
4427 if (tree->type == EX_OP &&
4428 (tree->opval.op != FUNCTION &&
4429 tree->opval.op != BLOCK &&
4430 tree->opval.op != NULLOP)) {
4433 if (tree->opval.op == FUNCTION) {
4435 value *args=FUNC_ARGS(tree->left->opval.val->type);
4436 fprintf(outfile,"FUNCTION (%s=%p) type (",
4437 tree->left->opval.val->name, tree);
4438 printTypeChain (tree->ftype,outfile);
4439 fprintf(outfile,") args (");
4442 fprintf (outfile, ", ");
4444 printTypeChain (args ? args->type : NULL, outfile);
4446 args= args ? args->next : NULL;
4448 fprintf(outfile,")\n");
4449 ast_print(tree->left,outfile,indent);
4450 ast_print(tree->right,outfile,indent);
4453 if (tree->opval.op == BLOCK) {
4454 symbol *decls = tree->values.sym;
4455 INDENT(indent,outfile);
4456 fprintf(outfile,"{\n");
4458 INDENT(indent+2,outfile);
4459 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4460 decls->name, decls);
4461 printTypeChain(decls->type,outfile);
4462 fprintf(outfile,")\n");
4464 decls = decls->next;
4466 ast_print(tree->right,outfile,indent+2);
4467 INDENT(indent,outfile);
4468 fprintf(outfile,"}\n");
4471 if (tree->opval.op == NULLOP) {
4472 fprintf(outfile,"\n");
4473 ast_print(tree->left,outfile,indent);
4474 fprintf(outfile,"\n");
4475 ast_print(tree->right,outfile,indent);
4478 INDENT(indent,outfile);
4480 /*------------------------------------------------------------------*/
4481 /*----------------------------*/
4482 /* leaf has been reached */
4483 /*----------------------------*/
4484 /* if this is of type value */
4485 /* just get the type */
4486 if (tree->type == EX_VALUE) {
4488 if (IS_LITERAL (tree->opval.val->etype)) {
4489 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4490 (int) floatFromVal(tree->opval.val),
4491 (int) floatFromVal(tree->opval.val),
4492 floatFromVal(tree->opval.val));
4493 } else if (tree->opval.val->sym) {
4494 /* if the undefined flag is set then give error message */
4495 if (tree->opval.val->sym->undefined) {
4496 fprintf(outfile,"UNDEFINED SYMBOL ");
4498 fprintf(outfile,"SYMBOL ");
4500 fprintf(outfile,"(%s=%p)",
4501 tree->opval.val->sym->name,tree);
4504 fprintf(outfile," type (");
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4508 fprintf(outfile,"\n");
4513 /* if type link for the case of cast */
4514 if (tree->type == EX_LINK) {
4515 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4516 printTypeChain(tree->opval.lnk,outfile);
4517 fprintf(outfile,")\n");
4522 /* depending on type of operator do */
4524 switch (tree->opval.op) {
4525 /*------------------------------------------------------------------*/
4526 /*----------------------------*/
4528 /*----------------------------*/
4530 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4531 printTypeChain(tree->ftype,outfile);
4532 fprintf(outfile,")\n");
4533 ast_print(tree->left,outfile,indent+2);
4534 ast_print(tree->right,outfile,indent+2);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4540 /*----------------------------*/
4542 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->left,outfile,indent+2);
4546 ast_print(tree->right,outfile,indent+2);
4549 /*------------------------------------------------------------------*/
4550 /*----------------------------*/
4551 /* struct/union pointer */
4552 /*----------------------------*/
4554 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4555 printTypeChain(tree->ftype,outfile);
4556 fprintf(outfile,")\n");
4557 ast_print(tree->left,outfile,indent+2);
4558 ast_print(tree->right,outfile,indent+2);
4561 /*------------------------------------------------------------------*/
4562 /*----------------------------*/
4563 /* ++/-- operation */
4564 /*----------------------------*/
4565 case INC_OP: /* incerement operator unary so left only */
4566 fprintf(outfile,"INC_OP (%p) type (",tree);
4567 printTypeChain(tree->ftype,outfile);
4568 fprintf(outfile,")\n");
4569 ast_print(tree->left,outfile,indent+2);
4573 fprintf(outfile,"DEC_OP (%p) type (",tree);
4574 printTypeChain(tree->ftype,outfile);
4575 fprintf(outfile,")\n");
4576 ast_print(tree->left,outfile,indent+2);
4579 /*------------------------------------------------------------------*/
4580 /*----------------------------*/
4582 /*----------------------------*/
4585 fprintf(outfile,"& (%p) type (",tree);
4586 printTypeChain(tree->ftype,outfile);
4587 fprintf(outfile,")\n");
4588 ast_print(tree->left,outfile,indent+2);
4589 ast_print(tree->right,outfile,indent+2);
4591 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->left,outfile,indent+2);
4595 ast_print(tree->right,outfile,indent+2);
4598 /*----------------------------*/
4600 /*----------------------------*/
4602 fprintf(outfile,"OR (%p) type (",tree);
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->left,outfile,indent+2);
4606 ast_print(tree->right,outfile,indent+2);
4608 /*------------------------------------------------------------------*/
4609 /*----------------------------*/
4611 /*----------------------------*/
4613 fprintf(outfile,"XOR (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+2);
4617 ast_print(tree->right,outfile,indent+2);
4620 /*------------------------------------------------------------------*/
4621 /*----------------------------*/
4623 /*----------------------------*/
4625 fprintf(outfile,"DIV (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+2);
4629 ast_print(tree->right,outfile,indent+2);
4631 /*------------------------------------------------------------------*/
4632 /*----------------------------*/
4634 /*----------------------------*/
4636 fprintf(outfile,"MOD (%p) type (",tree);
4637 printTypeChain(tree->ftype,outfile);
4638 fprintf(outfile,")\n");
4639 ast_print(tree->left,outfile,indent+2);
4640 ast_print(tree->right,outfile,indent+2);
4643 /*------------------------------------------------------------------*/
4644 /*----------------------------*/
4645 /* address dereference */
4646 /*----------------------------*/
4647 case '*': /* can be unary : if right is null then unary operation */
4649 fprintf(outfile,"DEREF (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->left,outfile,indent+2);
4655 /*------------------------------------------------------------------*/
4656 /*----------------------------*/
4657 /* multiplication */
4658 /*----------------------------*/
4659 fprintf(outfile,"MULT (%p) type (",tree);
4660 printTypeChain(tree->ftype,outfile);
4661 fprintf(outfile,")\n");
4662 ast_print(tree->left,outfile,indent+2);
4663 ast_print(tree->right,outfile,indent+2);
4667 /*------------------------------------------------------------------*/
4668 /*----------------------------*/
4669 /* unary '+' operator */
4670 /*----------------------------*/
4674 fprintf(outfile,"UPLUS (%p) type (",tree);
4675 printTypeChain(tree->ftype,outfile);
4676 fprintf(outfile,")\n");
4677 ast_print(tree->left,outfile,indent+2);
4679 /*------------------------------------------------------------------*/
4680 /*----------------------------*/
4682 /*----------------------------*/
4683 fprintf(outfile,"ADD (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+2);
4687 ast_print(tree->right,outfile,indent+2);
4690 /*------------------------------------------------------------------*/
4691 /*----------------------------*/
4693 /*----------------------------*/
4694 case '-': /* can be unary */
4696 fprintf(outfile,"UMINUS (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+2);
4701 /*------------------------------------------------------------------*/
4702 /*----------------------------*/
4704 /*----------------------------*/
4705 fprintf(outfile,"SUB (%p) type (",tree);
4706 printTypeChain(tree->ftype,outfile);
4707 fprintf(outfile,")\n");
4708 ast_print(tree->left,outfile,indent+2);
4709 ast_print(tree->right,outfile,indent+2);
4712 /*------------------------------------------------------------------*/
4713 /*----------------------------*/
4715 /*----------------------------*/
4717 fprintf(outfile,"COMPL (%p) type (",tree);
4718 printTypeChain(tree->ftype,outfile);
4719 fprintf(outfile,")\n");
4720 ast_print(tree->left,outfile,indent+2);
4722 /*------------------------------------------------------------------*/
4723 /*----------------------------*/
4725 /*----------------------------*/
4727 fprintf(outfile,"NOT (%p) type (",tree);
4728 printTypeChain(tree->ftype,outfile);
4729 fprintf(outfile,")\n");
4730 ast_print(tree->left,outfile,indent+2);
4732 /*------------------------------------------------------------------*/
4733 /*----------------------------*/
4735 /*----------------------------*/
4737 fprintf(outfile,"RRC (%p) type (",tree);
4738 printTypeChain(tree->ftype,outfile);
4739 fprintf(outfile,")\n");
4740 ast_print(tree->left,outfile,indent+2);
4744 fprintf(outfile,"RLC (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+2);
4750 fprintf(outfile,"GETHBIT (%p) type (",tree);
4751 printTypeChain(tree->ftype,outfile);
4752 fprintf(outfile,")\n");
4753 ast_print(tree->left,outfile,indent+2);
4756 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4757 printTypeChain(tree->ftype,outfile);
4758 fprintf(outfile,")\n");
4759 ast_print(tree->left,outfile,indent+2);
4760 ast_print(tree->right,outfile,indent+2);
4763 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+2);
4767 ast_print(tree->right,outfile,indent+2);
4769 /*------------------------------------------------------------------*/
4770 /*----------------------------*/
4772 /*----------------------------*/
4773 case CAST: /* change the type */
4774 fprintf(outfile,"CAST (%p) from type (",tree);
4775 printTypeChain(tree->right->ftype,outfile);
4776 fprintf(outfile,") to type (");
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->right,outfile,indent+2);
4783 fprintf(outfile,"ANDAND (%p) type (",tree);
4784 printTypeChain(tree->ftype,outfile);
4785 fprintf(outfile,")\n");
4786 ast_print(tree->left,outfile,indent+2);
4787 ast_print(tree->right,outfile,indent+2);
4790 fprintf(outfile,"OROR (%p) type (",tree);
4791 printTypeChain(tree->ftype,outfile);
4792 fprintf(outfile,")\n");
4793 ast_print(tree->left,outfile,indent+2);
4794 ast_print(tree->right,outfile,indent+2);
4797 /*------------------------------------------------------------------*/
4798 /*----------------------------*/
4799 /* comparison operators */
4800 /*----------------------------*/
4802 fprintf(outfile,"GT(>) (%p) type (",tree);
4803 printTypeChain(tree->ftype,outfile);
4804 fprintf(outfile,")\n");
4805 ast_print(tree->left,outfile,indent+2);
4806 ast_print(tree->right,outfile,indent+2);
4809 fprintf(outfile,"LT(<) (%p) type (",tree);
4810 printTypeChain(tree->ftype,outfile);
4811 fprintf(outfile,")\n");
4812 ast_print(tree->left,outfile,indent+2);
4813 ast_print(tree->right,outfile,indent+2);
4816 fprintf(outfile,"LE(<=) (%p) type (",tree);
4817 printTypeChain(tree->ftype,outfile);
4818 fprintf(outfile,")\n");
4819 ast_print(tree->left,outfile,indent+2);
4820 ast_print(tree->right,outfile,indent+2);
4823 fprintf(outfile,"GE(>=) (%p) type (",tree);
4824 printTypeChain(tree->ftype,outfile);
4825 fprintf(outfile,")\n");
4826 ast_print(tree->left,outfile,indent+2);
4827 ast_print(tree->right,outfile,indent+2);
4830 fprintf(outfile,"EQ(==) (%p) type (",tree);
4831 printTypeChain(tree->ftype,outfile);
4832 fprintf(outfile,")\n");
4833 ast_print(tree->left,outfile,indent+2);
4834 ast_print(tree->right,outfile,indent+2);
4837 fprintf(outfile,"NE(!=) (%p) type (",tree);
4838 printTypeChain(tree->ftype,outfile);
4839 fprintf(outfile,")\n");
4840 ast_print(tree->left,outfile,indent+2);
4841 ast_print(tree->right,outfile,indent+2);
4842 /*------------------------------------------------------------------*/
4843 /*----------------------------*/
4845 /*----------------------------*/
4846 case SIZEOF: /* evaluate wihout code generation */
4847 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4850 /*------------------------------------------------------------------*/
4851 /*----------------------------*/
4852 /* conditional operator '?' */
4853 /*----------------------------*/
4855 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4856 printTypeChain(tree->ftype,outfile);
4857 fprintf(outfile,")\n");
4858 ast_print(tree->left,outfile,indent+2);
4859 ast_print(tree->right,outfile,indent+2);
4863 fprintf(outfile,"COLON(:) (%p) type (",tree);
4864 printTypeChain(tree->ftype,outfile);
4865 fprintf(outfile,")\n");
4866 ast_print(tree->left,outfile,indent+2);
4867 ast_print(tree->right,outfile,indent+2);
4870 /*------------------------------------------------------------------*/
4871 /*----------------------------*/
4872 /* assignment operators */
4873 /*----------------------------*/
4875 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4876 printTypeChain(tree->ftype,outfile);
4877 fprintf(outfile,")\n");
4878 ast_print(tree->left,outfile,indent+2);
4879 ast_print(tree->right,outfile,indent+2);
4882 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4883 printTypeChain(tree->ftype,outfile);
4884 fprintf(outfile,")\n");
4885 ast_print(tree->left,outfile,indent+2);
4886 ast_print(tree->right,outfile,indent+2);
4889 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4890 printTypeChain(tree->ftype,outfile);
4891 fprintf(outfile,")\n");
4892 ast_print(tree->left,outfile,indent+2);
4893 ast_print(tree->right,outfile,indent+2);
4896 fprintf(outfile,"ORASS(*=) (%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,"XORASS(*=) (%p) type (",tree);
4904 printTypeChain(tree->ftype,outfile);
4905 fprintf(outfile,")\n");
4906 ast_print(tree->left,outfile,indent+2);
4907 ast_print(tree->right,outfile,indent+2);
4910 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4911 printTypeChain(tree->ftype,outfile);
4912 fprintf(outfile,")\n");
4913 ast_print(tree->left,outfile,indent+2);
4914 ast_print(tree->right,outfile,indent+2);
4917 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4918 printTypeChain(tree->ftype,outfile);
4919 fprintf(outfile,")\n");
4920 ast_print(tree->left,outfile,indent+2);
4921 ast_print(tree->right,outfile,indent+2);
4923 /*------------------------------------------------------------------*/
4924 /*----------------------------*/
4926 /*----------------------------*/
4928 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4929 printTypeChain(tree->ftype,outfile);
4930 fprintf(outfile,")\n");
4931 ast_print(tree->left,outfile,indent+2);
4932 ast_print(tree->right,outfile,indent+2);
4934 /*------------------------------------------------------------------*/
4935 /*----------------------------*/
4937 /*----------------------------*/
4939 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4940 printTypeChain(tree->ftype,outfile);
4941 fprintf(outfile,")\n");
4942 ast_print(tree->left,outfile,indent+2);
4943 ast_print(tree->right,outfile,indent+2);
4945 /*------------------------------------------------------------------*/
4946 /*----------------------------*/
4947 /* straight assignemnt */
4948 /*----------------------------*/
4950 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4951 printTypeChain(tree->ftype,outfile);
4952 fprintf(outfile,")\n");
4953 ast_print(tree->left,outfile,indent+2);
4954 ast_print(tree->right,outfile,indent+2);
4956 /*------------------------------------------------------------------*/
4957 /*----------------------------*/
4958 /* comma operator */
4959 /*----------------------------*/
4961 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4962 printTypeChain(tree->ftype,outfile);
4963 fprintf(outfile,")\n");
4964 ast_print(tree->left,outfile,indent+2);
4965 ast_print(tree->right,outfile,indent+2);
4967 /*------------------------------------------------------------------*/
4968 /*----------------------------*/
4970 /*----------------------------*/
4973 fprintf(outfile,"CALL (%p) type (",tree);
4974 printTypeChain(tree->ftype,outfile);
4975 fprintf(outfile,")\n");
4976 ast_print(tree->left,outfile,indent+2);
4977 ast_print(tree->right,outfile,indent+2);
4980 fprintf(outfile,"PARMS\n");
4981 ast_print(tree->left,outfile,indent+2);
4982 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4983 ast_print(tree->right,outfile,indent+2);
4986 /*------------------------------------------------------------------*/
4987 /*----------------------------*/
4988 /* return statement */
4989 /*----------------------------*/
4991 fprintf(outfile,"RETURN (%p) type (",tree);
4992 printTypeChain(tree->right->ftype,outfile);
4993 fprintf(outfile,")\n");
4994 ast_print(tree->right,outfile,indent+2);
4996 /*------------------------------------------------------------------*/
4997 /*----------------------------*/
4998 /* label statement */
4999 /*----------------------------*/
5001 fprintf(outfile,"LABEL (%p)\n",tree);
5002 ast_print(tree->left,outfile,indent+2);
5003 ast_print(tree->right,outfile,indent);
5005 /*------------------------------------------------------------------*/
5006 /*----------------------------*/
5007 /* switch statement */
5008 /*----------------------------*/
5012 fprintf(outfile,"SWITCH (%p) ",tree);
5013 ast_print(tree->left,outfile,0);
5014 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5015 INDENT(indent+2,outfile);
5016 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5017 (int) floatFromVal(val),
5018 tree->values.switchVals.swNum,
5019 (int) floatFromVal(val));
5021 ast_print(tree->right,outfile,indent);
5024 /*------------------------------------------------------------------*/
5025 /*----------------------------*/
5027 /*----------------------------*/
5029 fprintf(outfile,"IF (%p) \n",tree);
5030 ast_print(tree->left,outfile,indent+2);
5031 if (tree->trueLabel) {
5032 INDENT(indent,outfile);
5033 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5035 if (tree->falseLabel) {
5036 INDENT(indent,outfile);
5037 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5039 ast_print(tree->right,outfile,indent+2);
5041 /*------------------------------------------------------------------*/
5042 /*----------------------------*/
5044 /*----------------------------*/
5046 fprintf(outfile,"FOR (%p) \n",tree);
5047 if (AST_FOR( tree, initExpr)) {
5048 INDENT(indent+2,outfile);
5049 fprintf(outfile,"INIT EXPR ");
5050 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5052 if (AST_FOR( tree, condExpr)) {
5053 INDENT(indent+2,outfile);
5054 fprintf(outfile,"COND EXPR ");
5055 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5057 if (AST_FOR( tree, loopExpr)) {
5058 INDENT(indent+2,outfile);
5059 fprintf(outfile,"LOOP EXPR ");
5060 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5062 fprintf(outfile,"FOR LOOP BODY \n");
5063 ast_print(tree->left,outfile,indent+2);
5072 ast_print(t,stdout,0);