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 /* insert the symbol into the symbol table */
1128 /* with level = 0 & name = rname */
1129 newSym = copySymbol (sym);
1130 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1132 /* now lift the code to main */
1133 if (IS_AGGREGATE (sym->type)) {
1134 work = initAggregates (sym, sym->ival, NULL);
1136 if (getNelements(sym->type, sym->ival)>1) {
1137 werror (W_EXCESS_INITIALIZERS, "scalar",
1138 sym->name, sym->lineDef);
1140 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1141 list2expr (sym->ival));
1144 setAstLineno (work, sym->lineDef);
1148 staticAutos = newNode (NULLOP, staticAutos, work);
1155 /* if there is an initial value */
1156 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1158 if (IS_AGGREGATE (sym->type)) {
1159 work = initAggregates (sym, sym->ival, NULL);
1161 if (getNelements(sym->type, sym->ival)>1) {
1162 werror (W_EXCESS_INITIALIZERS, "scalar",
1163 sym->name, sym->lineDef);
1165 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1166 list2expr (sym->ival));
1169 setAstLineno (work, sym->lineDef);
1172 init = newNode (NULLOP, init, work);
1181 /*-----------------------------------------------------------------*/
1182 /* stringToSymbol - creates a symbol from a literal string */
1183 /*-----------------------------------------------------------------*/
1185 stringToSymbol (value * val)
1187 char name[SDCC_NAME_MAX + 1];
1188 static int charLbl = 0;
1191 sprintf (name, "_str_%d", charLbl++);
1192 sym = newSymbol (name, 0); /* make it @ level 0 */
1193 strcpy (sym->rname, name);
1195 /* copy the type from the value passed */
1196 sym->type = copyLinkChain (val->type);
1197 sym->etype = getSpec (sym->type);
1198 /* change to storage class & output class */
1199 SPEC_SCLS (sym->etype) = S_CODE;
1200 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1201 SPEC_STAT (sym->etype) = 1;
1202 /* make the level & block = 0 */
1203 sym->block = sym->level = 0;
1205 /* create an ival */
1206 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1211 allocVariables (sym);
1214 return symbolVal (sym);
1218 /*-----------------------------------------------------------------*/
1219 /* processBlockVars - will go thru the ast looking for block if */
1220 /* a block is found then will allocate the syms */
1221 /* will also gather the auto inits present */
1222 /*-----------------------------------------------------------------*/
1224 processBlockVars (ast * tree, int *stack, int action)
1229 /* if this is a block */
1230 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1234 if (action == ALLOCATE)
1236 *stack += allocVariables (tree->values.sym);
1237 autoInit = gatherAutoInit (tree->values.sym);
1239 /* if there are auto inits then do them */
1241 tree->left = newNode (NULLOP, autoInit, tree->left);
1243 else /* action is deallocate */
1244 deallocLocal (tree->values.sym);
1247 processBlockVars (tree->left, stack, action);
1248 processBlockVars (tree->right, stack, action);
1252 /*-----------------------------------------------------------------*/
1253 /* constExprValue - returns the value of a constant expression */
1254 /* or NULL if it is not a constant expression */
1255 /*-----------------------------------------------------------------*/
1257 constExprValue (ast * cexpr, int check)
1259 cexpr = decorateType (resolveSymbols (cexpr));
1261 /* if this is not a constant then */
1262 if (!IS_LITERAL (cexpr->ftype))
1264 /* then check if this is a literal array
1266 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1267 SPEC_CVAL (cexpr->etype).v_char &&
1268 IS_ARRAY (cexpr->ftype))
1270 value *val = valFromType (cexpr->ftype);
1271 SPEC_SCLS (val->etype) = S_LITERAL;
1272 val->sym = cexpr->opval.val->sym;
1273 val->sym->type = copyLinkChain (cexpr->ftype);
1274 val->sym->etype = getSpec (val->sym->type);
1275 strcpy (val->name, cexpr->opval.val->sym->rname);
1279 /* if we are casting a literal value then */
1280 if (IS_AST_OP (cexpr) &&
1281 cexpr->opval.op == CAST &&
1282 IS_LITERAL (cexpr->left->ftype))
1283 return valCastLiteral (cexpr->ftype,
1284 floatFromVal (cexpr->left->opval.val));
1286 if (IS_AST_VALUE (cexpr))
1287 return cexpr->opval.val;
1290 werror (E_CONST_EXPECTED, "found expression");
1295 /* return the value */
1296 return cexpr->opval.val;
1300 /*-----------------------------------------------------------------*/
1301 /* isLabelInAst - will return true if a given label is found */
1302 /*-----------------------------------------------------------------*/
1304 isLabelInAst (symbol * label, ast * tree)
1306 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1309 if (IS_AST_OP (tree) &&
1310 tree->opval.op == LABEL &&
1311 isSymbolEqual (AST_SYMBOL (tree->left), label))
1314 return isLabelInAst (label, tree->right) &&
1315 isLabelInAst (label, tree->left);
1319 /*-----------------------------------------------------------------*/
1320 /* isLoopCountable - return true if the loop count can be determi- */
1321 /* -ned at compile time . */
1322 /*-----------------------------------------------------------------*/
1324 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1325 symbol ** sym, ast ** init, ast ** end)
1328 /* the loop is considered countable if the following
1329 conditions are true :-
1331 a) initExpr :- <sym> = <const>
1332 b) condExpr :- <sym> < <const1>
1333 c) loopExpr :- <sym> ++
1336 /* first check the initExpr */
1337 if (IS_AST_OP (initExpr) &&
1338 initExpr->opval.op == '=' && /* is assignment */
1339 IS_AST_SYM_VALUE (initExpr->left))
1340 { /* left is a symbol */
1342 *sym = AST_SYMBOL (initExpr->left);
1343 *init = initExpr->right;
1348 /* for now the symbol has to be of
1350 if (!IS_INTEGRAL ((*sym)->type))
1353 /* now check condExpr */
1354 if (IS_AST_OP (condExpr))
1357 switch (condExpr->opval.op)
1360 if (IS_AST_SYM_VALUE (condExpr->left) &&
1361 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1362 IS_AST_LIT_VALUE (condExpr->right))
1364 *end = condExpr->right;
1370 if (IS_AST_OP (condExpr->left) &&
1371 condExpr->left->opval.op == '>' &&
1372 IS_AST_LIT_VALUE (condExpr->left->right) &&
1373 IS_AST_SYM_VALUE (condExpr->left->left) &&
1374 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1377 *end = newNode ('+', condExpr->left->right,
1378 newAst_VALUE (constVal ("1")));
1389 /* check loop expression is of the form <sym>++ */
1390 if (!IS_AST_OP (loopExpr))
1393 /* check if <sym> ++ */
1394 if (loopExpr->opval.op == INC_OP)
1400 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1401 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1408 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1409 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1417 if (loopExpr->opval.op == ADD_ASSIGN)
1420 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1421 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1422 IS_AST_LIT_VALUE (loopExpr->right) &&
1423 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1431 /*-----------------------------------------------------------------*/
1432 /* astHasVolatile - returns true if ast contains any volatile */
1433 /*-----------------------------------------------------------------*/
1435 astHasVolatile (ast * tree)
1440 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1443 if (IS_AST_OP (tree))
1444 return astHasVolatile (tree->left) ||
1445 astHasVolatile (tree->right);
1450 /*-----------------------------------------------------------------*/
1451 /* astHasPointer - return true if the ast contains any ptr variable */
1452 /*-----------------------------------------------------------------*/
1454 astHasPointer (ast * tree)
1459 if (IS_AST_LINK (tree))
1462 /* if we hit an array expression then check
1463 only the left side */
1464 if (IS_AST_OP (tree) && tree->opval.op == '[')
1465 return astHasPointer (tree->left);
1467 if (IS_AST_VALUE (tree))
1468 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1470 return astHasPointer (tree->left) ||
1471 astHasPointer (tree->right);
1475 /*-----------------------------------------------------------------*/
1476 /* astHasSymbol - return true if the ast has the given symbol */
1477 /*-----------------------------------------------------------------*/
1479 astHasSymbol (ast * tree, symbol * sym)
1481 if (!tree || IS_AST_LINK (tree))
1484 if (IS_AST_VALUE (tree))
1486 if (IS_AST_SYM_VALUE (tree))
1487 return isSymbolEqual (AST_SYMBOL (tree), sym);
1492 return astHasSymbol (tree->left, sym) ||
1493 astHasSymbol (tree->right, sym);
1496 /*-----------------------------------------------------------------*/
1497 /* astHasDeref - return true if the ast has an indirect access */
1498 /*-----------------------------------------------------------------*/
1500 astHasDeref (ast * tree)
1502 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1505 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1507 return astHasDeref (tree->left) || astHasDeref (tree->right);
1510 /*-----------------------------------------------------------------*/
1511 /* isConformingBody - the loop body has to conform to a set of rules */
1512 /* for the loop to be considered reversible read on for rules */
1513 /*-----------------------------------------------------------------*/
1515 isConformingBody (ast * pbody, symbol * sym, ast * body)
1518 /* we are going to do a pre-order traversal of the
1519 tree && check for the following conditions. (essentially
1520 a set of very shallow tests )
1521 a) the sym passed does not participate in
1522 any arithmetic operation
1523 b) There are no function calls
1524 c) all jumps are within the body
1525 d) address of loop control variable not taken
1526 e) if an assignment has a pointer on the
1527 left hand side make sure right does not have
1528 loop control variable */
1530 /* if we reach the end or a leaf then true */
1531 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1535 /* if anything else is "volatile" */
1536 if (IS_VOLATILE (TETYPE (pbody)))
1539 /* we will walk the body in a pre-order traversal for
1541 switch (pbody->opval.op)
1543 /*------------------------------------------------------------------*/
1545 return isConformingBody (pbody->right, sym, body);
1547 /*------------------------------------------------------------------*/
1552 /*------------------------------------------------------------------*/
1553 case INC_OP: /* incerement operator unary so left only */
1556 /* sure we are not sym is not modified */
1558 IS_AST_SYM_VALUE (pbody->left) &&
1559 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1563 IS_AST_SYM_VALUE (pbody->right) &&
1564 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1569 /*------------------------------------------------------------------*/
1571 case '*': /* can be unary : if right is null then unary operation */
1576 /* if right is NULL then unary operation */
1577 /*------------------------------------------------------------------*/
1578 /*----------------------------*/
1580 /*----------------------------*/
1583 if (IS_AST_SYM_VALUE (pbody->left) &&
1584 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1587 return isConformingBody (pbody->left, sym, body);
1591 if (astHasSymbol (pbody->left, sym) ||
1592 astHasSymbol (pbody->right, sym))
1597 /*------------------------------------------------------------------*/
1605 if (IS_AST_SYM_VALUE (pbody->left) &&
1606 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1609 if (IS_AST_SYM_VALUE (pbody->right) &&
1610 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1613 return isConformingBody (pbody->left, sym, body) &&
1614 isConformingBody (pbody->right, sym, body);
1621 if (IS_AST_SYM_VALUE (pbody->left) &&
1622 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1624 return isConformingBody (pbody->left, sym, body);
1626 /*------------------------------------------------------------------*/
1638 case SIZEOF: /* evaluate wihout code generation */
1640 return isConformingBody (pbody->left, sym, body) &&
1641 isConformingBody (pbody->right, sym, body);
1643 /*------------------------------------------------------------------*/
1646 /* if left has a pointer & right has loop
1647 control variable then we cannot */
1648 if (astHasPointer (pbody->left) &&
1649 astHasSymbol (pbody->right, sym))
1651 if (astHasVolatile (pbody->left))
1654 if (IS_AST_SYM_VALUE (pbody->left) &&
1655 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1658 if (astHasVolatile (pbody->left))
1661 if (astHasDeref(pbody->right)) return FALSE;
1663 return isConformingBody (pbody->left, sym, body) &&
1664 isConformingBody (pbody->right, sym, body);
1675 assert ("Parser should not have generated this\n");
1677 /*------------------------------------------------------------------*/
1678 /*----------------------------*/
1679 /* comma operator */
1680 /*----------------------------*/
1682 return isConformingBody (pbody->left, sym, body) &&
1683 isConformingBody (pbody->right, sym, body);
1685 /*------------------------------------------------------------------*/
1686 /*----------------------------*/
1688 /*----------------------------*/
1692 /*------------------------------------------------------------------*/
1693 /*----------------------------*/
1694 /* return statement */
1695 /*----------------------------*/
1700 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1705 if (astHasSymbol (pbody->left, sym))
1712 return isConformingBody (pbody->left, sym, body) &&
1713 isConformingBody (pbody->right, sym, body);
1719 /*-----------------------------------------------------------------*/
1720 /* isLoopReversible - takes a for loop as input && returns true */
1721 /* if the for loop is reversible. If yes will set the value of */
1722 /* the loop control var & init value & termination value */
1723 /*-----------------------------------------------------------------*/
1725 isLoopReversible (ast * loop, symbol ** loopCntrl,
1726 ast ** init, ast ** end)
1728 /* if option says don't do it then don't */
1729 if (optimize.noLoopReverse)
1731 /* there are several tests to determine this */
1733 /* for loop has to be of the form
1734 for ( <sym> = <const1> ;
1735 [<sym> < <const2>] ;
1736 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1738 if (!isLoopCountable (AST_FOR (loop, initExpr),
1739 AST_FOR (loop, condExpr),
1740 AST_FOR (loop, loopExpr),
1741 loopCntrl, init, end))
1744 /* now do some serious checking on the body of the loop
1747 return isConformingBody (loop->left, *loopCntrl, loop->left);
1751 /*-----------------------------------------------------------------*/
1752 /* replLoopSym - replace the loop sym by loop sym -1 */
1753 /*-----------------------------------------------------------------*/
1755 replLoopSym (ast * body, symbol * sym)
1758 if (!body || IS_AST_LINK (body))
1761 if (IS_AST_SYM_VALUE (body))
1764 if (isSymbolEqual (AST_SYMBOL (body), sym))
1768 body->opval.op = '-';
1769 body->left = newAst_VALUE (symbolVal (sym));
1770 body->right = newAst_VALUE (constVal ("1"));
1778 replLoopSym (body->left, sym);
1779 replLoopSym (body->right, sym);
1783 /*-----------------------------------------------------------------*/
1784 /* reverseLoop - do the actual loop reversal */
1785 /*-----------------------------------------------------------------*/
1787 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1791 /* create the following tree
1796 if (sym) goto for_continue ;
1799 /* put it together piece by piece */
1800 rloop = newNode (NULLOP,
1801 createIf (newAst_VALUE (symbolVal (sym)),
1803 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1806 newAst_VALUE (symbolVal (sym)),
1809 replLoopSym (loop->left, sym);
1811 rloop = newNode (NULLOP,
1813 newAst_VALUE (symbolVal (sym)),
1814 newNode ('-', end, init)),
1815 createLabel (AST_FOR (loop, continueLabel),
1819 newNode (SUB_ASSIGN,
1820 newAst_VALUE (symbolVal (sym)),
1821 newAst_VALUE (constVal ("1"))),
1824 return decorateType (rloop);
1828 /*-----------------------------------------------------------------*/
1829 /* decorateType - compute type for this tree also does type cheking */
1830 /* this is done bottom up, since type have to flow upwards */
1831 /* it also does constant folding, and paramater checking */
1832 /*-----------------------------------------------------------------*/
1834 decorateType (ast * tree)
1842 /* if already has type then do nothing */
1843 if (tree->decorated)
1846 tree->decorated = 1;
1848 /* print the line */
1849 /* if not block & function */
1850 if (tree->type == EX_OP &&
1851 (tree->opval.op != FUNCTION &&
1852 tree->opval.op != BLOCK &&
1853 tree->opval.op != NULLOP))
1855 filename = tree->filename;
1856 lineno = tree->lineno;
1859 /* if any child is an error | this one is an error do nothing */
1860 if (tree->isError ||
1861 (tree->left && tree->left->isError) ||
1862 (tree->right && tree->right->isError))
1865 /*------------------------------------------------------------------*/
1866 /*----------------------------*/
1867 /* leaf has been reached */
1868 /*----------------------------*/
1869 /* if this is of type value */
1870 /* just get the type */
1871 if (tree->type == EX_VALUE)
1874 if (IS_LITERAL (tree->opval.val->etype))
1877 /* if this is a character array then declare it */
1878 if (IS_ARRAY (tree->opval.val->type))
1879 tree->opval.val = stringToSymbol (tree->opval.val);
1881 /* otherwise just copy the type information */
1882 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1886 if (tree->opval.val->sym)
1888 /* if the undefined flag is set then give error message */
1889 if (tree->opval.val->sym->undefined)
1891 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1893 TTYPE (tree) = TETYPE (tree) =
1894 tree->opval.val->type = tree->opval.val->sym->type =
1895 tree->opval.val->etype = tree->opval.val->sym->etype =
1896 copyLinkChain (INTTYPE);
1901 /* if impilicit i.e. struct/union member then no type */
1902 if (tree->opval.val->sym->implicit)
1903 TTYPE (tree) = TETYPE (tree) = NULL;
1908 /* else copy the type */
1909 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1911 /* and mark it as referenced */
1912 tree->opval.val->sym->isref = 1;
1920 /* if type link for the case of cast */
1921 if (tree->type == EX_LINK)
1923 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1930 dtl = decorateType (tree->left);
1931 /* delay right side for '?' operator since conditional macro expansions might
1933 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1935 /* this is to take care of situations
1936 when the tree gets rewritten */
1937 if (dtl != tree->left)
1939 if (dtr != tree->right)
1943 /* depending on type of operator do */
1945 switch (tree->opval.op)
1947 /*------------------------------------------------------------------*/
1948 /*----------------------------*/
1950 /*----------------------------*/
1953 /* determine which is the array & which the index */
1954 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1957 ast *tempTree = tree->left;
1958 tree->left = tree->right;
1959 tree->right = tempTree;
1962 /* first check if this is a array or a pointer */
1963 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1965 werror (E_NEED_ARRAY_PTR, "[]");
1966 goto errorTreeReturn;
1969 /* check if the type of the idx */
1970 if (!IS_INTEGRAL (RTYPE (tree)))
1972 werror (E_IDX_NOT_INT);
1973 goto errorTreeReturn;
1976 /* if the left is an rvalue then error */
1979 werror (E_LVALUE_REQUIRED, "array access");
1980 goto errorTreeReturn;
1983 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1984 if (IS_PTR(LTYPE(tree))) {
1985 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1989 /*------------------------------------------------------------------*/
1990 /*----------------------------*/
1992 /*----------------------------*/
1994 /* if this is not a structure */
1995 if (!IS_STRUCT (LTYPE (tree)))
1997 werror (E_STRUCT_UNION, ".");
1998 goto errorTreeReturn;
2000 TTYPE (tree) = structElemType (LTYPE (tree),
2001 (tree->right->type == EX_VALUE ?
2002 tree->right->opval.val : NULL));
2003 TETYPE (tree) = getSpec (TTYPE (tree));
2006 /*------------------------------------------------------------------*/
2007 /*----------------------------*/
2008 /* struct/union pointer */
2009 /*----------------------------*/
2011 /* if not pointer to a structure */
2012 if (!IS_PTR (LTYPE (tree)))
2014 werror (E_PTR_REQD);
2015 goto errorTreeReturn;
2018 if (!IS_STRUCT (LTYPE (tree)->next))
2020 werror (E_STRUCT_UNION, "->");
2021 goto errorTreeReturn;
2024 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2025 (tree->right->type == EX_VALUE ?
2026 tree->right->opval.val : NULL));
2027 TETYPE (tree) = getSpec (TTYPE (tree));
2030 /*------------------------------------------------------------------*/
2031 /*----------------------------*/
2032 /* ++/-- operation */
2033 /*----------------------------*/
2034 case INC_OP: /* incerement operator unary so left only */
2037 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2038 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2039 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2040 werror (E_CODE_WRITE, "++/--");
2049 /*------------------------------------------------------------------*/
2050 /*----------------------------*/
2052 /*----------------------------*/
2053 case '&': /* can be unary */
2054 /* if right is NULL then unary operation */
2055 if (tree->right) /* not an unary operation */
2058 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2060 werror (E_BITWISE_OP);
2061 werror (W_CONTINUE, "left & right types are ");
2062 printTypeChain (LTYPE (tree), stderr);
2063 fprintf (stderr, ",");
2064 printTypeChain (RTYPE (tree), stderr);
2065 fprintf (stderr, "\n");
2066 goto errorTreeReturn;
2069 /* if they are both literal */
2070 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2072 tree->type = EX_VALUE;
2073 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2074 valFromType (RETYPE (tree)), '&');
2076 tree->right = tree->left = NULL;
2077 TETYPE (tree) = tree->opval.val->etype;
2078 TTYPE (tree) = tree->opval.val->type;
2082 /* see if this is a GETHBIT operation if yes
2085 ast *otree = optimizeGetHbit (tree);
2088 return decorateType (otree);
2092 computeType (LTYPE (tree), RTYPE (tree));
2093 TETYPE (tree) = getSpec (TTYPE (tree));
2095 LRVAL (tree) = RRVAL (tree) = 1;
2099 /*------------------------------------------------------------------*/
2100 /*----------------------------*/
2102 /*----------------------------*/
2104 p->class = DECLARATOR;
2105 /* if bit field then error */
2106 if (IS_BITVAR (tree->left->etype))
2108 werror (E_ILLEGAL_ADDR, "address of bit variable");
2109 goto errorTreeReturn;
2112 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2114 werror (E_ILLEGAL_ADDR, "address of register variable");
2115 goto errorTreeReturn;
2118 if (IS_FUNC (LTYPE (tree)))
2120 werror (E_ILLEGAL_ADDR, "address of function");
2121 goto errorTreeReturn;
2124 if (IS_LITERAL(LTYPE(tree)))
2126 werror (E_ILLEGAL_ADDR, "address of literal");
2127 goto errorTreeReturn;
2132 werror (E_LVALUE_REQUIRED, "address of");
2133 goto errorTreeReturn;
2135 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2137 DCL_TYPE (p) = CPOINTER;
2138 DCL_PTR_CONST (p) = port->mem.code_ro;
2140 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2141 DCL_TYPE (p) = FPOINTER;
2142 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2143 DCL_TYPE (p) = PPOINTER;
2144 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2145 DCL_TYPE (p) = IPOINTER;
2146 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2147 DCL_TYPE (p) = EEPPOINTER;
2148 else if (SPEC_OCLS(tree->left->etype))
2149 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2151 DCL_TYPE (p) = POINTER;
2153 if (IS_AST_SYM_VALUE (tree->left))
2155 AST_SYMBOL (tree->left)->addrtaken = 1;
2156 AST_SYMBOL (tree->left)->allocreq = 1;
2159 p->next = LTYPE (tree);
2161 TETYPE (tree) = getSpec (TTYPE (tree));
2162 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2163 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2168 /*------------------------------------------------------------------*/
2169 /*----------------------------*/
2171 /*----------------------------*/
2173 /* if the rewrite succeeds then don't go any furthur */
2175 ast *wtree = optimizeRRCRLC (tree);
2177 return decorateType (wtree);
2179 /*------------------------------------------------------------------*/
2180 /*----------------------------*/
2182 /*----------------------------*/
2184 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2186 werror (E_BITWISE_OP);
2187 werror (W_CONTINUE, "left & right types are ");
2188 printTypeChain (LTYPE (tree), stderr);
2189 fprintf (stderr, ",");
2190 printTypeChain (RTYPE (tree), stderr);
2191 fprintf (stderr, "\n");
2192 goto errorTreeReturn;
2195 /* if they are both literal then */
2196 /* rewrite the tree */
2197 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2199 tree->type = EX_VALUE;
2200 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2201 valFromType (RETYPE (tree)),
2203 tree->right = tree->left = NULL;
2204 TETYPE (tree) = tree->opval.val->etype;
2205 TTYPE (tree) = tree->opval.val->type;
2208 LRVAL (tree) = RRVAL (tree) = 1;
2209 TETYPE (tree) = getSpec (TTYPE (tree) =
2210 computeType (LTYPE (tree),
2213 /*------------------------------------------------------------------*/
2214 /*----------------------------*/
2216 /*----------------------------*/
2218 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2220 werror (E_INVALID_OP, "divide");
2221 goto errorTreeReturn;
2223 /* if they are both literal then */
2224 /* rewrite the tree */
2225 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2227 tree->type = EX_VALUE;
2228 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2229 valFromType (RETYPE (tree)));
2230 tree->right = tree->left = NULL;
2231 TETYPE (tree) = getSpec (TTYPE (tree) =
2232 tree->opval.val->type);
2235 LRVAL (tree) = RRVAL (tree) = 1;
2236 TETYPE (tree) = getSpec (TTYPE (tree) =
2237 computeType (LTYPE (tree),
2241 /*------------------------------------------------------------------*/
2242 /*----------------------------*/
2244 /*----------------------------*/
2246 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2248 werror (E_BITWISE_OP);
2249 werror (W_CONTINUE, "left & right types are ");
2250 printTypeChain (LTYPE (tree), stderr);
2251 fprintf (stderr, ",");
2252 printTypeChain (RTYPE (tree), stderr);
2253 fprintf (stderr, "\n");
2254 goto errorTreeReturn;
2256 /* if they are both literal then */
2257 /* rewrite the tree */
2258 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2260 tree->type = EX_VALUE;
2261 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2262 valFromType (RETYPE (tree)));
2263 tree->right = tree->left = NULL;
2264 TETYPE (tree) = getSpec (TTYPE (tree) =
2265 tree->opval.val->type);
2268 LRVAL (tree) = RRVAL (tree) = 1;
2269 TETYPE (tree) = getSpec (TTYPE (tree) =
2270 computeType (LTYPE (tree),
2274 /*------------------------------------------------------------------*/
2275 /*----------------------------*/
2276 /* address dereference */
2277 /*----------------------------*/
2278 case '*': /* can be unary : if right is null then unary operation */
2281 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2283 werror (E_PTR_REQD);
2284 goto errorTreeReturn;
2289 werror (E_LVALUE_REQUIRED, "pointer deref");
2290 goto errorTreeReturn;
2292 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2293 LTYPE (tree)->next : NULL);
2294 TETYPE (tree) = getSpec (TTYPE (tree));
2295 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2299 /*------------------------------------------------------------------*/
2300 /*----------------------------*/
2301 /* multiplication */
2302 /*----------------------------*/
2303 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2305 werror (E_INVALID_OP, "multiplication");
2306 goto errorTreeReturn;
2309 /* if they are both literal then */
2310 /* rewrite the tree */
2311 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2313 tree->type = EX_VALUE;
2314 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2315 valFromType (RETYPE (tree)));
2316 tree->right = tree->left = NULL;
2317 TETYPE (tree) = getSpec (TTYPE (tree) =
2318 tree->opval.val->type);
2322 /* if left is a literal exchange left & right */
2323 if (IS_LITERAL (LTYPE (tree)))
2325 ast *tTree = tree->left;
2326 tree->left = tree->right;
2327 tree->right = tTree;
2330 LRVAL (tree) = RRVAL (tree) = 1;
2331 /* promote result to int if left & right are char
2332 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2333 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2334 TETYPE (tree) = getSpec (TTYPE (tree) =
2335 computeType (LTYPE (tree),
2337 SPEC_NOUN(TETYPE(tree)) = V_INT;
2339 TETYPE (tree) = getSpec (TTYPE (tree) =
2340 computeType (LTYPE (tree),
2345 /*------------------------------------------------------------------*/
2346 /*----------------------------*/
2347 /* unary '+' operator */
2348 /*----------------------------*/
2353 if (!IS_INTEGRAL (LTYPE (tree)))
2355 werror (E_UNARY_OP, '+');
2356 goto errorTreeReturn;
2359 /* if left is a literal then do it */
2360 if (IS_LITERAL (LTYPE (tree)))
2362 tree->type = EX_VALUE;
2363 tree->opval.val = valFromType (LETYPE (tree));
2365 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2369 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2373 /*------------------------------------------------------------------*/
2374 /*----------------------------*/
2376 /*----------------------------*/
2378 /* this is not a unary operation */
2379 /* if both pointers then problem */
2380 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2381 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2383 werror (E_PTR_PLUS_PTR);
2384 goto errorTreeReturn;
2387 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2388 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2390 werror (E_PLUS_INVALID, "+");
2391 goto errorTreeReturn;
2394 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2395 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2397 werror (E_PLUS_INVALID, "+");
2398 goto errorTreeReturn;
2400 /* if they are both literal then */
2401 /* rewrite the tree */
2402 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2404 tree->type = EX_VALUE;
2405 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2406 valFromType (RETYPE (tree)));
2407 tree->right = tree->left = NULL;
2408 TETYPE (tree) = getSpec (TTYPE (tree) =
2409 tree->opval.val->type);
2413 /* if the right is a pointer or left is a literal
2414 xchange left & right */
2415 if (IS_ARRAY (RTYPE (tree)) ||
2416 IS_PTR (RTYPE (tree)) ||
2417 IS_LITERAL (LTYPE (tree)))
2419 ast *tTree = tree->left;
2420 tree->left = tree->right;
2421 tree->right = tTree;
2424 LRVAL (tree) = RRVAL (tree) = 1;
2425 /* if the left is a pointer */
2426 if (IS_PTR (LTYPE (tree)))
2427 TETYPE (tree) = getSpec (TTYPE (tree) =
2430 TETYPE (tree) = getSpec (TTYPE (tree) =
2431 computeType (LTYPE (tree),
2435 /*------------------------------------------------------------------*/
2436 /*----------------------------*/
2438 /*----------------------------*/
2439 case '-': /* can be unary */
2440 /* if right is null then unary */
2444 if (!IS_ARITHMETIC (LTYPE (tree)))
2446 werror (E_UNARY_OP, tree->opval.op);
2447 goto errorTreeReturn;
2450 /* if left is a literal then do it */
2451 if (IS_LITERAL (LTYPE (tree)))
2453 tree->type = EX_VALUE;
2454 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2456 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2457 SPEC_USIGN(TETYPE(tree)) = 0;
2461 TTYPE (tree) = LTYPE (tree);
2465 /*------------------------------------------------------------------*/
2466 /*----------------------------*/
2468 /*----------------------------*/
2470 if (!(IS_PTR (LTYPE (tree)) ||
2471 IS_ARRAY (LTYPE (tree)) ||
2472 IS_ARITHMETIC (LTYPE (tree))))
2474 werror (E_PLUS_INVALID, "-");
2475 goto errorTreeReturn;
2478 if (!(IS_PTR (RTYPE (tree)) ||
2479 IS_ARRAY (RTYPE (tree)) ||
2480 IS_ARITHMETIC (RTYPE (tree))))
2482 werror (E_PLUS_INVALID, "-");
2483 goto errorTreeReturn;
2486 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2487 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2488 IS_INTEGRAL (RTYPE (tree))))
2490 werror (E_PLUS_INVALID, "-");
2491 goto errorTreeReturn;
2494 /* if they are both literal then */
2495 /* rewrite the tree */
2496 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2498 tree->type = EX_VALUE;
2499 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2500 valFromType (RETYPE (tree)));
2501 tree->right = tree->left = NULL;
2502 TETYPE (tree) = getSpec (TTYPE (tree) =
2503 tree->opval.val->type);
2507 /* if the left & right are equal then zero */
2508 if (isAstEqual (tree->left, tree->right))
2510 tree->type = EX_VALUE;
2511 tree->left = tree->right = NULL;
2512 tree->opval.val = constVal ("0");
2513 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2517 /* if both of them are pointers or arrays then */
2518 /* the result is going to be an integer */
2519 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2520 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2521 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2523 /* if only the left is a pointer */
2524 /* then result is a pointer */
2525 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2526 TETYPE (tree) = getSpec (TTYPE (tree) =
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 computeType (LTYPE (tree),
2532 LRVAL (tree) = RRVAL (tree) = 1;
2535 /*------------------------------------------------------------------*/
2536 /*----------------------------*/
2538 /*----------------------------*/
2540 /* can be only integral type */
2541 if (!IS_INTEGRAL (LTYPE (tree)))
2543 werror (E_UNARY_OP, tree->opval.op);
2544 goto errorTreeReturn;
2547 /* if left is a literal then do it */
2548 if (IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2553 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2557 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2560 /*------------------------------------------------------------------*/
2561 /*----------------------------*/
2563 /*----------------------------*/
2565 /* can be pointer */
2566 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2567 !IS_PTR (LTYPE (tree)) &&
2568 !IS_ARRAY (LTYPE (tree)))
2570 werror (E_UNARY_OP, tree->opval.op);
2571 goto errorTreeReturn;
2574 /* if left is a literal then do it */
2575 if (IS_LITERAL (LTYPE (tree)))
2577 tree->type = EX_VALUE;
2578 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2580 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2584 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2587 /*------------------------------------------------------------------*/
2588 /*----------------------------*/
2590 /*----------------------------*/
2593 TTYPE (tree) = LTYPE (tree);
2594 TETYPE (tree) = LETYPE (tree);
2598 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2603 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2605 werror (E_SHIFT_OP_INVALID);
2606 werror (W_CONTINUE, "left & right types are ");
2607 printTypeChain (LTYPE (tree), stderr);
2608 fprintf (stderr, ",");
2609 printTypeChain (RTYPE (tree), stderr);
2610 fprintf (stderr, "\n");
2611 goto errorTreeReturn;
2614 /* if they are both literal then */
2615 /* rewrite the tree */
2616 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2618 tree->type = EX_VALUE;
2619 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2620 valFromType (RETYPE (tree)),
2621 (tree->opval.op == LEFT_OP ? 1 : 0));
2622 tree->right = tree->left = NULL;
2623 TETYPE (tree) = getSpec (TTYPE (tree) =
2624 tree->opval.val->type);
2627 /* if only the right side is a literal & we are
2628 shifting more than size of the left operand then zero */
2629 if (IS_LITERAL (RTYPE (tree)) &&
2630 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2631 (getSize (LTYPE (tree)) * 8))
2633 werror (W_SHIFT_CHANGED,
2634 (tree->opval.op == LEFT_OP ? "left" : "right"));
2635 tree->type = EX_VALUE;
2636 tree->left = tree->right = NULL;
2637 tree->opval.val = constVal ("0");
2638 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2641 LRVAL (tree) = RRVAL (tree) = 1;
2642 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2644 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2648 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2652 /*------------------------------------------------------------------*/
2653 /*----------------------------*/
2655 /*----------------------------*/
2656 case CAST: /* change the type */
2657 /* cannot cast to an aggregate type */
2658 if (IS_AGGREGATE (LTYPE (tree)))
2660 werror (E_CAST_ILLEGAL);
2661 goto errorTreeReturn;
2664 /* make sure the type is complete and sane */
2665 checkTypeSanity(LETYPE(tree), "(cast)");
2668 /* if the right is a literal replace the tree */
2669 if (IS_LITERAL (RETYPE (tree))) {
2670 if (!IS_PTR (LTYPE (tree))) {
2671 tree->type = EX_VALUE;
2673 valCastLiteral (LTYPE (tree),
2674 floatFromVal (valFromType (RETYPE (tree))));
2677 TTYPE (tree) = tree->opval.val->type;
2678 tree->values.literalFromCast = 1;
2679 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2680 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2681 sym_link *rest = LTYPE(tree)->next;
2682 werror(W_LITERAL_GENERIC);
2683 TTYPE(tree) = newLink();
2684 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2685 TTYPE(tree)->next = rest;
2686 tree->left->opval.lnk = TTYPE(tree);
2689 TTYPE (tree) = LTYPE (tree);
2693 TTYPE (tree) = LTYPE (tree);
2697 /* if pointer to struct then check names */
2698 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2699 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2700 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2701 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2703 /* if the right is a literal replace the tree */
2704 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2705 tree->type = EX_VALUE;
2707 valCastLiteral (LTYPE (tree),
2708 floatFromVal (valFromType (RETYPE (tree))));
2711 TTYPE (tree) = tree->opval.val->type;
2712 tree->values.literalFromCast = 1;
2714 TTYPE (tree) = LTYPE (tree);
2718 TETYPE (tree) = getSpec (TTYPE (tree));
2722 /*------------------------------------------------------------------*/
2723 /*----------------------------*/
2724 /* logical &&, || */
2725 /*----------------------------*/
2728 /* each must me arithmetic type or be a pointer */
2729 if (!IS_PTR (LTYPE (tree)) &&
2730 !IS_ARRAY (LTYPE (tree)) &&
2731 !IS_INTEGRAL (LTYPE (tree)))
2733 werror (E_COMPARE_OP);
2734 goto errorTreeReturn;
2737 if (!IS_PTR (RTYPE (tree)) &&
2738 !IS_ARRAY (RTYPE (tree)) &&
2739 !IS_INTEGRAL (RTYPE (tree)))
2741 werror (E_COMPARE_OP);
2742 goto errorTreeReturn;
2744 /* if they are both literal then */
2745 /* rewrite the tree */
2746 if (IS_LITERAL (RTYPE (tree)) &&
2747 IS_LITERAL (LTYPE (tree)))
2749 tree->type = EX_VALUE;
2750 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2751 valFromType (RETYPE (tree)),
2753 tree->right = tree->left = NULL;
2754 TETYPE (tree) = getSpec (TTYPE (tree) =
2755 tree->opval.val->type);
2758 LRVAL (tree) = RRVAL (tree) = 1;
2759 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2762 /*------------------------------------------------------------------*/
2763 /*----------------------------*/
2764 /* comparison operators */
2765 /*----------------------------*/
2773 ast *lt = optimizeCompare (tree);
2779 /* if they are pointers they must be castable */
2780 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2782 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2784 werror (E_COMPARE_OP);
2785 fprintf (stderr, "comparing type ");
2786 printTypeChain (LTYPE (tree), stderr);
2787 fprintf (stderr, "to type ");
2788 printTypeChain (RTYPE (tree), stderr);
2789 fprintf (stderr, "\n");
2790 goto errorTreeReturn;
2793 /* else they should be promotable to one another */
2796 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2797 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2799 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2801 werror (E_COMPARE_OP);
2802 fprintf (stderr, "comparing type ");
2803 printTypeChain (LTYPE (tree), stderr);
2804 fprintf (stderr, "to type ");
2805 printTypeChain (RTYPE (tree), stderr);
2806 fprintf (stderr, "\n");
2807 goto errorTreeReturn;
2811 /* if they are both literal then */
2812 /* rewrite the tree */
2813 if (IS_LITERAL (RTYPE (tree)) &&
2814 IS_LITERAL (LTYPE (tree)))
2816 tree->type = EX_VALUE;
2817 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2818 valFromType (RETYPE (tree)),
2820 tree->right = tree->left = NULL;
2821 TETYPE (tree) = getSpec (TTYPE (tree) =
2822 tree->opval.val->type);
2825 LRVAL (tree) = RRVAL (tree) = 1;
2826 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2829 /*------------------------------------------------------------------*/
2830 /*----------------------------*/
2832 /*----------------------------*/
2833 case SIZEOF: /* evaluate wihout code generation */
2834 /* change the type to a integer */
2835 tree->type = EX_VALUE;
2836 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2837 tree->opval.val = constVal (buffer);
2838 tree->right = tree->left = NULL;
2839 TETYPE (tree) = getSpec (TTYPE (tree) =
2840 tree->opval.val->type);
2843 /*------------------------------------------------------------------*/
2844 /*----------------------------*/
2846 /*----------------------------*/
2848 /* return typeof enum value */
2849 tree->type = EX_VALUE;
2852 if (IS_SPEC(tree->right->ftype)) {
2853 switch (SPEC_NOUN(tree->right->ftype)) {
2855 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2856 else typeofv = TYPEOF_INT;
2859 typeofv = TYPEOF_FLOAT;
2862 typeofv = TYPEOF_CHAR;
2865 typeofv = TYPEOF_VOID;
2868 typeofv = TYPEOF_STRUCT;
2871 typeofv = TYPEOF_BIT;
2874 typeofv = TYPEOF_SBIT;
2880 switch (DCL_TYPE(tree->right->ftype)) {
2882 typeofv = TYPEOF_POINTER;
2885 typeofv = TYPEOF_FPOINTER;
2888 typeofv = TYPEOF_CPOINTER;
2891 typeofv = TYPEOF_GPOINTER;
2894 typeofv = TYPEOF_PPOINTER;
2897 typeofv = TYPEOF_IPOINTER;
2900 typeofv = TYPEOF_ARRAY;
2903 typeofv = TYPEOF_FUNCTION;
2909 sprintf (buffer, "%d", typeofv);
2910 tree->opval.val = constVal (buffer);
2911 tree->right = tree->left = NULL;
2912 TETYPE (tree) = getSpec (TTYPE (tree) =
2913 tree->opval.val->type);
2916 /*------------------------------------------------------------------*/
2917 /*----------------------------*/
2918 /* conditional operator '?' */
2919 /*----------------------------*/
2921 /* the type is value of the colon operator (on the right) */
2922 assert(IS_COLON_OP(tree->right));
2923 /* if already known then replace the tree : optimizer will do it
2924 but faster to do it here */
2925 if (IS_LITERAL (LTYPE(tree))) {
2926 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2927 return decorateType(tree->right->left) ;
2929 return decorateType(tree->right->right) ;
2932 tree->right = decorateType(tree->right);
2933 TTYPE (tree) = RTYPE(tree);
2934 TETYPE (tree) = getSpec (TTYPE (tree));
2939 /* if they don't match we have a problem */
2940 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2942 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2943 goto errorTreeReturn;
2946 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2947 TETYPE (tree) = getSpec (TTYPE (tree));
2951 /*------------------------------------------------------------------*/
2952 /*----------------------------*/
2953 /* assignment operators */
2954 /*----------------------------*/
2957 /* for these it must be both must be integral */
2958 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2959 !IS_ARITHMETIC (RTYPE (tree)))
2961 werror (E_OPS_INTEGRAL);
2962 goto errorTreeReturn;
2965 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2967 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2968 werror (E_CODE_WRITE, " ");
2972 werror (E_LVALUE_REQUIRED, "*= or /=");
2973 goto errorTreeReturn;
2984 /* for these it must be both must be integral */
2985 if (!IS_INTEGRAL (LTYPE (tree)) ||
2986 !IS_INTEGRAL (RTYPE (tree)))
2988 werror (E_OPS_INTEGRAL);
2989 goto errorTreeReturn;
2992 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2994 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2995 werror (E_CODE_WRITE, " ");
2999 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3000 goto errorTreeReturn;
3006 /*------------------------------------------------------------------*/
3007 /*----------------------------*/
3009 /*----------------------------*/
3011 if (!(IS_PTR (LTYPE (tree)) ||
3012 IS_ARITHMETIC (LTYPE (tree))))
3014 werror (E_PLUS_INVALID, "-=");
3015 goto errorTreeReturn;
3018 if (!(IS_PTR (RTYPE (tree)) ||
3019 IS_ARITHMETIC (RTYPE (tree))))
3021 werror (E_PLUS_INVALID, "-=");
3022 goto errorTreeReturn;
3025 TETYPE (tree) = getSpec (TTYPE (tree) =
3026 computeType (LTYPE (tree),
3029 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3030 werror (E_CODE_WRITE, " ");
3034 werror (E_LVALUE_REQUIRED, "-=");
3035 goto errorTreeReturn;
3041 /*------------------------------------------------------------------*/
3042 /*----------------------------*/
3044 /*----------------------------*/
3046 /* this is not a unary operation */
3047 /* if both pointers then problem */
3048 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3050 werror (E_PTR_PLUS_PTR);
3051 goto errorTreeReturn;
3054 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3056 werror (E_PLUS_INVALID, "+=");
3057 goto errorTreeReturn;
3060 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3062 werror (E_PLUS_INVALID, "+=");
3063 goto errorTreeReturn;
3066 TETYPE (tree) = getSpec (TTYPE (tree) =
3067 computeType (LTYPE (tree),
3070 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3071 werror (E_CODE_WRITE, " ");
3075 werror (E_LVALUE_REQUIRED, "+=");
3076 goto errorTreeReturn;
3079 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3080 tree->opval.op = '=';
3084 /*------------------------------------------------------------------*/
3085 /*----------------------------*/
3086 /* straight assignemnt */
3087 /*----------------------------*/
3089 /* cannot be an aggregate */
3090 if (IS_AGGREGATE (LTYPE (tree)))
3092 werror (E_AGGR_ASSIGN);
3093 goto errorTreeReturn;
3096 /* they should either match or be castable */
3097 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3099 werror (E_TYPE_MISMATCH, "assignment", " ");
3100 fprintf (stderr, "type --> '");
3101 printTypeChain (RTYPE (tree), stderr);
3102 fprintf (stderr, "' ");
3103 fprintf (stderr, "assigned to type --> '");
3104 printTypeChain (LTYPE (tree), stderr);
3105 fprintf (stderr, "'\n");
3106 goto errorTreeReturn;
3109 /* if the left side of the tree is of type void
3110 then report error */
3111 if (IS_VOID (LTYPE (tree)))
3113 werror (E_CAST_ZERO);
3114 printFromToType(RTYPE(tree), LTYPE(tree));
3117 TETYPE (tree) = getSpec (TTYPE (tree) =
3121 if (!tree->initMode ) {
3122 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3123 werror (E_CODE_WRITE, " ");
3127 werror (E_LVALUE_REQUIRED, "=");
3128 goto errorTreeReturn;
3133 /*------------------------------------------------------------------*/
3134 /*----------------------------*/
3135 /* comma operator */
3136 /*----------------------------*/
3138 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3141 /*------------------------------------------------------------------*/
3142 /*----------------------------*/
3144 /*----------------------------*/
3148 if (processParms (tree->left,
3149 FUNC_ARGS(tree->left->ftype),
3150 tree->right, &parmNumber, TRUE)) {
3151 goto errorTreeReturn;
3154 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3155 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3157 //FUNC_ARGS(tree->left->ftype) =
3158 //reverseVal (FUNC_ARGS(tree->left->ftype));
3159 reverseParms (tree->right);
3162 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3165 /*------------------------------------------------------------------*/
3166 /*----------------------------*/
3167 /* return statement */
3168 /*----------------------------*/
3173 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3175 werror (W_RETURN_MISMATCH);
3176 printFromToType (RTYPE(tree), currFunc->type->next);
3177 goto errorTreeReturn;
3180 if (IS_VOID (currFunc->type->next)
3182 !IS_VOID (RTYPE (tree)))
3184 werror (E_FUNC_VOID);
3185 goto errorTreeReturn;
3188 /* if there is going to be a casing required then add it */
3189 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3192 decorateType (newNode (CAST,
3193 newAst_LINK (copyLinkChain (currFunc->type->next)),
3202 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3204 werror (E_VOID_FUNC, currFunc->name);
3205 goto errorTreeReturn;
3208 TTYPE (tree) = TETYPE (tree) = NULL;
3211 /*------------------------------------------------------------------*/
3212 /*----------------------------*/
3213 /* switch statement */
3214 /*----------------------------*/
3216 /* the switch value must be an integer */
3217 if (!IS_INTEGRAL (LTYPE (tree)))
3219 werror (E_SWITCH_NON_INTEGER);
3220 goto errorTreeReturn;
3223 TTYPE (tree) = TETYPE (tree) = NULL;
3226 /*------------------------------------------------------------------*/
3227 /*----------------------------*/
3229 /*----------------------------*/
3231 tree->left = backPatchLabels (tree->left,
3234 TTYPE (tree) = TETYPE (tree) = NULL;
3237 /*------------------------------------------------------------------*/
3238 /*----------------------------*/
3240 /*----------------------------*/
3243 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3244 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3245 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3247 /* if the for loop is reversible then
3248 reverse it otherwise do what we normally
3254 if (isLoopReversible (tree, &sym, &init, &end))
3255 return reverseLoop (tree, sym, init, end);
3257 return decorateType (createFor (AST_FOR (tree, trueLabel),
3258 AST_FOR (tree, continueLabel),
3259 AST_FOR (tree, falseLabel),
3260 AST_FOR (tree, condLabel),
3261 AST_FOR (tree, initExpr),
3262 AST_FOR (tree, condExpr),
3263 AST_FOR (tree, loopExpr),
3267 TTYPE (tree) = TETYPE (tree) = NULL;
3271 /* some error found this tree will be killed */
3273 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3274 tree->opval.op = NULLOP;
3280 /*-----------------------------------------------------------------*/
3281 /* sizeofOp - processes size of operation */
3282 /*-----------------------------------------------------------------*/
3284 sizeofOp (sym_link * type)
3288 /* make sure the type is complete and sane */
3289 checkTypeSanity(type, "(sizeof)");
3291 /* get the size and convert it to character */
3292 sprintf (buff, "%d", getSize (type));
3294 /* now convert into value */
3295 return constVal (buff);
3299 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3300 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3301 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3302 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3303 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3304 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3305 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3307 /*-----------------------------------------------------------------*/
3308 /* backPatchLabels - change and or not operators to flow control */
3309 /*-----------------------------------------------------------------*/
3311 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3317 if (!(IS_ANDORNOT (tree)))
3320 /* if this an and */
3323 static int localLbl = 0;
3326 sprintf (buffer, "_and_%d", localLbl++);
3327 localLabel = newSymbol (buffer, NestLevel);
3329 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3331 /* if left is already a IFX then just change the if true label in that */
3332 if (!IS_IFX (tree->left))
3333 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3335 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3336 /* right is a IFX then just join */
3337 if (IS_IFX (tree->right))
3338 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3340 tree->right = createLabel (localLabel, tree->right);
3341 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3343 return newNode (NULLOP, tree->left, tree->right);
3346 /* if this is an or operation */
3349 static int localLbl = 0;
3352 sprintf (buffer, "_or_%d", localLbl++);
3353 localLabel = newSymbol (buffer, NestLevel);
3355 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3357 /* if left is already a IFX then just change the if true label in that */
3358 if (!IS_IFX (tree->left))
3359 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3361 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3362 /* right is a IFX then just join */
3363 if (IS_IFX (tree->right))
3364 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3366 tree->right = createLabel (localLabel, tree->right);
3367 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3369 return newNode (NULLOP, tree->left, tree->right);
3375 int wasnot = IS_NOT (tree->left);
3376 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3378 /* if the left is already a IFX */
3379 if (!IS_IFX (tree->left))
3380 tree->left = newNode (IFX, tree->left, NULL);
3384 tree->left->trueLabel = trueLabel;
3385 tree->left->falseLabel = falseLabel;
3389 tree->left->trueLabel = falseLabel;
3390 tree->left->falseLabel = trueLabel;
3397 tree->trueLabel = trueLabel;
3398 tree->falseLabel = falseLabel;
3405 /*-----------------------------------------------------------------*/
3406 /* createBlock - create expression tree for block */
3407 /*-----------------------------------------------------------------*/
3409 createBlock (symbol * decl, ast * body)
3413 /* if the block has nothing */
3417 ex = newNode (BLOCK, NULL, body);
3418 ex->values.sym = decl;
3420 ex->right = ex->right;
3426 /*-----------------------------------------------------------------*/
3427 /* createLabel - creates the expression tree for labels */
3428 /*-----------------------------------------------------------------*/
3430 createLabel (symbol * label, ast * stmnt)
3433 char name[SDCC_NAME_MAX + 1];
3436 /* must create fresh symbol if the symbol name */
3437 /* exists in the symbol table, since there can */
3438 /* be a variable with the same name as the labl */
3439 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3440 (csym->level == label->level))
3441 label = newSymbol (label->name, label->level);
3443 /* change the name before putting it in add _ */
3444 sprintf (name, "%s", label->name);
3446 /* put the label in the LabelSymbol table */
3447 /* but first check if a label of the same */
3449 if ((csym = findSym (LabelTab, NULL, name)))
3450 werror (E_DUPLICATE_LABEL, label->name);
3452 addSym (LabelTab, label, name, label->level, 0, 0);
3455 label->key = labelKey++;
3456 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3462 /*-----------------------------------------------------------------*/
3463 /* createCase - generates the parsetree for a case statement */
3464 /*-----------------------------------------------------------------*/
3466 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3468 char caseLbl[SDCC_NAME_MAX + 1];
3472 /* if the switch statement does not exist */
3473 /* then case is out of context */
3476 werror (E_CASE_CONTEXT);
3480 caseVal = decorateType (resolveSymbols (caseVal));
3481 /* if not a constant then error */
3482 if (!IS_LITERAL (caseVal->ftype))
3484 werror (E_CASE_CONSTANT);
3488 /* if not a integer than error */
3489 if (!IS_INTEGRAL (caseVal->ftype))
3491 werror (E_CASE_NON_INTEGER);
3495 /* find the end of the switch values chain */
3496 if (!(val = swStat->values.switchVals.swVals))
3497 swStat->values.switchVals.swVals = caseVal->opval.val;
3500 /* also order the cases according to value */
3502 int cVal = (int) floatFromVal (caseVal->opval.val);
3503 while (val && (int) floatFromVal (val) < cVal)
3509 /* if we reached the end then */
3512 pval->next = caseVal->opval.val;
3516 /* we found a value greater than */
3517 /* the current value we must add this */
3518 /* before the value */
3519 caseVal->opval.val->next = val;
3521 /* if this was the first in chain */
3522 if (swStat->values.switchVals.swVals == val)
3523 swStat->values.switchVals.swVals =
3526 pval->next = caseVal->opval.val;
3531 /* create the case label */
3532 sprintf (caseLbl, "_case_%d_%d",
3533 swStat->values.switchVals.swNum,
3534 (int) floatFromVal (caseVal->opval.val));
3536 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3541 /*-----------------------------------------------------------------*/
3542 /* createDefault - creates the parse tree for the default statement */
3543 /*-----------------------------------------------------------------*/
3545 createDefault (ast * swStat, ast * stmnt)
3547 char defLbl[SDCC_NAME_MAX + 1];
3549 /* if the switch statement does not exist */
3550 /* then case is out of context */
3553 werror (E_CASE_CONTEXT);
3557 /* turn on the default flag */
3558 swStat->values.switchVals.swDefault = 1;
3560 /* create the label */
3561 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3562 return createLabel (newSymbol (defLbl, 0), stmnt);
3565 /*-----------------------------------------------------------------*/
3566 /* createIf - creates the parsetree for the if statement */
3567 /*-----------------------------------------------------------------*/
3569 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3571 static int Lblnum = 0;
3573 symbol *ifTrue, *ifFalse, *ifEnd;
3575 /* if neither exists */
3576 if (!elseBody && !ifBody) {
3577 // if there are no side effects (i++, j() etc)
3578 if (!hasSEFcalls(condAst)) {
3583 /* create the labels */
3584 sprintf (buffer, "_iffalse_%d", Lblnum);
3585 ifFalse = newSymbol (buffer, NestLevel);
3586 /* if no else body then end == false */
3591 sprintf (buffer, "_ifend_%d", Lblnum);
3592 ifEnd = newSymbol (buffer, NestLevel);
3595 sprintf (buffer, "_iftrue_%d", Lblnum);
3596 ifTrue = newSymbol (buffer, NestLevel);
3600 /* attach the ifTrue label to the top of it body */
3601 ifBody = createLabel (ifTrue, ifBody);
3602 /* attach a goto end to the ifBody if else is present */
3605 ifBody = newNode (NULLOP, ifBody,
3607 newAst_VALUE (symbolVal (ifEnd)),
3609 /* put the elseLabel on the else body */
3610 elseBody = createLabel (ifFalse, elseBody);
3611 /* out the end at the end of the body */
3612 elseBody = newNode (NULLOP,
3614 createLabel (ifEnd, NULL));
3618 ifBody = newNode (NULLOP, ifBody,
3619 createLabel (ifFalse, NULL));
3621 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3622 if (IS_IFX (condAst))
3625 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3627 return newNode (NULLOP, ifTree,
3628 newNode (NULLOP, ifBody, elseBody));
3632 /*-----------------------------------------------------------------*/
3633 /* createDo - creates parse tree for do */
3636 /* _docontinue_n: */
3637 /* condition_expression +-> trueLabel -> _dobody_n */
3639 /* +-> falseLabel-> _dobreak_n */
3641 /*-----------------------------------------------------------------*/
3643 createDo (symbol * trueLabel, symbol * continueLabel,
3644 symbol * falseLabel, ast * condAst, ast * doBody)
3649 /* if the body does not exist then it is simple */
3652 condAst = backPatchLabels (condAst, continueLabel, NULL);
3653 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3654 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3655 doTree->trueLabel = continueLabel;
3656 doTree->falseLabel = NULL;
3660 /* otherwise we have a body */
3661 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3663 /* attach the body label to the top */
3664 doBody = createLabel (trueLabel, doBody);
3665 /* attach the continue label to end of body */
3666 doBody = newNode (NULLOP, doBody,
3667 createLabel (continueLabel, NULL));
3669 /* now put the break label at the end */
3670 if (IS_IFX (condAst))
3673 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3675 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3677 /* putting it together */
3678 return newNode (NULLOP, doBody, doTree);
3681 /*-----------------------------------------------------------------*/
3682 /* createFor - creates parse tree for 'for' statement */
3685 /* condExpr +-> trueLabel -> _forbody_n */
3687 /* +-> falseLabel-> _forbreak_n */
3690 /* _forcontinue_n: */
3692 /* goto _forcond_n ; */
3694 /*-----------------------------------------------------------------*/
3696 createFor (symbol * trueLabel, symbol * continueLabel,
3697 symbol * falseLabel, symbol * condLabel,
3698 ast * initExpr, ast * condExpr, ast * loopExpr,
3703 /* if loopexpression not present then we can generate it */
3704 /* the same way as a while */
3706 return newNode (NULLOP, initExpr,
3707 createWhile (trueLabel, continueLabel,
3708 falseLabel, condExpr, forBody));
3709 /* vanilla for statement */
3710 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3712 if (condExpr && !IS_IFX (condExpr))
3713 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3716 /* attach condition label to condition */
3717 condExpr = createLabel (condLabel, condExpr);
3719 /* attach body label to body */
3720 forBody = createLabel (trueLabel, forBody);
3722 /* attach continue to forLoop expression & attach */
3723 /* goto the forcond @ and of loopExpression */
3724 loopExpr = createLabel (continueLabel,
3728 newAst_VALUE (symbolVal (condLabel)),
3730 /* now start putting them together */
3731 forTree = newNode (NULLOP, initExpr, condExpr);
3732 forTree = newNode (NULLOP, forTree, forBody);
3733 forTree = newNode (NULLOP, forTree, loopExpr);
3734 /* finally add the break label */
3735 forTree = newNode (NULLOP, forTree,
3736 createLabel (falseLabel, NULL));
3740 /*-----------------------------------------------------------------*/
3741 /* createWhile - creates parse tree for while statement */
3742 /* the while statement will be created as follows */
3744 /* _while_continue_n: */
3745 /* condition_expression +-> trueLabel -> _while_boby_n */
3747 /* +-> falseLabel -> _while_break_n */
3748 /* _while_body_n: */
3750 /* goto _while_continue_n */
3751 /* _while_break_n: */
3752 /*-----------------------------------------------------------------*/
3754 createWhile (symbol * trueLabel, symbol * continueLabel,
3755 symbol * falseLabel, ast * condExpr, ast * whileBody)
3759 /* put the continue label */
3760 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3761 condExpr = createLabel (continueLabel, condExpr);
3762 condExpr->lineno = 0;
3764 /* put the body label in front of the body */
3765 whileBody = createLabel (trueLabel, whileBody);
3766 whileBody->lineno = 0;
3767 /* put a jump to continue at the end of the body */
3768 /* and put break label at the end of the body */
3769 whileBody = newNode (NULLOP,
3772 newAst_VALUE (symbolVal (continueLabel)),
3773 createLabel (falseLabel, NULL)));
3775 /* put it all together */
3776 if (IS_IFX (condExpr))
3777 whileTree = condExpr;
3780 whileTree = newNode (IFX, condExpr, NULL);
3781 /* put the true & false labels in place */
3782 whileTree->trueLabel = trueLabel;
3783 whileTree->falseLabel = falseLabel;
3786 return newNode (NULLOP, whileTree, whileBody);
3789 /*-----------------------------------------------------------------*/
3790 /* optimizeGetHbit - get highest order bit of the expression */
3791 /*-----------------------------------------------------------------*/
3793 optimizeGetHbit (ast * tree)
3796 /* if this is not a bit and */
3797 if (!IS_BITAND (tree))
3800 /* will look for tree of the form
3801 ( expr >> ((sizeof expr) -1) ) & 1 */
3802 if (!IS_AST_LIT_VALUE (tree->right))
3805 if (AST_LIT_VALUE (tree->right) != 1)
3808 if (!IS_RIGHT_OP (tree->left))
3811 if (!IS_AST_LIT_VALUE (tree->left->right))
3814 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3815 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3818 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3822 /*-----------------------------------------------------------------*/
3823 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3824 /*-----------------------------------------------------------------*/
3826 optimizeRRCRLC (ast * root)
3828 /* will look for trees of the form
3829 (?expr << 1) | (?expr >> 7) or
3830 (?expr >> 7) | (?expr << 1) will make that
3831 into a RLC : operation ..
3833 (?expr >> 1) | (?expr << 7) or
3834 (?expr << 7) | (?expr >> 1) will make that
3835 into a RRC operation
3836 note : by 7 I mean (number of bits required to hold the
3838 /* if the root operations is not a | operation the not */
3839 if (!IS_BITOR (root))
3842 /* I have to think of a better way to match patterns this sucks */
3843 /* that aside let start looking for the first case : I use a the
3844 negative check a lot to improve the efficiency */
3845 /* (?expr << 1) | (?expr >> 7) */
3846 if (IS_LEFT_OP (root->left) &&
3847 IS_RIGHT_OP (root->right))
3850 if (!SPEC_USIGN (TETYPE (root->left->left)))
3853 if (!IS_AST_LIT_VALUE (root->left->right) ||
3854 !IS_AST_LIT_VALUE (root->right->right))
3857 /* make sure it is the same expression */
3858 if (!isAstEqual (root->left->left,
3862 if (AST_LIT_VALUE (root->left->right) != 1)
3865 if (AST_LIT_VALUE (root->right->right) !=
3866 (getSize (TTYPE (root->left->left)) * 8 - 1))
3869 /* whew got the first case : create the AST */
3870 return newNode (RLC, root->left->left, NULL);
3874 /* check for second case */
3875 /* (?expr >> 7) | (?expr << 1) */
3876 if (IS_LEFT_OP (root->right) &&
3877 IS_RIGHT_OP (root->left))
3880 if (!SPEC_USIGN (TETYPE (root->left->left)))
3883 if (!IS_AST_LIT_VALUE (root->left->right) ||
3884 !IS_AST_LIT_VALUE (root->right->right))
3887 /* make sure it is the same symbol */
3888 if (!isAstEqual (root->left->left,
3892 if (AST_LIT_VALUE (root->right->right) != 1)
3895 if (AST_LIT_VALUE (root->left->right) !=
3896 (getSize (TTYPE (root->left->left)) * 8 - 1))
3899 /* whew got the first case : create the AST */
3900 return newNode (RLC, root->left->left, NULL);
3905 /* third case for RRC */
3906 /* (?symbol >> 1) | (?symbol << 7) */
3907 if (IS_LEFT_OP (root->right) &&
3908 IS_RIGHT_OP (root->left))
3911 if (!SPEC_USIGN (TETYPE (root->left->left)))
3914 if (!IS_AST_LIT_VALUE (root->left->right) ||
3915 !IS_AST_LIT_VALUE (root->right->right))
3918 /* make sure it is the same symbol */
3919 if (!isAstEqual (root->left->left,
3923 if (AST_LIT_VALUE (root->left->right) != 1)
3926 if (AST_LIT_VALUE (root->right->right) !=
3927 (getSize (TTYPE (root->left->left)) * 8 - 1))
3930 /* whew got the first case : create the AST */
3931 return newNode (RRC, root->left->left, NULL);
3935 /* fourth and last case for now */
3936 /* (?symbol << 7) | (?symbol >> 1) */
3937 if (IS_RIGHT_OP (root->right) &&
3938 IS_LEFT_OP (root->left))
3941 if (!SPEC_USIGN (TETYPE (root->left->left)))
3944 if (!IS_AST_LIT_VALUE (root->left->right) ||
3945 !IS_AST_LIT_VALUE (root->right->right))
3948 /* make sure it is the same symbol */
3949 if (!isAstEqual (root->left->left,
3953 if (AST_LIT_VALUE (root->right->right) != 1)
3956 if (AST_LIT_VALUE (root->left->right) !=
3957 (getSize (TTYPE (root->left->left)) * 8 - 1))
3960 /* whew got the first case : create the AST */
3961 return newNode (RRC, root->left->left, NULL);
3965 /* not found return root */
3969 /*-----------------------------------------------------------------*/
3970 /* optimizeCompare - otimizes compares for bit variables */
3971 /*-----------------------------------------------------------------*/
3973 optimizeCompare (ast * root)
3975 ast *optExpr = NULL;
3978 unsigned int litValue;
3980 /* if nothing then return nothing */
3984 /* if not a compare op then do leaves */
3985 if (!IS_COMPARE_OP (root))
3987 root->left = optimizeCompare (root->left);
3988 root->right = optimizeCompare (root->right);
3992 /* if left & right are the same then depending
3993 of the operation do */
3994 if (isAstEqual (root->left, root->right))
3996 switch (root->opval.op)
4001 optExpr = newAst_VALUE (constVal ("0"));
4006 optExpr = newAst_VALUE (constVal ("1"));
4010 return decorateType (optExpr);
4013 vleft = (root->left->type == EX_VALUE ?
4014 root->left->opval.val : NULL);
4016 vright = (root->right->type == EX_VALUE ?
4017 root->right->opval.val : NULL);
4019 //#define EXPERIMENTAL
4021 /* if left is unsigned and right is literal */
4022 if (vleft && vright &&
4023 IS_UNSIGNED(vleft->etype) &&
4024 IS_LITERAL(vright->etype)) {
4025 double dval=floatFromVal(vright);
4026 int op=root->opval.op;
4028 fprintf (stderr,"op: '");
4030 case LE_OP: fprintf (stderr, "<= '"); break;
4031 case EQ_OP: fprintf (stderr, "== '"); break;
4032 case GE_OP: fprintf (stderr, ">= '"); break;
4033 default: fprintf (stderr, "%c '", op); break;
4035 fprintf (stderr, "%f\n", dval);
4042 if (dval<0 || (op=='<' && dval==0)) {
4043 // unsigned is never < 0
4044 werror (W_IF_NEVER_TRUE);
4045 optExpr = newAst_VALUE (constVal("0"));
4046 return decorateType (optExpr);
4050 // change this into a cheaper EQ_OP
4051 fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
4052 root->opval.op=EQ_OP;
4059 if (dval>0 || (op==GE_OP && dval==0)) {
4060 // unsigned is never < 0
4061 werror (W_IF_ALWAYS_TRUE);
4062 optExpr = newAst_VALUE (constVal("1"));
4063 return decorateType (optExpr);
4067 // change this into a cheaper reversed EQ_OP
4068 fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
4069 root->opval.op=EQ_OP;
4076 /* if left is a BITVAR in BITSPACE */
4077 /* and right is a LITERAL then opt- */
4078 /* imize else do nothing */
4079 if (vleft && vright &&
4080 IS_BITVAR (vleft->etype) &&
4081 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4082 IS_LITERAL (vright->etype))
4085 /* if right side > 1 then comparison may never succeed */
4086 if ((litValue = (int) floatFromVal (vright)) > 1)
4088 werror (W_BAD_COMPARE);
4094 switch (root->opval.op)
4096 case '>': /* bit value greater than 1 cannot be */
4097 werror (W_BAD_COMPARE);
4101 case '<': /* bit value < 1 means 0 */
4103 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4106 case LE_OP: /* bit value <= 1 means no check */
4107 optExpr = newAst_VALUE (vright);
4110 case GE_OP: /* bit value >= 1 means only check for = */
4112 optExpr = newAst_VALUE (vleft);
4117 { /* literal is zero */
4118 switch (root->opval.op)
4120 case '<': /* bit value < 0 cannot be */
4121 werror (W_BAD_COMPARE);
4125 case '>': /* bit value > 0 means 1 */
4127 optExpr = newAst_VALUE (vleft);
4130 case LE_OP: /* bit value <= 0 means no check */
4131 case GE_OP: /* bit value >= 0 means no check */
4132 werror (W_BAD_COMPARE);
4136 case EQ_OP: /* bit == 0 means ! of bit */
4137 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4141 return decorateType (resolveSymbols (optExpr));
4142 } /* end-of-if of BITVAR */
4147 /*-----------------------------------------------------------------*/
4148 /* addSymToBlock : adds the symbol to the first block we find */
4149 /*-----------------------------------------------------------------*/
4151 addSymToBlock (symbol * sym, ast * tree)
4153 /* reached end of tree or a leaf */
4154 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4158 if (IS_AST_OP (tree) &&
4159 tree->opval.op == BLOCK)
4162 symbol *lsym = copySymbol (sym);
4164 lsym->next = AST_VALUES (tree, sym);
4165 AST_VALUES (tree, sym) = lsym;
4169 addSymToBlock (sym, tree->left);
4170 addSymToBlock (sym, tree->right);
4173 /*-----------------------------------------------------------------*/
4174 /* processRegParms - do processing for register parameters */
4175 /*-----------------------------------------------------------------*/
4177 processRegParms (value * args, ast * body)
4181 if (IS_REGPARM (args->etype))
4182 addSymToBlock (args->sym, body);
4187 /*-----------------------------------------------------------------*/
4188 /* resetParmKey - resets the operandkeys for the symbols */
4189 /*-----------------------------------------------------------------*/
4190 DEFSETFUNC (resetParmKey)
4201 /*-----------------------------------------------------------------*/
4202 /* createFunction - This is the key node that calls the iCode for */
4203 /* generating the code for a function. Note code */
4204 /* is generated function by function, later when */
4205 /* add inter-procedural analysis this will change */
4206 /*-----------------------------------------------------------------*/
4208 createFunction (symbol * name, ast * body)
4214 iCode *piCode = NULL;
4216 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4217 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4219 /* if check function return 0 then some problem */
4220 if (checkFunction (name, NULL) == 0)
4223 /* create a dummy block if none exists */
4225 body = newNode (BLOCK, NULL, NULL);
4229 /* check if the function name already in the symbol table */
4230 if ((csym = findSym (SymbolTab, NULL, name->name)))
4233 /* special case for compiler defined functions
4234 we need to add the name to the publics list : this
4235 actually means we are now compiling the compiler
4239 addSet (&publics, name);
4245 allocVariables (name);
4247 name->lastLine = yylineno;
4250 /* set the stack pointer */
4251 /* PENDING: check this for the mcs51 */
4252 stackPtr = -port->stack.direction * port->stack.call_overhead;
4253 if (IFFUNC_ISISR (name->type))
4254 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4255 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4256 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4258 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4260 fetype = getSpec (name->type); /* get the specifier for the function */
4261 /* if this is a reentrant function then */
4262 if (IFFUNC_ISREENT (name->type))
4265 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4267 /* do processing for parameters that are passed in registers */
4268 processRegParms (FUNC_ARGS(name->type), body);
4270 /* set the stack pointer */
4274 /* allocate & autoinit the block variables */
4275 processBlockVars (body, &stack, ALLOCATE);
4277 /* save the stack information */
4278 if (options.useXstack)
4279 name->xstack = SPEC_STAK (fetype) = stack;
4281 name->stack = SPEC_STAK (fetype) = stack;
4283 /* name needs to be mangled */
4284 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4286 body = resolveSymbols (body); /* resolve the symbols */
4287 body = decorateType (body); /* propagateType & do semantic checks */
4289 ex = newAst_VALUE (symbolVal (name)); /* create name */
4290 ex = newNode (FUNCTION, ex, body);
4291 ex->values.args = FUNC_ARGS(name->type);
4293 if (options.dump_tree) PA(ex);
4296 werror (E_FUNC_NO_CODE, name->name);
4300 /* create the node & generate intermediate code */
4302 codeOutFile = code->oFile;
4303 piCode = iCodeFromAst (ex);
4307 werror (E_FUNC_NO_CODE, name->name);
4311 eBBlockFromiCode (piCode);
4313 /* if there are any statics then do them */
4316 GcurMemmap = statsg;
4317 codeOutFile = statsg->oFile;
4318 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4324 /* dealloc the block variables */
4325 processBlockVars (body, &stack, DEALLOCATE);
4326 /* deallocate paramaters */
4327 deallocParms (FUNC_ARGS(name->type));
4329 if (IFFUNC_ISREENT (name->type))
4332 /* we are done freeup memory & cleanup */
4336 FUNC_HASBODY(name->type) = 1;
4337 addSet (&operKeyReset, name);
4338 applyToSet (operKeyReset, resetParmKey);
4341 cdbStructBlock (1, cdbFile);
4343 cleanUpLevel (LabelTab, 0);
4344 cleanUpBlock (StructTab, 1);
4345 cleanUpBlock (TypedefTab, 1);
4347 xstack->syms = NULL;
4348 istack->syms = NULL;
4353 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4354 /*-----------------------------------------------------------------*/
4355 /* ast_print : prints the ast (for debugging purposes) */
4356 /*-----------------------------------------------------------------*/
4358 void ast_print (ast * tree, FILE *outfile, int indent)
4363 /* can print only decorated trees */
4364 if (!tree->decorated) return;
4366 /* if any child is an error | this one is an error do nothing */
4367 if (tree->isError ||
4368 (tree->left && tree->left->isError) ||
4369 (tree->right && tree->right->isError)) {
4370 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4374 /* print the line */
4375 /* if not block & function */
4376 if (tree->type == EX_OP &&
4377 (tree->opval.op != FUNCTION &&
4378 tree->opval.op != BLOCK &&
4379 tree->opval.op != NULLOP)) {
4382 if (tree->opval.op == FUNCTION) {
4384 value *args=FUNC_ARGS(tree->left->opval.val->type);
4385 fprintf(outfile,"FUNCTION (%s=%p) type (",
4386 tree->left->opval.val->name, tree);
4387 printTypeChain (tree->ftype,outfile);
4388 fprintf(outfile,") args (");
4391 fprintf (outfile, ", ");
4393 printTypeChain (args ? args->type : NULL, outfile);
4395 args= args ? args->next : NULL;
4397 fprintf(outfile,")\n");
4398 ast_print(tree->left,outfile,indent);
4399 ast_print(tree->right,outfile,indent);
4402 if (tree->opval.op == BLOCK) {
4403 symbol *decls = tree->values.sym;
4404 INDENT(indent,outfile);
4405 fprintf(outfile,"{\n");
4407 INDENT(indent+2,outfile);
4408 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4409 decls->name, decls);
4410 printTypeChain(decls->type,outfile);
4411 fprintf(outfile,")\n");
4413 decls = decls->next;
4415 ast_print(tree->right,outfile,indent+2);
4416 INDENT(indent,outfile);
4417 fprintf(outfile,"}\n");
4420 if (tree->opval.op == NULLOP) {
4421 fprintf(outfile,"\n");
4422 ast_print(tree->left,outfile,indent);
4423 fprintf(outfile,"\n");
4424 ast_print(tree->right,outfile,indent);
4427 INDENT(indent,outfile);
4429 /*------------------------------------------------------------------*/
4430 /*----------------------------*/
4431 /* leaf has been reached */
4432 /*----------------------------*/
4433 /* if this is of type value */
4434 /* just get the type */
4435 if (tree->type == EX_VALUE) {
4437 if (IS_LITERAL (tree->opval.val->etype)) {
4438 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4439 (int) floatFromVal(tree->opval.val),
4440 (int) floatFromVal(tree->opval.val),
4441 floatFromVal(tree->opval.val));
4442 } else if (tree->opval.val->sym) {
4443 /* if the undefined flag is set then give error message */
4444 if (tree->opval.val->sym->undefined) {
4445 fprintf(outfile,"UNDEFINED SYMBOL ");
4447 fprintf(outfile,"SYMBOL ");
4449 fprintf(outfile,"(%s=%p)",
4450 tree->opval.val->sym->name,tree);
4453 fprintf(outfile," type (");
4454 printTypeChain(tree->ftype,outfile);
4455 fprintf(outfile,")\n");
4457 fprintf(outfile,"\n");
4462 /* if type link for the case of cast */
4463 if (tree->type == EX_LINK) {
4464 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4465 printTypeChain(tree->opval.lnk,outfile);
4466 fprintf(outfile,")\n");
4471 /* depending on type of operator do */
4473 switch (tree->opval.op) {
4474 /*------------------------------------------------------------------*/
4475 /*----------------------------*/
4477 /*----------------------------*/
4479 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4480 printTypeChain(tree->ftype,outfile);
4481 fprintf(outfile,")\n");
4482 ast_print(tree->left,outfile,indent+2);
4483 ast_print(tree->right,outfile,indent+2);
4486 /*------------------------------------------------------------------*/
4487 /*----------------------------*/
4489 /*----------------------------*/
4491 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4492 printTypeChain(tree->ftype,outfile);
4493 fprintf(outfile,")\n");
4494 ast_print(tree->left,outfile,indent+2);
4495 ast_print(tree->right,outfile,indent+2);
4498 /*------------------------------------------------------------------*/
4499 /*----------------------------*/
4500 /* struct/union pointer */
4501 /*----------------------------*/
4503 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4504 printTypeChain(tree->ftype,outfile);
4505 fprintf(outfile,")\n");
4506 ast_print(tree->left,outfile,indent+2);
4507 ast_print(tree->right,outfile,indent+2);
4510 /*------------------------------------------------------------------*/
4511 /*----------------------------*/
4512 /* ++/-- operation */
4513 /*----------------------------*/
4514 case INC_OP: /* incerement operator unary so left only */
4515 fprintf(outfile,"INC_OP (%p) type (",tree);
4516 printTypeChain(tree->ftype,outfile);
4517 fprintf(outfile,")\n");
4518 ast_print(tree->left,outfile,indent+2);
4522 fprintf(outfile,"DEC_OP (%p) type (",tree);
4523 printTypeChain(tree->ftype,outfile);
4524 fprintf(outfile,")\n");
4525 ast_print(tree->left,outfile,indent+2);
4528 /*------------------------------------------------------------------*/
4529 /*----------------------------*/
4531 /*----------------------------*/
4534 fprintf(outfile,"& (%p) type (",tree);
4535 printTypeChain(tree->ftype,outfile);
4536 fprintf(outfile,")\n");
4537 ast_print(tree->left,outfile,indent+2);
4538 ast_print(tree->right,outfile,indent+2);
4540 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4541 printTypeChain(tree->ftype,outfile);
4542 fprintf(outfile,")\n");
4543 ast_print(tree->left,outfile,indent+2);
4544 ast_print(tree->right,outfile,indent+2);
4547 /*----------------------------*/
4549 /*----------------------------*/
4551 fprintf(outfile,"OR (%p) type (",tree);
4552 printTypeChain(tree->ftype,outfile);
4553 fprintf(outfile,")\n");
4554 ast_print(tree->left,outfile,indent+2);
4555 ast_print(tree->right,outfile,indent+2);
4557 /*------------------------------------------------------------------*/
4558 /*----------------------------*/
4560 /*----------------------------*/
4562 fprintf(outfile,"XOR (%p) type (",tree);
4563 printTypeChain(tree->ftype,outfile);
4564 fprintf(outfile,")\n");
4565 ast_print(tree->left,outfile,indent+2);
4566 ast_print(tree->right,outfile,indent+2);
4569 /*------------------------------------------------------------------*/
4570 /*----------------------------*/
4572 /*----------------------------*/
4574 fprintf(outfile,"DIV (%p) type (",tree);
4575 printTypeChain(tree->ftype,outfile);
4576 fprintf(outfile,")\n");
4577 ast_print(tree->left,outfile,indent+2);
4578 ast_print(tree->right,outfile,indent+2);
4580 /*------------------------------------------------------------------*/
4581 /*----------------------------*/
4583 /*----------------------------*/
4585 fprintf(outfile,"MOD (%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);
4592 /*------------------------------------------------------------------*/
4593 /*----------------------------*/
4594 /* address dereference */
4595 /*----------------------------*/
4596 case '*': /* can be unary : if right is null then unary operation */
4598 fprintf(outfile,"DEREF (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+2);
4604 /*------------------------------------------------------------------*/
4605 /*----------------------------*/
4606 /* multiplication */
4607 /*----------------------------*/
4608 fprintf(outfile,"MULT (%p) type (",tree);
4609 printTypeChain(tree->ftype,outfile);
4610 fprintf(outfile,")\n");
4611 ast_print(tree->left,outfile,indent+2);
4612 ast_print(tree->right,outfile,indent+2);
4616 /*------------------------------------------------------------------*/
4617 /*----------------------------*/
4618 /* unary '+' operator */
4619 /*----------------------------*/
4623 fprintf(outfile,"UPLUS (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+2);
4628 /*------------------------------------------------------------------*/
4629 /*----------------------------*/
4631 /*----------------------------*/
4632 fprintf(outfile,"ADD (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+2);
4636 ast_print(tree->right,outfile,indent+2);
4639 /*------------------------------------------------------------------*/
4640 /*----------------------------*/
4642 /*----------------------------*/
4643 case '-': /* can be unary */
4645 fprintf(outfile,"UMINUS (%p) type (",tree);
4646 printTypeChain(tree->ftype,outfile);
4647 fprintf(outfile,")\n");
4648 ast_print(tree->left,outfile,indent+2);
4650 /*------------------------------------------------------------------*/
4651 /*----------------------------*/
4653 /*----------------------------*/
4654 fprintf(outfile,"SUB (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+2);
4658 ast_print(tree->right,outfile,indent+2);
4661 /*------------------------------------------------------------------*/
4662 /*----------------------------*/
4664 /*----------------------------*/
4666 fprintf(outfile,"COMPL (%p) type (",tree);
4667 printTypeChain(tree->ftype,outfile);
4668 fprintf(outfile,")\n");
4669 ast_print(tree->left,outfile,indent+2);
4671 /*------------------------------------------------------------------*/
4672 /*----------------------------*/
4674 /*----------------------------*/
4676 fprintf(outfile,"NOT (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+2);
4681 /*------------------------------------------------------------------*/
4682 /*----------------------------*/
4684 /*----------------------------*/
4686 fprintf(outfile,"RRC (%p) type (",tree);
4687 printTypeChain(tree->ftype,outfile);
4688 fprintf(outfile,")\n");
4689 ast_print(tree->left,outfile,indent+2);
4693 fprintf(outfile,"RLC (%p) type (",tree);
4694 printTypeChain(tree->ftype,outfile);
4695 fprintf(outfile,")\n");
4696 ast_print(tree->left,outfile,indent+2);
4699 fprintf(outfile,"GETHBIT (%p) type (",tree);
4700 printTypeChain(tree->ftype,outfile);
4701 fprintf(outfile,")\n");
4702 ast_print(tree->left,outfile,indent+2);
4705 fprintf(outfile,"LEFT_SHIFT (%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 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4713 printTypeChain(tree->ftype,outfile);
4714 fprintf(outfile,")\n");
4715 ast_print(tree->left,outfile,indent+2);
4716 ast_print(tree->right,outfile,indent+2);
4718 /*------------------------------------------------------------------*/
4719 /*----------------------------*/
4721 /*----------------------------*/
4722 case CAST: /* change the type */
4723 fprintf(outfile,"CAST (%p) from type (",tree);
4724 printTypeChain(tree->right->ftype,outfile);
4725 fprintf(outfile,") to type (");
4726 printTypeChain(tree->ftype,outfile);
4727 fprintf(outfile,")\n");
4728 ast_print(tree->right,outfile,indent+2);
4732 fprintf(outfile,"ANDAND (%p) type (",tree);
4733 printTypeChain(tree->ftype,outfile);
4734 fprintf(outfile,")\n");
4735 ast_print(tree->left,outfile,indent+2);
4736 ast_print(tree->right,outfile,indent+2);
4739 fprintf(outfile,"OROR (%p) type (",tree);
4740 printTypeChain(tree->ftype,outfile);
4741 fprintf(outfile,")\n");
4742 ast_print(tree->left,outfile,indent+2);
4743 ast_print(tree->right,outfile,indent+2);
4746 /*------------------------------------------------------------------*/
4747 /*----------------------------*/
4748 /* comparison operators */
4749 /*----------------------------*/
4751 fprintf(outfile,"GT(>) (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+2);
4755 ast_print(tree->right,outfile,indent+2);
4758 fprintf(outfile,"LT(<) (%p) type (",tree);
4759 printTypeChain(tree->ftype,outfile);
4760 fprintf(outfile,")\n");
4761 ast_print(tree->left,outfile,indent+2);
4762 ast_print(tree->right,outfile,indent+2);
4765 fprintf(outfile,"LE(<=) (%p) type (",tree);
4766 printTypeChain(tree->ftype,outfile);
4767 fprintf(outfile,")\n");
4768 ast_print(tree->left,outfile,indent+2);
4769 ast_print(tree->right,outfile,indent+2);
4772 fprintf(outfile,"GE(>=) (%p) type (",tree);
4773 printTypeChain(tree->ftype,outfile);
4774 fprintf(outfile,")\n");
4775 ast_print(tree->left,outfile,indent+2);
4776 ast_print(tree->right,outfile,indent+2);
4779 fprintf(outfile,"EQ(==) (%p) type (",tree);
4780 printTypeChain(tree->ftype,outfile);
4781 fprintf(outfile,")\n");
4782 ast_print(tree->left,outfile,indent+2);
4783 ast_print(tree->right,outfile,indent+2);
4786 fprintf(outfile,"NE(!=) (%p) type (",tree);
4787 printTypeChain(tree->ftype,outfile);
4788 fprintf(outfile,")\n");
4789 ast_print(tree->left,outfile,indent+2);
4790 ast_print(tree->right,outfile,indent+2);
4791 /*------------------------------------------------------------------*/
4792 /*----------------------------*/
4794 /*----------------------------*/
4795 case SIZEOF: /* evaluate wihout code generation */
4796 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4799 /*------------------------------------------------------------------*/
4800 /*----------------------------*/
4801 /* conditional operator '?' */
4802 /*----------------------------*/
4804 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4805 printTypeChain(tree->ftype,outfile);
4806 fprintf(outfile,")\n");
4807 ast_print(tree->left,outfile,indent+2);
4808 ast_print(tree->right,outfile,indent+2);
4812 fprintf(outfile,"COLON(:) (%p) type (",tree);
4813 printTypeChain(tree->ftype,outfile);
4814 fprintf(outfile,")\n");
4815 ast_print(tree->left,outfile,indent+2);
4816 ast_print(tree->right,outfile,indent+2);
4819 /*------------------------------------------------------------------*/
4820 /*----------------------------*/
4821 /* assignment operators */
4822 /*----------------------------*/
4824 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4825 printTypeChain(tree->ftype,outfile);
4826 fprintf(outfile,")\n");
4827 ast_print(tree->left,outfile,indent+2);
4828 ast_print(tree->right,outfile,indent+2);
4831 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4832 printTypeChain(tree->ftype,outfile);
4833 fprintf(outfile,")\n");
4834 ast_print(tree->left,outfile,indent+2);
4835 ast_print(tree->right,outfile,indent+2);
4838 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4839 printTypeChain(tree->ftype,outfile);
4840 fprintf(outfile,")\n");
4841 ast_print(tree->left,outfile,indent+2);
4842 ast_print(tree->right,outfile,indent+2);
4845 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4846 printTypeChain(tree->ftype,outfile);
4847 fprintf(outfile,")\n");
4848 ast_print(tree->left,outfile,indent+2);
4849 ast_print(tree->right,outfile,indent+2);
4852 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4853 printTypeChain(tree->ftype,outfile);
4854 fprintf(outfile,")\n");
4855 ast_print(tree->left,outfile,indent+2);
4856 ast_print(tree->right,outfile,indent+2);
4859 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4860 printTypeChain(tree->ftype,outfile);
4861 fprintf(outfile,")\n");
4862 ast_print(tree->left,outfile,indent+2);
4863 ast_print(tree->right,outfile,indent+2);
4866 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4867 printTypeChain(tree->ftype,outfile);
4868 fprintf(outfile,")\n");
4869 ast_print(tree->left,outfile,indent+2);
4870 ast_print(tree->right,outfile,indent+2);
4872 /*------------------------------------------------------------------*/
4873 /*----------------------------*/
4875 /*----------------------------*/
4877 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4878 printTypeChain(tree->ftype,outfile);
4879 fprintf(outfile,")\n");
4880 ast_print(tree->left,outfile,indent+2);
4881 ast_print(tree->right,outfile,indent+2);
4883 /*------------------------------------------------------------------*/
4884 /*----------------------------*/
4886 /*----------------------------*/
4888 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4889 printTypeChain(tree->ftype,outfile);
4890 fprintf(outfile,")\n");
4891 ast_print(tree->left,outfile,indent+2);
4892 ast_print(tree->right,outfile,indent+2);
4894 /*------------------------------------------------------------------*/
4895 /*----------------------------*/
4896 /* straight assignemnt */
4897 /*----------------------------*/
4899 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4900 printTypeChain(tree->ftype,outfile);
4901 fprintf(outfile,")\n");
4902 ast_print(tree->left,outfile,indent+2);
4903 ast_print(tree->right,outfile,indent+2);
4905 /*------------------------------------------------------------------*/
4906 /*----------------------------*/
4907 /* comma operator */
4908 /*----------------------------*/
4910 fprintf(outfile,"COMMA(,) (%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);
4916 /*------------------------------------------------------------------*/
4917 /*----------------------------*/
4919 /*----------------------------*/
4922 fprintf(outfile,"CALL (%p) type (",tree);
4923 printTypeChain(tree->ftype,outfile);
4924 fprintf(outfile,")\n");
4925 ast_print(tree->left,outfile,indent+2);
4926 ast_print(tree->right,outfile,indent+2);
4929 fprintf(outfile,"PARMS\n");
4930 ast_print(tree->left,outfile,indent+2);
4931 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4932 ast_print(tree->right,outfile,indent+2);
4935 /*------------------------------------------------------------------*/
4936 /*----------------------------*/
4937 /* return statement */
4938 /*----------------------------*/
4940 fprintf(outfile,"RETURN (%p) type (",tree);
4941 printTypeChain(tree->right->ftype,outfile);
4942 fprintf(outfile,")\n");
4943 ast_print(tree->right,outfile,indent+2);
4945 /*------------------------------------------------------------------*/
4946 /*----------------------------*/
4947 /* label statement */
4948 /*----------------------------*/
4950 fprintf(outfile,"LABEL (%p)\n",tree);
4951 ast_print(tree->left,outfile,indent+2);
4952 ast_print(tree->right,outfile,indent);
4954 /*------------------------------------------------------------------*/
4955 /*----------------------------*/
4956 /* switch statement */
4957 /*----------------------------*/
4961 fprintf(outfile,"SWITCH (%p) ",tree);
4962 ast_print(tree->left,outfile,0);
4963 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4964 INDENT(indent+2,outfile);
4965 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4966 (int) floatFromVal(val),
4967 tree->values.switchVals.swNum,
4968 (int) floatFromVal(val));
4970 ast_print(tree->right,outfile,indent);
4973 /*------------------------------------------------------------------*/
4974 /*----------------------------*/
4976 /*----------------------------*/
4978 fprintf(outfile,"IF (%p) \n",tree);
4979 ast_print(tree->left,outfile,indent+2);
4980 if (tree->trueLabel) {
4981 INDENT(indent,outfile);
4982 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4984 if (tree->falseLabel) {
4985 INDENT(indent,outfile);
4986 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4988 ast_print(tree->right,outfile,indent+2);
4990 /*------------------------------------------------------------------*/
4991 /*----------------------------*/
4993 /*----------------------------*/
4995 fprintf(outfile,"FOR (%p) \n",tree);
4996 if (AST_FOR( tree, initExpr)) {
4997 INDENT(indent+2,outfile);
4998 fprintf(outfile,"INIT EXPR ");
4999 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5001 if (AST_FOR( tree, condExpr)) {
5002 INDENT(indent+2,outfile);
5003 fprintf(outfile,"COND EXPR ");
5004 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5006 if (AST_FOR( tree, loopExpr)) {
5007 INDENT(indent+2,outfile);
5008 fprintf(outfile,"LOOP EXPR ");
5009 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5011 fprintf(outfile,"FOR LOOP BODY \n");
5012 ast_print(tree->left,outfile,indent+2);
5021 ast_print(t,stdout,0);