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)
645 if (IS_CAST_OP (actParm)
646 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
648 /* Parameter was explicitly typecast; don't touch it. */
652 /* If it's a small integer, upcast to int. */
653 if (IS_INTEGRAL (actParm->ftype)
654 && getSize (actParm->ftype) < (unsigned) INTSIZE)
656 newType = newAst_LINK (INTTYPE);
659 if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
661 newType = newAst_LINK (copyLinkChain (actParm->ftype));
662 DCL_TYPE (newType->opval.lnk) = GPOINTER;
665 if (IS_AGGREGATE (actParm->ftype))
667 newType = newAst_LINK (copyLinkChain (actParm->ftype));
668 DCL_TYPE (newType->opval.lnk) = GPOINTER;
673 /* cast required; change this op to a cast. */
674 ast *parmCopy = resolveSymbols (copyAst (actParm));
676 actParm->type = EX_OP;
677 actParm->opval.op = CAST;
678 actParm->left = newType;
679 actParm->right = parmCopy;
680 decorateType (actParm);
682 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
684 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
685 processParms (func, NULL, actParm->right, parmNumber, rightmost));
690 /* if defined parameters ended but actual has not & */
692 if (!defParm && actParm &&
693 (options.stackAuto || IS_RENT (fetype)))
696 resolveSymbols (actParm);
697 /* if this is a PARAM node then match left & right */
698 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
700 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
701 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
705 /* If we have found a value node by following only right-hand links,
706 * then we know that there are no more values after us.
708 * Therefore, if there are more defined parameters, the caller didn't
711 if (rightmost && defParm->next)
713 werror (E_TOO_FEW_PARMS);
718 /* the parameter type must be at least castable */
719 if (checkType (defParm->type, actParm->ftype) == 0)
721 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
722 werror (E_CONTINUE, "defined type ");
723 printTypeChain (defParm->type, stderr);
724 fprintf (stderr, "\n");
725 werror (E_CONTINUE, "actual type ");
726 printTypeChain (actParm->ftype, stderr);
727 fprintf (stderr, "\n");
730 /* if the parameter is castable then add the cast */
731 if (checkType (defParm->type, actParm->ftype) < 0)
733 ast *pTree = resolveSymbols (copyAst (actParm));
735 /* now change the current one to a cast */
736 actParm->type = EX_OP;
737 actParm->opval.op = CAST;
738 actParm->left = newAst_LINK (defParm->type);
739 actParm->right = pTree;
740 actParm->etype = defParm->etype;
741 actParm->ftype = defParm->type;
744 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
746 actParm->argSym = defParm->sym;
747 /* make a copy and change the regparm type to the defined parm */
748 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
749 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
753 /*-----------------------------------------------------------------*/
754 /* createIvalType - generates ival for basic types */
755 /*-----------------------------------------------------------------*/
757 createIvalType (ast * sym, sym_link * type, initList * ilist)
761 /* if initList is deep */
762 if (ilist->type == INIT_DEEP)
763 ilist = ilist->init.deep;
765 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
766 return decorateType (newNode ('=', sym, iExpr));
769 /*-----------------------------------------------------------------*/
770 /* createIvalStruct - generates initial value for structures */
771 /*-----------------------------------------------------------------*/
773 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
779 sflds = SPEC_STRUCT (type)->fields;
780 if (ilist->type != INIT_DEEP)
782 werror (E_INIT_STRUCT, "");
786 iloop = ilist->init.deep;
788 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
792 /* if we have come to end */
796 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
797 lAst = decorateType (resolveSymbols (lAst));
798 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
804 /*-----------------------------------------------------------------*/
805 /* createIvalArray - generates code for array initialization */
806 /*-----------------------------------------------------------------*/
808 createIvalArray (ast * sym, sym_link * type, initList * ilist)
812 int lcnt = 0, size = 0;
814 /* take care of the special case */
815 /* array of characters can be init */
817 if (IS_CHAR (type->next))
818 if ((rast = createIvalCharPtr (sym,
820 decorateType (resolveSymbols (list2expr (ilist))))))
822 return decorateType (resolveSymbols (rast));
824 /* not the special case */
825 if (ilist->type != INIT_DEEP)
827 werror (E_INIT_STRUCT, "");
831 iloop = ilist->init.deep;
832 lcnt = DCL_ELEM (type);
839 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
840 aSym = decorateType (resolveSymbols (aSym));
841 rast = createIval (aSym, type->next, iloop, rast);
842 iloop = (iloop ? iloop->next : NULL);
845 /* if not array limits given & we */
846 /* are out of initialisers then */
847 if (!DCL_ELEM (type) && !iloop)
850 /* no of elements given and we */
851 /* have generated for all of them */
856 /* if we have not been given a size */
857 if (!DCL_ELEM (type))
858 DCL_ELEM (type) = size;
860 return decorateType (resolveSymbols (rast));
864 /*-----------------------------------------------------------------*/
865 /* createIvalCharPtr - generates initial values for char pointers */
866 /*-----------------------------------------------------------------*/
868 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
872 /* if this is a pointer & right is a literal array then */
873 /* just assignment will do */
874 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
875 SPEC_SCLS (iexpr->etype) == S_CODE)
876 && IS_ARRAY (iexpr->ftype)))
877 return newNode ('=', sym, iexpr);
879 /* left side is an array so we have to assign each */
881 if ((IS_LITERAL (iexpr->etype) ||
882 SPEC_SCLS (iexpr->etype) == S_CODE)
883 && IS_ARRAY (iexpr->ftype))
886 /* for each character generate an assignment */
887 /* to the array element */
888 char *s = SPEC_CVAL (iexpr->etype).v_char;
893 rast = newNode (NULLOP,
897 newAst_VALUE (valueFromLit ((float) i))),
898 newAst_VALUE (valueFromLit (*s))));
902 rast = newNode (NULLOP,
906 newAst_VALUE (valueFromLit ((float) i))),
907 newAst_VALUE (valueFromLit (*s))));
908 return decorateType (resolveSymbols (rast));
914 /*-----------------------------------------------------------------*/
915 /* createIvalPtr - generates initial value for pointers */
916 /*-----------------------------------------------------------------*/
918 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
924 if (ilist->type == INIT_DEEP)
925 ilist = ilist->init.deep;
927 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
929 /* if character pointer */
930 if (IS_CHAR (type->next))
931 if ((rast = createIvalCharPtr (sym, type, iexpr)))
934 return newNode ('=', sym, iexpr);
937 /*-----------------------------------------------------------------*/
938 /* createIval - generates code for initial value */
939 /*-----------------------------------------------------------------*/
941 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
948 /* if structure then */
949 if (IS_STRUCT (type))
950 rast = createIvalStruct (sym, type, ilist);
952 /* if this is a pointer */
954 rast = createIvalPtr (sym, type, ilist);
956 /* if this is an array */
958 rast = createIvalArray (sym, type, ilist);
960 /* if type is SPECIFIER */
962 rast = createIvalType (sym, type, ilist);
964 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
966 return decorateType (resolveSymbols (rast));
969 /*-----------------------------------------------------------------*/
970 /* initAggregates - initialises aggregate variables with initv */
971 /*-----------------------------------------------------------------*/
973 initAggregates (symbol * sym, initList * ival, ast * wid)
975 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
978 /*-----------------------------------------------------------------*/
979 /* gatherAutoInit - creates assignment expressions for initial */
981 /*-----------------------------------------------------------------*/
983 gatherAutoInit (symbol * autoChain)
990 for (sym = autoChain; sym; sym = sym->next)
993 /* resolve the symbols in the ival */
995 resolveIvalSym (sym->ival);
997 /* if this is a static variable & has an */
998 /* initial value the code needs to be lifted */
999 /* here to the main portion since they can be */
1000 /* initialised only once at the start */
1001 if (IS_STATIC (sym->etype) && sym->ival &&
1002 SPEC_SCLS (sym->etype) != S_CODE)
1006 // this can only be a constant
1007 if (!IS_LITERAL(sym->ival->init.node->etype)) {
1008 werror (E_CONST_EXPECTED);
1011 /* insert the symbol into the symbol table */
1012 /* with level = 0 & name = rname */
1013 newSym = copySymbol (sym);
1014 addSym (SymbolTab, newSym, newSym->name, 0, 0);
1016 /* now lift the code to main */
1017 if (IS_AGGREGATE (sym->type))
1018 work = initAggregates (sym, sym->ival, NULL);
1020 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1021 list2expr (sym->ival));
1023 setAstLineno (work, sym->lineDef);
1027 staticAutos = newNode (NULLOP, staticAutos, work);
1034 /* if there is an initial value */
1035 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1037 if (IS_AGGREGATE (sym->type))
1038 work = initAggregates (sym, sym->ival, NULL);
1040 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1041 list2expr (sym->ival));
1043 setAstLineno (work, sym->lineDef);
1046 init = newNode (NULLOP, init, work);
1055 /*-----------------------------------------------------------------*/
1056 /* stringToSymbol - creates a symbol from a literal string */
1057 /*-----------------------------------------------------------------*/
1059 stringToSymbol (value * val)
1061 char name[SDCC_NAME_MAX + 1];
1062 static int charLbl = 0;
1065 sprintf (name, "_str_%d", charLbl++);
1066 sym = newSymbol (name, 0); /* make it @ level 0 */
1067 strcpy (sym->rname, name);
1069 /* copy the type from the value passed */
1070 sym->type = copyLinkChain (val->type);
1071 sym->etype = getSpec (sym->type);
1072 /* change to storage class & output class */
1073 SPEC_SCLS (sym->etype) = S_CODE;
1074 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1075 SPEC_STAT (sym->etype) = 1;
1076 /* make the level & block = 0 */
1077 sym->block = sym->level = 0;
1079 /* create an ival */
1080 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1085 allocVariables (sym);
1088 return symbolVal (sym);
1092 /*-----------------------------------------------------------------*/
1093 /* processBlockVars - will go thru the ast looking for block if */
1094 /* a block is found then will allocate the syms */
1095 /* will also gather the auto inits present */
1096 /*-----------------------------------------------------------------*/
1098 processBlockVars (ast * tree, int *stack, int action)
1103 /* if this is a block */
1104 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1108 if (action == ALLOCATE)
1110 autoInit = gatherAutoInit (tree->values.sym);
1111 *stack += allocVariables (tree->values.sym);
1113 /* if there are auto inits then do them */
1115 tree->left = newNode (NULLOP, autoInit, tree->left);
1117 else /* action is deallocate */
1118 deallocLocal (tree->values.sym);
1121 processBlockVars (tree->left, stack, action);
1122 processBlockVars (tree->right, stack, action);
1126 /*-----------------------------------------------------------------*/
1127 /* constExprValue - returns the value of a constant expression */
1128 /*-----------------------------------------------------------------*/
1130 constExprValue (ast * cexpr, int check)
1132 cexpr = decorateType (resolveSymbols (cexpr));
1134 /* if this is not a constant then */
1135 if (!IS_LITERAL (cexpr->ftype))
1137 /* then check if this is a literal array
1139 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1140 SPEC_CVAL (cexpr->etype).v_char &&
1141 IS_ARRAY (cexpr->ftype))
1143 value *val = valFromType (cexpr->ftype);
1144 SPEC_SCLS (val->etype) = S_LITERAL;
1145 val->sym = cexpr->opval.val->sym;
1146 val->sym->type = copyLinkChain (cexpr->ftype);
1147 val->sym->etype = getSpec (val->sym->type);
1148 strcpy (val->name, cexpr->opval.val->sym->rname);
1152 /* if we are casting a literal value then */
1153 if (IS_AST_OP (cexpr) &&
1154 cexpr->opval.op == CAST &&
1155 IS_LITERAL (cexpr->left->ftype))
1156 return valCastLiteral (cexpr->ftype,
1157 floatFromVal (cexpr->left->opval.val));
1159 if (IS_AST_VALUE (cexpr))
1160 return cexpr->opval.val;
1163 werror (E_CONST_EXPECTED, "found expression");
1168 /* return the value */
1169 return cexpr->opval.val;
1173 /*-----------------------------------------------------------------*/
1174 /* isLabelInAst - will return true if a given label is found */
1175 /*-----------------------------------------------------------------*/
1177 isLabelInAst (symbol * label, ast * tree)
1179 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1182 if (IS_AST_OP (tree) &&
1183 tree->opval.op == LABEL &&
1184 isSymbolEqual (AST_SYMBOL (tree->left), label))
1187 return isLabelInAst (label, tree->right) &&
1188 isLabelInAst (label, tree->left);
1192 /*-----------------------------------------------------------------*/
1193 /* isLoopCountable - return true if the loop count can be determi- */
1194 /* -ned at compile time . */
1195 /*-----------------------------------------------------------------*/
1197 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1198 symbol ** sym, ast ** init, ast ** end)
1201 /* the loop is considered countable if the following
1202 conditions are true :-
1204 a) initExpr :- <sym> = <const>
1205 b) condExpr :- <sym> < <const1>
1206 c) loopExpr :- <sym> ++
1209 /* first check the initExpr */
1210 if (IS_AST_OP (initExpr) &&
1211 initExpr->opval.op == '=' && /* is assignment */
1212 IS_AST_SYM_VALUE (initExpr->left))
1213 { /* left is a symbol */
1215 *sym = AST_SYMBOL (initExpr->left);
1216 *init = initExpr->right;
1221 /* for now the symbol has to be of
1223 if (!IS_INTEGRAL ((*sym)->type))
1226 /* now check condExpr */
1227 if (IS_AST_OP (condExpr))
1230 switch (condExpr->opval.op)
1233 if (IS_AST_SYM_VALUE (condExpr->left) &&
1234 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1235 IS_AST_LIT_VALUE (condExpr->right))
1237 *end = condExpr->right;
1243 if (IS_AST_OP (condExpr->left) &&
1244 condExpr->left->opval.op == '>' &&
1245 IS_AST_LIT_VALUE (condExpr->left->right) &&
1246 IS_AST_SYM_VALUE (condExpr->left->left) &&
1247 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1250 *end = newNode ('+', condExpr->left->right,
1251 newAst_VALUE (constVal ("1")));
1262 /* check loop expression is of the form <sym>++ */
1263 if (!IS_AST_OP (loopExpr))
1266 /* check if <sym> ++ */
1267 if (loopExpr->opval.op == INC_OP)
1273 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1274 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1281 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1282 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1290 if (loopExpr->opval.op == ADD_ASSIGN)
1293 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1294 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1295 IS_AST_LIT_VALUE (loopExpr->right) &&
1296 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1304 /*-----------------------------------------------------------------*/
1305 /* astHasVolatile - returns true if ast contains any volatile */
1306 /*-----------------------------------------------------------------*/
1308 astHasVolatile (ast * tree)
1313 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1316 if (IS_AST_OP (tree))
1317 return astHasVolatile (tree->left) ||
1318 astHasVolatile (tree->right);
1323 /*-----------------------------------------------------------------*/
1324 /* astHasPointer - return true if the ast contains any ptr variable */
1325 /*-----------------------------------------------------------------*/
1327 astHasPointer (ast * tree)
1332 if (IS_AST_LINK (tree))
1335 /* if we hit an array expression then check
1336 only the left side */
1337 if (IS_AST_OP (tree) && tree->opval.op == '[')
1338 return astHasPointer (tree->left);
1340 if (IS_AST_VALUE (tree))
1341 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1343 return astHasPointer (tree->left) ||
1344 astHasPointer (tree->right);
1348 /*-----------------------------------------------------------------*/
1349 /* astHasSymbol - return true if the ast has the given symbol */
1350 /*-----------------------------------------------------------------*/
1352 astHasSymbol (ast * tree, symbol * sym)
1354 if (!tree || IS_AST_LINK (tree))
1357 if (IS_AST_VALUE (tree))
1359 if (IS_AST_SYM_VALUE (tree))
1360 return isSymbolEqual (AST_SYMBOL (tree), sym);
1365 return astHasSymbol (tree->left, sym) ||
1366 astHasSymbol (tree->right, sym);
1369 /*-----------------------------------------------------------------*/
1370 /* isConformingBody - the loop body has to conform to a set of rules */
1371 /* for the loop to be considered reversible read on for rules */
1372 /*-----------------------------------------------------------------*/
1374 isConformingBody (ast * pbody, symbol * sym, ast * body)
1377 /* we are going to do a pre-order traversal of the
1378 tree && check for the following conditions. (essentially
1379 a set of very shallow tests )
1380 a) the sym passed does not participate in
1381 any arithmetic operation
1382 b) There are no function calls
1383 c) all jumps are within the body
1384 d) address of loop control variable not taken
1385 e) if an assignment has a pointer on the
1386 left hand side make sure right does not have
1387 loop control variable */
1389 /* if we reach the end or a leaf then true */
1390 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1394 /* if anything else is "volatile" */
1395 if (IS_VOLATILE (TETYPE (pbody)))
1398 /* we will walk the body in a pre-order traversal for
1400 switch (pbody->opval.op)
1402 /*------------------------------------------------------------------*/
1404 return isConformingBody (pbody->right, sym, body);
1406 /*------------------------------------------------------------------*/
1411 /*------------------------------------------------------------------*/
1412 case INC_OP: /* incerement operator unary so left only */
1415 /* sure we are not sym is not modified */
1417 IS_AST_SYM_VALUE (pbody->left) &&
1418 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1422 IS_AST_SYM_VALUE (pbody->right) &&
1423 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1428 /*------------------------------------------------------------------*/
1430 case '*': /* can be unary : if right is null then unary operation */
1435 /* if right is NULL then unary operation */
1436 /*------------------------------------------------------------------*/
1437 /*----------------------------*/
1439 /*----------------------------*/
1442 if (IS_AST_SYM_VALUE (pbody->left) &&
1443 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1446 return isConformingBody (pbody->left, sym, body);
1450 if (astHasSymbol (pbody->left, sym) ||
1451 astHasSymbol (pbody->right, sym))
1456 /*------------------------------------------------------------------*/
1464 if (IS_AST_SYM_VALUE (pbody->left) &&
1465 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1468 if (IS_AST_SYM_VALUE (pbody->right) &&
1469 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1472 return isConformingBody (pbody->left, sym, body) &&
1473 isConformingBody (pbody->right, sym, body);
1480 if (IS_AST_SYM_VALUE (pbody->left) &&
1481 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1483 return isConformingBody (pbody->left, sym, body);
1485 /*------------------------------------------------------------------*/
1497 case SIZEOF: /* evaluate wihout code generation */
1499 return isConformingBody (pbody->left, sym, body) &&
1500 isConformingBody (pbody->right, sym, body);
1502 /*------------------------------------------------------------------*/
1505 /* if left has a pointer & right has loop
1506 control variable then we cannot */
1507 if (astHasPointer (pbody->left) &&
1508 astHasSymbol (pbody->right, sym))
1510 if (astHasVolatile (pbody->left))
1513 if (IS_AST_SYM_VALUE (pbody->left) &&
1514 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1517 if (astHasVolatile (pbody->left))
1520 return isConformingBody (pbody->left, sym, body) &&
1521 isConformingBody (pbody->right, sym, body);
1532 assert ("Parser should not have generated this\n");
1534 /*------------------------------------------------------------------*/
1535 /*----------------------------*/
1536 /* comma operator */
1537 /*----------------------------*/
1539 return isConformingBody (pbody->left, sym, body) &&
1540 isConformingBody (pbody->right, sym, body);
1542 /*------------------------------------------------------------------*/
1543 /*----------------------------*/
1545 /*----------------------------*/
1549 /*------------------------------------------------------------------*/
1550 /*----------------------------*/
1551 /* return statement */
1552 /*----------------------------*/
1557 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1562 if (astHasSymbol (pbody->left, sym))
1569 return isConformingBody (pbody->left, sym, body) &&
1570 isConformingBody (pbody->right, sym, body);
1576 /*-----------------------------------------------------------------*/
1577 /* isLoopReversible - takes a for loop as input && returns true */
1578 /* if the for loop is reversible. If yes will set the value of */
1579 /* the loop control var & init value & termination value */
1580 /*-----------------------------------------------------------------*/
1582 isLoopReversible (ast * loop, symbol ** loopCntrl,
1583 ast ** init, ast ** end)
1585 /* if option says don't do it then don't */
1586 if (optimize.noLoopReverse)
1588 /* there are several tests to determine this */
1590 /* for loop has to be of the form
1591 for ( <sym> = <const1> ;
1592 [<sym> < <const2>] ;
1593 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1595 if (!isLoopCountable (AST_FOR (loop, initExpr),
1596 AST_FOR (loop, condExpr),
1597 AST_FOR (loop, loopExpr),
1598 loopCntrl, init, end))
1601 /* now do some serious checking on the body of the loop
1604 return isConformingBody (loop->left, *loopCntrl, loop->left);
1608 /*-----------------------------------------------------------------*/
1609 /* replLoopSym - replace the loop sym by loop sym -1 */
1610 /*-----------------------------------------------------------------*/
1612 replLoopSym (ast * body, symbol * sym)
1615 if (!body || IS_AST_LINK (body))
1618 if (IS_AST_SYM_VALUE (body))
1621 if (isSymbolEqual (AST_SYMBOL (body), sym))
1625 body->opval.op = '-';
1626 body->left = newAst_VALUE (symbolVal (sym));
1627 body->right = newAst_VALUE (constVal ("1"));
1635 replLoopSym (body->left, sym);
1636 replLoopSym (body->right, sym);
1640 /*-----------------------------------------------------------------*/
1641 /* reverseLoop - do the actual loop reversal */
1642 /*-----------------------------------------------------------------*/
1644 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1648 /* create the following tree
1653 if (sym) goto for_continue ;
1656 /* put it together piece by piece */
1657 rloop = newNode (NULLOP,
1658 createIf (newAst_VALUE (symbolVal (sym)),
1660 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1663 newAst_VALUE (symbolVal (sym)),
1666 replLoopSym (loop->left, sym);
1668 rloop = newNode (NULLOP,
1670 newAst_VALUE (symbolVal (sym)),
1671 newNode ('-', end, init)),
1672 createLabel (AST_FOR (loop, continueLabel),
1676 newNode (SUB_ASSIGN,
1677 newAst_VALUE (symbolVal (sym)),
1678 newAst_VALUE (constVal ("1"))),
1681 return decorateType (rloop);
1685 #define DEMAND_INTEGER_PROMOTION
1687 #ifdef DEMAND_INTEGER_PROMOTION
1689 /*-----------------------------------------------------------------*/
1690 /* walk a tree looking for the leaves. Add a typecast to the given */
1691 /* type to each value leaf node. */
1692 /*-----------------------------------------------------------------*/
1694 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1696 if (!node || IS_CALLOP(node))
1698 /* WTF? We should never get here. */
1702 if (!node->left && !node->right)
1704 /* We're at a leaf; if it's a value, apply the typecast */
1705 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1707 *parentPtr = decorateType (newNode (CAST,
1708 newAst_LINK (copyLinkChain (type)),
1716 pushTypeCastToLeaves (type, node->left, &(node->left));
1720 pushTypeCastToLeaves (type, node->right, &(node->right));
1727 /*-----------------------------------------------------------------*/
1728 /* Given an assignment operation in a tree, determine if the LHS */
1729 /* (the result) has a different (integer) type than the RHS. */
1730 /* If so, walk the RHS and add a typecast to the type of the LHS */
1731 /* to all leaf nodes. */
1732 /*-----------------------------------------------------------------*/
1734 propAsgType (ast * tree)
1736 #ifdef DEMAND_INTEGER_PROMOTION
1737 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1739 /* Nothing to do here... */
1743 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1745 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1752 /*-----------------------------------------------------------------*/
1753 /* decorateType - compute type for this tree also does type cheking */
1754 /* this is done bottom up, since type have to flow upwards */
1755 /* it also does constant folding, and paramater checking */
1756 /*-----------------------------------------------------------------*/
1758 decorateType (ast * tree)
1766 /* if already has type then do nothing */
1767 if (tree->decorated)
1770 tree->decorated = 1;
1772 /* print the line */
1773 /* if not block & function */
1774 if (tree->type == EX_OP &&
1775 (tree->opval.op != FUNCTION &&
1776 tree->opval.op != BLOCK &&
1777 tree->opval.op != NULLOP))
1779 filename = tree->filename;
1780 lineno = tree->lineno;
1783 /* if any child is an error | this one is an error do nothing */
1784 if (tree->isError ||
1785 (tree->left && tree->left->isError) ||
1786 (tree->right && tree->right->isError))
1789 /*------------------------------------------------------------------*/
1790 /*----------------------------*/
1791 /* leaf has been reached */
1792 /*----------------------------*/
1793 /* if this is of type value */
1794 /* just get the type */
1795 if (tree->type == EX_VALUE)
1798 if (IS_LITERAL (tree->opval.val->etype))
1801 /* if this is a character array then declare it */
1802 if (IS_ARRAY (tree->opval.val->type))
1803 tree->opval.val = stringToSymbol (tree->opval.val);
1805 /* otherwise just copy the type information */
1806 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1807 if (funcInChain (tree->opval.val->type))
1809 tree->hasVargs = tree->opval.val->sym->hasVargs;
1810 tree->args = copyValueChain (tree->opval.val->sym->args);
1815 if (tree->opval.val->sym)
1817 /* if the undefined flag is set then give error message */
1818 if (tree->opval.val->sym->undefined)
1820 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1822 TTYPE (tree) = TETYPE (tree) =
1823 tree->opval.val->type = tree->opval.val->sym->type =
1824 tree->opval.val->etype = tree->opval.val->sym->etype =
1825 copyLinkChain (INTTYPE);
1830 /* if impilicit i.e. struct/union member then no type */
1831 if (tree->opval.val->sym->implicit)
1832 TTYPE (tree) = TETYPE (tree) = NULL;
1837 /* else copy the type */
1838 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1840 /* and mark it as referenced */
1841 tree->opval.val->sym->isref = 1;
1842 /* if this is of type function or function pointer */
1843 if (funcInChain (tree->opval.val->type))
1845 tree->hasVargs = tree->opval.val->sym->hasVargs;
1846 tree->args = copyValueChain (tree->opval.val->sym->args);
1856 /* if type link for the case of cast */
1857 if (tree->type == EX_LINK)
1859 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1866 dtl = decorateType (tree->left);
1867 dtr = decorateType (tree->right);
1869 /* this is to take care of situations
1870 when the tree gets rewritten */
1871 if (dtl != tree->left)
1873 if (dtr != tree->right)
1877 /* depending on type of operator do */
1879 switch (tree->opval.op)
1881 /*------------------------------------------------------------------*/
1882 /*----------------------------*/
1884 /*----------------------------*/
1887 /* determine which is the array & which the index */
1888 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1891 ast *tempTree = tree->left;
1892 tree->left = tree->right;
1893 tree->right = tempTree;
1896 /* first check if this is a array or a pointer */
1897 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1899 werror (E_NEED_ARRAY_PTR, "[]");
1900 goto errorTreeReturn;
1903 /* check if the type of the idx */
1904 if (!IS_INTEGRAL (RTYPE (tree)))
1906 werror (E_IDX_NOT_INT);
1907 goto errorTreeReturn;
1910 /* if the left is an rvalue then error */
1913 werror (E_LVALUE_REQUIRED, "array access");
1914 goto errorTreeReturn;
1917 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1918 if (IS_PTR(LTYPE(tree))) {
1919 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1923 /*------------------------------------------------------------------*/
1924 /*----------------------------*/
1926 /*----------------------------*/
1928 /* if this is not a structure */
1929 if (!IS_STRUCT (LTYPE (tree)))
1931 werror (E_STRUCT_UNION, ".");
1932 goto errorTreeReturn;
1934 TTYPE (tree) = structElemType (LTYPE (tree),
1935 (tree->right->type == EX_VALUE ?
1936 tree->right->opval.val : NULL), &tree->args);
1937 TETYPE (tree) = getSpec (TTYPE (tree));
1940 /*------------------------------------------------------------------*/
1941 /*----------------------------*/
1942 /* struct/union pointer */
1943 /*----------------------------*/
1945 /* if not pointer to a structure */
1946 if (!IS_PTR (LTYPE (tree)))
1948 werror (E_PTR_REQD);
1949 goto errorTreeReturn;
1952 if (!IS_STRUCT (LTYPE (tree)->next))
1954 werror (E_STRUCT_UNION, "->");
1955 goto errorTreeReturn;
1958 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1959 (tree->right->type == EX_VALUE ?
1960 tree->right->opval.val : NULL), &tree->args);
1961 TETYPE (tree) = getSpec (TTYPE (tree));
1964 /*------------------------------------------------------------------*/
1965 /*----------------------------*/
1966 /* ++/-- operation */
1967 /*----------------------------*/
1968 case INC_OP: /* incerement operator unary so left only */
1971 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1972 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1973 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
1974 werror (E_CODE_WRITE, "++/--");
1983 /*------------------------------------------------------------------*/
1984 /*----------------------------*/
1986 /*----------------------------*/
1987 case '&': /* can be unary */
1988 /* if right is NULL then unary operation */
1989 if (tree->right) /* not an unary operation */
1992 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1994 werror (E_BITWISE_OP);
1995 werror (E_CONTINUE, "left & right types are ");
1996 printTypeChain (LTYPE (tree), stderr);
1997 fprintf (stderr, ",");
1998 printTypeChain (RTYPE (tree), stderr);
1999 fprintf (stderr, "\n");
2000 goto errorTreeReturn;
2003 /* if they are both literal */
2004 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2006 tree->type = EX_VALUE;
2007 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2008 valFromType (RETYPE (tree)), '&');
2010 tree->right = tree->left = NULL;
2011 TETYPE (tree) = tree->opval.val->etype;
2012 TTYPE (tree) = tree->opval.val->type;
2016 /* see if this is a GETHBIT operation if yes
2019 ast *otree = optimizeGetHbit (tree);
2022 return decorateType (otree);
2025 /* if right or left is literal then result of that type */
2026 if (IS_LITERAL (RTYPE (tree)))
2029 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2030 TETYPE (tree) = getSpec (TTYPE (tree));
2031 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2035 if (IS_LITERAL (LTYPE (tree)))
2037 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2038 TETYPE (tree) = getSpec (TTYPE (tree));
2039 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2045 computeType (LTYPE (tree), RTYPE (tree));
2046 TETYPE (tree) = getSpec (TTYPE (tree));
2049 LRVAL (tree) = RRVAL (tree) = 1;
2053 /*------------------------------------------------------------------*/
2054 /*----------------------------*/
2056 /*----------------------------*/
2058 p->class = DECLARATOR;
2059 /* if bit field then error */
2060 if (IS_BITVAR (tree->left->etype))
2062 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2063 goto errorTreeReturn;
2066 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2068 werror (E_ILLEGAL_ADDR, "address of register variable");
2069 goto errorTreeReturn;
2072 if (IS_FUNC (LTYPE (tree)))
2074 werror (E_ILLEGAL_ADDR, "address of function");
2075 goto errorTreeReturn;
2080 werror (E_LVALUE_REQUIRED, "address of");
2081 goto errorTreeReturn;
2083 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2085 DCL_TYPE (p) = CPOINTER;
2086 DCL_PTR_CONST (p) = port->mem.code_ro;
2088 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2089 DCL_TYPE (p) = FPOINTER;
2090 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2091 DCL_TYPE (p) = PPOINTER;
2092 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2093 DCL_TYPE (p) = IPOINTER;
2094 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2095 DCL_TYPE (p) = EEPPOINTER;
2097 DCL_TYPE (p) = POINTER;
2099 if (IS_AST_SYM_VALUE (tree->left))
2101 AST_SYMBOL (tree->left)->addrtaken = 1;
2102 AST_SYMBOL (tree->left)->allocreq = 1;
2105 p->next = LTYPE (tree);
2107 TETYPE (tree) = getSpec (TTYPE (tree));
2108 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2109 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2114 /*------------------------------------------------------------------*/
2115 /*----------------------------*/
2117 /*----------------------------*/
2119 /* if the rewrite succeeds then don't go any furthur */
2121 ast *wtree = optimizeRRCRLC (tree);
2123 return decorateType (wtree);
2125 /*------------------------------------------------------------------*/
2126 /*----------------------------*/
2128 /*----------------------------*/
2130 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2132 werror (E_BITWISE_OP);
2133 werror (E_CONTINUE, "left & right types are ");
2134 printTypeChain (LTYPE (tree), stderr);
2135 fprintf (stderr, ",");
2136 printTypeChain (RTYPE (tree), stderr);
2137 fprintf (stderr, "\n");
2138 goto errorTreeReturn;
2141 /* if they are both literal then */
2142 /* rewrite the tree */
2143 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2145 tree->type = EX_VALUE;
2146 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2147 valFromType (RETYPE (tree)),
2149 tree->right = tree->left = NULL;
2150 TETYPE (tree) = tree->opval.val->etype;
2151 TTYPE (tree) = tree->opval.val->type;
2154 LRVAL (tree) = RRVAL (tree) = 1;
2155 TETYPE (tree) = getSpec (TTYPE (tree) =
2156 computeType (LTYPE (tree),
2159 /*------------------------------------------------------------------*/
2160 /*----------------------------*/
2162 /*----------------------------*/
2164 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2166 werror (E_INVALID_OP, "divide");
2167 goto errorTreeReturn;
2169 /* if they are both literal then */
2170 /* rewrite the tree */
2171 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2173 tree->type = EX_VALUE;
2174 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2175 valFromType (RETYPE (tree)));
2176 tree->right = tree->left = NULL;
2177 TETYPE (tree) = getSpec (TTYPE (tree) =
2178 tree->opval.val->type);
2181 LRVAL (tree) = RRVAL (tree) = 1;
2182 TETYPE (tree) = getSpec (TTYPE (tree) =
2183 computeType (LTYPE (tree),
2187 /*------------------------------------------------------------------*/
2188 /*----------------------------*/
2190 /*----------------------------*/
2192 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2194 werror (E_BITWISE_OP);
2195 werror (E_CONTINUE, "left & right types are ");
2196 printTypeChain (LTYPE (tree), stderr);
2197 fprintf (stderr, ",");
2198 printTypeChain (RTYPE (tree), stderr);
2199 fprintf (stderr, "\n");
2200 goto errorTreeReturn;
2202 /* if they are both literal then */
2203 /* rewrite the tree */
2204 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2206 tree->type = EX_VALUE;
2207 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2208 valFromType (RETYPE (tree)));
2209 tree->right = tree->left = NULL;
2210 TETYPE (tree) = getSpec (TTYPE (tree) =
2211 tree->opval.val->type);
2214 LRVAL (tree) = RRVAL (tree) = 1;
2215 TETYPE (tree) = getSpec (TTYPE (tree) =
2216 computeType (LTYPE (tree),
2220 /*------------------------------------------------------------------*/
2221 /*----------------------------*/
2222 /* address dereference */
2223 /*----------------------------*/
2224 case '*': /* can be unary : if right is null then unary operation */
2227 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2229 werror (E_PTR_REQD);
2230 goto errorTreeReturn;
2235 werror (E_LVALUE_REQUIRED, "pointer deref");
2236 goto errorTreeReturn;
2238 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2239 LTYPE (tree)->next : NULL);
2240 TETYPE (tree) = getSpec (TTYPE (tree));
2241 tree->args = tree->left->args;
2242 tree->hasVargs = tree->left->hasVargs;
2243 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2247 /*------------------------------------------------------------------*/
2248 /*----------------------------*/
2249 /* multiplication */
2250 /*----------------------------*/
2251 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2253 werror (E_INVALID_OP, "multiplication");
2254 goto errorTreeReturn;
2257 /* if they are both literal then */
2258 /* rewrite the tree */
2259 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2261 tree->type = EX_VALUE;
2262 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2263 valFromType (RETYPE (tree)));
2264 tree->right = tree->left = NULL;
2265 TETYPE (tree) = getSpec (TTYPE (tree) =
2266 tree->opval.val->type);
2270 /* if left is a literal exchange left & right */
2271 if (IS_LITERAL (LTYPE (tree)))
2273 ast *tTree = tree->left;
2274 tree->left = tree->right;
2275 tree->right = tTree;
2278 LRVAL (tree) = RRVAL (tree) = 1;
2279 /* promote result to int if left & right are char / short
2280 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2281 if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) &&
2282 (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
2283 TETYPE (tree) = getSpec (TTYPE (tree) =
2284 computeType (LTYPE (tree),
2286 SPEC_NOUN(TETYPE(tree)) = V_INT;
2287 SPEC_SHORT(TETYPE(tree))=0;
2289 TETYPE (tree) = getSpec (TTYPE (tree) =
2290 computeType (LTYPE (tree),
2295 /*------------------------------------------------------------------*/
2296 /*----------------------------*/
2297 /* unary '+' operator */
2298 /*----------------------------*/
2303 if (!IS_INTEGRAL (LTYPE (tree)))
2305 werror (E_UNARY_OP, '+');
2306 goto errorTreeReturn;
2309 /* if left is a literal then do it */
2310 if (IS_LITERAL (LTYPE (tree)))
2312 tree->type = EX_VALUE;
2313 tree->opval.val = valFromType (LETYPE (tree));
2315 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2319 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2323 /*------------------------------------------------------------------*/
2324 /*----------------------------*/
2326 /*----------------------------*/
2328 /* this is not a unary operation */
2329 /* if both pointers then problem */
2330 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2331 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2333 werror (E_PTR_PLUS_PTR);
2334 goto errorTreeReturn;
2337 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2338 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2340 werror (E_PLUS_INVALID, "+");
2341 goto errorTreeReturn;
2344 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2345 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2347 werror (E_PLUS_INVALID, "+");
2348 goto errorTreeReturn;
2350 /* if they are both literal then */
2351 /* rewrite the tree */
2352 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2354 tree->type = EX_VALUE;
2355 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2356 valFromType (RETYPE (tree)));
2357 tree->right = tree->left = NULL;
2358 TETYPE (tree) = getSpec (TTYPE (tree) =
2359 tree->opval.val->type);
2363 /* if the right is a pointer or left is a literal
2364 xchange left & right */
2365 if (IS_ARRAY (RTYPE (tree)) ||
2366 IS_PTR (RTYPE (tree)) ||
2367 IS_LITERAL (LTYPE (tree)))
2369 ast *tTree = tree->left;
2370 tree->left = tree->right;
2371 tree->right = tTree;
2374 LRVAL (tree) = RRVAL (tree) = 1;
2375 /* if the left is a pointer */
2376 if (IS_PTR (LTYPE (tree)))
2377 TETYPE (tree) = getSpec (TTYPE (tree) =
2380 TETYPE (tree) = getSpec (TTYPE (tree) =
2381 computeType (LTYPE (tree),
2385 /*------------------------------------------------------------------*/
2386 /*----------------------------*/
2388 /*----------------------------*/
2389 case '-': /* can be unary */
2390 /* if right is null then unary */
2394 if (!IS_ARITHMETIC (LTYPE (tree)))
2396 werror (E_UNARY_OP, tree->opval.op);
2397 goto errorTreeReturn;
2400 /* if left is a literal then do it */
2401 if (IS_LITERAL (LTYPE (tree)))
2403 tree->type = EX_VALUE;
2404 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2406 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2407 SPEC_USIGN(TETYPE(tree)) = 0;
2411 TTYPE (tree) = LTYPE (tree);
2415 /*------------------------------------------------------------------*/
2416 /*----------------------------*/
2418 /*----------------------------*/
2420 if (!(IS_PTR (LTYPE (tree)) ||
2421 IS_ARRAY (LTYPE (tree)) ||
2422 IS_ARITHMETIC (LTYPE (tree))))
2424 werror (E_PLUS_INVALID, "-");
2425 goto errorTreeReturn;
2428 if (!(IS_PTR (RTYPE (tree)) ||
2429 IS_ARRAY (RTYPE (tree)) ||
2430 IS_ARITHMETIC (RTYPE (tree))))
2432 werror (E_PLUS_INVALID, "-");
2433 goto errorTreeReturn;
2436 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2437 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2438 IS_INTEGRAL (RTYPE (tree))))
2440 werror (E_PLUS_INVALID, "-");
2441 goto errorTreeReturn;
2444 /* if they are both literal then */
2445 /* rewrite the tree */
2446 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2448 tree->type = EX_VALUE;
2449 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2450 valFromType (RETYPE (tree)));
2451 tree->right = tree->left = NULL;
2452 TETYPE (tree) = getSpec (TTYPE (tree) =
2453 tree->opval.val->type);
2457 /* if the left & right are equal then zero */
2458 if (isAstEqual (tree->left, tree->right))
2460 tree->type = EX_VALUE;
2461 tree->left = tree->right = NULL;
2462 tree->opval.val = constVal ("0");
2463 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2467 /* if both of them are pointers or arrays then */
2468 /* the result is going to be an integer */
2469 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2470 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2471 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2473 /* if only the left is a pointer */
2474 /* then result is a pointer */
2475 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2476 TETYPE (tree) = getSpec (TTYPE (tree) =
2479 TETYPE (tree) = getSpec (TTYPE (tree) =
2480 computeType (LTYPE (tree),
2482 LRVAL (tree) = RRVAL (tree) = 1;
2485 /*------------------------------------------------------------------*/
2486 /*----------------------------*/
2488 /*----------------------------*/
2490 /* can be only integral type */
2491 if (!IS_INTEGRAL (LTYPE (tree)))
2493 werror (E_UNARY_OP, tree->opval.op);
2494 goto errorTreeReturn;
2497 /* if left is a literal then do it */
2498 if (IS_LITERAL (LTYPE (tree)))
2500 tree->type = EX_VALUE;
2501 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2503 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2507 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2510 /*------------------------------------------------------------------*/
2511 /*----------------------------*/
2513 /*----------------------------*/
2515 /* can be pointer */
2516 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2517 !IS_PTR (LTYPE (tree)) &&
2518 !IS_ARRAY (LTYPE (tree)))
2520 werror (E_UNARY_OP, tree->opval.op);
2521 goto errorTreeReturn;
2524 /* if left is a literal then do it */
2525 if (IS_LITERAL (LTYPE (tree)))
2527 tree->type = EX_VALUE;
2528 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2530 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2534 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2537 /*------------------------------------------------------------------*/
2538 /*----------------------------*/
2540 /*----------------------------*/
2543 TTYPE (tree) = LTYPE (tree);
2544 TETYPE (tree) = LETYPE (tree);
2548 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2553 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2555 werror (E_SHIFT_OP_INVALID);
2556 werror (E_CONTINUE, "left & right types are ");
2557 printTypeChain (LTYPE (tree), stderr);
2558 fprintf (stderr, ",");
2559 printTypeChain (RTYPE (tree), stderr);
2560 fprintf (stderr, "\n");
2561 goto errorTreeReturn;
2564 /* if they are both literal then */
2565 /* rewrite the tree */
2566 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2568 tree->type = EX_VALUE;
2569 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2570 valFromType (RETYPE (tree)),
2571 (tree->opval.op == LEFT_OP ? 1 : 0));
2572 tree->right = tree->left = NULL;
2573 TETYPE (tree) = getSpec (TTYPE (tree) =
2574 tree->opval.val->type);
2577 /* if only the right side is a literal & we are
2578 shifting more than size of the left operand then zero */
2579 if (IS_LITERAL (RTYPE (tree)) &&
2580 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2581 (getSize (LTYPE (tree)) * 8))
2583 werror (W_SHIFT_CHANGED,
2584 (tree->opval.op == LEFT_OP ? "left" : "right"));
2585 tree->type = EX_VALUE;
2586 tree->left = tree->right = NULL;
2587 tree->opval.val = constVal ("0");
2588 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2591 LRVAL (tree) = RRVAL (tree) = 1;
2592 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2594 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2598 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2602 /*------------------------------------------------------------------*/
2603 /*----------------------------*/
2605 /*----------------------------*/
2606 case CAST: /* change the type */
2607 /* cannot cast to an aggregate type */
2608 if (IS_AGGREGATE (LTYPE (tree)))
2610 werror (E_CAST_ILLEGAL);
2611 goto errorTreeReturn;
2614 /* if the right is a literal replace the tree */
2615 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2617 tree->type = EX_VALUE;
2619 valCastLiteral (LTYPE (tree),
2620 floatFromVal (valFromType (RETYPE (tree))));
2623 TTYPE (tree) = tree->opval.val->type;
2624 tree->values.literalFromCast = 1;
2628 TTYPE (tree) = LTYPE (tree);
2632 TETYPE (tree) = getSpec (TTYPE (tree));
2636 /*------------------------------------------------------------------*/
2637 /*----------------------------*/
2638 /* logical &&, || */
2639 /*----------------------------*/
2642 /* each must me arithmetic type or be a pointer */
2643 if (!IS_PTR (LTYPE (tree)) &&
2644 !IS_ARRAY (LTYPE (tree)) &&
2645 !IS_INTEGRAL (LTYPE (tree)))
2647 werror (E_COMPARE_OP);
2648 goto errorTreeReturn;
2651 if (!IS_PTR (RTYPE (tree)) &&
2652 !IS_ARRAY (RTYPE (tree)) &&
2653 !IS_INTEGRAL (RTYPE (tree)))
2655 werror (E_COMPARE_OP);
2656 goto errorTreeReturn;
2658 /* if they are both literal then */
2659 /* rewrite the tree */
2660 if (IS_LITERAL (RTYPE (tree)) &&
2661 IS_LITERAL (LTYPE (tree)))
2663 tree->type = EX_VALUE;
2664 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2665 valFromType (RETYPE (tree)),
2667 tree->right = tree->left = NULL;
2668 TETYPE (tree) = getSpec (TTYPE (tree) =
2669 tree->opval.val->type);
2672 LRVAL (tree) = RRVAL (tree) = 1;
2673 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2676 /*------------------------------------------------------------------*/
2677 /*----------------------------*/
2678 /* comparison operators */
2679 /*----------------------------*/
2687 ast *lt = optimizeCompare (tree);
2693 /* if they are pointers they must be castable */
2694 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2696 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2698 werror (E_COMPARE_OP);
2699 fprintf (stderr, "comparing type ");
2700 printTypeChain (LTYPE (tree), stderr);
2701 fprintf (stderr, "to type ");
2702 printTypeChain (RTYPE (tree), stderr);
2703 fprintf (stderr, "\n");
2704 goto errorTreeReturn;
2707 /* else they should be promotable to one another */
2710 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2711 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2713 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2715 werror (E_COMPARE_OP);
2716 fprintf (stderr, "comparing type ");
2717 printTypeChain (LTYPE (tree), stderr);
2718 fprintf (stderr, "to type ");
2719 printTypeChain (RTYPE (tree), stderr);
2720 fprintf (stderr, "\n");
2721 goto errorTreeReturn;
2725 /* if they are both literal then */
2726 /* rewrite the tree */
2727 if (IS_LITERAL (RTYPE (tree)) &&
2728 IS_LITERAL (LTYPE (tree)))
2730 tree->type = EX_VALUE;
2731 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2732 valFromType (RETYPE (tree)),
2734 tree->right = tree->left = NULL;
2735 TETYPE (tree) = getSpec (TTYPE (tree) =
2736 tree->opval.val->type);
2739 LRVAL (tree) = RRVAL (tree) = 1;
2740 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2743 /*------------------------------------------------------------------*/
2744 /*----------------------------*/
2746 /*----------------------------*/
2747 case SIZEOF: /* evaluate wihout code generation */
2748 /* change the type to a integer */
2749 tree->type = EX_VALUE;
2750 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2751 tree->opval.val = constVal (buffer);
2752 tree->right = tree->left = NULL;
2753 TETYPE (tree) = getSpec (TTYPE (tree) =
2754 tree->opval.val->type);
2757 /*------------------------------------------------------------------*/
2758 /*----------------------------*/
2759 /* conditional operator '?' */
2760 /*----------------------------*/
2762 /* the type is one on the left */
2763 TTYPE (tree) = LTYPE (tree);
2764 TETYPE (tree) = getSpec (TTYPE (tree));
2768 /* if they don't match we have a problem */
2769 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2771 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2772 goto errorTreeReturn;
2775 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2776 TETYPE (tree) = getSpec (TTYPE (tree));
2780 /*------------------------------------------------------------------*/
2781 /*----------------------------*/
2782 /* assignment operators */
2783 /*----------------------------*/
2786 /* for these it must be both must be integral */
2787 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2788 !IS_ARITHMETIC (RTYPE (tree)))
2790 werror (E_OPS_INTEGRAL);
2791 goto errorTreeReturn;
2794 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2796 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2797 werror (E_CODE_WRITE, " ");
2801 werror (E_LVALUE_REQUIRED, "*= or /=");
2802 goto errorTreeReturn;
2815 /* for these it must be both must be integral */
2816 if (!IS_INTEGRAL (LTYPE (tree)) ||
2817 !IS_INTEGRAL (RTYPE (tree)))
2819 werror (E_OPS_INTEGRAL);
2820 goto errorTreeReturn;
2823 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2825 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2826 werror (E_CODE_WRITE, " ");
2830 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2831 goto errorTreeReturn;
2839 /*------------------------------------------------------------------*/
2840 /*----------------------------*/
2842 /*----------------------------*/
2844 if (!(IS_PTR (LTYPE (tree)) ||
2845 IS_ARITHMETIC (LTYPE (tree))))
2847 werror (E_PLUS_INVALID, "-=");
2848 goto errorTreeReturn;
2851 if (!(IS_PTR (RTYPE (tree)) ||
2852 IS_ARITHMETIC (RTYPE (tree))))
2854 werror (E_PLUS_INVALID, "-=");
2855 goto errorTreeReturn;
2858 TETYPE (tree) = getSpec (TTYPE (tree) =
2859 computeType (LTYPE (tree),
2862 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2863 werror (E_CODE_WRITE, " ");
2867 werror (E_LVALUE_REQUIRED, "-=");
2868 goto errorTreeReturn;
2876 /*------------------------------------------------------------------*/
2877 /*----------------------------*/
2879 /*----------------------------*/
2881 /* this is not a unary operation */
2882 /* if both pointers then problem */
2883 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2885 werror (E_PTR_PLUS_PTR);
2886 goto errorTreeReturn;
2889 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2891 werror (E_PLUS_INVALID, "+=");
2892 goto errorTreeReturn;
2895 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2897 werror (E_PLUS_INVALID, "+=");
2898 goto errorTreeReturn;
2901 TETYPE (tree) = getSpec (TTYPE (tree) =
2902 computeType (LTYPE (tree),
2905 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2906 werror (E_CODE_WRITE, " ");
2910 werror (E_LVALUE_REQUIRED, "+=");
2911 goto errorTreeReturn;
2914 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2915 tree->opval.op = '=';
2921 /*------------------------------------------------------------------*/
2922 /*----------------------------*/
2923 /* straight assignemnt */
2924 /*----------------------------*/
2926 /* cannot be an aggregate */
2927 if (IS_AGGREGATE (LTYPE (tree)))
2929 werror (E_AGGR_ASSIGN);
2930 goto errorTreeReturn;
2933 /* they should either match or be castable */
2934 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2936 werror (E_TYPE_MISMATCH, "assignment", " ");
2937 fprintf (stderr, "type --> '");
2938 printTypeChain (RTYPE (tree), stderr);
2939 fprintf (stderr, "' ");
2940 fprintf (stderr, "assigned to type --> '");
2941 printTypeChain (LTYPE (tree), stderr);
2942 fprintf (stderr, "'\n");
2943 goto errorTreeReturn;
2946 /* if the left side of the tree is of type void
2947 then report error */
2948 if (IS_VOID (LTYPE (tree)))
2950 werror (E_CAST_ZERO);
2951 fprintf (stderr, "type --> '");
2952 printTypeChain (RTYPE (tree), stderr);
2953 fprintf (stderr, "' ");
2954 fprintf (stderr, "assigned to type --> '");
2955 printTypeChain (LTYPE (tree), stderr);
2956 fprintf (stderr, "'\n");
2959 /* extra checks for pointer types */
2960 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2961 !IS_GENPTR (LTYPE (tree)))
2963 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2964 werror (W_PTR_ASSIGN);
2967 TETYPE (tree) = getSpec (TTYPE (tree) =
2971 if (!tree->initMode ) {
2972 if (IS_CONSTANT (LETYPE (tree))) {
2973 werror (E_CODE_WRITE, " ");
2978 werror (E_LVALUE_REQUIRED, "=");
2979 goto errorTreeReturn;
2986 /*------------------------------------------------------------------*/
2987 /*----------------------------*/
2988 /* comma operator */
2989 /*----------------------------*/
2991 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
2994 /*------------------------------------------------------------------*/
2995 /*----------------------------*/
2997 /*----------------------------*/
3001 if (processParms (tree->left,
3003 tree->right, &parmNumber, TRUE))
3004 goto errorTreeReturn;
3006 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3008 tree->left->args = reverseVal (tree->left->args);
3009 reverseParms (tree->right);
3012 tree->args = tree->left->args;
3013 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3016 /*------------------------------------------------------------------*/
3017 /*----------------------------*/
3018 /* return statement */
3019 /*----------------------------*/
3024 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3026 werror (E_RETURN_MISMATCH);
3027 goto errorTreeReturn;
3030 if (IS_VOID (currFunc->type->next)
3032 !IS_VOID (RTYPE (tree)))
3034 werror (E_FUNC_VOID);
3035 goto errorTreeReturn;
3038 /* if there is going to be a casing required then add it */
3039 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3041 #if 0 && defined DEMAND_INTEGER_PROMOTION
3042 if (IS_INTEGRAL (currFunc->type->next))
3044 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3050 decorateType (newNode (CAST,
3051 newAst_LINK (copyLinkChain (currFunc->type->next)),
3061 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3063 werror (E_VOID_FUNC, currFunc->name);
3064 goto errorTreeReturn;
3067 TTYPE (tree) = TETYPE (tree) = NULL;
3070 /*------------------------------------------------------------------*/
3071 /*----------------------------*/
3072 /* switch statement */
3073 /*----------------------------*/
3075 /* the switch value must be an integer */
3076 if (!IS_INTEGRAL (LTYPE (tree)))
3078 werror (E_SWITCH_NON_INTEGER);
3079 goto errorTreeReturn;
3082 TTYPE (tree) = TETYPE (tree) = NULL;
3085 /*------------------------------------------------------------------*/
3086 /*----------------------------*/
3088 /*----------------------------*/
3090 tree->left = backPatchLabels (tree->left,
3093 TTYPE (tree) = TETYPE (tree) = NULL;
3096 /*------------------------------------------------------------------*/
3097 /*----------------------------*/
3099 /*----------------------------*/
3102 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3103 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3104 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3106 /* if the for loop is reversible then
3107 reverse it otherwise do what we normally
3113 if (isLoopReversible (tree, &sym, &init, &end))
3114 return reverseLoop (tree, sym, init, end);
3116 return decorateType (createFor (AST_FOR (tree, trueLabel),
3117 AST_FOR (tree, continueLabel),
3118 AST_FOR (tree, falseLabel),
3119 AST_FOR (tree, condLabel),
3120 AST_FOR (tree, initExpr),
3121 AST_FOR (tree, condExpr),
3122 AST_FOR (tree, loopExpr),
3126 TTYPE (tree) = TETYPE (tree) = NULL;
3130 /* some error found this tree will be killed */
3132 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3133 tree->opval.op = NULLOP;
3139 /*-----------------------------------------------------------------*/
3140 /* sizeofOp - processes size of operation */
3141 /*-----------------------------------------------------------------*/
3143 sizeofOp (sym_link * type)
3147 /* get the size and convert it to character */
3148 sprintf (buff, "%d", getSize (type));
3150 /* now convert into value */
3151 return constVal (buff);
3155 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3156 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3157 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3158 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3159 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3160 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3161 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3163 /*-----------------------------------------------------------------*/
3164 /* backPatchLabels - change and or not operators to flow control */
3165 /*-----------------------------------------------------------------*/
3167 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3173 if (!(IS_ANDORNOT (tree)))
3176 /* if this an and */
3179 static int localLbl = 0;
3182 sprintf (buffer, "_and_%d", localLbl++);
3183 localLabel = newSymbol (buffer, NestLevel);
3185 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3187 /* if left is already a IFX then just change the if true label in that */
3188 if (!IS_IFX (tree->left))
3189 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3191 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3192 /* right is a IFX then just join */
3193 if (IS_IFX (tree->right))
3194 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3196 tree->right = createLabel (localLabel, tree->right);
3197 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3199 return newNode (NULLOP, tree->left, tree->right);
3202 /* if this is an or operation */
3205 static int localLbl = 0;
3208 sprintf (buffer, "_or_%d", localLbl++);
3209 localLabel = newSymbol (buffer, NestLevel);
3211 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3213 /* if left is already a IFX then just change the if true label in that */
3214 if (!IS_IFX (tree->left))
3215 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3217 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3218 /* right is a IFX then just join */
3219 if (IS_IFX (tree->right))
3220 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3222 tree->right = createLabel (localLabel, tree->right);
3223 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3225 return newNode (NULLOP, tree->left, tree->right);
3231 int wasnot = IS_NOT (tree->left);
3232 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3234 /* if the left is already a IFX */
3235 if (!IS_IFX (tree->left))
3236 tree->left = newNode (IFX, tree->left, NULL);
3240 tree->left->trueLabel = trueLabel;
3241 tree->left->falseLabel = falseLabel;
3245 tree->left->trueLabel = falseLabel;
3246 tree->left->falseLabel = trueLabel;
3253 tree->trueLabel = trueLabel;
3254 tree->falseLabel = falseLabel;
3261 /*-----------------------------------------------------------------*/
3262 /* createBlock - create expression tree for block */
3263 /*-----------------------------------------------------------------*/
3265 createBlock (symbol * decl, ast * body)
3269 /* if the block has nothing */
3273 ex = newNode (BLOCK, NULL, body);
3274 ex->values.sym = decl;
3276 ex->right = ex->right;
3282 /*-----------------------------------------------------------------*/
3283 /* createLabel - creates the expression tree for labels */
3284 /*-----------------------------------------------------------------*/
3286 createLabel (symbol * label, ast * stmnt)
3289 char name[SDCC_NAME_MAX + 1];
3292 /* must create fresh symbol if the symbol name */
3293 /* exists in the symbol table, since there can */
3294 /* be a variable with the same name as the labl */
3295 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3296 (csym->level == label->level))
3297 label = newSymbol (label->name, label->level);
3299 /* change the name before putting it in add _ */
3300 sprintf (name, "%s", label->name);
3302 /* put the label in the LabelSymbol table */
3303 /* but first check if a label of the same */
3305 if ((csym = findSym (LabelTab, NULL, name)))
3306 werror (E_DUPLICATE_LABEL, label->name);
3308 addSym (LabelTab, label, name, label->level, 0);
3311 label->key = labelKey++;
3312 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3318 /*-----------------------------------------------------------------*/
3319 /* createCase - generates the parsetree for a case statement */
3320 /*-----------------------------------------------------------------*/
3322 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3324 char caseLbl[SDCC_NAME_MAX + 1];
3328 /* if the switch statement does not exist */
3329 /* then case is out of context */
3332 werror (E_CASE_CONTEXT);
3336 caseVal = decorateType (resolveSymbols (caseVal));
3337 /* if not a constant then error */
3338 if (!IS_LITERAL (caseVal->ftype))
3340 werror (E_CASE_CONSTANT);
3344 /* if not a integer than error */
3345 if (!IS_INTEGRAL (caseVal->ftype))
3347 werror (E_CASE_NON_INTEGER);
3351 /* find the end of the switch values chain */
3352 if (!(val = swStat->values.switchVals.swVals))
3353 swStat->values.switchVals.swVals = caseVal->opval.val;
3356 /* also order the cases according to value */
3358 int cVal = (int) floatFromVal (caseVal->opval.val);
3359 while (val && (int) floatFromVal (val) < cVal)
3365 /* if we reached the end then */
3368 pval->next = caseVal->opval.val;
3372 /* we found a value greater than */
3373 /* the current value we must add this */
3374 /* before the value */
3375 caseVal->opval.val->next = val;
3377 /* if this was the first in chain */
3378 if (swStat->values.switchVals.swVals == val)
3379 swStat->values.switchVals.swVals =
3382 pval->next = caseVal->opval.val;
3387 /* create the case label */
3388 sprintf (caseLbl, "_case_%d_%d",
3389 swStat->values.switchVals.swNum,
3390 (int) floatFromVal (caseVal->opval.val));
3392 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3397 /*-----------------------------------------------------------------*/
3398 /* createDefault - creates the parse tree for the default statement */
3399 /*-----------------------------------------------------------------*/
3401 createDefault (ast * swStat, ast * stmnt)
3403 char defLbl[SDCC_NAME_MAX + 1];
3405 /* if the switch statement does not exist */
3406 /* then case is out of context */
3409 werror (E_CASE_CONTEXT);
3413 /* turn on the default flag */
3414 swStat->values.switchVals.swDefault = 1;
3416 /* create the label */
3417 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3418 return createLabel (newSymbol (defLbl, 0), stmnt);
3421 /*-----------------------------------------------------------------*/
3422 /* createIf - creates the parsetree for the if statement */
3423 /*-----------------------------------------------------------------*/
3425 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3427 static int Lblnum = 0;
3429 symbol *ifTrue, *ifFalse, *ifEnd;
3431 /* if neither exists */
3432 if (!elseBody && !ifBody)
3435 /* create the labels */
3436 sprintf (buffer, "_iffalse_%d", Lblnum);
3437 ifFalse = newSymbol (buffer, NestLevel);
3438 /* if no else body then end == false */
3443 sprintf (buffer, "_ifend_%d", Lblnum);
3444 ifEnd = newSymbol (buffer, NestLevel);
3447 sprintf (buffer, "_iftrue_%d", Lblnum);
3448 ifTrue = newSymbol (buffer, NestLevel);
3452 /* attach the ifTrue label to the top of it body */
3453 ifBody = createLabel (ifTrue, ifBody);
3454 /* attach a goto end to the ifBody if else is present */
3457 ifBody = newNode (NULLOP, ifBody,
3459 newAst_VALUE (symbolVal (ifEnd)),
3461 /* put the elseLabel on the else body */
3462 elseBody = createLabel (ifFalse, elseBody);
3463 /* out the end at the end of the body */
3464 elseBody = newNode (NULLOP,
3466 createLabel (ifEnd, NULL));
3470 ifBody = newNode (NULLOP, ifBody,
3471 createLabel (ifFalse, NULL));
3473 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3474 if (IS_IFX (condAst))
3477 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3479 return newNode (NULLOP, ifTree,
3480 newNode (NULLOP, ifBody, elseBody));
3484 /*-----------------------------------------------------------------*/
3485 /* createDo - creates parse tree for do */
3488 /* _docontinue_n: */
3489 /* condition_expression +-> trueLabel -> _dobody_n */
3491 /* +-> falseLabel-> _dobreak_n */
3493 /*-----------------------------------------------------------------*/
3495 createDo (symbol * trueLabel, symbol * continueLabel,
3496 symbol * falseLabel, ast * condAst, ast * doBody)
3501 /* if the body does not exist then it is simple */
3504 condAst = backPatchLabels (condAst, continueLabel, NULL);
3505 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3506 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3507 doTree->trueLabel = continueLabel;
3508 doTree->falseLabel = NULL;
3512 /* otherwise we have a body */
3513 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3515 /* attach the body label to the top */
3516 doBody = createLabel (trueLabel, doBody);
3517 /* attach the continue label to end of body */
3518 doBody = newNode (NULLOP, doBody,
3519 createLabel (continueLabel, NULL));
3521 /* now put the break label at the end */
3522 if (IS_IFX (condAst))
3525 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3527 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3529 /* putting it together */
3530 return newNode (NULLOP, doBody, doTree);
3533 /*-----------------------------------------------------------------*/
3534 /* createFor - creates parse tree for 'for' statement */
3537 /* condExpr +-> trueLabel -> _forbody_n */
3539 /* +-> falseLabel-> _forbreak_n */
3542 /* _forcontinue_n: */
3544 /* goto _forcond_n ; */
3546 /*-----------------------------------------------------------------*/
3548 createFor (symbol * trueLabel, symbol * continueLabel,
3549 symbol * falseLabel, symbol * condLabel,
3550 ast * initExpr, ast * condExpr, ast * loopExpr,
3555 /* if loopexpression not present then we can generate it */
3556 /* the same way as a while */
3558 return newNode (NULLOP, initExpr,
3559 createWhile (trueLabel, continueLabel,
3560 falseLabel, condExpr, forBody));
3561 /* vanilla for statement */
3562 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3564 if (condExpr && !IS_IFX (condExpr))
3565 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3568 /* attach condition label to condition */
3569 condExpr = createLabel (condLabel, condExpr);
3571 /* attach body label to body */
3572 forBody = createLabel (trueLabel, forBody);
3574 /* attach continue to forLoop expression & attach */
3575 /* goto the forcond @ and of loopExpression */
3576 loopExpr = createLabel (continueLabel,
3580 newAst_VALUE (symbolVal (condLabel)),
3582 /* now start putting them together */
3583 forTree = newNode (NULLOP, initExpr, condExpr);
3584 forTree = newNode (NULLOP, forTree, forBody);
3585 forTree = newNode (NULLOP, forTree, loopExpr);
3586 /* finally add the break label */
3587 forTree = newNode (NULLOP, forTree,
3588 createLabel (falseLabel, NULL));
3592 /*-----------------------------------------------------------------*/
3593 /* createWhile - creates parse tree for while statement */
3594 /* the while statement will be created as follows */
3596 /* _while_continue_n: */
3597 /* condition_expression +-> trueLabel -> _while_boby_n */
3599 /* +-> falseLabel -> _while_break_n */
3600 /* _while_body_n: */
3602 /* goto _while_continue_n */
3603 /* _while_break_n: */
3604 /*-----------------------------------------------------------------*/
3606 createWhile (symbol * trueLabel, symbol * continueLabel,
3607 symbol * falseLabel, ast * condExpr, ast * whileBody)
3611 /* put the continue label */
3612 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3613 condExpr = createLabel (continueLabel, condExpr);
3614 condExpr->lineno = 0;
3616 /* put the body label in front of the body */
3617 whileBody = createLabel (trueLabel, whileBody);
3618 whileBody->lineno = 0;
3619 /* put a jump to continue at the end of the body */
3620 /* and put break label at the end of the body */
3621 whileBody = newNode (NULLOP,
3624 newAst_VALUE (symbolVal (continueLabel)),
3625 createLabel (falseLabel, NULL)));
3627 /* put it all together */
3628 if (IS_IFX (condExpr))
3629 whileTree = condExpr;
3632 whileTree = newNode (IFX, condExpr, NULL);
3633 /* put the true & false labels in place */
3634 whileTree->trueLabel = trueLabel;
3635 whileTree->falseLabel = falseLabel;
3638 return newNode (NULLOP, whileTree, whileBody);
3641 /*-----------------------------------------------------------------*/
3642 /* optimizeGetHbit - get highest order bit of the expression */
3643 /*-----------------------------------------------------------------*/
3645 optimizeGetHbit (ast * tree)
3648 /* if this is not a bit and */
3649 if (!IS_BITAND (tree))
3652 /* will look for tree of the form
3653 ( expr >> ((sizeof expr) -1) ) & 1 */
3654 if (!IS_AST_LIT_VALUE (tree->right))
3657 if (AST_LIT_VALUE (tree->right) != 1)
3660 if (!IS_RIGHT_OP (tree->left))
3663 if (!IS_AST_LIT_VALUE (tree->left->right))
3666 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3667 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3670 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3674 /*-----------------------------------------------------------------*/
3675 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3676 /*-----------------------------------------------------------------*/
3678 optimizeRRCRLC (ast * root)
3680 /* will look for trees of the form
3681 (?expr << 1) | (?expr >> 7) or
3682 (?expr >> 7) | (?expr << 1) will make that
3683 into a RLC : operation ..
3685 (?expr >> 1) | (?expr << 7) or
3686 (?expr << 7) | (?expr >> 1) will make that
3687 into a RRC operation
3688 note : by 7 I mean (number of bits required to hold the
3690 /* if the root operations is not a | operation the not */
3691 if (!IS_BITOR (root))
3694 /* I have to think of a better way to match patterns this sucks */
3695 /* that aside let start looking for the first case : I use a the
3696 negative check a lot to improve the efficiency */
3697 /* (?expr << 1) | (?expr >> 7) */
3698 if (IS_LEFT_OP (root->left) &&
3699 IS_RIGHT_OP (root->right))
3702 if (!SPEC_USIGN (TETYPE (root->left->left)))
3705 if (!IS_AST_LIT_VALUE (root->left->right) ||
3706 !IS_AST_LIT_VALUE (root->right->right))
3709 /* make sure it is the same expression */
3710 if (!isAstEqual (root->left->left,
3714 if (AST_LIT_VALUE (root->left->right) != 1)
3717 if (AST_LIT_VALUE (root->right->right) !=
3718 (getSize (TTYPE (root->left->left)) * 8 - 1))
3721 /* whew got the first case : create the AST */
3722 return newNode (RLC, root->left->left, NULL);
3726 /* check for second case */
3727 /* (?expr >> 7) | (?expr << 1) */
3728 if (IS_LEFT_OP (root->right) &&
3729 IS_RIGHT_OP (root->left))
3732 if (!SPEC_USIGN (TETYPE (root->left->left)))
3735 if (!IS_AST_LIT_VALUE (root->left->right) ||
3736 !IS_AST_LIT_VALUE (root->right->right))
3739 /* make sure it is the same symbol */
3740 if (!isAstEqual (root->left->left,
3744 if (AST_LIT_VALUE (root->right->right) != 1)
3747 if (AST_LIT_VALUE (root->left->right) !=
3748 (getSize (TTYPE (root->left->left)) * 8 - 1))
3751 /* whew got the first case : create the AST */
3752 return newNode (RLC, root->left->left, NULL);
3757 /* third case for RRC */
3758 /* (?symbol >> 1) | (?symbol << 7) */
3759 if (IS_LEFT_OP (root->right) &&
3760 IS_RIGHT_OP (root->left))
3763 if (!SPEC_USIGN (TETYPE (root->left->left)))
3766 if (!IS_AST_LIT_VALUE (root->left->right) ||
3767 !IS_AST_LIT_VALUE (root->right->right))
3770 /* make sure it is the same symbol */
3771 if (!isAstEqual (root->left->left,
3775 if (AST_LIT_VALUE (root->left->right) != 1)
3778 if (AST_LIT_VALUE (root->right->right) !=
3779 (getSize (TTYPE (root->left->left)) * 8 - 1))
3782 /* whew got the first case : create the AST */
3783 return newNode (RRC, root->left->left, NULL);
3787 /* fourth and last case for now */
3788 /* (?symbol << 7) | (?symbol >> 1) */
3789 if (IS_RIGHT_OP (root->right) &&
3790 IS_LEFT_OP (root->left))
3793 if (!SPEC_USIGN (TETYPE (root->left->left)))
3796 if (!IS_AST_LIT_VALUE (root->left->right) ||
3797 !IS_AST_LIT_VALUE (root->right->right))
3800 /* make sure it is the same symbol */
3801 if (!isAstEqual (root->left->left,
3805 if (AST_LIT_VALUE (root->right->right) != 1)
3808 if (AST_LIT_VALUE (root->left->right) !=
3809 (getSize (TTYPE (root->left->left)) * 8 - 1))
3812 /* whew got the first case : create the AST */
3813 return newNode (RRC, root->left->left, NULL);
3817 /* not found return root */
3821 /*-----------------------------------------------------------------*/
3822 /* optimizeCompare - otimizes compares for bit variables */
3823 /*-----------------------------------------------------------------*/
3825 optimizeCompare (ast * root)
3827 ast *optExpr = NULL;
3830 unsigned int litValue;
3832 /* if nothing then return nothing */
3836 /* if not a compare op then do leaves */
3837 if (!IS_COMPARE_OP (root))
3839 root->left = optimizeCompare (root->left);
3840 root->right = optimizeCompare (root->right);
3844 /* if left & right are the same then depending
3845 of the operation do */
3846 if (isAstEqual (root->left, root->right))
3848 switch (root->opval.op)
3853 optExpr = newAst_VALUE (constVal ("0"));
3858 optExpr = newAst_VALUE (constVal ("1"));
3862 return decorateType (optExpr);
3865 vleft = (root->left->type == EX_VALUE ?
3866 root->left->opval.val : NULL);
3868 vright = (root->right->type == EX_VALUE ?
3869 root->right->opval.val : NULL);
3871 /* if left is a BITVAR in BITSPACE */
3872 /* and right is a LITERAL then opt- */
3873 /* imize else do nothing */
3874 if (vleft && vright &&
3875 IS_BITVAR (vleft->etype) &&
3876 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3877 IS_LITERAL (vright->etype))
3880 /* if right side > 1 then comparison may never succeed */
3881 if ((litValue = (int) floatFromVal (vright)) > 1)
3883 werror (W_BAD_COMPARE);
3889 switch (root->opval.op)
3891 case '>': /* bit value greater than 1 cannot be */
3892 werror (W_BAD_COMPARE);
3896 case '<': /* bit value < 1 means 0 */
3898 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3901 case LE_OP: /* bit value <= 1 means no check */
3902 optExpr = newAst_VALUE (vright);
3905 case GE_OP: /* bit value >= 1 means only check for = */
3907 optExpr = newAst_VALUE (vleft);
3912 { /* literal is zero */
3913 switch (root->opval.op)
3915 case '<': /* bit value < 0 cannot be */
3916 werror (W_BAD_COMPARE);
3920 case '>': /* bit value > 0 means 1 */
3922 optExpr = newAst_VALUE (vleft);
3925 case LE_OP: /* bit value <= 0 means no check */
3926 case GE_OP: /* bit value >= 0 means no check */
3927 werror (W_BAD_COMPARE);
3931 case EQ_OP: /* bit == 0 means ! of bit */
3932 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3936 return decorateType (resolveSymbols (optExpr));
3937 } /* end-of-if of BITVAR */
3942 /*-----------------------------------------------------------------*/
3943 /* addSymToBlock : adds the symbol to the first block we find */
3944 /*-----------------------------------------------------------------*/
3946 addSymToBlock (symbol * sym, ast * tree)
3948 /* reached end of tree or a leaf */
3949 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3953 if (IS_AST_OP (tree) &&
3954 tree->opval.op == BLOCK)
3957 symbol *lsym = copySymbol (sym);
3959 lsym->next = AST_VALUES (tree, sym);
3960 AST_VALUES (tree, sym) = lsym;
3964 addSymToBlock (sym, tree->left);
3965 addSymToBlock (sym, tree->right);
3968 /*-----------------------------------------------------------------*/
3969 /* processRegParms - do processing for register parameters */
3970 /*-----------------------------------------------------------------*/
3972 processRegParms (value * args, ast * body)
3976 if (IS_REGPARM (args->etype))
3977 addSymToBlock (args->sym, body);
3982 /*-----------------------------------------------------------------*/
3983 /* resetParmKey - resets the operandkeys for the symbols */
3984 /*-----------------------------------------------------------------*/
3985 DEFSETFUNC (resetParmKey)
3996 /*-----------------------------------------------------------------*/
3997 /* createFunction - This is the key node that calls the iCode for */
3998 /* generating the code for a function. Note code */
3999 /* is generated function by function, later when */
4000 /* add inter-procedural analysis this will change */
4001 /*-----------------------------------------------------------------*/
4003 createFunction (symbol * name, ast * body)
4009 iCode *piCode = NULL;
4011 /* if check function return 0 then some problem */
4012 if (checkFunction (name) == 0)
4015 /* create a dummy block if none exists */
4017 body = newNode (BLOCK, NULL, NULL);
4021 /* check if the function name already in the symbol table */
4022 if ((csym = findSym (SymbolTab, NULL, name->name)))
4025 /* special case for compiler defined functions
4026 we need to add the name to the publics list : this
4027 actually means we are now compiling the compiler
4031 addSet (&publics, name);
4037 allocVariables (name);
4039 name->lastLine = yylineno;
4041 processFuncArgs (currFunc, 0);
4043 /* set the stack pointer */
4044 /* PENDING: check this for the mcs51 */
4045 stackPtr = -port->stack.direction * port->stack.call_overhead;
4046 if (IS_ISR (name->etype))
4047 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4048 if (IS_RENT (name->etype) || options.stackAuto)
4049 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4051 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4053 fetype = getSpec (name->type); /* get the specifier for the function */
4054 /* if this is a reentrant function then */
4055 if (IS_RENT (fetype))
4058 allocParms (name->args); /* allocate the parameters */
4060 /* do processing for parameters that are passed in registers */
4061 processRegParms (name->args, body);
4063 /* set the stack pointer */
4067 /* allocate & autoinit the block variables */
4068 processBlockVars (body, &stack, ALLOCATE);
4070 /* save the stack information */
4071 if (options.useXstack)
4072 name->xstack = SPEC_STAK (fetype) = stack;
4074 name->stack = SPEC_STAK (fetype) = stack;
4076 /* name needs to be mangled */
4077 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4079 body = resolveSymbols (body); /* resolve the symbols */
4080 body = decorateType (body); /* propagateType & do semantic checks */
4082 ex = newAst_VALUE (symbolVal (name)); /* create name */
4083 ex = newNode (FUNCTION, ex, body);
4084 ex->values.args = name->args;
4088 werror (E_FUNC_NO_CODE, name->name);
4092 /* create the node & generate intermediate code */
4094 codeOutFile = code->oFile;
4095 piCode = iCodeFromAst (ex);
4099 werror (E_FUNC_NO_CODE, name->name);
4103 eBBlockFromiCode (piCode);
4105 /* if there are any statics then do them */
4108 GcurMemmap = statsg;
4109 codeOutFile = statsg->oFile;
4110 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4116 /* dealloc the block variables */
4117 processBlockVars (body, &stack, DEALLOCATE);
4118 /* deallocate paramaters */
4119 deallocParms (name->args);
4121 if (IS_RENT (fetype))
4124 /* we are done freeup memory & cleanup */
4129 addSet (&operKeyReset, name);
4130 applyToSet (operKeyReset, resetParmKey);
4132 if (options.debug && !options.nodebug)
4133 cdbStructBlock (1, cdbFile);
4135 cleanUpLevel (LabelTab, 0);
4136 cleanUpBlock (StructTab, 1);
4137 cleanUpBlock (TypedefTab, 1);
4139 xstack->syms = NULL;
4140 istack->syms = NULL;
4145 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4146 /*-----------------------------------------------------------------*/
4147 /* ast_print : prints the ast (for debugging purposes) */
4148 /*-----------------------------------------------------------------*/
4150 void ast_print (ast * tree, FILE *outfile, int indent)
4155 /* can print only decorated trees */
4156 if (!tree->decorated) return;
4158 /* if any child is an error | this one is an error do nothing */
4159 if (tree->isError ||
4160 (tree->left && tree->left->isError) ||
4161 (tree->right && tree->right->isError)) {
4162 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4166 /* print the line */
4167 /* if not block & function */
4168 if (tree->type == EX_OP &&
4169 (tree->opval.op != FUNCTION &&
4170 tree->opval.op != BLOCK &&
4171 tree->opval.op != NULLOP)) {
4174 if (tree->opval.op == FUNCTION) {
4175 fprintf(outfile,"FUNCTION (%p) type (",tree);
4176 printTypeChain (tree->ftype,outfile);
4177 fprintf(outfile,")\n");
4178 ast_print(tree->left,outfile,indent+4);
4179 ast_print(tree->right,outfile,indent+4);
4182 if (tree->opval.op == BLOCK) {
4183 symbol *decls = tree->values.sym;
4184 fprintf(outfile,"{\n");
4186 INDENT(indent+4,outfile);
4187 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4188 printTypeChain(decls->type,outfile);
4189 fprintf(outfile,")\n");
4191 decls = decls->next;
4193 ast_print(tree->right,outfile,indent+4);
4194 fprintf(outfile,"}\n");
4197 if (tree->opval.op == NULLOP) {
4198 fprintf(outfile,"\n");
4199 ast_print(tree->left,outfile,indent);
4200 fprintf(outfile,"\n");
4201 ast_print(tree->right,outfile,indent);
4204 INDENT(indent,outfile);
4206 /*------------------------------------------------------------------*/
4207 /*----------------------------*/
4208 /* leaf has been reached */
4209 /*----------------------------*/
4210 /* if this is of type value */
4211 /* just get the type */
4212 if (tree->type == EX_VALUE) {
4214 if (IS_LITERAL (tree->opval.val->etype)) {
4215 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4216 (int) floatFromVal(tree->opval.val),
4217 (int) floatFromVal(tree->opval.val),
4218 floatFromVal(tree->opval.val));
4219 } else if (tree->opval.val->sym) {
4220 /* if the undefined flag is set then give error message */
4221 if (tree->opval.val->sym->undefined) {
4222 fprintf(outfile,"UNDEFINED SYMBOL ");
4224 fprintf(outfile,"SYMBOL ");
4226 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4229 fprintf(outfile," type (");
4230 printTypeChain(tree->ftype,outfile);
4231 fprintf(outfile,")\n");
4233 fprintf(outfile,"\n");
4238 /* if type link for the case of cast */
4239 if (tree->type == EX_LINK) {
4240 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4241 printTypeChain(tree->opval.lnk,outfile);
4242 fprintf(outfile,")\n");
4247 /* depending on type of operator do */
4249 switch (tree->opval.op) {
4250 /*------------------------------------------------------------------*/
4251 /*----------------------------*/
4253 /*----------------------------*/
4255 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4256 printTypeChain(tree->ftype,outfile);
4257 fprintf(outfile,")\n");
4258 ast_print(tree->left,outfile,indent+4);
4259 ast_print(tree->right,outfile,indent+4);
4262 /*------------------------------------------------------------------*/
4263 /*----------------------------*/
4265 /*----------------------------*/
4267 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4268 printTypeChain(tree->ftype,outfile);
4269 fprintf(outfile,")\n");
4270 ast_print(tree->left,outfile,indent+4);
4271 ast_print(tree->right,outfile,indent+4);
4274 /*------------------------------------------------------------------*/
4275 /*----------------------------*/
4276 /* struct/union pointer */
4277 /*----------------------------*/
4279 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4280 printTypeChain(tree->ftype,outfile);
4281 fprintf(outfile,")\n");
4282 ast_print(tree->left,outfile,indent+4);
4283 ast_print(tree->right,outfile,indent+4);
4286 /*------------------------------------------------------------------*/
4287 /*----------------------------*/
4288 /* ++/-- operation */
4289 /*----------------------------*/
4290 case INC_OP: /* incerement operator unary so left only */
4291 fprintf(outfile,"INC_OP (%p) type (",tree);
4292 printTypeChain(tree->ftype,outfile);
4293 fprintf(outfile,")\n");
4294 ast_print(tree->left,outfile,indent+4);
4298 fprintf(outfile,"DEC_OP (%p) type (",tree);
4299 printTypeChain(tree->ftype,outfile);
4300 fprintf(outfile,")\n");
4301 ast_print(tree->left,outfile,indent+4);
4304 /*------------------------------------------------------------------*/
4305 /*----------------------------*/
4307 /*----------------------------*/
4310 fprintf(outfile,"& (%p) type (",tree);
4311 printTypeChain(tree->ftype,outfile);
4312 fprintf(outfile,")\n");
4313 ast_print(tree->left,outfile,indent+4);
4314 ast_print(tree->right,outfile,indent+4);
4316 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4317 printTypeChain(tree->ftype,outfile);
4318 fprintf(outfile,")\n");
4319 ast_print(tree->left,outfile,indent+4);
4320 ast_print(tree->right,outfile,indent+4);
4323 /*----------------------------*/
4325 /*----------------------------*/
4327 fprintf(outfile,"OR (%p) type (",tree);
4328 printTypeChain(tree->ftype,outfile);
4329 fprintf(outfile,")\n");
4330 ast_print(tree->left,outfile,indent+4);
4331 ast_print(tree->right,outfile,indent+4);
4333 /*------------------------------------------------------------------*/
4334 /*----------------------------*/
4336 /*----------------------------*/
4338 fprintf(outfile,"XOR (%p) type (",tree);
4339 printTypeChain(tree->ftype,outfile);
4340 fprintf(outfile,")\n");
4341 ast_print(tree->left,outfile,indent+4);
4342 ast_print(tree->right,outfile,indent+4);
4345 /*------------------------------------------------------------------*/
4346 /*----------------------------*/
4348 /*----------------------------*/
4350 fprintf(outfile,"DIV (%p) type (",tree);
4351 printTypeChain(tree->ftype,outfile);
4352 fprintf(outfile,")\n");
4353 ast_print(tree->left,outfile,indent+4);
4354 ast_print(tree->right,outfile,indent+4);
4356 /*------------------------------------------------------------------*/
4357 /*----------------------------*/
4359 /*----------------------------*/
4361 fprintf(outfile,"MOD (%p) type (",tree);
4362 printTypeChain(tree->ftype,outfile);
4363 fprintf(outfile,")\n");
4364 ast_print(tree->left,outfile,indent+4);
4365 ast_print(tree->right,outfile,indent+4);
4368 /*------------------------------------------------------------------*/
4369 /*----------------------------*/
4370 /* address dereference */
4371 /*----------------------------*/
4372 case '*': /* can be unary : if right is null then unary operation */
4374 fprintf(outfile,"DEREF (%p) type (",tree);
4375 printTypeChain(tree->ftype,outfile);
4376 fprintf(outfile,")\n");
4377 ast_print(tree->left,outfile,indent+4);
4380 /*------------------------------------------------------------------*/
4381 /*----------------------------*/
4382 /* multiplication */
4383 /*----------------------------*/
4384 fprintf(outfile,"MULT (%p) type (",tree);
4385 printTypeChain(tree->ftype,outfile);
4386 fprintf(outfile,")\n");
4387 ast_print(tree->left,outfile,indent+4);
4388 ast_print(tree->right,outfile,indent+4);
4392 /*------------------------------------------------------------------*/
4393 /*----------------------------*/
4394 /* unary '+' operator */
4395 /*----------------------------*/
4399 fprintf(outfile,"UPLUS (%p) type (",tree);
4400 printTypeChain(tree->ftype,outfile);
4401 fprintf(outfile,")\n");
4402 ast_print(tree->left,outfile,indent+4);
4404 /*------------------------------------------------------------------*/
4405 /*----------------------------*/
4407 /*----------------------------*/
4408 fprintf(outfile,"ADD (%p) type (",tree);
4409 printTypeChain(tree->ftype,outfile);
4410 fprintf(outfile,")\n");
4411 ast_print(tree->left,outfile,indent+4);
4412 ast_print(tree->right,outfile,indent+4);
4415 /*------------------------------------------------------------------*/
4416 /*----------------------------*/
4418 /*----------------------------*/
4419 case '-': /* can be unary */
4421 fprintf(outfile,"UMINUS (%p) type (",tree);
4422 printTypeChain(tree->ftype,outfile);
4423 fprintf(outfile,")\n");
4424 ast_print(tree->left,outfile,indent+4);
4426 /*------------------------------------------------------------------*/
4427 /*----------------------------*/
4429 /*----------------------------*/
4430 fprintf(outfile,"SUB (%p) type (",tree);
4431 printTypeChain(tree->ftype,outfile);
4432 fprintf(outfile,")\n");
4433 ast_print(tree->left,outfile,indent+4);
4434 ast_print(tree->right,outfile,indent+4);
4437 /*------------------------------------------------------------------*/
4438 /*----------------------------*/
4440 /*----------------------------*/
4442 fprintf(outfile,"COMPL (%p) type (",tree);
4443 printTypeChain(tree->ftype,outfile);
4444 fprintf(outfile,")\n");
4445 ast_print(tree->left,outfile,indent+4);
4447 /*------------------------------------------------------------------*/
4448 /*----------------------------*/
4450 /*----------------------------*/
4452 fprintf(outfile,"NOT (%p) type (",tree);
4453 printTypeChain(tree->ftype,outfile);
4454 fprintf(outfile,")\n");
4455 ast_print(tree->left,outfile,indent+4);
4457 /*------------------------------------------------------------------*/
4458 /*----------------------------*/
4460 /*----------------------------*/
4462 fprintf(outfile,"RRC (%p) type (",tree);
4463 printTypeChain(tree->ftype,outfile);
4464 fprintf(outfile,")\n");
4465 ast_print(tree->left,outfile,indent+4);
4469 fprintf(outfile,"RLC (%p) type (",tree);
4470 printTypeChain(tree->ftype,outfile);
4471 fprintf(outfile,")\n");
4472 ast_print(tree->left,outfile,indent+4);
4475 fprintf(outfile,"GETHBIT (%p) type (",tree);
4476 printTypeChain(tree->ftype,outfile);
4477 fprintf(outfile,")\n");
4478 ast_print(tree->left,outfile,indent+4);
4481 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4482 printTypeChain(tree->ftype,outfile);
4483 fprintf(outfile,")\n");
4484 ast_print(tree->left,outfile,indent+4);
4485 ast_print(tree->right,outfile,indent+4);
4488 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4489 printTypeChain(tree->ftype,outfile);
4490 fprintf(outfile,")\n");
4491 ast_print(tree->left,outfile,indent+4);
4492 ast_print(tree->right,outfile,indent+4);
4494 /*------------------------------------------------------------------*/
4495 /*----------------------------*/
4497 /*----------------------------*/
4498 case CAST: /* change the type */
4499 fprintf(outfile,"CAST (%p) type (",tree);
4500 printTypeChain(tree->ftype,outfile);
4501 fprintf(outfile,")\n");
4502 ast_print(tree->right,outfile,indent+4);
4506 fprintf(outfile,"ANDAND (%p) type (",tree);
4507 printTypeChain(tree->ftype,outfile);
4508 fprintf(outfile,")\n");
4509 ast_print(tree->left,outfile,indent+4);
4510 ast_print(tree->right,outfile,indent+4);
4513 fprintf(outfile,"OROR (%p) type (",tree);
4514 printTypeChain(tree->ftype,outfile);
4515 fprintf(outfile,")\n");
4516 ast_print(tree->left,outfile,indent+4);
4517 ast_print(tree->right,outfile,indent+4);
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4522 /* comparison operators */
4523 /*----------------------------*/
4525 fprintf(outfile,"GT(>) (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+4);
4529 ast_print(tree->right,outfile,indent+4);
4532 fprintf(outfile,"LT(<) (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+4);
4536 ast_print(tree->right,outfile,indent+4);
4539 fprintf(outfile,"LE(<=) (%p) type (",tree);
4540 printTypeChain(tree->ftype,outfile);
4541 fprintf(outfile,")\n");
4542 ast_print(tree->left,outfile,indent+4);
4543 ast_print(tree->right,outfile,indent+4);
4546 fprintf(outfile,"GE(>=) (%p) type (",tree);
4547 printTypeChain(tree->ftype,outfile);
4548 fprintf(outfile,")\n");
4549 ast_print(tree->left,outfile,indent+4);
4550 ast_print(tree->right,outfile,indent+4);
4553 fprintf(outfile,"EQ(==) (%p) type (",tree);
4554 printTypeChain(tree->ftype,outfile);
4555 fprintf(outfile,")\n");
4556 ast_print(tree->left,outfile,indent+4);
4557 ast_print(tree->right,outfile,indent+4);
4560 fprintf(outfile,"NE(!=) (%p) type (",tree);
4561 printTypeChain(tree->ftype,outfile);
4562 fprintf(outfile,")\n");
4563 ast_print(tree->left,outfile,indent+4);
4564 ast_print(tree->right,outfile,indent+4);
4565 /*------------------------------------------------------------------*/
4566 /*----------------------------*/
4568 /*----------------------------*/
4569 case SIZEOF: /* evaluate wihout code generation */
4570 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4573 /*------------------------------------------------------------------*/
4574 /*----------------------------*/
4575 /* conditional operator '?' */
4576 /*----------------------------*/
4578 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+4);
4582 ast_print(tree->right,outfile,indent+4);
4585 fprintf(outfile,"COLON(:) (%p) type (",tree);
4586 printTypeChain(tree->ftype,outfile);
4587 fprintf(outfile,")\n");
4588 ast_print(tree->left,outfile,indent+4);
4589 ast_print(tree->right,outfile,indent+4);
4592 /*------------------------------------------------------------------*/
4593 /*----------------------------*/
4594 /* assignment operators */
4595 /*----------------------------*/
4597 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->left,outfile,indent+4);
4601 ast_print(tree->right,outfile,indent+4);
4604 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4605 printTypeChain(tree->ftype,outfile);
4606 fprintf(outfile,")\n");
4607 ast_print(tree->left,outfile,indent+4);
4608 ast_print(tree->right,outfile,indent+4);
4611 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4612 printTypeChain(tree->ftype,outfile);
4613 fprintf(outfile,")\n");
4614 ast_print(tree->left,outfile,indent+4);
4615 ast_print(tree->right,outfile,indent+4);
4618 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4619 printTypeChain(tree->ftype,outfile);
4620 fprintf(outfile,")\n");
4621 ast_print(tree->left,outfile,indent+4);
4622 ast_print(tree->right,outfile,indent+4);
4625 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4626 printTypeChain(tree->ftype,outfile);
4627 fprintf(outfile,")\n");
4628 ast_print(tree->left,outfile,indent+4);
4629 ast_print(tree->right,outfile,indent+4);
4632 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+4);
4636 ast_print(tree->right,outfile,indent+4);
4639 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4640 printTypeChain(tree->ftype,outfile);
4641 fprintf(outfile,")\n");
4642 ast_print(tree->left,outfile,indent+4);
4643 ast_print(tree->right,outfile,indent+4);
4645 /*------------------------------------------------------------------*/
4646 /*----------------------------*/
4648 /*----------------------------*/
4650 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+4);
4654 ast_print(tree->right,outfile,indent+4);
4656 /*------------------------------------------------------------------*/
4657 /*----------------------------*/
4659 /*----------------------------*/
4661 fprintf(outfile,"ADDASS(+=) (%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);
4667 /*------------------------------------------------------------------*/
4668 /*----------------------------*/
4669 /* straight assignemnt */
4670 /*----------------------------*/
4672 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4673 printTypeChain(tree->ftype,outfile);
4674 fprintf(outfile,")\n");
4675 ast_print(tree->left,outfile,indent+4);
4676 ast_print(tree->right,outfile,indent+4);
4678 /*------------------------------------------------------------------*/
4679 /*----------------------------*/
4680 /* comma operator */
4681 /*----------------------------*/
4683 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+4);
4687 ast_print(tree->right,outfile,indent+4);
4689 /*------------------------------------------------------------------*/
4690 /*----------------------------*/
4692 /*----------------------------*/
4695 fprintf(outfile,"CALL (%p) type (",tree);
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->left,outfile,indent+4);
4699 ast_print(tree->right,outfile,indent+4);
4702 fprintf(outfile,"PARM ");
4703 ast_print(tree->left,outfile,indent+4);
4704 if (tree->right && !IS_AST_PARAM(tree->right)) {
4705 fprintf(outfile,"PARM ");
4706 ast_print(tree->right,outfile,indent+4);
4709 /*------------------------------------------------------------------*/
4710 /*----------------------------*/
4711 /* return statement */
4712 /*----------------------------*/
4714 fprintf(outfile,"RETURN (%p) type (",tree);
4715 printTypeChain(tree->right->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->right,outfile,indent+4);
4719 /*------------------------------------------------------------------*/
4720 /*----------------------------*/
4721 /* label statement */
4722 /*----------------------------*/
4724 fprintf(outfile,"LABEL (%p)",tree);
4725 ast_print(tree->left,outfile,indent+4);
4726 ast_print(tree->right,outfile,indent);
4728 /*------------------------------------------------------------------*/
4729 /*----------------------------*/
4730 /* switch statement */
4731 /*----------------------------*/
4735 fprintf(outfile,"SWITCH (%p) ",tree);
4736 ast_print(tree->left,outfile,0);
4737 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4738 INDENT(indent+4,outfile);
4739 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4740 (int) floatFromVal(val),
4741 tree->values.switchVals.swNum,
4742 (int) floatFromVal(val));
4744 ast_print(tree->right,outfile,indent);
4747 /*------------------------------------------------------------------*/
4748 /*----------------------------*/
4750 /*----------------------------*/
4752 ast_print(tree->left,outfile,indent);
4753 INDENT(indent,outfile);
4754 fprintf(outfile,"IF (%p) \n",tree);
4755 if (tree->trueLabel) {
4756 INDENT(indent,outfile);
4757 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4759 if (tree->falseLabel) {
4760 INDENT(indent,outfile);
4761 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4763 ast_print(tree->right,outfile,indent);
4765 /*------------------------------------------------------------------*/
4766 /*----------------------------*/
4768 /*----------------------------*/
4770 fprintf(outfile,"FOR (%p) \n",tree);
4771 if (AST_FOR( tree, initExpr)) {
4772 INDENT(indent+4,outfile);
4773 fprintf(outfile,"INIT EXPR ");
4774 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4776 if (AST_FOR( tree, condExpr)) {
4777 INDENT(indent+4,outfile);
4778 fprintf(outfile,"COND EXPR ");
4779 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4781 if (AST_FOR( tree, loopExpr)) {
4782 INDENT(indent+4,outfile);
4783 fprintf(outfile,"LOOP EXPR ");
4784 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4786 fprintf(outfile,"FOR LOOP BODY \n");
4787 ast_print(tree->left,outfile,indent+4);
4796 ast_print(t,stdout,1);