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 *);
57 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
62 printTypeChain (tree->ftype, stdout);
67 /*-----------------------------------------------------------------*/
68 /* newAst - creates a fresh node for an expression tree */
69 /*-----------------------------------------------------------------*/
72 newAst (int type, void *op)
75 static int oldLineno = 0;
77 ex = Safe_alloc ( sizeof (ast));
80 ex->lineno = (noLineno ? oldLineno : yylineno);
81 ex->filename = currFname;
82 ex->level = NestLevel;
83 ex->block = currBlockno;
84 ex->initMode = inInitMode;
86 /* depending on the type */
90 ex->opval.val = (value *) op;
93 ex->opval.op = (long) op;
96 ex->opval.lnk = (sym_link *) op;
99 ex->opval.stmnt = (unsigned) op;
107 newAst_ (unsigned type)
110 static int oldLineno = 0;
112 ex = Safe_alloc ( sizeof (ast));
115 ex->lineno = (noLineno ? oldLineno : yylineno);
116 ex->filename = currFname;
117 ex->level = NestLevel;
118 ex->block = currBlockno;
119 ex->initMode = inInitMode;
124 newAst_VALUE (value * val)
126 ast *ex = newAst_ (EX_VALUE);
132 newAst_OP (unsigned op)
134 ast *ex = newAst_ (EX_OP);
140 newAst_LINK (sym_link * val)
142 ast *ex = newAst_ (EX_LINK);
148 newAst_STMNT (unsigned val)
150 ast *ex = newAst_ (EX_STMNT);
151 ex->opval.stmnt = val;
155 /*-----------------------------------------------------------------*/
156 /* newNode - creates a new node */
157 /*-----------------------------------------------------------------*/
159 newNode (long op, ast * left, ast * right)
170 /*-----------------------------------------------------------------*/
171 /* newIfxNode - creates a new Ifx Node */
172 /*-----------------------------------------------------------------*/
174 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
178 /* if this is a literal then we already know the result */
179 if (condAst->etype && IS_LITERAL (condAst->etype))
181 /* then depending on the expression value */
182 if (floatFromVal (condAst->opval.val))
183 ifxNode = newNode (GOTO,
184 newAst_VALUE (symbolVal (trueLabel)),
187 ifxNode = newNode (GOTO,
188 newAst_VALUE (symbolVal (falseLabel)),
193 ifxNode = newNode (IFX, condAst, NULL);
194 ifxNode->trueLabel = trueLabel;
195 ifxNode->falseLabel = falseLabel;
201 /*-----------------------------------------------------------------*/
202 /* copyAstValues - copies value portion of ast if needed */
203 /*-----------------------------------------------------------------*/
205 copyAstValues (ast * dest, ast * src)
207 switch (src->opval.op)
210 dest->values.sym = copySymbolChain (src->values.sym);
214 dest->values.switchVals.swVals =
215 copyValue (src->values.switchVals.swVals);
216 dest->values.switchVals.swDefault =
217 src->values.switchVals.swDefault;
218 dest->values.switchVals.swNum =
219 src->values.switchVals.swNum;
223 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
224 strcpy (dest->values.inlineasm, src->values.inlineasm);
228 dest->values.constlist = copyLiteralList(src->values.constlist);
232 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
233 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
234 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
235 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
236 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
237 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
238 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
243 /*-----------------------------------------------------------------*/
244 /* copyAst - makes a copy of a given astession */
245 /*-----------------------------------------------------------------*/
254 dest = Safe_alloc ( sizeof (ast));
256 dest->type = src->type;
257 dest->lineno = src->lineno;
258 dest->level = src->level;
259 dest->funcName = src->funcName;
261 /* if this is a leaf */
263 if (src->type == EX_VALUE)
265 dest->opval.val = copyValue (src->opval.val);
270 if (src->type == EX_LINK)
272 dest->opval.lnk = copyLinkChain (src->opval.lnk);
276 dest->opval.op = src->opval.op;
278 /* if this is a node that has special values */
279 copyAstValues (dest, src);
282 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
284 dest->trueLabel = copySymbol (src->trueLabel);
285 dest->falseLabel = copySymbol (src->falseLabel);
286 dest->left = copyAst (src->left);
287 dest->right = copyAst (src->right);
293 /*-----------------------------------------------------------------*/
294 /* hasSEFcalls - returns TRUE if tree has a function call */
295 /*-----------------------------------------------------------------*/
297 hasSEFcalls (ast * tree)
302 if (tree->type == EX_OP &&
303 (tree->opval.op == CALL ||
304 tree->opval.op == PCALL ||
305 tree->opval.op == '=' ||
306 tree->opval.op == INC_OP ||
307 tree->opval.op == DEC_OP))
310 return (hasSEFcalls (tree->left) |
311 hasSEFcalls (tree->right));
314 /*-----------------------------------------------------------------*/
315 /* isAstEqual - compares two asts & returns 1 if they are equal */
316 /*-----------------------------------------------------------------*/
318 isAstEqual (ast * t1, ast * t2)
327 if (t1->type != t2->type)
333 if (t1->opval.op != t2->opval.op)
335 return (isAstEqual (t1->left, t2->left) &&
336 isAstEqual (t1->right, t2->right));
340 if (t1->opval.val->sym)
342 if (!t2->opval.val->sym)
345 return isSymbolEqual (t1->opval.val->sym,
350 if (t2->opval.val->sym)
353 return (floatFromVal (t1->opval.val) ==
354 floatFromVal (t2->opval.val));
358 /* only compare these two types */
366 /*-----------------------------------------------------------------*/
367 /* resolveSymbols - resolve symbols from the symbol table */
368 /*-----------------------------------------------------------------*/
370 resolveSymbols (ast * tree)
372 /* walk the entire tree and check for values */
373 /* with symbols if we find one then replace */
374 /* symbol with that from the symbol table */
380 /* if not block & function */
381 if (tree->type == EX_OP &&
382 (tree->opval.op != FUNCTION &&
383 tree->opval.op != BLOCK &&
384 tree->opval.op != NULLOP))
386 filename = tree->filename;
387 lineno = tree->lineno;
390 /* make sure we resolve the true & false labels for ifx */
391 if (tree->type == EX_OP && tree->opval.op == IFX)
397 if ((csym = findSym (LabelTab, tree->trueLabel,
398 tree->trueLabel->name)))
399 tree->trueLabel = csym;
401 werror (E_LABEL_UNDEF, tree->trueLabel->name);
404 if (tree->falseLabel)
406 if ((csym = findSym (LabelTab,
408 tree->falseLabel->name)))
409 tree->falseLabel = csym;
411 werror (E_LABEL_UNDEF, tree->falseLabel->name);
416 /* if this is a label resolve it from the labelTab */
417 if (IS_AST_VALUE (tree) &&
418 tree->opval.val->sym &&
419 tree->opval.val->sym->islbl)
422 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
423 tree->opval.val->sym->name);
426 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
428 tree->opval.val->sym = csym;
430 goto resolveChildren;
433 /* do only for leafs */
434 if (IS_AST_VALUE (tree) &&
435 tree->opval.val->sym &&
436 !tree->opval.val->sym->implicit)
439 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
441 /* if found in the symbol table & they r not the same */
442 if (csym && tree->opval.val->sym != csym)
444 tree->opval.val->sym = csym;
445 tree->opval.val->type = csym->type;
446 tree->opval.val->etype = csym->etype;
449 /* if not found in the symbol table */
450 /* mark it as undefined assume it is */
451 /* an integer in data space */
452 if (!csym && !tree->opval.val->sym->implicit)
455 /* if this is a function name then */
456 /* mark it as returning an int */
459 tree->opval.val->sym->type = newLink ();
460 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
461 tree->opval.val->sym->type->next =
462 tree->opval.val->sym->etype = newIntLink ();
463 tree->opval.val->etype = tree->opval.val->etype;
464 tree->opval.val->type = tree->opval.val->sym->type;
465 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
466 allocVariables (tree->opval.val->sym);
470 tree->opval.val->sym->undefined = 1;
471 tree->opval.val->type =
472 tree->opval.val->etype = newIntLink ();
473 tree->opval.val->sym->type =
474 tree->opval.val->sym->etype = newIntLink ();
480 resolveSymbols (tree->left);
481 resolveSymbols (tree->right);
486 /*-----------------------------------------------------------------*/
487 /* setAstLineno - walks a ast tree & sets the line number */
488 /*-----------------------------------------------------------------*/
490 setAstLineno (ast * tree, int lineno)
495 tree->lineno = lineno;
496 setAstLineno (tree->left, lineno);
497 setAstLineno (tree->right, lineno);
502 /* this functions seems to be superfluous?! kmh */
504 /*-----------------------------------------------------------------*/
505 /* resolveFromTable - will return the symbal table value */
506 /*-----------------------------------------------------------------*/
508 resolveFromTable (value * val)
515 csym = findSymWithLevel (SymbolTab, val->sym);
517 /* if found in the symbol table & they r not the same */
518 if (csym && val->sym != csym &&
519 csym->level == val->sym->level &&
525 val->type = csym->type;
526 val->etype = csym->etype;
533 /*-----------------------------------------------------------------*/
534 /* funcOfType :- function of type with name */
535 /*-----------------------------------------------------------------*/
537 funcOfType (char *name, sym_link * type, sym_link * argType,
541 /* create the symbol */
542 sym = newSymbol (name, 0);
544 /* setup return value */
545 sym->type = newLink ();
546 DCL_TYPE (sym->type) = FUNCTION;
547 sym->type->next = copyLinkChain (type);
548 sym->etype = getSpec (sym->type);
549 FUNC_ISREENT(sym->type) = rent;
551 /* if arguments required */
555 args = FUNC_ARGS(sym->type) = newValue ();
559 args->type = copyLinkChain (argType);
560 args->etype = getSpec (args->type);
563 args = args->next = newValue ();
570 allocVariables (sym);
575 /*-----------------------------------------------------------------*/
576 /* reverseParms - will reverse a parameter tree */
577 /*-----------------------------------------------------------------*/
579 reverseParms (ast * ptree)
585 /* top down if we find a nonParm tree then quit */
586 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
589 ptree->left = ptree->right;
590 ptree->right = ttree;
591 reverseParms (ptree->left);
592 reverseParms (ptree->right);
598 /*-----------------------------------------------------------------*/
599 /* processParms - makes sure the parameters are okay and do some */
600 /* processing with them */
601 /*-----------------------------------------------------------------*/
603 processParms (ast * func,
606 int *parmNumber, // unused, although updated
607 bool rightmost) // double checked?
609 /* if none of them exist */
610 if (!defParm && !actParm)
614 if (getenv("DEBUG_SANITY")) {
615 fprintf (stderr, "processParms: %s ", defParm->name);
617 /* make sure the type is complete and sane */
618 checkTypeSanity(defParm->etype, defParm->name);
621 /* if the function is being called via a pointer & */
622 /* it has not been defined a reentrant then we cannot */
623 /* have parameters */
624 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
626 werror (W_NONRENT_ARGS);
630 /* if defined parameters ended but actual parameters */
631 /* exist and this is not defined as a variable arg */
632 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
634 werror (E_TOO_MANY_PARMS);
638 /* if defined parameters present but no actual parameters */
639 if (defParm && !actParm)
641 werror (E_TOO_FEW_PARMS);
645 /* If this is a varargs function... */
646 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
651 if (IS_CAST_OP (actParm)
652 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
654 /* Parameter was explicitly typecast; don't touch it. */
658 /* The ternary ('?') operator is weird: the ftype of the
659 * operator is the type of the condition, but it will return a
660 * (possibly) different type.
662 if (IS_TERNARY_OP(actParm))
664 assert(IS_COLON_OP(actParm->right));
665 assert(actParm->right->left);
666 ftype = actParm->right->left->ftype;
670 ftype = actParm->ftype;
673 /* If it's a small integer, upcast to int. */
674 if (IS_INTEGRAL (ftype)
675 && (getSize (ftype) < (unsigned) INTSIZE))
677 newType = newAst_LINK(INTTYPE);
680 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
682 newType = newAst_LINK (copyLinkChain(ftype));
683 DCL_TYPE (newType->opval.lnk) = GPOINTER;
686 if (IS_AGGREGATE (ftype))
688 newType = newAst_LINK (copyLinkChain (ftype));
689 DCL_TYPE (newType->opval.lnk) = GPOINTER;
693 /* cast required; change this op to a cast. */
694 ast *parmCopy = resolveSymbols (copyAst (actParm));
696 actParm->type = EX_OP;
697 actParm->opval.op = CAST;
698 actParm->left = newType;
699 actParm->right = parmCopy;
700 decorateType (actParm);
702 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
704 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
705 processParms (func, NULL, actParm->right, parmNumber, rightmost));
710 /* if defined parameters ended but actual has not & */
712 if (!defParm && actParm &&
713 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
716 resolveSymbols (actParm);
717 /* if this is a PARAM node then match left & right */
718 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
720 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
721 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
725 /* If we have found a value node by following only right-hand links,
726 * then we know that there are no more values after us.
728 * Therefore, if there are more defined parameters, the caller didn't
731 if (0 && rightmost && defParm->next)
733 werror (E_TOO_FEW_PARMS);
738 /* the parameter type must be at least castable */
739 if (compareType (defParm->type, actParm->ftype) == 0) {
740 werror (E_INCOMPAT_TYPES);
741 fprintf (stderr, "type --> '");
742 printTypeChain (actParm->ftype, stderr);
743 fprintf (stderr, "' ");
744 fprintf (stderr, "assigned to type --> '");
745 printTypeChain (defParm->type, stderr);
746 fprintf (stderr, "'\n");
750 /* if the parameter is castable then add the cast */
751 if (compareType (defParm->type, actParm->ftype) < 0)
753 ast *pTree = resolveSymbols (copyAst (actParm));
755 /* now change the current one to a cast */
756 actParm->type = EX_OP;
757 actParm->opval.op = CAST;
758 actParm->left = newAst_LINK (defParm->type);
759 actParm->right = pTree;
760 actParm->etype = defParm->etype;
761 actParm->ftype = defParm->type;
764 /* make a copy and change the regparm type to the defined parm */
765 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
766 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
770 /*-----------------------------------------------------------------*/
771 /* createIvalType - generates ival for basic types */
772 /*-----------------------------------------------------------------*/
774 createIvalType (ast * sym, sym_link * type, initList * ilist)
778 /* if initList is deep */
779 if (ilist->type == INIT_DEEP)
780 ilist = ilist->init.deep;
782 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
783 return decorateType (newNode ('=', sym, iExpr));
786 /*-----------------------------------------------------------------*/
787 /* createIvalStruct - generates initial value for structures */
788 /*-----------------------------------------------------------------*/
790 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
796 sflds = SPEC_STRUCT (type)->fields;
797 if (ilist->type != INIT_DEEP)
799 werror (E_INIT_STRUCT, "");
803 iloop = ilist->init.deep;
805 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
809 /* if we have come to end */
813 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
814 lAst = decorateType (resolveSymbols (lAst));
815 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
821 /*-----------------------------------------------------------------*/
822 /* createIvalArray - generates code for array initialization */
823 /*-----------------------------------------------------------------*/
825 createIvalArray (ast * sym, sym_link * type, initList * ilist)
829 int lcnt = 0, size = 0;
830 literalList *literalL;
832 /* take care of the special case */
833 /* array of characters can be init */
835 if (IS_CHAR (type->next))
836 if ((rast = createIvalCharPtr (sym,
838 decorateType (resolveSymbols (list2expr (ilist))))))
840 return decorateType (resolveSymbols (rast));
842 /* not the special case */
843 if (ilist->type != INIT_DEEP)
845 werror (E_INIT_STRUCT, "");
849 iloop = ilist->init.deep;
850 lcnt = DCL_ELEM (type);
852 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
856 aSym = decorateType (resolveSymbols(sym));
858 rast = newNode(ARRAYINIT, aSym, NULL);
859 rast->values.constlist = literalL;
861 // Make sure size is set to length of initializer list.
868 if (lcnt && size > lcnt)
870 // Array size was specified, and we have more initializers than needed.
871 char *name=sym->opval.val->sym->name;
872 int lineno=sym->opval.val->sym->lineDef;
874 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
883 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
884 aSym = decorateType (resolveSymbols (aSym));
885 rast = createIval (aSym, type->next, iloop, rast);
886 iloop = (iloop ? iloop->next : NULL);
892 /* no of elements given and we */
893 /* have generated for all of them */
896 // there has to be a better way
897 char *name=sym->opval.val->sym->name;
898 int lineno=sym->opval.val->sym->lineDef;
899 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
906 /* if we have not been given a size */
907 if (!DCL_ELEM (type))
909 DCL_ELEM (type) = size;
912 return decorateType (resolveSymbols (rast));
916 /*-----------------------------------------------------------------*/
917 /* createIvalCharPtr - generates initial values for char pointers */
918 /*-----------------------------------------------------------------*/
920 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
924 /* if this is a pointer & right is a literal array then */
925 /* just assignment will do */
926 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
927 SPEC_SCLS (iexpr->etype) == S_CODE)
928 && IS_ARRAY (iexpr->ftype)))
929 return newNode ('=', sym, iexpr);
931 /* left side is an array so we have to assign each */
933 if ((IS_LITERAL (iexpr->etype) ||
934 SPEC_SCLS (iexpr->etype) == S_CODE)
935 && IS_ARRAY (iexpr->ftype))
937 /* for each character generate an assignment */
938 /* to the array element */
939 char *s = SPEC_CVAL (iexpr->etype).v_char;
944 rast = newNode (NULLOP,
948 newAst_VALUE (valueFromLit ((float) i))),
949 newAst_VALUE (valueFromLit (*s))));
953 rast = newNode (NULLOP,
957 newAst_VALUE (valueFromLit ((float) i))),
958 newAst_VALUE (valueFromLit (*s))));
959 return decorateType (resolveSymbols (rast));
965 /*-----------------------------------------------------------------*/
966 /* createIvalPtr - generates initial value for pointers */
967 /*-----------------------------------------------------------------*/
969 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
975 if (ilist->type == INIT_DEEP)
976 ilist = ilist->init.deep;
978 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
980 /* if character pointer */
981 if (IS_CHAR (type->next))
982 if ((rast = createIvalCharPtr (sym, type, iexpr)))
985 return newNode ('=', sym, iexpr);
988 /*-----------------------------------------------------------------*/
989 /* createIval - generates code for initial value */
990 /*-----------------------------------------------------------------*/
992 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
999 /* if structure then */
1000 if (IS_STRUCT (type))
1001 rast = createIvalStruct (sym, type, ilist);
1003 /* if this is a pointer */
1005 rast = createIvalPtr (sym, type, ilist);
1007 /* if this is an array */
1008 if (IS_ARRAY (type))
1009 rast = createIvalArray (sym, type, ilist);
1011 /* if type is SPECIFIER */
1013 rast = createIvalType (sym, type, ilist);
1016 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1018 return decorateType (resolveSymbols (rast));
1021 /*-----------------------------------------------------------------*/
1022 /* initAggregates - initialises aggregate variables with initv */
1023 /*-----------------------------------------------------------------*/
1025 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1027 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1031 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1033 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1034 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1035 "with -mmcs51 and --model-large");
1039 if (SPEC_OCLS(sym->etype)==xdata &&
1040 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1043 newSym=copySymbol (sym);
1044 SPEC_OCLS(newSym->etype)=code;
1045 sprintf (newSym->name, "%s_init__", sym->name);
1046 sprintf (newSym->rname,"%s_init__", sym->rname);
1047 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1049 // emit it in the static segment
1050 addSet(&statsg->syms, newSym);
1052 // now memcpy() the entire array from cseg
1053 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1054 newAst_VALUE (symbolVal (sym)),
1055 newAst_VALUE (symbolVal (newSym)));
1056 return decorateType(resolveSymbols(ast));
1060 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1063 /*-----------------------------------------------------------------*/
1064 /* gatherAutoInit - creates assignment expressions for initial */
1066 /*-----------------------------------------------------------------*/
1068 gatherAutoInit (symbol * autoChain)
1075 for (sym = autoChain; sym; sym = sym->next)
1078 /* resolve the symbols in the ival */
1080 resolveIvalSym (sym->ival);
1082 /* if this is a static variable & has an */
1083 /* initial value the code needs to be lifted */
1084 /* here to the main portion since they can be */
1085 /* initialised only once at the start */
1086 if (IS_STATIC (sym->etype) && sym->ival &&
1087 SPEC_SCLS (sym->etype) != S_CODE)
1091 // this can only be a constant
1092 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1093 werror (E_CONST_EXPECTED);
1096 /* insert the symbol into the symbol table */
1097 /* with level = 0 & name = rname */
1098 newSym = copySymbol (sym);
1099 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1101 /* now lift the code to main */
1102 if (IS_AGGREGATE (sym->type))
1103 work = initAggregates (sym, sym->ival, NULL);
1105 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1106 list2expr (sym->ival));
1108 setAstLineno (work, sym->lineDef);
1112 staticAutos = newNode (NULLOP, staticAutos, work);
1119 /* if there is an initial value */
1120 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1122 if (IS_AGGREGATE (sym->type))
1123 work = initAggregates (sym, sym->ival, NULL);
1125 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1126 list2expr (sym->ival));
1128 setAstLineno (work, sym->lineDef);
1131 init = newNode (NULLOP, init, work);
1140 /*-----------------------------------------------------------------*/
1141 /* stringToSymbol - creates a symbol from a literal string */
1142 /*-----------------------------------------------------------------*/
1144 stringToSymbol (value * val)
1146 char name[SDCC_NAME_MAX + 1];
1147 static int charLbl = 0;
1150 sprintf (name, "_str_%d", charLbl++);
1151 sym = newSymbol (name, 0); /* make it @ level 0 */
1152 strcpy (sym->rname, name);
1154 /* copy the type from the value passed */
1155 sym->type = copyLinkChain (val->type);
1156 sym->etype = getSpec (sym->type);
1157 /* change to storage class & output class */
1158 SPEC_SCLS (sym->etype) = S_CODE;
1159 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1160 SPEC_STAT (sym->etype) = 1;
1161 /* make the level & block = 0 */
1162 sym->block = sym->level = 0;
1164 /* create an ival */
1165 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1170 allocVariables (sym);
1173 return symbolVal (sym);
1177 /*-----------------------------------------------------------------*/
1178 /* processBlockVars - will go thru the ast looking for block if */
1179 /* a block is found then will allocate the syms */
1180 /* will also gather the auto inits present */
1181 /*-----------------------------------------------------------------*/
1183 processBlockVars (ast * tree, int *stack, int action)
1188 /* if this is a block */
1189 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1193 if (action == ALLOCATE)
1195 *stack += allocVariables (tree->values.sym);
1196 autoInit = gatherAutoInit (tree->values.sym);
1198 /* if there are auto inits then do them */
1200 tree->left = newNode (NULLOP, autoInit, tree->left);
1202 else /* action is deallocate */
1203 deallocLocal (tree->values.sym);
1206 processBlockVars (tree->left, stack, action);
1207 processBlockVars (tree->right, stack, action);
1211 /*-----------------------------------------------------------------*/
1212 /* constExprValue - returns the value of a constant expression */
1213 /* or NULL if it is not a constant expression */
1214 /*-----------------------------------------------------------------*/
1216 constExprValue (ast * cexpr, int check)
1218 cexpr = decorateType (resolveSymbols (cexpr));
1220 /* if this is not a constant then */
1221 if (!IS_LITERAL (cexpr->ftype))
1223 /* then check if this is a literal array
1225 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1226 SPEC_CVAL (cexpr->etype).v_char &&
1227 IS_ARRAY (cexpr->ftype))
1229 value *val = valFromType (cexpr->ftype);
1230 SPEC_SCLS (val->etype) = S_LITERAL;
1231 val->sym = cexpr->opval.val->sym;
1232 val->sym->type = copyLinkChain (cexpr->ftype);
1233 val->sym->etype = getSpec (val->sym->type);
1234 strcpy (val->name, cexpr->opval.val->sym->rname);
1238 /* if we are casting a literal value then */
1239 if (IS_AST_OP (cexpr) &&
1240 cexpr->opval.op == CAST &&
1241 IS_LITERAL (cexpr->left->ftype))
1242 return valCastLiteral (cexpr->ftype,
1243 floatFromVal (cexpr->left->opval.val));
1245 if (IS_AST_VALUE (cexpr))
1246 return cexpr->opval.val;
1249 werror (E_CONST_EXPECTED, "found expression");
1254 /* return the value */
1255 return cexpr->opval.val;
1259 /*-----------------------------------------------------------------*/
1260 /* isLabelInAst - will return true if a given label is found */
1261 /*-----------------------------------------------------------------*/
1263 isLabelInAst (symbol * label, ast * tree)
1265 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1268 if (IS_AST_OP (tree) &&
1269 tree->opval.op == LABEL &&
1270 isSymbolEqual (AST_SYMBOL (tree->left), label))
1273 return isLabelInAst (label, tree->right) &&
1274 isLabelInAst (label, tree->left);
1278 /*-----------------------------------------------------------------*/
1279 /* isLoopCountable - return true if the loop count can be determi- */
1280 /* -ned at compile time . */
1281 /*-----------------------------------------------------------------*/
1283 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1284 symbol ** sym, ast ** init, ast ** end)
1287 /* the loop is considered countable if the following
1288 conditions are true :-
1290 a) initExpr :- <sym> = <const>
1291 b) condExpr :- <sym> < <const1>
1292 c) loopExpr :- <sym> ++
1295 /* first check the initExpr */
1296 if (IS_AST_OP (initExpr) &&
1297 initExpr->opval.op == '=' && /* is assignment */
1298 IS_AST_SYM_VALUE (initExpr->left))
1299 { /* left is a symbol */
1301 *sym = AST_SYMBOL (initExpr->left);
1302 *init = initExpr->right;
1307 /* for now the symbol has to be of
1309 if (!IS_INTEGRAL ((*sym)->type))
1312 /* now check condExpr */
1313 if (IS_AST_OP (condExpr))
1316 switch (condExpr->opval.op)
1319 if (IS_AST_SYM_VALUE (condExpr->left) &&
1320 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1321 IS_AST_LIT_VALUE (condExpr->right))
1323 *end = condExpr->right;
1329 if (IS_AST_OP (condExpr->left) &&
1330 condExpr->left->opval.op == '>' &&
1331 IS_AST_LIT_VALUE (condExpr->left->right) &&
1332 IS_AST_SYM_VALUE (condExpr->left->left) &&
1333 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1336 *end = newNode ('+', condExpr->left->right,
1337 newAst_VALUE (constVal ("1")));
1348 /* check loop expression is of the form <sym>++ */
1349 if (!IS_AST_OP (loopExpr))
1352 /* check if <sym> ++ */
1353 if (loopExpr->opval.op == INC_OP)
1359 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1360 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1367 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1368 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1376 if (loopExpr->opval.op == ADD_ASSIGN)
1379 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1380 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1381 IS_AST_LIT_VALUE (loopExpr->right) &&
1382 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1390 /*-----------------------------------------------------------------*/
1391 /* astHasVolatile - returns true if ast contains any volatile */
1392 /*-----------------------------------------------------------------*/
1394 astHasVolatile (ast * tree)
1399 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1402 if (IS_AST_OP (tree))
1403 return astHasVolatile (tree->left) ||
1404 astHasVolatile (tree->right);
1409 /*-----------------------------------------------------------------*/
1410 /* astHasPointer - return true if the ast contains any ptr variable */
1411 /*-----------------------------------------------------------------*/
1413 astHasPointer (ast * tree)
1418 if (IS_AST_LINK (tree))
1421 /* if we hit an array expression then check
1422 only the left side */
1423 if (IS_AST_OP (tree) && tree->opval.op == '[')
1424 return astHasPointer (tree->left);
1426 if (IS_AST_VALUE (tree))
1427 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1429 return astHasPointer (tree->left) ||
1430 astHasPointer (tree->right);
1434 /*-----------------------------------------------------------------*/
1435 /* astHasSymbol - return true if the ast has the given symbol */
1436 /*-----------------------------------------------------------------*/
1438 astHasSymbol (ast * tree, symbol * sym)
1440 if (!tree || IS_AST_LINK (tree))
1443 if (IS_AST_VALUE (tree))
1445 if (IS_AST_SYM_VALUE (tree))
1446 return isSymbolEqual (AST_SYMBOL (tree), sym);
1451 return astHasSymbol (tree->left, sym) ||
1452 astHasSymbol (tree->right, sym);
1455 /*-----------------------------------------------------------------*/
1456 /* astHasDeref - return true if the ast has an indirect access */
1457 /*-----------------------------------------------------------------*/
1459 astHasDeref (ast * tree)
1461 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1464 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1466 return astHasDeref (tree->left) || astHasDeref (tree->right);
1469 /*-----------------------------------------------------------------*/
1470 /* isConformingBody - the loop body has to conform to a set of rules */
1471 /* for the loop to be considered reversible read on for rules */
1472 /*-----------------------------------------------------------------*/
1474 isConformingBody (ast * pbody, symbol * sym, ast * body)
1477 /* we are going to do a pre-order traversal of the
1478 tree && check for the following conditions. (essentially
1479 a set of very shallow tests )
1480 a) the sym passed does not participate in
1481 any arithmetic operation
1482 b) There are no function calls
1483 c) all jumps are within the body
1484 d) address of loop control variable not taken
1485 e) if an assignment has a pointer on the
1486 left hand side make sure right does not have
1487 loop control variable */
1489 /* if we reach the end or a leaf then true */
1490 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1494 /* if anything else is "volatile" */
1495 if (IS_VOLATILE (TETYPE (pbody)))
1498 /* we will walk the body in a pre-order traversal for
1500 switch (pbody->opval.op)
1502 /*------------------------------------------------------------------*/
1504 return isConformingBody (pbody->right, sym, body);
1506 /*------------------------------------------------------------------*/
1511 /*------------------------------------------------------------------*/
1512 case INC_OP: /* incerement operator unary so left only */
1515 /* sure we are not sym is not modified */
1517 IS_AST_SYM_VALUE (pbody->left) &&
1518 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1522 IS_AST_SYM_VALUE (pbody->right) &&
1523 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1528 /*------------------------------------------------------------------*/
1530 case '*': /* can be unary : if right is null then unary operation */
1535 /* if right is NULL then unary operation */
1536 /*------------------------------------------------------------------*/
1537 /*----------------------------*/
1539 /*----------------------------*/
1542 if (IS_AST_SYM_VALUE (pbody->left) &&
1543 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1546 return isConformingBody (pbody->left, sym, body);
1550 if (astHasSymbol (pbody->left, sym) ||
1551 astHasSymbol (pbody->right, sym))
1556 /*------------------------------------------------------------------*/
1564 if (IS_AST_SYM_VALUE (pbody->left) &&
1565 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1568 if (IS_AST_SYM_VALUE (pbody->right) &&
1569 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1572 return isConformingBody (pbody->left, sym, body) &&
1573 isConformingBody (pbody->right, sym, body);
1580 if (IS_AST_SYM_VALUE (pbody->left) &&
1581 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1583 return isConformingBody (pbody->left, sym, body);
1585 /*------------------------------------------------------------------*/
1597 case SIZEOF: /* evaluate wihout code generation */
1599 return isConformingBody (pbody->left, sym, body) &&
1600 isConformingBody (pbody->right, sym, body);
1602 /*------------------------------------------------------------------*/
1605 /* if left has a pointer & right has loop
1606 control variable then we cannot */
1607 if (astHasPointer (pbody->left) &&
1608 astHasSymbol (pbody->right, sym))
1610 if (astHasVolatile (pbody->left))
1613 if (IS_AST_SYM_VALUE (pbody->left) &&
1614 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1617 if (astHasVolatile (pbody->left))
1620 if (astHasDeref(pbody->right)) return FALSE;
1622 return isConformingBody (pbody->left, sym, body) &&
1623 isConformingBody (pbody->right, sym, body);
1634 assert ("Parser should not have generated this\n");
1636 /*------------------------------------------------------------------*/
1637 /*----------------------------*/
1638 /* comma operator */
1639 /*----------------------------*/
1641 return isConformingBody (pbody->left, sym, body) &&
1642 isConformingBody (pbody->right, sym, body);
1644 /*------------------------------------------------------------------*/
1645 /*----------------------------*/
1647 /*----------------------------*/
1651 /*------------------------------------------------------------------*/
1652 /*----------------------------*/
1653 /* return statement */
1654 /*----------------------------*/
1659 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1664 if (astHasSymbol (pbody->left, sym))
1671 return isConformingBody (pbody->left, sym, body) &&
1672 isConformingBody (pbody->right, sym, body);
1678 /*-----------------------------------------------------------------*/
1679 /* isLoopReversible - takes a for loop as input && returns true */
1680 /* if the for loop is reversible. If yes will set the value of */
1681 /* the loop control var & init value & termination value */
1682 /*-----------------------------------------------------------------*/
1684 isLoopReversible (ast * loop, symbol ** loopCntrl,
1685 ast ** init, ast ** end)
1687 /* if option says don't do it then don't */
1688 if (optimize.noLoopReverse)
1690 /* there are several tests to determine this */
1692 /* for loop has to be of the form
1693 for ( <sym> = <const1> ;
1694 [<sym> < <const2>] ;
1695 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1697 if (!isLoopCountable (AST_FOR (loop, initExpr),
1698 AST_FOR (loop, condExpr),
1699 AST_FOR (loop, loopExpr),
1700 loopCntrl, init, end))
1703 /* now do some serious checking on the body of the loop
1706 return isConformingBody (loop->left, *loopCntrl, loop->left);
1710 /*-----------------------------------------------------------------*/
1711 /* replLoopSym - replace the loop sym by loop sym -1 */
1712 /*-----------------------------------------------------------------*/
1714 replLoopSym (ast * body, symbol * sym)
1717 if (!body || IS_AST_LINK (body))
1720 if (IS_AST_SYM_VALUE (body))
1723 if (isSymbolEqual (AST_SYMBOL (body), sym))
1727 body->opval.op = '-';
1728 body->left = newAst_VALUE (symbolVal (sym));
1729 body->right = newAst_VALUE (constVal ("1"));
1737 replLoopSym (body->left, sym);
1738 replLoopSym (body->right, sym);
1742 /*-----------------------------------------------------------------*/
1743 /* reverseLoop - do the actual loop reversal */
1744 /*-----------------------------------------------------------------*/
1746 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1750 /* create the following tree
1755 if (sym) goto for_continue ;
1758 /* put it together piece by piece */
1759 rloop = newNode (NULLOP,
1760 createIf (newAst_VALUE (symbolVal (sym)),
1762 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1765 newAst_VALUE (symbolVal (sym)),
1768 replLoopSym (loop->left, sym);
1770 rloop = newNode (NULLOP,
1772 newAst_VALUE (symbolVal (sym)),
1773 newNode ('-', end, init)),
1774 createLabel (AST_FOR (loop, continueLabel),
1778 newNode (SUB_ASSIGN,
1779 newAst_VALUE (symbolVal (sym)),
1780 newAst_VALUE (constVal ("1"))),
1783 return decorateType (rloop);
1787 //#define DEMAND_INTEGER_PROMOTION
1789 #ifdef DEMAND_INTEGER_PROMOTION
1791 /*-----------------------------------------------------------------*/
1792 /* walk a tree looking for the leaves. Add a typecast to the given */
1793 /* type to each value leaf node. */
1794 /*-----------------------------------------------------------------*/
1796 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1798 if (!node || IS_CALLOP(node))
1800 /* WTF? We should never get here. */
1804 if (!node->left && !node->right)
1806 /* We're at a leaf; if it's a value, apply the typecast */
1807 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1809 *parentPtr = decorateType (newNode (CAST,
1810 newAst_LINK (copyLinkChain (type)),
1818 pushTypeCastToLeaves (type, node->left, &(node->left));
1822 pushTypeCastToLeaves (type, node->right, &(node->right));
1829 /*-----------------------------------------------------------------*/
1830 /* decorateType - compute type for this tree also does type cheking */
1831 /* this is done bottom up, since type have to flow upwards */
1832 /* it also does constant folding, and paramater checking */
1833 /*-----------------------------------------------------------------*/
1835 decorateType (ast * tree)
1843 /* if already has type then do nothing */
1844 if (tree->decorated)
1847 tree->decorated = 1;
1849 /* print the line */
1850 /* if not block & function */
1851 if (tree->type == EX_OP &&
1852 (tree->opval.op != FUNCTION &&
1853 tree->opval.op != BLOCK &&
1854 tree->opval.op != NULLOP))
1856 filename = tree->filename;
1857 lineno = tree->lineno;
1860 /* if any child is an error | this one is an error do nothing */
1861 if (tree->isError ||
1862 (tree->left && tree->left->isError) ||
1863 (tree->right && tree->right->isError))
1866 /*------------------------------------------------------------------*/
1867 /*----------------------------*/
1868 /* leaf has been reached */
1869 /*----------------------------*/
1870 /* if this is of type value */
1871 /* just get the type */
1872 if (tree->type == EX_VALUE)
1875 if (IS_LITERAL (tree->opval.val->etype))
1878 /* if this is a character array then declare it */
1879 if (IS_ARRAY (tree->opval.val->type))
1880 tree->opval.val = stringToSymbol (tree->opval.val);
1882 /* otherwise just copy the type information */
1883 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1887 if (tree->opval.val->sym)
1889 /* if the undefined flag is set then give error message */
1890 if (tree->opval.val->sym->undefined)
1892 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1894 TTYPE (tree) = TETYPE (tree) =
1895 tree->opval.val->type = tree->opval.val->sym->type =
1896 tree->opval.val->etype = tree->opval.val->sym->etype =
1897 copyLinkChain (INTTYPE);
1902 /* if impilicit i.e. struct/union member then no type */
1903 if (tree->opval.val->sym->implicit)
1904 TTYPE (tree) = TETYPE (tree) = NULL;
1909 /* else copy the type */
1910 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1912 /* and mark it as referenced */
1913 tree->opval.val->sym->isref = 1;
1921 /* if type link for the case of cast */
1922 if (tree->type == EX_LINK)
1924 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1931 dtl = decorateType (tree->left);
1932 dtr = decorateType (tree->right);
1934 /* this is to take care of situations
1935 when the tree gets rewritten */
1936 if (dtl != tree->left)
1938 if (dtr != tree->right)
1942 /* depending on type of operator do */
1944 switch (tree->opval.op)
1946 /*------------------------------------------------------------------*/
1947 /*----------------------------*/
1949 /*----------------------------*/
1952 /* determine which is the array & which the index */
1953 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1956 ast *tempTree = tree->left;
1957 tree->left = tree->right;
1958 tree->right = tempTree;
1961 /* first check if this is a array or a pointer */
1962 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1964 werror (E_NEED_ARRAY_PTR, "[]");
1965 goto errorTreeReturn;
1968 /* check if the type of the idx */
1969 if (!IS_INTEGRAL (RTYPE (tree)))
1971 werror (E_IDX_NOT_INT);
1972 goto errorTreeReturn;
1975 /* if the left is an rvalue then error */
1978 werror (E_LVALUE_REQUIRED, "array access");
1979 goto errorTreeReturn;
1982 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1983 if (IS_PTR(LTYPE(tree))) {
1984 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1988 /*------------------------------------------------------------------*/
1989 /*----------------------------*/
1991 /*----------------------------*/
1993 /* if this is not a structure */
1994 if (!IS_STRUCT (LTYPE (tree)))
1996 werror (E_STRUCT_UNION, ".");
1997 goto errorTreeReturn;
1999 TTYPE (tree) = structElemType (LTYPE (tree),
2000 (tree->right->type == EX_VALUE ?
2001 tree->right->opval.val : NULL));
2002 TETYPE (tree) = getSpec (TTYPE (tree));
2005 /*------------------------------------------------------------------*/
2006 /*----------------------------*/
2007 /* struct/union pointer */
2008 /*----------------------------*/
2010 /* if not pointer to a structure */
2011 if (!IS_PTR (LTYPE (tree)))
2013 werror (E_PTR_REQD);
2014 goto errorTreeReturn;
2017 if (!IS_STRUCT (LTYPE (tree)->next))
2019 werror (E_STRUCT_UNION, "->");
2020 goto errorTreeReturn;
2023 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2024 (tree->right->type == EX_VALUE ?
2025 tree->right->opval.val : NULL));
2026 TETYPE (tree) = getSpec (TTYPE (tree));
2029 /*------------------------------------------------------------------*/
2030 /*----------------------------*/
2031 /* ++/-- operation */
2032 /*----------------------------*/
2033 case INC_OP: /* incerement operator unary so left only */
2036 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2037 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2038 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2039 werror (E_CODE_WRITE, "++/--");
2048 /*------------------------------------------------------------------*/
2049 /*----------------------------*/
2051 /*----------------------------*/
2052 case '&': /* can be unary */
2053 /* if right is NULL then unary operation */
2054 if (tree->right) /* not an unary operation */
2057 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2059 werror (E_BITWISE_OP);
2060 werror (W_CONTINUE, "left & right types are ");
2061 printTypeChain (LTYPE (tree), stderr);
2062 fprintf (stderr, ",");
2063 printTypeChain (RTYPE (tree), stderr);
2064 fprintf (stderr, "\n");
2065 goto errorTreeReturn;
2068 /* if they are both literal */
2069 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2071 tree->type = EX_VALUE;
2072 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2073 valFromType (RETYPE (tree)), '&');
2075 tree->right = tree->left = NULL;
2076 TETYPE (tree) = tree->opval.val->etype;
2077 TTYPE (tree) = tree->opval.val->type;
2081 /* see if this is a GETHBIT operation if yes
2084 ast *otree = optimizeGetHbit (tree);
2087 return decorateType (otree);
2091 // we can't do this because of "(int & 0xff) << 3"
2093 /* if right or left is literal then result of that type */
2094 if (IS_LITERAL (RTYPE (tree)))
2097 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2098 TETYPE (tree) = getSpec (TTYPE (tree));
2099 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2103 if (IS_LITERAL (LTYPE (tree)))
2105 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2106 TETYPE (tree) = getSpec (TTYPE (tree));
2107 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2113 computeType (LTYPE (tree), RTYPE (tree));
2114 TETYPE (tree) = getSpec (TTYPE (tree));
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, "addrress 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;
2153 werror (E_LVALUE_REQUIRED, "address of");
2154 goto errorTreeReturn;
2156 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2158 DCL_TYPE (p) = CPOINTER;
2159 DCL_PTR_CONST (p) = port->mem.code_ro;
2161 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2162 DCL_TYPE (p) = FPOINTER;
2163 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2164 DCL_TYPE (p) = PPOINTER;
2165 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2166 DCL_TYPE (p) = IPOINTER;
2167 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2168 DCL_TYPE (p) = EEPPOINTER;
2170 DCL_TYPE (p) = POINTER;
2172 if (IS_AST_SYM_VALUE (tree->left))
2174 AST_SYMBOL (tree->left)->addrtaken = 1;
2175 AST_SYMBOL (tree->left)->allocreq = 1;
2178 p->next = LTYPE (tree);
2180 TETYPE (tree) = getSpec (TTYPE (tree));
2181 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2182 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2187 /*------------------------------------------------------------------*/
2188 /*----------------------------*/
2190 /*----------------------------*/
2192 /* if the rewrite succeeds then don't go any furthur */
2194 ast *wtree = optimizeRRCRLC (tree);
2196 return decorateType (wtree);
2198 /*------------------------------------------------------------------*/
2199 /*----------------------------*/
2201 /*----------------------------*/
2203 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2205 werror (E_BITWISE_OP);
2206 werror (W_CONTINUE, "left & right types are ");
2207 printTypeChain (LTYPE (tree), stderr);
2208 fprintf (stderr, ",");
2209 printTypeChain (RTYPE (tree), stderr);
2210 fprintf (stderr, "\n");
2211 goto errorTreeReturn;
2214 /* if they are both literal then */
2215 /* rewrite the tree */
2216 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2218 tree->type = EX_VALUE;
2219 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2220 valFromType (RETYPE (tree)),
2222 tree->right = tree->left = NULL;
2223 TETYPE (tree) = tree->opval.val->etype;
2224 TTYPE (tree) = tree->opval.val->type;
2227 LRVAL (tree) = RRVAL (tree) = 1;
2228 TETYPE (tree) = getSpec (TTYPE (tree) =
2229 computeType (LTYPE (tree),
2232 /*------------------------------------------------------------------*/
2233 /*----------------------------*/
2235 /*----------------------------*/
2237 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2239 werror (E_INVALID_OP, "divide");
2240 goto errorTreeReturn;
2242 /* if they are both literal then */
2243 /* rewrite the tree */
2244 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2246 tree->type = EX_VALUE;
2247 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2248 valFromType (RETYPE (tree)));
2249 tree->right = tree->left = NULL;
2250 TETYPE (tree) = getSpec (TTYPE (tree) =
2251 tree->opval.val->type);
2254 LRVAL (tree) = RRVAL (tree) = 1;
2255 TETYPE (tree) = getSpec (TTYPE (tree) =
2256 computeType (LTYPE (tree),
2260 /*------------------------------------------------------------------*/
2261 /*----------------------------*/
2263 /*----------------------------*/
2265 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2267 werror (E_BITWISE_OP);
2268 werror (W_CONTINUE, "left & right types are ");
2269 printTypeChain (LTYPE (tree), stderr);
2270 fprintf (stderr, ",");
2271 printTypeChain (RTYPE (tree), stderr);
2272 fprintf (stderr, "\n");
2273 goto errorTreeReturn;
2275 /* if they are both literal then */
2276 /* rewrite the tree */
2277 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2279 tree->type = EX_VALUE;
2280 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2281 valFromType (RETYPE (tree)));
2282 tree->right = tree->left = NULL;
2283 TETYPE (tree) = getSpec (TTYPE (tree) =
2284 tree->opval.val->type);
2287 LRVAL (tree) = RRVAL (tree) = 1;
2288 TETYPE (tree) = getSpec (TTYPE (tree) =
2289 computeType (LTYPE (tree),
2293 /*------------------------------------------------------------------*/
2294 /*----------------------------*/
2295 /* address dereference */
2296 /*----------------------------*/
2297 case '*': /* can be unary : if right is null then unary operation */
2300 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2302 werror (E_PTR_REQD);
2303 goto errorTreeReturn;
2308 werror (E_LVALUE_REQUIRED, "pointer deref");
2309 goto errorTreeReturn;
2311 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2312 LTYPE (tree)->next : NULL);
2313 TETYPE (tree) = getSpec (TTYPE (tree));
2314 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2318 /*------------------------------------------------------------------*/
2319 /*----------------------------*/
2320 /* multiplication */
2321 /*----------------------------*/
2322 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2324 werror (E_INVALID_OP, "multiplication");
2325 goto errorTreeReturn;
2328 /* if they are both literal then */
2329 /* rewrite the tree */
2330 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2332 tree->type = EX_VALUE;
2333 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2334 valFromType (RETYPE (tree)));
2335 tree->right = tree->left = NULL;
2336 TETYPE (tree) = getSpec (TTYPE (tree) =
2337 tree->opval.val->type);
2341 /* if left is a literal exchange left & right */
2342 if (IS_LITERAL (LTYPE (tree)))
2344 ast *tTree = tree->left;
2345 tree->left = tree->right;
2346 tree->right = tTree;
2349 LRVAL (tree) = RRVAL (tree) = 1;
2350 /* promote result to int if left & right are char
2351 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2352 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2353 TETYPE (tree) = getSpec (TTYPE (tree) =
2354 computeType (LTYPE (tree),
2356 SPEC_NOUN(TETYPE(tree)) = V_INT;
2358 TETYPE (tree) = getSpec (TTYPE (tree) =
2359 computeType (LTYPE (tree),
2364 /*------------------------------------------------------------------*/
2365 /*----------------------------*/
2366 /* unary '+' operator */
2367 /*----------------------------*/
2372 if (!IS_INTEGRAL (LTYPE (tree)))
2374 werror (E_UNARY_OP, '+');
2375 goto errorTreeReturn;
2378 /* if left is a literal then do it */
2379 if (IS_LITERAL (LTYPE (tree)))
2381 tree->type = EX_VALUE;
2382 tree->opval.val = valFromType (LETYPE (tree));
2384 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2388 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2395 /*----------------------------*/
2397 /* this is not a unary operation */
2398 /* if both pointers then problem */
2399 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2400 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2402 werror (E_PTR_PLUS_PTR);
2403 goto errorTreeReturn;
2406 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2407 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2409 werror (E_PLUS_INVALID, "+");
2410 goto errorTreeReturn;
2413 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2414 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2416 werror (E_PLUS_INVALID, "+");
2417 goto errorTreeReturn;
2419 /* if they are both literal then */
2420 /* rewrite the tree */
2421 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2423 tree->type = EX_VALUE;
2424 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2425 valFromType (RETYPE (tree)));
2426 tree->right = tree->left = NULL;
2427 TETYPE (tree) = getSpec (TTYPE (tree) =
2428 tree->opval.val->type);
2432 /* if the right is a pointer or left is a literal
2433 xchange left & right */
2434 if (IS_ARRAY (RTYPE (tree)) ||
2435 IS_PTR (RTYPE (tree)) ||
2436 IS_LITERAL (LTYPE (tree)))
2438 ast *tTree = tree->left;
2439 tree->left = tree->right;
2440 tree->right = tTree;
2443 LRVAL (tree) = RRVAL (tree) = 1;
2444 /* if the left is a pointer */
2445 if (IS_PTR (LTYPE (tree)))
2446 TETYPE (tree) = getSpec (TTYPE (tree) =
2449 TETYPE (tree) = getSpec (TTYPE (tree) =
2450 computeType (LTYPE (tree),
2454 /*------------------------------------------------------------------*/
2455 /*----------------------------*/
2457 /*----------------------------*/
2458 case '-': /* can be unary */
2459 /* if right is null then unary */
2463 if (!IS_ARITHMETIC (LTYPE (tree)))
2465 werror (E_UNARY_OP, tree->opval.op);
2466 goto errorTreeReturn;
2469 /* if left is a literal then do it */
2470 if (IS_LITERAL (LTYPE (tree)))
2472 tree->type = EX_VALUE;
2473 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2475 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2476 SPEC_USIGN(TETYPE(tree)) = 0;
2480 TTYPE (tree) = LTYPE (tree);
2484 /*------------------------------------------------------------------*/
2485 /*----------------------------*/
2487 /*----------------------------*/
2489 if (!(IS_PTR (LTYPE (tree)) ||
2490 IS_ARRAY (LTYPE (tree)) ||
2491 IS_ARITHMETIC (LTYPE (tree))))
2493 werror (E_PLUS_INVALID, "-");
2494 goto errorTreeReturn;
2497 if (!(IS_PTR (RTYPE (tree)) ||
2498 IS_ARRAY (RTYPE (tree)) ||
2499 IS_ARITHMETIC (RTYPE (tree))))
2501 werror (E_PLUS_INVALID, "-");
2502 goto errorTreeReturn;
2505 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2506 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2507 IS_INTEGRAL (RTYPE (tree))))
2509 werror (E_PLUS_INVALID, "-");
2510 goto errorTreeReturn;
2513 /* if they are both literal then */
2514 /* rewrite the tree */
2515 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2517 tree->type = EX_VALUE;
2518 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2519 valFromType (RETYPE (tree)));
2520 tree->right = tree->left = NULL;
2521 TETYPE (tree) = getSpec (TTYPE (tree) =
2522 tree->opval.val->type);
2526 /* if the left & right are equal then zero */
2527 if (isAstEqual (tree->left, tree->right))
2529 tree->type = EX_VALUE;
2530 tree->left = tree->right = NULL;
2531 tree->opval.val = constVal ("0");
2532 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2536 /* if both of them are pointers or arrays then */
2537 /* the result is going to be an integer */
2538 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2539 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2540 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2542 /* if only the left is a pointer */
2543 /* then result is a pointer */
2544 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2545 TETYPE (tree) = getSpec (TTYPE (tree) =
2548 TETYPE (tree) = getSpec (TTYPE (tree) =
2549 computeType (LTYPE (tree),
2551 LRVAL (tree) = RRVAL (tree) = 1;
2554 /*------------------------------------------------------------------*/
2555 /*----------------------------*/
2557 /*----------------------------*/
2559 /* can be only integral type */
2560 if (!IS_INTEGRAL (LTYPE (tree)))
2562 werror (E_UNARY_OP, tree->opval.op);
2563 goto errorTreeReturn;
2566 /* if left is a literal then do it */
2567 if (IS_LITERAL (LTYPE (tree)))
2569 tree->type = EX_VALUE;
2570 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2572 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2576 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2579 /*------------------------------------------------------------------*/
2580 /*----------------------------*/
2582 /*----------------------------*/
2584 /* can be pointer */
2585 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2586 !IS_PTR (LTYPE (tree)) &&
2587 !IS_ARRAY (LTYPE (tree)))
2589 werror (E_UNARY_OP, tree->opval.op);
2590 goto errorTreeReturn;
2593 /* if left is a literal then do it */
2594 if (IS_LITERAL (LTYPE (tree)))
2596 tree->type = EX_VALUE;
2597 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2599 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2603 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2606 /*------------------------------------------------------------------*/
2607 /*----------------------------*/
2609 /*----------------------------*/
2612 TTYPE (tree) = LTYPE (tree);
2613 TETYPE (tree) = LETYPE (tree);
2617 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2622 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2624 werror (E_SHIFT_OP_INVALID);
2625 werror (W_CONTINUE, "left & right types are ");
2626 printTypeChain (LTYPE (tree), stderr);
2627 fprintf (stderr, ",");
2628 printTypeChain (RTYPE (tree), stderr);
2629 fprintf (stderr, "\n");
2630 goto errorTreeReturn;
2633 /* if they are both literal then */
2634 /* rewrite the tree */
2635 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2637 tree->type = EX_VALUE;
2638 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2639 valFromType (RETYPE (tree)),
2640 (tree->opval.op == LEFT_OP ? 1 : 0));
2641 tree->right = tree->left = NULL;
2642 TETYPE (tree) = getSpec (TTYPE (tree) =
2643 tree->opval.val->type);
2646 /* if only the right side is a literal & we are
2647 shifting more than size of the left operand then zero */
2648 if (IS_LITERAL (RTYPE (tree)) &&
2649 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2650 (getSize (LTYPE (tree)) * 8))
2652 werror (W_SHIFT_CHANGED,
2653 (tree->opval.op == LEFT_OP ? "left" : "right"));
2654 tree->type = EX_VALUE;
2655 tree->left = tree->right = NULL;
2656 tree->opval.val = constVal ("0");
2657 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2660 LRVAL (tree) = RRVAL (tree) = 1;
2661 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2663 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2667 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2671 /*------------------------------------------------------------------*/
2672 /*----------------------------*/
2674 /*----------------------------*/
2675 case CAST: /* change the type */
2676 /* cannot cast to an aggregate type */
2677 if (IS_AGGREGATE (LTYPE (tree)))
2679 werror (E_CAST_ILLEGAL);
2680 goto errorTreeReturn;
2683 /* make sure the type is complete and sane */
2684 checkTypeSanity(LETYPE(tree), "(cast)");
2687 /* if the right is a literal replace the tree */
2688 if (IS_LITERAL (RETYPE (tree))) {
2689 if (!IS_PTR (LTYPE (tree))) {
2690 tree->type = EX_VALUE;
2692 valCastLiteral (LTYPE (tree),
2693 floatFromVal (valFromType (RETYPE (tree))));
2696 TTYPE (tree) = tree->opval.val->type;
2697 tree->values.literalFromCast = 1;
2698 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2699 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2700 sym_link *rest = LTYPE(tree)->next;
2701 werror(W_LITERAL_GENERIC);
2702 TTYPE(tree) = newLink();
2703 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2704 TTYPE(tree)->next = rest;
2705 tree->left->opval.lnk = TTYPE(tree);
2708 TTYPE (tree) = LTYPE (tree);
2712 TTYPE (tree) = LTYPE (tree);
2716 /* if the right is a literal replace the tree */
2717 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2718 tree->type = EX_VALUE;
2720 valCastLiteral (LTYPE (tree),
2721 floatFromVal (valFromType (RETYPE (tree))));
2724 TTYPE (tree) = tree->opval.val->type;
2725 tree->values.literalFromCast = 1;
2727 TTYPE (tree) = LTYPE (tree);
2732 TETYPE (tree) = getSpec (TTYPE (tree));
2736 /*------------------------------------------------------------------*/
2737 /*----------------------------*/
2738 /* logical &&, || */
2739 /*----------------------------*/
2742 /* each must me arithmetic type or be a pointer */
2743 if (!IS_PTR (LTYPE (tree)) &&
2744 !IS_ARRAY (LTYPE (tree)) &&
2745 !IS_INTEGRAL (LTYPE (tree)))
2747 werror (E_COMPARE_OP);
2748 goto errorTreeReturn;
2751 if (!IS_PTR (RTYPE (tree)) &&
2752 !IS_ARRAY (RTYPE (tree)) &&
2753 !IS_INTEGRAL (RTYPE (tree)))
2755 werror (E_COMPARE_OP);
2756 goto errorTreeReturn;
2758 /* if they are both literal then */
2759 /* rewrite the tree */
2760 if (IS_LITERAL (RTYPE (tree)) &&
2761 IS_LITERAL (LTYPE (tree)))
2763 tree->type = EX_VALUE;
2764 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2765 valFromType (RETYPE (tree)),
2767 tree->right = tree->left = NULL;
2768 TETYPE (tree) = getSpec (TTYPE (tree) =
2769 tree->opval.val->type);
2772 LRVAL (tree) = RRVAL (tree) = 1;
2773 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2776 /*------------------------------------------------------------------*/
2777 /*----------------------------*/
2778 /* comparison operators */
2779 /*----------------------------*/
2787 ast *lt = optimizeCompare (tree);
2793 /* if they are pointers they must be castable */
2794 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2796 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2798 werror (E_COMPARE_OP);
2799 fprintf (stderr, "comparing type ");
2800 printTypeChain (LTYPE (tree), stderr);
2801 fprintf (stderr, "to type ");
2802 printTypeChain (RTYPE (tree), stderr);
2803 fprintf (stderr, "\n");
2804 goto errorTreeReturn;
2807 /* else they should be promotable to one another */
2810 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2811 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2813 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2815 werror (E_COMPARE_OP);
2816 fprintf (stderr, "comparing type ");
2817 printTypeChain (LTYPE (tree), stderr);
2818 fprintf (stderr, "to type ");
2819 printTypeChain (RTYPE (tree), stderr);
2820 fprintf (stderr, "\n");
2821 goto errorTreeReturn;
2825 /* if they are both literal then */
2826 /* rewrite the tree */
2827 if (IS_LITERAL (RTYPE (tree)) &&
2828 IS_LITERAL (LTYPE (tree)))
2830 tree->type = EX_VALUE;
2831 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2832 valFromType (RETYPE (tree)),
2834 tree->right = tree->left = NULL;
2835 TETYPE (tree) = getSpec (TTYPE (tree) =
2836 tree->opval.val->type);
2839 LRVAL (tree) = RRVAL (tree) = 1;
2840 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2843 /*------------------------------------------------------------------*/
2844 /*----------------------------*/
2846 /*----------------------------*/
2847 case SIZEOF: /* evaluate wihout code generation */
2848 /* change the type to a integer */
2849 tree->type = EX_VALUE;
2850 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2851 tree->opval.val = constVal (buffer);
2852 tree->right = tree->left = NULL;
2853 TETYPE (tree) = getSpec (TTYPE (tree) =
2854 tree->opval.val->type);
2857 /*------------------------------------------------------------------*/
2858 /*----------------------------*/
2859 /* conditional operator '?' */
2860 /*----------------------------*/
2862 /* the type is value of the colon operator (on the right) */
2863 assert(IS_COLON_OP(tree->right));
2864 /* if already known then replace the tree : optimizer will do it
2865 but faster to do it here */
2866 if (IS_LITERAL (LTYPE(tree))) {
2867 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2868 return tree->right->left ;
2870 return tree->right->right ;
2873 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2874 TETYPE (tree) = getSpec (TTYPE (tree));
2879 /* if they don't match we have a problem */
2880 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2882 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2883 goto errorTreeReturn;
2886 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2887 TETYPE (tree) = getSpec (TTYPE (tree));
2891 /*------------------------------------------------------------------*/
2892 /*----------------------------*/
2893 /* assignment operators */
2894 /*----------------------------*/
2897 /* for these it must be both must be integral */
2898 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2899 !IS_ARITHMETIC (RTYPE (tree)))
2901 werror (E_OPS_INTEGRAL);
2902 goto errorTreeReturn;
2905 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2907 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2908 werror (E_CODE_WRITE, " ");
2912 werror (E_LVALUE_REQUIRED, "*= or /=");
2913 goto errorTreeReturn;
2924 /* for these it must be both must be integral */
2925 if (!IS_INTEGRAL (LTYPE (tree)) ||
2926 !IS_INTEGRAL (RTYPE (tree)))
2928 werror (E_OPS_INTEGRAL);
2929 goto errorTreeReturn;
2932 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2934 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2935 werror (E_CODE_WRITE, " ");
2939 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2940 goto errorTreeReturn;
2946 /*------------------------------------------------------------------*/
2947 /*----------------------------*/
2949 /*----------------------------*/
2951 if (!(IS_PTR (LTYPE (tree)) ||
2952 IS_ARITHMETIC (LTYPE (tree))))
2954 werror (E_PLUS_INVALID, "-=");
2955 goto errorTreeReturn;
2958 if (!(IS_PTR (RTYPE (tree)) ||
2959 IS_ARITHMETIC (RTYPE (tree))))
2961 werror (E_PLUS_INVALID, "-=");
2962 goto errorTreeReturn;
2965 TETYPE (tree) = getSpec (TTYPE (tree) =
2966 computeType (LTYPE (tree),
2969 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2970 werror (E_CODE_WRITE, " ");
2974 werror (E_LVALUE_REQUIRED, "-=");
2975 goto errorTreeReturn;
2981 /*------------------------------------------------------------------*/
2982 /*----------------------------*/
2984 /*----------------------------*/
2986 /* this is not a unary operation */
2987 /* if both pointers then problem */
2988 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2990 werror (E_PTR_PLUS_PTR);
2991 goto errorTreeReturn;
2994 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2996 werror (E_PLUS_INVALID, "+=");
2997 goto errorTreeReturn;
3000 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3002 werror (E_PLUS_INVALID, "+=");
3003 goto errorTreeReturn;
3006 TETYPE (tree) = getSpec (TTYPE (tree) =
3007 computeType (LTYPE (tree),
3010 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3011 werror (E_CODE_WRITE, " ");
3015 werror (E_LVALUE_REQUIRED, "+=");
3016 goto errorTreeReturn;
3019 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3020 tree->opval.op = '=';
3024 /*------------------------------------------------------------------*/
3025 /*----------------------------*/
3026 /* straight assignemnt */
3027 /*----------------------------*/
3029 /* cannot be an aggregate */
3030 if (IS_AGGREGATE (LTYPE (tree)))
3032 werror (E_AGGR_ASSIGN);
3033 goto errorTreeReturn;
3036 /* they should either match or be castable */
3037 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3039 werror (E_TYPE_MISMATCH, "assignment", " ");
3040 fprintf (stderr, "type --> '");
3041 printTypeChain (RTYPE (tree), stderr);
3042 fprintf (stderr, "' ");
3043 fprintf (stderr, "assigned to type --> '");
3044 printTypeChain (LTYPE (tree), stderr);
3045 fprintf (stderr, "'\n");
3046 goto errorTreeReturn;
3049 /* if the left side of the tree is of type void
3050 then report error */
3051 if (IS_VOID (LTYPE (tree)))
3053 werror (E_CAST_ZERO);
3054 fprintf (stderr, "type --> '");
3055 printTypeChain (RTYPE (tree), stderr);
3056 fprintf (stderr, "' ");
3057 fprintf (stderr, "assigned to type --> '");
3058 printTypeChain (LTYPE (tree), stderr);
3059 fprintf (stderr, "'\n");
3062 TETYPE (tree) = getSpec (TTYPE (tree) =
3066 if (!tree->initMode ) {
3067 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3068 werror (E_CODE_WRITE, " ");
3072 werror (E_LVALUE_REQUIRED, "=");
3073 goto errorTreeReturn;
3078 /*------------------------------------------------------------------*/
3079 /*----------------------------*/
3080 /* comma operator */
3081 /*----------------------------*/
3083 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3086 /*------------------------------------------------------------------*/
3087 /*----------------------------*/
3089 /*----------------------------*/
3093 if (processParms (tree->left,
3094 FUNC_ARGS(tree->left->ftype),
3095 tree->right, &parmNumber, TRUE))
3096 goto errorTreeReturn;
3098 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3100 //IFFUNC_ARGS(tree->left->ftype) =
3101 //reverseVal (IFFUNC_ARGS(tree->left->ftype));
3102 reverseParms (tree->right);
3105 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3108 /*------------------------------------------------------------------*/
3109 /*----------------------------*/
3110 /* return statement */
3111 /*----------------------------*/
3116 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3118 werror (W_RETURN_MISMATCH);
3119 fprintf (stderr, "from type '");
3120 printTypeChain (RTYPE(tree), stderr);
3121 fprintf (stderr, "' to type '");
3122 printTypeChain (currFunc->type->next, stderr);
3123 fprintf (stderr, "'\n");
3124 goto errorTreeReturn;
3127 if (IS_VOID (currFunc->type->next)
3129 !IS_VOID (RTYPE (tree)))
3131 werror (E_FUNC_VOID);
3132 goto errorTreeReturn;
3135 /* if there is going to be a casing required then add it */
3136 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3139 decorateType (newNode (CAST,
3140 newAst_LINK (copyLinkChain (currFunc->type->next)),
3149 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3151 werror (E_VOID_FUNC, currFunc->name);
3152 goto errorTreeReturn;
3155 TTYPE (tree) = TETYPE (tree) = NULL;
3158 /*------------------------------------------------------------------*/
3159 /*----------------------------*/
3160 /* switch statement */
3161 /*----------------------------*/
3163 /* the switch value must be an integer */
3164 if (!IS_INTEGRAL (LTYPE (tree)))
3166 werror (E_SWITCH_NON_INTEGER);
3167 goto errorTreeReturn;
3170 TTYPE (tree) = TETYPE (tree) = NULL;
3173 /*------------------------------------------------------------------*/
3174 /*----------------------------*/
3176 /*----------------------------*/
3178 tree->left = backPatchLabels (tree->left,
3181 TTYPE (tree) = TETYPE (tree) = NULL;
3184 /*------------------------------------------------------------------*/
3185 /*----------------------------*/
3187 /*----------------------------*/
3190 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3191 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3192 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3194 /* if the for loop is reversible then
3195 reverse it otherwise do what we normally
3201 if (isLoopReversible (tree, &sym, &init, &end))
3202 return reverseLoop (tree, sym, init, end);
3204 return decorateType (createFor (AST_FOR (tree, trueLabel),
3205 AST_FOR (tree, continueLabel),
3206 AST_FOR (tree, falseLabel),
3207 AST_FOR (tree, condLabel),
3208 AST_FOR (tree, initExpr),
3209 AST_FOR (tree, condExpr),
3210 AST_FOR (tree, loopExpr),
3214 TTYPE (tree) = TETYPE (tree) = NULL;
3218 /* some error found this tree will be killed */
3220 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3221 tree->opval.op = NULLOP;
3227 /*-----------------------------------------------------------------*/
3228 /* sizeofOp - processes size of operation */
3229 /*-----------------------------------------------------------------*/
3231 sizeofOp (sym_link * type)
3235 /* make sure the type is complete and sane */
3236 checkTypeSanity(type, "(sizeof)");
3238 /* get the size and convert it to character */
3239 sprintf (buff, "%d", getSize (type));
3241 /* now convert into value */
3242 return constVal (buff);
3246 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3247 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3248 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3249 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3250 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3251 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3252 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3254 /*-----------------------------------------------------------------*/
3255 /* backPatchLabels - change and or not operators to flow control */
3256 /*-----------------------------------------------------------------*/
3258 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3264 if (!(IS_ANDORNOT (tree)))
3267 /* if this an and */
3270 static int localLbl = 0;
3273 sprintf (buffer, "_and_%d", localLbl++);
3274 localLabel = newSymbol (buffer, NestLevel);
3276 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3278 /* if left is already a IFX then just change the if true label in that */
3279 if (!IS_IFX (tree->left))
3280 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3282 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3283 /* right is a IFX then just join */
3284 if (IS_IFX (tree->right))
3285 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3287 tree->right = createLabel (localLabel, tree->right);
3288 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3290 return newNode (NULLOP, tree->left, tree->right);
3293 /* if this is an or operation */
3296 static int localLbl = 0;
3299 sprintf (buffer, "_or_%d", localLbl++);
3300 localLabel = newSymbol (buffer, NestLevel);
3302 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3304 /* if left is already a IFX then just change the if true label in that */
3305 if (!IS_IFX (tree->left))
3306 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3308 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3309 /* right is a IFX then just join */
3310 if (IS_IFX (tree->right))
3311 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3313 tree->right = createLabel (localLabel, tree->right);
3314 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3316 return newNode (NULLOP, tree->left, tree->right);
3322 int wasnot = IS_NOT (tree->left);
3323 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3325 /* if the left is already a IFX */
3326 if (!IS_IFX (tree->left))
3327 tree->left = newNode (IFX, tree->left, NULL);
3331 tree->left->trueLabel = trueLabel;
3332 tree->left->falseLabel = falseLabel;
3336 tree->left->trueLabel = falseLabel;
3337 tree->left->falseLabel = trueLabel;
3344 tree->trueLabel = trueLabel;
3345 tree->falseLabel = falseLabel;
3352 /*-----------------------------------------------------------------*/
3353 /* createBlock - create expression tree for block */
3354 /*-----------------------------------------------------------------*/
3356 createBlock (symbol * decl, ast * body)
3360 /* if the block has nothing */
3364 ex = newNode (BLOCK, NULL, body);
3365 ex->values.sym = decl;
3367 ex->right = ex->right;
3373 /*-----------------------------------------------------------------*/
3374 /* createLabel - creates the expression tree for labels */
3375 /*-----------------------------------------------------------------*/
3377 createLabel (symbol * label, ast * stmnt)
3380 char name[SDCC_NAME_MAX + 1];
3383 /* must create fresh symbol if the symbol name */
3384 /* exists in the symbol table, since there can */
3385 /* be a variable with the same name as the labl */
3386 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3387 (csym->level == label->level))
3388 label = newSymbol (label->name, label->level);
3390 /* change the name before putting it in add _ */
3391 sprintf (name, "%s", label->name);
3393 /* put the label in the LabelSymbol table */
3394 /* but first check if a label of the same */
3396 if ((csym = findSym (LabelTab, NULL, name)))
3397 werror (E_DUPLICATE_LABEL, label->name);
3399 addSym (LabelTab, label, name, label->level, 0, 0);
3402 label->key = labelKey++;
3403 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3409 /*-----------------------------------------------------------------*/
3410 /* createCase - generates the parsetree for a case statement */
3411 /*-----------------------------------------------------------------*/
3413 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3415 char caseLbl[SDCC_NAME_MAX + 1];
3419 /* if the switch statement does not exist */
3420 /* then case is out of context */
3423 werror (E_CASE_CONTEXT);
3427 caseVal = decorateType (resolveSymbols (caseVal));
3428 /* if not a constant then error */
3429 if (!IS_LITERAL (caseVal->ftype))
3431 werror (E_CASE_CONSTANT);
3435 /* if not a integer than error */
3436 if (!IS_INTEGRAL (caseVal->ftype))
3438 werror (E_CASE_NON_INTEGER);
3442 /* find the end of the switch values chain */
3443 if (!(val = swStat->values.switchVals.swVals))
3444 swStat->values.switchVals.swVals = caseVal->opval.val;
3447 /* also order the cases according to value */
3449 int cVal = (int) floatFromVal (caseVal->opval.val);
3450 while (val && (int) floatFromVal (val) < cVal)
3456 /* if we reached the end then */
3459 pval->next = caseVal->opval.val;
3463 /* we found a value greater than */
3464 /* the current value we must add this */
3465 /* before the value */
3466 caseVal->opval.val->next = val;
3468 /* if this was the first in chain */
3469 if (swStat->values.switchVals.swVals == val)
3470 swStat->values.switchVals.swVals =
3473 pval->next = caseVal->opval.val;
3478 /* create the case label */
3479 sprintf (caseLbl, "_case_%d_%d",
3480 swStat->values.switchVals.swNum,
3481 (int) floatFromVal (caseVal->opval.val));
3483 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3488 /*-----------------------------------------------------------------*/
3489 /* createDefault - creates the parse tree for the default statement */
3490 /*-----------------------------------------------------------------*/
3492 createDefault (ast * swStat, ast * stmnt)
3494 char defLbl[SDCC_NAME_MAX + 1];
3496 /* if the switch statement does not exist */
3497 /* then case is out of context */
3500 werror (E_CASE_CONTEXT);
3504 /* turn on the default flag */
3505 swStat->values.switchVals.swDefault = 1;
3507 /* create the label */
3508 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3509 return createLabel (newSymbol (defLbl, 0), stmnt);
3512 /*-----------------------------------------------------------------*/
3513 /* createIf - creates the parsetree for the if statement */
3514 /*-----------------------------------------------------------------*/
3516 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3518 static int Lblnum = 0;
3520 symbol *ifTrue, *ifFalse, *ifEnd;
3522 /* if neither exists */
3523 if (!elseBody && !ifBody) {
3524 // if there are no side effects (i++, j() etc)
3525 if (!hasSEFcalls(condAst)) {
3530 /* create the labels */
3531 sprintf (buffer, "_iffalse_%d", Lblnum);
3532 ifFalse = newSymbol (buffer, NestLevel);
3533 /* if no else body then end == false */
3538 sprintf (buffer, "_ifend_%d", Lblnum);
3539 ifEnd = newSymbol (buffer, NestLevel);
3542 sprintf (buffer, "_iftrue_%d", Lblnum);
3543 ifTrue = newSymbol (buffer, NestLevel);
3547 /* attach the ifTrue label to the top of it body */
3548 ifBody = createLabel (ifTrue, ifBody);
3549 /* attach a goto end to the ifBody if else is present */
3552 ifBody = newNode (NULLOP, ifBody,
3554 newAst_VALUE (symbolVal (ifEnd)),
3556 /* put the elseLabel on the else body */
3557 elseBody = createLabel (ifFalse, elseBody);
3558 /* out the end at the end of the body */
3559 elseBody = newNode (NULLOP,
3561 createLabel (ifEnd, NULL));
3565 ifBody = newNode (NULLOP, ifBody,
3566 createLabel (ifFalse, NULL));
3568 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3569 if (IS_IFX (condAst))
3572 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3574 return newNode (NULLOP, ifTree,
3575 newNode (NULLOP, ifBody, elseBody));
3579 /*-----------------------------------------------------------------*/
3580 /* createDo - creates parse tree for do */
3583 /* _docontinue_n: */
3584 /* condition_expression +-> trueLabel -> _dobody_n */
3586 /* +-> falseLabel-> _dobreak_n */
3588 /*-----------------------------------------------------------------*/
3590 createDo (symbol * trueLabel, symbol * continueLabel,
3591 symbol * falseLabel, ast * condAst, ast * doBody)
3596 /* if the body does not exist then it is simple */
3599 condAst = backPatchLabels (condAst, continueLabel, NULL);
3600 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3601 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3602 doTree->trueLabel = continueLabel;
3603 doTree->falseLabel = NULL;
3607 /* otherwise we have a body */
3608 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3610 /* attach the body label to the top */
3611 doBody = createLabel (trueLabel, doBody);
3612 /* attach the continue label to end of body */
3613 doBody = newNode (NULLOP, doBody,
3614 createLabel (continueLabel, NULL));
3616 /* now put the break label at the end */
3617 if (IS_IFX (condAst))
3620 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3622 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3624 /* putting it together */
3625 return newNode (NULLOP, doBody, doTree);
3628 /*-----------------------------------------------------------------*/
3629 /* createFor - creates parse tree for 'for' statement */
3632 /* condExpr +-> trueLabel -> _forbody_n */
3634 /* +-> falseLabel-> _forbreak_n */
3637 /* _forcontinue_n: */
3639 /* goto _forcond_n ; */
3641 /*-----------------------------------------------------------------*/
3643 createFor (symbol * trueLabel, symbol * continueLabel,
3644 symbol * falseLabel, symbol * condLabel,
3645 ast * initExpr, ast * condExpr, ast * loopExpr,
3650 /* if loopexpression not present then we can generate it */
3651 /* the same way as a while */
3653 return newNode (NULLOP, initExpr,
3654 createWhile (trueLabel, continueLabel,
3655 falseLabel, condExpr, forBody));
3656 /* vanilla for statement */
3657 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3659 if (condExpr && !IS_IFX (condExpr))
3660 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3663 /* attach condition label to condition */
3664 condExpr = createLabel (condLabel, condExpr);
3666 /* attach body label to body */
3667 forBody = createLabel (trueLabel, forBody);
3669 /* attach continue to forLoop expression & attach */
3670 /* goto the forcond @ and of loopExpression */
3671 loopExpr = createLabel (continueLabel,
3675 newAst_VALUE (symbolVal (condLabel)),
3677 /* now start putting them together */
3678 forTree = newNode (NULLOP, initExpr, condExpr);
3679 forTree = newNode (NULLOP, forTree, forBody);
3680 forTree = newNode (NULLOP, forTree, loopExpr);
3681 /* finally add the break label */
3682 forTree = newNode (NULLOP, forTree,
3683 createLabel (falseLabel, NULL));
3687 /*-----------------------------------------------------------------*/
3688 /* createWhile - creates parse tree for while statement */
3689 /* the while statement will be created as follows */
3691 /* _while_continue_n: */
3692 /* condition_expression +-> trueLabel -> _while_boby_n */
3694 /* +-> falseLabel -> _while_break_n */
3695 /* _while_body_n: */
3697 /* goto _while_continue_n */
3698 /* _while_break_n: */
3699 /*-----------------------------------------------------------------*/
3701 createWhile (symbol * trueLabel, symbol * continueLabel,
3702 symbol * falseLabel, ast * condExpr, ast * whileBody)
3706 /* put the continue label */
3707 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3708 condExpr = createLabel (continueLabel, condExpr);
3709 condExpr->lineno = 0;
3711 /* put the body label in front of the body */
3712 whileBody = createLabel (trueLabel, whileBody);
3713 whileBody->lineno = 0;
3714 /* put a jump to continue at the end of the body */
3715 /* and put break label at the end of the body */
3716 whileBody = newNode (NULLOP,
3719 newAst_VALUE (symbolVal (continueLabel)),
3720 createLabel (falseLabel, NULL)));
3722 /* put it all together */
3723 if (IS_IFX (condExpr))
3724 whileTree = condExpr;
3727 whileTree = newNode (IFX, condExpr, NULL);
3728 /* put the true & false labels in place */
3729 whileTree->trueLabel = trueLabel;
3730 whileTree->falseLabel = falseLabel;
3733 return newNode (NULLOP, whileTree, whileBody);
3736 /*-----------------------------------------------------------------*/
3737 /* optimizeGetHbit - get highest order bit of the expression */
3738 /*-----------------------------------------------------------------*/
3740 optimizeGetHbit (ast * tree)
3743 /* if this is not a bit and */
3744 if (!IS_BITAND (tree))
3747 /* will look for tree of the form
3748 ( expr >> ((sizeof expr) -1) ) & 1 */
3749 if (!IS_AST_LIT_VALUE (tree->right))
3752 if (AST_LIT_VALUE (tree->right) != 1)
3755 if (!IS_RIGHT_OP (tree->left))
3758 if (!IS_AST_LIT_VALUE (tree->left->right))
3761 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3762 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3765 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3769 /*-----------------------------------------------------------------*/
3770 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3771 /*-----------------------------------------------------------------*/
3773 optimizeRRCRLC (ast * root)
3775 /* will look for trees of the form
3776 (?expr << 1) | (?expr >> 7) or
3777 (?expr >> 7) | (?expr << 1) will make that
3778 into a RLC : operation ..
3780 (?expr >> 1) | (?expr << 7) or
3781 (?expr << 7) | (?expr >> 1) will make that
3782 into a RRC operation
3783 note : by 7 I mean (number of bits required to hold the
3785 /* if the root operations is not a | operation the not */
3786 if (!IS_BITOR (root))
3789 /* I have to think of a better way to match patterns this sucks */
3790 /* that aside let start looking for the first case : I use a the
3791 negative check a lot to improve the efficiency */
3792 /* (?expr << 1) | (?expr >> 7) */
3793 if (IS_LEFT_OP (root->left) &&
3794 IS_RIGHT_OP (root->right))
3797 if (!SPEC_USIGN (TETYPE (root->left->left)))
3800 if (!IS_AST_LIT_VALUE (root->left->right) ||
3801 !IS_AST_LIT_VALUE (root->right->right))
3804 /* make sure it is the same expression */
3805 if (!isAstEqual (root->left->left,
3809 if (AST_LIT_VALUE (root->left->right) != 1)
3812 if (AST_LIT_VALUE (root->right->right) !=
3813 (getSize (TTYPE (root->left->left)) * 8 - 1))
3816 /* whew got the first case : create the AST */
3817 return newNode (RLC, root->left->left, NULL);
3821 /* check for second case */
3822 /* (?expr >> 7) | (?expr << 1) */
3823 if (IS_LEFT_OP (root->right) &&
3824 IS_RIGHT_OP (root->left))
3827 if (!SPEC_USIGN (TETYPE (root->left->left)))
3830 if (!IS_AST_LIT_VALUE (root->left->right) ||
3831 !IS_AST_LIT_VALUE (root->right->right))
3834 /* make sure it is the same symbol */
3835 if (!isAstEqual (root->left->left,
3839 if (AST_LIT_VALUE (root->right->right) != 1)
3842 if (AST_LIT_VALUE (root->left->right) !=
3843 (getSize (TTYPE (root->left->left)) * 8 - 1))
3846 /* whew got the first case : create the AST */
3847 return newNode (RLC, root->left->left, NULL);
3852 /* third case for RRC */
3853 /* (?symbol >> 1) | (?symbol << 7) */
3854 if (IS_LEFT_OP (root->right) &&
3855 IS_RIGHT_OP (root->left))
3858 if (!SPEC_USIGN (TETYPE (root->left->left)))
3861 if (!IS_AST_LIT_VALUE (root->left->right) ||
3862 !IS_AST_LIT_VALUE (root->right->right))
3865 /* make sure it is the same symbol */
3866 if (!isAstEqual (root->left->left,
3870 if (AST_LIT_VALUE (root->left->right) != 1)
3873 if (AST_LIT_VALUE (root->right->right) !=
3874 (getSize (TTYPE (root->left->left)) * 8 - 1))
3877 /* whew got the first case : create the AST */
3878 return newNode (RRC, root->left->left, NULL);
3882 /* fourth and last case for now */
3883 /* (?symbol << 7) | (?symbol >> 1) */
3884 if (IS_RIGHT_OP (root->right) &&
3885 IS_LEFT_OP (root->left))
3888 if (!SPEC_USIGN (TETYPE (root->left->left)))
3891 if (!IS_AST_LIT_VALUE (root->left->right) ||
3892 !IS_AST_LIT_VALUE (root->right->right))
3895 /* make sure it is the same symbol */
3896 if (!isAstEqual (root->left->left,
3900 if (AST_LIT_VALUE (root->right->right) != 1)
3903 if (AST_LIT_VALUE (root->left->right) !=
3904 (getSize (TTYPE (root->left->left)) * 8 - 1))
3907 /* whew got the first case : create the AST */
3908 return newNode (RRC, root->left->left, NULL);
3912 /* not found return root */
3916 /*-----------------------------------------------------------------*/
3917 /* optimizeCompare - otimizes compares for bit variables */
3918 /*-----------------------------------------------------------------*/
3920 optimizeCompare (ast * root)
3922 ast *optExpr = NULL;
3925 unsigned int litValue;
3927 /* if nothing then return nothing */
3931 /* if not a compare op then do leaves */
3932 if (!IS_COMPARE_OP (root))
3934 root->left = optimizeCompare (root->left);
3935 root->right = optimizeCompare (root->right);
3939 /* if left & right are the same then depending
3940 of the operation do */
3941 if (isAstEqual (root->left, root->right))
3943 switch (root->opval.op)
3948 optExpr = newAst_VALUE (constVal ("0"));
3953 optExpr = newAst_VALUE (constVal ("1"));
3957 return decorateType (optExpr);
3960 vleft = (root->left->type == EX_VALUE ?
3961 root->left->opval.val : NULL);
3963 vright = (root->right->type == EX_VALUE ?
3964 root->right->opval.val : NULL);
3966 /* if left is a BITVAR in BITSPACE */
3967 /* and right is a LITERAL then opt- */
3968 /* imize else do nothing */
3969 if (vleft && vright &&
3970 IS_BITVAR (vleft->etype) &&
3971 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3972 IS_LITERAL (vright->etype))
3975 /* if right side > 1 then comparison may never succeed */
3976 if ((litValue = (int) floatFromVal (vright)) > 1)
3978 werror (W_BAD_COMPARE);
3984 switch (root->opval.op)
3986 case '>': /* bit value greater than 1 cannot be */
3987 werror (W_BAD_COMPARE);
3991 case '<': /* bit value < 1 means 0 */
3993 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3996 case LE_OP: /* bit value <= 1 means no check */
3997 optExpr = newAst_VALUE (vright);
4000 case GE_OP: /* bit value >= 1 means only check for = */
4002 optExpr = newAst_VALUE (vleft);
4007 { /* literal is zero */
4008 switch (root->opval.op)
4010 case '<': /* bit value < 0 cannot be */
4011 werror (W_BAD_COMPARE);
4015 case '>': /* bit value > 0 means 1 */
4017 optExpr = newAst_VALUE (vleft);
4020 case LE_OP: /* bit value <= 0 means no check */
4021 case GE_OP: /* bit value >= 0 means no check */
4022 werror (W_BAD_COMPARE);
4026 case EQ_OP: /* bit == 0 means ! of bit */
4027 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4031 return decorateType (resolveSymbols (optExpr));
4032 } /* end-of-if of BITVAR */
4037 /*-----------------------------------------------------------------*/
4038 /* addSymToBlock : adds the symbol to the first block we find */
4039 /*-----------------------------------------------------------------*/
4041 addSymToBlock (symbol * sym, ast * tree)
4043 /* reached end of tree or a leaf */
4044 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4048 if (IS_AST_OP (tree) &&
4049 tree->opval.op == BLOCK)
4052 symbol *lsym = copySymbol (sym);
4054 lsym->next = AST_VALUES (tree, sym);
4055 AST_VALUES (tree, sym) = lsym;
4059 addSymToBlock (sym, tree->left);
4060 addSymToBlock (sym, tree->right);
4063 /*-----------------------------------------------------------------*/
4064 /* processRegParms - do processing for register parameters */
4065 /*-----------------------------------------------------------------*/
4067 processRegParms (value * args, ast * body)
4071 if (IS_REGPARM (args->etype))
4072 addSymToBlock (args->sym, body);
4077 /*-----------------------------------------------------------------*/
4078 /* resetParmKey - resets the operandkeys for the symbols */
4079 /*-----------------------------------------------------------------*/
4080 DEFSETFUNC (resetParmKey)
4091 /*-----------------------------------------------------------------*/
4092 /* createFunction - This is the key node that calls the iCode for */
4093 /* generating the code for a function. Note code */
4094 /* is generated function by function, later when */
4095 /* add inter-procedural analysis this will change */
4096 /*-----------------------------------------------------------------*/
4098 createFunction (symbol * name, ast * body)
4104 iCode *piCode = NULL;
4106 /* if check function return 0 then some problem */
4107 if (checkFunction (name, NULL) == 0)
4110 /* create a dummy block if none exists */
4112 body = newNode (BLOCK, NULL, NULL);
4116 /* check if the function name already in the symbol table */
4117 if ((csym = findSym (SymbolTab, NULL, name->name)))
4120 /* special case for compiler defined functions
4121 we need to add the name to the publics list : this
4122 actually means we are now compiling the compiler
4126 addSet (&publics, name);
4132 allocVariables (name);
4134 name->lastLine = yylineno;
4136 processFuncArgs (currFunc, 0);
4138 /* set the stack pointer */
4139 /* PENDING: check this for the mcs51 */
4140 stackPtr = -port->stack.direction * port->stack.call_overhead;
4141 if (IFFUNC_ISISR (name->type))
4142 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4143 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4144 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4146 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4148 fetype = getSpec (name->type); /* get the specifier for the function */
4149 /* if this is a reentrant function then */
4150 if (IFFUNC_ISREENT (name->type))
4153 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4155 /* do processing for parameters that are passed in registers */
4156 processRegParms (FUNC_ARGS(name->type), body);
4158 /* set the stack pointer */
4162 /* allocate & autoinit the block variables */
4163 processBlockVars (body, &stack, ALLOCATE);
4165 /* save the stack information */
4166 if (options.useXstack)
4167 name->xstack = SPEC_STAK (fetype) = stack;
4169 name->stack = SPEC_STAK (fetype) = stack;
4171 /* name needs to be mangled */
4172 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4174 body = resolveSymbols (body); /* resolve the symbols */
4175 body = decorateType (body); /* propagateType & do semantic checks */
4177 ex = newAst_VALUE (symbolVal (name)); /* create name */
4178 ex = newNode (FUNCTION, ex, body);
4179 ex->values.args = FUNC_ARGS(name->type);
4183 werror (E_FUNC_NO_CODE, name->name);
4187 /* create the node & generate intermediate code */
4189 codeOutFile = code->oFile;
4190 piCode = iCodeFromAst (ex);
4194 werror (E_FUNC_NO_CODE, name->name);
4198 eBBlockFromiCode (piCode);
4200 /* if there are any statics then do them */
4203 GcurMemmap = statsg;
4204 codeOutFile = statsg->oFile;
4205 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4211 /* dealloc the block variables */
4212 processBlockVars (body, &stack, DEALLOCATE);
4213 /* deallocate paramaters */
4214 deallocParms (FUNC_ARGS(name->type));
4216 if (IFFUNC_ISREENT (name->type))
4219 /* we are done freeup memory & cleanup */
4223 FUNC_HASBODY(name->type) = 1;
4224 addSet (&operKeyReset, name);
4225 applyToSet (operKeyReset, resetParmKey);
4228 cdbStructBlock (1, cdbFile);
4230 cleanUpLevel (LabelTab, 0);
4231 cleanUpBlock (StructTab, 1);
4232 cleanUpBlock (TypedefTab, 1);
4234 xstack->syms = NULL;
4235 istack->syms = NULL;
4240 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4241 /*-----------------------------------------------------------------*/
4242 /* ast_print : prints the ast (for debugging purposes) */
4243 /*-----------------------------------------------------------------*/
4245 void ast_print (ast * tree, FILE *outfile, int indent)
4250 /* can print only decorated trees */
4251 if (!tree->decorated) return;
4253 /* if any child is an error | this one is an error do nothing */
4254 if (tree->isError ||
4255 (tree->left && tree->left->isError) ||
4256 (tree->right && tree->right->isError)) {
4257 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4261 /* print the line */
4262 /* if not block & function */
4263 if (tree->type == EX_OP &&
4264 (tree->opval.op != FUNCTION &&
4265 tree->opval.op != BLOCK &&
4266 tree->opval.op != NULLOP)) {
4269 if (tree->opval.op == FUNCTION) {
4270 fprintf(outfile,"FUNCTION (%p) type (",tree);
4271 printTypeChain (tree->ftype,outfile);
4272 fprintf(outfile,")\n");
4273 ast_print(tree->left,outfile,indent+4);
4274 ast_print(tree->right,outfile,indent+4);
4277 if (tree->opval.op == BLOCK) {
4278 symbol *decls = tree->values.sym;
4279 fprintf(outfile,"{\n");
4281 INDENT(indent+4,outfile);
4282 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4283 printTypeChain(decls->type,outfile);
4284 fprintf(outfile,")\n");
4286 decls = decls->next;
4288 ast_print(tree->right,outfile,indent+4);
4289 fprintf(outfile,"}\n");
4292 if (tree->opval.op == NULLOP) {
4293 fprintf(outfile,"\n");
4294 ast_print(tree->left,outfile,indent);
4295 fprintf(outfile,"\n");
4296 ast_print(tree->right,outfile,indent);
4299 INDENT(indent,outfile);
4301 /*------------------------------------------------------------------*/
4302 /*----------------------------*/
4303 /* leaf has been reached */
4304 /*----------------------------*/
4305 /* if this is of type value */
4306 /* just get the type */
4307 if (tree->type == EX_VALUE) {
4309 if (IS_LITERAL (tree->opval.val->etype)) {
4310 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4311 (int) floatFromVal(tree->opval.val),
4312 (int) floatFromVal(tree->opval.val),
4313 floatFromVal(tree->opval.val));
4314 } else if (tree->opval.val->sym) {
4315 /* if the undefined flag is set then give error message */
4316 if (tree->opval.val->sym->undefined) {
4317 fprintf(outfile,"UNDEFINED SYMBOL ");
4319 fprintf(outfile,"SYMBOL ");
4321 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4324 fprintf(outfile," type (");
4325 printTypeChain(tree->ftype,outfile);
4326 fprintf(outfile,")\n");
4328 fprintf(outfile,"\n");
4333 /* if type link for the case of cast */
4334 if (tree->type == EX_LINK) {
4335 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4336 printTypeChain(tree->opval.lnk,outfile);
4337 fprintf(outfile,")\n");
4342 /* depending on type of operator do */
4344 switch (tree->opval.op) {
4345 /*------------------------------------------------------------------*/
4346 /*----------------------------*/
4348 /*----------------------------*/
4350 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4351 printTypeChain(tree->ftype,outfile);
4352 fprintf(outfile,")\n");
4353 ast_print(tree->left,outfile,indent+4);
4354 ast_print(tree->right,outfile,indent+4);
4357 /*------------------------------------------------------------------*/
4358 /*----------------------------*/
4360 /*----------------------------*/
4362 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4363 printTypeChain(tree->ftype,outfile);
4364 fprintf(outfile,")\n");
4365 ast_print(tree->left,outfile,indent+4);
4366 ast_print(tree->right,outfile,indent+4);
4369 /*------------------------------------------------------------------*/
4370 /*----------------------------*/
4371 /* struct/union pointer */
4372 /*----------------------------*/
4374 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4375 printTypeChain(tree->ftype,outfile);
4376 fprintf(outfile,")\n");
4377 ast_print(tree->left,outfile,indent+4);
4378 ast_print(tree->right,outfile,indent+4);
4381 /*------------------------------------------------------------------*/
4382 /*----------------------------*/
4383 /* ++/-- operation */
4384 /*----------------------------*/
4385 case INC_OP: /* incerement operator unary so left only */
4386 fprintf(outfile,"INC_OP (%p) type (",tree);
4387 printTypeChain(tree->ftype,outfile);
4388 fprintf(outfile,")\n");
4389 ast_print(tree->left,outfile,indent+4);
4393 fprintf(outfile,"DEC_OP (%p) type (",tree);
4394 printTypeChain(tree->ftype,outfile);
4395 fprintf(outfile,")\n");
4396 ast_print(tree->left,outfile,indent+4);
4399 /*------------------------------------------------------------------*/
4400 /*----------------------------*/
4402 /*----------------------------*/
4405 fprintf(outfile,"& (%p) type (",tree);
4406 printTypeChain(tree->ftype,outfile);
4407 fprintf(outfile,")\n");
4408 ast_print(tree->left,outfile,indent+4);
4409 ast_print(tree->right,outfile,indent+4);
4411 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4412 printTypeChain(tree->ftype,outfile);
4413 fprintf(outfile,")\n");
4414 ast_print(tree->left,outfile,indent+4);
4415 ast_print(tree->right,outfile,indent+4);
4418 /*----------------------------*/
4420 /*----------------------------*/
4422 fprintf(outfile,"OR (%p) type (",tree);
4423 printTypeChain(tree->ftype,outfile);
4424 fprintf(outfile,")\n");
4425 ast_print(tree->left,outfile,indent+4);
4426 ast_print(tree->right,outfile,indent+4);
4428 /*------------------------------------------------------------------*/
4429 /*----------------------------*/
4431 /*----------------------------*/
4433 fprintf(outfile,"XOR (%p) type (",tree);
4434 printTypeChain(tree->ftype,outfile);
4435 fprintf(outfile,")\n");
4436 ast_print(tree->left,outfile,indent+4);
4437 ast_print(tree->right,outfile,indent+4);
4440 /*------------------------------------------------------------------*/
4441 /*----------------------------*/
4443 /*----------------------------*/
4445 fprintf(outfile,"DIV (%p) type (",tree);
4446 printTypeChain(tree->ftype,outfile);
4447 fprintf(outfile,")\n");
4448 ast_print(tree->left,outfile,indent+4);
4449 ast_print(tree->right,outfile,indent+4);
4451 /*------------------------------------------------------------------*/
4452 /*----------------------------*/
4454 /*----------------------------*/
4456 fprintf(outfile,"MOD (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+4);
4460 ast_print(tree->right,outfile,indent+4);
4463 /*------------------------------------------------------------------*/
4464 /*----------------------------*/
4465 /* address dereference */
4466 /*----------------------------*/
4467 case '*': /* can be unary : if right is null then unary operation */
4469 fprintf(outfile,"DEREF (%p) type (",tree);
4470 printTypeChain(tree->ftype,outfile);
4471 fprintf(outfile,")\n");
4472 ast_print(tree->left,outfile,indent+4);
4475 /*------------------------------------------------------------------*/
4476 /*----------------------------*/
4477 /* multiplication */
4478 /*----------------------------*/
4479 fprintf(outfile,"MULT (%p) type (",tree);
4480 printTypeChain(tree->ftype,outfile);
4481 fprintf(outfile,")\n");
4482 ast_print(tree->left,outfile,indent+4);
4483 ast_print(tree->right,outfile,indent+4);
4487 /*------------------------------------------------------------------*/
4488 /*----------------------------*/
4489 /* unary '+' operator */
4490 /*----------------------------*/
4494 fprintf(outfile,"UPLUS (%p) type (",tree);
4495 printTypeChain(tree->ftype,outfile);
4496 fprintf(outfile,")\n");
4497 ast_print(tree->left,outfile,indent+4);
4499 /*------------------------------------------------------------------*/
4500 /*----------------------------*/
4502 /*----------------------------*/
4503 fprintf(outfile,"ADD (%p) type (",tree);
4504 printTypeChain(tree->ftype,outfile);
4505 fprintf(outfile,")\n");
4506 ast_print(tree->left,outfile,indent+4);
4507 ast_print(tree->right,outfile,indent+4);
4510 /*------------------------------------------------------------------*/
4511 /*----------------------------*/
4513 /*----------------------------*/
4514 case '-': /* can be unary */
4516 fprintf(outfile,"UMINUS (%p) type (",tree);
4517 printTypeChain(tree->ftype,outfile);
4518 fprintf(outfile,")\n");
4519 ast_print(tree->left,outfile,indent+4);
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4524 /*----------------------------*/
4525 fprintf(outfile,"SUB (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+4);
4529 ast_print(tree->right,outfile,indent+4);
4532 /*------------------------------------------------------------------*/
4533 /*----------------------------*/
4535 /*----------------------------*/
4537 fprintf(outfile,"COMPL (%p) type (",tree);
4538 printTypeChain(tree->ftype,outfile);
4539 fprintf(outfile,")\n");
4540 ast_print(tree->left,outfile,indent+4);
4542 /*------------------------------------------------------------------*/
4543 /*----------------------------*/
4545 /*----------------------------*/
4547 fprintf(outfile,"NOT (%p) type (",tree);
4548 printTypeChain(tree->ftype,outfile);
4549 fprintf(outfile,")\n");
4550 ast_print(tree->left,outfile,indent+4);
4552 /*------------------------------------------------------------------*/
4553 /*----------------------------*/
4555 /*----------------------------*/
4557 fprintf(outfile,"RRC (%p) type (",tree);
4558 printTypeChain(tree->ftype,outfile);
4559 fprintf(outfile,")\n");
4560 ast_print(tree->left,outfile,indent+4);
4564 fprintf(outfile,"RLC (%p) type (",tree);
4565 printTypeChain(tree->ftype,outfile);
4566 fprintf(outfile,")\n");
4567 ast_print(tree->left,outfile,indent+4);
4570 fprintf(outfile,"GETHBIT (%p) type (",tree);
4571 printTypeChain(tree->ftype,outfile);
4572 fprintf(outfile,")\n");
4573 ast_print(tree->left,outfile,indent+4);
4576 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4577 printTypeChain(tree->ftype,outfile);
4578 fprintf(outfile,")\n");
4579 ast_print(tree->left,outfile,indent+4);
4580 ast_print(tree->right,outfile,indent+4);
4583 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4584 printTypeChain(tree->ftype,outfile);
4585 fprintf(outfile,")\n");
4586 ast_print(tree->left,outfile,indent+4);
4587 ast_print(tree->right,outfile,indent+4);
4589 /*------------------------------------------------------------------*/
4590 /*----------------------------*/
4592 /*----------------------------*/
4593 case CAST: /* change the type */
4594 fprintf(outfile,"CAST (%p) type (",tree);
4595 printTypeChain(tree->ftype,outfile);
4596 fprintf(outfile,")\n");
4597 ast_print(tree->right,outfile,indent+4);
4601 fprintf(outfile,"ANDAND (%p) type (",tree);
4602 printTypeChain(tree->ftype,outfile);
4603 fprintf(outfile,")\n");
4604 ast_print(tree->left,outfile,indent+4);
4605 ast_print(tree->right,outfile,indent+4);
4608 fprintf(outfile,"OROR (%p) type (",tree);
4609 printTypeChain(tree->ftype,outfile);
4610 fprintf(outfile,")\n");
4611 ast_print(tree->left,outfile,indent+4);
4612 ast_print(tree->right,outfile,indent+4);
4615 /*------------------------------------------------------------------*/
4616 /*----------------------------*/
4617 /* comparison operators */
4618 /*----------------------------*/
4620 fprintf(outfile,"GT(>) (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+4);
4624 ast_print(tree->right,outfile,indent+4);
4627 fprintf(outfile,"LT(<) (%p) type (",tree);
4628 printTypeChain(tree->ftype,outfile);
4629 fprintf(outfile,")\n");
4630 ast_print(tree->left,outfile,indent+4);
4631 ast_print(tree->right,outfile,indent+4);
4634 fprintf(outfile,"LE(<=) (%p) type (",tree);
4635 printTypeChain(tree->ftype,outfile);
4636 fprintf(outfile,")\n");
4637 ast_print(tree->left,outfile,indent+4);
4638 ast_print(tree->right,outfile,indent+4);
4641 fprintf(outfile,"GE(>=) (%p) type (",tree);
4642 printTypeChain(tree->ftype,outfile);
4643 fprintf(outfile,")\n");
4644 ast_print(tree->left,outfile,indent+4);
4645 ast_print(tree->right,outfile,indent+4);
4648 fprintf(outfile,"EQ(==) (%p) type (",tree);
4649 printTypeChain(tree->ftype,outfile);
4650 fprintf(outfile,")\n");
4651 ast_print(tree->left,outfile,indent+4);
4652 ast_print(tree->right,outfile,indent+4);
4655 fprintf(outfile,"NE(!=) (%p) type (",tree);
4656 printTypeChain(tree->ftype,outfile);
4657 fprintf(outfile,")\n");
4658 ast_print(tree->left,outfile,indent+4);
4659 ast_print(tree->right,outfile,indent+4);
4660 /*------------------------------------------------------------------*/
4661 /*----------------------------*/
4663 /*----------------------------*/
4664 case SIZEOF: /* evaluate wihout code generation */
4665 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4668 /*------------------------------------------------------------------*/
4669 /*----------------------------*/
4670 /* conditional operator '?' */
4671 /*----------------------------*/
4673 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4674 printTypeChain(tree->ftype,outfile);
4675 fprintf(outfile,")\n");
4676 ast_print(tree->left,outfile,indent+4);
4677 ast_print(tree->right,outfile,indent+4);
4681 fprintf(outfile,"COLON(:) (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->left,outfile,indent+4);
4685 ast_print(tree->right,outfile,indent+4);
4688 /*------------------------------------------------------------------*/
4689 /*----------------------------*/
4690 /* assignment operators */
4691 /*----------------------------*/
4693 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4694 printTypeChain(tree->ftype,outfile);
4695 fprintf(outfile,")\n");
4696 ast_print(tree->left,outfile,indent+4);
4697 ast_print(tree->right,outfile,indent+4);
4700 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4701 printTypeChain(tree->ftype,outfile);
4702 fprintf(outfile,")\n");
4703 ast_print(tree->left,outfile,indent+4);
4704 ast_print(tree->right,outfile,indent+4);
4707 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4708 printTypeChain(tree->ftype,outfile);
4709 fprintf(outfile,")\n");
4710 ast_print(tree->left,outfile,indent+4);
4711 ast_print(tree->right,outfile,indent+4);
4714 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+4);
4718 ast_print(tree->right,outfile,indent+4);
4721 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+4);
4725 ast_print(tree->right,outfile,indent+4);
4728 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+4);
4732 ast_print(tree->right,outfile,indent+4);
4735 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+4);
4739 ast_print(tree->right,outfile,indent+4);
4741 /*------------------------------------------------------------------*/
4742 /*----------------------------*/
4744 /*----------------------------*/
4746 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4747 printTypeChain(tree->ftype,outfile);
4748 fprintf(outfile,")\n");
4749 ast_print(tree->left,outfile,indent+4);
4750 ast_print(tree->right,outfile,indent+4);
4752 /*------------------------------------------------------------------*/
4753 /*----------------------------*/
4755 /*----------------------------*/
4757 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+4);
4761 ast_print(tree->right,outfile,indent+4);
4763 /*------------------------------------------------------------------*/
4764 /*----------------------------*/
4765 /* straight assignemnt */
4766 /*----------------------------*/
4768 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+4);
4772 ast_print(tree->right,outfile,indent+4);
4774 /*------------------------------------------------------------------*/
4775 /*----------------------------*/
4776 /* comma operator */
4777 /*----------------------------*/
4779 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4780 printTypeChain(tree->ftype,outfile);
4781 fprintf(outfile,")\n");
4782 ast_print(tree->left,outfile,indent+4);
4783 ast_print(tree->right,outfile,indent+4);
4785 /*------------------------------------------------------------------*/
4786 /*----------------------------*/
4788 /*----------------------------*/
4791 fprintf(outfile,"CALL (%p) type (",tree);
4792 printTypeChain(tree->ftype,outfile);
4793 fprintf(outfile,")\n");
4794 ast_print(tree->left,outfile,indent+4);
4795 ast_print(tree->right,outfile,indent+4);
4798 fprintf(outfile,"PARM ");
4799 ast_print(tree->left,outfile,indent+4);
4800 if (tree->right && !IS_AST_PARAM(tree->right)) {
4801 fprintf(outfile,"PARM ");
4802 ast_print(tree->right,outfile,indent+4);
4805 /*------------------------------------------------------------------*/
4806 /*----------------------------*/
4807 /* return statement */
4808 /*----------------------------*/
4810 fprintf(outfile,"RETURN (%p) type (",tree);
4811 printTypeChain(tree->right->ftype,outfile);
4812 fprintf(outfile,")\n");
4813 ast_print(tree->right,outfile,indent+4);
4815 /*------------------------------------------------------------------*/
4816 /*----------------------------*/
4817 /* label statement */
4818 /*----------------------------*/
4820 fprintf(outfile,"LABEL (%p)",tree);
4821 ast_print(tree->left,outfile,indent+4);
4822 ast_print(tree->right,outfile,indent);
4824 /*------------------------------------------------------------------*/
4825 /*----------------------------*/
4826 /* switch statement */
4827 /*----------------------------*/
4831 fprintf(outfile,"SWITCH (%p) ",tree);
4832 ast_print(tree->left,outfile,0);
4833 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4834 INDENT(indent+4,outfile);
4835 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4836 (int) floatFromVal(val),
4837 tree->values.switchVals.swNum,
4838 (int) floatFromVal(val));
4840 ast_print(tree->right,outfile,indent);
4843 /*------------------------------------------------------------------*/
4844 /*----------------------------*/
4846 /*----------------------------*/
4848 ast_print(tree->left,outfile,indent);
4849 INDENT(indent,outfile);
4850 fprintf(outfile,"IF (%p) \n",tree);
4851 if (tree->trueLabel) {
4852 INDENT(indent,outfile);
4853 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4855 if (tree->falseLabel) {
4856 INDENT(indent,outfile);
4857 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4859 ast_print(tree->right,outfile,indent);
4861 /*------------------------------------------------------------------*/
4862 /*----------------------------*/
4864 /*----------------------------*/
4866 fprintf(outfile,"FOR (%p) \n",tree);
4867 if (AST_FOR( tree, initExpr)) {
4868 INDENT(indent+4,outfile);
4869 fprintf(outfile,"INIT EXPR ");
4870 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4872 if (AST_FOR( tree, condExpr)) {
4873 INDENT(indent+4,outfile);
4874 fprintf(outfile,"COND EXPR ");
4875 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4877 if (AST_FOR( tree, loopExpr)) {
4878 INDENT(indent+4,outfile);
4879 fprintf(outfile,"LOOP EXPR ");
4880 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4882 fprintf(outfile,"FOR LOOP BODY \n");
4883 ast_print(tree->left,outfile,indent+4);
4892 ast_print(t,stdout,1);