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))
184 /* then depending on the expression value */
185 if (floatFromVal (condAst->opval.val))
186 ifxNode = newNode (GOTO,
187 newAst_VALUE (symbolVal (trueLabel)),
190 ifxNode = newNode (GOTO,
191 newAst_VALUE (symbolVal (falseLabel)),
196 ifxNode = newNode (IFX, condAst, NULL);
197 ifxNode->trueLabel = trueLabel;
198 ifxNode->falseLabel = falseLabel;
204 /*-----------------------------------------------------------------*/
205 /* copyAstValues - copies value portion of ast if needed */
206 /*-----------------------------------------------------------------*/
208 copyAstValues (ast * dest, ast * src)
210 switch (src->opval.op)
213 dest->values.sym = copySymbolChain (src->values.sym);
217 dest->values.switchVals.swVals =
218 copyValue (src->values.switchVals.swVals);
219 dest->values.switchVals.swDefault =
220 src->values.switchVals.swDefault;
221 dest->values.switchVals.swNum =
222 src->values.switchVals.swNum;
226 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
227 strcpy (dest->values.inlineasm, src->values.inlineasm);
230 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
231 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
232 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
233 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
234 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
235 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
236 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
241 /*-----------------------------------------------------------------*/
242 /* copyAst - makes a copy of a given astession */
243 /*-----------------------------------------------------------------*/
252 dest = Safe_calloc (1, sizeof (ast));
254 dest->type = src->type;
255 dest->lineno = src->lineno;
256 dest->level = src->level;
257 dest->funcName = src->funcName;
258 dest->argSym = src->argSym;
260 /* if this is a leaf */
262 if (src->type == EX_VALUE)
264 dest->opval.val = copyValue (src->opval.val);
269 if (src->type == EX_LINK)
271 dest->opval.lnk = copyLinkChain (src->opval.lnk);
275 dest->opval.op = src->opval.op;
277 /* if this is a node that has special values */
278 copyAstValues (dest, src);
281 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
283 dest->trueLabel = copySymbol (src->trueLabel);
284 dest->falseLabel = copySymbol (src->falseLabel);
285 dest->left = copyAst (src->left);
286 dest->right = copyAst (src->right);
292 /*-----------------------------------------------------------------*/
293 /* hasSEFcalls - returns TRUE if tree has a function call */
294 /*-----------------------------------------------------------------*/
296 hasSEFcalls (ast * tree)
301 if (tree->type == EX_OP &&
302 (tree->opval.op == CALL ||
303 tree->opval.op == PCALL ||
304 tree->opval.op == '=' ||
305 tree->opval.op == INC_OP ||
306 tree->opval.op == DEC_OP))
309 return (hasSEFcalls (tree->left) |
310 hasSEFcalls (tree->right));
313 /*-----------------------------------------------------------------*/
314 /* isAstEqual - compares two asts & returns 1 if they are equal */
315 /*-----------------------------------------------------------------*/
317 isAstEqual (ast * t1, ast * t2)
326 if (t1->type != t2->type)
332 if (t1->opval.op != t2->opval.op)
334 return (isAstEqual (t1->left, t2->left) &&
335 isAstEqual (t1->right, t2->right));
339 if (t1->opval.val->sym)
341 if (!t2->opval.val->sym)
344 return isSymbolEqual (t1->opval.val->sym,
349 if (t2->opval.val->sym)
352 return (floatFromVal (t1->opval.val) ==
353 floatFromVal (t2->opval.val));
357 /* only compare these two types */
365 /*-----------------------------------------------------------------*/
366 /* resolveSymbols - resolve symbols from the symbol table */
367 /*-----------------------------------------------------------------*/
369 resolveSymbols (ast * tree)
371 /* walk the entire tree and check for values */
372 /* with symbols if we find one then replace */
373 /* symbol with that from the symbol table */
379 /* if not block & function */
380 if (tree->type == EX_OP &&
381 (tree->opval.op != FUNCTION &&
382 tree->opval.op != BLOCK &&
383 tree->opval.op != NULLOP))
385 filename = tree->filename;
386 lineno = tree->lineno;
389 /* make sure we resolve the true & false labels for ifx */
390 if (tree->type == EX_OP && tree->opval.op == IFX)
396 if ((csym = findSym (LabelTab, tree->trueLabel,
397 tree->trueLabel->name)))
398 tree->trueLabel = csym;
400 werror (E_LABEL_UNDEF, tree->trueLabel->name);
403 if (tree->falseLabel)
405 if ((csym = findSym (LabelTab,
407 tree->falseLabel->name)))
408 tree->falseLabel = csym;
410 werror (E_LABEL_UNDEF, tree->falseLabel->name);
415 /* if this is a label resolve it from the labelTab */
416 if (IS_AST_VALUE (tree) &&
417 tree->opval.val->sym &&
418 tree->opval.val->sym->islbl)
421 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
422 tree->opval.val->sym->name);
425 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
427 tree->opval.val->sym = csym;
429 goto resolveChildren;
432 /* do only for leafs */
433 if (IS_AST_VALUE (tree) &&
434 tree->opval.val->sym &&
435 !tree->opval.val->sym->implicit)
438 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
440 /* if found in the symbol table & they r not the same */
441 if (csym && tree->opval.val->sym != csym)
443 tree->opval.val->sym = csym;
444 tree->opval.val->type = csym->type;
445 tree->opval.val->etype = csym->etype;
448 /* if not found in the symbol table */
449 /* mark it as undefined assume it is */
450 /* an integer in data space */
451 if (!csym && !tree->opval.val->sym->implicit)
454 /* if this is a function name then */
455 /* mark it as returning an int */
458 tree->opval.val->sym->type = newLink ();
459 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
460 tree->opval.val->sym->type->next =
461 tree->opval.val->sym->etype = newIntLink ();
462 tree->opval.val->etype = tree->opval.val->etype;
463 tree->opval.val->type = tree->opval.val->sym->type;
464 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
468 tree->opval.val->sym->undefined = 1;
469 tree->opval.val->type =
470 tree->opval.val->etype = newIntLink ();
471 tree->opval.val->sym->type =
472 tree->opval.val->sym->etype = newIntLink ();
478 resolveSymbols (tree->left);
479 resolveSymbols (tree->right);
484 /*-----------------------------------------------------------------*/
485 /* setAstLineno - walks a ast tree & sets the line number */
486 /*-----------------------------------------------------------------*/
488 setAstLineno (ast * tree, int lineno)
493 tree->lineno = lineno;
494 setAstLineno (tree->left, lineno);
495 setAstLineno (tree->right, lineno);
500 /* this functions seems to be superfluous?! kmh */
502 /*-----------------------------------------------------------------*/
503 /* resolveFromTable - will return the symbal table value */
504 /*-----------------------------------------------------------------*/
506 resolveFromTable (value * val)
513 csym = findSymWithLevel (SymbolTab, val->sym);
515 /* if found in the symbol table & they r not the same */
516 if (csym && val->sym != csym &&
517 csym->level == val->sym->level &&
523 val->type = csym->type;
524 val->etype = csym->etype;
531 /*-----------------------------------------------------------------*/
532 /* funcOfType :- function of type with name */
533 /*-----------------------------------------------------------------*/
535 funcOfType (char *name, sym_link * type, sym_link * argType,
539 /* create the symbol */
540 sym = newSymbol (name, 0);
542 /* if arguments required */
547 args = sym->args = newValue ();
551 args->type = copyLinkChain (argType);
552 args->etype = getSpec (args->type);
555 args = args->next = newValue ();
559 /* setup return value */
560 sym->type = newLink ();
561 DCL_TYPE (sym->type) = FUNCTION;
562 sym->type->next = copyLinkChain (type);
563 sym->etype = getSpec (sym->type);
564 SPEC_RENT (sym->etype) = rent;
569 allocVariables (sym);
574 /*-----------------------------------------------------------------*/
575 /* reverseParms - will reverse a parameter tree */
576 /*-----------------------------------------------------------------*/
578 reverseParms (ast * ptree)
584 /* top down if we find a nonParm tree then quit */
585 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
588 ptree->left = ptree->right;
589 ptree->right = ttree;
590 reverseParms (ptree->left);
591 reverseParms (ptree->right);
597 /*-----------------------------------------------------------------*/
598 /* processParms - makes sure the parameters are okay and do some */
599 /* processing with them */
600 /*-----------------------------------------------------------------*/
602 processParms (ast * func,
608 sym_link *fetype = func->etype;
610 /* if none of them exist */
611 if (!defParm && !actParm)
614 /* if the function is being called via a pointer & */
615 /* it has not been defined a reentrant then we cannot */
616 /* have parameters */
617 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
619 werror (E_NONRENT_ARGS);
623 /* if defined parameters ended but actual parameters */
624 /* exist and this is not defined as a variable arg */
625 /* also check if statckAuto option is specified */
626 if ((!defParm) && actParm && (!func->hasVargs) &&
627 !options.stackAuto && !IS_RENT (fetype))
629 werror (E_TOO_MANY_PARMS);
633 /* if defined parameters present but no actual parameters */
634 if (defParm && !actParm)
636 werror (E_TOO_FEW_PARMS);
640 /* If this is a varargs function... */
641 if (!defParm && actParm && func->hasVargs)
646 if (IS_CAST_OP (actParm)
647 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
649 /* Parameter was explicitly typecast; don't touch it. */
653 /* The ternary ('?') operator is weird: the ftype of the
654 * operator is the type of the condition, but it will return a
655 * (possibly) different type.
657 if (IS_TERNARY_OP(actParm))
659 assert(IS_COLON_OP(actParm->right));
660 assert(actParm->right->left);
661 ftype = actParm->right->left->ftype;
665 ftype = actParm->ftype;
668 /* If it's a small integer, upcast to int. */
669 if (IS_INTEGRAL (ftype)
670 && (getSize (ftype) < (unsigned) INTSIZE))
672 newType = newAst_LINK(INTTYPE);
675 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
677 newType = newAst_LINK (copyLinkChain(ftype));
678 DCL_TYPE (newType->opval.lnk) = GPOINTER;
681 if (IS_AGGREGATE (ftype))
683 newType = newAst_LINK (copyLinkChain (ftype));
684 DCL_TYPE (newType->opval.lnk) = GPOINTER;
688 /* cast required; change this op to a cast. */
689 ast *parmCopy = resolveSymbols (copyAst (actParm));
691 actParm->type = EX_OP;
692 actParm->opval.op = CAST;
693 actParm->left = newType;
694 actParm->right = parmCopy;
695 decorateType (actParm);
697 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
699 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
700 processParms (func, NULL, actParm->right, parmNumber, rightmost));
705 /* if defined parameters ended but actual has not & */
707 if (!defParm && actParm &&
708 (options.stackAuto || IS_RENT (fetype)))
711 resolveSymbols (actParm);
712 /* if this is a PARAM node then match left & right */
713 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
715 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
716 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
720 /* If we have found a value node by following only right-hand links,
721 * then we know that there are no more values after us.
723 * Therefore, if there are more defined parameters, the caller didn't
726 if (rightmost && defParm->next)
728 werror (E_TOO_FEW_PARMS);
733 /* the parameter type must be at least castable */
734 if (checkType (defParm->type, actParm->ftype) == 0)
736 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
737 werror (E_CONTINUE, "defined type ");
738 printTypeChain (defParm->type, stderr);
739 fprintf (stderr, "\n");
740 werror (E_CONTINUE, "actual type ");
741 printTypeChain (actParm->ftype, stderr);
742 fprintf (stderr, "\n");
745 /* if the parameter is castable then add the cast */
746 if (checkType (defParm->type, actParm->ftype) < 0)
748 ast *pTree = resolveSymbols (copyAst (actParm));
750 /* now change the current one to a cast */
751 actParm->type = EX_OP;
752 actParm->opval.op = CAST;
753 actParm->left = newAst_LINK (defParm->type);
754 actParm->right = pTree;
755 actParm->etype = defParm->etype;
756 actParm->ftype = defParm->type;
759 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
761 actParm->argSym = defParm->sym;
762 /* make a copy and change the regparm type to the defined parm */
763 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
764 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
768 /*-----------------------------------------------------------------*/
769 /* createIvalType - generates ival for basic types */
770 /*-----------------------------------------------------------------*/
772 createIvalType (ast * sym, sym_link * type, initList * ilist)
776 /* if initList is deep */
777 if (ilist->type == INIT_DEEP)
778 ilist = ilist->init.deep;
780 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
781 return decorateType (newNode ('=', sym, iExpr));
784 /*-----------------------------------------------------------------*/
785 /* createIvalStruct - generates initial value for structures */
786 /*-----------------------------------------------------------------*/
788 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
794 sflds = SPEC_STRUCT (type)->fields;
795 if (ilist->type != INIT_DEEP)
797 werror (E_INIT_STRUCT, "");
801 iloop = ilist->init.deep;
803 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
807 /* if we have come to end */
811 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
812 lAst = decorateType (resolveSymbols (lAst));
813 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
819 /*-----------------------------------------------------------------*/
820 /* createIvalArray - generates code for array initialization */
821 /*-----------------------------------------------------------------*/
823 createIvalArray (ast * sym, sym_link * type, initList * ilist)
827 int lcnt = 0, size = 0;
829 /* take care of the special case */
830 /* array of characters can be init */
832 if (IS_CHAR (type->next))
833 if ((rast = createIvalCharPtr (sym,
835 decorateType (resolveSymbols (list2expr (ilist))))))
837 return decorateType (resolveSymbols (rast));
839 /* not the special case */
840 if (ilist->type != INIT_DEEP)
842 werror (E_INIT_STRUCT, "");
846 iloop = ilist->init.deep;
847 lcnt = DCL_ELEM (type);
854 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
855 aSym = decorateType (resolveSymbols (aSym));
856 rast = createIval (aSym, type->next, iloop, rast);
857 iloop = (iloop ? iloop->next : NULL);
860 /* if not array limits given & we */
861 /* are out of initialisers then */
862 if (!DCL_ELEM (type) && !iloop)
865 /* no of elements given and we */
866 /* have generated for all of them */
868 /* if initializers left */
870 // there has to be a better way
871 char *name=sym->opval.val->sym->name;
872 int lineno=sym->opval.val->sym->lineDef;
873 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
879 /* if we have not been given a size */
880 if (!DCL_ELEM (type))
881 DCL_ELEM (type) = size;
883 return decorateType (resolveSymbols (rast));
887 /*-----------------------------------------------------------------*/
888 /* createIvalCharPtr - generates initial values for char pointers */
889 /*-----------------------------------------------------------------*/
891 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
895 /* if this is a pointer & right is a literal array then */
896 /* just assignment will do */
897 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
898 SPEC_SCLS (iexpr->etype) == S_CODE)
899 && IS_ARRAY (iexpr->ftype)))
900 return newNode ('=', sym, iexpr);
902 /* left side is an array so we have to assign each */
904 if ((IS_LITERAL (iexpr->etype) ||
905 SPEC_SCLS (iexpr->etype) == S_CODE)
906 && IS_ARRAY (iexpr->ftype))
909 /* for each character generate an assignment */
910 /* to the array element */
911 char *s = SPEC_CVAL (iexpr->etype).v_char;
916 rast = newNode (NULLOP,
920 newAst_VALUE (valueFromLit ((float) i))),
921 newAst_VALUE (valueFromLit (*s))));
925 rast = newNode (NULLOP,
929 newAst_VALUE (valueFromLit ((float) i))),
930 newAst_VALUE (valueFromLit (*s))));
931 return decorateType (resolveSymbols (rast));
937 /*-----------------------------------------------------------------*/
938 /* createIvalPtr - generates initial value for pointers */
939 /*-----------------------------------------------------------------*/
941 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
947 if (ilist->type == INIT_DEEP)
948 ilist = ilist->init.deep;
950 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
952 /* if character pointer */
953 if (IS_CHAR (type->next))
954 if ((rast = createIvalCharPtr (sym, type, iexpr)))
957 return newNode ('=', sym, iexpr);
960 /*-----------------------------------------------------------------*/
961 /* createIval - generates code for initial value */
962 /*-----------------------------------------------------------------*/
964 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
971 /* if structure then */
972 if (IS_STRUCT (type))
973 rast = createIvalStruct (sym, type, ilist);
975 /* if this is a pointer */
977 rast = createIvalPtr (sym, type, ilist);
979 /* if this is an array */
981 rast = createIvalArray (sym, type, ilist);
983 /* if type is SPECIFIER */
985 rast = createIvalType (sym, type, ilist);
987 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
989 return decorateType (resolveSymbols (rast));
992 /*-----------------------------------------------------------------*/
993 /* initAggregates - initialises aggregate variables with initv */
994 /*-----------------------------------------------------------------*/
996 initAggregates (symbol * sym, initList * ival, ast * wid)
998 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1001 /*-----------------------------------------------------------------*/
1002 /* gatherAutoInit - creates assignment expressions for initial */
1004 /*-----------------------------------------------------------------*/
1006 gatherAutoInit (symbol * autoChain)
1013 for (sym = autoChain; sym; sym = sym->next)
1016 /* resolve the symbols in the ival */
1018 resolveIvalSym (sym->ival);
1020 /* if this is a static variable & has an */
1021 /* initial value the code needs to be lifted */
1022 /* here to the main portion since they can be */
1023 /* initialised only once at the start */
1024 if (IS_STATIC (sym->etype) && sym->ival &&
1025 SPEC_SCLS (sym->etype) != S_CODE)
1029 // this can only be a constant
1030 if (!IS_LITERAL(sym->ival->init.node->etype)) {
1031 werror (E_CONST_EXPECTED);
1034 /* insert the symbol into the symbol table */
1035 /* with level = 0 & name = rname */
1036 newSym = copySymbol (sym);
1037 addSym (SymbolTab, newSym, newSym->name, 0, 0);
1039 /* now lift the code to main */
1040 if (IS_AGGREGATE (sym->type))
1041 work = initAggregates (sym, sym->ival, NULL);
1043 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1044 list2expr (sym->ival));
1046 setAstLineno (work, sym->lineDef);
1050 staticAutos = newNode (NULLOP, staticAutos, work);
1057 /* if there is an initial value */
1058 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1060 if (IS_AGGREGATE (sym->type))
1061 work = initAggregates (sym, sym->ival, NULL);
1063 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1064 list2expr (sym->ival));
1066 setAstLineno (work, sym->lineDef);
1069 init = newNode (NULLOP, init, work);
1078 /*-----------------------------------------------------------------*/
1079 /* stringToSymbol - creates a symbol from a literal string */
1080 /*-----------------------------------------------------------------*/
1082 stringToSymbol (value * val)
1084 char name[SDCC_NAME_MAX + 1];
1085 static int charLbl = 0;
1088 sprintf (name, "_str_%d", charLbl++);
1089 sym = newSymbol (name, 0); /* make it @ level 0 */
1090 strcpy (sym->rname, name);
1092 /* copy the type from the value passed */
1093 sym->type = copyLinkChain (val->type);
1094 sym->etype = getSpec (sym->type);
1095 /* change to storage class & output class */
1096 SPEC_SCLS (sym->etype) = S_CODE;
1097 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1098 SPEC_STAT (sym->etype) = 1;
1099 /* make the level & block = 0 */
1100 sym->block = sym->level = 0;
1102 /* create an ival */
1103 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1108 allocVariables (sym);
1111 return symbolVal (sym);
1115 /*-----------------------------------------------------------------*/
1116 /* processBlockVars - will go thru the ast looking for block if */
1117 /* a block is found then will allocate the syms */
1118 /* will also gather the auto inits present */
1119 /*-----------------------------------------------------------------*/
1121 processBlockVars (ast * tree, int *stack, int action)
1126 /* if this is a block */
1127 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1131 if (action == ALLOCATE)
1133 autoInit = gatherAutoInit (tree->values.sym);
1134 *stack += allocVariables (tree->values.sym);
1136 /* if there are auto inits then do them */
1138 tree->left = newNode (NULLOP, autoInit, tree->left);
1140 else /* action is deallocate */
1141 deallocLocal (tree->values.sym);
1144 processBlockVars (tree->left, stack, action);
1145 processBlockVars (tree->right, stack, action);
1149 /*-----------------------------------------------------------------*/
1150 /* constExprValue - returns the value of a constant expression */
1151 /*-----------------------------------------------------------------*/
1153 constExprValue (ast * cexpr, int check)
1155 cexpr = decorateType (resolveSymbols (cexpr));
1157 /* if this is not a constant then */
1158 if (!IS_LITERAL (cexpr->ftype))
1160 /* then check if this is a literal array
1162 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1163 SPEC_CVAL (cexpr->etype).v_char &&
1164 IS_ARRAY (cexpr->ftype))
1166 value *val = valFromType (cexpr->ftype);
1167 SPEC_SCLS (val->etype) = S_LITERAL;
1168 val->sym = cexpr->opval.val->sym;
1169 val->sym->type = copyLinkChain (cexpr->ftype);
1170 val->sym->etype = getSpec (val->sym->type);
1171 strcpy (val->name, cexpr->opval.val->sym->rname);
1175 /* if we are casting a literal value then */
1176 if (IS_AST_OP (cexpr) &&
1177 cexpr->opval.op == CAST &&
1178 IS_LITERAL (cexpr->left->ftype))
1179 return valCastLiteral (cexpr->ftype,
1180 floatFromVal (cexpr->left->opval.val));
1182 if (IS_AST_VALUE (cexpr))
1183 return cexpr->opval.val;
1186 werror (E_CONST_EXPECTED, "found expression");
1191 /* return the value */
1192 return cexpr->opval.val;
1196 /*-----------------------------------------------------------------*/
1197 /* isLabelInAst - will return true if a given label is found */
1198 /*-----------------------------------------------------------------*/
1200 isLabelInAst (symbol * label, ast * tree)
1202 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1205 if (IS_AST_OP (tree) &&
1206 tree->opval.op == LABEL &&
1207 isSymbolEqual (AST_SYMBOL (tree->left), label))
1210 return isLabelInAst (label, tree->right) &&
1211 isLabelInAst (label, tree->left);
1215 /*-----------------------------------------------------------------*/
1216 /* isLoopCountable - return true if the loop count can be determi- */
1217 /* -ned at compile time . */
1218 /*-----------------------------------------------------------------*/
1220 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1221 symbol ** sym, ast ** init, ast ** end)
1224 /* the loop is considered countable if the following
1225 conditions are true :-
1227 a) initExpr :- <sym> = <const>
1228 b) condExpr :- <sym> < <const1>
1229 c) loopExpr :- <sym> ++
1232 /* first check the initExpr */
1233 if (IS_AST_OP (initExpr) &&
1234 initExpr->opval.op == '=' && /* is assignment */
1235 IS_AST_SYM_VALUE (initExpr->left))
1236 { /* left is a symbol */
1238 *sym = AST_SYMBOL (initExpr->left);
1239 *init = initExpr->right;
1244 /* for now the symbol has to be of
1246 if (!IS_INTEGRAL ((*sym)->type))
1249 /* now check condExpr */
1250 if (IS_AST_OP (condExpr))
1253 switch (condExpr->opval.op)
1256 if (IS_AST_SYM_VALUE (condExpr->left) &&
1257 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1258 IS_AST_LIT_VALUE (condExpr->right))
1260 *end = condExpr->right;
1266 if (IS_AST_OP (condExpr->left) &&
1267 condExpr->left->opval.op == '>' &&
1268 IS_AST_LIT_VALUE (condExpr->left->right) &&
1269 IS_AST_SYM_VALUE (condExpr->left->left) &&
1270 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1273 *end = newNode ('+', condExpr->left->right,
1274 newAst_VALUE (constVal ("1")));
1285 /* check loop expression is of the form <sym>++ */
1286 if (!IS_AST_OP (loopExpr))
1289 /* check if <sym> ++ */
1290 if (loopExpr->opval.op == INC_OP)
1296 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1297 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1304 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1305 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1313 if (loopExpr->opval.op == ADD_ASSIGN)
1316 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1317 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1318 IS_AST_LIT_VALUE (loopExpr->right) &&
1319 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1327 /*-----------------------------------------------------------------*/
1328 /* astHasVolatile - returns true if ast contains any volatile */
1329 /*-----------------------------------------------------------------*/
1331 astHasVolatile (ast * tree)
1336 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1339 if (IS_AST_OP (tree))
1340 return astHasVolatile (tree->left) ||
1341 astHasVolatile (tree->right);
1346 /*-----------------------------------------------------------------*/
1347 /* astHasPointer - return true if the ast contains any ptr variable */
1348 /*-----------------------------------------------------------------*/
1350 astHasPointer (ast * tree)
1355 if (IS_AST_LINK (tree))
1358 /* if we hit an array expression then check
1359 only the left side */
1360 if (IS_AST_OP (tree) && tree->opval.op == '[')
1361 return astHasPointer (tree->left);
1363 if (IS_AST_VALUE (tree))
1364 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1366 return astHasPointer (tree->left) ||
1367 astHasPointer (tree->right);
1371 /*-----------------------------------------------------------------*/
1372 /* astHasSymbol - return true if the ast has the given symbol */
1373 /*-----------------------------------------------------------------*/
1375 astHasSymbol (ast * tree, symbol * sym)
1377 if (!tree || IS_AST_LINK (tree))
1380 if (IS_AST_VALUE (tree))
1382 if (IS_AST_SYM_VALUE (tree))
1383 return isSymbolEqual (AST_SYMBOL (tree), sym);
1388 return astHasSymbol (tree->left, sym) ||
1389 astHasSymbol (tree->right, sym);
1392 /*-----------------------------------------------------------------*/
1393 /* isConformingBody - the loop body has to conform to a set of rules */
1394 /* for the loop to be considered reversible read on for rules */
1395 /*-----------------------------------------------------------------*/
1397 isConformingBody (ast * pbody, symbol * sym, ast * body)
1400 /* we are going to do a pre-order traversal of the
1401 tree && check for the following conditions. (essentially
1402 a set of very shallow tests )
1403 a) the sym passed does not participate in
1404 any arithmetic operation
1405 b) There are no function calls
1406 c) all jumps are within the body
1407 d) address of loop control variable not taken
1408 e) if an assignment has a pointer on the
1409 left hand side make sure right does not have
1410 loop control variable */
1412 /* if we reach the end or a leaf then true */
1413 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1417 /* if anything else is "volatile" */
1418 if (IS_VOLATILE (TETYPE (pbody)))
1421 /* we will walk the body in a pre-order traversal for
1423 switch (pbody->opval.op)
1425 /*------------------------------------------------------------------*/
1427 return isConformingBody (pbody->right, sym, body);
1429 /*------------------------------------------------------------------*/
1434 /*------------------------------------------------------------------*/
1435 case INC_OP: /* incerement operator unary so left only */
1438 /* sure we are not sym is not modified */
1440 IS_AST_SYM_VALUE (pbody->left) &&
1441 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1445 IS_AST_SYM_VALUE (pbody->right) &&
1446 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1451 /*------------------------------------------------------------------*/
1453 case '*': /* can be unary : if right is null then unary operation */
1458 /* if right is NULL then unary operation */
1459 /*------------------------------------------------------------------*/
1460 /*----------------------------*/
1462 /*----------------------------*/
1465 if (IS_AST_SYM_VALUE (pbody->left) &&
1466 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1469 return isConformingBody (pbody->left, sym, body);
1473 if (astHasSymbol (pbody->left, sym) ||
1474 astHasSymbol (pbody->right, sym))
1479 /*------------------------------------------------------------------*/
1487 if (IS_AST_SYM_VALUE (pbody->left) &&
1488 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1491 if (IS_AST_SYM_VALUE (pbody->right) &&
1492 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1495 return isConformingBody (pbody->left, sym, body) &&
1496 isConformingBody (pbody->right, sym, body);
1503 if (IS_AST_SYM_VALUE (pbody->left) &&
1504 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1506 return isConformingBody (pbody->left, sym, body);
1508 /*------------------------------------------------------------------*/
1520 case SIZEOF: /* evaluate wihout code generation */
1522 return isConformingBody (pbody->left, sym, body) &&
1523 isConformingBody (pbody->right, sym, body);
1525 /*------------------------------------------------------------------*/
1528 /* if left has a pointer & right has loop
1529 control variable then we cannot */
1530 if (astHasPointer (pbody->left) &&
1531 astHasSymbol (pbody->right, sym))
1533 if (astHasVolatile (pbody->left))
1536 if (IS_AST_SYM_VALUE (pbody->left) &&
1537 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1540 if (astHasVolatile (pbody->left))
1543 return isConformingBody (pbody->left, sym, body) &&
1544 isConformingBody (pbody->right, sym, body);
1555 assert ("Parser should not have generated this\n");
1557 /*------------------------------------------------------------------*/
1558 /*----------------------------*/
1559 /* comma operator */
1560 /*----------------------------*/
1562 return isConformingBody (pbody->left, sym, body) &&
1563 isConformingBody (pbody->right, sym, body);
1565 /*------------------------------------------------------------------*/
1566 /*----------------------------*/
1568 /*----------------------------*/
1572 /*------------------------------------------------------------------*/
1573 /*----------------------------*/
1574 /* return statement */
1575 /*----------------------------*/
1580 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1585 if (astHasSymbol (pbody->left, sym))
1592 return isConformingBody (pbody->left, sym, body) &&
1593 isConformingBody (pbody->right, sym, body);
1599 /*-----------------------------------------------------------------*/
1600 /* isLoopReversible - takes a for loop as input && returns true */
1601 /* if the for loop is reversible. If yes will set the value of */
1602 /* the loop control var & init value & termination value */
1603 /*-----------------------------------------------------------------*/
1605 isLoopReversible (ast * loop, symbol ** loopCntrl,
1606 ast ** init, ast ** end)
1608 /* if option says don't do it then don't */
1609 if (optimize.noLoopReverse)
1611 /* there are several tests to determine this */
1613 /* for loop has to be of the form
1614 for ( <sym> = <const1> ;
1615 [<sym> < <const2>] ;
1616 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1618 if (!isLoopCountable (AST_FOR (loop, initExpr),
1619 AST_FOR (loop, condExpr),
1620 AST_FOR (loop, loopExpr),
1621 loopCntrl, init, end))
1624 /* now do some serious checking on the body of the loop
1627 return isConformingBody (loop->left, *loopCntrl, loop->left);
1631 /*-----------------------------------------------------------------*/
1632 /* replLoopSym - replace the loop sym by loop sym -1 */
1633 /*-----------------------------------------------------------------*/
1635 replLoopSym (ast * body, symbol * sym)
1638 if (!body || IS_AST_LINK (body))
1641 if (IS_AST_SYM_VALUE (body))
1644 if (isSymbolEqual (AST_SYMBOL (body), sym))
1648 body->opval.op = '-';
1649 body->left = newAst_VALUE (symbolVal (sym));
1650 body->right = newAst_VALUE (constVal ("1"));
1658 replLoopSym (body->left, sym);
1659 replLoopSym (body->right, sym);
1663 /*-----------------------------------------------------------------*/
1664 /* reverseLoop - do the actual loop reversal */
1665 /*-----------------------------------------------------------------*/
1667 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1671 /* create the following tree
1676 if (sym) goto for_continue ;
1679 /* put it together piece by piece */
1680 rloop = newNode (NULLOP,
1681 createIf (newAst_VALUE (symbolVal (sym)),
1683 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1686 newAst_VALUE (symbolVal (sym)),
1689 replLoopSym (loop->left, sym);
1691 rloop = newNode (NULLOP,
1693 newAst_VALUE (symbolVal (sym)),
1694 newNode ('-', end, init)),
1695 createLabel (AST_FOR (loop, continueLabel),
1699 newNode (SUB_ASSIGN,
1700 newAst_VALUE (symbolVal (sym)),
1701 newAst_VALUE (constVal ("1"))),
1704 return decorateType (rloop);
1708 #define DEMAND_INTEGER_PROMOTION
1710 #ifdef DEMAND_INTEGER_PROMOTION
1712 /*-----------------------------------------------------------------*/
1713 /* walk a tree looking for the leaves. Add a typecast to the given */
1714 /* type to each value leaf node. */
1715 /*-----------------------------------------------------------------*/
1717 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1719 if (!node || IS_CALLOP(node))
1721 /* WTF? We should never get here. */
1725 if (!node->left && !node->right)
1727 /* We're at a leaf; if it's a value, apply the typecast */
1728 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1730 *parentPtr = decorateType (newNode (CAST,
1731 newAst_LINK (copyLinkChain (type)),
1739 pushTypeCastToLeaves (type, node->left, &(node->left));
1743 pushTypeCastToLeaves (type, node->right, &(node->right));
1750 /*-----------------------------------------------------------------*/
1751 /* Given an assignment operation in a tree, determine if the LHS */
1752 /* (the result) has a different (integer) type than the RHS. */
1753 /* If so, walk the RHS and add a typecast to the type of the LHS */
1754 /* to all leaf nodes. */
1755 /*-----------------------------------------------------------------*/
1757 propAsgType (ast * tree)
1759 #ifdef DEMAND_INTEGER_PROMOTION
1760 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1762 /* Nothing to do here... */
1766 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1768 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1775 /*-----------------------------------------------------------------*/
1776 /* decorateType - compute type for this tree also does type cheking */
1777 /* this is done bottom up, since type have to flow upwards */
1778 /* it also does constant folding, and paramater checking */
1779 /*-----------------------------------------------------------------*/
1781 decorateType (ast * tree)
1789 /* if already has type then do nothing */
1790 if (tree->decorated)
1793 tree->decorated = 1;
1795 /* print the line */
1796 /* if not block & function */
1797 if (tree->type == EX_OP &&
1798 (tree->opval.op != FUNCTION &&
1799 tree->opval.op != BLOCK &&
1800 tree->opval.op != NULLOP))
1802 filename = tree->filename;
1803 lineno = tree->lineno;
1806 /* if any child is an error | this one is an error do nothing */
1807 if (tree->isError ||
1808 (tree->left && tree->left->isError) ||
1809 (tree->right && tree->right->isError))
1812 /*------------------------------------------------------------------*/
1813 /*----------------------------*/
1814 /* leaf has been reached */
1815 /*----------------------------*/
1816 /* if this is of type value */
1817 /* just get the type */
1818 if (tree->type == EX_VALUE)
1821 if (IS_LITERAL (tree->opval.val->etype))
1824 /* if this is a character array then declare it */
1825 if (IS_ARRAY (tree->opval.val->type))
1826 tree->opval.val = stringToSymbol (tree->opval.val);
1828 /* otherwise just copy the type information */
1829 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1830 if (funcInChain (tree->opval.val->type))
1832 tree->hasVargs = tree->opval.val->sym->hasVargs;
1833 tree->args = copyValueChain (tree->opval.val->sym->args);
1838 if (tree->opval.val->sym)
1840 /* if the undefined flag is set then give error message */
1841 if (tree->opval.val->sym->undefined)
1843 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1845 TTYPE (tree) = TETYPE (tree) =
1846 tree->opval.val->type = tree->opval.val->sym->type =
1847 tree->opval.val->etype = tree->opval.val->sym->etype =
1848 copyLinkChain (INTTYPE);
1853 /* if impilicit i.e. struct/union member then no type */
1854 if (tree->opval.val->sym->implicit)
1855 TTYPE (tree) = TETYPE (tree) = NULL;
1860 /* else copy the type */
1861 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1863 /* and mark it as referenced */
1864 tree->opval.val->sym->isref = 1;
1865 /* if this is of type function or function pointer */
1866 if (funcInChain (tree->opval.val->type))
1868 tree->hasVargs = tree->opval.val->sym->hasVargs;
1869 tree->args = copyValueChain (tree->opval.val->sym->args);
1879 /* if type link for the case of cast */
1880 if (tree->type == EX_LINK)
1882 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1889 dtl = decorateType (tree->left);
1890 dtr = decorateType (tree->right);
1892 /* this is to take care of situations
1893 when the tree gets rewritten */
1894 if (dtl != tree->left)
1896 if (dtr != tree->right)
1900 /* depending on type of operator do */
1902 switch (tree->opval.op)
1904 /*------------------------------------------------------------------*/
1905 /*----------------------------*/
1907 /*----------------------------*/
1910 /* determine which is the array & which the index */
1911 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1914 ast *tempTree = tree->left;
1915 tree->left = tree->right;
1916 tree->right = tempTree;
1919 /* first check if this is a array or a pointer */
1920 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1922 werror (E_NEED_ARRAY_PTR, "[]");
1923 goto errorTreeReturn;
1926 /* check if the type of the idx */
1927 if (!IS_INTEGRAL (RTYPE (tree)))
1929 werror (E_IDX_NOT_INT);
1930 goto errorTreeReturn;
1933 /* if the left is an rvalue then error */
1936 werror (E_LVALUE_REQUIRED, "array access");
1937 goto errorTreeReturn;
1940 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1941 if (IS_PTR(LTYPE(tree))) {
1942 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1946 /*------------------------------------------------------------------*/
1947 /*----------------------------*/
1949 /*----------------------------*/
1951 /* if this is not a structure */
1952 if (!IS_STRUCT (LTYPE (tree)))
1954 werror (E_STRUCT_UNION, ".");
1955 goto errorTreeReturn;
1957 TTYPE (tree) = structElemType (LTYPE (tree),
1958 (tree->right->type == EX_VALUE ?
1959 tree->right->opval.val : NULL), &tree->args);
1960 TETYPE (tree) = getSpec (TTYPE (tree));
1963 /*------------------------------------------------------------------*/
1964 /*----------------------------*/
1965 /* struct/union pointer */
1966 /*----------------------------*/
1968 /* if not pointer to a structure */
1969 if (!IS_PTR (LTYPE (tree)))
1971 werror (E_PTR_REQD);
1972 goto errorTreeReturn;
1975 if (!IS_STRUCT (LTYPE (tree)->next))
1977 werror (E_STRUCT_UNION, "->");
1978 goto errorTreeReturn;
1981 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1982 (tree->right->type == EX_VALUE ?
1983 tree->right->opval.val : NULL), &tree->args);
1984 TETYPE (tree) = getSpec (TTYPE (tree));
1987 /*------------------------------------------------------------------*/
1988 /*----------------------------*/
1989 /* ++/-- operation */
1990 /*----------------------------*/
1991 case INC_OP: /* incerement operator unary so left only */
1994 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1995 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1996 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
1997 werror (E_CODE_WRITE, "++/--");
2006 /*------------------------------------------------------------------*/
2007 /*----------------------------*/
2009 /*----------------------------*/
2010 case '&': /* can be unary */
2011 /* if right is NULL then unary operation */
2012 if (tree->right) /* not an unary operation */
2015 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2017 werror (E_BITWISE_OP);
2018 werror (E_CONTINUE, "left & right types are ");
2019 printTypeChain (LTYPE (tree), stderr);
2020 fprintf (stderr, ",");
2021 printTypeChain (RTYPE (tree), stderr);
2022 fprintf (stderr, "\n");
2023 goto errorTreeReturn;
2026 /* if they are both literal */
2027 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2029 tree->type = EX_VALUE;
2030 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2031 valFromType (RETYPE (tree)), '&');
2033 tree->right = tree->left = NULL;
2034 TETYPE (tree) = tree->opval.val->etype;
2035 TTYPE (tree) = tree->opval.val->type;
2039 /* see if this is a GETHBIT operation if yes
2042 ast *otree = optimizeGetHbit (tree);
2045 return decorateType (otree);
2048 /* if right or left is literal then result of that type */
2049 if (IS_LITERAL (RTYPE (tree)))
2052 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2053 TETYPE (tree) = getSpec (TTYPE (tree));
2054 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2058 if (IS_LITERAL (LTYPE (tree)))
2060 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2061 TETYPE (tree) = getSpec (TTYPE (tree));
2062 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2068 computeType (LTYPE (tree), RTYPE (tree));
2069 TETYPE (tree) = getSpec (TTYPE (tree));
2072 LRVAL (tree) = RRVAL (tree) = 1;
2076 /*------------------------------------------------------------------*/
2077 /*----------------------------*/
2079 /*----------------------------*/
2081 p->class = DECLARATOR;
2082 /* if bit field then error */
2083 if (IS_BITVAR (tree->left->etype))
2085 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2086 goto errorTreeReturn;
2089 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2091 werror (E_ILLEGAL_ADDR, "address of register variable");
2092 goto errorTreeReturn;
2095 if (IS_FUNC (LTYPE (tree)))
2097 werror (E_ILLEGAL_ADDR, "address of function");
2098 goto errorTreeReturn;
2103 werror (E_LVALUE_REQUIRED, "address of");
2104 goto errorTreeReturn;
2106 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2108 DCL_TYPE (p) = CPOINTER;
2109 DCL_PTR_CONST (p) = port->mem.code_ro;
2111 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2112 DCL_TYPE (p) = FPOINTER;
2113 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2114 DCL_TYPE (p) = PPOINTER;
2115 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2116 DCL_TYPE (p) = IPOINTER;
2117 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2118 DCL_TYPE (p) = EEPPOINTER;
2120 DCL_TYPE (p) = POINTER;
2122 if (IS_AST_SYM_VALUE (tree->left))
2124 AST_SYMBOL (tree->left)->addrtaken = 1;
2125 AST_SYMBOL (tree->left)->allocreq = 1;
2128 p->next = LTYPE (tree);
2130 TETYPE (tree) = getSpec (TTYPE (tree));
2131 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2132 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2137 /*------------------------------------------------------------------*/
2138 /*----------------------------*/
2140 /*----------------------------*/
2142 /* if the rewrite succeeds then don't go any furthur */
2144 ast *wtree = optimizeRRCRLC (tree);
2146 return decorateType (wtree);
2148 /*------------------------------------------------------------------*/
2149 /*----------------------------*/
2151 /*----------------------------*/
2153 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2155 werror (E_BITWISE_OP);
2156 werror (E_CONTINUE, "left & right types are ");
2157 printTypeChain (LTYPE (tree), stderr);
2158 fprintf (stderr, ",");
2159 printTypeChain (RTYPE (tree), stderr);
2160 fprintf (stderr, "\n");
2161 goto errorTreeReturn;
2164 /* if they are both literal then */
2165 /* rewrite the tree */
2166 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2168 tree->type = EX_VALUE;
2169 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2170 valFromType (RETYPE (tree)),
2172 tree->right = tree->left = NULL;
2173 TETYPE (tree) = tree->opval.val->etype;
2174 TTYPE (tree) = tree->opval.val->type;
2177 LRVAL (tree) = RRVAL (tree) = 1;
2178 TETYPE (tree) = getSpec (TTYPE (tree) =
2179 computeType (LTYPE (tree),
2182 /*------------------------------------------------------------------*/
2183 /*----------------------------*/
2185 /*----------------------------*/
2187 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2189 werror (E_INVALID_OP, "divide");
2190 goto errorTreeReturn;
2192 /* if they are both literal then */
2193 /* rewrite the tree */
2194 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2196 tree->type = EX_VALUE;
2197 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2198 valFromType (RETYPE (tree)));
2199 tree->right = tree->left = NULL;
2200 TETYPE (tree) = getSpec (TTYPE (tree) =
2201 tree->opval.val->type);
2204 LRVAL (tree) = RRVAL (tree) = 1;
2205 TETYPE (tree) = getSpec (TTYPE (tree) =
2206 computeType (LTYPE (tree),
2210 /*------------------------------------------------------------------*/
2211 /*----------------------------*/
2213 /*----------------------------*/
2215 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2217 werror (E_BITWISE_OP);
2218 werror (E_CONTINUE, "left & right types are ");
2219 printTypeChain (LTYPE (tree), stderr);
2220 fprintf (stderr, ",");
2221 printTypeChain (RTYPE (tree), stderr);
2222 fprintf (stderr, "\n");
2223 goto errorTreeReturn;
2225 /* if they are both literal then */
2226 /* rewrite the tree */
2227 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2229 tree->type = EX_VALUE;
2230 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2231 valFromType (RETYPE (tree)));
2232 tree->right = tree->left = NULL;
2233 TETYPE (tree) = getSpec (TTYPE (tree) =
2234 tree->opval.val->type);
2237 LRVAL (tree) = RRVAL (tree) = 1;
2238 TETYPE (tree) = getSpec (TTYPE (tree) =
2239 computeType (LTYPE (tree),
2243 /*------------------------------------------------------------------*/
2244 /*----------------------------*/
2245 /* address dereference */
2246 /*----------------------------*/
2247 case '*': /* can be unary : if right is null then unary operation */
2250 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2252 werror (E_PTR_REQD);
2253 goto errorTreeReturn;
2258 werror (E_LVALUE_REQUIRED, "pointer deref");
2259 goto errorTreeReturn;
2261 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2262 LTYPE (tree)->next : NULL);
2263 TETYPE (tree) = getSpec (TTYPE (tree));
2264 tree->args = tree->left->args;
2265 tree->hasVargs = tree->left->hasVargs;
2266 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2270 /*------------------------------------------------------------------*/
2271 /*----------------------------*/
2272 /* multiplication */
2273 /*----------------------------*/
2274 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2276 werror (E_INVALID_OP, "multiplication");
2277 goto errorTreeReturn;
2280 /* if they are both literal then */
2281 /* rewrite the tree */
2282 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2284 tree->type = EX_VALUE;
2285 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2286 valFromType (RETYPE (tree)));
2287 tree->right = tree->left = NULL;
2288 TETYPE (tree) = getSpec (TTYPE (tree) =
2289 tree->opval.val->type);
2293 /* if left is a literal exchange left & right */
2294 if (IS_LITERAL (LTYPE (tree)))
2296 ast *tTree = tree->left;
2297 tree->left = tree->right;
2298 tree->right = tTree;
2301 LRVAL (tree) = RRVAL (tree) = 1;
2302 /* promote result to int if left & right are char / short
2303 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2304 if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) &&
2305 (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
2306 TETYPE (tree) = getSpec (TTYPE (tree) =
2307 computeType (LTYPE (tree),
2309 SPEC_NOUN(TETYPE(tree)) = V_INT;
2310 SPEC_SHORT(TETYPE(tree))=0;
2312 TETYPE (tree) = getSpec (TTYPE (tree) =
2313 computeType (LTYPE (tree),
2318 /*------------------------------------------------------------------*/
2319 /*----------------------------*/
2320 /* unary '+' operator */
2321 /*----------------------------*/
2326 if (!IS_INTEGRAL (LTYPE (tree)))
2328 werror (E_UNARY_OP, '+');
2329 goto errorTreeReturn;
2332 /* if left is a literal then do it */
2333 if (IS_LITERAL (LTYPE (tree)))
2335 tree->type = EX_VALUE;
2336 tree->opval.val = valFromType (LETYPE (tree));
2338 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2342 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2346 /*------------------------------------------------------------------*/
2347 /*----------------------------*/
2349 /*----------------------------*/
2351 /* this is not a unary operation */
2352 /* if both pointers then problem */
2353 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2354 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2356 werror (E_PTR_PLUS_PTR);
2357 goto errorTreeReturn;
2360 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2361 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2363 werror (E_PLUS_INVALID, "+");
2364 goto errorTreeReturn;
2367 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2368 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2370 werror (E_PLUS_INVALID, "+");
2371 goto errorTreeReturn;
2373 /* if they are both literal then */
2374 /* rewrite the tree */
2375 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2377 tree->type = EX_VALUE;
2378 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2379 valFromType (RETYPE (tree)));
2380 tree->right = tree->left = NULL;
2381 TETYPE (tree) = getSpec (TTYPE (tree) =
2382 tree->opval.val->type);
2386 /* if the right is a pointer or left is a literal
2387 xchange left & right */
2388 if (IS_ARRAY (RTYPE (tree)) ||
2389 IS_PTR (RTYPE (tree)) ||
2390 IS_LITERAL (LTYPE (tree)))
2392 ast *tTree = tree->left;
2393 tree->left = tree->right;
2394 tree->right = tTree;
2397 LRVAL (tree) = RRVAL (tree) = 1;
2398 /* if the left is a pointer */
2399 if (IS_PTR (LTYPE (tree)))
2400 TETYPE (tree) = getSpec (TTYPE (tree) =
2403 TETYPE (tree) = getSpec (TTYPE (tree) =
2404 computeType (LTYPE (tree),
2408 /*------------------------------------------------------------------*/
2409 /*----------------------------*/
2411 /*----------------------------*/
2412 case '-': /* can be unary */
2413 /* if right is null then unary */
2417 if (!IS_ARITHMETIC (LTYPE (tree)))
2419 werror (E_UNARY_OP, tree->opval.op);
2420 goto errorTreeReturn;
2423 /* if left is a literal then do it */
2424 if (IS_LITERAL (LTYPE (tree)))
2426 tree->type = EX_VALUE;
2427 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2429 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2430 SPEC_USIGN(TETYPE(tree)) = 0;
2434 TTYPE (tree) = LTYPE (tree);
2438 /*------------------------------------------------------------------*/
2439 /*----------------------------*/
2441 /*----------------------------*/
2443 if (!(IS_PTR (LTYPE (tree)) ||
2444 IS_ARRAY (LTYPE (tree)) ||
2445 IS_ARITHMETIC (LTYPE (tree))))
2447 werror (E_PLUS_INVALID, "-");
2448 goto errorTreeReturn;
2451 if (!(IS_PTR (RTYPE (tree)) ||
2452 IS_ARRAY (RTYPE (tree)) ||
2453 IS_ARITHMETIC (RTYPE (tree))))
2455 werror (E_PLUS_INVALID, "-");
2456 goto errorTreeReturn;
2459 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2460 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2461 IS_INTEGRAL (RTYPE (tree))))
2463 werror (E_PLUS_INVALID, "-");
2464 goto errorTreeReturn;
2467 /* if they are both literal then */
2468 /* rewrite the tree */
2469 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2471 tree->type = EX_VALUE;
2472 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2473 valFromType (RETYPE (tree)));
2474 tree->right = tree->left = NULL;
2475 TETYPE (tree) = getSpec (TTYPE (tree) =
2476 tree->opval.val->type);
2480 /* if the left & right are equal then zero */
2481 if (isAstEqual (tree->left, tree->right))
2483 tree->type = EX_VALUE;
2484 tree->left = tree->right = NULL;
2485 tree->opval.val = constVal ("0");
2486 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2490 /* if both of them are pointers or arrays then */
2491 /* the result is going to be an integer */
2492 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2493 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2494 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2496 /* if only the left is a pointer */
2497 /* then result is a pointer */
2498 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2499 TETYPE (tree) = getSpec (TTYPE (tree) =
2502 TETYPE (tree) = getSpec (TTYPE (tree) =
2503 computeType (LTYPE (tree),
2505 LRVAL (tree) = RRVAL (tree) = 1;
2508 /*------------------------------------------------------------------*/
2509 /*----------------------------*/
2511 /*----------------------------*/
2513 /* can be only integral type */
2514 if (!IS_INTEGRAL (LTYPE (tree)))
2516 werror (E_UNARY_OP, tree->opval.op);
2517 goto errorTreeReturn;
2520 /* if left is a literal then do it */
2521 if (IS_LITERAL (LTYPE (tree)))
2523 tree->type = EX_VALUE;
2524 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2526 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2530 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2533 /*------------------------------------------------------------------*/
2534 /*----------------------------*/
2536 /*----------------------------*/
2538 /* can be pointer */
2539 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2540 !IS_PTR (LTYPE (tree)) &&
2541 !IS_ARRAY (LTYPE (tree)))
2543 werror (E_UNARY_OP, tree->opval.op);
2544 goto errorTreeReturn;
2547 /* if left is a literal then do it */
2548 if (IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2553 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2557 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2560 /*------------------------------------------------------------------*/
2561 /*----------------------------*/
2563 /*----------------------------*/
2566 TTYPE (tree) = LTYPE (tree);
2567 TETYPE (tree) = LETYPE (tree);
2571 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2576 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2578 werror (E_SHIFT_OP_INVALID);
2579 werror (E_CONTINUE, "left & right types are ");
2580 printTypeChain (LTYPE (tree), stderr);
2581 fprintf (stderr, ",");
2582 printTypeChain (RTYPE (tree), stderr);
2583 fprintf (stderr, "\n");
2584 goto errorTreeReturn;
2587 /* if they are both literal then */
2588 /* rewrite the tree */
2589 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2591 tree->type = EX_VALUE;
2592 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2593 valFromType (RETYPE (tree)),
2594 (tree->opval.op == LEFT_OP ? 1 : 0));
2595 tree->right = tree->left = NULL;
2596 TETYPE (tree) = getSpec (TTYPE (tree) =
2597 tree->opval.val->type);
2600 /* if only the right side is a literal & we are
2601 shifting more than size of the left operand then zero */
2602 if (IS_LITERAL (RTYPE (tree)) &&
2603 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2604 (getSize (LTYPE (tree)) * 8))
2606 werror (W_SHIFT_CHANGED,
2607 (tree->opval.op == LEFT_OP ? "left" : "right"));
2608 tree->type = EX_VALUE;
2609 tree->left = tree->right = NULL;
2610 tree->opval.val = constVal ("0");
2611 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2614 LRVAL (tree) = RRVAL (tree) = 1;
2615 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2617 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2621 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2625 /*------------------------------------------------------------------*/
2626 /*----------------------------*/
2628 /*----------------------------*/
2629 case CAST: /* change the type */
2630 /* cannot cast to an aggregate type */
2631 if (IS_AGGREGATE (LTYPE (tree)))
2633 werror (E_CAST_ILLEGAL);
2634 goto errorTreeReturn;
2637 /* make sure the type is complete and sane */
2638 checkTypeSanity(LETYPE(tree), "(cast)");
2640 /* if the right is a literal replace the tree */
2641 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2643 tree->type = EX_VALUE;
2645 valCastLiteral (LTYPE (tree),
2646 floatFromVal (valFromType (RETYPE (tree))));
2649 TTYPE (tree) = tree->opval.val->type;
2650 tree->values.literalFromCast = 1;
2654 TTYPE (tree) = LTYPE (tree);
2658 TETYPE (tree) = getSpec (TTYPE (tree));
2662 /*------------------------------------------------------------------*/
2663 /*----------------------------*/
2664 /* logical &&, || */
2665 /*----------------------------*/
2668 /* each must me arithmetic type or be a pointer */
2669 if (!IS_PTR (LTYPE (tree)) &&
2670 !IS_ARRAY (LTYPE (tree)) &&
2671 !IS_INTEGRAL (LTYPE (tree)))
2673 werror (E_COMPARE_OP);
2674 goto errorTreeReturn;
2677 if (!IS_PTR (RTYPE (tree)) &&
2678 !IS_ARRAY (RTYPE (tree)) &&
2679 !IS_INTEGRAL (RTYPE (tree)))
2681 werror (E_COMPARE_OP);
2682 goto errorTreeReturn;
2684 /* if they are both literal then */
2685 /* rewrite the tree */
2686 if (IS_LITERAL (RTYPE (tree)) &&
2687 IS_LITERAL (LTYPE (tree)))
2689 tree->type = EX_VALUE;
2690 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2691 valFromType (RETYPE (tree)),
2693 tree->right = tree->left = NULL;
2694 TETYPE (tree) = getSpec (TTYPE (tree) =
2695 tree->opval.val->type);
2698 LRVAL (tree) = RRVAL (tree) = 1;
2699 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2702 /*------------------------------------------------------------------*/
2703 /*----------------------------*/
2704 /* comparison operators */
2705 /*----------------------------*/
2713 ast *lt = optimizeCompare (tree);
2719 /* if they are pointers they must be castable */
2720 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2722 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2724 werror (E_COMPARE_OP);
2725 fprintf (stderr, "comparing type ");
2726 printTypeChain (LTYPE (tree), stderr);
2727 fprintf (stderr, "to type ");
2728 printTypeChain (RTYPE (tree), stderr);
2729 fprintf (stderr, "\n");
2730 goto errorTreeReturn;
2733 /* else they should be promotable to one another */
2736 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2737 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2739 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2741 werror (E_COMPARE_OP);
2742 fprintf (stderr, "comparing type ");
2743 printTypeChain (LTYPE (tree), stderr);
2744 fprintf (stderr, "to type ");
2745 printTypeChain (RTYPE (tree), stderr);
2746 fprintf (stderr, "\n");
2747 goto errorTreeReturn;
2751 /* if they are both literal then */
2752 /* rewrite the tree */
2753 if (IS_LITERAL (RTYPE (tree)) &&
2754 IS_LITERAL (LTYPE (tree)))
2756 tree->type = EX_VALUE;
2757 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2758 valFromType (RETYPE (tree)),
2760 tree->right = tree->left = NULL;
2761 TETYPE (tree) = getSpec (TTYPE (tree) =
2762 tree->opval.val->type);
2765 LRVAL (tree) = RRVAL (tree) = 1;
2766 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2769 /*------------------------------------------------------------------*/
2770 /*----------------------------*/
2772 /*----------------------------*/
2773 case SIZEOF: /* evaluate wihout code generation */
2774 /* change the type to a integer */
2775 tree->type = EX_VALUE;
2776 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2777 tree->opval.val = constVal (buffer);
2778 tree->right = tree->left = NULL;
2779 TETYPE (tree) = getSpec (TTYPE (tree) =
2780 tree->opval.val->type);
2783 /*------------------------------------------------------------------*/
2784 /*----------------------------*/
2785 /* conditional operator '?' */
2786 /*----------------------------*/
2788 /* the type is one on the left */
2789 TTYPE (tree) = LTYPE (tree);
2790 TETYPE (tree) = getSpec (TTYPE (tree));
2794 /* if they don't match we have a problem */
2795 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2797 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2798 goto errorTreeReturn;
2801 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2802 TETYPE (tree) = getSpec (TTYPE (tree));
2806 /*------------------------------------------------------------------*/
2807 /*----------------------------*/
2808 /* assignment operators */
2809 /*----------------------------*/
2812 /* for these it must be both must be integral */
2813 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2814 !IS_ARITHMETIC (RTYPE (tree)))
2816 werror (E_OPS_INTEGRAL);
2817 goto errorTreeReturn;
2820 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2822 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2823 werror (E_CODE_WRITE, " ");
2827 werror (E_LVALUE_REQUIRED, "*= or /=");
2828 goto errorTreeReturn;
2841 /* for these it must be both must be integral */
2842 if (!IS_INTEGRAL (LTYPE (tree)) ||
2843 !IS_INTEGRAL (RTYPE (tree)))
2845 werror (E_OPS_INTEGRAL);
2846 goto errorTreeReturn;
2849 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2851 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2852 werror (E_CODE_WRITE, " ");
2856 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2857 goto errorTreeReturn;
2865 /*------------------------------------------------------------------*/
2866 /*----------------------------*/
2868 /*----------------------------*/
2870 if (!(IS_PTR (LTYPE (tree)) ||
2871 IS_ARITHMETIC (LTYPE (tree))))
2873 werror (E_PLUS_INVALID, "-=");
2874 goto errorTreeReturn;
2877 if (!(IS_PTR (RTYPE (tree)) ||
2878 IS_ARITHMETIC (RTYPE (tree))))
2880 werror (E_PLUS_INVALID, "-=");
2881 goto errorTreeReturn;
2884 TETYPE (tree) = getSpec (TTYPE (tree) =
2885 computeType (LTYPE (tree),
2888 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2889 werror (E_CODE_WRITE, " ");
2893 werror (E_LVALUE_REQUIRED, "-=");
2894 goto errorTreeReturn;
2902 /*------------------------------------------------------------------*/
2903 /*----------------------------*/
2905 /*----------------------------*/
2907 /* this is not a unary operation */
2908 /* if both pointers then problem */
2909 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2911 werror (E_PTR_PLUS_PTR);
2912 goto errorTreeReturn;
2915 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2917 werror (E_PLUS_INVALID, "+=");
2918 goto errorTreeReturn;
2921 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2923 werror (E_PLUS_INVALID, "+=");
2924 goto errorTreeReturn;
2927 TETYPE (tree) = getSpec (TTYPE (tree) =
2928 computeType (LTYPE (tree),
2931 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2932 werror (E_CODE_WRITE, " ");
2936 werror (E_LVALUE_REQUIRED, "+=");
2937 goto errorTreeReturn;
2940 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2941 tree->opval.op = '=';
2947 /*------------------------------------------------------------------*/
2948 /*----------------------------*/
2949 /* straight assignemnt */
2950 /*----------------------------*/
2952 /* cannot be an aggregate */
2953 if (IS_AGGREGATE (LTYPE (tree)))
2955 werror (E_AGGR_ASSIGN);
2956 goto errorTreeReturn;
2959 /* they should either match or be castable */
2960 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2962 werror (E_TYPE_MISMATCH, "assignment", " ");
2963 fprintf (stderr, "type --> '");
2964 printTypeChain (RTYPE (tree), stderr);
2965 fprintf (stderr, "' ");
2966 fprintf (stderr, "assigned to type --> '");
2967 printTypeChain (LTYPE (tree), stderr);
2968 fprintf (stderr, "'\n");
2969 goto errorTreeReturn;
2972 /* if the left side of the tree is of type void
2973 then report error */
2974 if (IS_VOID (LTYPE (tree)))
2976 werror (E_CAST_ZERO);
2977 fprintf (stderr, "type --> '");
2978 printTypeChain (RTYPE (tree), stderr);
2979 fprintf (stderr, "' ");
2980 fprintf (stderr, "assigned to type --> '");
2981 printTypeChain (LTYPE (tree), stderr);
2982 fprintf (stderr, "'\n");
2985 /* extra checks for pointer types */
2986 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2987 !IS_GENPTR (LTYPE (tree)))
2989 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2990 werror (W_PTR_ASSIGN);
2993 TETYPE (tree) = getSpec (TTYPE (tree) =
2997 if (!tree->initMode ) {
2998 if (IS_CONSTANT (LETYPE (tree))) {
2999 werror (E_CODE_WRITE, " ");
3004 werror (E_LVALUE_REQUIRED, "=");
3005 goto errorTreeReturn;
3012 /*------------------------------------------------------------------*/
3013 /*----------------------------*/
3014 /* comma operator */
3015 /*----------------------------*/
3017 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3020 /*------------------------------------------------------------------*/
3021 /*----------------------------*/
3023 /*----------------------------*/
3027 if (processParms (tree->left,
3029 tree->right, &parmNumber, TRUE))
3030 goto errorTreeReturn;
3032 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3034 tree->left->args = reverseVal (tree->left->args);
3035 reverseParms (tree->right);
3038 tree->args = tree->left->args;
3039 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3042 /*------------------------------------------------------------------*/
3043 /*----------------------------*/
3044 /* return statement */
3045 /*----------------------------*/
3050 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3052 werror (E_RETURN_MISMATCH);
3053 goto errorTreeReturn;
3056 if (IS_VOID (currFunc->type->next)
3058 !IS_VOID (RTYPE (tree)))
3060 werror (E_FUNC_VOID);
3061 goto errorTreeReturn;
3064 /* if there is going to be a casing required then add it */
3065 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3067 #if 0 && defined DEMAND_INTEGER_PROMOTION
3068 if (IS_INTEGRAL (currFunc->type->next))
3070 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3076 decorateType (newNode (CAST,
3077 newAst_LINK (copyLinkChain (currFunc->type->next)),
3087 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3089 werror (E_VOID_FUNC, currFunc->name);
3090 goto errorTreeReturn;
3093 TTYPE (tree) = TETYPE (tree) = NULL;
3096 /*------------------------------------------------------------------*/
3097 /*----------------------------*/
3098 /* switch statement */
3099 /*----------------------------*/
3101 /* the switch value must be an integer */
3102 if (!IS_INTEGRAL (LTYPE (tree)))
3104 werror (E_SWITCH_NON_INTEGER);
3105 goto errorTreeReturn;
3108 TTYPE (tree) = TETYPE (tree) = NULL;
3111 /*------------------------------------------------------------------*/
3112 /*----------------------------*/
3114 /*----------------------------*/
3116 tree->left = backPatchLabels (tree->left,
3119 TTYPE (tree) = TETYPE (tree) = NULL;
3122 /*------------------------------------------------------------------*/
3123 /*----------------------------*/
3125 /*----------------------------*/
3128 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3129 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3130 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3132 /* if the for loop is reversible then
3133 reverse it otherwise do what we normally
3139 if (isLoopReversible (tree, &sym, &init, &end))
3140 return reverseLoop (tree, sym, init, end);
3142 return decorateType (createFor (AST_FOR (tree, trueLabel),
3143 AST_FOR (tree, continueLabel),
3144 AST_FOR (tree, falseLabel),
3145 AST_FOR (tree, condLabel),
3146 AST_FOR (tree, initExpr),
3147 AST_FOR (tree, condExpr),
3148 AST_FOR (tree, loopExpr),
3152 TTYPE (tree) = TETYPE (tree) = NULL;
3156 /* some error found this tree will be killed */
3158 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3159 tree->opval.op = NULLOP;
3165 /*-----------------------------------------------------------------*/
3166 /* sizeofOp - processes size of operation */
3167 /*-----------------------------------------------------------------*/
3169 sizeofOp (sym_link * type)
3173 /* make sure the type is complete and sane */
3174 checkTypeSanity(type, "(sizeof)");
3176 /* get the size and convert it to character */
3177 sprintf (buff, "%d", getSize (type));
3179 /* now convert into value */
3180 return constVal (buff);
3184 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3185 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3186 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3187 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3188 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3189 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3190 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3192 /*-----------------------------------------------------------------*/
3193 /* backPatchLabels - change and or not operators to flow control */
3194 /*-----------------------------------------------------------------*/
3196 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3202 if (!(IS_ANDORNOT (tree)))
3205 /* if this an and */
3208 static int localLbl = 0;
3211 sprintf (buffer, "_and_%d", localLbl++);
3212 localLabel = newSymbol (buffer, NestLevel);
3214 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3216 /* if left is already a IFX then just change the if true label in that */
3217 if (!IS_IFX (tree->left))
3218 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3220 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3221 /* right is a IFX then just join */
3222 if (IS_IFX (tree->right))
3223 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3225 tree->right = createLabel (localLabel, tree->right);
3226 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3228 return newNode (NULLOP, tree->left, tree->right);
3231 /* if this is an or operation */
3234 static int localLbl = 0;
3237 sprintf (buffer, "_or_%d", localLbl++);
3238 localLabel = newSymbol (buffer, NestLevel);
3240 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3242 /* if left is already a IFX then just change the if true label in that */
3243 if (!IS_IFX (tree->left))
3244 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3246 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3247 /* right is a IFX then just join */
3248 if (IS_IFX (tree->right))
3249 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3251 tree->right = createLabel (localLabel, tree->right);
3252 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3254 return newNode (NULLOP, tree->left, tree->right);
3260 int wasnot = IS_NOT (tree->left);
3261 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3263 /* if the left is already a IFX */
3264 if (!IS_IFX (tree->left))
3265 tree->left = newNode (IFX, tree->left, NULL);
3269 tree->left->trueLabel = trueLabel;
3270 tree->left->falseLabel = falseLabel;
3274 tree->left->trueLabel = falseLabel;
3275 tree->left->falseLabel = trueLabel;
3282 tree->trueLabel = trueLabel;
3283 tree->falseLabel = falseLabel;
3290 /*-----------------------------------------------------------------*/
3291 /* createBlock - create expression tree for block */
3292 /*-----------------------------------------------------------------*/
3294 createBlock (symbol * decl, ast * body)
3298 /* if the block has nothing */
3302 ex = newNode (BLOCK, NULL, body);
3303 ex->values.sym = decl;
3305 ex->right = ex->right;
3311 /*-----------------------------------------------------------------*/
3312 /* createLabel - creates the expression tree for labels */
3313 /*-----------------------------------------------------------------*/
3315 createLabel (symbol * label, ast * stmnt)
3318 char name[SDCC_NAME_MAX + 1];
3321 /* must create fresh symbol if the symbol name */
3322 /* exists in the symbol table, since there can */
3323 /* be a variable with the same name as the labl */
3324 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3325 (csym->level == label->level))
3326 label = newSymbol (label->name, label->level);
3328 /* change the name before putting it in add _ */
3329 sprintf (name, "%s", label->name);
3331 /* put the label in the LabelSymbol table */
3332 /* but first check if a label of the same */
3334 if ((csym = findSym (LabelTab, NULL, name)))
3335 werror (E_DUPLICATE_LABEL, label->name);
3337 addSym (LabelTab, label, name, label->level, 0);
3340 label->key = labelKey++;
3341 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3347 /*-----------------------------------------------------------------*/
3348 /* createCase - generates the parsetree for a case statement */
3349 /*-----------------------------------------------------------------*/
3351 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3353 char caseLbl[SDCC_NAME_MAX + 1];
3357 /* if the switch statement does not exist */
3358 /* then case is out of context */
3361 werror (E_CASE_CONTEXT);
3365 caseVal = decorateType (resolveSymbols (caseVal));
3366 /* if not a constant then error */
3367 if (!IS_LITERAL (caseVal->ftype))
3369 werror (E_CASE_CONSTANT);
3373 /* if not a integer than error */
3374 if (!IS_INTEGRAL (caseVal->ftype))
3376 werror (E_CASE_NON_INTEGER);
3380 /* find the end of the switch values chain */
3381 if (!(val = swStat->values.switchVals.swVals))
3382 swStat->values.switchVals.swVals = caseVal->opval.val;
3385 /* also order the cases according to value */
3387 int cVal = (int) floatFromVal (caseVal->opval.val);
3388 while (val && (int) floatFromVal (val) < cVal)
3394 /* if we reached the end then */
3397 pval->next = caseVal->opval.val;
3401 /* we found a value greater than */
3402 /* the current value we must add this */
3403 /* before the value */
3404 caseVal->opval.val->next = val;
3406 /* if this was the first in chain */
3407 if (swStat->values.switchVals.swVals == val)
3408 swStat->values.switchVals.swVals =
3411 pval->next = caseVal->opval.val;
3416 /* create the case label */
3417 sprintf (caseLbl, "_case_%d_%d",
3418 swStat->values.switchVals.swNum,
3419 (int) floatFromVal (caseVal->opval.val));
3421 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3426 /*-----------------------------------------------------------------*/
3427 /* createDefault - creates the parse tree for the default statement */
3428 /*-----------------------------------------------------------------*/
3430 createDefault (ast * swStat, ast * stmnt)
3432 char defLbl[SDCC_NAME_MAX + 1];
3434 /* if the switch statement does not exist */
3435 /* then case is out of context */
3438 werror (E_CASE_CONTEXT);
3442 /* turn on the default flag */
3443 swStat->values.switchVals.swDefault = 1;
3445 /* create the label */
3446 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3447 return createLabel (newSymbol (defLbl, 0), stmnt);
3450 /*-----------------------------------------------------------------*/
3451 /* createIf - creates the parsetree for the if statement */
3452 /*-----------------------------------------------------------------*/
3454 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3456 static int Lblnum = 0;
3458 symbol *ifTrue, *ifFalse, *ifEnd;
3460 /* if neither exists */
3461 if (!elseBody && !ifBody)
3464 /* create the labels */
3465 sprintf (buffer, "_iffalse_%d", Lblnum);
3466 ifFalse = newSymbol (buffer, NestLevel);
3467 /* if no else body then end == false */
3472 sprintf (buffer, "_ifend_%d", Lblnum);
3473 ifEnd = newSymbol (buffer, NestLevel);
3476 sprintf (buffer, "_iftrue_%d", Lblnum);
3477 ifTrue = newSymbol (buffer, NestLevel);
3481 /* attach the ifTrue label to the top of it body */
3482 ifBody = createLabel (ifTrue, ifBody);
3483 /* attach a goto end to the ifBody if else is present */
3486 ifBody = newNode (NULLOP, ifBody,
3488 newAst_VALUE (symbolVal (ifEnd)),
3490 /* put the elseLabel on the else body */
3491 elseBody = createLabel (ifFalse, elseBody);
3492 /* out the end at the end of the body */
3493 elseBody = newNode (NULLOP,
3495 createLabel (ifEnd, NULL));
3499 ifBody = newNode (NULLOP, ifBody,
3500 createLabel (ifFalse, NULL));
3502 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3503 if (IS_IFX (condAst))
3506 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3508 return newNode (NULLOP, ifTree,
3509 newNode (NULLOP, ifBody, elseBody));
3513 /*-----------------------------------------------------------------*/
3514 /* createDo - creates parse tree for do */
3517 /* _docontinue_n: */
3518 /* condition_expression +-> trueLabel -> _dobody_n */
3520 /* +-> falseLabel-> _dobreak_n */
3522 /*-----------------------------------------------------------------*/
3524 createDo (symbol * trueLabel, symbol * continueLabel,
3525 symbol * falseLabel, ast * condAst, ast * doBody)
3530 /* if the body does not exist then it is simple */
3533 condAst = backPatchLabels (condAst, continueLabel, NULL);
3534 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3535 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3536 doTree->trueLabel = continueLabel;
3537 doTree->falseLabel = NULL;
3541 /* otherwise we have a body */
3542 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3544 /* attach the body label to the top */
3545 doBody = createLabel (trueLabel, doBody);
3546 /* attach the continue label to end of body */
3547 doBody = newNode (NULLOP, doBody,
3548 createLabel (continueLabel, NULL));
3550 /* now put the break label at the end */
3551 if (IS_IFX (condAst))
3554 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3556 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3558 /* putting it together */
3559 return newNode (NULLOP, doBody, doTree);
3562 /*-----------------------------------------------------------------*/
3563 /* createFor - creates parse tree for 'for' statement */
3566 /* condExpr +-> trueLabel -> _forbody_n */
3568 /* +-> falseLabel-> _forbreak_n */
3571 /* _forcontinue_n: */
3573 /* goto _forcond_n ; */
3575 /*-----------------------------------------------------------------*/
3577 createFor (symbol * trueLabel, symbol * continueLabel,
3578 symbol * falseLabel, symbol * condLabel,
3579 ast * initExpr, ast * condExpr, ast * loopExpr,
3584 /* if loopexpression not present then we can generate it */
3585 /* the same way as a while */
3587 return newNode (NULLOP, initExpr,
3588 createWhile (trueLabel, continueLabel,
3589 falseLabel, condExpr, forBody));
3590 /* vanilla for statement */
3591 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3593 if (condExpr && !IS_IFX (condExpr))
3594 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3597 /* attach condition label to condition */
3598 condExpr = createLabel (condLabel, condExpr);
3600 /* attach body label to body */
3601 forBody = createLabel (trueLabel, forBody);
3603 /* attach continue to forLoop expression & attach */
3604 /* goto the forcond @ and of loopExpression */
3605 loopExpr = createLabel (continueLabel,
3609 newAst_VALUE (symbolVal (condLabel)),
3611 /* now start putting them together */
3612 forTree = newNode (NULLOP, initExpr, condExpr);
3613 forTree = newNode (NULLOP, forTree, forBody);
3614 forTree = newNode (NULLOP, forTree, loopExpr);
3615 /* finally add the break label */
3616 forTree = newNode (NULLOP, forTree,
3617 createLabel (falseLabel, NULL));
3621 /*-----------------------------------------------------------------*/
3622 /* createWhile - creates parse tree for while statement */
3623 /* the while statement will be created as follows */
3625 /* _while_continue_n: */
3626 /* condition_expression +-> trueLabel -> _while_boby_n */
3628 /* +-> falseLabel -> _while_break_n */
3629 /* _while_body_n: */
3631 /* goto _while_continue_n */
3632 /* _while_break_n: */
3633 /*-----------------------------------------------------------------*/
3635 createWhile (symbol * trueLabel, symbol * continueLabel,
3636 symbol * falseLabel, ast * condExpr, ast * whileBody)
3640 /* put the continue label */
3641 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3642 condExpr = createLabel (continueLabel, condExpr);
3643 condExpr->lineno = 0;
3645 /* put the body label in front of the body */
3646 whileBody = createLabel (trueLabel, whileBody);
3647 whileBody->lineno = 0;
3648 /* put a jump to continue at the end of the body */
3649 /* and put break label at the end of the body */
3650 whileBody = newNode (NULLOP,
3653 newAst_VALUE (symbolVal (continueLabel)),
3654 createLabel (falseLabel, NULL)));
3656 /* put it all together */
3657 if (IS_IFX (condExpr))
3658 whileTree = condExpr;
3661 whileTree = newNode (IFX, condExpr, NULL);
3662 /* put the true & false labels in place */
3663 whileTree->trueLabel = trueLabel;
3664 whileTree->falseLabel = falseLabel;
3667 return newNode (NULLOP, whileTree, whileBody);
3670 /*-----------------------------------------------------------------*/
3671 /* optimizeGetHbit - get highest order bit of the expression */
3672 /*-----------------------------------------------------------------*/
3674 optimizeGetHbit (ast * tree)
3677 /* if this is not a bit and */
3678 if (!IS_BITAND (tree))
3681 /* will look for tree of the form
3682 ( expr >> ((sizeof expr) -1) ) & 1 */
3683 if (!IS_AST_LIT_VALUE (tree->right))
3686 if (AST_LIT_VALUE (tree->right) != 1)
3689 if (!IS_RIGHT_OP (tree->left))
3692 if (!IS_AST_LIT_VALUE (tree->left->right))
3695 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3696 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3699 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3703 /*-----------------------------------------------------------------*/
3704 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3705 /*-----------------------------------------------------------------*/
3707 optimizeRRCRLC (ast * root)
3709 /* will look for trees of the form
3710 (?expr << 1) | (?expr >> 7) or
3711 (?expr >> 7) | (?expr << 1) will make that
3712 into a RLC : operation ..
3714 (?expr >> 1) | (?expr << 7) or
3715 (?expr << 7) | (?expr >> 1) will make that
3716 into a RRC operation
3717 note : by 7 I mean (number of bits required to hold the
3719 /* if the root operations is not a | operation the not */
3720 if (!IS_BITOR (root))
3723 /* I have to think of a better way to match patterns this sucks */
3724 /* that aside let start looking for the first case : I use a the
3725 negative check a lot to improve the efficiency */
3726 /* (?expr << 1) | (?expr >> 7) */
3727 if (IS_LEFT_OP (root->left) &&
3728 IS_RIGHT_OP (root->right))
3731 if (!SPEC_USIGN (TETYPE (root->left->left)))
3734 if (!IS_AST_LIT_VALUE (root->left->right) ||
3735 !IS_AST_LIT_VALUE (root->right->right))
3738 /* make sure it is the same expression */
3739 if (!isAstEqual (root->left->left,
3743 if (AST_LIT_VALUE (root->left->right) != 1)
3746 if (AST_LIT_VALUE (root->right->right) !=
3747 (getSize (TTYPE (root->left->left)) * 8 - 1))
3750 /* whew got the first case : create the AST */
3751 return newNode (RLC, root->left->left, NULL);
3755 /* check for second case */
3756 /* (?expr >> 7) | (?expr << 1) */
3757 if (IS_LEFT_OP (root->right) &&
3758 IS_RIGHT_OP (root->left))
3761 if (!SPEC_USIGN (TETYPE (root->left->left)))
3764 if (!IS_AST_LIT_VALUE (root->left->right) ||
3765 !IS_AST_LIT_VALUE (root->right->right))
3768 /* make sure it is the same symbol */
3769 if (!isAstEqual (root->left->left,
3773 if (AST_LIT_VALUE (root->right->right) != 1)
3776 if (AST_LIT_VALUE (root->left->right) !=
3777 (getSize (TTYPE (root->left->left)) * 8 - 1))
3780 /* whew got the first case : create the AST */
3781 return newNode (RLC, root->left->left, NULL);
3786 /* third case for RRC */
3787 /* (?symbol >> 1) | (?symbol << 7) */
3788 if (IS_LEFT_OP (root->right) &&
3789 IS_RIGHT_OP (root->left))
3792 if (!SPEC_USIGN (TETYPE (root->left->left)))
3795 if (!IS_AST_LIT_VALUE (root->left->right) ||
3796 !IS_AST_LIT_VALUE (root->right->right))
3799 /* make sure it is the same symbol */
3800 if (!isAstEqual (root->left->left,
3804 if (AST_LIT_VALUE (root->left->right) != 1)
3807 if (AST_LIT_VALUE (root->right->right) !=
3808 (getSize (TTYPE (root->left->left)) * 8 - 1))
3811 /* whew got the first case : create the AST */
3812 return newNode (RRC, root->left->left, NULL);
3816 /* fourth and last case for now */
3817 /* (?symbol << 7) | (?symbol >> 1) */
3818 if (IS_RIGHT_OP (root->right) &&
3819 IS_LEFT_OP (root->left))
3822 if (!SPEC_USIGN (TETYPE (root->left->left)))
3825 if (!IS_AST_LIT_VALUE (root->left->right) ||
3826 !IS_AST_LIT_VALUE (root->right->right))
3829 /* make sure it is the same symbol */
3830 if (!isAstEqual (root->left->left,
3834 if (AST_LIT_VALUE (root->right->right) != 1)
3837 if (AST_LIT_VALUE (root->left->right) !=
3838 (getSize (TTYPE (root->left->left)) * 8 - 1))
3841 /* whew got the first case : create the AST */
3842 return newNode (RRC, root->left->left, NULL);
3846 /* not found return root */
3850 /*-----------------------------------------------------------------*/
3851 /* optimizeCompare - otimizes compares for bit variables */
3852 /*-----------------------------------------------------------------*/
3854 optimizeCompare (ast * root)
3856 ast *optExpr = NULL;
3859 unsigned int litValue;
3861 /* if nothing then return nothing */
3865 /* if not a compare op then do leaves */
3866 if (!IS_COMPARE_OP (root))
3868 root->left = optimizeCompare (root->left);
3869 root->right = optimizeCompare (root->right);
3873 /* if left & right are the same then depending
3874 of the operation do */
3875 if (isAstEqual (root->left, root->right))
3877 switch (root->opval.op)
3882 optExpr = newAst_VALUE (constVal ("0"));
3887 optExpr = newAst_VALUE (constVal ("1"));
3891 return decorateType (optExpr);
3894 vleft = (root->left->type == EX_VALUE ?
3895 root->left->opval.val : NULL);
3897 vright = (root->right->type == EX_VALUE ?
3898 root->right->opval.val : NULL);
3900 /* if left is a BITVAR in BITSPACE */
3901 /* and right is a LITERAL then opt- */
3902 /* imize else do nothing */
3903 if (vleft && vright &&
3904 IS_BITVAR (vleft->etype) &&
3905 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3906 IS_LITERAL (vright->etype))
3909 /* if right side > 1 then comparison may never succeed */
3910 if ((litValue = (int) floatFromVal (vright)) > 1)
3912 werror (W_BAD_COMPARE);
3918 switch (root->opval.op)
3920 case '>': /* bit value greater than 1 cannot be */
3921 werror (W_BAD_COMPARE);
3925 case '<': /* bit value < 1 means 0 */
3927 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3930 case LE_OP: /* bit value <= 1 means no check */
3931 optExpr = newAst_VALUE (vright);
3934 case GE_OP: /* bit value >= 1 means only check for = */
3936 optExpr = newAst_VALUE (vleft);
3941 { /* literal is zero */
3942 switch (root->opval.op)
3944 case '<': /* bit value < 0 cannot be */
3945 werror (W_BAD_COMPARE);
3949 case '>': /* bit value > 0 means 1 */
3951 optExpr = newAst_VALUE (vleft);
3954 case LE_OP: /* bit value <= 0 means no check */
3955 case GE_OP: /* bit value >= 0 means no check */
3956 werror (W_BAD_COMPARE);
3960 case EQ_OP: /* bit == 0 means ! of bit */
3961 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3965 return decorateType (resolveSymbols (optExpr));
3966 } /* end-of-if of BITVAR */
3971 /*-----------------------------------------------------------------*/
3972 /* addSymToBlock : adds the symbol to the first block we find */
3973 /*-----------------------------------------------------------------*/
3975 addSymToBlock (symbol * sym, ast * tree)
3977 /* reached end of tree or a leaf */
3978 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3982 if (IS_AST_OP (tree) &&
3983 tree->opval.op == BLOCK)
3986 symbol *lsym = copySymbol (sym);
3988 lsym->next = AST_VALUES (tree, sym);
3989 AST_VALUES (tree, sym) = lsym;
3993 addSymToBlock (sym, tree->left);
3994 addSymToBlock (sym, tree->right);
3997 /*-----------------------------------------------------------------*/
3998 /* processRegParms - do processing for register parameters */
3999 /*-----------------------------------------------------------------*/
4001 processRegParms (value * args, ast * body)
4005 if (IS_REGPARM (args->etype))
4006 addSymToBlock (args->sym, body);
4011 /*-----------------------------------------------------------------*/
4012 /* resetParmKey - resets the operandkeys for the symbols */
4013 /*-----------------------------------------------------------------*/
4014 DEFSETFUNC (resetParmKey)
4025 /*-----------------------------------------------------------------*/
4026 /* createFunction - This is the key node that calls the iCode for */
4027 /* generating the code for a function. Note code */
4028 /* is generated function by function, later when */
4029 /* add inter-procedural analysis this will change */
4030 /*-----------------------------------------------------------------*/
4032 createFunction (symbol * name, ast * body)
4038 iCode *piCode = NULL;
4040 /* if check function return 0 then some problem */
4041 if (checkFunction (name) == 0)
4044 /* create a dummy block if none exists */
4046 body = newNode (BLOCK, NULL, NULL);
4050 /* check if the function name already in the symbol table */
4051 if ((csym = findSym (SymbolTab, NULL, name->name)))
4054 /* special case for compiler defined functions
4055 we need to add the name to the publics list : this
4056 actually means we are now compiling the compiler
4060 addSet (&publics, name);
4066 allocVariables (name);
4068 name->lastLine = yylineno;
4070 processFuncArgs (currFunc, 0);
4072 /* set the stack pointer */
4073 /* PENDING: check this for the mcs51 */
4074 stackPtr = -port->stack.direction * port->stack.call_overhead;
4075 if (IS_ISR (name->etype))
4076 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4077 if (IS_RENT (name->etype) || options.stackAuto)
4078 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4080 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4082 fetype = getSpec (name->type); /* get the specifier for the function */
4083 /* if this is a reentrant function then */
4084 if (IS_RENT (fetype))
4087 allocParms (name->args); /* allocate the parameters */
4089 /* do processing for parameters that are passed in registers */
4090 processRegParms (name->args, body);
4092 /* set the stack pointer */
4096 /* allocate & autoinit the block variables */
4097 processBlockVars (body, &stack, ALLOCATE);
4099 /* save the stack information */
4100 if (options.useXstack)
4101 name->xstack = SPEC_STAK (fetype) = stack;
4103 name->stack = SPEC_STAK (fetype) = stack;
4105 /* name needs to be mangled */
4106 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4108 body = resolveSymbols (body); /* resolve the symbols */
4109 body = decorateType (body); /* propagateType & do semantic checks */
4111 ex = newAst_VALUE (symbolVal (name)); /* create name */
4112 ex = newNode (FUNCTION, ex, body);
4113 ex->values.args = name->args;
4117 werror (E_FUNC_NO_CODE, name->name);
4121 /* create the node & generate intermediate code */
4123 codeOutFile = code->oFile;
4124 piCode = iCodeFromAst (ex);
4128 werror (E_FUNC_NO_CODE, name->name);
4132 eBBlockFromiCode (piCode);
4134 /* if there are any statics then do them */
4137 GcurMemmap = statsg;
4138 codeOutFile = statsg->oFile;
4139 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4145 /* dealloc the block variables */
4146 processBlockVars (body, &stack, DEALLOCATE);
4147 /* deallocate paramaters */
4148 deallocParms (name->args);
4150 if (IS_RENT (fetype))
4153 /* we are done freeup memory & cleanup */
4158 addSet (&operKeyReset, name);
4159 applyToSet (operKeyReset, resetParmKey);
4161 if (options.debug && !options.nodebug)
4162 cdbStructBlock (1, cdbFile);
4164 cleanUpLevel (LabelTab, 0);
4165 cleanUpBlock (StructTab, 1);
4166 cleanUpBlock (TypedefTab, 1);
4168 xstack->syms = NULL;
4169 istack->syms = NULL;
4174 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4175 /*-----------------------------------------------------------------*/
4176 /* ast_print : prints the ast (for debugging purposes) */
4177 /*-----------------------------------------------------------------*/
4179 void ast_print (ast * tree, FILE *outfile, int indent)
4184 /* can print only decorated trees */
4185 if (!tree->decorated) return;
4187 /* if any child is an error | this one is an error do nothing */
4188 if (tree->isError ||
4189 (tree->left && tree->left->isError) ||
4190 (tree->right && tree->right->isError)) {
4191 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4195 /* print the line */
4196 /* if not block & function */
4197 if (tree->type == EX_OP &&
4198 (tree->opval.op != FUNCTION &&
4199 tree->opval.op != BLOCK &&
4200 tree->opval.op != NULLOP)) {
4203 if (tree->opval.op == FUNCTION) {
4204 fprintf(outfile,"FUNCTION (%p) type (",tree);
4205 printTypeChain (tree->ftype,outfile);
4206 fprintf(outfile,")\n");
4207 ast_print(tree->left,outfile,indent+4);
4208 ast_print(tree->right,outfile,indent+4);
4211 if (tree->opval.op == BLOCK) {
4212 symbol *decls = tree->values.sym;
4213 fprintf(outfile,"{\n");
4215 INDENT(indent+4,outfile);
4216 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4217 printTypeChain(decls->type,outfile);
4218 fprintf(outfile,")\n");
4220 decls = decls->next;
4222 ast_print(tree->right,outfile,indent+4);
4223 fprintf(outfile,"}\n");
4226 if (tree->opval.op == NULLOP) {
4227 fprintf(outfile,"\n");
4228 ast_print(tree->left,outfile,indent);
4229 fprintf(outfile,"\n");
4230 ast_print(tree->right,outfile,indent);
4233 INDENT(indent,outfile);
4235 /*------------------------------------------------------------------*/
4236 /*----------------------------*/
4237 /* leaf has been reached */
4238 /*----------------------------*/
4239 /* if this is of type value */
4240 /* just get the type */
4241 if (tree->type == EX_VALUE) {
4243 if (IS_LITERAL (tree->opval.val->etype)) {
4244 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4245 (int) floatFromVal(tree->opval.val),
4246 (int) floatFromVal(tree->opval.val),
4247 floatFromVal(tree->opval.val));
4248 } else if (tree->opval.val->sym) {
4249 /* if the undefined flag is set then give error message */
4250 if (tree->opval.val->sym->undefined) {
4251 fprintf(outfile,"UNDEFINED SYMBOL ");
4253 fprintf(outfile,"SYMBOL ");
4255 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4258 fprintf(outfile," type (");
4259 printTypeChain(tree->ftype,outfile);
4260 fprintf(outfile,")\n");
4262 fprintf(outfile,"\n");
4267 /* if type link for the case of cast */
4268 if (tree->type == EX_LINK) {
4269 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4270 printTypeChain(tree->opval.lnk,outfile);
4271 fprintf(outfile,")\n");
4276 /* depending on type of operator do */
4278 switch (tree->opval.op) {
4279 /*------------------------------------------------------------------*/
4280 /*----------------------------*/
4282 /*----------------------------*/
4284 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4285 printTypeChain(tree->ftype,outfile);
4286 fprintf(outfile,")\n");
4287 ast_print(tree->left,outfile,indent+4);
4288 ast_print(tree->right,outfile,indent+4);
4291 /*------------------------------------------------------------------*/
4292 /*----------------------------*/
4294 /*----------------------------*/
4296 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4297 printTypeChain(tree->ftype,outfile);
4298 fprintf(outfile,")\n");
4299 ast_print(tree->left,outfile,indent+4);
4300 ast_print(tree->right,outfile,indent+4);
4303 /*------------------------------------------------------------------*/
4304 /*----------------------------*/
4305 /* struct/union pointer */
4306 /*----------------------------*/
4308 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4309 printTypeChain(tree->ftype,outfile);
4310 fprintf(outfile,")\n");
4311 ast_print(tree->left,outfile,indent+4);
4312 ast_print(tree->right,outfile,indent+4);
4315 /*------------------------------------------------------------------*/
4316 /*----------------------------*/
4317 /* ++/-- operation */
4318 /*----------------------------*/
4319 case INC_OP: /* incerement operator unary so left only */
4320 fprintf(outfile,"INC_OP (%p) type (",tree);
4321 printTypeChain(tree->ftype,outfile);
4322 fprintf(outfile,")\n");
4323 ast_print(tree->left,outfile,indent+4);
4327 fprintf(outfile,"DEC_OP (%p) type (",tree);
4328 printTypeChain(tree->ftype,outfile);
4329 fprintf(outfile,")\n");
4330 ast_print(tree->left,outfile,indent+4);
4333 /*------------------------------------------------------------------*/
4334 /*----------------------------*/
4336 /*----------------------------*/
4339 fprintf(outfile,"& (%p) type (",tree);
4340 printTypeChain(tree->ftype,outfile);
4341 fprintf(outfile,")\n");
4342 ast_print(tree->left,outfile,indent+4);
4343 ast_print(tree->right,outfile,indent+4);
4345 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4346 printTypeChain(tree->ftype,outfile);
4347 fprintf(outfile,")\n");
4348 ast_print(tree->left,outfile,indent+4);
4349 ast_print(tree->right,outfile,indent+4);
4352 /*----------------------------*/
4354 /*----------------------------*/
4356 fprintf(outfile,"OR (%p) type (",tree);
4357 printTypeChain(tree->ftype,outfile);
4358 fprintf(outfile,")\n");
4359 ast_print(tree->left,outfile,indent+4);
4360 ast_print(tree->right,outfile,indent+4);
4362 /*------------------------------------------------------------------*/
4363 /*----------------------------*/
4365 /*----------------------------*/
4367 fprintf(outfile,"XOR (%p) type (",tree);
4368 printTypeChain(tree->ftype,outfile);
4369 fprintf(outfile,")\n");
4370 ast_print(tree->left,outfile,indent+4);
4371 ast_print(tree->right,outfile,indent+4);
4374 /*------------------------------------------------------------------*/
4375 /*----------------------------*/
4377 /*----------------------------*/
4379 fprintf(outfile,"DIV (%p) type (",tree);
4380 printTypeChain(tree->ftype,outfile);
4381 fprintf(outfile,")\n");
4382 ast_print(tree->left,outfile,indent+4);
4383 ast_print(tree->right,outfile,indent+4);
4385 /*------------------------------------------------------------------*/
4386 /*----------------------------*/
4388 /*----------------------------*/
4390 fprintf(outfile,"MOD (%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 /*------------------------------------------------------------------*/
4398 /*----------------------------*/
4399 /* address dereference */
4400 /*----------------------------*/
4401 case '*': /* can be unary : if right is null then unary operation */
4403 fprintf(outfile,"DEREF (%p) type (",tree);
4404 printTypeChain(tree->ftype,outfile);
4405 fprintf(outfile,")\n");
4406 ast_print(tree->left,outfile,indent+4);
4409 /*------------------------------------------------------------------*/
4410 /*----------------------------*/
4411 /* multiplication */
4412 /*----------------------------*/
4413 fprintf(outfile,"MULT (%p) type (",tree);
4414 printTypeChain(tree->ftype,outfile);
4415 fprintf(outfile,")\n");
4416 ast_print(tree->left,outfile,indent+4);
4417 ast_print(tree->right,outfile,indent+4);
4421 /*------------------------------------------------------------------*/
4422 /*----------------------------*/
4423 /* unary '+' operator */
4424 /*----------------------------*/
4428 fprintf(outfile,"UPLUS (%p) type (",tree);
4429 printTypeChain(tree->ftype,outfile);
4430 fprintf(outfile,")\n");
4431 ast_print(tree->left,outfile,indent+4);
4433 /*------------------------------------------------------------------*/
4434 /*----------------------------*/
4436 /*----------------------------*/
4437 fprintf(outfile,"ADD (%p) type (",tree);
4438 printTypeChain(tree->ftype,outfile);
4439 fprintf(outfile,")\n");
4440 ast_print(tree->left,outfile,indent+4);
4441 ast_print(tree->right,outfile,indent+4);
4444 /*------------------------------------------------------------------*/
4445 /*----------------------------*/
4447 /*----------------------------*/
4448 case '-': /* can be unary */
4450 fprintf(outfile,"UMINUS (%p) type (",tree);
4451 printTypeChain(tree->ftype,outfile);
4452 fprintf(outfile,")\n");
4453 ast_print(tree->left,outfile,indent+4);
4455 /*------------------------------------------------------------------*/
4456 /*----------------------------*/
4458 /*----------------------------*/
4459 fprintf(outfile,"SUB (%p) type (",tree);
4460 printTypeChain(tree->ftype,outfile);
4461 fprintf(outfile,")\n");
4462 ast_print(tree->left,outfile,indent+4);
4463 ast_print(tree->right,outfile,indent+4);
4466 /*------------------------------------------------------------------*/
4467 /*----------------------------*/
4469 /*----------------------------*/
4471 fprintf(outfile,"COMPL (%p) type (",tree);
4472 printTypeChain(tree->ftype,outfile);
4473 fprintf(outfile,")\n");
4474 ast_print(tree->left,outfile,indent+4);
4476 /*------------------------------------------------------------------*/
4477 /*----------------------------*/
4479 /*----------------------------*/
4481 fprintf(outfile,"NOT (%p) type (",tree);
4482 printTypeChain(tree->ftype,outfile);
4483 fprintf(outfile,")\n");
4484 ast_print(tree->left,outfile,indent+4);
4486 /*------------------------------------------------------------------*/
4487 /*----------------------------*/
4489 /*----------------------------*/
4491 fprintf(outfile,"RRC (%p) type (",tree);
4492 printTypeChain(tree->ftype,outfile);
4493 fprintf(outfile,")\n");
4494 ast_print(tree->left,outfile,indent+4);
4498 fprintf(outfile,"RLC (%p) type (",tree);
4499 printTypeChain(tree->ftype,outfile);
4500 fprintf(outfile,")\n");
4501 ast_print(tree->left,outfile,indent+4);
4504 fprintf(outfile,"GETHBIT (%p) type (",tree);
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4507 ast_print(tree->left,outfile,indent+4);
4510 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4511 printTypeChain(tree->ftype,outfile);
4512 fprintf(outfile,")\n");
4513 ast_print(tree->left,outfile,indent+4);
4514 ast_print(tree->right,outfile,indent+4);
4517 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4518 printTypeChain(tree->ftype,outfile);
4519 fprintf(outfile,")\n");
4520 ast_print(tree->left,outfile,indent+4);
4521 ast_print(tree->right,outfile,indent+4);
4523 /*------------------------------------------------------------------*/
4524 /*----------------------------*/
4526 /*----------------------------*/
4527 case CAST: /* change the type */
4528 fprintf(outfile,"CAST (%p) type (",tree);
4529 printTypeChain(tree->ftype,outfile);
4530 fprintf(outfile,")\n");
4531 ast_print(tree->right,outfile,indent+4);
4535 fprintf(outfile,"ANDAND (%p) type (",tree);
4536 printTypeChain(tree->ftype,outfile);
4537 fprintf(outfile,")\n");
4538 ast_print(tree->left,outfile,indent+4);
4539 ast_print(tree->right,outfile,indent+4);
4542 fprintf(outfile,"OROR (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->left,outfile,indent+4);
4546 ast_print(tree->right,outfile,indent+4);
4549 /*------------------------------------------------------------------*/
4550 /*----------------------------*/
4551 /* comparison operators */
4552 /*----------------------------*/
4554 fprintf(outfile,"GT(>) (%p) type (",tree);
4555 printTypeChain(tree->ftype,outfile);
4556 fprintf(outfile,")\n");
4557 ast_print(tree->left,outfile,indent+4);
4558 ast_print(tree->right,outfile,indent+4);
4561 fprintf(outfile,"LT(<) (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+4);
4565 ast_print(tree->right,outfile,indent+4);
4568 fprintf(outfile,"LE(<=) (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+4);
4572 ast_print(tree->right,outfile,indent+4);
4575 fprintf(outfile,"GE(>=) (%p) type (",tree);
4576 printTypeChain(tree->ftype,outfile);
4577 fprintf(outfile,")\n");
4578 ast_print(tree->left,outfile,indent+4);
4579 ast_print(tree->right,outfile,indent+4);
4582 fprintf(outfile,"EQ(==) (%p) type (",tree);
4583 printTypeChain(tree->ftype,outfile);
4584 fprintf(outfile,")\n");
4585 ast_print(tree->left,outfile,indent+4);
4586 ast_print(tree->right,outfile,indent+4);
4589 fprintf(outfile,"NE(!=) (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->left,outfile,indent+4);
4593 ast_print(tree->right,outfile,indent+4);
4594 /*------------------------------------------------------------------*/
4595 /*----------------------------*/
4597 /*----------------------------*/
4598 case SIZEOF: /* evaluate wihout code generation */
4599 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4602 /*------------------------------------------------------------------*/
4603 /*----------------------------*/
4604 /* conditional operator '?' */
4605 /*----------------------------*/
4607 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4608 printTypeChain(tree->ftype,outfile);
4609 fprintf(outfile,")\n");
4610 ast_print(tree->left,outfile,indent+4);
4611 ast_print(tree->right,outfile,indent+4);
4614 fprintf(outfile,"COLON(:) (%p) type (",tree);
4615 printTypeChain(tree->ftype,outfile);
4616 fprintf(outfile,")\n");
4617 ast_print(tree->left,outfile,indent+4);
4618 ast_print(tree->right,outfile,indent+4);
4621 /*------------------------------------------------------------------*/
4622 /*----------------------------*/
4623 /* assignment operators */
4624 /*----------------------------*/
4626 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4627 printTypeChain(tree->ftype,outfile);
4628 fprintf(outfile,")\n");
4629 ast_print(tree->left,outfile,indent+4);
4630 ast_print(tree->right,outfile,indent+4);
4633 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4634 printTypeChain(tree->ftype,outfile);
4635 fprintf(outfile,")\n");
4636 ast_print(tree->left,outfile,indent+4);
4637 ast_print(tree->right,outfile,indent+4);
4640 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+4);
4644 ast_print(tree->right,outfile,indent+4);
4647 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+4);
4651 ast_print(tree->right,outfile,indent+4);
4654 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+4);
4658 ast_print(tree->right,outfile,indent+4);
4661 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4662 printTypeChain(tree->ftype,outfile);
4663 fprintf(outfile,")\n");
4664 ast_print(tree->left,outfile,indent+4);
4665 ast_print(tree->right,outfile,indent+4);
4668 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4669 printTypeChain(tree->ftype,outfile);
4670 fprintf(outfile,")\n");
4671 ast_print(tree->left,outfile,indent+4);
4672 ast_print(tree->right,outfile,indent+4);
4674 /*------------------------------------------------------------------*/
4675 /*----------------------------*/
4677 /*----------------------------*/
4679 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4680 printTypeChain(tree->ftype,outfile);
4681 fprintf(outfile,")\n");
4682 ast_print(tree->left,outfile,indent+4);
4683 ast_print(tree->right,outfile,indent+4);
4685 /*------------------------------------------------------------------*/
4686 /*----------------------------*/
4688 /*----------------------------*/
4690 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+4);
4694 ast_print(tree->right,outfile,indent+4);
4696 /*------------------------------------------------------------------*/
4697 /*----------------------------*/
4698 /* straight assignemnt */
4699 /*----------------------------*/
4701 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4702 printTypeChain(tree->ftype,outfile);
4703 fprintf(outfile,")\n");
4704 ast_print(tree->left,outfile,indent+4);
4705 ast_print(tree->right,outfile,indent+4);
4707 /*------------------------------------------------------------------*/
4708 /*----------------------------*/
4709 /* comma operator */
4710 /*----------------------------*/
4712 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4713 printTypeChain(tree->ftype,outfile);
4714 fprintf(outfile,")\n");
4715 ast_print(tree->left,outfile,indent+4);
4716 ast_print(tree->right,outfile,indent+4);
4718 /*------------------------------------------------------------------*/
4719 /*----------------------------*/
4721 /*----------------------------*/
4724 fprintf(outfile,"CALL (%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);
4731 fprintf(outfile,"PARM ");
4732 ast_print(tree->left,outfile,indent+4);
4733 if (tree->right && !IS_AST_PARAM(tree->right)) {
4734 fprintf(outfile,"PARM ");
4735 ast_print(tree->right,outfile,indent+4);
4738 /*------------------------------------------------------------------*/
4739 /*----------------------------*/
4740 /* return statement */
4741 /*----------------------------*/
4743 fprintf(outfile,"RETURN (%p) type (",tree);
4744 printTypeChain(tree->right->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->right,outfile,indent+4);
4748 /*------------------------------------------------------------------*/
4749 /*----------------------------*/
4750 /* label statement */
4751 /*----------------------------*/
4753 fprintf(outfile,"LABEL (%p)",tree);
4754 ast_print(tree->left,outfile,indent+4);
4755 ast_print(tree->right,outfile,indent);
4757 /*------------------------------------------------------------------*/
4758 /*----------------------------*/
4759 /* switch statement */
4760 /*----------------------------*/
4764 fprintf(outfile,"SWITCH (%p) ",tree);
4765 ast_print(tree->left,outfile,0);
4766 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4767 INDENT(indent+4,outfile);
4768 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4769 (int) floatFromVal(val),
4770 tree->values.switchVals.swNum,
4771 (int) floatFromVal(val));
4773 ast_print(tree->right,outfile,indent);
4776 /*------------------------------------------------------------------*/
4777 /*----------------------------*/
4779 /*----------------------------*/
4781 ast_print(tree->left,outfile,indent);
4782 INDENT(indent,outfile);
4783 fprintf(outfile,"IF (%p) \n",tree);
4784 if (tree->trueLabel) {
4785 INDENT(indent,outfile);
4786 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4788 if (tree->falseLabel) {
4789 INDENT(indent,outfile);
4790 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4792 ast_print(tree->right,outfile,indent);
4794 /*------------------------------------------------------------------*/
4795 /*----------------------------*/
4797 /*----------------------------*/
4799 fprintf(outfile,"FOR (%p) \n",tree);
4800 if (AST_FOR( tree, initExpr)) {
4801 INDENT(indent+4,outfile);
4802 fprintf(outfile,"INIT EXPR ");
4803 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4805 if (AST_FOR( tree, condExpr)) {
4806 INDENT(indent+4,outfile);
4807 fprintf(outfile,"COND EXPR ");
4808 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4810 if (AST_FOR( tree, loopExpr)) {
4811 INDENT(indent+4,outfile);
4812 fprintf(outfile,"LOOP EXPR ");
4813 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4815 fprintf(outfile,"FOR LOOP BODY \n");
4816 ast_print(tree->left,outfile,indent+4);
4825 ast_print(t,stdout,1);