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));
2029 /* adjust the storage class */
2030 switch (DCL_TYPE(tree->left->ftype)) {
2034 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2037 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2042 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2045 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2048 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2057 /*------------------------------------------------------------------*/
2058 /*----------------------------*/
2059 /* ++/-- operation */
2060 /*----------------------------*/
2061 case INC_OP: /* incerement operator unary so left only */
2064 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2065 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2066 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2067 werror (E_CODE_WRITE, "++/--");
2076 /*------------------------------------------------------------------*/
2077 /*----------------------------*/
2079 /*----------------------------*/
2080 case '&': /* can be unary */
2081 /* if right is NULL then unary operation */
2082 if (tree->right) /* not an unary operation */
2085 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2087 werror (E_BITWISE_OP);
2088 werror (W_CONTINUE, "left & right types are ");
2089 printTypeChain (LTYPE (tree), stderr);
2090 fprintf (stderr, ",");
2091 printTypeChain (RTYPE (tree), stderr);
2092 fprintf (stderr, "\n");
2093 goto errorTreeReturn;
2096 /* if they are both literal */
2097 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2099 tree->type = EX_VALUE;
2100 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2101 valFromType (RETYPE (tree)), '&');
2103 tree->right = tree->left = NULL;
2104 TETYPE (tree) = tree->opval.val->etype;
2105 TTYPE (tree) = tree->opval.val->type;
2109 /* see if this is a GETHBIT operation if yes
2112 ast *otree = optimizeGetHbit (tree);
2115 return decorateType (otree);
2119 computeType (LTYPE (tree), RTYPE (tree));
2120 TETYPE (tree) = getSpec (TTYPE (tree));
2122 LRVAL (tree) = RRVAL (tree) = 1;
2126 /*------------------------------------------------------------------*/
2127 /*----------------------------*/
2129 /*----------------------------*/
2131 p->class = DECLARATOR;
2132 /* if bit field then error */
2133 if (IS_BITVAR (tree->left->etype))
2135 werror (E_ILLEGAL_ADDR, "address of bit variable");
2136 goto errorTreeReturn;
2139 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2141 werror (E_ILLEGAL_ADDR, "address of register variable");
2142 goto errorTreeReturn;
2145 if (IS_FUNC (LTYPE (tree)))
2147 werror (E_ILLEGAL_ADDR, "address of function");
2148 goto errorTreeReturn;
2151 if (IS_LITERAL(LTYPE(tree)))
2153 werror (E_ILLEGAL_ADDR, "address of literal");
2154 goto errorTreeReturn;
2159 werror (E_LVALUE_REQUIRED, "address of");
2160 goto errorTreeReturn;
2162 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2164 DCL_TYPE (p) = CPOINTER;
2165 DCL_PTR_CONST (p) = port->mem.code_ro;
2167 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2168 DCL_TYPE (p) = FPOINTER;
2169 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2170 DCL_TYPE (p) = PPOINTER;
2171 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2172 DCL_TYPE (p) = IPOINTER;
2173 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2174 DCL_TYPE (p) = EEPPOINTER;
2175 else if (SPEC_OCLS(tree->left->etype))
2176 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2178 DCL_TYPE (p) = POINTER;
2180 if (IS_AST_SYM_VALUE (tree->left))
2182 AST_SYMBOL (tree->left)->addrtaken = 1;
2183 AST_SYMBOL (tree->left)->allocreq = 1;
2186 p->next = LTYPE (tree);
2188 TETYPE (tree) = getSpec (TTYPE (tree));
2189 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2190 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2195 /*------------------------------------------------------------------*/
2196 /*----------------------------*/
2198 /*----------------------------*/
2200 /* if the rewrite succeeds then don't go any furthur */
2202 ast *wtree = optimizeRRCRLC (tree);
2204 return decorateType (wtree);
2206 /*------------------------------------------------------------------*/
2207 /*----------------------------*/
2209 /*----------------------------*/
2211 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2213 werror (E_BITWISE_OP);
2214 werror (W_CONTINUE, "left & right types are ");
2215 printTypeChain (LTYPE (tree), stderr);
2216 fprintf (stderr, ",");
2217 printTypeChain (RTYPE (tree), stderr);
2218 fprintf (stderr, "\n");
2219 goto errorTreeReturn;
2222 /* if they are both literal then */
2223 /* rewrite the tree */
2224 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2226 tree->type = EX_VALUE;
2227 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2228 valFromType (RETYPE (tree)),
2230 tree->right = tree->left = NULL;
2231 TETYPE (tree) = tree->opval.val->etype;
2232 TTYPE (tree) = tree->opval.val->type;
2235 LRVAL (tree) = RRVAL (tree) = 1;
2236 TETYPE (tree) = getSpec (TTYPE (tree) =
2237 computeType (LTYPE (tree),
2240 /*------------------------------------------------------------------*/
2241 /*----------------------------*/
2243 /*----------------------------*/
2245 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2247 werror (E_INVALID_OP, "divide");
2248 goto errorTreeReturn;
2250 /* if they are both literal then */
2251 /* rewrite the tree */
2252 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2254 tree->type = EX_VALUE;
2255 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2256 valFromType (RETYPE (tree)));
2257 tree->right = tree->left = NULL;
2258 TETYPE (tree) = getSpec (TTYPE (tree) =
2259 tree->opval.val->type);
2262 LRVAL (tree) = RRVAL (tree) = 1;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 computeType (LTYPE (tree),
2268 /*------------------------------------------------------------------*/
2269 /*----------------------------*/
2271 /*----------------------------*/
2273 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2275 werror (E_BITWISE_OP);
2276 werror (W_CONTINUE, "left & right types are ");
2277 printTypeChain (LTYPE (tree), stderr);
2278 fprintf (stderr, ",");
2279 printTypeChain (RTYPE (tree), stderr);
2280 fprintf (stderr, "\n");
2281 goto errorTreeReturn;
2283 /* if they are both literal then */
2284 /* rewrite the tree */
2285 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2287 tree->type = EX_VALUE;
2288 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2289 valFromType (RETYPE (tree)));
2290 tree->right = tree->left = NULL;
2291 TETYPE (tree) = getSpec (TTYPE (tree) =
2292 tree->opval.val->type);
2295 LRVAL (tree) = RRVAL (tree) = 1;
2296 TETYPE (tree) = getSpec (TTYPE (tree) =
2297 computeType (LTYPE (tree),
2301 /*------------------------------------------------------------------*/
2302 /*----------------------------*/
2303 /* address dereference */
2304 /*----------------------------*/
2305 case '*': /* can be unary : if right is null then unary operation */
2308 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2310 werror (E_PTR_REQD);
2311 goto errorTreeReturn;
2316 werror (E_LVALUE_REQUIRED, "pointer deref");
2317 goto errorTreeReturn;
2319 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2320 LTYPE (tree)->next : NULL);
2321 TETYPE (tree) = getSpec (TTYPE (tree));
2322 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2326 /*------------------------------------------------------------------*/
2327 /*----------------------------*/
2328 /* multiplication */
2329 /*----------------------------*/
2330 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2332 werror (E_INVALID_OP, "multiplication");
2333 goto errorTreeReturn;
2336 /* if they are both literal then */
2337 /* rewrite the tree */
2338 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2340 tree->type = EX_VALUE;
2341 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2342 valFromType (RETYPE (tree)));
2343 tree->right = tree->left = NULL;
2344 TETYPE (tree) = getSpec (TTYPE (tree) =
2345 tree->opval.val->type);
2349 /* if left is a literal exchange left & right */
2350 if (IS_LITERAL (LTYPE (tree)))
2352 ast *tTree = tree->left;
2353 tree->left = tree->right;
2354 tree->right = tTree;
2357 LRVAL (tree) = RRVAL (tree) = 1;
2358 /* promote result to int if left & right are char
2359 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2360 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2361 TETYPE (tree) = getSpec (TTYPE (tree) =
2362 computeType (LTYPE (tree),
2364 SPEC_NOUN(TETYPE(tree)) = V_INT;
2366 TETYPE (tree) = getSpec (TTYPE (tree) =
2367 computeType (LTYPE (tree),
2372 /*------------------------------------------------------------------*/
2373 /*----------------------------*/
2374 /* unary '+' operator */
2375 /*----------------------------*/
2380 if (!IS_INTEGRAL (LTYPE (tree)))
2382 werror (E_UNARY_OP, '+');
2383 goto errorTreeReturn;
2386 /* if left is a literal then do it */
2387 if (IS_LITERAL (LTYPE (tree)))
2389 tree->type = EX_VALUE;
2390 tree->opval.val = valFromType (LETYPE (tree));
2392 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2396 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2400 /*------------------------------------------------------------------*/
2401 /*----------------------------*/
2403 /*----------------------------*/
2405 /* this is not a unary operation */
2406 /* if both pointers then problem */
2407 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2408 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2410 werror (E_PTR_PLUS_PTR);
2411 goto errorTreeReturn;
2414 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2415 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2417 werror (E_PLUS_INVALID, "+");
2418 goto errorTreeReturn;
2421 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2422 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2424 werror (E_PLUS_INVALID, "+");
2425 goto errorTreeReturn;
2427 /* if they are both literal then */
2428 /* rewrite the tree */
2429 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2431 tree->type = EX_VALUE;
2432 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2433 valFromType (RETYPE (tree)));
2434 tree->right = tree->left = NULL;
2435 TETYPE (tree) = getSpec (TTYPE (tree) =
2436 tree->opval.val->type);
2440 /* if the right is a pointer or left is a literal
2441 xchange left & right */
2442 if (IS_ARRAY (RTYPE (tree)) ||
2443 IS_PTR (RTYPE (tree)) ||
2444 IS_LITERAL (LTYPE (tree)))
2446 ast *tTree = tree->left;
2447 tree->left = tree->right;
2448 tree->right = tTree;
2451 LRVAL (tree) = RRVAL (tree) = 1;
2452 /* if the left is a pointer */
2453 if (IS_PTR (LTYPE (tree)))
2454 TETYPE (tree) = getSpec (TTYPE (tree) =
2457 TETYPE (tree) = getSpec (TTYPE (tree) =
2458 computeType (LTYPE (tree),
2462 /*------------------------------------------------------------------*/
2463 /*----------------------------*/
2465 /*----------------------------*/
2466 case '-': /* can be unary */
2467 /* if right is null then unary */
2471 if (!IS_ARITHMETIC (LTYPE (tree)))
2473 werror (E_UNARY_OP, tree->opval.op);
2474 goto errorTreeReturn;
2477 /* if left is a literal then do it */
2478 if (IS_LITERAL (LTYPE (tree)))
2480 tree->type = EX_VALUE;
2481 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2483 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2484 SPEC_USIGN(TETYPE(tree)) = 0;
2488 TTYPE (tree) = LTYPE (tree);
2492 /*------------------------------------------------------------------*/
2493 /*----------------------------*/
2495 /*----------------------------*/
2497 if (!(IS_PTR (LTYPE (tree)) ||
2498 IS_ARRAY (LTYPE (tree)) ||
2499 IS_ARITHMETIC (LTYPE (tree))))
2501 werror (E_PLUS_INVALID, "-");
2502 goto errorTreeReturn;
2505 if (!(IS_PTR (RTYPE (tree)) ||
2506 IS_ARRAY (RTYPE (tree)) ||
2507 IS_ARITHMETIC (RTYPE (tree))))
2509 werror (E_PLUS_INVALID, "-");
2510 goto errorTreeReturn;
2513 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2514 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2515 IS_INTEGRAL (RTYPE (tree))))
2517 werror (E_PLUS_INVALID, "-");
2518 goto errorTreeReturn;
2521 /* if they are both literal then */
2522 /* rewrite the tree */
2523 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2525 tree->type = EX_VALUE;
2526 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2527 valFromType (RETYPE (tree)));
2528 tree->right = tree->left = NULL;
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 tree->opval.val->type);
2534 /* if the left & right are equal then zero */
2535 if (isAstEqual (tree->left, tree->right))
2537 tree->type = EX_VALUE;
2538 tree->left = tree->right = NULL;
2539 tree->opval.val = constVal ("0");
2540 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2544 /* if both of them are pointers or arrays then */
2545 /* the result is going to be an integer */
2546 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2547 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2548 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2550 /* if only the left is a pointer */
2551 /* then result is a pointer */
2552 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2553 TETYPE (tree) = getSpec (TTYPE (tree) =
2556 TETYPE (tree) = getSpec (TTYPE (tree) =
2557 computeType (LTYPE (tree),
2559 LRVAL (tree) = RRVAL (tree) = 1;
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2565 /*----------------------------*/
2567 /* can be only integral type */
2568 if (!IS_INTEGRAL (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 = valComplement (valFromType (LETYPE (tree)));
2580 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2584 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2587 /*------------------------------------------------------------------*/
2588 /*----------------------------*/
2590 /*----------------------------*/
2592 /* can be pointer */
2593 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2594 !IS_PTR (LTYPE (tree)) &&
2595 !IS_ARRAY (LTYPE (tree)))
2597 werror (E_UNARY_OP, tree->opval.op);
2598 goto errorTreeReturn;
2601 /* if left is a literal then do it */
2602 if (IS_LITERAL (LTYPE (tree)))
2604 tree->type = EX_VALUE;
2605 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2607 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2611 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2614 /*------------------------------------------------------------------*/
2615 /*----------------------------*/
2617 /*----------------------------*/
2620 TTYPE (tree) = LTYPE (tree);
2621 TETYPE (tree) = LETYPE (tree);
2625 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2630 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2632 werror (E_SHIFT_OP_INVALID);
2633 werror (W_CONTINUE, "left & right types are ");
2634 printTypeChain (LTYPE (tree), stderr);
2635 fprintf (stderr, ",");
2636 printTypeChain (RTYPE (tree), stderr);
2637 fprintf (stderr, "\n");
2638 goto errorTreeReturn;
2641 /* if they are both literal then */
2642 /* rewrite the tree */
2643 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2645 tree->type = EX_VALUE;
2646 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2647 valFromType (RETYPE (tree)),
2648 (tree->opval.op == LEFT_OP ? 1 : 0));
2649 tree->right = tree->left = NULL;
2650 TETYPE (tree) = getSpec (TTYPE (tree) =
2651 tree->opval.val->type);
2654 /* if only the right side is a literal & we are
2655 shifting more than size of the left operand then zero */
2656 if (IS_LITERAL (RTYPE (tree)) &&
2657 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2658 (getSize (LTYPE (tree)) * 8))
2660 werror (W_SHIFT_CHANGED,
2661 (tree->opval.op == LEFT_OP ? "left" : "right"));
2662 tree->type = EX_VALUE;
2663 tree->left = tree->right = NULL;
2664 tree->opval.val = constVal ("0");
2665 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2668 LRVAL (tree) = RRVAL (tree) = 1;
2669 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2671 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2675 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2679 /*------------------------------------------------------------------*/
2680 /*----------------------------*/
2682 /*----------------------------*/
2683 case CAST: /* change the type */
2684 /* cannot cast to an aggregate type */
2685 if (IS_AGGREGATE (LTYPE (tree)))
2687 werror (E_CAST_ILLEGAL);
2688 goto errorTreeReturn;
2691 /* make sure the type is complete and sane */
2692 checkTypeSanity(LETYPE(tree), "(cast)");
2695 /* if the right is a literal replace the tree */
2696 if (IS_LITERAL (RETYPE (tree))) {
2697 if (!IS_PTR (LTYPE (tree))) {
2698 tree->type = EX_VALUE;
2700 valCastLiteral (LTYPE (tree),
2701 floatFromVal (valFromType (RETYPE (tree))));
2704 TTYPE (tree) = tree->opval.val->type;
2705 tree->values.literalFromCast = 1;
2706 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2707 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2708 sym_link *rest = LTYPE(tree)->next;
2709 werror(W_LITERAL_GENERIC);
2710 TTYPE(tree) = newLink();
2711 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2712 TTYPE(tree)->next = rest;
2713 tree->left->opval.lnk = TTYPE(tree);
2716 TTYPE (tree) = LTYPE (tree);
2720 TTYPE (tree) = LTYPE (tree);
2724 /* if pointer to struct then check names */
2725 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2726 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2727 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2728 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2730 /* if the right is a literal replace the tree */
2731 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2732 tree->type = EX_VALUE;
2734 valCastLiteral (LTYPE (tree),
2735 floatFromVal (valFromType (RETYPE (tree))));
2738 TTYPE (tree) = tree->opval.val->type;
2739 tree->values.literalFromCast = 1;
2741 TTYPE (tree) = LTYPE (tree);
2745 TETYPE (tree) = getSpec (TTYPE (tree));
2749 /*------------------------------------------------------------------*/
2750 /*----------------------------*/
2751 /* logical &&, || */
2752 /*----------------------------*/
2755 /* each must me arithmetic type or be a pointer */
2756 if (!IS_PTR (LTYPE (tree)) &&
2757 !IS_ARRAY (LTYPE (tree)) &&
2758 !IS_INTEGRAL (LTYPE (tree)))
2760 werror (E_COMPARE_OP);
2761 goto errorTreeReturn;
2764 if (!IS_PTR (RTYPE (tree)) &&
2765 !IS_ARRAY (RTYPE (tree)) &&
2766 !IS_INTEGRAL (RTYPE (tree)))
2768 werror (E_COMPARE_OP);
2769 goto errorTreeReturn;
2771 /* if they are both literal then */
2772 /* rewrite the tree */
2773 if (IS_LITERAL (RTYPE (tree)) &&
2774 IS_LITERAL (LTYPE (tree)))
2776 tree->type = EX_VALUE;
2777 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2778 valFromType (RETYPE (tree)),
2780 tree->right = tree->left = NULL;
2781 TETYPE (tree) = getSpec (TTYPE (tree) =
2782 tree->opval.val->type);
2785 LRVAL (tree) = RRVAL (tree) = 1;
2786 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2789 /*------------------------------------------------------------------*/
2790 /*----------------------------*/
2791 /* comparison operators */
2792 /*----------------------------*/
2800 ast *lt = optimizeCompare (tree);
2806 /* if they are pointers they must be castable */
2807 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2809 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2811 werror (E_COMPARE_OP);
2812 fprintf (stderr, "comparing type ");
2813 printTypeChain (LTYPE (tree), stderr);
2814 fprintf (stderr, "to type ");
2815 printTypeChain (RTYPE (tree), stderr);
2816 fprintf (stderr, "\n");
2817 goto errorTreeReturn;
2820 /* else they should be promotable to one another */
2823 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2824 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2826 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2828 werror (E_COMPARE_OP);
2829 fprintf (stderr, "comparing type ");
2830 printTypeChain (LTYPE (tree), stderr);
2831 fprintf (stderr, "to type ");
2832 printTypeChain (RTYPE (tree), stderr);
2833 fprintf (stderr, "\n");
2834 goto errorTreeReturn;
2838 /* if they are both literal then */
2839 /* rewrite the tree */
2840 if (IS_LITERAL (RTYPE (tree)) &&
2841 IS_LITERAL (LTYPE (tree)))
2843 tree->type = EX_VALUE;
2844 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2845 valFromType (RETYPE (tree)),
2847 tree->right = tree->left = NULL;
2848 TETYPE (tree) = getSpec (TTYPE (tree) =
2849 tree->opval.val->type);
2852 LRVAL (tree) = RRVAL (tree) = 1;
2853 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2856 /*------------------------------------------------------------------*/
2857 /*----------------------------*/
2859 /*----------------------------*/
2860 case SIZEOF: /* evaluate wihout code generation */
2861 /* change the type to a integer */
2862 tree->type = EX_VALUE;
2863 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2864 tree->opval.val = constVal (buffer);
2865 tree->right = tree->left = NULL;
2866 TETYPE (tree) = getSpec (TTYPE (tree) =
2867 tree->opval.val->type);
2870 /*------------------------------------------------------------------*/
2871 /*----------------------------*/
2873 /*----------------------------*/
2875 /* return typeof enum value */
2876 tree->type = EX_VALUE;
2879 if (IS_SPEC(tree->right->ftype)) {
2880 switch (SPEC_NOUN(tree->right->ftype)) {
2882 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2883 else typeofv = TYPEOF_INT;
2886 typeofv = TYPEOF_FLOAT;
2889 typeofv = TYPEOF_CHAR;
2892 typeofv = TYPEOF_VOID;
2895 typeofv = TYPEOF_STRUCT;
2898 typeofv = TYPEOF_BIT;
2901 typeofv = TYPEOF_SBIT;
2907 switch (DCL_TYPE(tree->right->ftype)) {
2909 typeofv = TYPEOF_POINTER;
2912 typeofv = TYPEOF_FPOINTER;
2915 typeofv = TYPEOF_CPOINTER;
2918 typeofv = TYPEOF_GPOINTER;
2921 typeofv = TYPEOF_PPOINTER;
2924 typeofv = TYPEOF_IPOINTER;
2927 typeofv = TYPEOF_ARRAY;
2930 typeofv = TYPEOF_FUNCTION;
2936 sprintf (buffer, "%d", typeofv);
2937 tree->opval.val = constVal (buffer);
2938 tree->right = tree->left = NULL;
2939 TETYPE (tree) = getSpec (TTYPE (tree) =
2940 tree->opval.val->type);
2943 /*------------------------------------------------------------------*/
2944 /*----------------------------*/
2945 /* conditional operator '?' */
2946 /*----------------------------*/
2948 /* the type is value of the colon operator (on the right) */
2949 assert(IS_COLON_OP(tree->right));
2950 /* if already known then replace the tree : optimizer will do it
2951 but faster to do it here */
2952 if (IS_LITERAL (LTYPE(tree))) {
2953 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2954 return decorateType(tree->right->left) ;
2956 return decorateType(tree->right->right) ;
2959 tree->right = decorateType(tree->right);
2960 TTYPE (tree) = RTYPE(tree);
2961 TETYPE (tree) = getSpec (TTYPE (tree));
2966 /* if they don't match we have a problem */
2967 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2969 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2970 goto errorTreeReturn;
2973 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2974 TETYPE (tree) = getSpec (TTYPE (tree));
2978 /*------------------------------------------------------------------*/
2979 /*----------------------------*/
2980 /* assignment operators */
2981 /*----------------------------*/
2984 /* for these it must be both must be integral */
2985 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2986 !IS_ARITHMETIC (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 /=");
3000 goto errorTreeReturn;
3011 /* for these it must be both must be integral */
3012 if (!IS_INTEGRAL (LTYPE (tree)) ||
3013 !IS_INTEGRAL (RTYPE (tree)))
3015 werror (E_OPS_INTEGRAL);
3016 goto errorTreeReturn;
3019 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3021 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3022 werror (E_CODE_WRITE, " ");
3026 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3027 goto errorTreeReturn;
3033 /*------------------------------------------------------------------*/
3034 /*----------------------------*/
3036 /*----------------------------*/
3038 if (!(IS_PTR (LTYPE (tree)) ||
3039 IS_ARITHMETIC (LTYPE (tree))))
3041 werror (E_PLUS_INVALID, "-=");
3042 goto errorTreeReturn;
3045 if (!(IS_PTR (RTYPE (tree)) ||
3046 IS_ARITHMETIC (RTYPE (tree))))
3048 werror (E_PLUS_INVALID, "-=");
3049 goto errorTreeReturn;
3052 TETYPE (tree) = getSpec (TTYPE (tree) =
3053 computeType (LTYPE (tree),
3056 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3057 werror (E_CODE_WRITE, " ");
3061 werror (E_LVALUE_REQUIRED, "-=");
3062 goto errorTreeReturn;
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3071 /*----------------------------*/
3073 /* this is not a unary operation */
3074 /* if both pointers then problem */
3075 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3077 werror (E_PTR_PLUS_PTR);
3078 goto errorTreeReturn;
3081 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3083 werror (E_PLUS_INVALID, "+=");
3084 goto errorTreeReturn;
3087 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3089 werror (E_PLUS_INVALID, "+=");
3090 goto errorTreeReturn;
3093 TETYPE (tree) = getSpec (TTYPE (tree) =
3094 computeType (LTYPE (tree),
3097 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3098 werror (E_CODE_WRITE, " ");
3102 werror (E_LVALUE_REQUIRED, "+=");
3103 goto errorTreeReturn;
3106 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3107 tree->opval.op = '=';
3111 /*------------------------------------------------------------------*/
3112 /*----------------------------*/
3113 /* straight assignemnt */
3114 /*----------------------------*/
3116 /* cannot be an aggregate */
3117 if (IS_AGGREGATE (LTYPE (tree)))
3119 werror (E_AGGR_ASSIGN);
3120 goto errorTreeReturn;
3123 /* they should either match or be castable */
3124 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3126 werror (E_TYPE_MISMATCH, "assignment", " ");
3127 fprintf (stderr, "type --> '");
3128 printTypeChain (RTYPE (tree), stderr);
3129 fprintf (stderr, "' ");
3130 fprintf (stderr, "assigned to type --> '");
3131 printTypeChain (LTYPE (tree), stderr);
3132 fprintf (stderr, "'\n");
3133 goto errorTreeReturn;
3136 /* if the left side of the tree is of type void
3137 then report error */
3138 if (IS_VOID (LTYPE (tree)))
3140 werror (E_CAST_ZERO);
3141 printFromToType(RTYPE(tree), LTYPE(tree));
3144 TETYPE (tree) = getSpec (TTYPE (tree) =
3148 if (!tree->initMode ) {
3149 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3150 werror (E_CODE_WRITE, " ");
3154 werror (E_LVALUE_REQUIRED, "=");
3155 goto errorTreeReturn;
3160 /*------------------------------------------------------------------*/
3161 /*----------------------------*/
3162 /* comma operator */
3163 /*----------------------------*/
3165 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3168 /*------------------------------------------------------------------*/
3169 /*----------------------------*/
3171 /*----------------------------*/
3175 if (processParms (tree->left,
3176 FUNC_ARGS(tree->left->ftype),
3177 tree->right, &parmNumber, TRUE)) {
3178 goto errorTreeReturn;
3181 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3182 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3184 //FUNC_ARGS(tree->left->ftype) =
3185 //reverseVal (FUNC_ARGS(tree->left->ftype));
3186 reverseParms (tree->right);
3189 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3192 /*------------------------------------------------------------------*/
3193 /*----------------------------*/
3194 /* return statement */
3195 /*----------------------------*/
3200 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3202 werror (W_RETURN_MISMATCH);
3203 printFromToType (RTYPE(tree), currFunc->type->next);
3204 goto errorTreeReturn;
3207 if (IS_VOID (currFunc->type->next)
3209 !IS_VOID (RTYPE (tree)))
3211 werror (E_FUNC_VOID);
3212 goto errorTreeReturn;
3215 /* if there is going to be a casing required then add it */
3216 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3219 decorateType (newNode (CAST,
3220 newAst_LINK (copyLinkChain (currFunc->type->next)),
3229 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3231 werror (E_VOID_FUNC, currFunc->name);
3232 goto errorTreeReturn;
3235 TTYPE (tree) = TETYPE (tree) = NULL;
3238 /*------------------------------------------------------------------*/
3239 /*----------------------------*/
3240 /* switch statement */
3241 /*----------------------------*/
3243 /* the switch value must be an integer */
3244 if (!IS_INTEGRAL (LTYPE (tree)))
3246 werror (E_SWITCH_NON_INTEGER);
3247 goto errorTreeReturn;
3250 TTYPE (tree) = TETYPE (tree) = NULL;
3253 /*------------------------------------------------------------------*/
3254 /*----------------------------*/
3256 /*----------------------------*/
3258 tree->left = backPatchLabels (tree->left,
3261 TTYPE (tree) = TETYPE (tree) = NULL;
3264 /*------------------------------------------------------------------*/
3265 /*----------------------------*/
3267 /*----------------------------*/
3270 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3271 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3272 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3274 /* if the for loop is reversible then
3275 reverse it otherwise do what we normally
3281 if (isLoopReversible (tree, &sym, &init, &end))
3282 return reverseLoop (tree, sym, init, end);
3284 return decorateType (createFor (AST_FOR (tree, trueLabel),
3285 AST_FOR (tree, continueLabel),
3286 AST_FOR (tree, falseLabel),
3287 AST_FOR (tree, condLabel),
3288 AST_FOR (tree, initExpr),
3289 AST_FOR (tree, condExpr),
3290 AST_FOR (tree, loopExpr),
3294 TTYPE (tree) = TETYPE (tree) = NULL;
3298 /* some error found this tree will be killed */
3300 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3301 tree->opval.op = NULLOP;
3307 /*-----------------------------------------------------------------*/
3308 /* sizeofOp - processes size of operation */
3309 /*-----------------------------------------------------------------*/
3311 sizeofOp (sym_link * type)
3315 /* make sure the type is complete and sane */
3316 checkTypeSanity(type, "(sizeof)");
3318 /* get the size and convert it to character */
3319 sprintf (buff, "%d", getSize (type));
3321 /* now convert into value */
3322 return constVal (buff);
3326 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3327 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3328 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3329 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3330 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3331 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3332 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3334 /*-----------------------------------------------------------------*/
3335 /* backPatchLabels - change and or not operators to flow control */
3336 /*-----------------------------------------------------------------*/
3338 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3344 if (!(IS_ANDORNOT (tree)))
3347 /* if this an and */
3350 static int localLbl = 0;
3353 sprintf (buffer, "_and_%d", localLbl++);
3354 localLabel = newSymbol (buffer, NestLevel);
3356 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3358 /* if left is already a IFX then just change the if true label in that */
3359 if (!IS_IFX (tree->left))
3360 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3362 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3363 /* right is a IFX then just join */
3364 if (IS_IFX (tree->right))
3365 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3367 tree->right = createLabel (localLabel, tree->right);
3368 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3370 return newNode (NULLOP, tree->left, tree->right);
3373 /* if this is an or operation */
3376 static int localLbl = 0;
3379 sprintf (buffer, "_or_%d", localLbl++);
3380 localLabel = newSymbol (buffer, NestLevel);
3382 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3384 /* if left is already a IFX then just change the if true label in that */
3385 if (!IS_IFX (tree->left))
3386 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3388 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3389 /* right is a IFX then just join */
3390 if (IS_IFX (tree->right))
3391 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3393 tree->right = createLabel (localLabel, tree->right);
3394 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3396 return newNode (NULLOP, tree->left, tree->right);
3402 int wasnot = IS_NOT (tree->left);
3403 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3405 /* if the left is already a IFX */
3406 if (!IS_IFX (tree->left))
3407 tree->left = newNode (IFX, tree->left, NULL);
3411 tree->left->trueLabel = trueLabel;
3412 tree->left->falseLabel = falseLabel;
3416 tree->left->trueLabel = falseLabel;
3417 tree->left->falseLabel = trueLabel;
3424 tree->trueLabel = trueLabel;
3425 tree->falseLabel = falseLabel;
3432 /*-----------------------------------------------------------------*/
3433 /* createBlock - create expression tree for block */
3434 /*-----------------------------------------------------------------*/
3436 createBlock (symbol * decl, ast * body)
3440 /* if the block has nothing */
3444 ex = newNode (BLOCK, NULL, body);
3445 ex->values.sym = decl;
3447 ex->right = ex->right;
3453 /*-----------------------------------------------------------------*/
3454 /* createLabel - creates the expression tree for labels */
3455 /*-----------------------------------------------------------------*/
3457 createLabel (symbol * label, ast * stmnt)
3460 char name[SDCC_NAME_MAX + 1];
3463 /* must create fresh symbol if the symbol name */
3464 /* exists in the symbol table, since there can */
3465 /* be a variable with the same name as the labl */
3466 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3467 (csym->level == label->level))
3468 label = newSymbol (label->name, label->level);
3470 /* change the name before putting it in add _ */
3471 sprintf (name, "%s", label->name);
3473 /* put the label in the LabelSymbol table */
3474 /* but first check if a label of the same */
3476 if ((csym = findSym (LabelTab, NULL, name)))
3477 werror (E_DUPLICATE_LABEL, label->name);
3479 addSym (LabelTab, label, name, label->level, 0, 0);
3482 label->key = labelKey++;
3483 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3489 /*-----------------------------------------------------------------*/
3490 /* createCase - generates the parsetree for a case statement */
3491 /*-----------------------------------------------------------------*/
3493 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3495 char caseLbl[SDCC_NAME_MAX + 1];
3499 /* if the switch statement does not exist */
3500 /* then case is out of context */
3503 werror (E_CASE_CONTEXT);
3507 caseVal = decorateType (resolveSymbols (caseVal));
3508 /* if not a constant then error */
3509 if (!IS_LITERAL (caseVal->ftype))
3511 werror (E_CASE_CONSTANT);
3515 /* if not a integer than error */
3516 if (!IS_INTEGRAL (caseVal->ftype))
3518 werror (E_CASE_NON_INTEGER);
3522 /* find the end of the switch values chain */
3523 if (!(val = swStat->values.switchVals.swVals))
3524 swStat->values.switchVals.swVals = caseVal->opval.val;
3527 /* also order the cases according to value */
3529 int cVal = (int) floatFromVal (caseVal->opval.val);
3530 while (val && (int) floatFromVal (val) < cVal)
3536 /* if we reached the end then */
3539 pval->next = caseVal->opval.val;
3543 /* we found a value greater than */
3544 /* the current value we must add this */
3545 /* before the value */
3546 caseVal->opval.val->next = val;
3548 /* if this was the first in chain */
3549 if (swStat->values.switchVals.swVals == val)
3550 swStat->values.switchVals.swVals =
3553 pval->next = caseVal->opval.val;
3558 /* create the case label */
3559 sprintf (caseLbl, "_case_%d_%d",
3560 swStat->values.switchVals.swNum,
3561 (int) floatFromVal (caseVal->opval.val));
3563 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3568 /*-----------------------------------------------------------------*/
3569 /* createDefault - creates the parse tree for the default statement */
3570 /*-----------------------------------------------------------------*/
3572 createDefault (ast * swStat, ast * stmnt)
3574 char defLbl[SDCC_NAME_MAX + 1];
3576 /* if the switch statement does not exist */
3577 /* then case is out of context */
3580 werror (E_CASE_CONTEXT);
3584 /* turn on the default flag */
3585 swStat->values.switchVals.swDefault = 1;
3587 /* create the label */
3588 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3589 return createLabel (newSymbol (defLbl, 0), stmnt);
3592 /*-----------------------------------------------------------------*/
3593 /* createIf - creates the parsetree for the if statement */
3594 /*-----------------------------------------------------------------*/
3596 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3598 static int Lblnum = 0;
3600 symbol *ifTrue, *ifFalse, *ifEnd;
3602 /* if neither exists */
3603 if (!elseBody && !ifBody) {
3604 // if there are no side effects (i++, j() etc)
3605 if (!hasSEFcalls(condAst)) {
3610 /* create the labels */
3611 sprintf (buffer, "_iffalse_%d", Lblnum);
3612 ifFalse = newSymbol (buffer, NestLevel);
3613 /* if no else body then end == false */
3618 sprintf (buffer, "_ifend_%d", Lblnum);
3619 ifEnd = newSymbol (buffer, NestLevel);
3622 sprintf (buffer, "_iftrue_%d", Lblnum);
3623 ifTrue = newSymbol (buffer, NestLevel);
3627 /* attach the ifTrue label to the top of it body */
3628 ifBody = createLabel (ifTrue, ifBody);
3629 /* attach a goto end to the ifBody if else is present */
3632 ifBody = newNode (NULLOP, ifBody,
3634 newAst_VALUE (symbolVal (ifEnd)),
3636 /* put the elseLabel on the else body */
3637 elseBody = createLabel (ifFalse, elseBody);
3638 /* out the end at the end of the body */
3639 elseBody = newNode (NULLOP,
3641 createLabel (ifEnd, NULL));
3645 ifBody = newNode (NULLOP, ifBody,
3646 createLabel (ifFalse, NULL));
3648 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3649 if (IS_IFX (condAst))
3652 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3654 return newNode (NULLOP, ifTree,
3655 newNode (NULLOP, ifBody, elseBody));
3659 /*-----------------------------------------------------------------*/
3660 /* createDo - creates parse tree for do */
3663 /* _docontinue_n: */
3664 /* condition_expression +-> trueLabel -> _dobody_n */
3666 /* +-> falseLabel-> _dobreak_n */
3668 /*-----------------------------------------------------------------*/
3670 createDo (symbol * trueLabel, symbol * continueLabel,
3671 symbol * falseLabel, ast * condAst, ast * doBody)
3676 /* if the body does not exist then it is simple */
3679 condAst = backPatchLabels (condAst, continueLabel, NULL);
3680 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3681 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3682 doTree->trueLabel = continueLabel;
3683 doTree->falseLabel = NULL;
3687 /* otherwise we have a body */
3688 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3690 /* attach the body label to the top */
3691 doBody = createLabel (trueLabel, doBody);
3692 /* attach the continue label to end of body */
3693 doBody = newNode (NULLOP, doBody,
3694 createLabel (continueLabel, NULL));
3696 /* now put the break label at the end */
3697 if (IS_IFX (condAst))
3700 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3702 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3704 /* putting it together */
3705 return newNode (NULLOP, doBody, doTree);
3708 /*-----------------------------------------------------------------*/
3709 /* createFor - creates parse tree for 'for' statement */
3712 /* condExpr +-> trueLabel -> _forbody_n */
3714 /* +-> falseLabel-> _forbreak_n */
3717 /* _forcontinue_n: */
3719 /* goto _forcond_n ; */
3721 /*-----------------------------------------------------------------*/
3723 createFor (symbol * trueLabel, symbol * continueLabel,
3724 symbol * falseLabel, symbol * condLabel,
3725 ast * initExpr, ast * condExpr, ast * loopExpr,
3730 /* if loopexpression not present then we can generate it */
3731 /* the same way as a while */
3733 return newNode (NULLOP, initExpr,
3734 createWhile (trueLabel, continueLabel,
3735 falseLabel, condExpr, forBody));
3736 /* vanilla for statement */
3737 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3739 if (condExpr && !IS_IFX (condExpr))
3740 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3743 /* attach condition label to condition */
3744 condExpr = createLabel (condLabel, condExpr);
3746 /* attach body label to body */
3747 forBody = createLabel (trueLabel, forBody);
3749 /* attach continue to forLoop expression & attach */
3750 /* goto the forcond @ and of loopExpression */
3751 loopExpr = createLabel (continueLabel,
3755 newAst_VALUE (symbolVal (condLabel)),
3757 /* now start putting them together */
3758 forTree = newNode (NULLOP, initExpr, condExpr);
3759 forTree = newNode (NULLOP, forTree, forBody);
3760 forTree = newNode (NULLOP, forTree, loopExpr);
3761 /* finally add the break label */
3762 forTree = newNode (NULLOP, forTree,
3763 createLabel (falseLabel, NULL));
3767 /*-----------------------------------------------------------------*/
3768 /* createWhile - creates parse tree for while statement */
3769 /* the while statement will be created as follows */
3771 /* _while_continue_n: */
3772 /* condition_expression +-> trueLabel -> _while_boby_n */
3774 /* +-> falseLabel -> _while_break_n */
3775 /* _while_body_n: */
3777 /* goto _while_continue_n */
3778 /* _while_break_n: */
3779 /*-----------------------------------------------------------------*/
3781 createWhile (symbol * trueLabel, symbol * continueLabel,
3782 symbol * falseLabel, ast * condExpr, ast * whileBody)
3786 /* put the continue label */
3787 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3788 condExpr = createLabel (continueLabel, condExpr);
3789 condExpr->lineno = 0;
3791 /* put the body label in front of the body */
3792 whileBody = createLabel (trueLabel, whileBody);
3793 whileBody->lineno = 0;
3794 /* put a jump to continue at the end of the body */
3795 /* and put break label at the end of the body */
3796 whileBody = newNode (NULLOP,
3799 newAst_VALUE (symbolVal (continueLabel)),
3800 createLabel (falseLabel, NULL)));
3802 /* put it all together */
3803 if (IS_IFX (condExpr))
3804 whileTree = condExpr;
3807 whileTree = newNode (IFX, condExpr, NULL);
3808 /* put the true & false labels in place */
3809 whileTree->trueLabel = trueLabel;
3810 whileTree->falseLabel = falseLabel;
3813 return newNode (NULLOP, whileTree, whileBody);
3816 /*-----------------------------------------------------------------*/
3817 /* optimizeGetHbit - get highest order bit of the expression */
3818 /*-----------------------------------------------------------------*/
3820 optimizeGetHbit (ast * tree)
3823 /* if this is not a bit and */
3824 if (!IS_BITAND (tree))
3827 /* will look for tree of the form
3828 ( expr >> ((sizeof expr) -1) ) & 1 */
3829 if (!IS_AST_LIT_VALUE (tree->right))
3832 if (AST_LIT_VALUE (tree->right) != 1)
3835 if (!IS_RIGHT_OP (tree->left))
3838 if (!IS_AST_LIT_VALUE (tree->left->right))
3841 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3842 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3845 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3849 /*-----------------------------------------------------------------*/
3850 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3851 /*-----------------------------------------------------------------*/
3853 optimizeRRCRLC (ast * root)
3855 /* will look for trees of the form
3856 (?expr << 1) | (?expr >> 7) or
3857 (?expr >> 7) | (?expr << 1) will make that
3858 into a RLC : operation ..
3860 (?expr >> 1) | (?expr << 7) or
3861 (?expr << 7) | (?expr >> 1) will make that
3862 into a RRC operation
3863 note : by 7 I mean (number of bits required to hold the
3865 /* if the root operations is not a | operation the not */
3866 if (!IS_BITOR (root))
3869 /* I have to think of a better way to match patterns this sucks */
3870 /* that aside let start looking for the first case : I use a the
3871 negative check a lot to improve the efficiency */
3872 /* (?expr << 1) | (?expr >> 7) */
3873 if (IS_LEFT_OP (root->left) &&
3874 IS_RIGHT_OP (root->right))
3877 if (!SPEC_USIGN (TETYPE (root->left->left)))
3880 if (!IS_AST_LIT_VALUE (root->left->right) ||
3881 !IS_AST_LIT_VALUE (root->right->right))
3884 /* make sure it is the same expression */
3885 if (!isAstEqual (root->left->left,
3889 if (AST_LIT_VALUE (root->left->right) != 1)
3892 if (AST_LIT_VALUE (root->right->right) !=
3893 (getSize (TTYPE (root->left->left)) * 8 - 1))
3896 /* whew got the first case : create the AST */
3897 return newNode (RLC, root->left->left, NULL);
3901 /* check for second case */
3902 /* (?expr >> 7) | (?expr << 1) */
3903 if (IS_LEFT_OP (root->right) &&
3904 IS_RIGHT_OP (root->left))
3907 if (!SPEC_USIGN (TETYPE (root->left->left)))
3910 if (!IS_AST_LIT_VALUE (root->left->right) ||
3911 !IS_AST_LIT_VALUE (root->right->right))
3914 /* make sure it is the same symbol */
3915 if (!isAstEqual (root->left->left,
3919 if (AST_LIT_VALUE (root->right->right) != 1)
3922 if (AST_LIT_VALUE (root->left->right) !=
3923 (getSize (TTYPE (root->left->left)) * 8 - 1))
3926 /* whew got the first case : create the AST */
3927 return newNode (RLC, root->left->left, NULL);
3932 /* third case for RRC */
3933 /* (?symbol >> 1) | (?symbol << 7) */
3934 if (IS_LEFT_OP (root->right) &&
3935 IS_RIGHT_OP (root->left))
3938 if (!SPEC_USIGN (TETYPE (root->left->left)))
3941 if (!IS_AST_LIT_VALUE (root->left->right) ||
3942 !IS_AST_LIT_VALUE (root->right->right))
3945 /* make sure it is the same symbol */
3946 if (!isAstEqual (root->left->left,
3950 if (AST_LIT_VALUE (root->left->right) != 1)
3953 if (AST_LIT_VALUE (root->right->right) !=
3954 (getSize (TTYPE (root->left->left)) * 8 - 1))
3957 /* whew got the first case : create the AST */
3958 return newNode (RRC, root->left->left, NULL);
3962 /* fourth and last case for now */
3963 /* (?symbol << 7) | (?symbol >> 1) */
3964 if (IS_RIGHT_OP (root->right) &&
3965 IS_LEFT_OP (root->left))
3968 if (!SPEC_USIGN (TETYPE (root->left->left)))
3971 if (!IS_AST_LIT_VALUE (root->left->right) ||
3972 !IS_AST_LIT_VALUE (root->right->right))
3975 /* make sure it is the same symbol */
3976 if (!isAstEqual (root->left->left,
3980 if (AST_LIT_VALUE (root->right->right) != 1)
3983 if (AST_LIT_VALUE (root->left->right) !=
3984 (getSize (TTYPE (root->left->left)) * 8 - 1))
3987 /* whew got the first case : create the AST */
3988 return newNode (RRC, root->left->left, NULL);
3992 /* not found return root */
3996 /*-----------------------------------------------------------------*/
3997 /* optimizeCompare - otimizes compares for bit variables */
3998 /*-----------------------------------------------------------------*/
4000 optimizeCompare (ast * root)
4002 ast *optExpr = NULL;
4005 unsigned int litValue;
4007 /* if nothing then return nothing */
4011 /* if not a compare op then do leaves */
4012 if (!IS_COMPARE_OP (root))
4014 root->left = optimizeCompare (root->left);
4015 root->right = optimizeCompare (root->right);
4019 /* if left & right are the same then depending
4020 of the operation do */
4021 if (isAstEqual (root->left, root->right))
4023 switch (root->opval.op)
4028 optExpr = newAst_VALUE (constVal ("0"));
4033 optExpr = newAst_VALUE (constVal ("1"));
4037 return decorateType (optExpr);
4040 vleft = (root->left->type == EX_VALUE ?
4041 root->left->opval.val : NULL);
4043 vright = (root->right->type == EX_VALUE ?
4044 root->right->opval.val : NULL);
4046 //#define EXPERIMENTAL
4048 /* if left is unsigned and right is literal */
4049 if (vleft && vright &&
4050 IS_UNSIGNED(vleft->etype) &&
4051 IS_LITERAL(vright->etype)) {
4052 double dval=floatFromVal(vright);
4053 int op=root->opval.op;
4055 fprintf (stderr,"op: '");
4057 case LE_OP: fprintf (stderr, "<= '"); break;
4058 case EQ_OP: fprintf (stderr, "== '"); break;
4059 case GE_OP: fprintf (stderr, ">= '"); break;
4060 default: fprintf (stderr, "%c '", op); break;
4062 fprintf (stderr, "%f\n", dval);
4069 if (dval<0 || (op=='<' && dval==0)) {
4070 // unsigned is never < 0
4071 werror (W_IF_NEVER_TRUE);
4072 optExpr = newAst_VALUE (constVal("0"));
4073 return decorateType (optExpr);
4077 // change this into a cheaper EQ_OP
4078 fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
4079 root->opval.op=EQ_OP;
4086 if (dval>0 || (op==GE_OP && dval==0)) {
4087 // unsigned is never < 0
4088 werror (W_IF_ALWAYS_TRUE);
4089 optExpr = newAst_VALUE (constVal("1"));
4090 return decorateType (optExpr);
4094 // change this into a cheaper reversed EQ_OP
4095 fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
4096 root->opval.op=EQ_OP;
4103 /* if left is a BITVAR in BITSPACE */
4104 /* and right is a LITERAL then opt- */
4105 /* imize else do nothing */
4106 if (vleft && vright &&
4107 IS_BITVAR (vleft->etype) &&
4108 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4109 IS_LITERAL (vright->etype))
4112 /* if right side > 1 then comparison may never succeed */
4113 if ((litValue = (int) floatFromVal (vright)) > 1)
4115 werror (W_BAD_COMPARE);
4121 switch (root->opval.op)
4123 case '>': /* bit value greater than 1 cannot be */
4124 werror (W_BAD_COMPARE);
4128 case '<': /* bit value < 1 means 0 */
4130 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4133 case LE_OP: /* bit value <= 1 means no check */
4134 optExpr = newAst_VALUE (vright);
4137 case GE_OP: /* bit value >= 1 means only check for = */
4139 optExpr = newAst_VALUE (vleft);
4144 { /* literal is zero */
4145 switch (root->opval.op)
4147 case '<': /* bit value < 0 cannot be */
4148 werror (W_BAD_COMPARE);
4152 case '>': /* bit value > 0 means 1 */
4154 optExpr = newAst_VALUE (vleft);
4157 case LE_OP: /* bit value <= 0 means no check */
4158 case GE_OP: /* bit value >= 0 means no check */
4159 werror (W_BAD_COMPARE);
4163 case EQ_OP: /* bit == 0 means ! of bit */
4164 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4168 return decorateType (resolveSymbols (optExpr));
4169 } /* end-of-if of BITVAR */
4174 /*-----------------------------------------------------------------*/
4175 /* addSymToBlock : adds the symbol to the first block we find */
4176 /*-----------------------------------------------------------------*/
4178 addSymToBlock (symbol * sym, ast * tree)
4180 /* reached end of tree or a leaf */
4181 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4185 if (IS_AST_OP (tree) &&
4186 tree->opval.op == BLOCK)
4189 symbol *lsym = copySymbol (sym);
4191 lsym->next = AST_VALUES (tree, sym);
4192 AST_VALUES (tree, sym) = lsym;
4196 addSymToBlock (sym, tree->left);
4197 addSymToBlock (sym, tree->right);
4200 /*-----------------------------------------------------------------*/
4201 /* processRegParms - do processing for register parameters */
4202 /*-----------------------------------------------------------------*/
4204 processRegParms (value * args, ast * body)
4208 if (IS_REGPARM (args->etype))
4209 addSymToBlock (args->sym, body);
4214 /*-----------------------------------------------------------------*/
4215 /* resetParmKey - resets the operandkeys for the symbols */
4216 /*-----------------------------------------------------------------*/
4217 DEFSETFUNC (resetParmKey)
4228 /*-----------------------------------------------------------------*/
4229 /* createFunction - This is the key node that calls the iCode for */
4230 /* generating the code for a function. Note code */
4231 /* is generated function by function, later when */
4232 /* add inter-procedural analysis this will change */
4233 /*-----------------------------------------------------------------*/
4235 createFunction (symbol * name, ast * body)
4241 iCode *piCode = NULL;
4243 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4244 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4246 /* if check function return 0 then some problem */
4247 if (checkFunction (name, NULL) == 0)
4250 /* create a dummy block if none exists */
4252 body = newNode (BLOCK, NULL, NULL);
4256 /* check if the function name already in the symbol table */
4257 if ((csym = findSym (SymbolTab, NULL, name->name)))
4260 /* special case for compiler defined functions
4261 we need to add the name to the publics list : this
4262 actually means we are now compiling the compiler
4266 addSet (&publics, name);
4272 allocVariables (name);
4274 name->lastLine = yylineno;
4277 /* set the stack pointer */
4278 /* PENDING: check this for the mcs51 */
4279 stackPtr = -port->stack.direction * port->stack.call_overhead;
4280 if (IFFUNC_ISISR (name->type))
4281 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4282 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4283 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4285 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4287 fetype = getSpec (name->type); /* get the specifier for the function */
4288 /* if this is a reentrant function then */
4289 if (IFFUNC_ISREENT (name->type))
4292 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4294 /* do processing for parameters that are passed in registers */
4295 processRegParms (FUNC_ARGS(name->type), body);
4297 /* set the stack pointer */
4301 /* allocate & autoinit the block variables */
4302 processBlockVars (body, &stack, ALLOCATE);
4304 /* save the stack information */
4305 if (options.useXstack)
4306 name->xstack = SPEC_STAK (fetype) = stack;
4308 name->stack = SPEC_STAK (fetype) = stack;
4310 /* name needs to be mangled */
4311 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4313 body = resolveSymbols (body); /* resolve the symbols */
4314 body = decorateType (body); /* propagateType & do semantic checks */
4316 ex = newAst_VALUE (symbolVal (name)); /* create name */
4317 ex = newNode (FUNCTION, ex, body);
4318 ex->values.args = FUNC_ARGS(name->type);
4320 if (options.dump_tree) PA(ex);
4323 werror (E_FUNC_NO_CODE, name->name);
4327 /* create the node & generate intermediate code */
4329 codeOutFile = code->oFile;
4330 piCode = iCodeFromAst (ex);
4334 werror (E_FUNC_NO_CODE, name->name);
4338 eBBlockFromiCode (piCode);
4340 /* if there are any statics then do them */
4343 GcurMemmap = statsg;
4344 codeOutFile = statsg->oFile;
4345 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4351 /* dealloc the block variables */
4352 processBlockVars (body, &stack, DEALLOCATE);
4353 /* deallocate paramaters */
4354 deallocParms (FUNC_ARGS(name->type));
4356 if (IFFUNC_ISREENT (name->type))
4359 /* we are done freeup memory & cleanup */
4363 FUNC_HASBODY(name->type) = 1;
4364 addSet (&operKeyReset, name);
4365 applyToSet (operKeyReset, resetParmKey);
4368 cdbStructBlock (1, cdbFile);
4370 cleanUpLevel (LabelTab, 0);
4371 cleanUpBlock (StructTab, 1);
4372 cleanUpBlock (TypedefTab, 1);
4374 xstack->syms = NULL;
4375 istack->syms = NULL;
4380 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4381 /*-----------------------------------------------------------------*/
4382 /* ast_print : prints the ast (for debugging purposes) */
4383 /*-----------------------------------------------------------------*/
4385 void ast_print (ast * tree, FILE *outfile, int indent)
4390 /* can print only decorated trees */
4391 if (!tree->decorated) return;
4393 /* if any child is an error | this one is an error do nothing */
4394 if (tree->isError ||
4395 (tree->left && tree->left->isError) ||
4396 (tree->right && tree->right->isError)) {
4397 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4401 /* print the line */
4402 /* if not block & function */
4403 if (tree->type == EX_OP &&
4404 (tree->opval.op != FUNCTION &&
4405 tree->opval.op != BLOCK &&
4406 tree->opval.op != NULLOP)) {
4409 if (tree->opval.op == FUNCTION) {
4411 value *args=FUNC_ARGS(tree->left->opval.val->type);
4412 fprintf(outfile,"FUNCTION (%s=%p) type (",
4413 tree->left->opval.val->name, tree);
4414 printTypeChain (tree->ftype,outfile);
4415 fprintf(outfile,") args (");
4418 fprintf (outfile, ", ");
4420 printTypeChain (args ? args->type : NULL, outfile);
4422 args= args ? args->next : NULL;
4424 fprintf(outfile,")\n");
4425 ast_print(tree->left,outfile,indent);
4426 ast_print(tree->right,outfile,indent);
4429 if (tree->opval.op == BLOCK) {
4430 symbol *decls = tree->values.sym;
4431 INDENT(indent,outfile);
4432 fprintf(outfile,"{\n");
4434 INDENT(indent+2,outfile);
4435 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4436 decls->name, decls);
4437 printTypeChain(decls->type,outfile);
4438 fprintf(outfile,")\n");
4440 decls = decls->next;
4442 ast_print(tree->right,outfile,indent+2);
4443 INDENT(indent,outfile);
4444 fprintf(outfile,"}\n");
4447 if (tree->opval.op == NULLOP) {
4448 fprintf(outfile,"\n");
4449 ast_print(tree->left,outfile,indent);
4450 fprintf(outfile,"\n");
4451 ast_print(tree->right,outfile,indent);
4454 INDENT(indent,outfile);
4456 /*------------------------------------------------------------------*/
4457 /*----------------------------*/
4458 /* leaf has been reached */
4459 /*----------------------------*/
4460 /* if this is of type value */
4461 /* just get the type */
4462 if (tree->type == EX_VALUE) {
4464 if (IS_LITERAL (tree->opval.val->etype)) {
4465 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4466 (int) floatFromVal(tree->opval.val),
4467 (int) floatFromVal(tree->opval.val),
4468 floatFromVal(tree->opval.val));
4469 } else if (tree->opval.val->sym) {
4470 /* if the undefined flag is set then give error message */
4471 if (tree->opval.val->sym->undefined) {
4472 fprintf(outfile,"UNDEFINED SYMBOL ");
4474 fprintf(outfile,"SYMBOL ");
4476 fprintf(outfile,"(%s=%p)",
4477 tree->opval.val->sym->name,tree);
4480 fprintf(outfile," type (");
4481 printTypeChain(tree->ftype,outfile);
4482 fprintf(outfile,")\n");
4484 fprintf(outfile,"\n");
4489 /* if type link for the case of cast */
4490 if (tree->type == EX_LINK) {
4491 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4492 printTypeChain(tree->opval.lnk,outfile);
4493 fprintf(outfile,")\n");
4498 /* depending on type of operator do */
4500 switch (tree->opval.op) {
4501 /*------------------------------------------------------------------*/
4502 /*----------------------------*/
4504 /*----------------------------*/
4506 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4507 printTypeChain(tree->ftype,outfile);
4508 fprintf(outfile,")\n");
4509 ast_print(tree->left,outfile,indent+2);
4510 ast_print(tree->right,outfile,indent+2);
4513 /*------------------------------------------------------------------*/
4514 /*----------------------------*/
4516 /*----------------------------*/
4518 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4519 printTypeChain(tree->ftype,outfile);
4520 fprintf(outfile,")\n");
4521 ast_print(tree->left,outfile,indent+2);
4522 ast_print(tree->right,outfile,indent+2);
4525 /*------------------------------------------------------------------*/
4526 /*----------------------------*/
4527 /* struct/union pointer */
4528 /*----------------------------*/
4530 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4531 printTypeChain(tree->ftype,outfile);
4532 fprintf(outfile,")\n");
4533 ast_print(tree->left,outfile,indent+2);
4534 ast_print(tree->right,outfile,indent+2);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4539 /* ++/-- operation */
4540 /*----------------------------*/
4541 case INC_OP: /* incerement operator unary so left only */
4542 fprintf(outfile,"INC_OP (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->left,outfile,indent+2);
4549 fprintf(outfile,"DEC_OP (%p) type (",tree);
4550 printTypeChain(tree->ftype,outfile);
4551 fprintf(outfile,")\n");
4552 ast_print(tree->left,outfile,indent+2);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4558 /*----------------------------*/
4561 fprintf(outfile,"& (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+2);
4565 ast_print(tree->right,outfile,indent+2);
4567 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+2);
4571 ast_print(tree->right,outfile,indent+2);
4574 /*----------------------------*/
4576 /*----------------------------*/
4578 fprintf(outfile,"OR (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+2);
4582 ast_print(tree->right,outfile,indent+2);
4584 /*------------------------------------------------------------------*/
4585 /*----------------------------*/
4587 /*----------------------------*/
4589 fprintf(outfile,"XOR (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->left,outfile,indent+2);
4593 ast_print(tree->right,outfile,indent+2);
4596 /*------------------------------------------------------------------*/
4597 /*----------------------------*/
4599 /*----------------------------*/
4601 fprintf(outfile,"DIV (%p) type (",tree);
4602 printTypeChain(tree->ftype,outfile);
4603 fprintf(outfile,")\n");
4604 ast_print(tree->left,outfile,indent+2);
4605 ast_print(tree->right,outfile,indent+2);
4607 /*------------------------------------------------------------------*/
4608 /*----------------------------*/
4610 /*----------------------------*/
4612 fprintf(outfile,"MOD (%p) type (",tree);
4613 printTypeChain(tree->ftype,outfile);
4614 fprintf(outfile,")\n");
4615 ast_print(tree->left,outfile,indent+2);
4616 ast_print(tree->right,outfile,indent+2);
4619 /*------------------------------------------------------------------*/
4620 /*----------------------------*/
4621 /* address dereference */
4622 /*----------------------------*/
4623 case '*': /* can be unary : if right is null then unary operation */
4625 fprintf(outfile,"DEREF (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+2);
4631 /*------------------------------------------------------------------*/
4632 /*----------------------------*/
4633 /* multiplication */
4634 /*----------------------------*/
4635 fprintf(outfile,"MULT (%p) type (",tree);
4636 printTypeChain(tree->ftype,outfile);
4637 fprintf(outfile,")\n");
4638 ast_print(tree->left,outfile,indent+2);
4639 ast_print(tree->right,outfile,indent+2);
4643 /*------------------------------------------------------------------*/
4644 /*----------------------------*/
4645 /* unary '+' operator */
4646 /*----------------------------*/
4650 fprintf(outfile,"UPLUS (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+2);
4655 /*------------------------------------------------------------------*/
4656 /*----------------------------*/
4658 /*----------------------------*/
4659 fprintf(outfile,"ADD (%p) type (",tree);
4660 printTypeChain(tree->ftype,outfile);
4661 fprintf(outfile,")\n");
4662 ast_print(tree->left,outfile,indent+2);
4663 ast_print(tree->right,outfile,indent+2);
4666 /*------------------------------------------------------------------*/
4667 /*----------------------------*/
4669 /*----------------------------*/
4670 case '-': /* can be unary */
4672 fprintf(outfile,"UMINUS (%p) type (",tree);
4673 printTypeChain(tree->ftype,outfile);
4674 fprintf(outfile,")\n");
4675 ast_print(tree->left,outfile,indent+2);
4677 /*------------------------------------------------------------------*/
4678 /*----------------------------*/
4680 /*----------------------------*/
4681 fprintf(outfile,"SUB (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->left,outfile,indent+2);
4685 ast_print(tree->right,outfile,indent+2);
4688 /*------------------------------------------------------------------*/
4689 /*----------------------------*/
4691 /*----------------------------*/
4693 fprintf(outfile,"COMPL (%p) type (",tree);
4694 printTypeChain(tree->ftype,outfile);
4695 fprintf(outfile,")\n");
4696 ast_print(tree->left,outfile,indent+2);
4698 /*------------------------------------------------------------------*/
4699 /*----------------------------*/
4701 /*----------------------------*/
4703 fprintf(outfile,"NOT (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+2);
4708 /*------------------------------------------------------------------*/
4709 /*----------------------------*/
4711 /*----------------------------*/
4713 fprintf(outfile,"RRC (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+2);
4720 fprintf(outfile,"RLC (%p) type (",tree);
4721 printTypeChain(tree->ftype,outfile);
4722 fprintf(outfile,")\n");
4723 ast_print(tree->left,outfile,indent+2);
4726 fprintf(outfile,"GETHBIT (%p) type (",tree);
4727 printTypeChain(tree->ftype,outfile);
4728 fprintf(outfile,")\n");
4729 ast_print(tree->left,outfile,indent+2);
4732 fprintf(outfile,"LEFT_SHIFT (%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,"RIGHT_SHIFT (%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);
4745 /*------------------------------------------------------------------*/
4746 /*----------------------------*/
4748 /*----------------------------*/
4749 case CAST: /* change the type */
4750 fprintf(outfile,"CAST (%p) from type (",tree);
4751 printTypeChain(tree->right->ftype,outfile);
4752 fprintf(outfile,") to type (");
4753 printTypeChain(tree->ftype,outfile);
4754 fprintf(outfile,")\n");
4755 ast_print(tree->right,outfile,indent+2);
4759 fprintf(outfile,"ANDAND (%p) type (",tree);
4760 printTypeChain(tree->ftype,outfile);
4761 fprintf(outfile,")\n");
4762 ast_print(tree->left,outfile,indent+2);
4763 ast_print(tree->right,outfile,indent+2);
4766 fprintf(outfile,"OROR (%p) type (",tree);
4767 printTypeChain(tree->ftype,outfile);
4768 fprintf(outfile,")\n");
4769 ast_print(tree->left,outfile,indent+2);
4770 ast_print(tree->right,outfile,indent+2);
4773 /*------------------------------------------------------------------*/
4774 /*----------------------------*/
4775 /* comparison operators */
4776 /*----------------------------*/
4778 fprintf(outfile,"GT(>) (%p) type (",tree);
4779 printTypeChain(tree->ftype,outfile);
4780 fprintf(outfile,")\n");
4781 ast_print(tree->left,outfile,indent+2);
4782 ast_print(tree->right,outfile,indent+2);
4785 fprintf(outfile,"LT(<) (%p) type (",tree);
4786 printTypeChain(tree->ftype,outfile);
4787 fprintf(outfile,")\n");
4788 ast_print(tree->left,outfile,indent+2);
4789 ast_print(tree->right,outfile,indent+2);
4792 fprintf(outfile,"LE(<=) (%p) type (",tree);
4793 printTypeChain(tree->ftype,outfile);
4794 fprintf(outfile,")\n");
4795 ast_print(tree->left,outfile,indent+2);
4796 ast_print(tree->right,outfile,indent+2);
4799 fprintf(outfile,"GE(>=) (%p) type (",tree);
4800 printTypeChain(tree->ftype,outfile);
4801 fprintf(outfile,")\n");
4802 ast_print(tree->left,outfile,indent+2);
4803 ast_print(tree->right,outfile,indent+2);
4806 fprintf(outfile,"EQ(==) (%p) type (",tree);
4807 printTypeChain(tree->ftype,outfile);
4808 fprintf(outfile,")\n");
4809 ast_print(tree->left,outfile,indent+2);
4810 ast_print(tree->right,outfile,indent+2);
4813 fprintf(outfile,"NE(!=) (%p) type (",tree);
4814 printTypeChain(tree->ftype,outfile);
4815 fprintf(outfile,")\n");
4816 ast_print(tree->left,outfile,indent+2);
4817 ast_print(tree->right,outfile,indent+2);
4818 /*------------------------------------------------------------------*/
4819 /*----------------------------*/
4821 /*----------------------------*/
4822 case SIZEOF: /* evaluate wihout code generation */
4823 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4826 /*------------------------------------------------------------------*/
4827 /*----------------------------*/
4828 /* conditional operator '?' */
4829 /*----------------------------*/
4831 fprintf(outfile,"QUEST(?) (%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);
4839 fprintf(outfile,"COLON(:) (%p) type (",tree);
4840 printTypeChain(tree->ftype,outfile);
4841 fprintf(outfile,")\n");
4842 ast_print(tree->left,outfile,indent+2);
4843 ast_print(tree->right,outfile,indent+2);
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4848 /* assignment operators */
4849 /*----------------------------*/
4851 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4852 printTypeChain(tree->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 ast_print(tree->right,outfile,indent+2);
4858 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4859 printTypeChain(tree->ftype,outfile);
4860 fprintf(outfile,")\n");
4861 ast_print(tree->left,outfile,indent+2);
4862 ast_print(tree->right,outfile,indent+2);
4865 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4866 printTypeChain(tree->ftype,outfile);
4867 fprintf(outfile,")\n");
4868 ast_print(tree->left,outfile,indent+2);
4869 ast_print(tree->right,outfile,indent+2);
4872 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4873 printTypeChain(tree->ftype,outfile);
4874 fprintf(outfile,")\n");
4875 ast_print(tree->left,outfile,indent+2);
4876 ast_print(tree->right,outfile,indent+2);
4879 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4880 printTypeChain(tree->ftype,outfile);
4881 fprintf(outfile,")\n");
4882 ast_print(tree->left,outfile,indent+2);
4883 ast_print(tree->right,outfile,indent+2);
4886 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4887 printTypeChain(tree->ftype,outfile);
4888 fprintf(outfile,")\n");
4889 ast_print(tree->left,outfile,indent+2);
4890 ast_print(tree->right,outfile,indent+2);
4893 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4894 printTypeChain(tree->ftype,outfile);
4895 fprintf(outfile,")\n");
4896 ast_print(tree->left,outfile,indent+2);
4897 ast_print(tree->right,outfile,indent+2);
4899 /*------------------------------------------------------------------*/
4900 /*----------------------------*/
4902 /*----------------------------*/
4904 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4905 printTypeChain(tree->ftype,outfile);
4906 fprintf(outfile,")\n");
4907 ast_print(tree->left,outfile,indent+2);
4908 ast_print(tree->right,outfile,indent+2);
4910 /*------------------------------------------------------------------*/
4911 /*----------------------------*/
4913 /*----------------------------*/
4915 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4916 printTypeChain(tree->ftype,outfile);
4917 fprintf(outfile,")\n");
4918 ast_print(tree->left,outfile,indent+2);
4919 ast_print(tree->right,outfile,indent+2);
4921 /*------------------------------------------------------------------*/
4922 /*----------------------------*/
4923 /* straight assignemnt */
4924 /*----------------------------*/
4926 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4927 printTypeChain(tree->ftype,outfile);
4928 fprintf(outfile,")\n");
4929 ast_print(tree->left,outfile,indent+2);
4930 ast_print(tree->right,outfile,indent+2);
4932 /*------------------------------------------------------------------*/
4933 /*----------------------------*/
4934 /* comma operator */
4935 /*----------------------------*/
4937 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4938 printTypeChain(tree->ftype,outfile);
4939 fprintf(outfile,")\n");
4940 ast_print(tree->left,outfile,indent+2);
4941 ast_print(tree->right,outfile,indent+2);
4943 /*------------------------------------------------------------------*/
4944 /*----------------------------*/
4946 /*----------------------------*/
4949 fprintf(outfile,"CALL (%p) type (",tree);
4950 printTypeChain(tree->ftype,outfile);
4951 fprintf(outfile,")\n");
4952 ast_print(tree->left,outfile,indent+2);
4953 ast_print(tree->right,outfile,indent+2);
4956 fprintf(outfile,"PARMS\n");
4957 ast_print(tree->left,outfile,indent+2);
4958 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4959 ast_print(tree->right,outfile,indent+2);
4962 /*------------------------------------------------------------------*/
4963 /*----------------------------*/
4964 /* return statement */
4965 /*----------------------------*/
4967 fprintf(outfile,"RETURN (%p) type (",tree);
4968 printTypeChain(tree->right->ftype,outfile);
4969 fprintf(outfile,")\n");
4970 ast_print(tree->right,outfile,indent+2);
4972 /*------------------------------------------------------------------*/
4973 /*----------------------------*/
4974 /* label statement */
4975 /*----------------------------*/
4977 fprintf(outfile,"LABEL (%p)\n",tree);
4978 ast_print(tree->left,outfile,indent+2);
4979 ast_print(tree->right,outfile,indent);
4981 /*------------------------------------------------------------------*/
4982 /*----------------------------*/
4983 /* switch statement */
4984 /*----------------------------*/
4988 fprintf(outfile,"SWITCH (%p) ",tree);
4989 ast_print(tree->left,outfile,0);
4990 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4991 INDENT(indent+2,outfile);
4992 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4993 (int) floatFromVal(val),
4994 tree->values.switchVals.swNum,
4995 (int) floatFromVal(val));
4997 ast_print(tree->right,outfile,indent);
5000 /*------------------------------------------------------------------*/
5001 /*----------------------------*/
5003 /*----------------------------*/
5005 fprintf(outfile,"IF (%p) \n",tree);
5006 ast_print(tree->left,outfile,indent+2);
5007 if (tree->trueLabel) {
5008 INDENT(indent,outfile);
5009 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5011 if (tree->falseLabel) {
5012 INDENT(indent,outfile);
5013 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5015 ast_print(tree->right,outfile,indent+2);
5017 /*------------------------------------------------------------------*/
5018 /*----------------------------*/
5020 /*----------------------------*/
5022 fprintf(outfile,"FOR (%p) \n",tree);
5023 if (AST_FOR( tree, initExpr)) {
5024 INDENT(indent+2,outfile);
5025 fprintf(outfile,"INIT EXPR ");
5026 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5028 if (AST_FOR( tree, condExpr)) {
5029 INDENT(indent+2,outfile);
5030 fprintf(outfile,"COND EXPR ");
5031 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5033 if (AST_FOR( tree, loopExpr)) {
5034 INDENT(indent+2,outfile);
5035 fprintf(outfile,"LOOP EXPR ");
5036 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5038 fprintf(outfile,"FOR LOOP BODY \n");
5039 ast_print(tree->left,outfile,indent+2);
5048 ast_print(t,stdout,0);