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);
230 dest->values.constlist = copyLiteralList(src->values.constlist);
234 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
235 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
236 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
237 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
238 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
239 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
240 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
245 /*-----------------------------------------------------------------*/
246 /* copyAst - makes a copy of a given astession */
247 /*-----------------------------------------------------------------*/
256 dest = Safe_calloc (1, sizeof (ast));
258 dest->type = src->type;
259 dest->lineno = src->lineno;
260 dest->level = src->level;
261 dest->funcName = src->funcName;
262 dest->argSym = src->argSym;
264 /* if this is a leaf */
266 if (src->type == EX_VALUE)
268 dest->opval.val = copyValue (src->opval.val);
273 if (src->type == EX_LINK)
275 dest->opval.lnk = copyLinkChain (src->opval.lnk);
279 dest->opval.op = src->opval.op;
281 /* if this is a node that has special values */
282 copyAstValues (dest, src);
285 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
287 dest->trueLabel = copySymbol (src->trueLabel);
288 dest->falseLabel = copySymbol (src->falseLabel);
289 dest->left = copyAst (src->left);
290 dest->right = copyAst (src->right);
296 /*-----------------------------------------------------------------*/
297 /* hasSEFcalls - returns TRUE if tree has a function call */
298 /*-----------------------------------------------------------------*/
300 hasSEFcalls (ast * tree)
305 if (tree->type == EX_OP &&
306 (tree->opval.op == CALL ||
307 tree->opval.op == PCALL ||
308 tree->opval.op == '=' ||
309 tree->opval.op == INC_OP ||
310 tree->opval.op == DEC_OP))
313 return (hasSEFcalls (tree->left) |
314 hasSEFcalls (tree->right));
317 /*-----------------------------------------------------------------*/
318 /* isAstEqual - compares two asts & returns 1 if they are equal */
319 /*-----------------------------------------------------------------*/
321 isAstEqual (ast * t1, ast * t2)
330 if (t1->type != t2->type)
336 if (t1->opval.op != t2->opval.op)
338 return (isAstEqual (t1->left, t2->left) &&
339 isAstEqual (t1->right, t2->right));
343 if (t1->opval.val->sym)
345 if (!t2->opval.val->sym)
348 return isSymbolEqual (t1->opval.val->sym,
353 if (t2->opval.val->sym)
356 return (floatFromVal (t1->opval.val) ==
357 floatFromVal (t2->opval.val));
361 /* only compare these two types */
369 /*-----------------------------------------------------------------*/
370 /* resolveSymbols - resolve symbols from the symbol table */
371 /*-----------------------------------------------------------------*/
373 resolveSymbols (ast * tree)
375 /* walk the entire tree and check for values */
376 /* with symbols if we find one then replace */
377 /* symbol with that from the symbol table */
383 /* if not block & function */
384 if (tree->type == EX_OP &&
385 (tree->opval.op != FUNCTION &&
386 tree->opval.op != BLOCK &&
387 tree->opval.op != NULLOP))
389 filename = tree->filename;
390 lineno = tree->lineno;
393 /* make sure we resolve the true & false labels for ifx */
394 if (tree->type == EX_OP && tree->opval.op == IFX)
400 if ((csym = findSym (LabelTab, tree->trueLabel,
401 tree->trueLabel->name)))
402 tree->trueLabel = csym;
404 werror (E_LABEL_UNDEF, tree->trueLabel->name);
407 if (tree->falseLabel)
409 if ((csym = findSym (LabelTab,
411 tree->falseLabel->name)))
412 tree->falseLabel = csym;
414 werror (E_LABEL_UNDEF, tree->falseLabel->name);
419 /* if this is a label resolve it from the labelTab */
420 if (IS_AST_VALUE (tree) &&
421 tree->opval.val->sym &&
422 tree->opval.val->sym->islbl)
425 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
426 tree->opval.val->sym->name);
429 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
431 tree->opval.val->sym = csym;
433 goto resolveChildren;
436 /* do only for leafs */
437 if (IS_AST_VALUE (tree) &&
438 tree->opval.val->sym &&
439 !tree->opval.val->sym->implicit)
442 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
444 /* if found in the symbol table & they r not the same */
445 if (csym && tree->opval.val->sym != csym)
447 tree->opval.val->sym = csym;
448 tree->opval.val->type = csym->type;
449 tree->opval.val->etype = csym->etype;
452 /* if not found in the symbol table */
453 /* mark it as undefined assume it is */
454 /* an integer in data space */
455 if (!csym && !tree->opval.val->sym->implicit)
458 /* if this is a function name then */
459 /* mark it as returning an int */
462 tree->opval.val->sym->type = newLink ();
463 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
464 tree->opval.val->sym->type->next =
465 tree->opval.val->sym->etype = newIntLink ();
466 tree->opval.val->etype = tree->opval.val->etype;
467 tree->opval.val->type = tree->opval.val->sym->type;
468 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
472 tree->opval.val->sym->undefined = 1;
473 tree->opval.val->type =
474 tree->opval.val->etype = newIntLink ();
475 tree->opval.val->sym->type =
476 tree->opval.val->sym->etype = newIntLink ();
482 resolveSymbols (tree->left);
483 resolveSymbols (tree->right);
488 /*-----------------------------------------------------------------*/
489 /* setAstLineno - walks a ast tree & sets the line number */
490 /*-----------------------------------------------------------------*/
492 setAstLineno (ast * tree, int lineno)
497 tree->lineno = lineno;
498 setAstLineno (tree->left, lineno);
499 setAstLineno (tree->right, lineno);
504 /* this functions seems to be superfluous?! kmh */
506 /*-----------------------------------------------------------------*/
507 /* resolveFromTable - will return the symbal table value */
508 /*-----------------------------------------------------------------*/
510 resolveFromTable (value * val)
517 csym = findSymWithLevel (SymbolTab, val->sym);
519 /* if found in the symbol table & they r not the same */
520 if (csym && val->sym != csym &&
521 csym->level == val->sym->level &&
527 val->type = csym->type;
528 val->etype = csym->etype;
535 /*-----------------------------------------------------------------*/
536 /* funcOfType :- function of type with name */
537 /*-----------------------------------------------------------------*/
539 funcOfType (char *name, sym_link * type, sym_link * argType,
543 /* create the symbol */
544 sym = newSymbol (name, 0);
546 /* if arguments required */
551 args = sym->args = newValue ();
555 args->type = copyLinkChain (argType);
556 args->etype = getSpec (args->type);
559 args = args->next = newValue ();
563 /* setup return value */
564 sym->type = newLink ();
565 DCL_TYPE (sym->type) = FUNCTION;
566 sym->type->next = copyLinkChain (type);
567 sym->etype = getSpec (sym->type);
568 SPEC_RENT (sym->etype) = rent;
573 allocVariables (sym);
578 /*-----------------------------------------------------------------*/
579 /* reverseParms - will reverse a parameter tree */
580 /*-----------------------------------------------------------------*/
582 reverseParms (ast * ptree)
588 /* top down if we find a nonParm tree then quit */
589 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
592 ptree->left = ptree->right;
593 ptree->right = ttree;
594 reverseParms (ptree->left);
595 reverseParms (ptree->right);
601 /*-----------------------------------------------------------------*/
602 /* processParms - makes sure the parameters are okay and do some */
603 /* processing with them */
604 /*-----------------------------------------------------------------*/
606 processParms (ast * func,
612 sym_link *fetype = func->etype;
614 /* if none of them exist */
615 if (!defParm && !actParm)
619 if (getenv("DEBUG_SANITY")) {
620 fprintf (stderr, "addSym: %s ", defParm->name);
622 /* make sure the type is complete and sane */
623 checkTypeSanity(defParm->etype, defParm->name);
626 /* if the function is being called via a pointer & */
627 /* it has not been defined a reentrant then we cannot */
628 /* have parameters */
629 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
631 werror (E_NONRENT_ARGS);
635 /* if defined parameters ended but actual parameters */
636 /* exist and this is not defined as a variable arg */
637 /* also check if statckAuto option is specified */
638 if ((!defParm) && actParm && (!func->hasVargs) &&
639 !options.stackAuto && !IS_RENT (fetype))
641 werror (E_TOO_MANY_PARMS);
645 /* if defined parameters present but no actual parameters */
646 if (defParm && !actParm)
648 werror (E_TOO_FEW_PARMS);
652 /* If this is a varargs function... */
653 if (!defParm && actParm && func->hasVargs)
658 if (IS_CAST_OP (actParm)
659 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
661 /* Parameter was explicitly typecast; don't touch it. */
665 /* The ternary ('?') operator is weird: the ftype of the
666 * operator is the type of the condition, but it will return a
667 * (possibly) different type.
669 if (IS_TERNARY_OP(actParm))
671 assert(IS_COLON_OP(actParm->right));
672 assert(actParm->right->left);
673 ftype = actParm->right->left->ftype;
677 ftype = actParm->ftype;
680 /* If it's a small integer, upcast to int. */
681 if (IS_INTEGRAL (ftype)
682 && (getSize (ftype) < (unsigned) INTSIZE))
684 newType = newAst_LINK(INTTYPE);
687 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
689 newType = newAst_LINK (copyLinkChain(ftype));
690 DCL_TYPE (newType->opval.lnk) = GPOINTER;
693 if (IS_AGGREGATE (ftype))
695 newType = newAst_LINK (copyLinkChain (ftype));
696 DCL_TYPE (newType->opval.lnk) = GPOINTER;
700 /* cast required; change this op to a cast. */
701 ast *parmCopy = resolveSymbols (copyAst (actParm));
703 actParm->type = EX_OP;
704 actParm->opval.op = CAST;
705 actParm->left = newType;
706 actParm->right = parmCopy;
707 decorateType (actParm);
709 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
711 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
712 processParms (func, NULL, actParm->right, parmNumber, rightmost));
717 /* if defined parameters ended but actual has not & */
719 if (!defParm && actParm &&
720 (options.stackAuto || IS_RENT (fetype)))
723 resolveSymbols (actParm);
724 /* if this is a PARAM node then match left & right */
725 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
727 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
728 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
732 /* If we have found a value node by following only right-hand links,
733 * then we know that there are no more values after us.
735 * Therefore, if there are more defined parameters, the caller didn't
738 if (rightmost && defParm->next)
740 werror (E_TOO_FEW_PARMS);
745 /* the parameter type must be at least castable */
746 if (compareType (defParm->type, actParm->ftype) == 0)
748 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
749 werror (E_CONTINUE, "defined type ");
750 printTypeChain (defParm->type, stderr);
751 fprintf (stderr, "\n");
752 werror (E_CONTINUE, "actual type ");
753 printTypeChain (actParm->ftype, stderr);
754 fprintf (stderr, "\n");
757 /* if the parameter is castable then add the cast */
758 if (compareType (defParm->type, actParm->ftype) < 0)
760 ast *pTree = resolveSymbols (copyAst (actParm));
762 /* now change the current one to a cast */
763 actParm->type = EX_OP;
764 actParm->opval.op = CAST;
765 actParm->left = newAst_LINK (defParm->type);
766 actParm->right = pTree;
767 actParm->etype = defParm->etype;
768 actParm->ftype = defParm->type;
771 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
773 actParm->argSym = defParm->sym;
774 /* make a copy and change the regparm type to the defined parm */
775 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
776 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
780 /*-----------------------------------------------------------------*/
781 /* createIvalType - generates ival for basic types */
782 /*-----------------------------------------------------------------*/
784 createIvalType (ast * sym, sym_link * type, initList * ilist)
788 /* if initList is deep */
789 if (ilist->type == INIT_DEEP)
790 ilist = ilist->init.deep;
792 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
793 return decorateType (newNode ('=', sym, iExpr));
796 /*-----------------------------------------------------------------*/
797 /* createIvalStruct - generates initial value for structures */
798 /*-----------------------------------------------------------------*/
800 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
806 sflds = SPEC_STRUCT (type)->fields;
807 if (ilist->type != INIT_DEEP)
809 werror (E_INIT_STRUCT, "");
813 iloop = ilist->init.deep;
815 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
819 /* if we have come to end */
823 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
824 lAst = decorateType (resolveSymbols (lAst));
825 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
831 /*-----------------------------------------------------------------*/
832 /* createIvalArray - generates code for array initialization */
833 /*-----------------------------------------------------------------*/
835 createIvalArray (ast * sym, sym_link * type, initList * ilist)
839 int lcnt = 0, size = 0;
840 literalList *literalL;
842 /* take care of the special case */
843 /* array of characters can be init */
845 if (IS_CHAR (type->next))
846 if ((rast = createIvalCharPtr (sym,
848 decorateType (resolveSymbols (list2expr (ilist))))))
850 return decorateType (resolveSymbols (rast));
852 /* not the special case */
853 if (ilist->type != INIT_DEEP)
855 werror (E_INIT_STRUCT, "");
859 iloop = ilist->init.deep;
860 lcnt = DCL_ELEM (type);
862 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
866 aSym = decorateType (resolveSymbols(sym));
868 rast = newNode(ARRAYINIT, aSym, NULL);
869 rast->values.constlist = literalL;
871 // Make sure size is set to length of initializer list.
878 if (lcnt && size > lcnt)
880 // Array size was specified, and we have more initializers than needed.
881 char *name=sym->opval.val->sym->name;
882 int lineno=sym->opval.val->sym->lineDef;
884 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
893 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
894 aSym = decorateType (resolveSymbols (aSym));
895 rast = createIval (aSym, type->next, iloop, rast);
896 iloop = (iloop ? iloop->next : NULL);
902 /* no of elements given and we */
903 /* have generated for all of them */
906 // there has to be a better way
907 char *name=sym->opval.val->sym->name;
908 int lineno=sym->opval.val->sym->lineDef;
909 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
916 /* if we have not been given a size */
917 if (!DCL_ELEM (type))
919 DCL_ELEM (type) = size;
922 return decorateType (resolveSymbols (rast));
926 /*-----------------------------------------------------------------*/
927 /* createIvalCharPtr - generates initial values for char pointers */
928 /*-----------------------------------------------------------------*/
930 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
934 /* if this is a pointer & right is a literal array then */
935 /* just assignment will do */
936 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
937 SPEC_SCLS (iexpr->etype) == S_CODE)
938 && IS_ARRAY (iexpr->ftype)))
939 return newNode ('=', sym, iexpr);
941 /* left side is an array so we have to assign each */
943 if ((IS_LITERAL (iexpr->etype) ||
944 SPEC_SCLS (iexpr->etype) == S_CODE)
945 && IS_ARRAY (iexpr->ftype))
947 /* for each character generate an assignment */
948 /* to the array element */
949 char *s = SPEC_CVAL (iexpr->etype).v_char;
954 rast = newNode (NULLOP,
958 newAst_VALUE (valueFromLit ((float) i))),
959 newAst_VALUE (valueFromLit (*s))));
963 rast = newNode (NULLOP,
967 newAst_VALUE (valueFromLit ((float) i))),
968 newAst_VALUE (valueFromLit (*s))));
969 return decorateType (resolveSymbols (rast));
975 /*-----------------------------------------------------------------*/
976 /* createIvalPtr - generates initial value for pointers */
977 /*-----------------------------------------------------------------*/
979 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
985 if (ilist->type == INIT_DEEP)
986 ilist = ilist->init.deep;
988 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
990 /* if character pointer */
991 if (IS_CHAR (type->next))
992 if ((rast = createIvalCharPtr (sym, type, iexpr)))
995 return newNode ('=', sym, iexpr);
998 /*-----------------------------------------------------------------*/
999 /* createIval - generates code for initial value */
1000 /*-----------------------------------------------------------------*/
1002 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1009 /* if structure then */
1010 if (IS_STRUCT (type))
1011 rast = createIvalStruct (sym, type, ilist);
1013 /* if this is a pointer */
1015 rast = createIvalPtr (sym, type, ilist);
1017 /* if this is an array */
1018 if (IS_ARRAY (type))
1019 rast = createIvalArray (sym, type, ilist);
1021 /* if type is SPECIFIER */
1023 rast = createIvalType (sym, type, ilist);
1025 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1027 return decorateType (resolveSymbols (rast));
1030 /*-----------------------------------------------------------------*/
1031 /* initAggregates - initialises aggregate variables with initv */
1032 /*-----------------------------------------------------------------*/
1034 initAggregates (symbol * sym, initList * ival, ast * wid)
1036 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1039 /*-----------------------------------------------------------------*/
1040 /* gatherAutoInit - creates assignment expressions for initial */
1042 /*-----------------------------------------------------------------*/
1044 gatherAutoInit (symbol * autoChain)
1051 for (sym = autoChain; sym; sym = sym->next)
1054 /* resolve the symbols in the ival */
1056 resolveIvalSym (sym->ival);
1058 /* if this is a static variable & has an */
1059 /* initial value the code needs to be lifted */
1060 /* here to the main portion since they can be */
1061 /* initialised only once at the start */
1062 if (IS_STATIC (sym->etype) && sym->ival &&
1063 SPEC_SCLS (sym->etype) != S_CODE)
1067 // this can only be a constant
1068 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1069 werror (E_CONST_EXPECTED);
1072 /* insert the symbol into the symbol table */
1073 /* with level = 0 & name = rname */
1074 newSym = copySymbol (sym);
1075 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1077 /* now lift the code to main */
1078 if (IS_AGGREGATE (sym->type))
1079 work = initAggregates (sym, sym->ival, NULL);
1081 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1082 list2expr (sym->ival));
1084 setAstLineno (work, sym->lineDef);
1088 staticAutos = newNode (NULLOP, staticAutos, work);
1095 /* if there is an initial value */
1096 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1098 if (IS_AGGREGATE (sym->type))
1099 work = initAggregates (sym, sym->ival, NULL);
1101 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1102 list2expr (sym->ival));
1104 setAstLineno (work, sym->lineDef);
1107 init = newNode (NULLOP, init, work);
1116 /*-----------------------------------------------------------------*/
1117 /* stringToSymbol - creates a symbol from a literal string */
1118 /*-----------------------------------------------------------------*/
1120 stringToSymbol (value * val)
1122 char name[SDCC_NAME_MAX + 1];
1123 static int charLbl = 0;
1126 sprintf (name, "_str_%d", charLbl++);
1127 sym = newSymbol (name, 0); /* make it @ level 0 */
1128 strcpy (sym->rname, name);
1130 /* copy the type from the value passed */
1131 sym->type = copyLinkChain (val->type);
1132 sym->etype = getSpec (sym->type);
1133 /* change to storage class & output class */
1134 SPEC_SCLS (sym->etype) = S_CODE;
1135 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1136 SPEC_STAT (sym->etype) = 1;
1137 /* make the level & block = 0 */
1138 sym->block = sym->level = 0;
1140 /* create an ival */
1141 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1146 allocVariables (sym);
1149 return symbolVal (sym);
1153 /*-----------------------------------------------------------------*/
1154 /* processBlockVars - will go thru the ast looking for block if */
1155 /* a block is found then will allocate the syms */
1156 /* will also gather the auto inits present */
1157 /*-----------------------------------------------------------------*/
1159 processBlockVars (ast * tree, int *stack, int action)
1164 /* if this is a block */
1165 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1169 if (action == ALLOCATE)
1171 autoInit = gatherAutoInit (tree->values.sym);
1172 *stack += allocVariables (tree->values.sym);
1174 /* if there are auto inits then do them */
1176 tree->left = newNode (NULLOP, autoInit, tree->left);
1178 else /* action is deallocate */
1179 deallocLocal (tree->values.sym);
1182 processBlockVars (tree->left, stack, action);
1183 processBlockVars (tree->right, stack, action);
1187 /*-----------------------------------------------------------------*/
1188 /* constExprValue - returns the value of a constant expression */
1189 /*-----------------------------------------------------------------*/
1191 constExprValue (ast * cexpr, int check)
1193 cexpr = decorateType (resolveSymbols (cexpr));
1195 /* if this is not a constant then */
1196 if (!IS_LITERAL (cexpr->ftype))
1198 /* then check if this is a literal array
1200 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1201 SPEC_CVAL (cexpr->etype).v_char &&
1202 IS_ARRAY (cexpr->ftype))
1204 value *val = valFromType (cexpr->ftype);
1205 SPEC_SCLS (val->etype) = S_LITERAL;
1206 val->sym = cexpr->opval.val->sym;
1207 val->sym->type = copyLinkChain (cexpr->ftype);
1208 val->sym->etype = getSpec (val->sym->type);
1209 strcpy (val->name, cexpr->opval.val->sym->rname);
1213 /* if we are casting a literal value then */
1214 if (IS_AST_OP (cexpr) &&
1215 cexpr->opval.op == CAST &&
1216 IS_LITERAL (cexpr->left->ftype))
1217 return valCastLiteral (cexpr->ftype,
1218 floatFromVal (cexpr->left->opval.val));
1220 if (IS_AST_VALUE (cexpr))
1221 return cexpr->opval.val;
1224 werror (E_CONST_EXPECTED, "found expression");
1229 /* return the value */
1230 return cexpr->opval.val;
1234 /*-----------------------------------------------------------------*/
1235 /* isLabelInAst - will return true if a given label is found */
1236 /*-----------------------------------------------------------------*/
1238 isLabelInAst (symbol * label, ast * tree)
1240 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1243 if (IS_AST_OP (tree) &&
1244 tree->opval.op == LABEL &&
1245 isSymbolEqual (AST_SYMBOL (tree->left), label))
1248 return isLabelInAst (label, tree->right) &&
1249 isLabelInAst (label, tree->left);
1253 /*-----------------------------------------------------------------*/
1254 /* isLoopCountable - return true if the loop count can be determi- */
1255 /* -ned at compile time . */
1256 /*-----------------------------------------------------------------*/
1258 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1259 symbol ** sym, ast ** init, ast ** end)
1262 /* the loop is considered countable if the following
1263 conditions are true :-
1265 a) initExpr :- <sym> = <const>
1266 b) condExpr :- <sym> < <const1>
1267 c) loopExpr :- <sym> ++
1270 /* first check the initExpr */
1271 if (IS_AST_OP (initExpr) &&
1272 initExpr->opval.op == '=' && /* is assignment */
1273 IS_AST_SYM_VALUE (initExpr->left))
1274 { /* left is a symbol */
1276 *sym = AST_SYMBOL (initExpr->left);
1277 *init = initExpr->right;
1282 /* for now the symbol has to be of
1284 if (!IS_INTEGRAL ((*sym)->type))
1287 /* now check condExpr */
1288 if (IS_AST_OP (condExpr))
1291 switch (condExpr->opval.op)
1294 if (IS_AST_SYM_VALUE (condExpr->left) &&
1295 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1296 IS_AST_LIT_VALUE (condExpr->right))
1298 *end = condExpr->right;
1304 if (IS_AST_OP (condExpr->left) &&
1305 condExpr->left->opval.op == '>' &&
1306 IS_AST_LIT_VALUE (condExpr->left->right) &&
1307 IS_AST_SYM_VALUE (condExpr->left->left) &&
1308 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1311 *end = newNode ('+', condExpr->left->right,
1312 newAst_VALUE (constVal ("1")));
1323 /* check loop expression is of the form <sym>++ */
1324 if (!IS_AST_OP (loopExpr))
1327 /* check if <sym> ++ */
1328 if (loopExpr->opval.op == INC_OP)
1334 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1335 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1342 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1343 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1351 if (loopExpr->opval.op == ADD_ASSIGN)
1354 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1355 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1356 IS_AST_LIT_VALUE (loopExpr->right) &&
1357 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1365 /*-----------------------------------------------------------------*/
1366 /* astHasVolatile - returns true if ast contains any volatile */
1367 /*-----------------------------------------------------------------*/
1369 astHasVolatile (ast * tree)
1374 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1377 if (IS_AST_OP (tree))
1378 return astHasVolatile (tree->left) ||
1379 astHasVolatile (tree->right);
1384 /*-----------------------------------------------------------------*/
1385 /* astHasPointer - return true if the ast contains any ptr variable */
1386 /*-----------------------------------------------------------------*/
1388 astHasPointer (ast * tree)
1393 if (IS_AST_LINK (tree))
1396 /* if we hit an array expression then check
1397 only the left side */
1398 if (IS_AST_OP (tree) && tree->opval.op == '[')
1399 return astHasPointer (tree->left);
1401 if (IS_AST_VALUE (tree))
1402 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1404 return astHasPointer (tree->left) ||
1405 astHasPointer (tree->right);
1409 /*-----------------------------------------------------------------*/
1410 /* astHasSymbol - return true if the ast has the given symbol */
1411 /*-----------------------------------------------------------------*/
1413 astHasSymbol (ast * tree, symbol * sym)
1415 if (!tree || IS_AST_LINK (tree))
1418 if (IS_AST_VALUE (tree))
1420 if (IS_AST_SYM_VALUE (tree))
1421 return isSymbolEqual (AST_SYMBOL (tree), sym);
1426 return astHasSymbol (tree->left, sym) ||
1427 astHasSymbol (tree->right, sym);
1430 /*-----------------------------------------------------------------*/
1431 /* isConformingBody - the loop body has to conform to a set of rules */
1432 /* for the loop to be considered reversible read on for rules */
1433 /*-----------------------------------------------------------------*/
1435 isConformingBody (ast * pbody, symbol * sym, ast * body)
1438 /* we are going to do a pre-order traversal of the
1439 tree && check for the following conditions. (essentially
1440 a set of very shallow tests )
1441 a) the sym passed does not participate in
1442 any arithmetic operation
1443 b) There are no function calls
1444 c) all jumps are within the body
1445 d) address of loop control variable not taken
1446 e) if an assignment has a pointer on the
1447 left hand side make sure right does not have
1448 loop control variable */
1450 /* if we reach the end or a leaf then true */
1451 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1455 /* if anything else is "volatile" */
1456 if (IS_VOLATILE (TETYPE (pbody)))
1459 /* we will walk the body in a pre-order traversal for
1461 switch (pbody->opval.op)
1463 /*------------------------------------------------------------------*/
1465 return isConformingBody (pbody->right, sym, body);
1467 /*------------------------------------------------------------------*/
1472 /*------------------------------------------------------------------*/
1473 case INC_OP: /* incerement operator unary so left only */
1476 /* sure we are not sym is not modified */
1478 IS_AST_SYM_VALUE (pbody->left) &&
1479 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1483 IS_AST_SYM_VALUE (pbody->right) &&
1484 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1489 /*------------------------------------------------------------------*/
1491 case '*': /* can be unary : if right is null then unary operation */
1496 /* if right is NULL then unary operation */
1497 /*------------------------------------------------------------------*/
1498 /*----------------------------*/
1500 /*----------------------------*/
1503 if (IS_AST_SYM_VALUE (pbody->left) &&
1504 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1507 return isConformingBody (pbody->left, sym, body);
1511 if (astHasSymbol (pbody->left, sym) ||
1512 astHasSymbol (pbody->right, sym))
1517 /*------------------------------------------------------------------*/
1525 if (IS_AST_SYM_VALUE (pbody->left) &&
1526 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1529 if (IS_AST_SYM_VALUE (pbody->right) &&
1530 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1533 return isConformingBody (pbody->left, sym, body) &&
1534 isConformingBody (pbody->right, sym, body);
1541 if (IS_AST_SYM_VALUE (pbody->left) &&
1542 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1544 return isConformingBody (pbody->left, sym, body);
1546 /*------------------------------------------------------------------*/
1558 case SIZEOF: /* evaluate wihout code generation */
1560 return isConformingBody (pbody->left, sym, body) &&
1561 isConformingBody (pbody->right, sym, body);
1563 /*------------------------------------------------------------------*/
1566 /* if left has a pointer & right has loop
1567 control variable then we cannot */
1568 if (astHasPointer (pbody->left) &&
1569 astHasSymbol (pbody->right, sym))
1571 if (astHasVolatile (pbody->left))
1574 if (IS_AST_SYM_VALUE (pbody->left) &&
1575 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1578 if (astHasVolatile (pbody->left))
1581 return isConformingBody (pbody->left, sym, body) &&
1582 isConformingBody (pbody->right, sym, body);
1593 assert ("Parser should not have generated this\n");
1595 /*------------------------------------------------------------------*/
1596 /*----------------------------*/
1597 /* comma operator */
1598 /*----------------------------*/
1600 return isConformingBody (pbody->left, sym, body) &&
1601 isConformingBody (pbody->right, sym, body);
1603 /*------------------------------------------------------------------*/
1604 /*----------------------------*/
1606 /*----------------------------*/
1610 /*------------------------------------------------------------------*/
1611 /*----------------------------*/
1612 /* return statement */
1613 /*----------------------------*/
1618 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1623 if (astHasSymbol (pbody->left, sym))
1630 return isConformingBody (pbody->left, sym, body) &&
1631 isConformingBody (pbody->right, sym, body);
1637 /*-----------------------------------------------------------------*/
1638 /* isLoopReversible - takes a for loop as input && returns true */
1639 /* if the for loop is reversible. If yes will set the value of */
1640 /* the loop control var & init value & termination value */
1641 /*-----------------------------------------------------------------*/
1643 isLoopReversible (ast * loop, symbol ** loopCntrl,
1644 ast ** init, ast ** end)
1646 /* if option says don't do it then don't */
1647 if (optimize.noLoopReverse)
1649 /* there are several tests to determine this */
1651 /* for loop has to be of the form
1652 for ( <sym> = <const1> ;
1653 [<sym> < <const2>] ;
1654 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1656 if (!isLoopCountable (AST_FOR (loop, initExpr),
1657 AST_FOR (loop, condExpr),
1658 AST_FOR (loop, loopExpr),
1659 loopCntrl, init, end))
1662 /* now do some serious checking on the body of the loop
1665 return isConformingBody (loop->left, *loopCntrl, loop->left);
1669 /*-----------------------------------------------------------------*/
1670 /* replLoopSym - replace the loop sym by loop sym -1 */
1671 /*-----------------------------------------------------------------*/
1673 replLoopSym (ast * body, symbol * sym)
1676 if (!body || IS_AST_LINK (body))
1679 if (IS_AST_SYM_VALUE (body))
1682 if (isSymbolEqual (AST_SYMBOL (body), sym))
1686 body->opval.op = '-';
1687 body->left = newAst_VALUE (symbolVal (sym));
1688 body->right = newAst_VALUE (constVal ("1"));
1696 replLoopSym (body->left, sym);
1697 replLoopSym (body->right, sym);
1701 /*-----------------------------------------------------------------*/
1702 /* reverseLoop - do the actual loop reversal */
1703 /*-----------------------------------------------------------------*/
1705 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1709 /* create the following tree
1714 if (sym) goto for_continue ;
1717 /* put it together piece by piece */
1718 rloop = newNode (NULLOP,
1719 createIf (newAst_VALUE (symbolVal (sym)),
1721 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1724 newAst_VALUE (symbolVal (sym)),
1727 replLoopSym (loop->left, sym);
1729 rloop = newNode (NULLOP,
1731 newAst_VALUE (symbolVal (sym)),
1732 newNode ('-', end, init)),
1733 createLabel (AST_FOR (loop, continueLabel),
1737 newNode (SUB_ASSIGN,
1738 newAst_VALUE (symbolVal (sym)),
1739 newAst_VALUE (constVal ("1"))),
1742 return decorateType (rloop);
1746 //#define DEMAND_INTEGER_PROMOTION
1748 #ifdef DEMAND_INTEGER_PROMOTION
1750 /*-----------------------------------------------------------------*/
1751 /* walk a tree looking for the leaves. Add a typecast to the given */
1752 /* type to each value leaf node. */
1753 /*-----------------------------------------------------------------*/
1755 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1757 if (!node || IS_CALLOP(node))
1759 /* WTF? We should never get here. */
1763 if (!node->left && !node->right)
1765 /* We're at a leaf; if it's a value, apply the typecast */
1766 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1768 *parentPtr = decorateType (newNode (CAST,
1769 newAst_LINK (copyLinkChain (type)),
1777 pushTypeCastToLeaves (type, node->left, &(node->left));
1781 pushTypeCastToLeaves (type, node->right, &(node->right));
1788 /*-----------------------------------------------------------------*/
1789 /* Given an assignment operation in a tree, determine if the LHS */
1790 /* (the result) has a different (integer) type than the RHS. */
1791 /* If so, walk the RHS and add a typecast to the type of the LHS */
1792 /* to all leaf nodes. */
1793 /*-----------------------------------------------------------------*/
1795 propAsgType (ast * tree)
1797 #ifdef DEMAND_INTEGER_PROMOTION
1798 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1800 /* Nothing to do here... */
1804 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1806 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1813 /*-----------------------------------------------------------------*/
1814 /* decorateType - compute type for this tree also does type cheking */
1815 /* this is done bottom up, since type have to flow upwards */
1816 /* it also does constant folding, and paramater checking */
1817 /*-----------------------------------------------------------------*/
1819 decorateType (ast * tree)
1827 /* if already has type then do nothing */
1828 if (tree->decorated)
1831 tree->decorated = 1;
1833 /* print the line */
1834 /* if not block & function */
1835 if (tree->type == EX_OP &&
1836 (tree->opval.op != FUNCTION &&
1837 tree->opval.op != BLOCK &&
1838 tree->opval.op != NULLOP))
1840 filename = tree->filename;
1841 lineno = tree->lineno;
1844 /* if any child is an error | this one is an error do nothing */
1845 if (tree->isError ||
1846 (tree->left && tree->left->isError) ||
1847 (tree->right && tree->right->isError))
1850 /*------------------------------------------------------------------*/
1851 /*----------------------------*/
1852 /* leaf has been reached */
1853 /*----------------------------*/
1854 /* if this is of type value */
1855 /* just get the type */
1856 if (tree->type == EX_VALUE)
1859 if (IS_LITERAL (tree->opval.val->etype))
1862 /* if this is a character array then declare it */
1863 if (IS_ARRAY (tree->opval.val->type))
1864 tree->opval.val = stringToSymbol (tree->opval.val);
1866 /* otherwise just copy the type information */
1867 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1868 if (funcInChain (tree->opval.val->type))
1870 tree->hasVargs = tree->opval.val->sym->hasVargs;
1871 tree->args = copyValueChain (tree->opval.val->sym->args);
1876 if (tree->opval.val->sym)
1878 /* if the undefined flag is set then give error message */
1879 if (tree->opval.val->sym->undefined)
1881 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1883 TTYPE (tree) = TETYPE (tree) =
1884 tree->opval.val->type = tree->opval.val->sym->type =
1885 tree->opval.val->etype = tree->opval.val->sym->etype =
1886 copyLinkChain (INTTYPE);
1891 /* if impilicit i.e. struct/union member then no type */
1892 if (tree->opval.val->sym->implicit)
1893 TTYPE (tree) = TETYPE (tree) = NULL;
1898 /* else copy the type */
1899 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1901 /* and mark it as referenced */
1902 tree->opval.val->sym->isref = 1;
1903 /* if this is of type function or function pointer */
1904 if (funcInChain (tree->opval.val->type))
1906 tree->hasVargs = tree->opval.val->sym->hasVargs;
1907 tree->args = copyValueChain (tree->opval.val->sym->args);
1917 /* if type link for the case of cast */
1918 if (tree->type == EX_LINK)
1920 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1927 dtl = decorateType (tree->left);
1928 dtr = decorateType (tree->right);
1930 /* this is to take care of situations
1931 when the tree gets rewritten */
1932 if (dtl != tree->left)
1934 if (dtr != tree->right)
1938 /* depending on type of operator do */
1940 switch (tree->opval.op)
1942 /*------------------------------------------------------------------*/
1943 /*----------------------------*/
1945 /*----------------------------*/
1948 /* determine which is the array & which the index */
1949 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1952 ast *tempTree = tree->left;
1953 tree->left = tree->right;
1954 tree->right = tempTree;
1957 /* first check if this is a array or a pointer */
1958 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1960 werror (E_NEED_ARRAY_PTR, "[]");
1961 goto errorTreeReturn;
1964 /* check if the type of the idx */
1965 if (!IS_INTEGRAL (RTYPE (tree)))
1967 werror (E_IDX_NOT_INT);
1968 goto errorTreeReturn;
1971 /* if the left is an rvalue then error */
1974 werror (E_LVALUE_REQUIRED, "array access");
1975 goto errorTreeReturn;
1978 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1979 if (IS_PTR(LTYPE(tree))) {
1980 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1984 /*------------------------------------------------------------------*/
1985 /*----------------------------*/
1987 /*----------------------------*/
1989 /* if this is not a structure */
1990 if (!IS_STRUCT (LTYPE (tree)))
1992 werror (E_STRUCT_UNION, ".");
1993 goto errorTreeReturn;
1995 TTYPE (tree) = structElemType (LTYPE (tree),
1996 (tree->right->type == EX_VALUE ?
1997 tree->right->opval.val : NULL), &tree->args);
1998 TETYPE (tree) = getSpec (TTYPE (tree));
2001 /*------------------------------------------------------------------*/
2002 /*----------------------------*/
2003 /* struct/union pointer */
2004 /*----------------------------*/
2006 /* if not pointer to a structure */
2007 if (!IS_PTR (LTYPE (tree)))
2009 werror (E_PTR_REQD);
2010 goto errorTreeReturn;
2013 if (!IS_STRUCT (LTYPE (tree)->next))
2015 werror (E_STRUCT_UNION, "->");
2016 goto errorTreeReturn;
2019 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2020 (tree->right->type == EX_VALUE ?
2021 tree->right->opval.val : NULL), &tree->args);
2022 TETYPE (tree) = getSpec (TTYPE (tree));
2025 /*------------------------------------------------------------------*/
2026 /*----------------------------*/
2027 /* ++/-- operation */
2028 /*----------------------------*/
2029 case INC_OP: /* incerement operator unary so left only */
2032 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2033 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2034 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
2035 werror (E_CODE_WRITE, "++/--");
2044 /*------------------------------------------------------------------*/
2045 /*----------------------------*/
2047 /*----------------------------*/
2048 case '&': /* can be unary */
2049 /* if right is NULL then unary operation */
2050 if (tree->right) /* not an unary operation */
2053 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2055 werror (E_BITWISE_OP);
2056 werror (E_CONTINUE, "left & right types are ");
2057 printTypeChain (LTYPE (tree), stderr);
2058 fprintf (stderr, ",");
2059 printTypeChain (RTYPE (tree), stderr);
2060 fprintf (stderr, "\n");
2061 goto errorTreeReturn;
2064 /* if they are both literal */
2065 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2067 tree->type = EX_VALUE;
2068 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2069 valFromType (RETYPE (tree)), '&');
2071 tree->right = tree->left = NULL;
2072 TETYPE (tree) = tree->opval.val->etype;
2073 TTYPE (tree) = tree->opval.val->type;
2077 /* see if this is a GETHBIT operation if yes
2080 ast *otree = optimizeGetHbit (tree);
2083 return decorateType (otree);
2087 // we can't do this because of "(int & 0xff) << 3"
2089 /* if right or left is literal then result of that type */
2090 if (IS_LITERAL (RTYPE (tree)))
2093 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2094 TETYPE (tree) = getSpec (TTYPE (tree));
2095 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2099 if (IS_LITERAL (LTYPE (tree)))
2101 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2102 TETYPE (tree) = getSpec (TTYPE (tree));
2103 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2109 computeType (LTYPE (tree), RTYPE (tree));
2110 TETYPE (tree) = getSpec (TTYPE (tree));
2115 computeType (LTYPE (tree), RTYPE (tree));
2116 TETYPE (tree) = getSpec (TTYPE (tree));
2118 LRVAL (tree) = RRVAL (tree) = 1;
2122 /*------------------------------------------------------------------*/
2123 /*----------------------------*/
2125 /*----------------------------*/
2127 p->class = DECLARATOR;
2128 /* if bit field then error */
2129 if (IS_BITVAR (tree->left->etype))
2131 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2132 goto errorTreeReturn;
2135 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2137 werror (E_ILLEGAL_ADDR, "address of register variable");
2138 goto errorTreeReturn;
2141 if (IS_FUNC (LTYPE (tree)))
2143 werror (E_ILLEGAL_ADDR, "address of function");
2144 goto errorTreeReturn;
2149 werror (E_LVALUE_REQUIRED, "address of");
2150 goto errorTreeReturn;
2152 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2154 DCL_TYPE (p) = CPOINTER;
2155 DCL_PTR_CONST (p) = port->mem.code_ro;
2157 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2158 DCL_TYPE (p) = FPOINTER;
2159 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2160 DCL_TYPE (p) = PPOINTER;
2161 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2162 DCL_TYPE (p) = IPOINTER;
2163 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2164 DCL_TYPE (p) = EEPPOINTER;
2166 DCL_TYPE (p) = POINTER;
2168 if (IS_AST_SYM_VALUE (tree->left))
2170 AST_SYMBOL (tree->left)->addrtaken = 1;
2171 AST_SYMBOL (tree->left)->allocreq = 1;
2174 p->next = LTYPE (tree);
2176 TETYPE (tree) = getSpec (TTYPE (tree));
2177 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2178 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2183 /*------------------------------------------------------------------*/
2184 /*----------------------------*/
2186 /*----------------------------*/
2188 /* if the rewrite succeeds then don't go any furthur */
2190 ast *wtree = optimizeRRCRLC (tree);
2192 return decorateType (wtree);
2194 /*------------------------------------------------------------------*/
2195 /*----------------------------*/
2197 /*----------------------------*/
2199 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2201 werror (E_BITWISE_OP);
2202 werror (E_CONTINUE, "left & right types are ");
2203 printTypeChain (LTYPE (tree), stderr);
2204 fprintf (stderr, ",");
2205 printTypeChain (RTYPE (tree), stderr);
2206 fprintf (stderr, "\n");
2207 goto errorTreeReturn;
2210 /* if they are both literal then */
2211 /* rewrite the tree */
2212 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2214 tree->type = EX_VALUE;
2215 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2216 valFromType (RETYPE (tree)),
2218 tree->right = tree->left = NULL;
2219 TETYPE (tree) = tree->opval.val->etype;
2220 TTYPE (tree) = tree->opval.val->type;
2223 LRVAL (tree) = RRVAL (tree) = 1;
2224 TETYPE (tree) = getSpec (TTYPE (tree) =
2225 computeType (LTYPE (tree),
2228 /*------------------------------------------------------------------*/
2229 /*----------------------------*/
2231 /*----------------------------*/
2233 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2235 werror (E_INVALID_OP, "divide");
2236 goto errorTreeReturn;
2238 /* if they are both literal then */
2239 /* rewrite the tree */
2240 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2242 tree->type = EX_VALUE;
2243 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2244 valFromType (RETYPE (tree)));
2245 tree->right = tree->left = NULL;
2246 TETYPE (tree) = getSpec (TTYPE (tree) =
2247 tree->opval.val->type);
2250 LRVAL (tree) = RRVAL (tree) = 1;
2251 TETYPE (tree) = getSpec (TTYPE (tree) =
2252 computeType (LTYPE (tree),
2256 /*------------------------------------------------------------------*/
2257 /*----------------------------*/
2259 /*----------------------------*/
2261 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2263 werror (E_BITWISE_OP);
2264 werror (E_CONTINUE, "left & right types are ");
2265 printTypeChain (LTYPE (tree), stderr);
2266 fprintf (stderr, ",");
2267 printTypeChain (RTYPE (tree), stderr);
2268 fprintf (stderr, "\n");
2269 goto errorTreeReturn;
2271 /* if they are both literal then */
2272 /* rewrite the tree */
2273 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2275 tree->type = EX_VALUE;
2276 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2277 valFromType (RETYPE (tree)));
2278 tree->right = tree->left = NULL;
2279 TETYPE (tree) = getSpec (TTYPE (tree) =
2280 tree->opval.val->type);
2283 LRVAL (tree) = RRVAL (tree) = 1;
2284 TETYPE (tree) = getSpec (TTYPE (tree) =
2285 computeType (LTYPE (tree),
2289 /*------------------------------------------------------------------*/
2290 /*----------------------------*/
2291 /* address dereference */
2292 /*----------------------------*/
2293 case '*': /* can be unary : if right is null then unary operation */
2296 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2298 werror (E_PTR_REQD);
2299 goto errorTreeReturn;
2304 werror (E_LVALUE_REQUIRED, "pointer deref");
2305 goto errorTreeReturn;
2307 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2308 LTYPE (tree)->next : NULL);
2309 TETYPE (tree) = getSpec (TTYPE (tree));
2310 tree->args = tree->left->args;
2311 tree->hasVargs = tree->left->hasVargs;
2312 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2316 /*------------------------------------------------------------------*/
2317 /*----------------------------*/
2318 /* multiplication */
2319 /*----------------------------*/
2320 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2322 werror (E_INVALID_OP, "multiplication");
2323 goto errorTreeReturn;
2326 /* if they are both literal then */
2327 /* rewrite the tree */
2328 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2330 tree->type = EX_VALUE;
2331 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2332 valFromType (RETYPE (tree)));
2333 tree->right = tree->left = NULL;
2334 TETYPE (tree) = getSpec (TTYPE (tree) =
2335 tree->opval.val->type);
2339 /* if left is a literal exchange left & right */
2340 if (IS_LITERAL (LTYPE (tree)))
2342 ast *tTree = tree->left;
2343 tree->left = tree->right;
2344 tree->right = tTree;
2347 LRVAL (tree) = RRVAL (tree) = 1;
2348 /* promote result to int if left & right are char
2349 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2350 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2351 TETYPE (tree) = getSpec (TTYPE (tree) =
2352 computeType (LTYPE (tree),
2354 SPEC_NOUN(TETYPE(tree)) = V_INT;
2356 TETYPE (tree) = getSpec (TTYPE (tree) =
2357 computeType (LTYPE (tree),
2362 /*------------------------------------------------------------------*/
2363 /*----------------------------*/
2364 /* unary '+' operator */
2365 /*----------------------------*/
2370 if (!IS_INTEGRAL (LTYPE (tree)))
2372 werror (E_UNARY_OP, '+');
2373 goto errorTreeReturn;
2376 /* if left is a literal then do it */
2377 if (IS_LITERAL (LTYPE (tree)))
2379 tree->type = EX_VALUE;
2380 tree->opval.val = valFromType (LETYPE (tree));
2382 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2386 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2390 /*------------------------------------------------------------------*/
2391 /*----------------------------*/
2393 /*----------------------------*/
2395 /* this is not a unary operation */
2396 /* if both pointers then problem */
2397 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2398 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2400 werror (E_PTR_PLUS_PTR);
2401 goto errorTreeReturn;
2404 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2405 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2407 werror (E_PLUS_INVALID, "+");
2408 goto errorTreeReturn;
2411 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2412 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2414 werror (E_PLUS_INVALID, "+");
2415 goto errorTreeReturn;
2417 /* if they are both literal then */
2418 /* rewrite the tree */
2419 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2421 tree->type = EX_VALUE;
2422 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2423 valFromType (RETYPE (tree)));
2424 tree->right = tree->left = NULL;
2425 TETYPE (tree) = getSpec (TTYPE (tree) =
2426 tree->opval.val->type);
2430 /* if the right is a pointer or left is a literal
2431 xchange left & right */
2432 if (IS_ARRAY (RTYPE (tree)) ||
2433 IS_PTR (RTYPE (tree)) ||
2434 IS_LITERAL (LTYPE (tree)))
2436 ast *tTree = tree->left;
2437 tree->left = tree->right;
2438 tree->right = tTree;
2441 LRVAL (tree) = RRVAL (tree) = 1;
2442 /* if the left is a pointer */
2443 if (IS_PTR (LTYPE (tree)))
2444 TETYPE (tree) = getSpec (TTYPE (tree) =
2447 TETYPE (tree) = getSpec (TTYPE (tree) =
2448 computeType (LTYPE (tree),
2452 /*------------------------------------------------------------------*/
2453 /*----------------------------*/
2455 /*----------------------------*/
2456 case '-': /* can be unary */
2457 /* if right is null then unary */
2461 if (!IS_ARITHMETIC (LTYPE (tree)))
2463 werror (E_UNARY_OP, tree->opval.op);
2464 goto errorTreeReturn;
2467 /* if left is a literal then do it */
2468 if (IS_LITERAL (LTYPE (tree)))
2470 tree->type = EX_VALUE;
2471 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2473 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2474 SPEC_USIGN(TETYPE(tree)) = 0;
2478 TTYPE (tree) = LTYPE (tree);
2482 /*------------------------------------------------------------------*/
2483 /*----------------------------*/
2485 /*----------------------------*/
2487 if (!(IS_PTR (LTYPE (tree)) ||
2488 IS_ARRAY (LTYPE (tree)) ||
2489 IS_ARITHMETIC (LTYPE (tree))))
2491 werror (E_PLUS_INVALID, "-");
2492 goto errorTreeReturn;
2495 if (!(IS_PTR (RTYPE (tree)) ||
2496 IS_ARRAY (RTYPE (tree)) ||
2497 IS_ARITHMETIC (RTYPE (tree))))
2499 werror (E_PLUS_INVALID, "-");
2500 goto errorTreeReturn;
2503 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2504 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2505 IS_INTEGRAL (RTYPE (tree))))
2507 werror (E_PLUS_INVALID, "-");
2508 goto errorTreeReturn;
2511 /* if they are both literal then */
2512 /* rewrite the tree */
2513 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2515 tree->type = EX_VALUE;
2516 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2517 valFromType (RETYPE (tree)));
2518 tree->right = tree->left = NULL;
2519 TETYPE (tree) = getSpec (TTYPE (tree) =
2520 tree->opval.val->type);
2524 /* if the left & right are equal then zero */
2525 if (isAstEqual (tree->left, tree->right))
2527 tree->type = EX_VALUE;
2528 tree->left = tree->right = NULL;
2529 tree->opval.val = constVal ("0");
2530 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2534 /* if both of them are pointers or arrays then */
2535 /* the result is going to be an integer */
2536 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2537 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2538 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2540 /* if only the left is a pointer */
2541 /* then result is a pointer */
2542 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2543 TETYPE (tree) = getSpec (TTYPE (tree) =
2546 TETYPE (tree) = getSpec (TTYPE (tree) =
2547 computeType (LTYPE (tree),
2549 LRVAL (tree) = RRVAL (tree) = 1;
2552 /*------------------------------------------------------------------*/
2553 /*----------------------------*/
2555 /*----------------------------*/
2557 /* can be only integral type */
2558 if (!IS_INTEGRAL (LTYPE (tree)))
2560 werror (E_UNARY_OP, tree->opval.op);
2561 goto errorTreeReturn;
2564 /* if left is a literal then do it */
2565 if (IS_LITERAL (LTYPE (tree)))
2567 tree->type = EX_VALUE;
2568 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2570 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2574 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2577 /*------------------------------------------------------------------*/
2578 /*----------------------------*/
2580 /*----------------------------*/
2582 /* can be pointer */
2583 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2584 !IS_PTR (LTYPE (tree)) &&
2585 !IS_ARRAY (LTYPE (tree)))
2587 werror (E_UNARY_OP, tree->opval.op);
2588 goto errorTreeReturn;
2591 /* if left is a literal then do it */
2592 if (IS_LITERAL (LTYPE (tree)))
2594 tree->type = EX_VALUE;
2595 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2597 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2601 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2604 /*------------------------------------------------------------------*/
2605 /*----------------------------*/
2607 /*----------------------------*/
2610 TTYPE (tree) = LTYPE (tree);
2611 TETYPE (tree) = LETYPE (tree);
2615 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2620 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2622 werror (E_SHIFT_OP_INVALID);
2623 werror (E_CONTINUE, "left & right types are ");
2624 printTypeChain (LTYPE (tree), stderr);
2625 fprintf (stderr, ",");
2626 printTypeChain (RTYPE (tree), stderr);
2627 fprintf (stderr, "\n");
2628 goto errorTreeReturn;
2631 /* if they are both literal then */
2632 /* rewrite the tree */
2633 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2635 tree->type = EX_VALUE;
2636 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2637 valFromType (RETYPE (tree)),
2638 (tree->opval.op == LEFT_OP ? 1 : 0));
2639 tree->right = tree->left = NULL;
2640 TETYPE (tree) = getSpec (TTYPE (tree) =
2641 tree->opval.val->type);
2644 /* if only the right side is a literal & we are
2645 shifting more than size of the left operand then zero */
2646 if (IS_LITERAL (RTYPE (tree)) &&
2647 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2648 (getSize (LTYPE (tree)) * 8))
2650 werror (W_SHIFT_CHANGED,
2651 (tree->opval.op == LEFT_OP ? "left" : "right"));
2652 tree->type = EX_VALUE;
2653 tree->left = tree->right = NULL;
2654 tree->opval.val = constVal ("0");
2655 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2658 LRVAL (tree) = RRVAL (tree) = 1;
2659 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2661 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2665 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2669 /*------------------------------------------------------------------*/
2670 /*----------------------------*/
2672 /*----------------------------*/
2673 case CAST: /* change the type */
2674 /* cannot cast to an aggregate type */
2675 if (IS_AGGREGATE (LTYPE (tree)))
2677 werror (E_CAST_ILLEGAL);
2678 goto errorTreeReturn;
2681 /* make sure the type is complete and sane */
2682 checkTypeSanity(LETYPE(tree), "(cast)");
2684 /* if the right is a literal replace the tree */
2685 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2687 tree->type = EX_VALUE;
2689 valCastLiteral (LTYPE (tree),
2690 floatFromVal (valFromType (RETYPE (tree))));
2693 TTYPE (tree) = tree->opval.val->type;
2694 tree->values.literalFromCast = 1;
2698 TTYPE (tree) = LTYPE (tree);
2702 TETYPE (tree) = getSpec (TTYPE (tree));
2706 /*------------------------------------------------------------------*/
2707 /*----------------------------*/
2708 /* logical &&, || */
2709 /*----------------------------*/
2712 /* each must me arithmetic type or be a pointer */
2713 if (!IS_PTR (LTYPE (tree)) &&
2714 !IS_ARRAY (LTYPE (tree)) &&
2715 !IS_INTEGRAL (LTYPE (tree)))
2717 werror (E_COMPARE_OP);
2718 goto errorTreeReturn;
2721 if (!IS_PTR (RTYPE (tree)) &&
2722 !IS_ARRAY (RTYPE (tree)) &&
2723 !IS_INTEGRAL (RTYPE (tree)))
2725 werror (E_COMPARE_OP);
2726 goto errorTreeReturn;
2728 /* if they are both literal then */
2729 /* rewrite the tree */
2730 if (IS_LITERAL (RTYPE (tree)) &&
2731 IS_LITERAL (LTYPE (tree)))
2733 tree->type = EX_VALUE;
2734 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2735 valFromType (RETYPE (tree)),
2737 tree->right = tree->left = NULL;
2738 TETYPE (tree) = getSpec (TTYPE (tree) =
2739 tree->opval.val->type);
2742 LRVAL (tree) = RRVAL (tree) = 1;
2743 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2746 /*------------------------------------------------------------------*/
2747 /*----------------------------*/
2748 /* comparison operators */
2749 /*----------------------------*/
2757 ast *lt = optimizeCompare (tree);
2763 /* if they are pointers they must be castable */
2764 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2766 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2768 werror (E_COMPARE_OP);
2769 fprintf (stderr, "comparing type ");
2770 printTypeChain (LTYPE (tree), stderr);
2771 fprintf (stderr, "to type ");
2772 printTypeChain (RTYPE (tree), stderr);
2773 fprintf (stderr, "\n");
2774 goto errorTreeReturn;
2777 /* else they should be promotable to one another */
2780 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2781 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2783 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2785 werror (E_COMPARE_OP);
2786 fprintf (stderr, "comparing type ");
2787 printTypeChain (LTYPE (tree), stderr);
2788 fprintf (stderr, "to type ");
2789 printTypeChain (RTYPE (tree), stderr);
2790 fprintf (stderr, "\n");
2791 goto errorTreeReturn;
2795 /* if they are both literal then */
2796 /* rewrite the tree */
2797 if (IS_LITERAL (RTYPE (tree)) &&
2798 IS_LITERAL (LTYPE (tree)))
2800 tree->type = EX_VALUE;
2801 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2802 valFromType (RETYPE (tree)),
2804 tree->right = tree->left = NULL;
2805 TETYPE (tree) = getSpec (TTYPE (tree) =
2806 tree->opval.val->type);
2809 LRVAL (tree) = RRVAL (tree) = 1;
2810 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2813 /*------------------------------------------------------------------*/
2814 /*----------------------------*/
2816 /*----------------------------*/
2817 case SIZEOF: /* evaluate wihout code generation */
2818 /* change the type to a integer */
2819 tree->type = EX_VALUE;
2820 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2821 tree->opval.val = constVal (buffer);
2822 tree->right = tree->left = NULL;
2823 TETYPE (tree) = getSpec (TTYPE (tree) =
2824 tree->opval.val->type);
2827 /*------------------------------------------------------------------*/
2828 /*----------------------------*/
2829 /* conditional operator '?' */
2830 /*----------------------------*/
2832 /* the type is value of the colon operator (on the right) */
2833 assert(IS_COLON_OP(tree->right));
2834 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2835 TETYPE (tree) = getSpec (TTYPE (tree));
2839 /* if they don't match we have a problem */
2840 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2842 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2843 goto errorTreeReturn;
2846 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2847 TETYPE (tree) = getSpec (TTYPE (tree));
2851 /*------------------------------------------------------------------*/
2852 /*----------------------------*/
2853 /* assignment operators */
2854 /*----------------------------*/
2857 /* for these it must be both must be integral */
2858 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2859 !IS_ARITHMETIC (RTYPE (tree)))
2861 werror (E_OPS_INTEGRAL);
2862 goto errorTreeReturn;
2865 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2867 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2868 werror (E_CODE_WRITE, " ");
2872 werror (E_LVALUE_REQUIRED, "*= or /=");
2873 goto errorTreeReturn;
2886 /* for these it must be both must be integral */
2887 if (!IS_INTEGRAL (LTYPE (tree)) ||
2888 !IS_INTEGRAL (RTYPE (tree)))
2890 werror (E_OPS_INTEGRAL);
2891 goto errorTreeReturn;
2894 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2896 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2897 werror (E_CODE_WRITE, " ");
2901 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2902 goto errorTreeReturn;
2910 /*------------------------------------------------------------------*/
2911 /*----------------------------*/
2913 /*----------------------------*/
2915 if (!(IS_PTR (LTYPE (tree)) ||
2916 IS_ARITHMETIC (LTYPE (tree))))
2918 werror (E_PLUS_INVALID, "-=");
2919 goto errorTreeReturn;
2922 if (!(IS_PTR (RTYPE (tree)) ||
2923 IS_ARITHMETIC (RTYPE (tree))))
2925 werror (E_PLUS_INVALID, "-=");
2926 goto errorTreeReturn;
2929 TETYPE (tree) = getSpec (TTYPE (tree) =
2930 computeType (LTYPE (tree),
2933 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2934 werror (E_CODE_WRITE, " ");
2938 werror (E_LVALUE_REQUIRED, "-=");
2939 goto errorTreeReturn;
2947 /*------------------------------------------------------------------*/
2948 /*----------------------------*/
2950 /*----------------------------*/
2952 /* this is not a unary operation */
2953 /* if both pointers then problem */
2954 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2956 werror (E_PTR_PLUS_PTR);
2957 goto errorTreeReturn;
2960 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2962 werror (E_PLUS_INVALID, "+=");
2963 goto errorTreeReturn;
2966 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2968 werror (E_PLUS_INVALID, "+=");
2969 goto errorTreeReturn;
2972 TETYPE (tree) = getSpec (TTYPE (tree) =
2973 computeType (LTYPE (tree),
2976 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2977 werror (E_CODE_WRITE, " ");
2981 werror (E_LVALUE_REQUIRED, "+=");
2982 goto errorTreeReturn;
2985 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2986 tree->opval.op = '=';
2992 /*------------------------------------------------------------------*/
2993 /*----------------------------*/
2994 /* straight assignemnt */
2995 /*----------------------------*/
2997 /* cannot be an aggregate */
2998 if (IS_AGGREGATE (LTYPE (tree)))
3000 werror (E_AGGR_ASSIGN);
3001 goto errorTreeReturn;
3004 /* they should either match or be castable */
3005 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3007 werror (E_TYPE_MISMATCH, "assignment", " ");
3008 fprintf (stderr, "type --> '");
3009 printTypeChain (RTYPE (tree), stderr);
3010 fprintf (stderr, "' ");
3011 fprintf (stderr, "assigned to type --> '");
3012 printTypeChain (LTYPE (tree), stderr);
3013 fprintf (stderr, "'\n");
3014 goto errorTreeReturn;
3017 /* if the left side of the tree is of type void
3018 then report error */
3019 if (IS_VOID (LTYPE (tree)))
3021 werror (E_CAST_ZERO);
3022 fprintf (stderr, "type --> '");
3023 printTypeChain (RTYPE (tree), stderr);
3024 fprintf (stderr, "' ");
3025 fprintf (stderr, "assigned to type --> '");
3026 printTypeChain (LTYPE (tree), stderr);
3027 fprintf (stderr, "'\n");
3030 /* extra checks for pointer types */
3031 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
3032 !IS_GENPTR (LTYPE (tree)))
3034 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
3035 werror (W_PTR_ASSIGN);
3038 TETYPE (tree) = getSpec (TTYPE (tree) =
3042 if (!tree->initMode ) {
3043 if (IS_CONSTANT (LETYPE (tree))) {
3044 werror (E_CODE_WRITE, " ");
3049 werror (E_LVALUE_REQUIRED, "=");
3050 goto errorTreeReturn;
3057 /*------------------------------------------------------------------*/
3058 /*----------------------------*/
3059 /* comma operator */
3060 /*----------------------------*/
3062 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3068 /*----------------------------*/
3072 if (processParms (tree->left,
3074 tree->right, &parmNumber, TRUE))
3075 goto errorTreeReturn;
3077 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3079 tree->left->args = reverseVal (tree->left->args);
3080 reverseParms (tree->right);
3083 tree->args = tree->left->args;
3084 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3087 /*------------------------------------------------------------------*/
3088 /*----------------------------*/
3089 /* return statement */
3090 /*----------------------------*/
3095 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3097 werror (E_RETURN_MISMATCH);
3098 goto errorTreeReturn;
3101 if (IS_VOID (currFunc->type->next)
3103 !IS_VOID (RTYPE (tree)))
3105 werror (E_FUNC_VOID);
3106 goto errorTreeReturn;
3109 /* if there is going to be a casing required then add it */
3110 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3112 #if 0 && defined DEMAND_INTEGER_PROMOTION
3113 if (IS_INTEGRAL (currFunc->type->next))
3115 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3121 decorateType (newNode (CAST,
3122 newAst_LINK (copyLinkChain (currFunc->type->next)),
3132 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3134 werror (E_VOID_FUNC, currFunc->name);
3135 goto errorTreeReturn;
3138 TTYPE (tree) = TETYPE (tree) = NULL;
3141 /*------------------------------------------------------------------*/
3142 /*----------------------------*/
3143 /* switch statement */
3144 /*----------------------------*/
3146 /* the switch value must be an integer */
3147 if (!IS_INTEGRAL (LTYPE (tree)))
3149 werror (E_SWITCH_NON_INTEGER);
3150 goto errorTreeReturn;
3153 TTYPE (tree) = TETYPE (tree) = NULL;
3156 /*------------------------------------------------------------------*/
3157 /*----------------------------*/
3159 /*----------------------------*/
3161 tree->left = backPatchLabels (tree->left,
3164 TTYPE (tree) = TETYPE (tree) = NULL;
3167 /*------------------------------------------------------------------*/
3168 /*----------------------------*/
3170 /*----------------------------*/
3173 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3174 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3175 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3177 /* if the for loop is reversible then
3178 reverse it otherwise do what we normally
3184 if (isLoopReversible (tree, &sym, &init, &end))
3185 return reverseLoop (tree, sym, init, end);
3187 return decorateType (createFor (AST_FOR (tree, trueLabel),
3188 AST_FOR (tree, continueLabel),
3189 AST_FOR (tree, falseLabel),
3190 AST_FOR (tree, condLabel),
3191 AST_FOR (tree, initExpr),
3192 AST_FOR (tree, condExpr),
3193 AST_FOR (tree, loopExpr),
3197 TTYPE (tree) = TETYPE (tree) = NULL;
3201 /* some error found this tree will be killed */
3203 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3204 tree->opval.op = NULLOP;
3210 /*-----------------------------------------------------------------*/
3211 /* sizeofOp - processes size of operation */
3212 /*-----------------------------------------------------------------*/
3214 sizeofOp (sym_link * type)
3218 /* make sure the type is complete and sane */
3219 checkTypeSanity(type, "(sizeof)");
3221 /* get the size and convert it to character */
3222 sprintf (buff, "%d", getSize (type));
3224 /* now convert into value */
3225 return constVal (buff);
3229 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3230 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3231 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3232 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3233 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3234 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3235 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3237 /*-----------------------------------------------------------------*/
3238 /* backPatchLabels - change and or not operators to flow control */
3239 /*-----------------------------------------------------------------*/
3241 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3247 if (!(IS_ANDORNOT (tree)))
3250 /* if this an and */
3253 static int localLbl = 0;
3256 sprintf (buffer, "_and_%d", localLbl++);
3257 localLabel = newSymbol (buffer, NestLevel);
3259 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3261 /* if left is already a IFX then just change the if true label in that */
3262 if (!IS_IFX (tree->left))
3263 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3265 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3266 /* right is a IFX then just join */
3267 if (IS_IFX (tree->right))
3268 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3270 tree->right = createLabel (localLabel, tree->right);
3271 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3273 return newNode (NULLOP, tree->left, tree->right);
3276 /* if this is an or operation */
3279 static int localLbl = 0;
3282 sprintf (buffer, "_or_%d", localLbl++);
3283 localLabel = newSymbol (buffer, NestLevel);
3285 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3287 /* if left is already a IFX then just change the if true label in that */
3288 if (!IS_IFX (tree->left))
3289 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3291 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3292 /* right is a IFX then just join */
3293 if (IS_IFX (tree->right))
3294 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3296 tree->right = createLabel (localLabel, tree->right);
3297 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3299 return newNode (NULLOP, tree->left, tree->right);
3305 int wasnot = IS_NOT (tree->left);
3306 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3308 /* if the left is already a IFX */
3309 if (!IS_IFX (tree->left))
3310 tree->left = newNode (IFX, tree->left, NULL);
3314 tree->left->trueLabel = trueLabel;
3315 tree->left->falseLabel = falseLabel;
3319 tree->left->trueLabel = falseLabel;
3320 tree->left->falseLabel = trueLabel;
3327 tree->trueLabel = trueLabel;
3328 tree->falseLabel = falseLabel;
3335 /*-----------------------------------------------------------------*/
3336 /* createBlock - create expression tree for block */
3337 /*-----------------------------------------------------------------*/
3339 createBlock (symbol * decl, ast * body)
3343 /* if the block has nothing */
3347 ex = newNode (BLOCK, NULL, body);
3348 ex->values.sym = decl;
3350 ex->right = ex->right;
3356 /*-----------------------------------------------------------------*/
3357 /* createLabel - creates the expression tree for labels */
3358 /*-----------------------------------------------------------------*/
3360 createLabel (symbol * label, ast * stmnt)
3363 char name[SDCC_NAME_MAX + 1];
3366 /* must create fresh symbol if the symbol name */
3367 /* exists in the symbol table, since there can */
3368 /* be a variable with the same name as the labl */
3369 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3370 (csym->level == label->level))
3371 label = newSymbol (label->name, label->level);
3373 /* change the name before putting it in add _ */
3374 sprintf (name, "%s", label->name);
3376 /* put the label in the LabelSymbol table */
3377 /* but first check if a label of the same */
3379 if ((csym = findSym (LabelTab, NULL, name)))
3380 werror (E_DUPLICATE_LABEL, label->name);
3382 addSym (LabelTab, label, name, label->level, 0, 0);
3385 label->key = labelKey++;
3386 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3392 /*-----------------------------------------------------------------*/
3393 /* createCase - generates the parsetree for a case statement */
3394 /*-----------------------------------------------------------------*/
3396 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3398 char caseLbl[SDCC_NAME_MAX + 1];
3402 /* if the switch statement does not exist */
3403 /* then case is out of context */
3406 werror (E_CASE_CONTEXT);
3410 caseVal = decorateType (resolveSymbols (caseVal));
3411 /* if not a constant then error */
3412 if (!IS_LITERAL (caseVal->ftype))
3414 werror (E_CASE_CONSTANT);
3418 /* if not a integer than error */
3419 if (!IS_INTEGRAL (caseVal->ftype))
3421 werror (E_CASE_NON_INTEGER);
3425 /* find the end of the switch values chain */
3426 if (!(val = swStat->values.switchVals.swVals))
3427 swStat->values.switchVals.swVals = caseVal->opval.val;
3430 /* also order the cases according to value */
3432 int cVal = (int) floatFromVal (caseVal->opval.val);
3433 while (val && (int) floatFromVal (val) < cVal)
3439 /* if we reached the end then */
3442 pval->next = caseVal->opval.val;
3446 /* we found a value greater than */
3447 /* the current value we must add this */
3448 /* before the value */
3449 caseVal->opval.val->next = val;
3451 /* if this was the first in chain */
3452 if (swStat->values.switchVals.swVals == val)
3453 swStat->values.switchVals.swVals =
3456 pval->next = caseVal->opval.val;
3461 /* create the case label */
3462 sprintf (caseLbl, "_case_%d_%d",
3463 swStat->values.switchVals.swNum,
3464 (int) floatFromVal (caseVal->opval.val));
3466 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3471 /*-----------------------------------------------------------------*/
3472 /* createDefault - creates the parse tree for the default statement */
3473 /*-----------------------------------------------------------------*/
3475 createDefault (ast * swStat, ast * stmnt)
3477 char defLbl[SDCC_NAME_MAX + 1];
3479 /* if the switch statement does not exist */
3480 /* then case is out of context */
3483 werror (E_CASE_CONTEXT);
3487 /* turn on the default flag */
3488 swStat->values.switchVals.swDefault = 1;
3490 /* create the label */
3491 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3492 return createLabel (newSymbol (defLbl, 0), stmnt);
3495 /*-----------------------------------------------------------------*/
3496 /* createIf - creates the parsetree for the if statement */
3497 /*-----------------------------------------------------------------*/
3499 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3501 static int Lblnum = 0;
3503 symbol *ifTrue, *ifFalse, *ifEnd;
3505 /* if neither exists */
3506 if (!elseBody && !ifBody)
3509 /* create the labels */
3510 sprintf (buffer, "_iffalse_%d", Lblnum);
3511 ifFalse = newSymbol (buffer, NestLevel);
3512 /* if no else body then end == false */
3517 sprintf (buffer, "_ifend_%d", Lblnum);
3518 ifEnd = newSymbol (buffer, NestLevel);
3521 sprintf (buffer, "_iftrue_%d", Lblnum);
3522 ifTrue = newSymbol (buffer, NestLevel);
3526 /* attach the ifTrue label to the top of it body */
3527 ifBody = createLabel (ifTrue, ifBody);
3528 /* attach a goto end to the ifBody if else is present */
3531 ifBody = newNode (NULLOP, ifBody,
3533 newAst_VALUE (symbolVal (ifEnd)),
3535 /* put the elseLabel on the else body */
3536 elseBody = createLabel (ifFalse, elseBody);
3537 /* out the end at the end of the body */
3538 elseBody = newNode (NULLOP,
3540 createLabel (ifEnd, NULL));
3544 ifBody = newNode (NULLOP, ifBody,
3545 createLabel (ifFalse, NULL));
3547 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3548 if (IS_IFX (condAst))
3551 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3553 return newNode (NULLOP, ifTree,
3554 newNode (NULLOP, ifBody, elseBody));
3558 /*-----------------------------------------------------------------*/
3559 /* createDo - creates parse tree for do */
3562 /* _docontinue_n: */
3563 /* condition_expression +-> trueLabel -> _dobody_n */
3565 /* +-> falseLabel-> _dobreak_n */
3567 /*-----------------------------------------------------------------*/
3569 createDo (symbol * trueLabel, symbol * continueLabel,
3570 symbol * falseLabel, ast * condAst, ast * doBody)
3575 /* if the body does not exist then it is simple */
3578 condAst = backPatchLabels (condAst, continueLabel, NULL);
3579 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3580 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3581 doTree->trueLabel = continueLabel;
3582 doTree->falseLabel = NULL;
3586 /* otherwise we have a body */
3587 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3589 /* attach the body label to the top */
3590 doBody = createLabel (trueLabel, doBody);
3591 /* attach the continue label to end of body */
3592 doBody = newNode (NULLOP, doBody,
3593 createLabel (continueLabel, NULL));
3595 /* now put the break label at the end */
3596 if (IS_IFX (condAst))
3599 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3601 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3603 /* putting it together */
3604 return newNode (NULLOP, doBody, doTree);
3607 /*-----------------------------------------------------------------*/
3608 /* createFor - creates parse tree for 'for' statement */
3611 /* condExpr +-> trueLabel -> _forbody_n */
3613 /* +-> falseLabel-> _forbreak_n */
3616 /* _forcontinue_n: */
3618 /* goto _forcond_n ; */
3620 /*-----------------------------------------------------------------*/
3622 createFor (symbol * trueLabel, symbol * continueLabel,
3623 symbol * falseLabel, symbol * condLabel,
3624 ast * initExpr, ast * condExpr, ast * loopExpr,
3629 /* if loopexpression not present then we can generate it */
3630 /* the same way as a while */
3632 return newNode (NULLOP, initExpr,
3633 createWhile (trueLabel, continueLabel,
3634 falseLabel, condExpr, forBody));
3635 /* vanilla for statement */
3636 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3638 if (condExpr && !IS_IFX (condExpr))
3639 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3642 /* attach condition label to condition */
3643 condExpr = createLabel (condLabel, condExpr);
3645 /* attach body label to body */
3646 forBody = createLabel (trueLabel, forBody);
3648 /* attach continue to forLoop expression & attach */
3649 /* goto the forcond @ and of loopExpression */
3650 loopExpr = createLabel (continueLabel,
3654 newAst_VALUE (symbolVal (condLabel)),
3656 /* now start putting them together */
3657 forTree = newNode (NULLOP, initExpr, condExpr);
3658 forTree = newNode (NULLOP, forTree, forBody);
3659 forTree = newNode (NULLOP, forTree, loopExpr);
3660 /* finally add the break label */
3661 forTree = newNode (NULLOP, forTree,
3662 createLabel (falseLabel, NULL));
3666 /*-----------------------------------------------------------------*/
3667 /* createWhile - creates parse tree for while statement */
3668 /* the while statement will be created as follows */
3670 /* _while_continue_n: */
3671 /* condition_expression +-> trueLabel -> _while_boby_n */
3673 /* +-> falseLabel -> _while_break_n */
3674 /* _while_body_n: */
3676 /* goto _while_continue_n */
3677 /* _while_break_n: */
3678 /*-----------------------------------------------------------------*/
3680 createWhile (symbol * trueLabel, symbol * continueLabel,
3681 symbol * falseLabel, ast * condExpr, ast * whileBody)
3685 /* put the continue label */
3686 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3687 condExpr = createLabel (continueLabel, condExpr);
3688 condExpr->lineno = 0;
3690 /* put the body label in front of the body */
3691 whileBody = createLabel (trueLabel, whileBody);
3692 whileBody->lineno = 0;
3693 /* put a jump to continue at the end of the body */
3694 /* and put break label at the end of the body */
3695 whileBody = newNode (NULLOP,
3698 newAst_VALUE (symbolVal (continueLabel)),
3699 createLabel (falseLabel, NULL)));
3701 /* put it all together */
3702 if (IS_IFX (condExpr))
3703 whileTree = condExpr;
3706 whileTree = newNode (IFX, condExpr, NULL);
3707 /* put the true & false labels in place */
3708 whileTree->trueLabel = trueLabel;
3709 whileTree->falseLabel = falseLabel;
3712 return newNode (NULLOP, whileTree, whileBody);
3715 /*-----------------------------------------------------------------*/
3716 /* optimizeGetHbit - get highest order bit of the expression */
3717 /*-----------------------------------------------------------------*/
3719 optimizeGetHbit (ast * tree)
3722 /* if this is not a bit and */
3723 if (!IS_BITAND (tree))
3726 /* will look for tree of the form
3727 ( expr >> ((sizeof expr) -1) ) & 1 */
3728 if (!IS_AST_LIT_VALUE (tree->right))
3731 if (AST_LIT_VALUE (tree->right) != 1)
3734 if (!IS_RIGHT_OP (tree->left))
3737 if (!IS_AST_LIT_VALUE (tree->left->right))
3740 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3741 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3744 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3748 /*-----------------------------------------------------------------*/
3749 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3750 /*-----------------------------------------------------------------*/
3752 optimizeRRCRLC (ast * root)
3754 /* will look for trees of the form
3755 (?expr << 1) | (?expr >> 7) or
3756 (?expr >> 7) | (?expr << 1) will make that
3757 into a RLC : operation ..
3759 (?expr >> 1) | (?expr << 7) or
3760 (?expr << 7) | (?expr >> 1) will make that
3761 into a RRC operation
3762 note : by 7 I mean (number of bits required to hold the
3764 /* if the root operations is not a | operation the not */
3765 if (!IS_BITOR (root))
3768 /* I have to think of a better way to match patterns this sucks */
3769 /* that aside let start looking for the first case : I use a the
3770 negative check a lot to improve the efficiency */
3771 /* (?expr << 1) | (?expr >> 7) */
3772 if (IS_LEFT_OP (root->left) &&
3773 IS_RIGHT_OP (root->right))
3776 if (!SPEC_USIGN (TETYPE (root->left->left)))
3779 if (!IS_AST_LIT_VALUE (root->left->right) ||
3780 !IS_AST_LIT_VALUE (root->right->right))
3783 /* make sure it is the same expression */
3784 if (!isAstEqual (root->left->left,
3788 if (AST_LIT_VALUE (root->left->right) != 1)
3791 if (AST_LIT_VALUE (root->right->right) !=
3792 (getSize (TTYPE (root->left->left)) * 8 - 1))
3795 /* whew got the first case : create the AST */
3796 return newNode (RLC, root->left->left, NULL);
3800 /* check for second case */
3801 /* (?expr >> 7) | (?expr << 1) */
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->right->right) != 1)
3821 if (AST_LIT_VALUE (root->left->right) !=
3822 (getSize (TTYPE (root->left->left)) * 8 - 1))
3825 /* whew got the first case : create the AST */
3826 return newNode (RLC, root->left->left, NULL);
3831 /* third case for RRC */
3832 /* (?symbol >> 1) | (?symbol << 7) */
3833 if (IS_LEFT_OP (root->right) &&
3834 IS_RIGHT_OP (root->left))
3837 if (!SPEC_USIGN (TETYPE (root->left->left)))
3840 if (!IS_AST_LIT_VALUE (root->left->right) ||
3841 !IS_AST_LIT_VALUE (root->right->right))
3844 /* make sure it is the same symbol */
3845 if (!isAstEqual (root->left->left,
3849 if (AST_LIT_VALUE (root->left->right) != 1)
3852 if (AST_LIT_VALUE (root->right->right) !=
3853 (getSize (TTYPE (root->left->left)) * 8 - 1))
3856 /* whew got the first case : create the AST */
3857 return newNode (RRC, root->left->left, NULL);
3861 /* fourth and last case for now */
3862 /* (?symbol << 7) | (?symbol >> 1) */
3863 if (IS_RIGHT_OP (root->right) &&
3864 IS_LEFT_OP (root->left))
3867 if (!SPEC_USIGN (TETYPE (root->left->left)))
3870 if (!IS_AST_LIT_VALUE (root->left->right) ||
3871 !IS_AST_LIT_VALUE (root->right->right))
3874 /* make sure it is the same symbol */
3875 if (!isAstEqual (root->left->left,
3879 if (AST_LIT_VALUE (root->right->right) != 1)
3882 if (AST_LIT_VALUE (root->left->right) !=
3883 (getSize (TTYPE (root->left->left)) * 8 - 1))
3886 /* whew got the first case : create the AST */
3887 return newNode (RRC, root->left->left, NULL);
3891 /* not found return root */
3895 /*-----------------------------------------------------------------*/
3896 /* optimizeCompare - otimizes compares for bit variables */
3897 /*-----------------------------------------------------------------*/
3899 optimizeCompare (ast * root)
3901 ast *optExpr = NULL;
3904 unsigned int litValue;
3906 /* if nothing then return nothing */
3910 /* if not a compare op then do leaves */
3911 if (!IS_COMPARE_OP (root))
3913 root->left = optimizeCompare (root->left);
3914 root->right = optimizeCompare (root->right);
3918 /* if left & right are the same then depending
3919 of the operation do */
3920 if (isAstEqual (root->left, root->right))
3922 switch (root->opval.op)
3927 optExpr = newAst_VALUE (constVal ("0"));
3932 optExpr = newAst_VALUE (constVal ("1"));
3936 return decorateType (optExpr);
3939 vleft = (root->left->type == EX_VALUE ?
3940 root->left->opval.val : NULL);
3942 vright = (root->right->type == EX_VALUE ?
3943 root->right->opval.val : NULL);
3945 /* if left is a BITVAR in BITSPACE */
3946 /* and right is a LITERAL then opt- */
3947 /* imize else do nothing */
3948 if (vleft && vright &&
3949 IS_BITVAR (vleft->etype) &&
3950 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3951 IS_LITERAL (vright->etype))
3954 /* if right side > 1 then comparison may never succeed */
3955 if ((litValue = (int) floatFromVal (vright)) > 1)
3957 werror (W_BAD_COMPARE);
3963 switch (root->opval.op)
3965 case '>': /* bit value greater than 1 cannot be */
3966 werror (W_BAD_COMPARE);
3970 case '<': /* bit value < 1 means 0 */
3972 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3975 case LE_OP: /* bit value <= 1 means no check */
3976 optExpr = newAst_VALUE (vright);
3979 case GE_OP: /* bit value >= 1 means only check for = */
3981 optExpr = newAst_VALUE (vleft);
3986 { /* literal is zero */
3987 switch (root->opval.op)
3989 case '<': /* bit value < 0 cannot be */
3990 werror (W_BAD_COMPARE);
3994 case '>': /* bit value > 0 means 1 */
3996 optExpr = newAst_VALUE (vleft);
3999 case LE_OP: /* bit value <= 0 means no check */
4000 case GE_OP: /* bit value >= 0 means no check */
4001 werror (W_BAD_COMPARE);
4005 case EQ_OP: /* bit == 0 means ! of bit */
4006 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4010 return decorateType (resolveSymbols (optExpr));
4011 } /* end-of-if of BITVAR */
4016 /*-----------------------------------------------------------------*/
4017 /* addSymToBlock : adds the symbol to the first block we find */
4018 /*-----------------------------------------------------------------*/
4020 addSymToBlock (symbol * sym, ast * tree)
4022 /* reached end of tree or a leaf */
4023 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4027 if (IS_AST_OP (tree) &&
4028 tree->opval.op == BLOCK)
4031 symbol *lsym = copySymbol (sym);
4033 lsym->next = AST_VALUES (tree, sym);
4034 AST_VALUES (tree, sym) = lsym;
4038 addSymToBlock (sym, tree->left);
4039 addSymToBlock (sym, tree->right);
4042 /*-----------------------------------------------------------------*/
4043 /* processRegParms - do processing for register parameters */
4044 /*-----------------------------------------------------------------*/
4046 processRegParms (value * args, ast * body)
4050 if (IS_REGPARM (args->etype))
4051 addSymToBlock (args->sym, body);
4056 /*-----------------------------------------------------------------*/
4057 /* resetParmKey - resets the operandkeys for the symbols */
4058 /*-----------------------------------------------------------------*/
4059 DEFSETFUNC (resetParmKey)
4070 /*-----------------------------------------------------------------*/
4071 /* createFunction - This is the key node that calls the iCode for */
4072 /* generating the code for a function. Note code */
4073 /* is generated function by function, later when */
4074 /* add inter-procedural analysis this will change */
4075 /*-----------------------------------------------------------------*/
4077 createFunction (symbol * name, ast * body)
4083 iCode *piCode = NULL;
4085 /* if check function return 0 then some problem */
4086 if (checkFunction (name) == 0)
4089 /* create a dummy block if none exists */
4091 body = newNode (BLOCK, NULL, NULL);
4095 /* check if the function name already in the symbol table */
4096 if ((csym = findSym (SymbolTab, NULL, name->name)))
4099 /* special case for compiler defined functions
4100 we need to add the name to the publics list : this
4101 actually means we are now compiling the compiler
4105 addSet (&publics, name);
4111 allocVariables (name);
4113 name->lastLine = yylineno;
4115 processFuncArgs (currFunc, 0);
4117 /* set the stack pointer */
4118 /* PENDING: check this for the mcs51 */
4119 stackPtr = -port->stack.direction * port->stack.call_overhead;
4120 if (IS_ISR (name->etype))
4121 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4122 if (IS_RENT (name->etype) || options.stackAuto)
4123 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4125 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4127 fetype = getSpec (name->type); /* get the specifier for the function */
4128 /* if this is a reentrant function then */
4129 if (IS_RENT (fetype))
4132 allocParms (name->args); /* allocate the parameters */
4134 /* do processing for parameters that are passed in registers */
4135 processRegParms (name->args, body);
4137 /* set the stack pointer */
4141 /* allocate & autoinit the block variables */
4142 processBlockVars (body, &stack, ALLOCATE);
4144 /* save the stack information */
4145 if (options.useXstack)
4146 name->xstack = SPEC_STAK (fetype) = stack;
4148 name->stack = SPEC_STAK (fetype) = stack;
4150 /* name needs to be mangled */
4151 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4153 body = resolveSymbols (body); /* resolve the symbols */
4154 body = decorateType (body); /* propagateType & do semantic checks */
4156 ex = newAst_VALUE (symbolVal (name)); /* create name */
4157 ex = newNode (FUNCTION, ex, body);
4158 ex->values.args = name->args;
4162 werror (E_FUNC_NO_CODE, name->name);
4166 /* create the node & generate intermediate code */
4168 codeOutFile = code->oFile;
4169 piCode = iCodeFromAst (ex);
4173 werror (E_FUNC_NO_CODE, name->name);
4177 eBBlockFromiCode (piCode);
4179 /* if there are any statics then do them */
4182 GcurMemmap = statsg;
4183 codeOutFile = statsg->oFile;
4184 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4190 /* dealloc the block variables */
4191 processBlockVars (body, &stack, DEALLOCATE);
4192 /* deallocate paramaters */
4193 deallocParms (name->args);
4195 if (IS_RENT (fetype))
4198 /* we are done freeup memory & cleanup */
4203 addSet (&operKeyReset, name);
4204 applyToSet (operKeyReset, resetParmKey);
4207 cdbStructBlock (1, cdbFile);
4209 cleanUpLevel (LabelTab, 0);
4210 cleanUpBlock (StructTab, 1);
4211 cleanUpBlock (TypedefTab, 1);
4213 xstack->syms = NULL;
4214 istack->syms = NULL;
4219 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4220 /*-----------------------------------------------------------------*/
4221 /* ast_print : prints the ast (for debugging purposes) */
4222 /*-----------------------------------------------------------------*/
4224 void ast_print (ast * tree, FILE *outfile, int indent)
4229 /* can print only decorated trees */
4230 if (!tree->decorated) return;
4232 /* if any child is an error | this one is an error do nothing */
4233 if (tree->isError ||
4234 (tree->left && tree->left->isError) ||
4235 (tree->right && tree->right->isError)) {
4236 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4240 /* print the line */
4241 /* if not block & function */
4242 if (tree->type == EX_OP &&
4243 (tree->opval.op != FUNCTION &&
4244 tree->opval.op != BLOCK &&
4245 tree->opval.op != NULLOP)) {
4248 if (tree->opval.op == FUNCTION) {
4249 fprintf(outfile,"FUNCTION (%p) type (",tree);
4250 printTypeChain (tree->ftype,outfile);
4251 fprintf(outfile,")\n");
4252 ast_print(tree->left,outfile,indent+4);
4253 ast_print(tree->right,outfile,indent+4);
4256 if (tree->opval.op == BLOCK) {
4257 symbol *decls = tree->values.sym;
4258 fprintf(outfile,"{\n");
4260 INDENT(indent+4,outfile);
4261 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4262 printTypeChain(decls->type,outfile);
4263 fprintf(outfile,")\n");
4265 decls = decls->next;
4267 ast_print(tree->right,outfile,indent+4);
4268 fprintf(outfile,"}\n");
4271 if (tree->opval.op == NULLOP) {
4272 fprintf(outfile,"\n");
4273 ast_print(tree->left,outfile,indent);
4274 fprintf(outfile,"\n");
4275 ast_print(tree->right,outfile,indent);
4278 INDENT(indent,outfile);
4280 /*------------------------------------------------------------------*/
4281 /*----------------------------*/
4282 /* leaf has been reached */
4283 /*----------------------------*/
4284 /* if this is of type value */
4285 /* just get the type */
4286 if (tree->type == EX_VALUE) {
4288 if (IS_LITERAL (tree->opval.val->etype)) {
4289 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4290 (int) floatFromVal(tree->opval.val),
4291 (int) floatFromVal(tree->opval.val),
4292 floatFromVal(tree->opval.val));
4293 } else if (tree->opval.val->sym) {
4294 /* if the undefined flag is set then give error message */
4295 if (tree->opval.val->sym->undefined) {
4296 fprintf(outfile,"UNDEFINED SYMBOL ");
4298 fprintf(outfile,"SYMBOL ");
4300 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4303 fprintf(outfile," type (");
4304 printTypeChain(tree->ftype,outfile);
4305 fprintf(outfile,")\n");
4307 fprintf(outfile,"\n");
4312 /* if type link for the case of cast */
4313 if (tree->type == EX_LINK) {
4314 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4315 printTypeChain(tree->opval.lnk,outfile);
4316 fprintf(outfile,")\n");
4321 /* depending on type of operator do */
4323 switch (tree->opval.op) {
4324 /*------------------------------------------------------------------*/
4325 /*----------------------------*/
4327 /*----------------------------*/
4329 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4330 printTypeChain(tree->ftype,outfile);
4331 fprintf(outfile,")\n");
4332 ast_print(tree->left,outfile,indent+4);
4333 ast_print(tree->right,outfile,indent+4);
4336 /*------------------------------------------------------------------*/
4337 /*----------------------------*/
4339 /*----------------------------*/
4341 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4342 printTypeChain(tree->ftype,outfile);
4343 fprintf(outfile,")\n");
4344 ast_print(tree->left,outfile,indent+4);
4345 ast_print(tree->right,outfile,indent+4);
4348 /*------------------------------------------------------------------*/
4349 /*----------------------------*/
4350 /* struct/union pointer */
4351 /*----------------------------*/
4353 fprintf(outfile,"PTR_ACCESS (%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);
4360 /*------------------------------------------------------------------*/
4361 /*----------------------------*/
4362 /* ++/-- operation */
4363 /*----------------------------*/
4364 case INC_OP: /* incerement operator unary so left only */
4365 fprintf(outfile,"INC_OP (%p) type (",tree);
4366 printTypeChain(tree->ftype,outfile);
4367 fprintf(outfile,")\n");
4368 ast_print(tree->left,outfile,indent+4);
4372 fprintf(outfile,"DEC_OP (%p) type (",tree);
4373 printTypeChain(tree->ftype,outfile);
4374 fprintf(outfile,")\n");
4375 ast_print(tree->left,outfile,indent+4);
4378 /*------------------------------------------------------------------*/
4379 /*----------------------------*/
4381 /*----------------------------*/
4384 fprintf(outfile,"& (%p) type (",tree);
4385 printTypeChain(tree->ftype,outfile);
4386 fprintf(outfile,")\n");
4387 ast_print(tree->left,outfile,indent+4);
4388 ast_print(tree->right,outfile,indent+4);
4390 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4391 printTypeChain(tree->ftype,outfile);
4392 fprintf(outfile,")\n");
4393 ast_print(tree->left,outfile,indent+4);
4394 ast_print(tree->right,outfile,indent+4);
4397 /*----------------------------*/
4399 /*----------------------------*/
4401 fprintf(outfile,"OR (%p) type (",tree);
4402 printTypeChain(tree->ftype,outfile);
4403 fprintf(outfile,")\n");
4404 ast_print(tree->left,outfile,indent+4);
4405 ast_print(tree->right,outfile,indent+4);
4407 /*------------------------------------------------------------------*/
4408 /*----------------------------*/
4410 /*----------------------------*/
4412 fprintf(outfile,"XOR (%p) type (",tree);
4413 printTypeChain(tree->ftype,outfile);
4414 fprintf(outfile,")\n");
4415 ast_print(tree->left,outfile,indent+4);
4416 ast_print(tree->right,outfile,indent+4);
4419 /*------------------------------------------------------------------*/
4420 /*----------------------------*/
4422 /*----------------------------*/
4424 fprintf(outfile,"DIV (%p) type (",tree);
4425 printTypeChain(tree->ftype,outfile);
4426 fprintf(outfile,")\n");
4427 ast_print(tree->left,outfile,indent+4);
4428 ast_print(tree->right,outfile,indent+4);
4430 /*------------------------------------------------------------------*/
4431 /*----------------------------*/
4433 /*----------------------------*/
4435 fprintf(outfile,"MOD (%p) type (",tree);
4436 printTypeChain(tree->ftype,outfile);
4437 fprintf(outfile,")\n");
4438 ast_print(tree->left,outfile,indent+4);
4439 ast_print(tree->right,outfile,indent+4);
4442 /*------------------------------------------------------------------*/
4443 /*----------------------------*/
4444 /* address dereference */
4445 /*----------------------------*/
4446 case '*': /* can be unary : if right is null then unary operation */
4448 fprintf(outfile,"DEREF (%p) type (",tree);
4449 printTypeChain(tree->ftype,outfile);
4450 fprintf(outfile,")\n");
4451 ast_print(tree->left,outfile,indent+4);
4454 /*------------------------------------------------------------------*/
4455 /*----------------------------*/
4456 /* multiplication */
4457 /*----------------------------*/
4458 fprintf(outfile,"MULT (%p) type (",tree);
4459 printTypeChain(tree->ftype,outfile);
4460 fprintf(outfile,")\n");
4461 ast_print(tree->left,outfile,indent+4);
4462 ast_print(tree->right,outfile,indent+4);
4466 /*------------------------------------------------------------------*/
4467 /*----------------------------*/
4468 /* unary '+' operator */
4469 /*----------------------------*/
4473 fprintf(outfile,"UPLUS (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+4);
4478 /*------------------------------------------------------------------*/
4479 /*----------------------------*/
4481 /*----------------------------*/
4482 fprintf(outfile,"ADD (%p) type (",tree);
4483 printTypeChain(tree->ftype,outfile);
4484 fprintf(outfile,")\n");
4485 ast_print(tree->left,outfile,indent+4);
4486 ast_print(tree->right,outfile,indent+4);
4489 /*------------------------------------------------------------------*/
4490 /*----------------------------*/
4492 /*----------------------------*/
4493 case '-': /* can be unary */
4495 fprintf(outfile,"UMINUS (%p) type (",tree);
4496 printTypeChain(tree->ftype,outfile);
4497 fprintf(outfile,")\n");
4498 ast_print(tree->left,outfile,indent+4);
4500 /*------------------------------------------------------------------*/
4501 /*----------------------------*/
4503 /*----------------------------*/
4504 fprintf(outfile,"SUB (%p) type (",tree);
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4507 ast_print(tree->left,outfile,indent+4);
4508 ast_print(tree->right,outfile,indent+4);
4511 /*------------------------------------------------------------------*/
4512 /*----------------------------*/
4514 /*----------------------------*/
4516 fprintf(outfile,"COMPL (%p) type (",tree);
4517 printTypeChain(tree->ftype,outfile);
4518 fprintf(outfile,")\n");
4519 ast_print(tree->left,outfile,indent+4);
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4524 /*----------------------------*/
4526 fprintf(outfile,"NOT (%p) type (",tree);
4527 printTypeChain(tree->ftype,outfile);
4528 fprintf(outfile,")\n");
4529 ast_print(tree->left,outfile,indent+4);
4531 /*------------------------------------------------------------------*/
4532 /*----------------------------*/
4534 /*----------------------------*/
4536 fprintf(outfile,"RRC (%p) type (",tree);
4537 printTypeChain(tree->ftype,outfile);
4538 fprintf(outfile,")\n");
4539 ast_print(tree->left,outfile,indent+4);
4543 fprintf(outfile,"RLC (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+4);
4549 fprintf(outfile,"GETHBIT (%p) type (",tree);
4550 printTypeChain(tree->ftype,outfile);
4551 fprintf(outfile,")\n");
4552 ast_print(tree->left,outfile,indent+4);
4555 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4556 printTypeChain(tree->ftype,outfile);
4557 fprintf(outfile,")\n");
4558 ast_print(tree->left,outfile,indent+4);
4559 ast_print(tree->right,outfile,indent+4);
4562 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4563 printTypeChain(tree->ftype,outfile);
4564 fprintf(outfile,")\n");
4565 ast_print(tree->left,outfile,indent+4);
4566 ast_print(tree->right,outfile,indent+4);
4568 /*------------------------------------------------------------------*/
4569 /*----------------------------*/
4571 /*----------------------------*/
4572 case CAST: /* change the type */
4573 fprintf(outfile,"CAST (%p) type (",tree);
4574 printTypeChain(tree->ftype,outfile);
4575 fprintf(outfile,")\n");
4576 ast_print(tree->right,outfile,indent+4);
4580 fprintf(outfile,"ANDAND (%p) type (",tree);
4581 printTypeChain(tree->ftype,outfile);
4582 fprintf(outfile,")\n");
4583 ast_print(tree->left,outfile,indent+4);
4584 ast_print(tree->right,outfile,indent+4);
4587 fprintf(outfile,"OROR (%p) type (",tree);
4588 printTypeChain(tree->ftype,outfile);
4589 fprintf(outfile,")\n");
4590 ast_print(tree->left,outfile,indent+4);
4591 ast_print(tree->right,outfile,indent+4);
4594 /*------------------------------------------------------------------*/
4595 /*----------------------------*/
4596 /* comparison operators */
4597 /*----------------------------*/
4599 fprintf(outfile,"GT(>) (%p) type (",tree);
4600 printTypeChain(tree->ftype,outfile);
4601 fprintf(outfile,")\n");
4602 ast_print(tree->left,outfile,indent+4);
4603 ast_print(tree->right,outfile,indent+4);
4606 fprintf(outfile,"LT(<) (%p) type (",tree);
4607 printTypeChain(tree->ftype,outfile);
4608 fprintf(outfile,")\n");
4609 ast_print(tree->left,outfile,indent+4);
4610 ast_print(tree->right,outfile,indent+4);
4613 fprintf(outfile,"LE(<=) (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+4);
4617 ast_print(tree->right,outfile,indent+4);
4620 fprintf(outfile,"GE(>=) (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+4);
4624 ast_print(tree->right,outfile,indent+4);
4627 fprintf(outfile,"EQ(==) (%p) type (",tree);
4628 printTypeChain(tree->ftype,outfile);
4629 fprintf(outfile,")\n");
4630 ast_print(tree->left,outfile,indent+4);
4631 ast_print(tree->right,outfile,indent+4);
4634 fprintf(outfile,"NE(!=) (%p) type (",tree);
4635 printTypeChain(tree->ftype,outfile);
4636 fprintf(outfile,")\n");
4637 ast_print(tree->left,outfile,indent+4);
4638 ast_print(tree->right,outfile,indent+4);
4639 /*------------------------------------------------------------------*/
4640 /*----------------------------*/
4642 /*----------------------------*/
4643 case SIZEOF: /* evaluate wihout code generation */
4644 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4647 /*------------------------------------------------------------------*/
4648 /*----------------------------*/
4649 /* conditional operator '?' */
4650 /*----------------------------*/
4652 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4653 printTypeChain(tree->ftype,outfile);
4654 fprintf(outfile,")\n");
4655 ast_print(tree->left,outfile,indent+4);
4656 ast_print(tree->right,outfile,indent+4);
4659 fprintf(outfile,"COLON(:) (%p) type (",tree);
4660 printTypeChain(tree->ftype,outfile);
4661 fprintf(outfile,")\n");
4662 ast_print(tree->left,outfile,indent+4);
4663 ast_print(tree->right,outfile,indent+4);
4666 /*------------------------------------------------------------------*/
4667 /*----------------------------*/
4668 /* assignment operators */
4669 /*----------------------------*/
4671 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+4);
4675 ast_print(tree->right,outfile,indent+4);
4678 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+4);
4682 ast_print(tree->right,outfile,indent+4);
4685 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4686 printTypeChain(tree->ftype,outfile);
4687 fprintf(outfile,")\n");
4688 ast_print(tree->left,outfile,indent+4);
4689 ast_print(tree->right,outfile,indent+4);
4692 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4693 printTypeChain(tree->ftype,outfile);
4694 fprintf(outfile,")\n");
4695 ast_print(tree->left,outfile,indent+4);
4696 ast_print(tree->right,outfile,indent+4);
4699 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4700 printTypeChain(tree->ftype,outfile);
4701 fprintf(outfile,")\n");
4702 ast_print(tree->left,outfile,indent+4);
4703 ast_print(tree->right,outfile,indent+4);
4706 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4707 printTypeChain(tree->ftype,outfile);
4708 fprintf(outfile,")\n");
4709 ast_print(tree->left,outfile,indent+4);
4710 ast_print(tree->right,outfile,indent+4);
4713 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+4);
4717 ast_print(tree->right,outfile,indent+4);
4719 /*------------------------------------------------------------------*/
4720 /*----------------------------*/
4722 /*----------------------------*/
4724 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4725 printTypeChain(tree->ftype,outfile);
4726 fprintf(outfile,")\n");
4727 ast_print(tree->left,outfile,indent+4);
4728 ast_print(tree->right,outfile,indent+4);
4730 /*------------------------------------------------------------------*/
4731 /*----------------------------*/
4733 /*----------------------------*/
4735 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+4);
4739 ast_print(tree->right,outfile,indent+4);
4741 /*------------------------------------------------------------------*/
4742 /*----------------------------*/
4743 /* straight assignemnt */
4744 /*----------------------------*/
4746 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4747 printTypeChain(tree->ftype,outfile);
4748 fprintf(outfile,")\n");
4749 ast_print(tree->left,outfile,indent+4);
4750 ast_print(tree->right,outfile,indent+4);
4752 /*------------------------------------------------------------------*/
4753 /*----------------------------*/
4754 /* comma operator */
4755 /*----------------------------*/
4757 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+4);
4761 ast_print(tree->right,outfile,indent+4);
4763 /*------------------------------------------------------------------*/
4764 /*----------------------------*/
4766 /*----------------------------*/
4769 fprintf(outfile,"CALL (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+4);
4773 ast_print(tree->right,outfile,indent+4);
4776 fprintf(outfile,"PARM ");
4777 ast_print(tree->left,outfile,indent+4);
4778 if (tree->right && !IS_AST_PARAM(tree->right)) {
4779 fprintf(outfile,"PARM ");
4780 ast_print(tree->right,outfile,indent+4);
4783 /*------------------------------------------------------------------*/
4784 /*----------------------------*/
4785 /* return statement */
4786 /*----------------------------*/
4788 fprintf(outfile,"RETURN (%p) type (",tree);
4789 printTypeChain(tree->right->ftype,outfile);
4790 fprintf(outfile,")\n");
4791 ast_print(tree->right,outfile,indent+4);
4793 /*------------------------------------------------------------------*/
4794 /*----------------------------*/
4795 /* label statement */
4796 /*----------------------------*/
4798 fprintf(outfile,"LABEL (%p)",tree);
4799 ast_print(tree->left,outfile,indent+4);
4800 ast_print(tree->right,outfile,indent);
4802 /*------------------------------------------------------------------*/
4803 /*----------------------------*/
4804 /* switch statement */
4805 /*----------------------------*/
4809 fprintf(outfile,"SWITCH (%p) ",tree);
4810 ast_print(tree->left,outfile,0);
4811 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4812 INDENT(indent+4,outfile);
4813 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4814 (int) floatFromVal(val),
4815 tree->values.switchVals.swNum,
4816 (int) floatFromVal(val));
4818 ast_print(tree->right,outfile,indent);
4821 /*------------------------------------------------------------------*/
4822 /*----------------------------*/
4824 /*----------------------------*/
4826 ast_print(tree->left,outfile,indent);
4827 INDENT(indent,outfile);
4828 fprintf(outfile,"IF (%p) \n",tree);
4829 if (tree->trueLabel) {
4830 INDENT(indent,outfile);
4831 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4833 if (tree->falseLabel) {
4834 INDENT(indent,outfile);
4835 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4837 ast_print(tree->right,outfile,indent);
4839 /*------------------------------------------------------------------*/
4840 /*----------------------------*/
4842 /*----------------------------*/
4844 fprintf(outfile,"FOR (%p) \n",tree);
4845 if (AST_FOR( tree, initExpr)) {
4846 INDENT(indent+4,outfile);
4847 fprintf(outfile,"INIT EXPR ");
4848 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4850 if (AST_FOR( tree, condExpr)) {
4851 INDENT(indent+4,outfile);
4852 fprintf(outfile,"COND EXPR ");
4853 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4855 if (AST_FOR( tree, loopExpr)) {
4856 INDENT(indent+4,outfile);
4857 fprintf(outfile,"LOOP EXPR ");
4858 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4860 fprintf(outfile,"FOR LOOP BODY \n");
4861 ast_print(tree->left,outfile,indent+4);
4870 ast_print(t,stdout,1);