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);
2056 // we can't do this because of "(int & 0xff) << 3"
2058 /* if right or left is literal then result of that type */
2059 if (IS_LITERAL (RTYPE (tree)))
2062 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2063 TETYPE (tree) = getSpec (TTYPE (tree));
2064 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2068 if (IS_LITERAL (LTYPE (tree)))
2070 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2071 TETYPE (tree) = getSpec (TTYPE (tree));
2072 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2078 computeType (LTYPE (tree), RTYPE (tree));
2079 TETYPE (tree) = getSpec (TTYPE (tree));
2084 computeType (LTYPE (tree), RTYPE (tree));
2085 TETYPE (tree) = getSpec (TTYPE (tree));
2087 LRVAL (tree) = RRVAL (tree) = 1;
2091 /*------------------------------------------------------------------*/
2092 /*----------------------------*/
2094 /*----------------------------*/
2096 p->class = DECLARATOR;
2097 /* if bit field then error */
2098 if (IS_BITVAR (tree->left->etype))
2100 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2101 goto errorTreeReturn;
2104 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2106 werror (E_ILLEGAL_ADDR, "address of register variable");
2107 goto errorTreeReturn;
2110 if (IS_FUNC (LTYPE (tree)))
2112 werror (E_ILLEGAL_ADDR, "address of function");
2113 goto errorTreeReturn;
2118 werror (E_LVALUE_REQUIRED, "address of");
2119 goto errorTreeReturn;
2121 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2123 DCL_TYPE (p) = CPOINTER;
2124 DCL_PTR_CONST (p) = port->mem.code_ro;
2126 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2127 DCL_TYPE (p) = FPOINTER;
2128 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2129 DCL_TYPE (p) = PPOINTER;
2130 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2131 DCL_TYPE (p) = IPOINTER;
2132 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2133 DCL_TYPE (p) = EEPPOINTER;
2135 DCL_TYPE (p) = POINTER;
2137 if (IS_AST_SYM_VALUE (tree->left))
2139 AST_SYMBOL (tree->left)->addrtaken = 1;
2140 AST_SYMBOL (tree->left)->allocreq = 1;
2143 p->next = LTYPE (tree);
2145 TETYPE (tree) = getSpec (TTYPE (tree));
2146 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2147 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2152 /*------------------------------------------------------------------*/
2153 /*----------------------------*/
2155 /*----------------------------*/
2157 /* if the rewrite succeeds then don't go any furthur */
2159 ast *wtree = optimizeRRCRLC (tree);
2161 return decorateType (wtree);
2163 /*------------------------------------------------------------------*/
2164 /*----------------------------*/
2166 /*----------------------------*/
2168 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2170 werror (E_BITWISE_OP);
2171 werror (E_CONTINUE, "left & right types are ");
2172 printTypeChain (LTYPE (tree), stderr);
2173 fprintf (stderr, ",");
2174 printTypeChain (RTYPE (tree), stderr);
2175 fprintf (stderr, "\n");
2176 goto errorTreeReturn;
2179 /* if they are both literal then */
2180 /* rewrite the tree */
2181 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2183 tree->type = EX_VALUE;
2184 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2185 valFromType (RETYPE (tree)),
2187 tree->right = tree->left = NULL;
2188 TETYPE (tree) = tree->opval.val->etype;
2189 TTYPE (tree) = tree->opval.val->type;
2192 LRVAL (tree) = RRVAL (tree) = 1;
2193 TETYPE (tree) = getSpec (TTYPE (tree) =
2194 computeType (LTYPE (tree),
2197 /*------------------------------------------------------------------*/
2198 /*----------------------------*/
2200 /*----------------------------*/
2202 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2204 werror (E_INVALID_OP, "divide");
2205 goto errorTreeReturn;
2207 /* if they are both literal then */
2208 /* rewrite the tree */
2209 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2211 tree->type = EX_VALUE;
2212 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2213 valFromType (RETYPE (tree)));
2214 tree->right = tree->left = NULL;
2215 TETYPE (tree) = getSpec (TTYPE (tree) =
2216 tree->opval.val->type);
2219 LRVAL (tree) = RRVAL (tree) = 1;
2220 TETYPE (tree) = getSpec (TTYPE (tree) =
2221 computeType (LTYPE (tree),
2225 /*------------------------------------------------------------------*/
2226 /*----------------------------*/
2228 /*----------------------------*/
2230 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2232 werror (E_BITWISE_OP);
2233 werror (E_CONTINUE, "left & right types are ");
2234 printTypeChain (LTYPE (tree), stderr);
2235 fprintf (stderr, ",");
2236 printTypeChain (RTYPE (tree), stderr);
2237 fprintf (stderr, "\n");
2238 goto errorTreeReturn;
2240 /* if they are both literal then */
2241 /* rewrite the tree */
2242 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2244 tree->type = EX_VALUE;
2245 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2246 valFromType (RETYPE (tree)));
2247 tree->right = tree->left = NULL;
2248 TETYPE (tree) = getSpec (TTYPE (tree) =
2249 tree->opval.val->type);
2252 LRVAL (tree) = RRVAL (tree) = 1;
2253 TETYPE (tree) = getSpec (TTYPE (tree) =
2254 computeType (LTYPE (tree),
2258 /*------------------------------------------------------------------*/
2259 /*----------------------------*/
2260 /* address dereference */
2261 /*----------------------------*/
2262 case '*': /* can be unary : if right is null then unary operation */
2265 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2267 werror (E_PTR_REQD);
2268 goto errorTreeReturn;
2273 werror (E_LVALUE_REQUIRED, "pointer deref");
2274 goto errorTreeReturn;
2276 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2277 LTYPE (tree)->next : NULL);
2278 TETYPE (tree) = getSpec (TTYPE (tree));
2279 tree->args = tree->left->args;
2280 tree->hasVargs = tree->left->hasVargs;
2281 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2285 /*------------------------------------------------------------------*/
2286 /*----------------------------*/
2287 /* multiplication */
2288 /*----------------------------*/
2289 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2291 werror (E_INVALID_OP, "multiplication");
2292 goto errorTreeReturn;
2295 /* if they are both literal then */
2296 /* rewrite the tree */
2297 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2299 tree->type = EX_VALUE;
2300 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2301 valFromType (RETYPE (tree)));
2302 tree->right = tree->left = NULL;
2303 TETYPE (tree) = getSpec (TTYPE (tree) =
2304 tree->opval.val->type);
2308 /* if left is a literal exchange left & right */
2309 if (IS_LITERAL (LTYPE (tree)))
2311 ast *tTree = tree->left;
2312 tree->left = tree->right;
2313 tree->right = tTree;
2316 LRVAL (tree) = RRVAL (tree) = 1;
2317 /* promote result to int if left & right are char
2318 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2319 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2320 TETYPE (tree) = getSpec (TTYPE (tree) =
2321 computeType (LTYPE (tree),
2323 SPEC_NOUN(TETYPE(tree)) = V_INT;
2325 TETYPE (tree) = getSpec (TTYPE (tree) =
2326 computeType (LTYPE (tree),
2331 /*------------------------------------------------------------------*/
2332 /*----------------------------*/
2333 /* unary '+' operator */
2334 /*----------------------------*/
2339 if (!IS_INTEGRAL (LTYPE (tree)))
2341 werror (E_UNARY_OP, '+');
2342 goto errorTreeReturn;
2345 /* if left is a literal then do it */
2346 if (IS_LITERAL (LTYPE (tree)))
2348 tree->type = EX_VALUE;
2349 tree->opval.val = valFromType (LETYPE (tree));
2351 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2355 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2359 /*------------------------------------------------------------------*/
2360 /*----------------------------*/
2362 /*----------------------------*/
2364 /* this is not a unary operation */
2365 /* if both pointers then problem */
2366 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2367 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2369 werror (E_PTR_PLUS_PTR);
2370 goto errorTreeReturn;
2373 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2374 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2376 werror (E_PLUS_INVALID, "+");
2377 goto errorTreeReturn;
2380 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2381 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2383 werror (E_PLUS_INVALID, "+");
2384 goto errorTreeReturn;
2386 /* if they are both literal then */
2387 /* rewrite the tree */
2388 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2390 tree->type = EX_VALUE;
2391 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2392 valFromType (RETYPE (tree)));
2393 tree->right = tree->left = NULL;
2394 TETYPE (tree) = getSpec (TTYPE (tree) =
2395 tree->opval.val->type);
2399 /* if the right is a pointer or left is a literal
2400 xchange left & right */
2401 if (IS_ARRAY (RTYPE (tree)) ||
2402 IS_PTR (RTYPE (tree)) ||
2403 IS_LITERAL (LTYPE (tree)))
2405 ast *tTree = tree->left;
2406 tree->left = tree->right;
2407 tree->right = tTree;
2410 LRVAL (tree) = RRVAL (tree) = 1;
2411 /* if the left is a pointer */
2412 if (IS_PTR (LTYPE (tree)))
2413 TETYPE (tree) = getSpec (TTYPE (tree) =
2416 TETYPE (tree) = getSpec (TTYPE (tree) =
2417 computeType (LTYPE (tree),
2421 /*------------------------------------------------------------------*/
2422 /*----------------------------*/
2424 /*----------------------------*/
2425 case '-': /* can be unary */
2426 /* if right is null then unary */
2430 if (!IS_ARITHMETIC (LTYPE (tree)))
2432 werror (E_UNARY_OP, tree->opval.op);
2433 goto errorTreeReturn;
2436 /* if left is a literal then do it */
2437 if (IS_LITERAL (LTYPE (tree)))
2439 tree->type = EX_VALUE;
2440 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2442 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2443 SPEC_USIGN(TETYPE(tree)) = 0;
2447 TTYPE (tree) = LTYPE (tree);
2451 /*------------------------------------------------------------------*/
2452 /*----------------------------*/
2454 /*----------------------------*/
2456 if (!(IS_PTR (LTYPE (tree)) ||
2457 IS_ARRAY (LTYPE (tree)) ||
2458 IS_ARITHMETIC (LTYPE (tree))))
2460 werror (E_PLUS_INVALID, "-");
2461 goto errorTreeReturn;
2464 if (!(IS_PTR (RTYPE (tree)) ||
2465 IS_ARRAY (RTYPE (tree)) ||
2466 IS_ARITHMETIC (RTYPE (tree))))
2468 werror (E_PLUS_INVALID, "-");
2469 goto errorTreeReturn;
2472 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2473 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2474 IS_INTEGRAL (RTYPE (tree))))
2476 werror (E_PLUS_INVALID, "-");
2477 goto errorTreeReturn;
2480 /* if they are both literal then */
2481 /* rewrite the tree */
2482 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2484 tree->type = EX_VALUE;
2485 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2486 valFromType (RETYPE (tree)));
2487 tree->right = tree->left = NULL;
2488 TETYPE (tree) = getSpec (TTYPE (tree) =
2489 tree->opval.val->type);
2493 /* if the left & right are equal then zero */
2494 if (isAstEqual (tree->left, tree->right))
2496 tree->type = EX_VALUE;
2497 tree->left = tree->right = NULL;
2498 tree->opval.val = constVal ("0");
2499 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2503 /* if both of them are pointers or arrays then */
2504 /* the result is going to be an integer */
2505 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2506 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2507 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2509 /* if only the left is a pointer */
2510 /* then result is a pointer */
2511 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2512 TETYPE (tree) = getSpec (TTYPE (tree) =
2515 TETYPE (tree) = getSpec (TTYPE (tree) =
2516 computeType (LTYPE (tree),
2518 LRVAL (tree) = RRVAL (tree) = 1;
2521 /*------------------------------------------------------------------*/
2522 /*----------------------------*/
2524 /*----------------------------*/
2526 /* can be only integral type */
2527 if (!IS_INTEGRAL (LTYPE (tree)))
2529 werror (E_UNARY_OP, tree->opval.op);
2530 goto errorTreeReturn;
2533 /* if left is a literal then do it */
2534 if (IS_LITERAL (LTYPE (tree)))
2536 tree->type = EX_VALUE;
2537 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2539 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2543 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2546 /*------------------------------------------------------------------*/
2547 /*----------------------------*/
2549 /*----------------------------*/
2551 /* can be pointer */
2552 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2553 !IS_PTR (LTYPE (tree)) &&
2554 !IS_ARRAY (LTYPE (tree)))
2556 werror (E_UNARY_OP, tree->opval.op);
2557 goto errorTreeReturn;
2560 /* if left is a literal then do it */
2561 if (IS_LITERAL (LTYPE (tree)))
2563 tree->type = EX_VALUE;
2564 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2566 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2570 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2573 /*------------------------------------------------------------------*/
2574 /*----------------------------*/
2576 /*----------------------------*/
2579 TTYPE (tree) = LTYPE (tree);
2580 TETYPE (tree) = LETYPE (tree);
2584 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2589 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2591 werror (E_SHIFT_OP_INVALID);
2592 werror (E_CONTINUE, "left & right types are ");
2593 printTypeChain (LTYPE (tree), stderr);
2594 fprintf (stderr, ",");
2595 printTypeChain (RTYPE (tree), stderr);
2596 fprintf (stderr, "\n");
2597 goto errorTreeReturn;
2600 /* if they are both literal then */
2601 /* rewrite the tree */
2602 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2604 tree->type = EX_VALUE;
2605 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2606 valFromType (RETYPE (tree)),
2607 (tree->opval.op == LEFT_OP ? 1 : 0));
2608 tree->right = tree->left = NULL;
2609 TETYPE (tree) = getSpec (TTYPE (tree) =
2610 tree->opval.val->type);
2613 /* if only the right side is a literal & we are
2614 shifting more than size of the left operand then zero */
2615 if (IS_LITERAL (RTYPE (tree)) &&
2616 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2617 (getSize (LTYPE (tree)) * 8))
2619 werror (W_SHIFT_CHANGED,
2620 (tree->opval.op == LEFT_OP ? "left" : "right"));
2621 tree->type = EX_VALUE;
2622 tree->left = tree->right = NULL;
2623 tree->opval.val = constVal ("0");
2624 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2627 LRVAL (tree) = RRVAL (tree) = 1;
2628 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2630 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2634 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2638 /*------------------------------------------------------------------*/
2639 /*----------------------------*/
2641 /*----------------------------*/
2642 case CAST: /* change the type */
2643 /* cannot cast to an aggregate type */
2644 if (IS_AGGREGATE (LTYPE (tree)))
2646 werror (E_CAST_ILLEGAL);
2647 goto errorTreeReturn;
2650 /* make sure the type is complete and sane */
2651 checkTypeSanity(LETYPE(tree), "(cast)");
2653 /* if the right is a literal replace the tree */
2654 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2656 tree->type = EX_VALUE;
2658 valCastLiteral (LTYPE (tree),
2659 floatFromVal (valFromType (RETYPE (tree))));
2662 TTYPE (tree) = tree->opval.val->type;
2663 tree->values.literalFromCast = 1;
2667 TTYPE (tree) = LTYPE (tree);
2671 TETYPE (tree) = getSpec (TTYPE (tree));
2675 /*------------------------------------------------------------------*/
2676 /*----------------------------*/
2677 /* logical &&, || */
2678 /*----------------------------*/
2681 /* each must me arithmetic type or be a pointer */
2682 if (!IS_PTR (LTYPE (tree)) &&
2683 !IS_ARRAY (LTYPE (tree)) &&
2684 !IS_INTEGRAL (LTYPE (tree)))
2686 werror (E_COMPARE_OP);
2687 goto errorTreeReturn;
2690 if (!IS_PTR (RTYPE (tree)) &&
2691 !IS_ARRAY (RTYPE (tree)) &&
2692 !IS_INTEGRAL (RTYPE (tree)))
2694 werror (E_COMPARE_OP);
2695 goto errorTreeReturn;
2697 /* if they are both literal then */
2698 /* rewrite the tree */
2699 if (IS_LITERAL (RTYPE (tree)) &&
2700 IS_LITERAL (LTYPE (tree)))
2702 tree->type = EX_VALUE;
2703 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2704 valFromType (RETYPE (tree)),
2706 tree->right = tree->left = NULL;
2707 TETYPE (tree) = getSpec (TTYPE (tree) =
2708 tree->opval.val->type);
2711 LRVAL (tree) = RRVAL (tree) = 1;
2712 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2715 /*------------------------------------------------------------------*/
2716 /*----------------------------*/
2717 /* comparison operators */
2718 /*----------------------------*/
2726 ast *lt = optimizeCompare (tree);
2732 /* if they are pointers they must be castable */
2733 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2735 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2737 werror (E_COMPARE_OP);
2738 fprintf (stderr, "comparing type ");
2739 printTypeChain (LTYPE (tree), stderr);
2740 fprintf (stderr, "to type ");
2741 printTypeChain (RTYPE (tree), stderr);
2742 fprintf (stderr, "\n");
2743 goto errorTreeReturn;
2746 /* else they should be promotable to one another */
2749 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2750 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2752 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2754 werror (E_COMPARE_OP);
2755 fprintf (stderr, "comparing type ");
2756 printTypeChain (LTYPE (tree), stderr);
2757 fprintf (stderr, "to type ");
2758 printTypeChain (RTYPE (tree), stderr);
2759 fprintf (stderr, "\n");
2760 goto errorTreeReturn;
2764 /* if they are both literal then */
2765 /* rewrite the tree */
2766 if (IS_LITERAL (RTYPE (tree)) &&
2767 IS_LITERAL (LTYPE (tree)))
2769 tree->type = EX_VALUE;
2770 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2771 valFromType (RETYPE (tree)),
2773 tree->right = tree->left = NULL;
2774 TETYPE (tree) = getSpec (TTYPE (tree) =
2775 tree->opval.val->type);
2778 LRVAL (tree) = RRVAL (tree) = 1;
2779 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2782 /*------------------------------------------------------------------*/
2783 /*----------------------------*/
2785 /*----------------------------*/
2786 case SIZEOF: /* evaluate wihout code generation */
2787 /* change the type to a integer */
2788 tree->type = EX_VALUE;
2789 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2790 tree->opval.val = constVal (buffer);
2791 tree->right = tree->left = NULL;
2792 TETYPE (tree) = getSpec (TTYPE (tree) =
2793 tree->opval.val->type);
2796 /*------------------------------------------------------------------*/
2797 /*----------------------------*/
2798 /* conditional operator '?' */
2799 /*----------------------------*/
2801 /* the type is value of the colon operator (on the right) */
2802 assert(IS_COLON_OP(tree->right));
2803 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2804 TETYPE (tree) = getSpec (TTYPE (tree));
2808 /* if they don't match we have a problem */
2809 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2811 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2812 goto errorTreeReturn;
2815 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2816 TETYPE (tree) = getSpec (TTYPE (tree));
2820 /*------------------------------------------------------------------*/
2821 /*----------------------------*/
2822 /* assignment operators */
2823 /*----------------------------*/
2826 /* for these it must be both must be integral */
2827 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2828 !IS_ARITHMETIC (RTYPE (tree)))
2830 werror (E_OPS_INTEGRAL);
2831 goto errorTreeReturn;
2834 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2836 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2837 werror (E_CODE_WRITE, " ");
2841 werror (E_LVALUE_REQUIRED, "*= or /=");
2842 goto errorTreeReturn;
2855 /* for these it must be both must be integral */
2856 if (!IS_INTEGRAL (LTYPE (tree)) ||
2857 !IS_INTEGRAL (RTYPE (tree)))
2859 werror (E_OPS_INTEGRAL);
2860 goto errorTreeReturn;
2863 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2865 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2866 werror (E_CODE_WRITE, " ");
2870 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2871 goto errorTreeReturn;
2879 /*------------------------------------------------------------------*/
2880 /*----------------------------*/
2882 /*----------------------------*/
2884 if (!(IS_PTR (LTYPE (tree)) ||
2885 IS_ARITHMETIC (LTYPE (tree))))
2887 werror (E_PLUS_INVALID, "-=");
2888 goto errorTreeReturn;
2891 if (!(IS_PTR (RTYPE (tree)) ||
2892 IS_ARITHMETIC (RTYPE (tree))))
2894 werror (E_PLUS_INVALID, "-=");
2895 goto errorTreeReturn;
2898 TETYPE (tree) = getSpec (TTYPE (tree) =
2899 computeType (LTYPE (tree),
2902 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2903 werror (E_CODE_WRITE, " ");
2907 werror (E_LVALUE_REQUIRED, "-=");
2908 goto errorTreeReturn;
2916 /*------------------------------------------------------------------*/
2917 /*----------------------------*/
2919 /*----------------------------*/
2921 /* this is not a unary operation */
2922 /* if both pointers then problem */
2923 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2925 werror (E_PTR_PLUS_PTR);
2926 goto errorTreeReturn;
2929 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2931 werror (E_PLUS_INVALID, "+=");
2932 goto errorTreeReturn;
2935 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2937 werror (E_PLUS_INVALID, "+=");
2938 goto errorTreeReturn;
2941 TETYPE (tree) = getSpec (TTYPE (tree) =
2942 computeType (LTYPE (tree),
2945 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2946 werror (E_CODE_WRITE, " ");
2950 werror (E_LVALUE_REQUIRED, "+=");
2951 goto errorTreeReturn;
2954 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2955 tree->opval.op = '=';
2961 /*------------------------------------------------------------------*/
2962 /*----------------------------*/
2963 /* straight assignemnt */
2964 /*----------------------------*/
2966 /* cannot be an aggregate */
2967 if (IS_AGGREGATE (LTYPE (tree)))
2969 werror (E_AGGR_ASSIGN);
2970 goto errorTreeReturn;
2973 /* they should either match or be castable */
2974 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2976 werror (E_TYPE_MISMATCH, "assignment", " ");
2977 fprintf (stderr, "type --> '");
2978 printTypeChain (RTYPE (tree), stderr);
2979 fprintf (stderr, "' ");
2980 fprintf (stderr, "assigned to type --> '");
2981 printTypeChain (LTYPE (tree), stderr);
2982 fprintf (stderr, "'\n");
2983 goto errorTreeReturn;
2986 /* if the left side of the tree is of type void
2987 then report error */
2988 if (IS_VOID (LTYPE (tree)))
2990 werror (E_CAST_ZERO);
2991 fprintf (stderr, "type --> '");
2992 printTypeChain (RTYPE (tree), stderr);
2993 fprintf (stderr, "' ");
2994 fprintf (stderr, "assigned to type --> '");
2995 printTypeChain (LTYPE (tree), stderr);
2996 fprintf (stderr, "'\n");
2999 /* extra checks for pointer types */
3000 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
3001 !IS_GENPTR (LTYPE (tree)))
3003 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
3004 werror (W_PTR_ASSIGN);
3007 TETYPE (tree) = getSpec (TTYPE (tree) =
3011 if (!tree->initMode ) {
3012 if (IS_CONSTANT (LETYPE (tree))) {
3013 werror (E_CODE_WRITE, " ");
3018 werror (E_LVALUE_REQUIRED, "=");
3019 goto errorTreeReturn;
3026 /*------------------------------------------------------------------*/
3027 /*----------------------------*/
3028 /* comma operator */
3029 /*----------------------------*/
3031 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3034 /*------------------------------------------------------------------*/
3035 /*----------------------------*/
3037 /*----------------------------*/
3041 if (processParms (tree->left,
3043 tree->right, &parmNumber, TRUE))
3044 goto errorTreeReturn;
3046 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3048 tree->left->args = reverseVal (tree->left->args);
3049 reverseParms (tree->right);
3052 tree->args = tree->left->args;
3053 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3056 /*------------------------------------------------------------------*/
3057 /*----------------------------*/
3058 /* return statement */
3059 /*----------------------------*/
3064 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3066 werror (E_RETURN_MISMATCH);
3067 goto errorTreeReturn;
3070 if (IS_VOID (currFunc->type->next)
3072 !IS_VOID (RTYPE (tree)))
3074 werror (E_FUNC_VOID);
3075 goto errorTreeReturn;
3078 /* if there is going to be a casing required then add it */
3079 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3081 #if 0 && defined DEMAND_INTEGER_PROMOTION
3082 if (IS_INTEGRAL (currFunc->type->next))
3084 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3090 decorateType (newNode (CAST,
3091 newAst_LINK (copyLinkChain (currFunc->type->next)),
3101 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3103 werror (E_VOID_FUNC, currFunc->name);
3104 goto errorTreeReturn;
3107 TTYPE (tree) = TETYPE (tree) = NULL;
3110 /*------------------------------------------------------------------*/
3111 /*----------------------------*/
3112 /* switch statement */
3113 /*----------------------------*/
3115 /* the switch value must be an integer */
3116 if (!IS_INTEGRAL (LTYPE (tree)))
3118 werror (E_SWITCH_NON_INTEGER);
3119 goto errorTreeReturn;
3122 TTYPE (tree) = TETYPE (tree) = NULL;
3125 /*------------------------------------------------------------------*/
3126 /*----------------------------*/
3128 /*----------------------------*/
3130 tree->left = backPatchLabels (tree->left,
3133 TTYPE (tree) = TETYPE (tree) = NULL;
3136 /*------------------------------------------------------------------*/
3137 /*----------------------------*/
3139 /*----------------------------*/
3142 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3143 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3144 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3146 /* if the for loop is reversible then
3147 reverse it otherwise do what we normally
3153 if (isLoopReversible (tree, &sym, &init, &end))
3154 return reverseLoop (tree, sym, init, end);
3156 return decorateType (createFor (AST_FOR (tree, trueLabel),
3157 AST_FOR (tree, continueLabel),
3158 AST_FOR (tree, falseLabel),
3159 AST_FOR (tree, condLabel),
3160 AST_FOR (tree, initExpr),
3161 AST_FOR (tree, condExpr),
3162 AST_FOR (tree, loopExpr),
3166 TTYPE (tree) = TETYPE (tree) = NULL;
3170 /* some error found this tree will be killed */
3172 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3173 tree->opval.op = NULLOP;
3179 /*-----------------------------------------------------------------*/
3180 /* sizeofOp - processes size of operation */
3181 /*-----------------------------------------------------------------*/
3183 sizeofOp (sym_link * type)
3187 /* make sure the type is complete and sane */
3188 checkTypeSanity(type, "(sizeof)");
3190 /* get the size and convert it to character */
3191 sprintf (buff, "%d", getSize (type));
3193 /* now convert into value */
3194 return constVal (buff);
3198 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3199 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3200 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3201 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3202 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3203 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3204 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3206 /*-----------------------------------------------------------------*/
3207 /* backPatchLabels - change and or not operators to flow control */
3208 /*-----------------------------------------------------------------*/
3210 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3216 if (!(IS_ANDORNOT (tree)))
3219 /* if this an and */
3222 static int localLbl = 0;
3225 sprintf (buffer, "_and_%d", localLbl++);
3226 localLabel = newSymbol (buffer, NestLevel);
3228 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3230 /* if left is already a IFX then just change the if true label in that */
3231 if (!IS_IFX (tree->left))
3232 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3234 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3235 /* right is a IFX then just join */
3236 if (IS_IFX (tree->right))
3237 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3239 tree->right = createLabel (localLabel, tree->right);
3240 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3242 return newNode (NULLOP, tree->left, tree->right);
3245 /* if this is an or operation */
3248 static int localLbl = 0;
3251 sprintf (buffer, "_or_%d", localLbl++);
3252 localLabel = newSymbol (buffer, NestLevel);
3254 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3256 /* if left is already a IFX then just change the if true label in that */
3257 if (!IS_IFX (tree->left))
3258 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3260 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3261 /* right is a IFX then just join */
3262 if (IS_IFX (tree->right))
3263 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3265 tree->right = createLabel (localLabel, tree->right);
3266 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3268 return newNode (NULLOP, tree->left, tree->right);
3274 int wasnot = IS_NOT (tree->left);
3275 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3277 /* if the left is already a IFX */
3278 if (!IS_IFX (tree->left))
3279 tree->left = newNode (IFX, tree->left, NULL);
3283 tree->left->trueLabel = trueLabel;
3284 tree->left->falseLabel = falseLabel;
3288 tree->left->trueLabel = falseLabel;
3289 tree->left->falseLabel = trueLabel;
3296 tree->trueLabel = trueLabel;
3297 tree->falseLabel = falseLabel;
3304 /*-----------------------------------------------------------------*/
3305 /* createBlock - create expression tree for block */
3306 /*-----------------------------------------------------------------*/
3308 createBlock (symbol * decl, ast * body)
3312 /* if the block has nothing */
3316 ex = newNode (BLOCK, NULL, body);
3317 ex->values.sym = decl;
3319 ex->right = ex->right;
3325 /*-----------------------------------------------------------------*/
3326 /* createLabel - creates the expression tree for labels */
3327 /*-----------------------------------------------------------------*/
3329 createLabel (symbol * label, ast * stmnt)
3332 char name[SDCC_NAME_MAX + 1];
3335 /* must create fresh symbol if the symbol name */
3336 /* exists in the symbol table, since there can */
3337 /* be a variable with the same name as the labl */
3338 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3339 (csym->level == label->level))
3340 label = newSymbol (label->name, label->level);
3342 /* change the name before putting it in add _ */
3343 sprintf (name, "%s", label->name);
3345 /* put the label in the LabelSymbol table */
3346 /* but first check if a label of the same */
3348 if ((csym = findSym (LabelTab, NULL, name)))
3349 werror (E_DUPLICATE_LABEL, label->name);
3351 addSym (LabelTab, label, name, label->level, 0, 0);
3354 label->key = labelKey++;
3355 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3361 /*-----------------------------------------------------------------*/
3362 /* createCase - generates the parsetree for a case statement */
3363 /*-----------------------------------------------------------------*/
3365 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3367 char caseLbl[SDCC_NAME_MAX + 1];
3371 /* if the switch statement does not exist */
3372 /* then case is out of context */
3375 werror (E_CASE_CONTEXT);
3379 caseVal = decorateType (resolveSymbols (caseVal));
3380 /* if not a constant then error */
3381 if (!IS_LITERAL (caseVal->ftype))
3383 werror (E_CASE_CONSTANT);
3387 /* if not a integer than error */
3388 if (!IS_INTEGRAL (caseVal->ftype))
3390 werror (E_CASE_NON_INTEGER);
3394 /* find the end of the switch values chain */
3395 if (!(val = swStat->values.switchVals.swVals))
3396 swStat->values.switchVals.swVals = caseVal->opval.val;
3399 /* also order the cases according to value */
3401 int cVal = (int) floatFromVal (caseVal->opval.val);
3402 while (val && (int) floatFromVal (val) < cVal)
3408 /* if we reached the end then */
3411 pval->next = caseVal->opval.val;
3415 /* we found a value greater than */
3416 /* the current value we must add this */
3417 /* before the value */
3418 caseVal->opval.val->next = val;
3420 /* if this was the first in chain */
3421 if (swStat->values.switchVals.swVals == val)
3422 swStat->values.switchVals.swVals =
3425 pval->next = caseVal->opval.val;
3430 /* create the case label */
3431 sprintf (caseLbl, "_case_%d_%d",
3432 swStat->values.switchVals.swNum,
3433 (int) floatFromVal (caseVal->opval.val));
3435 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3440 /*-----------------------------------------------------------------*/
3441 /* createDefault - creates the parse tree for the default statement */
3442 /*-----------------------------------------------------------------*/
3444 createDefault (ast * swStat, ast * stmnt)
3446 char defLbl[SDCC_NAME_MAX + 1];
3448 /* if the switch statement does not exist */
3449 /* then case is out of context */
3452 werror (E_CASE_CONTEXT);
3456 /* turn on the default flag */
3457 swStat->values.switchVals.swDefault = 1;
3459 /* create the label */
3460 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3461 return createLabel (newSymbol (defLbl, 0), stmnt);
3464 /*-----------------------------------------------------------------*/
3465 /* createIf - creates the parsetree for the if statement */
3466 /*-----------------------------------------------------------------*/
3468 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3470 static int Lblnum = 0;
3472 symbol *ifTrue, *ifFalse, *ifEnd;
3474 /* if neither exists */
3475 if (!elseBody && !ifBody)
3478 /* create the labels */
3479 sprintf (buffer, "_iffalse_%d", Lblnum);
3480 ifFalse = newSymbol (buffer, NestLevel);
3481 /* if no else body then end == false */
3486 sprintf (buffer, "_ifend_%d", Lblnum);
3487 ifEnd = newSymbol (buffer, NestLevel);
3490 sprintf (buffer, "_iftrue_%d", Lblnum);
3491 ifTrue = newSymbol (buffer, NestLevel);
3495 /* attach the ifTrue label to the top of it body */
3496 ifBody = createLabel (ifTrue, ifBody);
3497 /* attach a goto end to the ifBody if else is present */
3500 ifBody = newNode (NULLOP, ifBody,
3502 newAst_VALUE (symbolVal (ifEnd)),
3504 /* put the elseLabel on the else body */
3505 elseBody = createLabel (ifFalse, elseBody);
3506 /* out the end at the end of the body */
3507 elseBody = newNode (NULLOP,
3509 createLabel (ifEnd, NULL));
3513 ifBody = newNode (NULLOP, ifBody,
3514 createLabel (ifFalse, NULL));
3516 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3517 if (IS_IFX (condAst))
3520 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3522 return newNode (NULLOP, ifTree,
3523 newNode (NULLOP, ifBody, elseBody));
3527 /*-----------------------------------------------------------------*/
3528 /* createDo - creates parse tree for do */
3531 /* _docontinue_n: */
3532 /* condition_expression +-> trueLabel -> _dobody_n */
3534 /* +-> falseLabel-> _dobreak_n */
3536 /*-----------------------------------------------------------------*/
3538 createDo (symbol * trueLabel, symbol * continueLabel,
3539 symbol * falseLabel, ast * condAst, ast * doBody)
3544 /* if the body does not exist then it is simple */
3547 condAst = backPatchLabels (condAst, continueLabel, NULL);
3548 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3549 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3550 doTree->trueLabel = continueLabel;
3551 doTree->falseLabel = NULL;
3555 /* otherwise we have a body */
3556 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3558 /* attach the body label to the top */
3559 doBody = createLabel (trueLabel, doBody);
3560 /* attach the continue label to end of body */
3561 doBody = newNode (NULLOP, doBody,
3562 createLabel (continueLabel, NULL));
3564 /* now put the break label at the end */
3565 if (IS_IFX (condAst))
3568 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3570 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3572 /* putting it together */
3573 return newNode (NULLOP, doBody, doTree);
3576 /*-----------------------------------------------------------------*/
3577 /* createFor - creates parse tree for 'for' statement */
3580 /* condExpr +-> trueLabel -> _forbody_n */
3582 /* +-> falseLabel-> _forbreak_n */
3585 /* _forcontinue_n: */
3587 /* goto _forcond_n ; */
3589 /*-----------------------------------------------------------------*/
3591 createFor (symbol * trueLabel, symbol * continueLabel,
3592 symbol * falseLabel, symbol * condLabel,
3593 ast * initExpr, ast * condExpr, ast * loopExpr,
3598 /* if loopexpression not present then we can generate it */
3599 /* the same way as a while */
3601 return newNode (NULLOP, initExpr,
3602 createWhile (trueLabel, continueLabel,
3603 falseLabel, condExpr, forBody));
3604 /* vanilla for statement */
3605 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3607 if (condExpr && !IS_IFX (condExpr))
3608 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3611 /* attach condition label to condition */
3612 condExpr = createLabel (condLabel, condExpr);
3614 /* attach body label to body */
3615 forBody = createLabel (trueLabel, forBody);
3617 /* attach continue to forLoop expression & attach */
3618 /* goto the forcond @ and of loopExpression */
3619 loopExpr = createLabel (continueLabel,
3623 newAst_VALUE (symbolVal (condLabel)),
3625 /* now start putting them together */
3626 forTree = newNode (NULLOP, initExpr, condExpr);
3627 forTree = newNode (NULLOP, forTree, forBody);
3628 forTree = newNode (NULLOP, forTree, loopExpr);
3629 /* finally add the break label */
3630 forTree = newNode (NULLOP, forTree,
3631 createLabel (falseLabel, NULL));
3635 /*-----------------------------------------------------------------*/
3636 /* createWhile - creates parse tree for while statement */
3637 /* the while statement will be created as follows */
3639 /* _while_continue_n: */
3640 /* condition_expression +-> trueLabel -> _while_boby_n */
3642 /* +-> falseLabel -> _while_break_n */
3643 /* _while_body_n: */
3645 /* goto _while_continue_n */
3646 /* _while_break_n: */
3647 /*-----------------------------------------------------------------*/
3649 createWhile (symbol * trueLabel, symbol * continueLabel,
3650 symbol * falseLabel, ast * condExpr, ast * whileBody)
3654 /* put the continue label */
3655 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3656 condExpr = createLabel (continueLabel, condExpr);
3657 condExpr->lineno = 0;
3659 /* put the body label in front of the body */
3660 whileBody = createLabel (trueLabel, whileBody);
3661 whileBody->lineno = 0;
3662 /* put a jump to continue at the end of the body */
3663 /* and put break label at the end of the body */
3664 whileBody = newNode (NULLOP,
3667 newAst_VALUE (symbolVal (continueLabel)),
3668 createLabel (falseLabel, NULL)));
3670 /* put it all together */
3671 if (IS_IFX (condExpr))
3672 whileTree = condExpr;
3675 whileTree = newNode (IFX, condExpr, NULL);
3676 /* put the true & false labels in place */
3677 whileTree->trueLabel = trueLabel;
3678 whileTree->falseLabel = falseLabel;
3681 return newNode (NULLOP, whileTree, whileBody);
3684 /*-----------------------------------------------------------------*/
3685 /* optimizeGetHbit - get highest order bit of the expression */
3686 /*-----------------------------------------------------------------*/
3688 optimizeGetHbit (ast * tree)
3691 /* if this is not a bit and */
3692 if (!IS_BITAND (tree))
3695 /* will look for tree of the form
3696 ( expr >> ((sizeof expr) -1) ) & 1 */
3697 if (!IS_AST_LIT_VALUE (tree->right))
3700 if (AST_LIT_VALUE (tree->right) != 1)
3703 if (!IS_RIGHT_OP (tree->left))
3706 if (!IS_AST_LIT_VALUE (tree->left->right))
3709 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3710 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3713 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3717 /*-----------------------------------------------------------------*/
3718 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3719 /*-----------------------------------------------------------------*/
3721 optimizeRRCRLC (ast * root)
3723 /* will look for trees of the form
3724 (?expr << 1) | (?expr >> 7) or
3725 (?expr >> 7) | (?expr << 1) will make that
3726 into a RLC : operation ..
3728 (?expr >> 1) | (?expr << 7) or
3729 (?expr << 7) | (?expr >> 1) will make that
3730 into a RRC operation
3731 note : by 7 I mean (number of bits required to hold the
3733 /* if the root operations is not a | operation the not */
3734 if (!IS_BITOR (root))
3737 /* I have to think of a better way to match patterns this sucks */
3738 /* that aside let start looking for the first case : I use a the
3739 negative check a lot to improve the efficiency */
3740 /* (?expr << 1) | (?expr >> 7) */
3741 if (IS_LEFT_OP (root->left) &&
3742 IS_RIGHT_OP (root->right))
3745 if (!SPEC_USIGN (TETYPE (root->left->left)))
3748 if (!IS_AST_LIT_VALUE (root->left->right) ||
3749 !IS_AST_LIT_VALUE (root->right->right))
3752 /* make sure it is the same expression */
3753 if (!isAstEqual (root->left->left,
3757 if (AST_LIT_VALUE (root->left->right) != 1)
3760 if (AST_LIT_VALUE (root->right->right) !=
3761 (getSize (TTYPE (root->left->left)) * 8 - 1))
3764 /* whew got the first case : create the AST */
3765 return newNode (RLC, root->left->left, NULL);
3769 /* check for second case */
3770 /* (?expr >> 7) | (?expr << 1) */
3771 if (IS_LEFT_OP (root->right) &&
3772 IS_RIGHT_OP (root->left))
3775 if (!SPEC_USIGN (TETYPE (root->left->left)))
3778 if (!IS_AST_LIT_VALUE (root->left->right) ||
3779 !IS_AST_LIT_VALUE (root->right->right))
3782 /* make sure it is the same symbol */
3783 if (!isAstEqual (root->left->left,
3787 if (AST_LIT_VALUE (root->right->right) != 1)
3790 if (AST_LIT_VALUE (root->left->right) !=
3791 (getSize (TTYPE (root->left->left)) * 8 - 1))
3794 /* whew got the first case : create the AST */
3795 return newNode (RLC, root->left->left, NULL);
3800 /* third case for RRC */
3801 /* (?symbol >> 1) | (?symbol << 7) */
3802 if (IS_LEFT_OP (root->right) &&
3803 IS_RIGHT_OP (root->left))
3806 if (!SPEC_USIGN (TETYPE (root->left->left)))
3809 if (!IS_AST_LIT_VALUE (root->left->right) ||
3810 !IS_AST_LIT_VALUE (root->right->right))
3813 /* make sure it is the same symbol */
3814 if (!isAstEqual (root->left->left,
3818 if (AST_LIT_VALUE (root->left->right) != 1)
3821 if (AST_LIT_VALUE (root->right->right) !=
3822 (getSize (TTYPE (root->left->left)) * 8 - 1))
3825 /* whew got the first case : create the AST */
3826 return newNode (RRC, root->left->left, NULL);
3830 /* fourth and last case for now */
3831 /* (?symbol << 7) | (?symbol >> 1) */
3832 if (IS_RIGHT_OP (root->right) &&
3833 IS_LEFT_OP (root->left))
3836 if (!SPEC_USIGN (TETYPE (root->left->left)))
3839 if (!IS_AST_LIT_VALUE (root->left->right) ||
3840 !IS_AST_LIT_VALUE (root->right->right))
3843 /* make sure it is the same symbol */
3844 if (!isAstEqual (root->left->left,
3848 if (AST_LIT_VALUE (root->right->right) != 1)
3851 if (AST_LIT_VALUE (root->left->right) !=
3852 (getSize (TTYPE (root->left->left)) * 8 - 1))
3855 /* whew got the first case : create the AST */
3856 return newNode (RRC, root->left->left, NULL);
3860 /* not found return root */
3864 /*-----------------------------------------------------------------*/
3865 /* optimizeCompare - otimizes compares for bit variables */
3866 /*-----------------------------------------------------------------*/
3868 optimizeCompare (ast * root)
3870 ast *optExpr = NULL;
3873 unsigned int litValue;
3875 /* if nothing then return nothing */
3879 /* if not a compare op then do leaves */
3880 if (!IS_COMPARE_OP (root))
3882 root->left = optimizeCompare (root->left);
3883 root->right = optimizeCompare (root->right);
3887 /* if left & right are the same then depending
3888 of the operation do */
3889 if (isAstEqual (root->left, root->right))
3891 switch (root->opval.op)
3896 optExpr = newAst_VALUE (constVal ("0"));
3901 optExpr = newAst_VALUE (constVal ("1"));
3905 return decorateType (optExpr);
3908 vleft = (root->left->type == EX_VALUE ?
3909 root->left->opval.val : NULL);
3911 vright = (root->right->type == EX_VALUE ?
3912 root->right->opval.val : NULL);
3914 /* if left is a BITVAR in BITSPACE */
3915 /* and right is a LITERAL then opt- */
3916 /* imize else do nothing */
3917 if (vleft && vright &&
3918 IS_BITVAR (vleft->etype) &&
3919 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3920 IS_LITERAL (vright->etype))
3923 /* if right side > 1 then comparison may never succeed */
3924 if ((litValue = (int) floatFromVal (vright)) > 1)
3926 werror (W_BAD_COMPARE);
3932 switch (root->opval.op)
3934 case '>': /* bit value greater than 1 cannot be */
3935 werror (W_BAD_COMPARE);
3939 case '<': /* bit value < 1 means 0 */
3941 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3944 case LE_OP: /* bit value <= 1 means no check */
3945 optExpr = newAst_VALUE (vright);
3948 case GE_OP: /* bit value >= 1 means only check for = */
3950 optExpr = newAst_VALUE (vleft);
3955 { /* literal is zero */
3956 switch (root->opval.op)
3958 case '<': /* bit value < 0 cannot be */
3959 werror (W_BAD_COMPARE);
3963 case '>': /* bit value > 0 means 1 */
3965 optExpr = newAst_VALUE (vleft);
3968 case LE_OP: /* bit value <= 0 means no check */
3969 case GE_OP: /* bit value >= 0 means no check */
3970 werror (W_BAD_COMPARE);
3974 case EQ_OP: /* bit == 0 means ! of bit */
3975 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3979 return decorateType (resolveSymbols (optExpr));
3980 } /* end-of-if of BITVAR */
3985 /*-----------------------------------------------------------------*/
3986 /* addSymToBlock : adds the symbol to the first block we find */
3987 /*-----------------------------------------------------------------*/
3989 addSymToBlock (symbol * sym, ast * tree)
3991 /* reached end of tree or a leaf */
3992 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3996 if (IS_AST_OP (tree) &&
3997 tree->opval.op == BLOCK)
4000 symbol *lsym = copySymbol (sym);
4002 lsym->next = AST_VALUES (tree, sym);
4003 AST_VALUES (tree, sym) = lsym;
4007 addSymToBlock (sym, tree->left);
4008 addSymToBlock (sym, tree->right);
4011 /*-----------------------------------------------------------------*/
4012 /* processRegParms - do processing for register parameters */
4013 /*-----------------------------------------------------------------*/
4015 processRegParms (value * args, ast * body)
4019 if (IS_REGPARM (args->etype))
4020 addSymToBlock (args->sym, body);
4025 /*-----------------------------------------------------------------*/
4026 /* resetParmKey - resets the operandkeys for the symbols */
4027 /*-----------------------------------------------------------------*/
4028 DEFSETFUNC (resetParmKey)
4039 /*-----------------------------------------------------------------*/
4040 /* createFunction - This is the key node that calls the iCode for */
4041 /* generating the code for a function. Note code */
4042 /* is generated function by function, later when */
4043 /* add inter-procedural analysis this will change */
4044 /*-----------------------------------------------------------------*/
4046 createFunction (symbol * name, ast * body)
4052 iCode *piCode = NULL;
4054 /* if check function return 0 then some problem */
4055 if (checkFunction (name) == 0)
4058 /* create a dummy block if none exists */
4060 body = newNode (BLOCK, NULL, NULL);
4064 /* check if the function name already in the symbol table */
4065 if ((csym = findSym (SymbolTab, NULL, name->name)))
4068 /* special case for compiler defined functions
4069 we need to add the name to the publics list : this
4070 actually means we are now compiling the compiler
4074 addSet (&publics, name);
4080 allocVariables (name);
4082 name->lastLine = yylineno;
4084 processFuncArgs (currFunc, 0);
4086 /* set the stack pointer */
4087 /* PENDING: check this for the mcs51 */
4088 stackPtr = -port->stack.direction * port->stack.call_overhead;
4089 if (IS_ISR (name->etype))
4090 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4091 if (IS_RENT (name->etype) || options.stackAuto)
4092 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4094 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4096 fetype = getSpec (name->type); /* get the specifier for the function */
4097 /* if this is a reentrant function then */
4098 if (IS_RENT (fetype))
4101 allocParms (name->args); /* allocate the parameters */
4103 /* do processing for parameters that are passed in registers */
4104 processRegParms (name->args, body);
4106 /* set the stack pointer */
4110 /* allocate & autoinit the block variables */
4111 processBlockVars (body, &stack, ALLOCATE);
4113 /* save the stack information */
4114 if (options.useXstack)
4115 name->xstack = SPEC_STAK (fetype) = stack;
4117 name->stack = SPEC_STAK (fetype) = stack;
4119 /* name needs to be mangled */
4120 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4122 body = resolveSymbols (body); /* resolve the symbols */
4123 body = decorateType (body); /* propagateType & do semantic checks */
4125 ex = newAst_VALUE (symbolVal (name)); /* create name */
4126 ex = newNode (FUNCTION, ex, body);
4127 ex->values.args = name->args;
4131 werror (E_FUNC_NO_CODE, name->name);
4135 /* create the node & generate intermediate code */
4137 codeOutFile = code->oFile;
4138 piCode = iCodeFromAst (ex);
4142 werror (E_FUNC_NO_CODE, name->name);
4146 eBBlockFromiCode (piCode);
4148 /* if there are any statics then do them */
4151 GcurMemmap = statsg;
4152 codeOutFile = statsg->oFile;
4153 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4159 /* dealloc the block variables */
4160 processBlockVars (body, &stack, DEALLOCATE);
4161 /* deallocate paramaters */
4162 deallocParms (name->args);
4164 if (IS_RENT (fetype))
4167 /* we are done freeup memory & cleanup */
4172 addSet (&operKeyReset, name);
4173 applyToSet (operKeyReset, resetParmKey);
4176 cdbStructBlock (1, cdbFile);
4178 cleanUpLevel (LabelTab, 0);
4179 cleanUpBlock (StructTab, 1);
4180 cleanUpBlock (TypedefTab, 1);
4182 xstack->syms = NULL;
4183 istack->syms = NULL;
4188 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4189 /*-----------------------------------------------------------------*/
4190 /* ast_print : prints the ast (for debugging purposes) */
4191 /*-----------------------------------------------------------------*/
4193 void ast_print (ast * tree, FILE *outfile, int indent)
4198 /* can print only decorated trees */
4199 if (!tree->decorated) return;
4201 /* if any child is an error | this one is an error do nothing */
4202 if (tree->isError ||
4203 (tree->left && tree->left->isError) ||
4204 (tree->right && tree->right->isError)) {
4205 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4209 /* print the line */
4210 /* if not block & function */
4211 if (tree->type == EX_OP &&
4212 (tree->opval.op != FUNCTION &&
4213 tree->opval.op != BLOCK &&
4214 tree->opval.op != NULLOP)) {
4217 if (tree->opval.op == FUNCTION) {
4218 fprintf(outfile,"FUNCTION (%p) type (",tree);
4219 printTypeChain (tree->ftype,outfile);
4220 fprintf(outfile,")\n");
4221 ast_print(tree->left,outfile,indent+4);
4222 ast_print(tree->right,outfile,indent+4);
4225 if (tree->opval.op == BLOCK) {
4226 symbol *decls = tree->values.sym;
4227 fprintf(outfile,"{\n");
4229 INDENT(indent+4,outfile);
4230 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4231 printTypeChain(decls->type,outfile);
4232 fprintf(outfile,")\n");
4234 decls = decls->next;
4236 ast_print(tree->right,outfile,indent+4);
4237 fprintf(outfile,"}\n");
4240 if (tree->opval.op == NULLOP) {
4241 fprintf(outfile,"\n");
4242 ast_print(tree->left,outfile,indent);
4243 fprintf(outfile,"\n");
4244 ast_print(tree->right,outfile,indent);
4247 INDENT(indent,outfile);
4249 /*------------------------------------------------------------------*/
4250 /*----------------------------*/
4251 /* leaf has been reached */
4252 /*----------------------------*/
4253 /* if this is of type value */
4254 /* just get the type */
4255 if (tree->type == EX_VALUE) {
4257 if (IS_LITERAL (tree->opval.val->etype)) {
4258 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4259 (int) floatFromVal(tree->opval.val),
4260 (int) floatFromVal(tree->opval.val),
4261 floatFromVal(tree->opval.val));
4262 } else if (tree->opval.val->sym) {
4263 /* if the undefined flag is set then give error message */
4264 if (tree->opval.val->sym->undefined) {
4265 fprintf(outfile,"UNDEFINED SYMBOL ");
4267 fprintf(outfile,"SYMBOL ");
4269 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4272 fprintf(outfile," type (");
4273 printTypeChain(tree->ftype,outfile);
4274 fprintf(outfile,")\n");
4276 fprintf(outfile,"\n");
4281 /* if type link for the case of cast */
4282 if (tree->type == EX_LINK) {
4283 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4284 printTypeChain(tree->opval.lnk,outfile);
4285 fprintf(outfile,")\n");
4290 /* depending on type of operator do */
4292 switch (tree->opval.op) {
4293 /*------------------------------------------------------------------*/
4294 /*----------------------------*/
4296 /*----------------------------*/
4298 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4299 printTypeChain(tree->ftype,outfile);
4300 fprintf(outfile,")\n");
4301 ast_print(tree->left,outfile,indent+4);
4302 ast_print(tree->right,outfile,indent+4);
4305 /*------------------------------------------------------------------*/
4306 /*----------------------------*/
4308 /*----------------------------*/
4310 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4311 printTypeChain(tree->ftype,outfile);
4312 fprintf(outfile,")\n");
4313 ast_print(tree->left,outfile,indent+4);
4314 ast_print(tree->right,outfile,indent+4);
4317 /*------------------------------------------------------------------*/
4318 /*----------------------------*/
4319 /* struct/union pointer */
4320 /*----------------------------*/
4322 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4323 printTypeChain(tree->ftype,outfile);
4324 fprintf(outfile,")\n");
4325 ast_print(tree->left,outfile,indent+4);
4326 ast_print(tree->right,outfile,indent+4);
4329 /*------------------------------------------------------------------*/
4330 /*----------------------------*/
4331 /* ++/-- operation */
4332 /*----------------------------*/
4333 case INC_OP: /* incerement operator unary so left only */
4334 fprintf(outfile,"INC_OP (%p) type (",tree);
4335 printTypeChain(tree->ftype,outfile);
4336 fprintf(outfile,")\n");
4337 ast_print(tree->left,outfile,indent+4);
4341 fprintf(outfile,"DEC_OP (%p) type (",tree);
4342 printTypeChain(tree->ftype,outfile);
4343 fprintf(outfile,")\n");
4344 ast_print(tree->left,outfile,indent+4);
4347 /*------------------------------------------------------------------*/
4348 /*----------------------------*/
4350 /*----------------------------*/
4353 fprintf(outfile,"& (%p) type (",tree);
4354 printTypeChain(tree->ftype,outfile);
4355 fprintf(outfile,")\n");
4356 ast_print(tree->left,outfile,indent+4);
4357 ast_print(tree->right,outfile,indent+4);
4359 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4360 printTypeChain(tree->ftype,outfile);
4361 fprintf(outfile,")\n");
4362 ast_print(tree->left,outfile,indent+4);
4363 ast_print(tree->right,outfile,indent+4);
4366 /*----------------------------*/
4368 /*----------------------------*/
4370 fprintf(outfile,"OR (%p) type (",tree);
4371 printTypeChain(tree->ftype,outfile);
4372 fprintf(outfile,")\n");
4373 ast_print(tree->left,outfile,indent+4);
4374 ast_print(tree->right,outfile,indent+4);
4376 /*------------------------------------------------------------------*/
4377 /*----------------------------*/
4379 /*----------------------------*/
4381 fprintf(outfile,"XOR (%p) type (",tree);
4382 printTypeChain(tree->ftype,outfile);
4383 fprintf(outfile,")\n");
4384 ast_print(tree->left,outfile,indent+4);
4385 ast_print(tree->right,outfile,indent+4);
4388 /*------------------------------------------------------------------*/
4389 /*----------------------------*/
4391 /*----------------------------*/
4393 fprintf(outfile,"DIV (%p) type (",tree);
4394 printTypeChain(tree->ftype,outfile);
4395 fprintf(outfile,")\n");
4396 ast_print(tree->left,outfile,indent+4);
4397 ast_print(tree->right,outfile,indent+4);
4399 /*------------------------------------------------------------------*/
4400 /*----------------------------*/
4402 /*----------------------------*/
4404 fprintf(outfile,"MOD (%p) type (",tree);
4405 printTypeChain(tree->ftype,outfile);
4406 fprintf(outfile,")\n");
4407 ast_print(tree->left,outfile,indent+4);
4408 ast_print(tree->right,outfile,indent+4);
4411 /*------------------------------------------------------------------*/
4412 /*----------------------------*/
4413 /* address dereference */
4414 /*----------------------------*/
4415 case '*': /* can be unary : if right is null then unary operation */
4417 fprintf(outfile,"DEREF (%p) type (",tree);
4418 printTypeChain(tree->ftype,outfile);
4419 fprintf(outfile,")\n");
4420 ast_print(tree->left,outfile,indent+4);
4423 /*------------------------------------------------------------------*/
4424 /*----------------------------*/
4425 /* multiplication */
4426 /*----------------------------*/
4427 fprintf(outfile,"MULT (%p) type (",tree);
4428 printTypeChain(tree->ftype,outfile);
4429 fprintf(outfile,")\n");
4430 ast_print(tree->left,outfile,indent+4);
4431 ast_print(tree->right,outfile,indent+4);
4435 /*------------------------------------------------------------------*/
4436 /*----------------------------*/
4437 /* unary '+' operator */
4438 /*----------------------------*/
4442 fprintf(outfile,"UPLUS (%p) type (",tree);
4443 printTypeChain(tree->ftype,outfile);
4444 fprintf(outfile,")\n");
4445 ast_print(tree->left,outfile,indent+4);
4447 /*------------------------------------------------------------------*/
4448 /*----------------------------*/
4450 /*----------------------------*/
4451 fprintf(outfile,"ADD (%p) type (",tree);
4452 printTypeChain(tree->ftype,outfile);
4453 fprintf(outfile,")\n");
4454 ast_print(tree->left,outfile,indent+4);
4455 ast_print(tree->right,outfile,indent+4);
4458 /*------------------------------------------------------------------*/
4459 /*----------------------------*/
4461 /*----------------------------*/
4462 case '-': /* can be unary */
4464 fprintf(outfile,"UMINUS (%p) type (",tree);
4465 printTypeChain(tree->ftype,outfile);
4466 fprintf(outfile,")\n");
4467 ast_print(tree->left,outfile,indent+4);
4469 /*------------------------------------------------------------------*/
4470 /*----------------------------*/
4472 /*----------------------------*/
4473 fprintf(outfile,"SUB (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+4);
4477 ast_print(tree->right,outfile,indent+4);
4480 /*------------------------------------------------------------------*/
4481 /*----------------------------*/
4483 /*----------------------------*/
4485 fprintf(outfile,"COMPL (%p) type (",tree);
4486 printTypeChain(tree->ftype,outfile);
4487 fprintf(outfile,")\n");
4488 ast_print(tree->left,outfile,indent+4);
4490 /*------------------------------------------------------------------*/
4491 /*----------------------------*/
4493 /*----------------------------*/
4495 fprintf(outfile,"NOT (%p) type (",tree);
4496 printTypeChain(tree->ftype,outfile);
4497 fprintf(outfile,")\n");
4498 ast_print(tree->left,outfile,indent+4);
4500 /*------------------------------------------------------------------*/
4501 /*----------------------------*/
4503 /*----------------------------*/
4505 fprintf(outfile,"RRC (%p) type (",tree);
4506 printTypeChain(tree->ftype,outfile);
4507 fprintf(outfile,")\n");
4508 ast_print(tree->left,outfile,indent+4);
4512 fprintf(outfile,"RLC (%p) type (",tree);
4513 printTypeChain(tree->ftype,outfile);
4514 fprintf(outfile,")\n");
4515 ast_print(tree->left,outfile,indent+4);
4518 fprintf(outfile,"GETHBIT (%p) type (",tree);
4519 printTypeChain(tree->ftype,outfile);
4520 fprintf(outfile,")\n");
4521 ast_print(tree->left,outfile,indent+4);
4524 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+4);
4528 ast_print(tree->right,outfile,indent+4);
4531 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4532 printTypeChain(tree->ftype,outfile);
4533 fprintf(outfile,")\n");
4534 ast_print(tree->left,outfile,indent+4);
4535 ast_print(tree->right,outfile,indent+4);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4540 /*----------------------------*/
4541 case CAST: /* change the type */
4542 fprintf(outfile,"CAST (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->right,outfile,indent+4);
4549 fprintf(outfile,"ANDAND (%p) type (",tree);
4550 printTypeChain(tree->ftype,outfile);
4551 fprintf(outfile,")\n");
4552 ast_print(tree->left,outfile,indent+4);
4553 ast_print(tree->right,outfile,indent+4);
4556 fprintf(outfile,"OROR (%p) type (",tree);
4557 printTypeChain(tree->ftype,outfile);
4558 fprintf(outfile,")\n");
4559 ast_print(tree->left,outfile,indent+4);
4560 ast_print(tree->right,outfile,indent+4);
4563 /*------------------------------------------------------------------*/
4564 /*----------------------------*/
4565 /* comparison operators */
4566 /*----------------------------*/
4568 fprintf(outfile,"GT(>) (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+4);
4572 ast_print(tree->right,outfile,indent+4);
4575 fprintf(outfile,"LT(<) (%p) type (",tree);
4576 printTypeChain(tree->ftype,outfile);
4577 fprintf(outfile,")\n");
4578 ast_print(tree->left,outfile,indent+4);
4579 ast_print(tree->right,outfile,indent+4);
4582 fprintf(outfile,"LE(<=) (%p) type (",tree);
4583 printTypeChain(tree->ftype,outfile);
4584 fprintf(outfile,")\n");
4585 ast_print(tree->left,outfile,indent+4);
4586 ast_print(tree->right,outfile,indent+4);
4589 fprintf(outfile,"GE(>=) (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->left,outfile,indent+4);
4593 ast_print(tree->right,outfile,indent+4);
4596 fprintf(outfile,"EQ(==) (%p) type (",tree);
4597 printTypeChain(tree->ftype,outfile);
4598 fprintf(outfile,")\n");
4599 ast_print(tree->left,outfile,indent+4);
4600 ast_print(tree->right,outfile,indent+4);
4603 fprintf(outfile,"NE(!=) (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+4);
4607 ast_print(tree->right,outfile,indent+4);
4608 /*------------------------------------------------------------------*/
4609 /*----------------------------*/
4611 /*----------------------------*/
4612 case SIZEOF: /* evaluate wihout code generation */
4613 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4616 /*------------------------------------------------------------------*/
4617 /*----------------------------*/
4618 /* conditional operator '?' */
4619 /*----------------------------*/
4621 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4622 printTypeChain(tree->ftype,outfile);
4623 fprintf(outfile,")\n");
4624 ast_print(tree->left,outfile,indent+4);
4625 ast_print(tree->right,outfile,indent+4);
4628 fprintf(outfile,"COLON(:) (%p) type (",tree);
4629 printTypeChain(tree->ftype,outfile);
4630 fprintf(outfile,")\n");
4631 ast_print(tree->left,outfile,indent+4);
4632 ast_print(tree->right,outfile,indent+4);
4635 /*------------------------------------------------------------------*/
4636 /*----------------------------*/
4637 /* assignment operators */
4638 /*----------------------------*/
4640 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+4);
4644 ast_print(tree->right,outfile,indent+4);
4647 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+4);
4651 ast_print(tree->right,outfile,indent+4);
4654 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+4);
4658 ast_print(tree->right,outfile,indent+4);
4661 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4662 printTypeChain(tree->ftype,outfile);
4663 fprintf(outfile,")\n");
4664 ast_print(tree->left,outfile,indent+4);
4665 ast_print(tree->right,outfile,indent+4);
4668 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4669 printTypeChain(tree->ftype,outfile);
4670 fprintf(outfile,")\n");
4671 ast_print(tree->left,outfile,indent+4);
4672 ast_print(tree->right,outfile,indent+4);
4675 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+4);
4679 ast_print(tree->right,outfile,indent+4);
4682 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+4);
4686 ast_print(tree->right,outfile,indent+4);
4688 /*------------------------------------------------------------------*/
4689 /*----------------------------*/
4691 /*----------------------------*/
4693 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4694 printTypeChain(tree->ftype,outfile);
4695 fprintf(outfile,")\n");
4696 ast_print(tree->left,outfile,indent+4);
4697 ast_print(tree->right,outfile,indent+4);
4699 /*------------------------------------------------------------------*/
4700 /*----------------------------*/
4702 /*----------------------------*/
4704 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+4);
4708 ast_print(tree->right,outfile,indent+4);
4710 /*------------------------------------------------------------------*/
4711 /*----------------------------*/
4712 /* straight assignemnt */
4713 /*----------------------------*/
4715 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4716 printTypeChain(tree->ftype,outfile);
4717 fprintf(outfile,")\n");
4718 ast_print(tree->left,outfile,indent+4);
4719 ast_print(tree->right,outfile,indent+4);
4721 /*------------------------------------------------------------------*/
4722 /*----------------------------*/
4723 /* comma operator */
4724 /*----------------------------*/
4726 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4727 printTypeChain(tree->ftype,outfile);
4728 fprintf(outfile,")\n");
4729 ast_print(tree->left,outfile,indent+4);
4730 ast_print(tree->right,outfile,indent+4);
4732 /*------------------------------------------------------------------*/
4733 /*----------------------------*/
4735 /*----------------------------*/
4738 fprintf(outfile,"CALL (%p) type (",tree);
4739 printTypeChain(tree->ftype,outfile);
4740 fprintf(outfile,")\n");
4741 ast_print(tree->left,outfile,indent+4);
4742 ast_print(tree->right,outfile,indent+4);
4745 fprintf(outfile,"PARM ");
4746 ast_print(tree->left,outfile,indent+4);
4747 if (tree->right && !IS_AST_PARAM(tree->right)) {
4748 fprintf(outfile,"PARM ");
4749 ast_print(tree->right,outfile,indent+4);
4752 /*------------------------------------------------------------------*/
4753 /*----------------------------*/
4754 /* return statement */
4755 /*----------------------------*/
4757 fprintf(outfile,"RETURN (%p) type (",tree);
4758 printTypeChain(tree->right->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->right,outfile,indent+4);
4762 /*------------------------------------------------------------------*/
4763 /*----------------------------*/
4764 /* label statement */
4765 /*----------------------------*/
4767 fprintf(outfile,"LABEL (%p)",tree);
4768 ast_print(tree->left,outfile,indent+4);
4769 ast_print(tree->right,outfile,indent);
4771 /*------------------------------------------------------------------*/
4772 /*----------------------------*/
4773 /* switch statement */
4774 /*----------------------------*/
4778 fprintf(outfile,"SWITCH (%p) ",tree);
4779 ast_print(tree->left,outfile,0);
4780 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4781 INDENT(indent+4,outfile);
4782 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4783 (int) floatFromVal(val),
4784 tree->values.switchVals.swNum,
4785 (int) floatFromVal(val));
4787 ast_print(tree->right,outfile,indent);
4790 /*------------------------------------------------------------------*/
4791 /*----------------------------*/
4793 /*----------------------------*/
4795 ast_print(tree->left,outfile,indent);
4796 INDENT(indent,outfile);
4797 fprintf(outfile,"IF (%p) \n",tree);
4798 if (tree->trueLabel) {
4799 INDENT(indent,outfile);
4800 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4802 if (tree->falseLabel) {
4803 INDENT(indent,outfile);
4804 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4806 ast_print(tree->right,outfile,indent);
4808 /*------------------------------------------------------------------*/
4809 /*----------------------------*/
4811 /*----------------------------*/
4813 fprintf(outfile,"FOR (%p) \n",tree);
4814 if (AST_FOR( tree, initExpr)) {
4815 INDENT(indent+4,outfile);
4816 fprintf(outfile,"INIT EXPR ");
4817 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4819 if (AST_FOR( tree, condExpr)) {
4820 INDENT(indent+4,outfile);
4821 fprintf(outfile,"COND EXPR ");
4822 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4824 if (AST_FOR( tree, loopExpr)) {
4825 INDENT(indent+4,outfile);
4826 fprintf(outfile,"LOOP EXPR ");
4827 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4829 fprintf(outfile,"FOR LOOP BODY \n");
4830 ast_print(tree->left,outfile,indent+4);
4839 ast_print(t,stdout,1);