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 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
74 newAst (int type, void *op)
77 static int oldLineno = 0;
79 Safe_calloc (1, ex, sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : yylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
88 /* depending on the type */
92 ex->opval.val = (value *) op;
95 ex->opval.op = (long) op;
98 ex->opval.lnk = (sym_link *) op;
101 ex->opval.stmnt = (unsigned) op;
109 newAst_ (unsigned type)
112 static int oldLineno = 0;
114 ex = Safe_calloc (1, sizeof (ast));
117 ex->lineno = (noLineno ? oldLineno : yylineno);
118 ex->filename = currFname;
119 ex->level = NestLevel;
120 ex->block = currBlockno;
121 ex->initMode = inInitMode;
126 newAst_VALUE (value * val)
128 ast *ex = newAst_ (EX_VALUE);
134 newAst_OP (unsigned op)
136 ast *ex = newAst_ (EX_OP);
142 newAst_LINK (sym_link * val)
144 ast *ex = newAst_ (EX_LINK);
150 newAst_STMNT (unsigned val)
152 ast *ex = newAst_ (EX_STMNT);
153 ex->opval.stmnt = val;
157 /*-----------------------------------------------------------------*/
158 /* newNode - creates a new node */
159 /*-----------------------------------------------------------------*/
161 newNode (long op, ast * left, ast * right)
172 /*-----------------------------------------------------------------*/
173 /* newIfxNode - creates a new Ifx Node */
174 /*-----------------------------------------------------------------*/
176 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
180 /* if this is a literal then we already know the result */
181 if (condAst->etype && IS_LITERAL (condAst->etype))
183 /* then depending on the expression value */
184 if (floatFromVal (condAst->opval.val))
185 ifxNode = newNode (GOTO,
186 newAst_VALUE (symbolVal (trueLabel)),
189 ifxNode = newNode (GOTO,
190 newAst_VALUE (symbolVal (falseLabel)),
195 ifxNode = newNode (IFX, condAst, NULL);
196 ifxNode->trueLabel = trueLabel;
197 ifxNode->falseLabel = falseLabel;
203 /*-----------------------------------------------------------------*/
204 /* copyAstValues - copies value portion of ast if needed */
205 /*-----------------------------------------------------------------*/
207 copyAstValues (ast * dest, ast * src)
209 switch (src->opval.op)
212 dest->values.sym = copySymbolChain (src->values.sym);
216 dest->values.switchVals.swVals =
217 copyValue (src->values.switchVals.swVals);
218 dest->values.switchVals.swDefault =
219 src->values.switchVals.swDefault;
220 dest->values.switchVals.swNum =
221 src->values.switchVals.swNum;
225 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
226 strcpy (dest->values.inlineasm, src->values.inlineasm);
229 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
230 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
231 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
232 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
233 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
234 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
235 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
240 /*-----------------------------------------------------------------*/
241 /* copyAst - makes a copy of a given astession */
242 /*-----------------------------------------------------------------*/
251 dest = Safe_calloc (1, sizeof (ast));
253 dest->type = src->type;
254 dest->lineno = src->lineno;
255 dest->level = src->level;
256 dest->funcName = src->funcName;
257 dest->argSym = src->argSym;
259 /* if this is a leaf */
261 if (src->type == EX_VALUE)
263 dest->opval.val = copyValue (src->opval.val);
268 if (src->type == EX_LINK)
270 dest->opval.lnk = copyLinkChain (src->opval.lnk);
274 dest->opval.op = src->opval.op;
276 /* if this is a node that has special values */
277 copyAstValues (dest, src);
280 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
282 dest->trueLabel = copySymbol (src->trueLabel);
283 dest->falseLabel = copySymbol (src->falseLabel);
284 dest->left = copyAst (src->left);
285 dest->right = copyAst (src->right);
291 /*-----------------------------------------------------------------*/
292 /* hasSEFcalls - returns TRUE if tree has a function call */
293 /*-----------------------------------------------------------------*/
295 hasSEFcalls (ast * tree)
300 if (tree->type == EX_OP &&
301 (tree->opval.op == CALL ||
302 tree->opval.op == PCALL ||
303 tree->opval.op == '=' ||
304 tree->opval.op == INC_OP ||
305 tree->opval.op == DEC_OP))
308 return (hasSEFcalls (tree->left) |
309 hasSEFcalls (tree->right));
312 /*-----------------------------------------------------------------*/
313 /* isAstEqual - compares two asts & returns 1 if they are equal */
314 /*-----------------------------------------------------------------*/
316 isAstEqual (ast * t1, ast * t2)
325 if (t1->type != t2->type)
331 if (t1->opval.op != t2->opval.op)
333 return (isAstEqual (t1->left, t2->left) &&
334 isAstEqual (t1->right, t2->right));
338 if (t1->opval.val->sym)
340 if (!t2->opval.val->sym)
343 return isSymbolEqual (t1->opval.val->sym,
348 if (t2->opval.val->sym)
351 return (floatFromVal (t1->opval.val) ==
352 floatFromVal (t2->opval.val));
356 /* only compare these two types */
364 /*-----------------------------------------------------------------*/
365 /* resolveSymbols - resolve symbols from the symbol table */
366 /*-----------------------------------------------------------------*/
368 resolveSymbols (ast * tree)
370 /* walk the entire tree and check for values */
371 /* with symbols if we find one then replace */
372 /* symbol with that from the symbol table */
378 /* if not block & function */
379 if (tree->type == EX_OP &&
380 (tree->opval.op != FUNCTION &&
381 tree->opval.op != BLOCK &&
382 tree->opval.op != NULLOP))
384 filename = tree->filename;
385 lineno = tree->lineno;
388 /* make sure we resolve the true & false labels for ifx */
389 if (tree->type == EX_OP && tree->opval.op == IFX)
395 if ((csym = findSym (LabelTab, tree->trueLabel,
396 tree->trueLabel->name)))
397 tree->trueLabel = csym;
399 werror (E_LABEL_UNDEF, tree->trueLabel->name);
402 if (tree->falseLabel)
404 if ((csym = findSym (LabelTab,
406 tree->falseLabel->name)))
407 tree->falseLabel = csym;
409 werror (E_LABEL_UNDEF, tree->falseLabel->name);
414 /* if this is a label resolve it from the labelTab */
415 if (IS_AST_VALUE (tree) &&
416 tree->opval.val->sym &&
417 tree->opval.val->sym->islbl)
420 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
421 tree->opval.val->sym->name);
424 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
426 tree->opval.val->sym = csym;
428 goto resolveChildren;
431 /* do only for leafs */
432 if (IS_AST_VALUE (tree) &&
433 tree->opval.val->sym &&
434 !tree->opval.val->sym->implicit)
437 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
439 /* if found in the symbol table & they r not the same */
440 if (csym && tree->opval.val->sym != csym)
442 tree->opval.val->sym = csym;
443 tree->opval.val->type = csym->type;
444 tree->opval.val->etype = csym->etype;
447 /* if not found in the symbol table */
448 /* mark it as undefined assume it is */
449 /* an integer in data space */
450 if (!csym && !tree->opval.val->sym->implicit)
453 /* if this is a function name then */
454 /* mark it as returning an int */
457 tree->opval.val->sym->type = newLink ();
458 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
459 tree->opval.val->sym->type->next =
460 tree->opval.val->sym->etype = newIntLink ();
461 tree->opval.val->etype = tree->opval.val->etype;
462 tree->opval.val->type = tree->opval.val->sym->type;
463 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
467 tree->opval.val->sym->undefined = 1;
468 tree->opval.val->type =
469 tree->opval.val->etype = newIntLink ();
470 tree->opval.val->sym->type =
471 tree->opval.val->sym->etype = newIntLink ();
477 resolveSymbols (tree->left);
478 resolveSymbols (tree->right);
483 /*-----------------------------------------------------------------*/
484 /* setAstLineno - walks a ast tree & sets the line number */
485 /*-----------------------------------------------------------------*/
487 setAstLineno (ast * tree, int lineno)
492 tree->lineno = lineno;
493 setAstLineno (tree->left, lineno);
494 setAstLineno (tree->right, lineno);
499 /* this functions seems to be superfluous?! kmh */
501 /*-----------------------------------------------------------------*/
502 /* resolveFromTable - will return the symbal table value */
503 /*-----------------------------------------------------------------*/
505 resolveFromTable (value * val)
512 csym = findSymWithLevel (SymbolTab, val->sym);
514 /* if found in the symbol table & they r not the same */
515 if (csym && val->sym != csym &&
516 csym->level == val->sym->level &&
522 val->type = csym->type;
523 val->etype = csym->etype;
530 /*-----------------------------------------------------------------*/
531 /* funcOfType :- function of type with name */
532 /*-----------------------------------------------------------------*/
534 funcOfType (char *name, sym_link * type, sym_link * argType,
538 /* create the symbol */
539 sym = newSymbol (name, 0);
541 /* if arguments required */
546 args = sym->args = newValue ();
550 args->type = copyLinkChain (argType);
551 args->etype = getSpec (args->type);
554 args = args->next = newValue ();
558 /* setup return value */
559 sym->type = newLink ();
560 DCL_TYPE (sym->type) = FUNCTION;
561 sym->type->next = copyLinkChain (type);
562 sym->etype = getSpec (sym->type);
563 SPEC_RENT (sym->etype) = rent;
568 allocVariables (sym);
573 /*-----------------------------------------------------------------*/
574 /* reverseParms - will reverse a parameter tree */
575 /*-----------------------------------------------------------------*/
577 reverseParms (ast * ptree)
583 /* top down if we find a nonParm tree then quit */
584 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
587 ptree->left = ptree->right;
588 ptree->right = ttree;
589 reverseParms (ptree->left);
590 reverseParms (ptree->right);
596 /*-----------------------------------------------------------------*/
597 /* processParms - makes sure the parameters are okay and do some */
598 /* processing with them */
599 /*-----------------------------------------------------------------*/
601 processParms (ast * func,
607 sym_link *fetype = func->etype;
609 /* if none of them exist */
610 if (!defParm && !actParm)
614 if (getenv("DEBUG_SANITY")) {
615 fprintf (stderr, "addSym: %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 && !IS_RENT (fetype) && !options.stackAuto)
626 werror (E_NONRENT_ARGS);
630 /* if defined parameters ended but actual parameters */
631 /* exist and this is not defined as a variable arg */
632 /* also check if statckAuto option is specified */
633 if ((!defParm) && actParm && (!func->hasVargs) &&
634 !options.stackAuto && !IS_RENT (fetype))
636 werror (E_TOO_MANY_PARMS);
640 /* if defined parameters present but no actual parameters */
641 if (defParm && !actParm)
643 werror (E_TOO_FEW_PARMS);
647 /* If this is a varargs function... */
648 if (!defParm && actParm && func->hasVargs)
653 if (IS_CAST_OP (actParm)
654 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
656 /* Parameter was explicitly typecast; don't touch it. */
660 /* The ternary ('?') operator is weird: the ftype of the
661 * operator is the type of the condition, but it will return a
662 * (possibly) different type.
664 if (IS_TERNARY_OP(actParm))
666 assert(IS_COLON_OP(actParm->right));
667 assert(actParm->right->left);
668 ftype = actParm->right->left->ftype;
672 ftype = actParm->ftype;
675 /* If it's a small integer, upcast to int. */
676 if (IS_INTEGRAL (ftype)
677 && (getSize (ftype) < (unsigned) INTSIZE))
679 newType = newAst_LINK(INTTYPE);
682 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
684 newType = newAst_LINK (copyLinkChain(ftype));
685 DCL_TYPE (newType->opval.lnk) = GPOINTER;
688 if (IS_AGGREGATE (ftype))
690 newType = newAst_LINK (copyLinkChain (ftype));
691 DCL_TYPE (newType->opval.lnk) = GPOINTER;
695 /* cast required; change this op to a cast. */
696 ast *parmCopy = resolveSymbols (copyAst (actParm));
698 actParm->type = EX_OP;
699 actParm->opval.op = CAST;
700 actParm->left = newType;
701 actParm->right = parmCopy;
702 decorateType (actParm);
704 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
706 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
707 processParms (func, NULL, actParm->right, parmNumber, rightmost));
712 /* if defined parameters ended but actual has not & */
714 if (!defParm && actParm &&
715 (options.stackAuto || IS_RENT (fetype)))
718 resolveSymbols (actParm);
719 /* if this is a PARAM node then match left & right */
720 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
722 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
723 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
727 /* If we have found a value node by following only right-hand links,
728 * then we know that there are no more values after us.
730 * Therefore, if there are more defined parameters, the caller didn't
733 if (rightmost && defParm->next)
735 werror (E_TOO_FEW_PARMS);
740 /* the parameter type must be at least castable */
741 if (compareType (defParm->type, actParm->ftype) == 0)
743 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
744 werror (E_CONTINUE, "defined type ");
745 printTypeChain (defParm->type, stderr);
746 fprintf (stderr, "\n");
747 werror (E_CONTINUE, "actual type ");
748 printTypeChain (actParm->ftype, stderr);
749 fprintf (stderr, "\n");
752 /* if the parameter is castable then add the cast */
753 if (compareType (defParm->type, actParm->ftype) < 0)
755 ast *pTree = resolveSymbols (copyAst (actParm));
757 /* now change the current one to a cast */
758 actParm->type = EX_OP;
759 actParm->opval.op = CAST;
760 actParm->left = newAst_LINK (defParm->type);
761 actParm->right = pTree;
762 actParm->etype = defParm->etype;
763 actParm->ftype = defParm->type;
766 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
768 actParm->argSym = defParm->sym;
769 /* make a copy and change the regparm type to the defined parm */
770 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
771 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
775 /*-----------------------------------------------------------------*/
776 /* createIvalType - generates ival for basic types */
777 /*-----------------------------------------------------------------*/
779 createIvalType (ast * sym, sym_link * type, initList * ilist)
783 /* if initList is deep */
784 if (ilist->type == INIT_DEEP)
785 ilist = ilist->init.deep;
787 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
788 return decorateType (newNode ('=', sym, iExpr));
791 /*-----------------------------------------------------------------*/
792 /* createIvalStruct - generates initial value for structures */
793 /*-----------------------------------------------------------------*/
795 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
801 sflds = SPEC_STRUCT (type)->fields;
802 if (ilist->type != INIT_DEEP)
804 werror (E_INIT_STRUCT, "");
808 iloop = ilist->init.deep;
810 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
814 /* if we have come to end */
818 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
819 lAst = decorateType (resolveSymbols (lAst));
820 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
826 /*-----------------------------------------------------------------*/
827 /* createIvalArray - generates code for array initialization */
828 /*-----------------------------------------------------------------*/
830 createIvalArray (ast * sym, sym_link * type, initList * ilist)
834 int lcnt = 0, size = 0;
836 /* take care of the special case */
837 /* array of characters can be init */
839 if (IS_CHAR (type->next))
840 if ((rast = createIvalCharPtr (sym,
842 decorateType (resolveSymbols (list2expr (ilist))))))
844 return decorateType (resolveSymbols (rast));
846 /* not the special case */
847 if (ilist->type != INIT_DEEP)
849 werror (E_INIT_STRUCT, "");
853 iloop = ilist->init.deep;
854 lcnt = DCL_ELEM (type);
861 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
862 aSym = decorateType (resolveSymbols (aSym));
863 rast = createIval (aSym, type->next, iloop, rast);
864 iloop = (iloop ? iloop->next : NULL);
867 /* if not array limits given & we */
868 /* are out of initialisers then */
869 if (!DCL_ELEM (type) && !iloop)
872 /* no of elements given and we */
873 /* have generated for all of them */
875 /* if initializers left */
877 // there has to be a better way
878 char *name=sym->opval.val->sym->name;
879 int lineno=sym->opval.val->sym->lineDef;
880 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
886 /* if we have not been given a size */
887 if (!DCL_ELEM (type))
888 DCL_ELEM (type) = size;
890 return decorateType (resolveSymbols (rast));
894 /*-----------------------------------------------------------------*/
895 /* createIvalCharPtr - generates initial values for char pointers */
896 /*-----------------------------------------------------------------*/
898 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
902 /* if this is a pointer & right is a literal array then */
903 /* just assignment will do */
904 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
905 SPEC_SCLS (iexpr->etype) == S_CODE)
906 && IS_ARRAY (iexpr->ftype)))
907 return newNode ('=', sym, iexpr);
909 /* left side is an array so we have to assign each */
911 if ((IS_LITERAL (iexpr->etype) ||
912 SPEC_SCLS (iexpr->etype) == S_CODE)
913 && IS_ARRAY (iexpr->ftype))
916 /* for each character generate an assignment */
917 /* to the array element */
918 char *s = SPEC_CVAL (iexpr->etype).v_char;
923 rast = newNode (NULLOP,
927 newAst_VALUE (valueFromLit ((float) i))),
928 newAst_VALUE (valueFromLit (*s))));
932 rast = newNode (NULLOP,
936 newAst_VALUE (valueFromLit ((float) i))),
937 newAst_VALUE (valueFromLit (*s))));
938 return decorateType (resolveSymbols (rast));
944 /*-----------------------------------------------------------------*/
945 /* createIvalPtr - generates initial value for pointers */
946 /*-----------------------------------------------------------------*/
948 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
954 if (ilist->type == INIT_DEEP)
955 ilist = ilist->init.deep;
957 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
959 /* if character pointer */
960 if (IS_CHAR (type->next))
961 if ((rast = createIvalCharPtr (sym, type, iexpr)))
964 return newNode ('=', sym, iexpr);
967 /*-----------------------------------------------------------------*/
968 /* createIval - generates code for initial value */
969 /*-----------------------------------------------------------------*/
971 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
978 /* if structure then */
979 if (IS_STRUCT (type))
980 rast = createIvalStruct (sym, type, ilist);
982 /* if this is a pointer */
984 rast = createIvalPtr (sym, type, ilist);
986 /* if this is an array */
988 rast = createIvalArray (sym, type, ilist);
990 /* if type is SPECIFIER */
992 rast = createIvalType (sym, type, ilist);
994 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
996 return decorateType (resolveSymbols (rast));
999 /*-----------------------------------------------------------------*/
1000 /* initAggregates - initialises aggregate variables with initv */
1001 /*-----------------------------------------------------------------*/
1003 initAggregates (symbol * sym, initList * ival, ast * wid)
1005 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1008 /*-----------------------------------------------------------------*/
1009 /* gatherAutoInit - creates assignment expressions for initial */
1011 /*-----------------------------------------------------------------*/
1013 gatherAutoInit (symbol * autoChain)
1020 for (sym = autoChain; sym; sym = sym->next)
1023 /* resolve the symbols in the ival */
1025 resolveIvalSym (sym->ival);
1027 /* if this is a static variable & has an */
1028 /* initial value the code needs to be lifted */
1029 /* here to the main portion since they can be */
1030 /* initialised only once at the start */
1031 if (IS_STATIC (sym->etype) && sym->ival &&
1032 SPEC_SCLS (sym->etype) != S_CODE)
1036 // this can only be a constant
1037 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1038 werror (E_CONST_EXPECTED);
1041 /* insert the symbol into the symbol table */
1042 /* with level = 0 & name = rname */
1043 newSym = copySymbol (sym);
1044 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1046 /* now lift the code to main */
1047 if (IS_AGGREGATE (sym->type))
1048 work = initAggregates (sym, sym->ival, NULL);
1050 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1051 list2expr (sym->ival));
1053 setAstLineno (work, sym->lineDef);
1057 staticAutos = newNode (NULLOP, staticAutos, work);
1064 /* if there is an initial value */
1065 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1067 if (IS_AGGREGATE (sym->type))
1068 work = initAggregates (sym, sym->ival, NULL);
1070 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1071 list2expr (sym->ival));
1073 setAstLineno (work, sym->lineDef);
1076 init = newNode (NULLOP, init, work);
1085 /*-----------------------------------------------------------------*/
1086 /* stringToSymbol - creates a symbol from a literal string */
1087 /*-----------------------------------------------------------------*/
1089 stringToSymbol (value * val)
1091 char name[SDCC_NAME_MAX + 1];
1092 static int charLbl = 0;
1095 sprintf (name, "_str_%d", charLbl++);
1096 sym = newSymbol (name, 0); /* make it @ level 0 */
1097 strcpy (sym->rname, name);
1099 /* copy the type from the value passed */
1100 sym->type = copyLinkChain (val->type);
1101 sym->etype = getSpec (sym->type);
1102 /* change to storage class & output class */
1103 SPEC_SCLS (sym->etype) = S_CODE;
1104 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1105 SPEC_STAT (sym->etype) = 1;
1106 /* make the level & block = 0 */
1107 sym->block = sym->level = 0;
1109 /* create an ival */
1110 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1115 allocVariables (sym);
1118 return symbolVal (sym);
1122 /*-----------------------------------------------------------------*/
1123 /* processBlockVars - will go thru the ast looking for block if */
1124 /* a block is found then will allocate the syms */
1125 /* will also gather the auto inits present */
1126 /*-----------------------------------------------------------------*/
1128 processBlockVars (ast * tree, int *stack, int action)
1133 /* if this is a block */
1134 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1138 if (action == ALLOCATE)
1140 autoInit = gatherAutoInit (tree->values.sym);
1141 *stack += allocVariables (tree->values.sym);
1143 /* if there are auto inits then do them */
1145 tree->left = newNode (NULLOP, autoInit, tree->left);
1147 else /* action is deallocate */
1148 deallocLocal (tree->values.sym);
1151 processBlockVars (tree->left, stack, action);
1152 processBlockVars (tree->right, stack, action);
1156 /*-----------------------------------------------------------------*/
1157 /* constExprValue - returns the value of a constant expression */
1158 /*-----------------------------------------------------------------*/
1160 constExprValue (ast * cexpr, int check)
1162 cexpr = decorateType (resolveSymbols (cexpr));
1164 /* if this is not a constant then */
1165 if (!IS_LITERAL (cexpr->ftype))
1167 /* then check if this is a literal array
1169 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1170 SPEC_CVAL (cexpr->etype).v_char &&
1171 IS_ARRAY (cexpr->ftype))
1173 value *val = valFromType (cexpr->ftype);
1174 SPEC_SCLS (val->etype) = S_LITERAL;
1175 val->sym = cexpr->opval.val->sym;
1176 val->sym->type = copyLinkChain (cexpr->ftype);
1177 val->sym->etype = getSpec (val->sym->type);
1178 strcpy (val->name, cexpr->opval.val->sym->rname);
1182 /* if we are casting a literal value then */
1183 if (IS_AST_OP (cexpr) &&
1184 cexpr->opval.op == CAST &&
1185 IS_LITERAL (cexpr->left->ftype))
1186 return valCastLiteral (cexpr->ftype,
1187 floatFromVal (cexpr->left->opval.val));
1189 if (IS_AST_VALUE (cexpr))
1190 return cexpr->opval.val;
1193 werror (E_CONST_EXPECTED, "found expression");
1198 /* return the value */
1199 return cexpr->opval.val;
1203 /*-----------------------------------------------------------------*/
1204 /* isLabelInAst - will return true if a given label is found */
1205 /*-----------------------------------------------------------------*/
1207 isLabelInAst (symbol * label, ast * tree)
1209 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1212 if (IS_AST_OP (tree) &&
1213 tree->opval.op == LABEL &&
1214 isSymbolEqual (AST_SYMBOL (tree->left), label))
1217 return isLabelInAst (label, tree->right) &&
1218 isLabelInAst (label, tree->left);
1222 /*-----------------------------------------------------------------*/
1223 /* isLoopCountable - return true if the loop count can be determi- */
1224 /* -ned at compile time . */
1225 /*-----------------------------------------------------------------*/
1227 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1228 symbol ** sym, ast ** init, ast ** end)
1231 /* the loop is considered countable if the following
1232 conditions are true :-
1234 a) initExpr :- <sym> = <const>
1235 b) condExpr :- <sym> < <const1>
1236 c) loopExpr :- <sym> ++
1239 /* first check the initExpr */
1240 if (IS_AST_OP (initExpr) &&
1241 initExpr->opval.op == '=' && /* is assignment */
1242 IS_AST_SYM_VALUE (initExpr->left))
1243 { /* left is a symbol */
1245 *sym = AST_SYMBOL (initExpr->left);
1246 *init = initExpr->right;
1251 /* for now the symbol has to be of
1253 if (!IS_INTEGRAL ((*sym)->type))
1256 /* now check condExpr */
1257 if (IS_AST_OP (condExpr))
1260 switch (condExpr->opval.op)
1263 if (IS_AST_SYM_VALUE (condExpr->left) &&
1264 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1265 IS_AST_LIT_VALUE (condExpr->right))
1267 *end = condExpr->right;
1273 if (IS_AST_OP (condExpr->left) &&
1274 condExpr->left->opval.op == '>' &&
1275 IS_AST_LIT_VALUE (condExpr->left->right) &&
1276 IS_AST_SYM_VALUE (condExpr->left->left) &&
1277 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1280 *end = newNode ('+', condExpr->left->right,
1281 newAst_VALUE (constVal ("1")));
1292 /* check loop expression is of the form <sym>++ */
1293 if (!IS_AST_OP (loopExpr))
1296 /* check if <sym> ++ */
1297 if (loopExpr->opval.op == INC_OP)
1303 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1304 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1311 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1312 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1320 if (loopExpr->opval.op == ADD_ASSIGN)
1323 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1324 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1325 IS_AST_LIT_VALUE (loopExpr->right) &&
1326 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1334 /*-----------------------------------------------------------------*/
1335 /* astHasVolatile - returns true if ast contains any volatile */
1336 /*-----------------------------------------------------------------*/
1338 astHasVolatile (ast * tree)
1343 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1346 if (IS_AST_OP (tree))
1347 return astHasVolatile (tree->left) ||
1348 astHasVolatile (tree->right);
1353 /*-----------------------------------------------------------------*/
1354 /* astHasPointer - return true if the ast contains any ptr variable */
1355 /*-----------------------------------------------------------------*/
1357 astHasPointer (ast * tree)
1362 if (IS_AST_LINK (tree))
1365 /* if we hit an array expression then check
1366 only the left side */
1367 if (IS_AST_OP (tree) && tree->opval.op == '[')
1368 return astHasPointer (tree->left);
1370 if (IS_AST_VALUE (tree))
1371 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1373 return astHasPointer (tree->left) ||
1374 astHasPointer (tree->right);
1378 /*-----------------------------------------------------------------*/
1379 /* astHasSymbol - return true if the ast has the given symbol */
1380 /*-----------------------------------------------------------------*/
1382 astHasSymbol (ast * tree, symbol * sym)
1384 if (!tree || IS_AST_LINK (tree))
1387 if (IS_AST_VALUE (tree))
1389 if (IS_AST_SYM_VALUE (tree))
1390 return isSymbolEqual (AST_SYMBOL (tree), sym);
1395 return astHasSymbol (tree->left, sym) ||
1396 astHasSymbol (tree->right, sym);
1399 /*-----------------------------------------------------------------*/
1400 /* isConformingBody - the loop body has to conform to a set of rules */
1401 /* for the loop to be considered reversible read on for rules */
1402 /*-----------------------------------------------------------------*/
1404 isConformingBody (ast * pbody, symbol * sym, ast * body)
1407 /* we are going to do a pre-order traversal of the
1408 tree && check for the following conditions. (essentially
1409 a set of very shallow tests )
1410 a) the sym passed does not participate in
1411 any arithmetic operation
1412 b) There are no function calls
1413 c) all jumps are within the body
1414 d) address of loop control variable not taken
1415 e) if an assignment has a pointer on the
1416 left hand side make sure right does not have
1417 loop control variable */
1419 /* if we reach the end or a leaf then true */
1420 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1424 /* if anything else is "volatile" */
1425 if (IS_VOLATILE (TETYPE (pbody)))
1428 /* we will walk the body in a pre-order traversal for
1430 switch (pbody->opval.op)
1432 /*------------------------------------------------------------------*/
1434 return isConformingBody (pbody->right, sym, body);
1436 /*------------------------------------------------------------------*/
1441 /*------------------------------------------------------------------*/
1442 case INC_OP: /* incerement operator unary so left only */
1445 /* sure we are not sym is not modified */
1447 IS_AST_SYM_VALUE (pbody->left) &&
1448 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1452 IS_AST_SYM_VALUE (pbody->right) &&
1453 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1458 /*------------------------------------------------------------------*/
1460 case '*': /* can be unary : if right is null then unary operation */
1465 /* if right is NULL then unary operation */
1466 /*------------------------------------------------------------------*/
1467 /*----------------------------*/
1469 /*----------------------------*/
1472 if (IS_AST_SYM_VALUE (pbody->left) &&
1473 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1476 return isConformingBody (pbody->left, sym, body);
1480 if (astHasSymbol (pbody->left, sym) ||
1481 astHasSymbol (pbody->right, sym))
1486 /*------------------------------------------------------------------*/
1494 if (IS_AST_SYM_VALUE (pbody->left) &&
1495 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1498 if (IS_AST_SYM_VALUE (pbody->right) &&
1499 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1502 return isConformingBody (pbody->left, sym, body) &&
1503 isConformingBody (pbody->right, sym, body);
1510 if (IS_AST_SYM_VALUE (pbody->left) &&
1511 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1513 return isConformingBody (pbody->left, sym, body);
1515 /*------------------------------------------------------------------*/
1527 case SIZEOF: /* evaluate wihout code generation */
1529 return isConformingBody (pbody->left, sym, body) &&
1530 isConformingBody (pbody->right, sym, body);
1532 /*------------------------------------------------------------------*/
1535 /* if left has a pointer & right has loop
1536 control variable then we cannot */
1537 if (astHasPointer (pbody->left) &&
1538 astHasSymbol (pbody->right, sym))
1540 if (astHasVolatile (pbody->left))
1543 if (IS_AST_SYM_VALUE (pbody->left) &&
1544 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1547 if (astHasVolatile (pbody->left))
1550 return isConformingBody (pbody->left, sym, body) &&
1551 isConformingBody (pbody->right, sym, body);
1562 assert ("Parser should not have generated this\n");
1564 /*------------------------------------------------------------------*/
1565 /*----------------------------*/
1566 /* comma operator */
1567 /*----------------------------*/
1569 return isConformingBody (pbody->left, sym, body) &&
1570 isConformingBody (pbody->right, sym, body);
1572 /*------------------------------------------------------------------*/
1573 /*----------------------------*/
1575 /*----------------------------*/
1579 /*------------------------------------------------------------------*/
1580 /*----------------------------*/
1581 /* return statement */
1582 /*----------------------------*/
1587 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1592 if (astHasSymbol (pbody->left, sym))
1599 return isConformingBody (pbody->left, sym, body) &&
1600 isConformingBody (pbody->right, sym, body);
1606 /*-----------------------------------------------------------------*/
1607 /* isLoopReversible - takes a for loop as input && returns true */
1608 /* if the for loop is reversible. If yes will set the value of */
1609 /* the loop control var & init value & termination value */
1610 /*-----------------------------------------------------------------*/
1612 isLoopReversible (ast * loop, symbol ** loopCntrl,
1613 ast ** init, ast ** end)
1615 /* if option says don't do it then don't */
1616 if (optimize.noLoopReverse)
1618 /* there are several tests to determine this */
1620 /* for loop has to be of the form
1621 for ( <sym> = <const1> ;
1622 [<sym> < <const2>] ;
1623 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1625 if (!isLoopCountable (AST_FOR (loop, initExpr),
1626 AST_FOR (loop, condExpr),
1627 AST_FOR (loop, loopExpr),
1628 loopCntrl, init, end))
1631 /* now do some serious checking on the body of the loop
1634 return isConformingBody (loop->left, *loopCntrl, loop->left);
1638 /*-----------------------------------------------------------------*/
1639 /* replLoopSym - replace the loop sym by loop sym -1 */
1640 /*-----------------------------------------------------------------*/
1642 replLoopSym (ast * body, symbol * sym)
1645 if (!body || IS_AST_LINK (body))
1648 if (IS_AST_SYM_VALUE (body))
1651 if (isSymbolEqual (AST_SYMBOL (body), sym))
1655 body->opval.op = '-';
1656 body->left = newAst_VALUE (symbolVal (sym));
1657 body->right = newAst_VALUE (constVal ("1"));
1665 replLoopSym (body->left, sym);
1666 replLoopSym (body->right, sym);
1670 /*-----------------------------------------------------------------*/
1671 /* reverseLoop - do the actual loop reversal */
1672 /*-----------------------------------------------------------------*/
1674 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1678 /* create the following tree
1683 if (sym) goto for_continue ;
1686 /* put it together piece by piece */
1687 rloop = newNode (NULLOP,
1688 createIf (newAst_VALUE (symbolVal (sym)),
1690 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1693 newAst_VALUE (symbolVal (sym)),
1696 replLoopSym (loop->left, sym);
1698 rloop = newNode (NULLOP,
1700 newAst_VALUE (symbolVal (sym)),
1701 newNode ('-', end, init)),
1702 createLabel (AST_FOR (loop, continueLabel),
1706 newNode (SUB_ASSIGN,
1707 newAst_VALUE (symbolVal (sym)),
1708 newAst_VALUE (constVal ("1"))),
1711 return decorateType (rloop);
1715 #define DEMAND_INTEGER_PROMOTION
1717 #ifdef DEMAND_INTEGER_PROMOTION
1719 /*-----------------------------------------------------------------*/
1720 /* walk a tree looking for the leaves. Add a typecast to the given */
1721 /* type to each value leaf node. */
1722 /*-----------------------------------------------------------------*/
1724 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1726 if (!node || IS_CALLOP(node))
1728 /* WTF? We should never get here. */
1732 if (!node->left && !node->right)
1734 /* We're at a leaf; if it's a value, apply the typecast */
1735 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1737 *parentPtr = decorateType (newNode (CAST,
1738 newAst_LINK (copyLinkChain (type)),
1746 pushTypeCastToLeaves (type, node->left, &(node->left));
1750 pushTypeCastToLeaves (type, node->right, &(node->right));
1757 /*-----------------------------------------------------------------*/
1758 /* Given an assignment operation in a tree, determine if the LHS */
1759 /* (the result) has a different (integer) type than the RHS. */
1760 /* If so, walk the RHS and add a typecast to the type of the LHS */
1761 /* to all leaf nodes. */
1762 /*-----------------------------------------------------------------*/
1764 propAsgType (ast * tree)
1766 #ifdef DEMAND_INTEGER_PROMOTION
1767 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1769 /* Nothing to do here... */
1773 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1775 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1782 /*-----------------------------------------------------------------*/
1783 /* decorateType - compute type for this tree also does type cheking */
1784 /* this is done bottom up, since type have to flow upwards */
1785 /* it also does constant folding, and paramater checking */
1786 /*-----------------------------------------------------------------*/
1788 decorateType (ast * tree)
1796 /* if already has type then do nothing */
1797 if (tree->decorated)
1800 tree->decorated = 1;
1802 /* print the line */
1803 /* if not block & function */
1804 if (tree->type == EX_OP &&
1805 (tree->opval.op != FUNCTION &&
1806 tree->opval.op != BLOCK &&
1807 tree->opval.op != NULLOP))
1809 filename = tree->filename;
1810 lineno = tree->lineno;
1813 /* if any child is an error | this one is an error do nothing */
1814 if (tree->isError ||
1815 (tree->left && tree->left->isError) ||
1816 (tree->right && tree->right->isError))
1819 /*------------------------------------------------------------------*/
1820 /*----------------------------*/
1821 /* leaf has been reached */
1822 /*----------------------------*/
1823 /* if this is of type value */
1824 /* just get the type */
1825 if (tree->type == EX_VALUE)
1828 if (IS_LITERAL (tree->opval.val->etype))
1831 /* if this is a character array then declare it */
1832 if (IS_ARRAY (tree->opval.val->type))
1833 tree->opval.val = stringToSymbol (tree->opval.val);
1835 /* otherwise just copy the type information */
1836 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1837 if (funcInChain (tree->opval.val->type))
1839 tree->hasVargs = tree->opval.val->sym->hasVargs;
1840 tree->args = copyValueChain (tree->opval.val->sym->args);
1845 if (tree->opval.val->sym)
1847 /* if the undefined flag is set then give error message */
1848 if (tree->opval.val->sym->undefined)
1850 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1852 TTYPE (tree) = TETYPE (tree) =
1853 tree->opval.val->type = tree->opval.val->sym->type =
1854 tree->opval.val->etype = tree->opval.val->sym->etype =
1855 copyLinkChain (INTTYPE);
1860 /* if impilicit i.e. struct/union member then no type */
1861 if (tree->opval.val->sym->implicit)
1862 TTYPE (tree) = TETYPE (tree) = NULL;
1867 /* else copy the type */
1868 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1870 /* and mark it as referenced */
1871 tree->opval.val->sym->isref = 1;
1872 /* if this is of type function or function pointer */
1873 if (funcInChain (tree->opval.val->type))
1875 tree->hasVargs = tree->opval.val->sym->hasVargs;
1876 tree->args = copyValueChain (tree->opval.val->sym->args);
1886 /* if type link for the case of cast */
1887 if (tree->type == EX_LINK)
1889 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1896 dtl = decorateType (tree->left);
1897 dtr = decorateType (tree->right);
1899 /* this is to take care of situations
1900 when the tree gets rewritten */
1901 if (dtl != tree->left)
1903 if (dtr != tree->right)
1907 /* depending on type of operator do */
1909 switch (tree->opval.op)
1911 /*------------------------------------------------------------------*/
1912 /*----------------------------*/
1914 /*----------------------------*/
1917 /* determine which is the array & which the index */
1918 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1921 ast *tempTree = tree->left;
1922 tree->left = tree->right;
1923 tree->right = tempTree;
1926 /* first check if this is a array or a pointer */
1927 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1929 werror (E_NEED_ARRAY_PTR, "[]");
1930 goto errorTreeReturn;
1933 /* check if the type of the idx */
1934 if (!IS_INTEGRAL (RTYPE (tree)))
1936 werror (E_IDX_NOT_INT);
1937 goto errorTreeReturn;
1940 /* if the left is an rvalue then error */
1943 werror (E_LVALUE_REQUIRED, "array access");
1944 goto errorTreeReturn;
1947 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1948 if (IS_PTR(LTYPE(tree))) {
1949 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1953 /*------------------------------------------------------------------*/
1954 /*----------------------------*/
1956 /*----------------------------*/
1958 /* if this is not a structure */
1959 if (!IS_STRUCT (LTYPE (tree)))
1961 werror (E_STRUCT_UNION, ".");
1962 goto errorTreeReturn;
1964 TTYPE (tree) = structElemType (LTYPE (tree),
1965 (tree->right->type == EX_VALUE ?
1966 tree->right->opval.val : NULL), &tree->args);
1967 TETYPE (tree) = getSpec (TTYPE (tree));
1970 /*------------------------------------------------------------------*/
1971 /*----------------------------*/
1972 /* struct/union pointer */
1973 /*----------------------------*/
1975 /* if not pointer to a structure */
1976 if (!IS_PTR (LTYPE (tree)))
1978 werror (E_PTR_REQD);
1979 goto errorTreeReturn;
1982 if (!IS_STRUCT (LTYPE (tree)->next))
1984 werror (E_STRUCT_UNION, "->");
1985 goto errorTreeReturn;
1988 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1989 (tree->right->type == EX_VALUE ?
1990 tree->right->opval.val : NULL), &tree->args);
1991 TETYPE (tree) = getSpec (TTYPE (tree));
1994 /*------------------------------------------------------------------*/
1995 /*----------------------------*/
1996 /* ++/-- operation */
1997 /*----------------------------*/
1998 case INC_OP: /* incerement operator unary so left only */
2001 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2002 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2003 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2004 werror (E_CODE_WRITE, "++/--");
2013 /*------------------------------------------------------------------*/
2014 /*----------------------------*/
2016 /*----------------------------*/
2017 case '&': /* can be unary */
2018 /* if right is NULL then unary operation */
2019 if (tree->right) /* not an unary operation */
2022 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2024 werror (E_BITWISE_OP);
2025 werror (E_CONTINUE, "left & right types are ");
2026 printTypeChain (LTYPE (tree), stderr);
2027 fprintf (stderr, ",");
2028 printTypeChain (RTYPE (tree), stderr);
2029 fprintf (stderr, "\n");
2030 goto errorTreeReturn;
2033 /* if they are both literal */
2034 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2036 tree->type = EX_VALUE;
2037 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2038 valFromType (RETYPE (tree)), '&');
2040 tree->right = tree->left = NULL;
2041 TETYPE (tree) = tree->opval.val->etype;
2042 TTYPE (tree) = tree->opval.val->type;
2046 /* see if this is a GETHBIT operation if yes
2049 ast *otree = optimizeGetHbit (tree);
2052 return decorateType (otree);
2055 /* if right or left is literal then result of that type */
2056 if (IS_LITERAL (RTYPE (tree)))
2059 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2060 TETYPE (tree) = getSpec (TTYPE (tree));
2061 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2065 if (IS_LITERAL (LTYPE (tree)))
2067 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2068 TETYPE (tree) = getSpec (TTYPE (tree));
2069 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2075 computeType (LTYPE (tree), RTYPE (tree));
2076 TETYPE (tree) = getSpec (TTYPE (tree));
2079 LRVAL (tree) = RRVAL (tree) = 1;
2083 /*------------------------------------------------------------------*/
2084 /*----------------------------*/
2086 /*----------------------------*/
2088 p->class = DECLARATOR;
2089 /* if bit field then error */
2090 if (IS_BITVAR (tree->left->etype))
2092 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2093 goto errorTreeReturn;
2096 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2098 werror (E_ILLEGAL_ADDR, "address of register variable");
2099 goto errorTreeReturn;
2102 if (IS_FUNC (LTYPE (tree)))
2104 werror (E_ILLEGAL_ADDR, "address of function");
2105 goto errorTreeReturn;
2110 werror (E_LVALUE_REQUIRED, "address of");
2111 goto errorTreeReturn;
2113 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2115 DCL_TYPE (p) = CPOINTER;
2116 DCL_PTR_CONST (p) = port->mem.code_ro;
2118 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2119 DCL_TYPE (p) = FPOINTER;
2120 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2121 DCL_TYPE (p) = PPOINTER;
2122 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2123 DCL_TYPE (p) = IPOINTER;
2124 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2125 DCL_TYPE (p) = EEPPOINTER;
2127 DCL_TYPE (p) = POINTER;
2129 if (IS_AST_SYM_VALUE (tree->left))
2131 AST_SYMBOL (tree->left)->addrtaken = 1;
2132 AST_SYMBOL (tree->left)->allocreq = 1;
2135 p->next = LTYPE (tree);
2137 TETYPE (tree) = getSpec (TTYPE (tree));
2138 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2139 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2144 /*------------------------------------------------------------------*/
2145 /*----------------------------*/
2147 /*----------------------------*/
2149 /* if the rewrite succeeds then don't go any furthur */
2151 ast *wtree = optimizeRRCRLC (tree);
2153 return decorateType (wtree);
2155 /*------------------------------------------------------------------*/
2156 /*----------------------------*/
2158 /*----------------------------*/
2160 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2162 werror (E_BITWISE_OP);
2163 werror (E_CONTINUE, "left & right types are ");
2164 printTypeChain (LTYPE (tree), stderr);
2165 fprintf (stderr, ",");
2166 printTypeChain (RTYPE (tree), stderr);
2167 fprintf (stderr, "\n");
2168 goto errorTreeReturn;
2171 /* if they are both literal then */
2172 /* rewrite the tree */
2173 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2175 tree->type = EX_VALUE;
2176 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2177 valFromType (RETYPE (tree)),
2179 tree->right = tree->left = NULL;
2180 TETYPE (tree) = tree->opval.val->etype;
2181 TTYPE (tree) = tree->opval.val->type;
2184 LRVAL (tree) = RRVAL (tree) = 1;
2185 TETYPE (tree) = getSpec (TTYPE (tree) =
2186 computeType (LTYPE (tree),
2189 /*------------------------------------------------------------------*/
2190 /*----------------------------*/
2192 /*----------------------------*/
2194 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2196 werror (E_INVALID_OP, "divide");
2197 goto errorTreeReturn;
2199 /* if they are both literal then */
2200 /* rewrite the tree */
2201 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2203 tree->type = EX_VALUE;
2204 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2205 valFromType (RETYPE (tree)));
2206 tree->right = tree->left = NULL;
2207 TETYPE (tree) = getSpec (TTYPE (tree) =
2208 tree->opval.val->type);
2211 LRVAL (tree) = RRVAL (tree) = 1;
2212 TETYPE (tree) = getSpec (TTYPE (tree) =
2213 computeType (LTYPE (tree),
2217 /*------------------------------------------------------------------*/
2218 /*----------------------------*/
2220 /*----------------------------*/
2222 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2224 werror (E_BITWISE_OP);
2225 werror (E_CONTINUE, "left & right types are ");
2226 printTypeChain (LTYPE (tree), stderr);
2227 fprintf (stderr, ",");
2228 printTypeChain (RTYPE (tree), stderr);
2229 fprintf (stderr, "\n");
2230 goto errorTreeReturn;
2232 /* if they are both literal then */
2233 /* rewrite the tree */
2234 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2236 tree->type = EX_VALUE;
2237 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2238 valFromType (RETYPE (tree)));
2239 tree->right = tree->left = NULL;
2240 TETYPE (tree) = getSpec (TTYPE (tree) =
2241 tree->opval.val->type);
2244 LRVAL (tree) = RRVAL (tree) = 1;
2245 TETYPE (tree) = getSpec (TTYPE (tree) =
2246 computeType (LTYPE (tree),
2250 /*------------------------------------------------------------------*/
2251 /*----------------------------*/
2252 /* address dereference */
2253 /*----------------------------*/
2254 case '*': /* can be unary : if right is null then unary operation */
2257 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2259 werror (E_PTR_REQD);
2260 goto errorTreeReturn;
2265 werror (E_LVALUE_REQUIRED, "pointer deref");
2266 goto errorTreeReturn;
2268 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2269 LTYPE (tree)->next : NULL);
2270 TETYPE (tree) = getSpec (TTYPE (tree));
2271 tree->args = tree->left->args;
2272 tree->hasVargs = tree->left->hasVargs;
2273 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2277 /*------------------------------------------------------------------*/
2278 /*----------------------------*/
2279 /* multiplication */
2280 /*----------------------------*/
2281 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2283 werror (E_INVALID_OP, "multiplication");
2284 goto errorTreeReturn;
2287 /* if they are both literal then */
2288 /* rewrite the tree */
2289 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2291 tree->type = EX_VALUE;
2292 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2293 valFromType (RETYPE (tree)));
2294 tree->right = tree->left = NULL;
2295 TETYPE (tree) = getSpec (TTYPE (tree) =
2296 tree->opval.val->type);
2300 /* if left is a literal exchange left & right */
2301 if (IS_LITERAL (LTYPE (tree)))
2303 ast *tTree = tree->left;
2304 tree->left = tree->right;
2305 tree->right = tTree;
2308 LRVAL (tree) = RRVAL (tree) = 1;
2309 /* promote result to int if left & right are char
2310 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2311 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2312 TETYPE (tree) = getSpec (TTYPE (tree) =
2313 computeType (LTYPE (tree),
2315 SPEC_NOUN(TETYPE(tree)) = V_INT;
2317 TETYPE (tree) = getSpec (TTYPE (tree) =
2318 computeType (LTYPE (tree),
2323 /*------------------------------------------------------------------*/
2324 /*----------------------------*/
2325 /* unary '+' operator */
2326 /*----------------------------*/
2331 if (!IS_INTEGRAL (LTYPE (tree)))
2333 werror (E_UNARY_OP, '+');
2334 goto errorTreeReturn;
2337 /* if left is a literal then do it */
2338 if (IS_LITERAL (LTYPE (tree)))
2340 tree->type = EX_VALUE;
2341 tree->opval.val = valFromType (LETYPE (tree));
2343 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2347 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2351 /*------------------------------------------------------------------*/
2352 /*----------------------------*/
2354 /*----------------------------*/
2356 /* this is not a unary operation */
2357 /* if both pointers then problem */
2358 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2359 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2361 werror (E_PTR_PLUS_PTR);
2362 goto errorTreeReturn;
2365 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2366 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2368 werror (E_PLUS_INVALID, "+");
2369 goto errorTreeReturn;
2372 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2373 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2375 werror (E_PLUS_INVALID, "+");
2376 goto errorTreeReturn;
2378 /* if they are both literal then */
2379 /* rewrite the tree */
2380 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2382 tree->type = EX_VALUE;
2383 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2384 valFromType (RETYPE (tree)));
2385 tree->right = tree->left = NULL;
2386 TETYPE (tree) = getSpec (TTYPE (tree) =
2387 tree->opval.val->type);
2391 /* if the right is a pointer or left is a literal
2392 xchange left & right */
2393 if (IS_ARRAY (RTYPE (tree)) ||
2394 IS_PTR (RTYPE (tree)) ||
2395 IS_LITERAL (LTYPE (tree)))
2397 ast *tTree = tree->left;
2398 tree->left = tree->right;
2399 tree->right = tTree;
2402 LRVAL (tree) = RRVAL (tree) = 1;
2403 /* if the left is a pointer */
2404 if (IS_PTR (LTYPE (tree)))
2405 TETYPE (tree) = getSpec (TTYPE (tree) =
2408 TETYPE (tree) = getSpec (TTYPE (tree) =
2409 computeType (LTYPE (tree),
2413 /*------------------------------------------------------------------*/
2414 /*----------------------------*/
2416 /*----------------------------*/
2417 case '-': /* can be unary */
2418 /* if right is null then unary */
2422 if (!IS_ARITHMETIC (LTYPE (tree)))
2424 werror (E_UNARY_OP, tree->opval.op);
2425 goto errorTreeReturn;
2428 /* if left is a literal then do it */
2429 if (IS_LITERAL (LTYPE (tree)))
2431 tree->type = EX_VALUE;
2432 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2434 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2435 SPEC_USIGN(TETYPE(tree)) = 0;
2439 TTYPE (tree) = LTYPE (tree);
2443 /*------------------------------------------------------------------*/
2444 /*----------------------------*/
2446 /*----------------------------*/
2448 if (!(IS_PTR (LTYPE (tree)) ||
2449 IS_ARRAY (LTYPE (tree)) ||
2450 IS_ARITHMETIC (LTYPE (tree))))
2452 werror (E_PLUS_INVALID, "-");
2453 goto errorTreeReturn;
2456 if (!(IS_PTR (RTYPE (tree)) ||
2457 IS_ARRAY (RTYPE (tree)) ||
2458 IS_ARITHMETIC (RTYPE (tree))))
2460 werror (E_PLUS_INVALID, "-");
2461 goto errorTreeReturn;
2464 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2465 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2466 IS_INTEGRAL (RTYPE (tree))))
2468 werror (E_PLUS_INVALID, "-");
2469 goto errorTreeReturn;
2472 /* if they are both literal then */
2473 /* rewrite the tree */
2474 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2476 tree->type = EX_VALUE;
2477 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2478 valFromType (RETYPE (tree)));
2479 tree->right = tree->left = NULL;
2480 TETYPE (tree) = getSpec (TTYPE (tree) =
2481 tree->opval.val->type);
2485 /* if the left & right are equal then zero */
2486 if (isAstEqual (tree->left, tree->right))
2488 tree->type = EX_VALUE;
2489 tree->left = tree->right = NULL;
2490 tree->opval.val = constVal ("0");
2491 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2495 /* if both of them are pointers or arrays then */
2496 /* the result is going to be an integer */
2497 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2498 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2499 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2501 /* if only the left is a pointer */
2502 /* then result is a pointer */
2503 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2504 TETYPE (tree) = getSpec (TTYPE (tree) =
2507 TETYPE (tree) = getSpec (TTYPE (tree) =
2508 computeType (LTYPE (tree),
2510 LRVAL (tree) = RRVAL (tree) = 1;
2513 /*------------------------------------------------------------------*/
2514 /*----------------------------*/
2516 /*----------------------------*/
2518 /* can be only integral type */
2519 if (!IS_INTEGRAL (LTYPE (tree)))
2521 werror (E_UNARY_OP, tree->opval.op);
2522 goto errorTreeReturn;
2525 /* if left is a literal then do it */
2526 if (IS_LITERAL (LTYPE (tree)))
2528 tree->type = EX_VALUE;
2529 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2531 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2535 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2538 /*------------------------------------------------------------------*/
2539 /*----------------------------*/
2541 /*----------------------------*/
2543 /* can be pointer */
2544 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2545 !IS_PTR (LTYPE (tree)) &&
2546 !IS_ARRAY (LTYPE (tree)))
2548 werror (E_UNARY_OP, tree->opval.op);
2549 goto errorTreeReturn;
2552 /* if left is a literal then do it */
2553 if (IS_LITERAL (LTYPE (tree)))
2555 tree->type = EX_VALUE;
2556 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2558 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2562 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2565 /*------------------------------------------------------------------*/
2566 /*----------------------------*/
2568 /*----------------------------*/
2571 TTYPE (tree) = LTYPE (tree);
2572 TETYPE (tree) = LETYPE (tree);
2576 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2581 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2583 werror (E_SHIFT_OP_INVALID);
2584 werror (E_CONTINUE, "left & right types are ");
2585 printTypeChain (LTYPE (tree), stderr);
2586 fprintf (stderr, ",");
2587 printTypeChain (RTYPE (tree), stderr);
2588 fprintf (stderr, "\n");
2589 goto errorTreeReturn;
2592 /* if they are both literal then */
2593 /* rewrite the tree */
2594 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2596 tree->type = EX_VALUE;
2597 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2598 valFromType (RETYPE (tree)),
2599 (tree->opval.op == LEFT_OP ? 1 : 0));
2600 tree->right = tree->left = NULL;
2601 TETYPE (tree) = getSpec (TTYPE (tree) =
2602 tree->opval.val->type);
2605 /* if only the right side is a literal & we are
2606 shifting more than size of the left operand then zero */
2607 if (IS_LITERAL (RTYPE (tree)) &&
2608 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2609 (getSize (LTYPE (tree)) * 8))
2611 werror (W_SHIFT_CHANGED,
2612 (tree->opval.op == LEFT_OP ? "left" : "right"));
2613 tree->type = EX_VALUE;
2614 tree->left = tree->right = NULL;
2615 tree->opval.val = constVal ("0");
2616 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2619 LRVAL (tree) = RRVAL (tree) = 1;
2620 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2622 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2626 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2630 /*------------------------------------------------------------------*/
2631 /*----------------------------*/
2633 /*----------------------------*/
2634 case CAST: /* change the type */
2635 /* cannot cast to an aggregate type */
2636 if (IS_AGGREGATE (LTYPE (tree)))
2638 werror (E_CAST_ILLEGAL);
2639 goto errorTreeReturn;
2642 /* make sure the type is complete and sane */
2643 checkTypeSanity(LETYPE(tree), "(cast)");
2645 /* if the right is a literal replace the tree */
2646 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2648 tree->type = EX_VALUE;
2650 valCastLiteral (LTYPE (tree),
2651 floatFromVal (valFromType (RETYPE (tree))));
2654 TTYPE (tree) = tree->opval.val->type;
2655 tree->values.literalFromCast = 1;
2659 TTYPE (tree) = LTYPE (tree);
2663 TETYPE (tree) = getSpec (TTYPE (tree));
2667 /*------------------------------------------------------------------*/
2668 /*----------------------------*/
2669 /* logical &&, || */
2670 /*----------------------------*/
2673 /* each must me arithmetic type or be a pointer */
2674 if (!IS_PTR (LTYPE (tree)) &&
2675 !IS_ARRAY (LTYPE (tree)) &&
2676 !IS_INTEGRAL (LTYPE (tree)))
2678 werror (E_COMPARE_OP);
2679 goto errorTreeReturn;
2682 if (!IS_PTR (RTYPE (tree)) &&
2683 !IS_ARRAY (RTYPE (tree)) &&
2684 !IS_INTEGRAL (RTYPE (tree)))
2686 werror (E_COMPARE_OP);
2687 goto errorTreeReturn;
2689 /* if they are both literal then */
2690 /* rewrite the tree */
2691 if (IS_LITERAL (RTYPE (tree)) &&
2692 IS_LITERAL (LTYPE (tree)))
2694 tree->type = EX_VALUE;
2695 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2696 valFromType (RETYPE (tree)),
2698 tree->right = tree->left = NULL;
2699 TETYPE (tree) = getSpec (TTYPE (tree) =
2700 tree->opval.val->type);
2703 LRVAL (tree) = RRVAL (tree) = 1;
2704 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2707 /*------------------------------------------------------------------*/
2708 /*----------------------------*/
2709 /* comparison operators */
2710 /*----------------------------*/
2718 ast *lt = optimizeCompare (tree);
2724 /* if they are pointers they must be castable */
2725 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2727 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2729 werror (E_COMPARE_OP);
2730 fprintf (stderr, "comparing type ");
2731 printTypeChain (LTYPE (tree), stderr);
2732 fprintf (stderr, "to type ");
2733 printTypeChain (RTYPE (tree), stderr);
2734 fprintf (stderr, "\n");
2735 goto errorTreeReturn;
2738 /* else they should be promotable to one another */
2741 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2742 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2744 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2746 werror (E_COMPARE_OP);
2747 fprintf (stderr, "comparing type ");
2748 printTypeChain (LTYPE (tree), stderr);
2749 fprintf (stderr, "to type ");
2750 printTypeChain (RTYPE (tree), stderr);
2751 fprintf (stderr, "\n");
2752 goto errorTreeReturn;
2756 /* if they are both literal then */
2757 /* rewrite the tree */
2758 if (IS_LITERAL (RTYPE (tree)) &&
2759 IS_LITERAL (LTYPE (tree)))
2761 tree->type = EX_VALUE;
2762 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2763 valFromType (RETYPE (tree)),
2765 tree->right = tree->left = NULL;
2766 TETYPE (tree) = getSpec (TTYPE (tree) =
2767 tree->opval.val->type);
2770 LRVAL (tree) = RRVAL (tree) = 1;
2771 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2774 /*------------------------------------------------------------------*/
2775 /*----------------------------*/
2777 /*----------------------------*/
2778 case SIZEOF: /* evaluate wihout code generation */
2779 /* change the type to a integer */
2780 tree->type = EX_VALUE;
2781 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2782 tree->opval.val = constVal (buffer);
2783 tree->right = tree->left = NULL;
2784 TETYPE (tree) = getSpec (TTYPE (tree) =
2785 tree->opval.val->type);
2788 /*------------------------------------------------------------------*/
2789 /*----------------------------*/
2790 /* conditional operator '?' */
2791 /*----------------------------*/
2793 /* the type is value of the colon operator (on the right) */
2794 assert(IS_COLON_OP(tree->right));
2795 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2796 TETYPE (tree) = getSpec (TTYPE (tree));
2800 /* if they don't match we have a problem */
2801 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2803 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2804 goto errorTreeReturn;
2807 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2808 TETYPE (tree) = getSpec (TTYPE (tree));
2812 /*------------------------------------------------------------------*/
2813 /*----------------------------*/
2814 /* assignment operators */
2815 /*----------------------------*/
2818 /* for these it must be both must be integral */
2819 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2820 !IS_ARITHMETIC (RTYPE (tree)))
2822 werror (E_OPS_INTEGRAL);
2823 goto errorTreeReturn;
2826 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2828 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2829 werror (E_CODE_WRITE, " ");
2833 werror (E_LVALUE_REQUIRED, "*= or /=");
2834 goto errorTreeReturn;
2847 /* for these it must be both must be integral */
2848 if (!IS_INTEGRAL (LTYPE (tree)) ||
2849 !IS_INTEGRAL (RTYPE (tree)))
2851 werror (E_OPS_INTEGRAL);
2852 goto errorTreeReturn;
2855 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2857 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2858 werror (E_CODE_WRITE, " ");
2862 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2863 goto errorTreeReturn;
2871 /*------------------------------------------------------------------*/
2872 /*----------------------------*/
2874 /*----------------------------*/
2876 if (!(IS_PTR (LTYPE (tree)) ||
2877 IS_ARITHMETIC (LTYPE (tree))))
2879 werror (E_PLUS_INVALID, "-=");
2880 goto errorTreeReturn;
2883 if (!(IS_PTR (RTYPE (tree)) ||
2884 IS_ARITHMETIC (RTYPE (tree))))
2886 werror (E_PLUS_INVALID, "-=");
2887 goto errorTreeReturn;
2890 TETYPE (tree) = getSpec (TTYPE (tree) =
2891 computeType (LTYPE (tree),
2894 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2895 werror (E_CODE_WRITE, " ");
2899 werror (E_LVALUE_REQUIRED, "-=");
2900 goto errorTreeReturn;
2908 /*------------------------------------------------------------------*/
2909 /*----------------------------*/
2911 /*----------------------------*/
2913 /* this is not a unary operation */
2914 /* if both pointers then problem */
2915 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2917 werror (E_PTR_PLUS_PTR);
2918 goto errorTreeReturn;
2921 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2923 werror (E_PLUS_INVALID, "+=");
2924 goto errorTreeReturn;
2927 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2929 werror (E_PLUS_INVALID, "+=");
2930 goto errorTreeReturn;
2933 TETYPE (tree) = getSpec (TTYPE (tree) =
2934 computeType (LTYPE (tree),
2937 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2938 werror (E_CODE_WRITE, " ");
2942 werror (E_LVALUE_REQUIRED, "+=");
2943 goto errorTreeReturn;
2946 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2947 tree->opval.op = '=';
2953 /*------------------------------------------------------------------*/
2954 /*----------------------------*/
2955 /* straight assignemnt */
2956 /*----------------------------*/
2958 /* cannot be an aggregate */
2959 if (IS_AGGREGATE (LTYPE (tree)))
2961 werror (E_AGGR_ASSIGN);
2962 goto errorTreeReturn;
2965 /* they should either match or be castable */
2966 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2968 werror (E_TYPE_MISMATCH, "assignment", " ");
2969 fprintf (stderr, "type --> '");
2970 printTypeChain (RTYPE (tree), stderr);
2971 fprintf (stderr, "' ");
2972 fprintf (stderr, "assigned to type --> '");
2973 printTypeChain (LTYPE (tree), stderr);
2974 fprintf (stderr, "'\n");
2975 goto errorTreeReturn;
2978 /* if the left side of the tree is of type void
2979 then report error */
2980 if (IS_VOID (LTYPE (tree)))
2982 werror (E_CAST_ZERO);
2983 fprintf (stderr, "type --> '");
2984 printTypeChain (RTYPE (tree), stderr);
2985 fprintf (stderr, "' ");
2986 fprintf (stderr, "assigned to type --> '");
2987 printTypeChain (LTYPE (tree), stderr);
2988 fprintf (stderr, "'\n");
2991 /* extra checks for pointer types */
2992 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2993 !IS_GENPTR (LTYPE (tree)))
2995 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2996 werror (W_PTR_ASSIGN);
2999 TETYPE (tree) = getSpec (TTYPE (tree) =
3003 if (!tree->initMode ) {
3004 if (IS_CONSTANT (LETYPE (tree))) {
3005 werror (E_CODE_WRITE, " ");
3010 werror (E_LVALUE_REQUIRED, "=");
3011 goto errorTreeReturn;
3018 /*------------------------------------------------------------------*/
3019 /*----------------------------*/
3020 /* comma operator */
3021 /*----------------------------*/
3023 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3026 /*------------------------------------------------------------------*/
3027 /*----------------------------*/
3029 /*----------------------------*/
3033 if (processParms (tree->left,
3035 tree->right, &parmNumber, TRUE))
3036 goto errorTreeReturn;
3038 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3040 tree->left->args = reverseVal (tree->left->args);
3041 reverseParms (tree->right);
3044 tree->args = tree->left->args;
3045 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3048 /*------------------------------------------------------------------*/
3049 /*----------------------------*/
3050 /* return statement */
3051 /*----------------------------*/
3056 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3058 werror (E_RETURN_MISMATCH);
3059 goto errorTreeReturn;
3062 if (IS_VOID (currFunc->type->next)
3064 !IS_VOID (RTYPE (tree)))
3066 werror (E_FUNC_VOID);
3067 goto errorTreeReturn;
3070 /* if there is going to be a casing required then add it */
3071 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3073 #if 0 && defined DEMAND_INTEGER_PROMOTION
3074 if (IS_INTEGRAL (currFunc->type->next))
3076 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3082 decorateType (newNode (CAST,
3083 newAst_LINK (copyLinkChain (currFunc->type->next)),
3093 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3095 werror (E_VOID_FUNC, currFunc->name);
3096 goto errorTreeReturn;
3099 TTYPE (tree) = TETYPE (tree) = NULL;
3102 /*------------------------------------------------------------------*/
3103 /*----------------------------*/
3104 /* switch statement */
3105 /*----------------------------*/
3107 /* the switch value must be an integer */
3108 if (!IS_INTEGRAL (LTYPE (tree)))
3110 werror (E_SWITCH_NON_INTEGER);
3111 goto errorTreeReturn;
3114 TTYPE (tree) = TETYPE (tree) = NULL;
3117 /*------------------------------------------------------------------*/
3118 /*----------------------------*/
3120 /*----------------------------*/
3122 tree->left = backPatchLabels (tree->left,
3125 TTYPE (tree) = TETYPE (tree) = NULL;
3128 /*------------------------------------------------------------------*/
3129 /*----------------------------*/
3131 /*----------------------------*/
3134 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3135 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3136 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3138 /* if the for loop is reversible then
3139 reverse it otherwise do what we normally
3145 if (isLoopReversible (tree, &sym, &init, &end))
3146 return reverseLoop (tree, sym, init, end);
3148 return decorateType (createFor (AST_FOR (tree, trueLabel),
3149 AST_FOR (tree, continueLabel),
3150 AST_FOR (tree, falseLabel),
3151 AST_FOR (tree, condLabel),
3152 AST_FOR (tree, initExpr),
3153 AST_FOR (tree, condExpr),
3154 AST_FOR (tree, loopExpr),
3158 TTYPE (tree) = TETYPE (tree) = NULL;
3162 /* some error found this tree will be killed */
3164 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3165 tree->opval.op = NULLOP;
3171 /*-----------------------------------------------------------------*/
3172 /* sizeofOp - processes size of operation */
3173 /*-----------------------------------------------------------------*/
3175 sizeofOp (sym_link * type)
3179 /* make sure the type is complete and sane */
3180 checkTypeSanity(type, "(sizeof)");
3182 /* get the size and convert it to character */
3183 sprintf (buff, "%d", getSize (type));
3185 /* now convert into value */
3186 return constVal (buff);
3190 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3191 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3192 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3193 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3194 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3195 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3196 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3198 /*-----------------------------------------------------------------*/
3199 /* backPatchLabels - change and or not operators to flow control */
3200 /*-----------------------------------------------------------------*/
3202 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3208 if (!(IS_ANDORNOT (tree)))
3211 /* if this an and */
3214 static int localLbl = 0;
3217 sprintf (buffer, "_and_%d", localLbl++);
3218 localLabel = newSymbol (buffer, NestLevel);
3220 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3222 /* if left is already a IFX then just change the if true label in that */
3223 if (!IS_IFX (tree->left))
3224 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3226 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3227 /* right is a IFX then just join */
3228 if (IS_IFX (tree->right))
3229 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3231 tree->right = createLabel (localLabel, tree->right);
3232 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3234 return newNode (NULLOP, tree->left, tree->right);
3237 /* if this is an or operation */
3240 static int localLbl = 0;
3243 sprintf (buffer, "_or_%d", localLbl++);
3244 localLabel = newSymbol (buffer, NestLevel);
3246 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3248 /* if left is already a IFX then just change the if true label in that */
3249 if (!IS_IFX (tree->left))
3250 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3252 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3253 /* right is a IFX then just join */
3254 if (IS_IFX (tree->right))
3255 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3257 tree->right = createLabel (localLabel, tree->right);
3258 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3260 return newNode (NULLOP, tree->left, tree->right);
3266 int wasnot = IS_NOT (tree->left);
3267 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3269 /* if the left is already a IFX */
3270 if (!IS_IFX (tree->left))
3271 tree->left = newNode (IFX, tree->left, NULL);
3275 tree->left->trueLabel = trueLabel;
3276 tree->left->falseLabel = falseLabel;
3280 tree->left->trueLabel = falseLabel;
3281 tree->left->falseLabel = trueLabel;
3288 tree->trueLabel = trueLabel;
3289 tree->falseLabel = falseLabel;
3296 /*-----------------------------------------------------------------*/
3297 /* createBlock - create expression tree for block */
3298 /*-----------------------------------------------------------------*/
3300 createBlock (symbol * decl, ast * body)
3304 /* if the block has nothing */
3308 ex = newNode (BLOCK, NULL, body);
3309 ex->values.sym = decl;
3311 ex->right = ex->right;
3317 /*-----------------------------------------------------------------*/
3318 /* createLabel - creates the expression tree for labels */
3319 /*-----------------------------------------------------------------*/
3321 createLabel (symbol * label, ast * stmnt)
3324 char name[SDCC_NAME_MAX + 1];
3327 /* must create fresh symbol if the symbol name */
3328 /* exists in the symbol table, since there can */
3329 /* be a variable with the same name as the labl */
3330 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3331 (csym->level == label->level))
3332 label = newSymbol (label->name, label->level);
3334 /* change the name before putting it in add _ */
3335 sprintf (name, "%s", label->name);
3337 /* put the label in the LabelSymbol table */
3338 /* but first check if a label of the same */
3340 if ((csym = findSym (LabelTab, NULL, name)))
3341 werror (E_DUPLICATE_LABEL, label->name);
3343 addSym (LabelTab, label, name, label->level, 0, 0);
3346 label->key = labelKey++;
3347 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3353 /*-----------------------------------------------------------------*/
3354 /* createCase - generates the parsetree for a case statement */
3355 /*-----------------------------------------------------------------*/
3357 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3359 char caseLbl[SDCC_NAME_MAX + 1];
3363 /* if the switch statement does not exist */
3364 /* then case is out of context */
3367 werror (E_CASE_CONTEXT);
3371 caseVal = decorateType (resolveSymbols (caseVal));
3372 /* if not a constant then error */
3373 if (!IS_LITERAL (caseVal->ftype))
3375 werror (E_CASE_CONSTANT);
3379 /* if not a integer than error */
3380 if (!IS_INTEGRAL (caseVal->ftype))
3382 werror (E_CASE_NON_INTEGER);
3386 /* find the end of the switch values chain */
3387 if (!(val = swStat->values.switchVals.swVals))
3388 swStat->values.switchVals.swVals = caseVal->opval.val;
3391 /* also order the cases according to value */
3393 int cVal = (int) floatFromVal (caseVal->opval.val);
3394 while (val && (int) floatFromVal (val) < cVal)
3400 /* if we reached the end then */
3403 pval->next = caseVal->opval.val;
3407 /* we found a value greater than */
3408 /* the current value we must add this */
3409 /* before the value */
3410 caseVal->opval.val->next = val;
3412 /* if this was the first in chain */
3413 if (swStat->values.switchVals.swVals == val)
3414 swStat->values.switchVals.swVals =
3417 pval->next = caseVal->opval.val;
3422 /* create the case label */
3423 sprintf (caseLbl, "_case_%d_%d",
3424 swStat->values.switchVals.swNum,
3425 (int) floatFromVal (caseVal->opval.val));
3427 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3432 /*-----------------------------------------------------------------*/
3433 /* createDefault - creates the parse tree for the default statement */
3434 /*-----------------------------------------------------------------*/
3436 createDefault (ast * swStat, ast * stmnt)
3438 char defLbl[SDCC_NAME_MAX + 1];
3440 /* if the switch statement does not exist */
3441 /* then case is out of context */
3444 werror (E_CASE_CONTEXT);
3448 /* turn on the default flag */
3449 swStat->values.switchVals.swDefault = 1;
3451 /* create the label */
3452 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3453 return createLabel (newSymbol (defLbl, 0), stmnt);
3456 /*-----------------------------------------------------------------*/
3457 /* createIf - creates the parsetree for the if statement */
3458 /*-----------------------------------------------------------------*/
3460 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3462 static int Lblnum = 0;
3464 symbol *ifTrue, *ifFalse, *ifEnd;
3466 /* if neither exists */
3467 if (!elseBody && !ifBody)
3470 /* create the labels */
3471 sprintf (buffer, "_iffalse_%d", Lblnum);
3472 ifFalse = newSymbol (buffer, NestLevel);
3473 /* if no else body then end == false */
3478 sprintf (buffer, "_ifend_%d", Lblnum);
3479 ifEnd = newSymbol (buffer, NestLevel);
3482 sprintf (buffer, "_iftrue_%d", Lblnum);
3483 ifTrue = newSymbol (buffer, NestLevel);
3487 /* attach the ifTrue label to the top of it body */
3488 ifBody = createLabel (ifTrue, ifBody);
3489 /* attach a goto end to the ifBody if else is present */
3492 ifBody = newNode (NULLOP, ifBody,
3494 newAst_VALUE (symbolVal (ifEnd)),
3496 /* put the elseLabel on the else body */
3497 elseBody = createLabel (ifFalse, elseBody);
3498 /* out the end at the end of the body */
3499 elseBody = newNode (NULLOP,
3501 createLabel (ifEnd, NULL));
3505 ifBody = newNode (NULLOP, ifBody,
3506 createLabel (ifFalse, NULL));
3508 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3509 if (IS_IFX (condAst))
3512 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3514 return newNode (NULLOP, ifTree,
3515 newNode (NULLOP, ifBody, elseBody));
3519 /*-----------------------------------------------------------------*/
3520 /* createDo - creates parse tree for do */
3523 /* _docontinue_n: */
3524 /* condition_expression +-> trueLabel -> _dobody_n */
3526 /* +-> falseLabel-> _dobreak_n */
3528 /*-----------------------------------------------------------------*/
3530 createDo (symbol * trueLabel, symbol * continueLabel,
3531 symbol * falseLabel, ast * condAst, ast * doBody)
3536 /* if the body does not exist then it is simple */
3539 condAst = backPatchLabels (condAst, continueLabel, NULL);
3540 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3541 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3542 doTree->trueLabel = continueLabel;
3543 doTree->falseLabel = NULL;
3547 /* otherwise we have a body */
3548 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3550 /* attach the body label to the top */
3551 doBody = createLabel (trueLabel, doBody);
3552 /* attach the continue label to end of body */
3553 doBody = newNode (NULLOP, doBody,
3554 createLabel (continueLabel, NULL));
3556 /* now put the break label at the end */
3557 if (IS_IFX (condAst))
3560 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3562 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3564 /* putting it together */
3565 return newNode (NULLOP, doBody, doTree);
3568 /*-----------------------------------------------------------------*/
3569 /* createFor - creates parse tree for 'for' statement */
3572 /* condExpr +-> trueLabel -> _forbody_n */
3574 /* +-> falseLabel-> _forbreak_n */
3577 /* _forcontinue_n: */
3579 /* goto _forcond_n ; */
3581 /*-----------------------------------------------------------------*/
3583 createFor (symbol * trueLabel, symbol * continueLabel,
3584 symbol * falseLabel, symbol * condLabel,
3585 ast * initExpr, ast * condExpr, ast * loopExpr,
3590 /* if loopexpression not present then we can generate it */
3591 /* the same way as a while */
3593 return newNode (NULLOP, initExpr,
3594 createWhile (trueLabel, continueLabel,
3595 falseLabel, condExpr, forBody));
3596 /* vanilla for statement */
3597 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3599 if (condExpr && !IS_IFX (condExpr))
3600 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3603 /* attach condition label to condition */
3604 condExpr = createLabel (condLabel, condExpr);
3606 /* attach body label to body */
3607 forBody = createLabel (trueLabel, forBody);
3609 /* attach continue to forLoop expression & attach */
3610 /* goto the forcond @ and of loopExpression */
3611 loopExpr = createLabel (continueLabel,
3615 newAst_VALUE (symbolVal (condLabel)),
3617 /* now start putting them together */
3618 forTree = newNode (NULLOP, initExpr, condExpr);
3619 forTree = newNode (NULLOP, forTree, forBody);
3620 forTree = newNode (NULLOP, forTree, loopExpr);
3621 /* finally add the break label */
3622 forTree = newNode (NULLOP, forTree,
3623 createLabel (falseLabel, NULL));
3627 /*-----------------------------------------------------------------*/
3628 /* createWhile - creates parse tree for while statement */
3629 /* the while statement will be created as follows */
3631 /* _while_continue_n: */
3632 /* condition_expression +-> trueLabel -> _while_boby_n */
3634 /* +-> falseLabel -> _while_break_n */
3635 /* _while_body_n: */
3637 /* goto _while_continue_n */
3638 /* _while_break_n: */
3639 /*-----------------------------------------------------------------*/
3641 createWhile (symbol * trueLabel, symbol * continueLabel,
3642 symbol * falseLabel, ast * condExpr, ast * whileBody)
3646 /* put the continue label */
3647 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3648 condExpr = createLabel (continueLabel, condExpr);
3649 condExpr->lineno = 0;
3651 /* put the body label in front of the body */
3652 whileBody = createLabel (trueLabel, whileBody);
3653 whileBody->lineno = 0;
3654 /* put a jump to continue at the end of the body */
3655 /* and put break label at the end of the body */
3656 whileBody = newNode (NULLOP,
3659 newAst_VALUE (symbolVal (continueLabel)),
3660 createLabel (falseLabel, NULL)));
3662 /* put it all together */
3663 if (IS_IFX (condExpr))
3664 whileTree = condExpr;
3667 whileTree = newNode (IFX, condExpr, NULL);
3668 /* put the true & false labels in place */
3669 whileTree->trueLabel = trueLabel;
3670 whileTree->falseLabel = falseLabel;
3673 return newNode (NULLOP, whileTree, whileBody);
3676 /*-----------------------------------------------------------------*/
3677 /* optimizeGetHbit - get highest order bit of the expression */
3678 /*-----------------------------------------------------------------*/
3680 optimizeGetHbit (ast * tree)
3683 /* if this is not a bit and */
3684 if (!IS_BITAND (tree))
3687 /* will look for tree of the form
3688 ( expr >> ((sizeof expr) -1) ) & 1 */
3689 if (!IS_AST_LIT_VALUE (tree->right))
3692 if (AST_LIT_VALUE (tree->right) != 1)
3695 if (!IS_RIGHT_OP (tree->left))
3698 if (!IS_AST_LIT_VALUE (tree->left->right))
3701 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3702 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3705 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3709 /*-----------------------------------------------------------------*/
3710 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3711 /*-----------------------------------------------------------------*/
3713 optimizeRRCRLC (ast * root)
3715 /* will look for trees of the form
3716 (?expr << 1) | (?expr >> 7) or
3717 (?expr >> 7) | (?expr << 1) will make that
3718 into a RLC : operation ..
3720 (?expr >> 1) | (?expr << 7) or
3721 (?expr << 7) | (?expr >> 1) will make that
3722 into a RRC operation
3723 note : by 7 I mean (number of bits required to hold the
3725 /* if the root operations is not a | operation the not */
3726 if (!IS_BITOR (root))
3729 /* I have to think of a better way to match patterns this sucks */
3730 /* that aside let start looking for the first case : I use a the
3731 negative check a lot to improve the efficiency */
3732 /* (?expr << 1) | (?expr >> 7) */
3733 if (IS_LEFT_OP (root->left) &&
3734 IS_RIGHT_OP (root->right))
3737 if (!SPEC_USIGN (TETYPE (root->left->left)))
3740 if (!IS_AST_LIT_VALUE (root->left->right) ||
3741 !IS_AST_LIT_VALUE (root->right->right))
3744 /* make sure it is the same expression */
3745 if (!isAstEqual (root->left->left,
3749 if (AST_LIT_VALUE (root->left->right) != 1)
3752 if (AST_LIT_VALUE (root->right->right) !=
3753 (getSize (TTYPE (root->left->left)) * 8 - 1))
3756 /* whew got the first case : create the AST */
3757 return newNode (RLC, root->left->left, NULL);
3761 /* check for second case */
3762 /* (?expr >> 7) | (?expr << 1) */
3763 if (IS_LEFT_OP (root->right) &&
3764 IS_RIGHT_OP (root->left))
3767 if (!SPEC_USIGN (TETYPE (root->left->left)))
3770 if (!IS_AST_LIT_VALUE (root->left->right) ||
3771 !IS_AST_LIT_VALUE (root->right->right))
3774 /* make sure it is the same symbol */
3775 if (!isAstEqual (root->left->left,
3779 if (AST_LIT_VALUE (root->right->right) != 1)
3782 if (AST_LIT_VALUE (root->left->right) !=
3783 (getSize (TTYPE (root->left->left)) * 8 - 1))
3786 /* whew got the first case : create the AST */
3787 return newNode (RLC, root->left->left, NULL);
3792 /* third case for RRC */
3793 /* (?symbol >> 1) | (?symbol << 7) */
3794 if (IS_LEFT_OP (root->right) &&
3795 IS_RIGHT_OP (root->left))
3798 if (!SPEC_USIGN (TETYPE (root->left->left)))
3801 if (!IS_AST_LIT_VALUE (root->left->right) ||
3802 !IS_AST_LIT_VALUE (root->right->right))
3805 /* make sure it is the same symbol */
3806 if (!isAstEqual (root->left->left,
3810 if (AST_LIT_VALUE (root->left->right) != 1)
3813 if (AST_LIT_VALUE (root->right->right) !=
3814 (getSize (TTYPE (root->left->left)) * 8 - 1))
3817 /* whew got the first case : create the AST */
3818 return newNode (RRC, root->left->left, NULL);
3822 /* fourth and last case for now */
3823 /* (?symbol << 7) | (?symbol >> 1) */
3824 if (IS_RIGHT_OP (root->right) &&
3825 IS_LEFT_OP (root->left))
3828 if (!SPEC_USIGN (TETYPE (root->left->left)))
3831 if (!IS_AST_LIT_VALUE (root->left->right) ||
3832 !IS_AST_LIT_VALUE (root->right->right))
3835 /* make sure it is the same symbol */
3836 if (!isAstEqual (root->left->left,
3840 if (AST_LIT_VALUE (root->right->right) != 1)
3843 if (AST_LIT_VALUE (root->left->right) !=
3844 (getSize (TTYPE (root->left->left)) * 8 - 1))
3847 /* whew got the first case : create the AST */
3848 return newNode (RRC, root->left->left, NULL);
3852 /* not found return root */
3856 /*-----------------------------------------------------------------*/
3857 /* optimizeCompare - otimizes compares for bit variables */
3858 /*-----------------------------------------------------------------*/
3860 optimizeCompare (ast * root)
3862 ast *optExpr = NULL;
3865 unsigned int litValue;
3867 /* if nothing then return nothing */
3871 /* if not a compare op then do leaves */
3872 if (!IS_COMPARE_OP (root))
3874 root->left = optimizeCompare (root->left);
3875 root->right = optimizeCompare (root->right);
3879 /* if left & right are the same then depending
3880 of the operation do */
3881 if (isAstEqual (root->left, root->right))
3883 switch (root->opval.op)
3888 optExpr = newAst_VALUE (constVal ("0"));
3893 optExpr = newAst_VALUE (constVal ("1"));
3897 return decorateType (optExpr);
3900 vleft = (root->left->type == EX_VALUE ?
3901 root->left->opval.val : NULL);
3903 vright = (root->right->type == EX_VALUE ?
3904 root->right->opval.val : NULL);
3906 /* if left is a BITVAR in BITSPACE */
3907 /* and right is a LITERAL then opt- */
3908 /* imize else do nothing */
3909 if (vleft && vright &&
3910 IS_BITVAR (vleft->etype) &&
3911 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3912 IS_LITERAL (vright->etype))
3915 /* if right side > 1 then comparison may never succeed */
3916 if ((litValue = (int) floatFromVal (vright)) > 1)
3918 werror (W_BAD_COMPARE);
3924 switch (root->opval.op)
3926 case '>': /* bit value greater than 1 cannot be */
3927 werror (W_BAD_COMPARE);
3931 case '<': /* bit value < 1 means 0 */
3933 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3936 case LE_OP: /* bit value <= 1 means no check */
3937 optExpr = newAst_VALUE (vright);
3940 case GE_OP: /* bit value >= 1 means only check for = */
3942 optExpr = newAst_VALUE (vleft);
3947 { /* literal is zero */
3948 switch (root->opval.op)
3950 case '<': /* bit value < 0 cannot be */
3951 werror (W_BAD_COMPARE);
3955 case '>': /* bit value > 0 means 1 */
3957 optExpr = newAst_VALUE (vleft);
3960 case LE_OP: /* bit value <= 0 means no check */
3961 case GE_OP: /* bit value >= 0 means no check */
3962 werror (W_BAD_COMPARE);
3966 case EQ_OP: /* bit == 0 means ! of bit */
3967 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3971 return decorateType (resolveSymbols (optExpr));
3972 } /* end-of-if of BITVAR */
3977 /*-----------------------------------------------------------------*/
3978 /* addSymToBlock : adds the symbol to the first block we find */
3979 /*-----------------------------------------------------------------*/
3981 addSymToBlock (symbol * sym, ast * tree)
3983 /* reached end of tree or a leaf */
3984 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3988 if (IS_AST_OP (tree) &&
3989 tree->opval.op == BLOCK)
3992 symbol *lsym = copySymbol (sym);
3994 lsym->next = AST_VALUES (tree, sym);
3995 AST_VALUES (tree, sym) = lsym;
3999 addSymToBlock (sym, tree->left);
4000 addSymToBlock (sym, tree->right);
4003 /*-----------------------------------------------------------------*/
4004 /* processRegParms - do processing for register parameters */
4005 /*-----------------------------------------------------------------*/
4007 processRegParms (value * args, ast * body)
4011 if (IS_REGPARM (args->etype))
4012 addSymToBlock (args->sym, body);
4017 /*-----------------------------------------------------------------*/
4018 /* resetParmKey - resets the operandkeys for the symbols */
4019 /*-----------------------------------------------------------------*/
4020 DEFSETFUNC (resetParmKey)
4031 /*-----------------------------------------------------------------*/
4032 /* createFunction - This is the key node that calls the iCode for */
4033 /* generating the code for a function. Note code */
4034 /* is generated function by function, later when */
4035 /* add inter-procedural analysis this will change */
4036 /*-----------------------------------------------------------------*/
4038 createFunction (symbol * name, ast * body)
4044 iCode *piCode = NULL;
4046 /* if check function return 0 then some problem */
4047 if (checkFunction (name) == 0)
4050 /* create a dummy block if none exists */
4052 body = newNode (BLOCK, NULL, NULL);
4056 /* check if the function name already in the symbol table */
4057 if ((csym = findSym (SymbolTab, NULL, name->name)))
4060 /* special case for compiler defined functions
4061 we need to add the name to the publics list : this
4062 actually means we are now compiling the compiler
4066 addSet (&publics, name);
4072 allocVariables (name);
4074 name->lastLine = yylineno;
4076 processFuncArgs (currFunc, 0);
4078 /* set the stack pointer */
4079 /* PENDING: check this for the mcs51 */
4080 stackPtr = -port->stack.direction * port->stack.call_overhead;
4081 if (IS_ISR (name->etype))
4082 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4083 if (IS_RENT (name->etype) || options.stackAuto)
4084 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4086 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4088 fetype = getSpec (name->type); /* get the specifier for the function */
4089 /* if this is a reentrant function then */
4090 if (IS_RENT (fetype))
4093 allocParms (name->args); /* allocate the parameters */
4095 /* do processing for parameters that are passed in registers */
4096 processRegParms (name->args, body);
4098 /* set the stack pointer */
4102 /* allocate & autoinit the block variables */
4103 processBlockVars (body, &stack, ALLOCATE);
4105 /* save the stack information */
4106 if (options.useXstack)
4107 name->xstack = SPEC_STAK (fetype) = stack;
4109 name->stack = SPEC_STAK (fetype) = stack;
4111 /* name needs to be mangled */
4112 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4114 body = resolveSymbols (body); /* resolve the symbols */
4115 body = decorateType (body); /* propagateType & do semantic checks */
4117 ex = newAst_VALUE (symbolVal (name)); /* create name */
4118 ex = newNode (FUNCTION, ex, body);
4119 ex->values.args = name->args;
4123 werror (E_FUNC_NO_CODE, name->name);
4127 /* create the node & generate intermediate code */
4129 codeOutFile = code->oFile;
4130 piCode = iCodeFromAst (ex);
4134 werror (E_FUNC_NO_CODE, name->name);
4138 eBBlockFromiCode (piCode);
4140 /* if there are any statics then do them */
4143 GcurMemmap = statsg;
4144 codeOutFile = statsg->oFile;
4145 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4151 /* dealloc the block variables */
4152 processBlockVars (body, &stack, DEALLOCATE);
4153 /* deallocate paramaters */
4154 deallocParms (name->args);
4156 if (IS_RENT (fetype))
4159 /* we are done freeup memory & cleanup */
4164 addSet (&operKeyReset, name);
4165 applyToSet (operKeyReset, resetParmKey);
4168 cdbStructBlock (1, cdbFile);
4170 cleanUpLevel (LabelTab, 0);
4171 cleanUpBlock (StructTab, 1);
4172 cleanUpBlock (TypedefTab, 1);
4174 xstack->syms = NULL;
4175 istack->syms = NULL;
4180 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4181 /*-----------------------------------------------------------------*/
4182 /* ast_print : prints the ast (for debugging purposes) */
4183 /*-----------------------------------------------------------------*/
4185 void ast_print (ast * tree, FILE *outfile, int indent)
4190 /* can print only decorated trees */
4191 if (!tree->decorated) return;
4193 /* if any child is an error | this one is an error do nothing */
4194 if (tree->isError ||
4195 (tree->left && tree->left->isError) ||
4196 (tree->right && tree->right->isError)) {
4197 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4201 /* print the line */
4202 /* if not block & function */
4203 if (tree->type == EX_OP &&
4204 (tree->opval.op != FUNCTION &&
4205 tree->opval.op != BLOCK &&
4206 tree->opval.op != NULLOP)) {
4209 if (tree->opval.op == FUNCTION) {
4210 fprintf(outfile,"FUNCTION (%p) type (",tree);
4211 printTypeChain (tree->ftype,outfile);
4212 fprintf(outfile,")\n");
4213 ast_print(tree->left,outfile,indent+4);
4214 ast_print(tree->right,outfile,indent+4);
4217 if (tree->opval.op == BLOCK) {
4218 symbol *decls = tree->values.sym;
4219 fprintf(outfile,"{\n");
4221 INDENT(indent+4,outfile);
4222 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4223 printTypeChain(decls->type,outfile);
4224 fprintf(outfile,")\n");
4226 decls = decls->next;
4228 ast_print(tree->right,outfile,indent+4);
4229 fprintf(outfile,"}\n");
4232 if (tree->opval.op == NULLOP) {
4233 fprintf(outfile,"\n");
4234 ast_print(tree->left,outfile,indent);
4235 fprintf(outfile,"\n");
4236 ast_print(tree->right,outfile,indent);
4239 INDENT(indent,outfile);
4241 /*------------------------------------------------------------------*/
4242 /*----------------------------*/
4243 /* leaf has been reached */
4244 /*----------------------------*/
4245 /* if this is of type value */
4246 /* just get the type */
4247 if (tree->type == EX_VALUE) {
4249 if (IS_LITERAL (tree->opval.val->etype)) {
4250 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4251 (int) floatFromVal(tree->opval.val),
4252 (int) floatFromVal(tree->opval.val),
4253 floatFromVal(tree->opval.val));
4254 } else if (tree->opval.val->sym) {
4255 /* if the undefined flag is set then give error message */
4256 if (tree->opval.val->sym->undefined) {
4257 fprintf(outfile,"UNDEFINED SYMBOL ");
4259 fprintf(outfile,"SYMBOL ");
4261 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4264 fprintf(outfile," type (");
4265 printTypeChain(tree->ftype,outfile);
4266 fprintf(outfile,")\n");
4268 fprintf(outfile,"\n");
4273 /* if type link for the case of cast */
4274 if (tree->type == EX_LINK) {
4275 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4276 printTypeChain(tree->opval.lnk,outfile);
4277 fprintf(outfile,")\n");
4282 /* depending on type of operator do */
4284 switch (tree->opval.op) {
4285 /*------------------------------------------------------------------*/
4286 /*----------------------------*/
4288 /*----------------------------*/
4290 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4291 printTypeChain(tree->ftype,outfile);
4292 fprintf(outfile,")\n");
4293 ast_print(tree->left,outfile,indent+4);
4294 ast_print(tree->right,outfile,indent+4);
4297 /*------------------------------------------------------------------*/
4298 /*----------------------------*/
4300 /*----------------------------*/
4302 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4303 printTypeChain(tree->ftype,outfile);
4304 fprintf(outfile,")\n");
4305 ast_print(tree->left,outfile,indent+4);
4306 ast_print(tree->right,outfile,indent+4);
4309 /*------------------------------------------------------------------*/
4310 /*----------------------------*/
4311 /* struct/union pointer */
4312 /*----------------------------*/
4314 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4315 printTypeChain(tree->ftype,outfile);
4316 fprintf(outfile,")\n");
4317 ast_print(tree->left,outfile,indent+4);
4318 ast_print(tree->right,outfile,indent+4);
4321 /*------------------------------------------------------------------*/
4322 /*----------------------------*/
4323 /* ++/-- operation */
4324 /*----------------------------*/
4325 case INC_OP: /* incerement operator unary so left only */
4326 fprintf(outfile,"INC_OP (%p) type (",tree);
4327 printTypeChain(tree->ftype,outfile);
4328 fprintf(outfile,")\n");
4329 ast_print(tree->left,outfile,indent+4);
4333 fprintf(outfile,"DEC_OP (%p) type (",tree);
4334 printTypeChain(tree->ftype,outfile);
4335 fprintf(outfile,")\n");
4336 ast_print(tree->left,outfile,indent+4);
4339 /*------------------------------------------------------------------*/
4340 /*----------------------------*/
4342 /*----------------------------*/
4345 fprintf(outfile,"& (%p) type (",tree);
4346 printTypeChain(tree->ftype,outfile);
4347 fprintf(outfile,")\n");
4348 ast_print(tree->left,outfile,indent+4);
4349 ast_print(tree->right,outfile,indent+4);
4351 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4352 printTypeChain(tree->ftype,outfile);
4353 fprintf(outfile,")\n");
4354 ast_print(tree->left,outfile,indent+4);
4355 ast_print(tree->right,outfile,indent+4);
4358 /*----------------------------*/
4360 /*----------------------------*/
4362 fprintf(outfile,"OR (%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);
4368 /*------------------------------------------------------------------*/
4369 /*----------------------------*/
4371 /*----------------------------*/
4373 fprintf(outfile,"XOR (%p) type (",tree);
4374 printTypeChain(tree->ftype,outfile);
4375 fprintf(outfile,")\n");
4376 ast_print(tree->left,outfile,indent+4);
4377 ast_print(tree->right,outfile,indent+4);
4380 /*------------------------------------------------------------------*/
4381 /*----------------------------*/
4383 /*----------------------------*/
4385 fprintf(outfile,"DIV (%p) type (",tree);
4386 printTypeChain(tree->ftype,outfile);
4387 fprintf(outfile,")\n");
4388 ast_print(tree->left,outfile,indent+4);
4389 ast_print(tree->right,outfile,indent+4);
4391 /*------------------------------------------------------------------*/
4392 /*----------------------------*/
4394 /*----------------------------*/
4396 fprintf(outfile,"MOD (%p) type (",tree);
4397 printTypeChain(tree->ftype,outfile);
4398 fprintf(outfile,")\n");
4399 ast_print(tree->left,outfile,indent+4);
4400 ast_print(tree->right,outfile,indent+4);
4403 /*------------------------------------------------------------------*/
4404 /*----------------------------*/
4405 /* address dereference */
4406 /*----------------------------*/
4407 case '*': /* can be unary : if right is null then unary operation */
4409 fprintf(outfile,"DEREF (%p) type (",tree);
4410 printTypeChain(tree->ftype,outfile);
4411 fprintf(outfile,")\n");
4412 ast_print(tree->left,outfile,indent+4);
4415 /*------------------------------------------------------------------*/
4416 /*----------------------------*/
4417 /* multiplication */
4418 /*----------------------------*/
4419 fprintf(outfile,"MULT (%p) type (",tree);
4420 printTypeChain(tree->ftype,outfile);
4421 fprintf(outfile,")\n");
4422 ast_print(tree->left,outfile,indent+4);
4423 ast_print(tree->right,outfile,indent+4);
4427 /*------------------------------------------------------------------*/
4428 /*----------------------------*/
4429 /* unary '+' operator */
4430 /*----------------------------*/
4434 fprintf(outfile,"UPLUS (%p) type (",tree);
4435 printTypeChain(tree->ftype,outfile);
4436 fprintf(outfile,")\n");
4437 ast_print(tree->left,outfile,indent+4);
4439 /*------------------------------------------------------------------*/
4440 /*----------------------------*/
4442 /*----------------------------*/
4443 fprintf(outfile,"ADD (%p) type (",tree);
4444 printTypeChain(tree->ftype,outfile);
4445 fprintf(outfile,")\n");
4446 ast_print(tree->left,outfile,indent+4);
4447 ast_print(tree->right,outfile,indent+4);
4450 /*------------------------------------------------------------------*/
4451 /*----------------------------*/
4453 /*----------------------------*/
4454 case '-': /* can be unary */
4456 fprintf(outfile,"UMINUS (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+4);
4461 /*------------------------------------------------------------------*/
4462 /*----------------------------*/
4464 /*----------------------------*/
4465 fprintf(outfile,"SUB (%p) type (",tree);
4466 printTypeChain(tree->ftype,outfile);
4467 fprintf(outfile,")\n");
4468 ast_print(tree->left,outfile,indent+4);
4469 ast_print(tree->right,outfile,indent+4);
4472 /*------------------------------------------------------------------*/
4473 /*----------------------------*/
4475 /*----------------------------*/
4477 fprintf(outfile,"COMPL (%p) type (",tree);
4478 printTypeChain(tree->ftype,outfile);
4479 fprintf(outfile,")\n");
4480 ast_print(tree->left,outfile,indent+4);
4482 /*------------------------------------------------------------------*/
4483 /*----------------------------*/
4485 /*----------------------------*/
4487 fprintf(outfile,"NOT (%p) type (",tree);
4488 printTypeChain(tree->ftype,outfile);
4489 fprintf(outfile,")\n");
4490 ast_print(tree->left,outfile,indent+4);
4492 /*------------------------------------------------------------------*/
4493 /*----------------------------*/
4495 /*----------------------------*/
4497 fprintf(outfile,"RRC (%p) type (",tree);
4498 printTypeChain(tree->ftype,outfile);
4499 fprintf(outfile,")\n");
4500 ast_print(tree->left,outfile,indent+4);
4504 fprintf(outfile,"RLC (%p) type (",tree);
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4507 ast_print(tree->left,outfile,indent+4);
4510 fprintf(outfile,"GETHBIT (%p) type (",tree);
4511 printTypeChain(tree->ftype,outfile);
4512 fprintf(outfile,")\n");
4513 ast_print(tree->left,outfile,indent+4);
4516 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4517 printTypeChain(tree->ftype,outfile);
4518 fprintf(outfile,")\n");
4519 ast_print(tree->left,outfile,indent+4);
4520 ast_print(tree->right,outfile,indent+4);
4523 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4524 printTypeChain(tree->ftype,outfile);
4525 fprintf(outfile,")\n");
4526 ast_print(tree->left,outfile,indent+4);
4527 ast_print(tree->right,outfile,indent+4);
4529 /*------------------------------------------------------------------*/
4530 /*----------------------------*/
4532 /*----------------------------*/
4533 case CAST: /* change the type */
4534 fprintf(outfile,"CAST (%p) type (",tree);
4535 printTypeChain(tree->ftype,outfile);
4536 fprintf(outfile,")\n");
4537 ast_print(tree->right,outfile,indent+4);
4541 fprintf(outfile,"ANDAND (%p) type (",tree);
4542 printTypeChain(tree->ftype,outfile);
4543 fprintf(outfile,")\n");
4544 ast_print(tree->left,outfile,indent+4);
4545 ast_print(tree->right,outfile,indent+4);
4548 fprintf(outfile,"OROR (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+4);
4552 ast_print(tree->right,outfile,indent+4);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4557 /* comparison operators */
4558 /*----------------------------*/
4560 fprintf(outfile,"GT(>) (%p) type (",tree);
4561 printTypeChain(tree->ftype,outfile);
4562 fprintf(outfile,")\n");
4563 ast_print(tree->left,outfile,indent+4);
4564 ast_print(tree->right,outfile,indent+4);
4567 fprintf(outfile,"LT(<) (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+4);
4571 ast_print(tree->right,outfile,indent+4);
4574 fprintf(outfile,"LE(<=) (%p) type (",tree);
4575 printTypeChain(tree->ftype,outfile);
4576 fprintf(outfile,")\n");
4577 ast_print(tree->left,outfile,indent+4);
4578 ast_print(tree->right,outfile,indent+4);
4581 fprintf(outfile,"GE(>=) (%p) type (",tree);
4582 printTypeChain(tree->ftype,outfile);
4583 fprintf(outfile,")\n");
4584 ast_print(tree->left,outfile,indent+4);
4585 ast_print(tree->right,outfile,indent+4);
4588 fprintf(outfile,"EQ(==) (%p) type (",tree);
4589 printTypeChain(tree->ftype,outfile);
4590 fprintf(outfile,")\n");
4591 ast_print(tree->left,outfile,indent+4);
4592 ast_print(tree->right,outfile,indent+4);
4595 fprintf(outfile,"NE(!=) (%p) type (",tree);
4596 printTypeChain(tree->ftype,outfile);
4597 fprintf(outfile,")\n");
4598 ast_print(tree->left,outfile,indent+4);
4599 ast_print(tree->right,outfile,indent+4);
4600 /*------------------------------------------------------------------*/
4601 /*----------------------------*/
4603 /*----------------------------*/
4604 case SIZEOF: /* evaluate wihout code generation */
4605 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4608 /*------------------------------------------------------------------*/
4609 /*----------------------------*/
4610 /* conditional operator '?' */
4611 /*----------------------------*/
4613 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+4);
4617 ast_print(tree->right,outfile,indent+4);
4620 fprintf(outfile,"COLON(:) (%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 /*------------------------------------------------------------------*/
4628 /*----------------------------*/
4629 /* assignment operators */
4630 /*----------------------------*/
4632 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+4);
4636 ast_print(tree->right,outfile,indent+4);
4639 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4640 printTypeChain(tree->ftype,outfile);
4641 fprintf(outfile,")\n");
4642 ast_print(tree->left,outfile,indent+4);
4643 ast_print(tree->right,outfile,indent+4);
4646 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+4);
4650 ast_print(tree->right,outfile,indent+4);
4653 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4654 printTypeChain(tree->ftype,outfile);
4655 fprintf(outfile,")\n");
4656 ast_print(tree->left,outfile,indent+4);
4657 ast_print(tree->right,outfile,indent+4);
4660 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4661 printTypeChain(tree->ftype,outfile);
4662 fprintf(outfile,")\n");
4663 ast_print(tree->left,outfile,indent+4);
4664 ast_print(tree->right,outfile,indent+4);
4667 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4668 printTypeChain(tree->ftype,outfile);
4669 fprintf(outfile,")\n");
4670 ast_print(tree->left,outfile,indent+4);
4671 ast_print(tree->right,outfile,indent+4);
4674 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4675 printTypeChain(tree->ftype,outfile);
4676 fprintf(outfile,")\n");
4677 ast_print(tree->left,outfile,indent+4);
4678 ast_print(tree->right,outfile,indent+4);
4680 /*------------------------------------------------------------------*/
4681 /*----------------------------*/
4683 /*----------------------------*/
4685 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4686 printTypeChain(tree->ftype,outfile);
4687 fprintf(outfile,")\n");
4688 ast_print(tree->left,outfile,indent+4);
4689 ast_print(tree->right,outfile,indent+4);
4691 /*------------------------------------------------------------------*/
4692 /*----------------------------*/
4694 /*----------------------------*/
4696 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4702 /*------------------------------------------------------------------*/
4703 /*----------------------------*/
4704 /* straight assignemnt */
4705 /*----------------------------*/
4707 fprintf(outfile,"ASSIGN(=) (%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);
4713 /*------------------------------------------------------------------*/
4714 /*----------------------------*/
4715 /* comma operator */
4716 /*----------------------------*/
4718 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+4);
4722 ast_print(tree->right,outfile,indent+4);
4724 /*------------------------------------------------------------------*/
4725 /*----------------------------*/
4727 /*----------------------------*/
4730 fprintf(outfile,"CALL (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+4);
4734 ast_print(tree->right,outfile,indent+4);
4737 fprintf(outfile,"PARM ");
4738 ast_print(tree->left,outfile,indent+4);
4739 if (tree->right && !IS_AST_PARAM(tree->right)) {
4740 fprintf(outfile,"PARM ");
4741 ast_print(tree->right,outfile,indent+4);
4744 /*------------------------------------------------------------------*/
4745 /*----------------------------*/
4746 /* return statement */
4747 /*----------------------------*/
4749 fprintf(outfile,"RETURN (%p) type (",tree);
4750 printTypeChain(tree->right->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->right,outfile,indent+4);
4754 /*------------------------------------------------------------------*/
4755 /*----------------------------*/
4756 /* label statement */
4757 /*----------------------------*/
4759 fprintf(outfile,"LABEL (%p)",tree);
4760 ast_print(tree->left,outfile,indent+4);
4761 ast_print(tree->right,outfile,indent);
4763 /*------------------------------------------------------------------*/
4764 /*----------------------------*/
4765 /* switch statement */
4766 /*----------------------------*/
4770 fprintf(outfile,"SWITCH (%p) ",tree);
4771 ast_print(tree->left,outfile,0);
4772 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4773 INDENT(indent+4,outfile);
4774 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4775 (int) floatFromVal(val),
4776 tree->values.switchVals.swNum,
4777 (int) floatFromVal(val));
4779 ast_print(tree->right,outfile,indent);
4782 /*------------------------------------------------------------------*/
4783 /*----------------------------*/
4785 /*----------------------------*/
4787 ast_print(tree->left,outfile,indent);
4788 INDENT(indent,outfile);
4789 fprintf(outfile,"IF (%p) \n",tree);
4790 if (tree->trueLabel) {
4791 INDENT(indent,outfile);
4792 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4794 if (tree->falseLabel) {
4795 INDENT(indent,outfile);
4796 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4798 ast_print(tree->right,outfile,indent);
4800 /*------------------------------------------------------------------*/
4801 /*----------------------------*/
4803 /*----------------------------*/
4805 fprintf(outfile,"FOR (%p) \n",tree);
4806 if (AST_FOR( tree, initExpr)) {
4807 INDENT(indent+4,outfile);
4808 fprintf(outfile,"INIT EXPR ");
4809 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4811 if (AST_FOR( tree, condExpr)) {
4812 INDENT(indent+4,outfile);
4813 fprintf(outfile,"COND EXPR ");
4814 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4816 if (AST_FOR( tree, loopExpr)) {
4817 INDENT(indent+4,outfile);
4818 fprintf(outfile,"LOOP EXPR ");
4819 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4821 fprintf(outfile,"FOR LOOP BODY \n");
4822 ast_print(tree->left,outfile,indent+4);
4831 ast_print(t,stdout,1);