1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 set *operKeyReset = NULL;
31 ast *staticAutos = NULL;
34 #define LRVAL(x) x->left->rvalue
35 #define RRVAL(x) x->right->rvalue
36 #define TRVAL(x) x->rvalue
37 #define LLVAL(x) x->left->lvalue
38 #define RLVAL(x) x->right->lvalue
39 #define TLVAL(x) x->lvalue
40 #define RTYPE(x) x->right->ftype
41 #define RETYPE(x) x->right->etype
42 #define LTYPE(x) x->left->ftype
43 #define LETYPE(x) x->left->etype
44 #define TTYPE(x) x->ftype
45 #define TETYPE(x) x->etype
53 ast *createIval (ast *, sym_link *, initList *, ast *);
54 ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 ast *optimizeRRCRLC (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
74 newAst (int type, void *op)
77 static int oldLineno = 0;
79 Safe_calloc (1, ex, sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : yylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
88 /* depending on the type */
92 ex->opval.val = (value *) op;
95 ex->opval.op = (long) op;
98 ex->opval.lnk = (sym_link *) op;
101 ex->opval.stmnt = (unsigned) op;
109 newAst_ (unsigned type)
112 static int oldLineno = 0;
114 ex = Safe_calloc (1, sizeof (ast));
117 ex->lineno = (noLineno ? oldLineno : yylineno);
118 ex->filename = currFname;
119 ex->level = NestLevel;
120 ex->block = currBlockno;
121 ex->initMode = inInitMode;
126 newAst_VALUE (value * val)
128 ast *ex = newAst_ (EX_VALUE);
134 newAst_OP (unsigned op)
136 ast *ex = newAst_ (EX_OP);
142 newAst_LINK (sym_link * val)
144 ast *ex = newAst_ (EX_LINK);
150 newAst_STMNT (unsigned val)
152 ast *ex = newAst_ (EX_STMNT);
153 ex->opval.stmnt = val;
157 /*-----------------------------------------------------------------*/
158 /* newNode - creates a new node */
159 /*-----------------------------------------------------------------*/
161 newNode (long op, ast * left, ast * right)
172 /*-----------------------------------------------------------------*/
173 /* newIfxNode - creates a new Ifx Node */
174 /*-----------------------------------------------------------------*/
176 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
180 /* if this is a literal then we already know the result */
181 if (condAst->etype && IS_LITERAL (condAst->etype))
184 /* then depending on the expression value */
185 if (floatFromVal (condAst->opval.val))
186 ifxNode = newNode (GOTO,
187 newAst_VALUE (symbolVal (trueLabel)),
190 ifxNode = newNode (GOTO,
191 newAst_VALUE (symbolVal (falseLabel)),
196 ifxNode = newNode (IFX, condAst, NULL);
197 ifxNode->trueLabel = trueLabel;
198 ifxNode->falseLabel = falseLabel;
204 /*-----------------------------------------------------------------*/
205 /* copyAstValues - copies value portion of ast if needed */
206 /*-----------------------------------------------------------------*/
208 copyAstValues (ast * dest, ast * src)
210 switch (src->opval.op)
213 dest->values.sym = copySymbolChain (src->values.sym);
217 dest->values.switchVals.swVals =
218 copyValue (src->values.switchVals.swVals);
219 dest->values.switchVals.swDefault =
220 src->values.switchVals.swDefault;
221 dest->values.switchVals.swNum =
222 src->values.switchVals.swNum;
226 dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
227 strcpy (dest->values.inlineasm, src->values.inlineasm);
230 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
231 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
232 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
233 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
234 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
235 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
236 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
241 /*-----------------------------------------------------------------*/
242 /* copyAst - makes a copy of a given astession */
243 /*-----------------------------------------------------------------*/
252 dest = Safe_calloc (1, sizeof (ast));
254 dest->type = src->type;
255 dest->lineno = src->lineno;
256 dest->level = src->level;
257 dest->funcName = src->funcName;
258 dest->argSym = src->argSym;
260 /* if this is a leaf */
262 if (src->type == EX_VALUE)
264 dest->opval.val = copyValue (src->opval.val);
269 if (src->type == EX_LINK)
271 dest->opval.lnk = copyLinkChain (src->opval.lnk);
275 dest->opval.op = src->opval.op;
277 /* if this is a node that has special values */
278 copyAstValues (dest, src);
281 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
283 dest->trueLabel = copySymbol (src->trueLabel);
284 dest->falseLabel = copySymbol (src->falseLabel);
285 dest->left = copyAst (src->left);
286 dest->right = copyAst (src->right);
292 /*-----------------------------------------------------------------*/
293 /* hasSEFcalls - returns TRUE if tree has a function call */
294 /*-----------------------------------------------------------------*/
296 hasSEFcalls (ast * tree)
301 if (tree->type == EX_OP &&
302 (tree->opval.op == CALL ||
303 tree->opval.op == PCALL ||
304 tree->opval.op == '=' ||
305 tree->opval.op == INC_OP ||
306 tree->opval.op == DEC_OP))
309 return (hasSEFcalls (tree->left) |
310 hasSEFcalls (tree->right));
313 /*-----------------------------------------------------------------*/
314 /* isAstEqual - compares two asts & returns 1 if they are equal */
315 /*-----------------------------------------------------------------*/
317 isAstEqual (ast * t1, ast * t2)
326 if (t1->type != t2->type)
332 if (t1->opval.op != t2->opval.op)
334 return (isAstEqual (t1->left, t2->left) &&
335 isAstEqual (t1->right, t2->right));
339 if (t1->opval.val->sym)
341 if (!t2->opval.val->sym)
344 return isSymbolEqual (t1->opval.val->sym,
349 if (t2->opval.val->sym)
352 return (floatFromVal (t1->opval.val) ==
353 floatFromVal (t2->opval.val));
357 /* only compare these two types */
365 /*-----------------------------------------------------------------*/
366 /* resolveSymbols - resolve symbols from the symbol table */
367 /*-----------------------------------------------------------------*/
369 resolveSymbols (ast * tree)
371 /* walk the entire tree and check for values */
372 /* with symbols if we find one then replace */
373 /* symbol with that from the symbol table */
379 /* if not block & function */
380 if (tree->type == EX_OP &&
381 (tree->opval.op != FUNCTION &&
382 tree->opval.op != BLOCK &&
383 tree->opval.op != NULLOP))
385 filename = tree->filename;
386 lineno = tree->lineno;
389 /* make sure we resolve the true & false labels for ifx */
390 if (tree->type == EX_OP && tree->opval.op == IFX)
396 if ((csym = findSym (LabelTab, tree->trueLabel,
397 tree->trueLabel->name)))
398 tree->trueLabel = csym;
400 werror (E_LABEL_UNDEF, tree->trueLabel->name);
403 if (tree->falseLabel)
405 if ((csym = findSym (LabelTab,
407 tree->falseLabel->name)))
408 tree->falseLabel = csym;
410 werror (E_LABEL_UNDEF, tree->falseLabel->name);
415 /* if this is a label resolve it from the labelTab */
416 if (IS_AST_VALUE (tree) &&
417 tree->opval.val->sym &&
418 tree->opval.val->sym->islbl)
421 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
422 tree->opval.val->sym->name);
425 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
427 tree->opval.val->sym = csym;
429 goto resolveChildren;
432 /* do only for leafs */
433 if (IS_AST_VALUE (tree) &&
434 tree->opval.val->sym &&
435 !tree->opval.val->sym->implicit)
438 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
440 /* if found in the symbol table & they r not the same */
441 if (csym && tree->opval.val->sym != csym)
443 tree->opval.val->sym = csym;
444 tree->opval.val->type = csym->type;
445 tree->opval.val->etype = csym->etype;
448 /* if not found in the symbol table */
449 /* mark it as undefined assume it is */
450 /* an integer in data space */
451 if (!csym && !tree->opval.val->sym->implicit)
454 /* if this is a function name then */
455 /* mark it as returning an int */
458 tree->opval.val->sym->type = newLink ();
459 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
460 tree->opval.val->sym->type->next =
461 tree->opval.val->sym->etype = newIntLink ();
462 tree->opval.val->etype = tree->opval.val->etype;
463 tree->opval.val->type = tree->opval.val->sym->type;
464 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
468 tree->opval.val->sym->undefined = 1;
469 tree->opval.val->type =
470 tree->opval.val->etype = newIntLink ();
471 tree->opval.val->sym->type =
472 tree->opval.val->sym->etype = newIntLink ();
478 resolveSymbols (tree->left);
479 resolveSymbols (tree->right);
484 /*-----------------------------------------------------------------*/
485 /* setAstLineno - walks a ast tree & sets the line number */
486 /*-----------------------------------------------------------------*/
488 setAstLineno (ast * tree, int lineno)
493 tree->lineno = lineno;
494 setAstLineno (tree->left, lineno);
495 setAstLineno (tree->right, lineno);
500 /* this functions seems to be superfluous?! kmh */
502 /*-----------------------------------------------------------------*/
503 /* resolveFromTable - will return the symbal table value */
504 /*-----------------------------------------------------------------*/
506 resolveFromTable (value * val)
513 csym = findSymWithLevel (SymbolTab, val->sym);
515 /* if found in the symbol table & they r not the same */
516 if (csym && val->sym != csym &&
517 csym->level == val->sym->level &&
523 val->type = csym->type;
524 val->etype = csym->etype;
531 /*-----------------------------------------------------------------*/
532 /* funcOfType :- function of type with name */
533 /*-----------------------------------------------------------------*/
535 funcOfType (char *name, sym_link * type, sym_link * argType,
539 /* create the symbol */
540 sym = newSymbol (name, 0);
542 /* if arguments required */
547 args = sym->args = newValue ();
551 args->type = copyLinkChain (argType);
552 args->etype = getSpec (args->type);
555 args = args->next = newValue ();
559 /* setup return value */
560 sym->type = newLink ();
561 DCL_TYPE (sym->type) = FUNCTION;
562 sym->type->next = copyLinkChain (type);
563 sym->etype = getSpec (sym->type);
564 SPEC_RENT (sym->etype) = rent;
569 allocVariables (sym);
574 /*-----------------------------------------------------------------*/
575 /* reverseParms - will reverse a parameter tree */
576 /*-----------------------------------------------------------------*/
578 reverseParms (ast * ptree)
584 /* top down if we find a nonParm tree then quit */
585 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
588 ptree->left = ptree->right;
589 ptree->right = ttree;
590 reverseParms (ptree->left);
591 reverseParms (ptree->right);
597 /*-----------------------------------------------------------------*/
598 /* processParms - makes sure the parameters are okay and do some */
599 /* processing with them */
600 /*-----------------------------------------------------------------*/
602 processParms (ast * func,
608 sym_link *fetype = func->etype;
610 /* if none of them exist */
611 if (!defParm && !actParm)
614 /* if the function is being called via a pointer & */
615 /* it has not been defined a reentrant then we cannot */
616 /* have parameters */
617 if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
619 werror (E_NONRENT_ARGS);
623 /* if defined parameters ended but actual parameters */
624 /* exist and this is not defined as a variable arg */
625 /* also check if statckAuto option is specified */
626 if ((!defParm) && actParm && (!func->hasVargs) &&
627 !options.stackAuto && !IS_RENT (fetype))
629 werror (E_TOO_MANY_PARMS);
633 /* if defined parameters present but no actual parameters */
634 if (defParm && !actParm)
636 werror (E_TOO_FEW_PARMS);
640 /* If this is a varargs function... */
641 if (!defParm && actParm && func->hasVargs)
646 if (IS_CAST_OP (actParm)
647 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
649 /* Parameter was explicitly typecast; don't touch it. */
653 /* The ternary ('?') operator is weird: the ftype of the
654 * operator is the type of the condition, but it will return a
655 * (possibly) different type.
657 if (IS_TERNARY_OP(actParm))
659 assert(IS_COLON_OP(actParm->right));
660 assert(actParm->right->left);
661 ftype = actParm->right->left->ftype;
665 ftype = actParm->ftype;
668 /* If it's a small integer, upcast to int. */
669 if (IS_INTEGRAL (ftype)
670 && (getSize (ftype) < (unsigned) INTSIZE))
672 newType = newAst_LINK(INTTYPE);
675 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
677 newType = newAst_LINK (copyLinkChain(ftype));
678 DCL_TYPE (newType->opval.lnk) = GPOINTER;
681 if (IS_AGGREGATE (ftype))
683 newType = newAst_LINK (copyLinkChain (ftype));
684 DCL_TYPE (newType->opval.lnk) = GPOINTER;
688 /* cast required; change this op to a cast. */
689 ast *parmCopy = resolveSymbols (copyAst (actParm));
691 actParm->type = EX_OP;
692 actParm->opval.op = CAST;
693 actParm->left = newType;
694 actParm->right = parmCopy;
695 decorateType (actParm);
697 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
699 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
700 processParms (func, NULL, actParm->right, parmNumber, rightmost));
705 /* if defined parameters ended but actual has not & */
707 if (!defParm && actParm &&
708 (options.stackAuto || IS_RENT (fetype)))
711 resolveSymbols (actParm);
712 /* if this is a PARAM node then match left & right */
713 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
715 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
716 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
720 /* If we have found a value node by following only right-hand links,
721 * then we know that there are no more values after us.
723 * Therefore, if there are more defined parameters, the caller didn't
726 if (rightmost && defParm->next)
728 werror (E_TOO_FEW_PARMS);
733 /* the parameter type must be at least castable */
734 if (checkType (defParm->type, actParm->ftype) == 0)
736 werror (E_TYPE_MISMATCH_PARM, *parmNumber);
737 werror (E_CONTINUE, "defined type ");
738 printTypeChain (defParm->type, stderr);
739 fprintf (stderr, "\n");
740 werror (E_CONTINUE, "actual type ");
741 printTypeChain (actParm->ftype, stderr);
742 fprintf (stderr, "\n");
745 /* if the parameter is castable then add the cast */
746 if (checkType (defParm->type, actParm->ftype) < 0)
748 ast *pTree = resolveSymbols (copyAst (actParm));
750 /* now change the current one to a cast */
751 actParm->type = EX_OP;
752 actParm->opval.op = CAST;
753 actParm->left = newAst_LINK (defParm->type);
754 actParm->right = pTree;
755 actParm->etype = defParm->etype;
756 actParm->ftype = defParm->type;
759 /* actParm->argSym = resolveFromTable(defParm)->sym ; */
761 actParm->argSym = defParm->sym;
762 /* make a copy and change the regparm type to the defined parm */
763 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
764 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
768 /*-----------------------------------------------------------------*/
769 /* createIvalType - generates ival for basic types */
770 /*-----------------------------------------------------------------*/
772 createIvalType (ast * sym, sym_link * type, initList * ilist)
776 /* if initList is deep */
777 if (ilist->type == INIT_DEEP)
778 ilist = ilist->init.deep;
780 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
781 return decorateType (newNode ('=', sym, iExpr));
784 /*-----------------------------------------------------------------*/
785 /* createIvalStruct - generates initial value for structures */
786 /*-----------------------------------------------------------------*/
788 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
794 sflds = SPEC_STRUCT (type)->fields;
795 if (ilist->type != INIT_DEEP)
797 werror (E_INIT_STRUCT, "");
801 iloop = ilist->init.deep;
803 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
807 /* if we have come to end */
811 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
812 lAst = decorateType (resolveSymbols (lAst));
813 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
819 /*-----------------------------------------------------------------*/
820 /* createIvalArray - generates code for array initialization */
821 /*-----------------------------------------------------------------*/
823 createIvalArray (ast * sym, sym_link * type, initList * ilist)
827 int lcnt = 0, size = 0;
829 /* take care of the special case */
830 /* array of characters can be init */
832 if (IS_CHAR (type->next))
833 if ((rast = createIvalCharPtr (sym,
835 decorateType (resolveSymbols (list2expr (ilist))))))
837 return decorateType (resolveSymbols (rast));
839 /* not the special case */
840 if (ilist->type != INIT_DEEP)
842 werror (E_INIT_STRUCT, "");
846 iloop = ilist->init.deep;
847 lcnt = DCL_ELEM (type);
854 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1))));
855 aSym = decorateType (resolveSymbols (aSym));
856 rast = createIval (aSym, type->next, iloop, rast);
857 iloop = (iloop ? iloop->next : NULL);
860 /* if not array limits given & we */
861 /* are out of initialisers then */
862 if (!DCL_ELEM (type) && !iloop)
865 /* no of elements given and we */
866 /* have generated for all of them */
871 /* if we have not been given a size */
872 if (!DCL_ELEM (type))
873 DCL_ELEM (type) = size;
875 return decorateType (resolveSymbols (rast));
879 /*-----------------------------------------------------------------*/
880 /* createIvalCharPtr - generates initial values for char pointers */
881 /*-----------------------------------------------------------------*/
883 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
887 /* if this is a pointer & right is a literal array then */
888 /* just assignment will do */
889 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
890 SPEC_SCLS (iexpr->etype) == S_CODE)
891 && IS_ARRAY (iexpr->ftype)))
892 return newNode ('=', sym, iexpr);
894 /* left side is an array so we have to assign each */
896 if ((IS_LITERAL (iexpr->etype) ||
897 SPEC_SCLS (iexpr->etype) == S_CODE)
898 && IS_ARRAY (iexpr->ftype))
901 /* for each character generate an assignment */
902 /* to the array element */
903 char *s = SPEC_CVAL (iexpr->etype).v_char;
908 rast = newNode (NULLOP,
912 newAst_VALUE (valueFromLit ((float) i))),
913 newAst_VALUE (valueFromLit (*s))));
917 rast = newNode (NULLOP,
921 newAst_VALUE (valueFromLit ((float) i))),
922 newAst_VALUE (valueFromLit (*s))));
923 return decorateType (resolveSymbols (rast));
929 /*-----------------------------------------------------------------*/
930 /* createIvalPtr - generates initial value for pointers */
931 /*-----------------------------------------------------------------*/
933 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
939 if (ilist->type == INIT_DEEP)
940 ilist = ilist->init.deep;
942 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
944 /* if character pointer */
945 if (IS_CHAR (type->next))
946 if ((rast = createIvalCharPtr (sym, type, iexpr)))
949 return newNode ('=', sym, iexpr);
952 /*-----------------------------------------------------------------*/
953 /* createIval - generates code for initial value */
954 /*-----------------------------------------------------------------*/
956 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
963 /* if structure then */
964 if (IS_STRUCT (type))
965 rast = createIvalStruct (sym, type, ilist);
967 /* if this is a pointer */
969 rast = createIvalPtr (sym, type, ilist);
971 /* if this is an array */
973 rast = createIvalArray (sym, type, ilist);
975 /* if type is SPECIFIER */
977 rast = createIvalType (sym, type, ilist);
979 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
981 return decorateType (resolveSymbols (rast));
984 /*-----------------------------------------------------------------*/
985 /* initAggregates - initialises aggregate variables with initv */
986 /*-----------------------------------------------------------------*/
988 initAggregates (symbol * sym, initList * ival, ast * wid)
990 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
993 /*-----------------------------------------------------------------*/
994 /* gatherAutoInit - creates assignment expressions for initial */
996 /*-----------------------------------------------------------------*/
998 gatherAutoInit (symbol * autoChain)
1005 for (sym = autoChain; sym; sym = sym->next)
1008 /* resolve the symbols in the ival */
1010 resolveIvalSym (sym->ival);
1012 /* if this is a static variable & has an */
1013 /* initial value the code needs to be lifted */
1014 /* here to the main portion since they can be */
1015 /* initialised only once at the start */
1016 if (IS_STATIC (sym->etype) && sym->ival &&
1017 SPEC_SCLS (sym->etype) != S_CODE)
1021 // this can only be a constant
1022 if (!IS_LITERAL(sym->ival->init.node->etype)) {
1023 werror (E_CONST_EXPECTED);
1026 /* insert the symbol into the symbol table */
1027 /* with level = 0 & name = rname */
1028 newSym = copySymbol (sym);
1029 addSym (SymbolTab, newSym, newSym->name, 0, 0);
1031 /* now lift the code to main */
1032 if (IS_AGGREGATE (sym->type))
1033 work = initAggregates (sym, sym->ival, NULL);
1035 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1036 list2expr (sym->ival));
1038 setAstLineno (work, sym->lineDef);
1042 staticAutos = newNode (NULLOP, staticAutos, work);
1049 /* if there is an initial value */
1050 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1052 if (IS_AGGREGATE (sym->type))
1053 work = initAggregates (sym, sym->ival, NULL);
1055 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1056 list2expr (sym->ival));
1058 setAstLineno (work, sym->lineDef);
1061 init = newNode (NULLOP, init, work);
1070 /*-----------------------------------------------------------------*/
1071 /* stringToSymbol - creates a symbol from a literal string */
1072 /*-----------------------------------------------------------------*/
1074 stringToSymbol (value * val)
1076 char name[SDCC_NAME_MAX + 1];
1077 static int charLbl = 0;
1080 sprintf (name, "_str_%d", charLbl++);
1081 sym = newSymbol (name, 0); /* make it @ level 0 */
1082 strcpy (sym->rname, name);
1084 /* copy the type from the value passed */
1085 sym->type = copyLinkChain (val->type);
1086 sym->etype = getSpec (sym->type);
1087 /* change to storage class & output class */
1088 SPEC_SCLS (sym->etype) = S_CODE;
1089 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1090 SPEC_STAT (sym->etype) = 1;
1091 /* make the level & block = 0 */
1092 sym->block = sym->level = 0;
1094 /* create an ival */
1095 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1100 allocVariables (sym);
1103 return symbolVal (sym);
1107 /*-----------------------------------------------------------------*/
1108 /* processBlockVars - will go thru the ast looking for block if */
1109 /* a block is found then will allocate the syms */
1110 /* will also gather the auto inits present */
1111 /*-----------------------------------------------------------------*/
1113 processBlockVars (ast * tree, int *stack, int action)
1118 /* if this is a block */
1119 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1123 if (action == ALLOCATE)
1125 autoInit = gatherAutoInit (tree->values.sym);
1126 *stack += allocVariables (tree->values.sym);
1128 /* if there are auto inits then do them */
1130 tree->left = newNode (NULLOP, autoInit, tree->left);
1132 else /* action is deallocate */
1133 deallocLocal (tree->values.sym);
1136 processBlockVars (tree->left, stack, action);
1137 processBlockVars (tree->right, stack, action);
1141 /*-----------------------------------------------------------------*/
1142 /* constExprValue - returns the value of a constant expression */
1143 /*-----------------------------------------------------------------*/
1145 constExprValue (ast * cexpr, int check)
1147 cexpr = decorateType (resolveSymbols (cexpr));
1149 /* if this is not a constant then */
1150 if (!IS_LITERAL (cexpr->ftype))
1152 /* then check if this is a literal array
1154 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1155 SPEC_CVAL (cexpr->etype).v_char &&
1156 IS_ARRAY (cexpr->ftype))
1158 value *val = valFromType (cexpr->ftype);
1159 SPEC_SCLS (val->etype) = S_LITERAL;
1160 val->sym = cexpr->opval.val->sym;
1161 val->sym->type = copyLinkChain (cexpr->ftype);
1162 val->sym->etype = getSpec (val->sym->type);
1163 strcpy (val->name, cexpr->opval.val->sym->rname);
1167 /* if we are casting a literal value then */
1168 if (IS_AST_OP (cexpr) &&
1169 cexpr->opval.op == CAST &&
1170 IS_LITERAL (cexpr->left->ftype))
1171 return valCastLiteral (cexpr->ftype,
1172 floatFromVal (cexpr->left->opval.val));
1174 if (IS_AST_VALUE (cexpr))
1175 return cexpr->opval.val;
1178 werror (E_CONST_EXPECTED, "found expression");
1183 /* return the value */
1184 return cexpr->opval.val;
1188 /*-----------------------------------------------------------------*/
1189 /* isLabelInAst - will return true if a given label is found */
1190 /*-----------------------------------------------------------------*/
1192 isLabelInAst (symbol * label, ast * tree)
1194 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1197 if (IS_AST_OP (tree) &&
1198 tree->opval.op == LABEL &&
1199 isSymbolEqual (AST_SYMBOL (tree->left), label))
1202 return isLabelInAst (label, tree->right) &&
1203 isLabelInAst (label, tree->left);
1207 /*-----------------------------------------------------------------*/
1208 /* isLoopCountable - return true if the loop count can be determi- */
1209 /* -ned at compile time . */
1210 /*-----------------------------------------------------------------*/
1212 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1213 symbol ** sym, ast ** init, ast ** end)
1216 /* the loop is considered countable if the following
1217 conditions are true :-
1219 a) initExpr :- <sym> = <const>
1220 b) condExpr :- <sym> < <const1>
1221 c) loopExpr :- <sym> ++
1224 /* first check the initExpr */
1225 if (IS_AST_OP (initExpr) &&
1226 initExpr->opval.op == '=' && /* is assignment */
1227 IS_AST_SYM_VALUE (initExpr->left))
1228 { /* left is a symbol */
1230 *sym = AST_SYMBOL (initExpr->left);
1231 *init = initExpr->right;
1236 /* for now the symbol has to be of
1238 if (!IS_INTEGRAL ((*sym)->type))
1241 /* now check condExpr */
1242 if (IS_AST_OP (condExpr))
1245 switch (condExpr->opval.op)
1248 if (IS_AST_SYM_VALUE (condExpr->left) &&
1249 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1250 IS_AST_LIT_VALUE (condExpr->right))
1252 *end = condExpr->right;
1258 if (IS_AST_OP (condExpr->left) &&
1259 condExpr->left->opval.op == '>' &&
1260 IS_AST_LIT_VALUE (condExpr->left->right) &&
1261 IS_AST_SYM_VALUE (condExpr->left->left) &&
1262 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1265 *end = newNode ('+', condExpr->left->right,
1266 newAst_VALUE (constVal ("1")));
1277 /* check loop expression is of the form <sym>++ */
1278 if (!IS_AST_OP (loopExpr))
1281 /* check if <sym> ++ */
1282 if (loopExpr->opval.op == INC_OP)
1288 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1289 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1296 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1297 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1305 if (loopExpr->opval.op == ADD_ASSIGN)
1308 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1309 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1310 IS_AST_LIT_VALUE (loopExpr->right) &&
1311 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1319 /*-----------------------------------------------------------------*/
1320 /* astHasVolatile - returns true if ast contains any volatile */
1321 /*-----------------------------------------------------------------*/
1323 astHasVolatile (ast * tree)
1328 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1331 if (IS_AST_OP (tree))
1332 return astHasVolatile (tree->left) ||
1333 astHasVolatile (tree->right);
1338 /*-----------------------------------------------------------------*/
1339 /* astHasPointer - return true if the ast contains any ptr variable */
1340 /*-----------------------------------------------------------------*/
1342 astHasPointer (ast * tree)
1347 if (IS_AST_LINK (tree))
1350 /* if we hit an array expression then check
1351 only the left side */
1352 if (IS_AST_OP (tree) && tree->opval.op == '[')
1353 return astHasPointer (tree->left);
1355 if (IS_AST_VALUE (tree))
1356 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1358 return astHasPointer (tree->left) ||
1359 astHasPointer (tree->right);
1363 /*-----------------------------------------------------------------*/
1364 /* astHasSymbol - return true if the ast has the given symbol */
1365 /*-----------------------------------------------------------------*/
1367 astHasSymbol (ast * tree, symbol * sym)
1369 if (!tree || IS_AST_LINK (tree))
1372 if (IS_AST_VALUE (tree))
1374 if (IS_AST_SYM_VALUE (tree))
1375 return isSymbolEqual (AST_SYMBOL (tree), sym);
1380 return astHasSymbol (tree->left, sym) ||
1381 astHasSymbol (tree->right, sym);
1384 /*-----------------------------------------------------------------*/
1385 /* isConformingBody - the loop body has to conform to a set of rules */
1386 /* for the loop to be considered reversible read on for rules */
1387 /*-----------------------------------------------------------------*/
1389 isConformingBody (ast * pbody, symbol * sym, ast * body)
1392 /* we are going to do a pre-order traversal of the
1393 tree && check for the following conditions. (essentially
1394 a set of very shallow tests )
1395 a) the sym passed does not participate in
1396 any arithmetic operation
1397 b) There are no function calls
1398 c) all jumps are within the body
1399 d) address of loop control variable not taken
1400 e) if an assignment has a pointer on the
1401 left hand side make sure right does not have
1402 loop control variable */
1404 /* if we reach the end or a leaf then true */
1405 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1409 /* if anything else is "volatile" */
1410 if (IS_VOLATILE (TETYPE (pbody)))
1413 /* we will walk the body in a pre-order traversal for
1415 switch (pbody->opval.op)
1417 /*------------------------------------------------------------------*/
1419 return isConformingBody (pbody->right, sym, body);
1421 /*------------------------------------------------------------------*/
1426 /*------------------------------------------------------------------*/
1427 case INC_OP: /* incerement operator unary so left only */
1430 /* sure we are not sym is not modified */
1432 IS_AST_SYM_VALUE (pbody->left) &&
1433 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1437 IS_AST_SYM_VALUE (pbody->right) &&
1438 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1443 /*------------------------------------------------------------------*/
1445 case '*': /* can be unary : if right is null then unary operation */
1450 /* if right is NULL then unary operation */
1451 /*------------------------------------------------------------------*/
1452 /*----------------------------*/
1454 /*----------------------------*/
1457 if (IS_AST_SYM_VALUE (pbody->left) &&
1458 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1461 return isConformingBody (pbody->left, sym, body);
1465 if (astHasSymbol (pbody->left, sym) ||
1466 astHasSymbol (pbody->right, sym))
1471 /*------------------------------------------------------------------*/
1479 if (IS_AST_SYM_VALUE (pbody->left) &&
1480 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1483 if (IS_AST_SYM_VALUE (pbody->right) &&
1484 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1487 return isConformingBody (pbody->left, sym, body) &&
1488 isConformingBody (pbody->right, sym, body);
1495 if (IS_AST_SYM_VALUE (pbody->left) &&
1496 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1498 return isConformingBody (pbody->left, sym, body);
1500 /*------------------------------------------------------------------*/
1512 case SIZEOF: /* evaluate wihout code generation */
1514 return isConformingBody (pbody->left, sym, body) &&
1515 isConformingBody (pbody->right, sym, body);
1517 /*------------------------------------------------------------------*/
1520 /* if left has a pointer & right has loop
1521 control variable then we cannot */
1522 if (astHasPointer (pbody->left) &&
1523 astHasSymbol (pbody->right, sym))
1525 if (astHasVolatile (pbody->left))
1528 if (IS_AST_SYM_VALUE (pbody->left) &&
1529 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1532 if (astHasVolatile (pbody->left))
1535 return isConformingBody (pbody->left, sym, body) &&
1536 isConformingBody (pbody->right, sym, body);
1547 assert ("Parser should not have generated this\n");
1549 /*------------------------------------------------------------------*/
1550 /*----------------------------*/
1551 /* comma operator */
1552 /*----------------------------*/
1554 return isConformingBody (pbody->left, sym, body) &&
1555 isConformingBody (pbody->right, sym, body);
1557 /*------------------------------------------------------------------*/
1558 /*----------------------------*/
1560 /*----------------------------*/
1564 /*------------------------------------------------------------------*/
1565 /*----------------------------*/
1566 /* return statement */
1567 /*----------------------------*/
1572 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1577 if (astHasSymbol (pbody->left, sym))
1584 return isConformingBody (pbody->left, sym, body) &&
1585 isConformingBody (pbody->right, sym, body);
1591 /*-----------------------------------------------------------------*/
1592 /* isLoopReversible - takes a for loop as input && returns true */
1593 /* if the for loop is reversible. If yes will set the value of */
1594 /* the loop control var & init value & termination value */
1595 /*-----------------------------------------------------------------*/
1597 isLoopReversible (ast * loop, symbol ** loopCntrl,
1598 ast ** init, ast ** end)
1600 /* if option says don't do it then don't */
1601 if (optimize.noLoopReverse)
1603 /* there are several tests to determine this */
1605 /* for loop has to be of the form
1606 for ( <sym> = <const1> ;
1607 [<sym> < <const2>] ;
1608 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1610 if (!isLoopCountable (AST_FOR (loop, initExpr),
1611 AST_FOR (loop, condExpr),
1612 AST_FOR (loop, loopExpr),
1613 loopCntrl, init, end))
1616 /* now do some serious checking on the body of the loop
1619 return isConformingBody (loop->left, *loopCntrl, loop->left);
1623 /*-----------------------------------------------------------------*/
1624 /* replLoopSym - replace the loop sym by loop sym -1 */
1625 /*-----------------------------------------------------------------*/
1627 replLoopSym (ast * body, symbol * sym)
1630 if (!body || IS_AST_LINK (body))
1633 if (IS_AST_SYM_VALUE (body))
1636 if (isSymbolEqual (AST_SYMBOL (body), sym))
1640 body->opval.op = '-';
1641 body->left = newAst_VALUE (symbolVal (sym));
1642 body->right = newAst_VALUE (constVal ("1"));
1650 replLoopSym (body->left, sym);
1651 replLoopSym (body->right, sym);
1655 /*-----------------------------------------------------------------*/
1656 /* reverseLoop - do the actual loop reversal */
1657 /*-----------------------------------------------------------------*/
1659 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1663 /* create the following tree
1668 if (sym) goto for_continue ;
1671 /* put it together piece by piece */
1672 rloop = newNode (NULLOP,
1673 createIf (newAst_VALUE (symbolVal (sym)),
1675 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1678 newAst_VALUE (symbolVal (sym)),
1681 replLoopSym (loop->left, sym);
1683 rloop = newNode (NULLOP,
1685 newAst_VALUE (symbolVal (sym)),
1686 newNode ('-', end, init)),
1687 createLabel (AST_FOR (loop, continueLabel),
1691 newNode (SUB_ASSIGN,
1692 newAst_VALUE (symbolVal (sym)),
1693 newAst_VALUE (constVal ("1"))),
1696 return decorateType (rloop);
1700 #define DEMAND_INTEGER_PROMOTION
1702 #ifdef DEMAND_INTEGER_PROMOTION
1704 /*-----------------------------------------------------------------*/
1705 /* walk a tree looking for the leaves. Add a typecast to the given */
1706 /* type to each value leaf node. */
1707 /*-----------------------------------------------------------------*/
1709 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1711 if (!node || IS_CALLOP(node))
1713 /* WTF? We should never get here. */
1717 if (!node->left && !node->right)
1719 /* We're at a leaf; if it's a value, apply the typecast */
1720 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1722 *parentPtr = decorateType (newNode (CAST,
1723 newAst_LINK (copyLinkChain (type)),
1731 pushTypeCastToLeaves (type, node->left, &(node->left));
1735 pushTypeCastToLeaves (type, node->right, &(node->right));
1742 /*-----------------------------------------------------------------*/
1743 /* Given an assignment operation in a tree, determine if the LHS */
1744 /* (the result) has a different (integer) type than the RHS. */
1745 /* If so, walk the RHS and add a typecast to the type of the LHS */
1746 /* to all leaf nodes. */
1747 /*-----------------------------------------------------------------*/
1749 propAsgType (ast * tree)
1751 #ifdef DEMAND_INTEGER_PROMOTION
1752 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1754 /* Nothing to do here... */
1758 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1760 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1767 /*-----------------------------------------------------------------*/
1768 /* decorateType - compute type for this tree also does type cheking */
1769 /* this is done bottom up, since type have to flow upwards */
1770 /* it also does constant folding, and paramater checking */
1771 /*-----------------------------------------------------------------*/
1773 decorateType (ast * tree)
1781 /* if already has type then do nothing */
1782 if (tree->decorated)
1785 tree->decorated = 1;
1787 /* print the line */
1788 /* if not block & function */
1789 if (tree->type == EX_OP &&
1790 (tree->opval.op != FUNCTION &&
1791 tree->opval.op != BLOCK &&
1792 tree->opval.op != NULLOP))
1794 filename = tree->filename;
1795 lineno = tree->lineno;
1798 /* if any child is an error | this one is an error do nothing */
1799 if (tree->isError ||
1800 (tree->left && tree->left->isError) ||
1801 (tree->right && tree->right->isError))
1804 /*------------------------------------------------------------------*/
1805 /*----------------------------*/
1806 /* leaf has been reached */
1807 /*----------------------------*/
1808 /* if this is of type value */
1809 /* just get the type */
1810 if (tree->type == EX_VALUE)
1813 if (IS_LITERAL (tree->opval.val->etype))
1816 /* if this is a character array then declare it */
1817 if (IS_ARRAY (tree->opval.val->type))
1818 tree->opval.val = stringToSymbol (tree->opval.val);
1820 /* otherwise just copy the type information */
1821 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1822 if (funcInChain (tree->opval.val->type))
1824 tree->hasVargs = tree->opval.val->sym->hasVargs;
1825 tree->args = copyValueChain (tree->opval.val->sym->args);
1830 if (tree->opval.val->sym)
1832 /* if the undefined flag is set then give error message */
1833 if (tree->opval.val->sym->undefined)
1835 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1837 TTYPE (tree) = TETYPE (tree) =
1838 tree->opval.val->type = tree->opval.val->sym->type =
1839 tree->opval.val->etype = tree->opval.val->sym->etype =
1840 copyLinkChain (INTTYPE);
1845 /* if impilicit i.e. struct/union member then no type */
1846 if (tree->opval.val->sym->implicit)
1847 TTYPE (tree) = TETYPE (tree) = NULL;
1852 /* else copy the type */
1853 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1855 /* and mark it as referenced */
1856 tree->opval.val->sym->isref = 1;
1857 /* if this is of type function or function pointer */
1858 if (funcInChain (tree->opval.val->type))
1860 tree->hasVargs = tree->opval.val->sym->hasVargs;
1861 tree->args = copyValueChain (tree->opval.val->sym->args);
1871 /* if type link for the case of cast */
1872 if (tree->type == EX_LINK)
1874 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1881 dtl = decorateType (tree->left);
1882 dtr = decorateType (tree->right);
1884 /* this is to take care of situations
1885 when the tree gets rewritten */
1886 if (dtl != tree->left)
1888 if (dtr != tree->right)
1892 /* depending on type of operator do */
1894 switch (tree->opval.op)
1896 /*------------------------------------------------------------------*/
1897 /*----------------------------*/
1899 /*----------------------------*/
1902 /* determine which is the array & which the index */
1903 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1906 ast *tempTree = tree->left;
1907 tree->left = tree->right;
1908 tree->right = tempTree;
1911 /* first check if this is a array or a pointer */
1912 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1914 werror (E_NEED_ARRAY_PTR, "[]");
1915 goto errorTreeReturn;
1918 /* check if the type of the idx */
1919 if (!IS_INTEGRAL (RTYPE (tree)))
1921 werror (E_IDX_NOT_INT);
1922 goto errorTreeReturn;
1925 /* if the left is an rvalue then error */
1928 werror (E_LVALUE_REQUIRED, "array access");
1929 goto errorTreeReturn;
1932 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1933 if (IS_PTR(LTYPE(tree))) {
1934 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1938 /*------------------------------------------------------------------*/
1939 /*----------------------------*/
1941 /*----------------------------*/
1943 /* if this is not a structure */
1944 if (!IS_STRUCT (LTYPE (tree)))
1946 werror (E_STRUCT_UNION, ".");
1947 goto errorTreeReturn;
1949 TTYPE (tree) = structElemType (LTYPE (tree),
1950 (tree->right->type == EX_VALUE ?
1951 tree->right->opval.val : NULL), &tree->args);
1952 TETYPE (tree) = getSpec (TTYPE (tree));
1955 /*------------------------------------------------------------------*/
1956 /*----------------------------*/
1957 /* struct/union pointer */
1958 /*----------------------------*/
1960 /* if not pointer to a structure */
1961 if (!IS_PTR (LTYPE (tree)))
1963 werror (E_PTR_REQD);
1964 goto errorTreeReturn;
1967 if (!IS_STRUCT (LTYPE (tree)->next))
1969 werror (E_STRUCT_UNION, "->");
1970 goto errorTreeReturn;
1973 TTYPE (tree) = structElemType (LTYPE (tree)->next,
1974 (tree->right->type == EX_VALUE ?
1975 tree->right->opval.val : NULL), &tree->args);
1976 TETYPE (tree) = getSpec (TTYPE (tree));
1979 /*------------------------------------------------------------------*/
1980 /*----------------------------*/
1981 /* ++/-- operation */
1982 /*----------------------------*/
1983 case INC_OP: /* incerement operator unary so left only */
1986 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
1987 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
1988 if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
1989 werror (E_CODE_WRITE, "++/--");
1998 /*------------------------------------------------------------------*/
1999 /*----------------------------*/
2001 /*----------------------------*/
2002 case '&': /* can be unary */
2003 /* if right is NULL then unary operation */
2004 if (tree->right) /* not an unary operation */
2007 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2009 werror (E_BITWISE_OP);
2010 werror (E_CONTINUE, "left & right types are ");
2011 printTypeChain (LTYPE (tree), stderr);
2012 fprintf (stderr, ",");
2013 printTypeChain (RTYPE (tree), stderr);
2014 fprintf (stderr, "\n");
2015 goto errorTreeReturn;
2018 /* if they are both literal */
2019 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2021 tree->type = EX_VALUE;
2022 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2023 valFromType (RETYPE (tree)), '&');
2025 tree->right = tree->left = NULL;
2026 TETYPE (tree) = tree->opval.val->etype;
2027 TTYPE (tree) = tree->opval.val->type;
2031 /* see if this is a GETHBIT operation if yes
2034 ast *otree = optimizeGetHbit (tree);
2037 return decorateType (otree);
2040 /* if right or left is literal then result of that type */
2041 if (IS_LITERAL (RTYPE (tree)))
2044 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2045 TETYPE (tree) = getSpec (TTYPE (tree));
2046 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2050 if (IS_LITERAL (LTYPE (tree)))
2052 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2053 TETYPE (tree) = getSpec (TTYPE (tree));
2054 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2060 computeType (LTYPE (tree), RTYPE (tree));
2061 TETYPE (tree) = getSpec (TTYPE (tree));
2064 LRVAL (tree) = RRVAL (tree) = 1;
2068 /*------------------------------------------------------------------*/
2069 /*----------------------------*/
2071 /*----------------------------*/
2073 p->class = DECLARATOR;
2074 /* if bit field then error */
2075 if (IS_BITVAR (tree->left->etype))
2077 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2078 goto errorTreeReturn;
2081 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2083 werror (E_ILLEGAL_ADDR, "address of register variable");
2084 goto errorTreeReturn;
2087 if (IS_FUNC (LTYPE (tree)))
2089 werror (E_ILLEGAL_ADDR, "address of function");
2090 goto errorTreeReturn;
2095 werror (E_LVALUE_REQUIRED, "address of");
2096 goto errorTreeReturn;
2098 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2100 DCL_TYPE (p) = CPOINTER;
2101 DCL_PTR_CONST (p) = port->mem.code_ro;
2103 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2104 DCL_TYPE (p) = FPOINTER;
2105 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2106 DCL_TYPE (p) = PPOINTER;
2107 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2108 DCL_TYPE (p) = IPOINTER;
2109 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2110 DCL_TYPE (p) = EEPPOINTER;
2112 DCL_TYPE (p) = POINTER;
2114 if (IS_AST_SYM_VALUE (tree->left))
2116 AST_SYMBOL (tree->left)->addrtaken = 1;
2117 AST_SYMBOL (tree->left)->allocreq = 1;
2120 p->next = LTYPE (tree);
2122 TETYPE (tree) = getSpec (TTYPE (tree));
2123 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2124 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2129 /*------------------------------------------------------------------*/
2130 /*----------------------------*/
2132 /*----------------------------*/
2134 /* if the rewrite succeeds then don't go any furthur */
2136 ast *wtree = optimizeRRCRLC (tree);
2138 return decorateType (wtree);
2140 /*------------------------------------------------------------------*/
2141 /*----------------------------*/
2143 /*----------------------------*/
2145 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2147 werror (E_BITWISE_OP);
2148 werror (E_CONTINUE, "left & right types are ");
2149 printTypeChain (LTYPE (tree), stderr);
2150 fprintf (stderr, ",");
2151 printTypeChain (RTYPE (tree), stderr);
2152 fprintf (stderr, "\n");
2153 goto errorTreeReturn;
2156 /* if they are both literal then */
2157 /* rewrite the tree */
2158 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2160 tree->type = EX_VALUE;
2161 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2162 valFromType (RETYPE (tree)),
2164 tree->right = tree->left = NULL;
2165 TETYPE (tree) = tree->opval.val->etype;
2166 TTYPE (tree) = tree->opval.val->type;
2169 LRVAL (tree) = RRVAL (tree) = 1;
2170 TETYPE (tree) = getSpec (TTYPE (tree) =
2171 computeType (LTYPE (tree),
2174 /*------------------------------------------------------------------*/
2175 /*----------------------------*/
2177 /*----------------------------*/
2179 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2181 werror (E_INVALID_OP, "divide");
2182 goto errorTreeReturn;
2184 /* if they are both literal then */
2185 /* rewrite the tree */
2186 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2188 tree->type = EX_VALUE;
2189 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2190 valFromType (RETYPE (tree)));
2191 tree->right = tree->left = NULL;
2192 TETYPE (tree) = getSpec (TTYPE (tree) =
2193 tree->opval.val->type);
2196 LRVAL (tree) = RRVAL (tree) = 1;
2197 TETYPE (tree) = getSpec (TTYPE (tree) =
2198 computeType (LTYPE (tree),
2202 /*------------------------------------------------------------------*/
2203 /*----------------------------*/
2205 /*----------------------------*/
2207 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2209 werror (E_BITWISE_OP);
2210 werror (E_CONTINUE, "left & right types are ");
2211 printTypeChain (LTYPE (tree), stderr);
2212 fprintf (stderr, ",");
2213 printTypeChain (RTYPE (tree), stderr);
2214 fprintf (stderr, "\n");
2215 goto errorTreeReturn;
2217 /* if they are both literal then */
2218 /* rewrite the tree */
2219 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2221 tree->type = EX_VALUE;
2222 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2223 valFromType (RETYPE (tree)));
2224 tree->right = tree->left = NULL;
2225 TETYPE (tree) = getSpec (TTYPE (tree) =
2226 tree->opval.val->type);
2229 LRVAL (tree) = RRVAL (tree) = 1;
2230 TETYPE (tree) = getSpec (TTYPE (tree) =
2231 computeType (LTYPE (tree),
2235 /*------------------------------------------------------------------*/
2236 /*----------------------------*/
2237 /* address dereference */
2238 /*----------------------------*/
2239 case '*': /* can be unary : if right is null then unary operation */
2242 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2244 werror (E_PTR_REQD);
2245 goto errorTreeReturn;
2250 werror (E_LVALUE_REQUIRED, "pointer deref");
2251 goto errorTreeReturn;
2253 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2254 LTYPE (tree)->next : NULL);
2255 TETYPE (tree) = getSpec (TTYPE (tree));
2256 tree->args = tree->left->args;
2257 tree->hasVargs = tree->left->hasVargs;
2258 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2262 /*------------------------------------------------------------------*/
2263 /*----------------------------*/
2264 /* multiplication */
2265 /*----------------------------*/
2266 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2268 werror (E_INVALID_OP, "multiplication");
2269 goto errorTreeReturn;
2272 /* if they are both literal then */
2273 /* rewrite the tree */
2274 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2276 tree->type = EX_VALUE;
2277 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2278 valFromType (RETYPE (tree)));
2279 tree->right = tree->left = NULL;
2280 TETYPE (tree) = getSpec (TTYPE (tree) =
2281 tree->opval.val->type);
2285 /* if left is a literal exchange left & right */
2286 if (IS_LITERAL (LTYPE (tree)))
2288 ast *tTree = tree->left;
2289 tree->left = tree->right;
2290 tree->right = tTree;
2293 LRVAL (tree) = RRVAL (tree) = 1;
2294 /* promote result to int if left & right are char / short
2295 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2296 if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) &&
2297 (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) {
2298 TETYPE (tree) = getSpec (TTYPE (tree) =
2299 computeType (LTYPE (tree),
2301 SPEC_NOUN(TETYPE(tree)) = V_INT;
2302 SPEC_SHORT(TETYPE(tree))=0;
2304 TETYPE (tree) = getSpec (TTYPE (tree) =
2305 computeType (LTYPE (tree),
2310 /*------------------------------------------------------------------*/
2311 /*----------------------------*/
2312 /* unary '+' operator */
2313 /*----------------------------*/
2318 if (!IS_INTEGRAL (LTYPE (tree)))
2320 werror (E_UNARY_OP, '+');
2321 goto errorTreeReturn;
2324 /* if left is a literal then do it */
2325 if (IS_LITERAL (LTYPE (tree)))
2327 tree->type = EX_VALUE;
2328 tree->opval.val = valFromType (LETYPE (tree));
2330 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2334 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2338 /*------------------------------------------------------------------*/
2339 /*----------------------------*/
2341 /*----------------------------*/
2343 /* this is not a unary operation */
2344 /* if both pointers then problem */
2345 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2346 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2348 werror (E_PTR_PLUS_PTR);
2349 goto errorTreeReturn;
2352 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2353 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2355 werror (E_PLUS_INVALID, "+");
2356 goto errorTreeReturn;
2359 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2360 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2362 werror (E_PLUS_INVALID, "+");
2363 goto errorTreeReturn;
2365 /* if they are both literal then */
2366 /* rewrite the tree */
2367 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2369 tree->type = EX_VALUE;
2370 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2371 valFromType (RETYPE (tree)));
2372 tree->right = tree->left = NULL;
2373 TETYPE (tree) = getSpec (TTYPE (tree) =
2374 tree->opval.val->type);
2378 /* if the right is a pointer or left is a literal
2379 xchange left & right */
2380 if (IS_ARRAY (RTYPE (tree)) ||
2381 IS_PTR (RTYPE (tree)) ||
2382 IS_LITERAL (LTYPE (tree)))
2384 ast *tTree = tree->left;
2385 tree->left = tree->right;
2386 tree->right = tTree;
2389 LRVAL (tree) = RRVAL (tree) = 1;
2390 /* if the left is a pointer */
2391 if (IS_PTR (LTYPE (tree)))
2392 TETYPE (tree) = getSpec (TTYPE (tree) =
2395 TETYPE (tree) = getSpec (TTYPE (tree) =
2396 computeType (LTYPE (tree),
2400 /*------------------------------------------------------------------*/
2401 /*----------------------------*/
2403 /*----------------------------*/
2404 case '-': /* can be unary */
2405 /* if right is null then unary */
2409 if (!IS_ARITHMETIC (LTYPE (tree)))
2411 werror (E_UNARY_OP, tree->opval.op);
2412 goto errorTreeReturn;
2415 /* if left is a literal then do it */
2416 if (IS_LITERAL (LTYPE (tree)))
2418 tree->type = EX_VALUE;
2419 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2421 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2422 SPEC_USIGN(TETYPE(tree)) = 0;
2426 TTYPE (tree) = LTYPE (tree);
2430 /*------------------------------------------------------------------*/
2431 /*----------------------------*/
2433 /*----------------------------*/
2435 if (!(IS_PTR (LTYPE (tree)) ||
2436 IS_ARRAY (LTYPE (tree)) ||
2437 IS_ARITHMETIC (LTYPE (tree))))
2439 werror (E_PLUS_INVALID, "-");
2440 goto errorTreeReturn;
2443 if (!(IS_PTR (RTYPE (tree)) ||
2444 IS_ARRAY (RTYPE (tree)) ||
2445 IS_ARITHMETIC (RTYPE (tree))))
2447 werror (E_PLUS_INVALID, "-");
2448 goto errorTreeReturn;
2451 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2452 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2453 IS_INTEGRAL (RTYPE (tree))))
2455 werror (E_PLUS_INVALID, "-");
2456 goto errorTreeReturn;
2459 /* if they are both literal then */
2460 /* rewrite the tree */
2461 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2463 tree->type = EX_VALUE;
2464 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2465 valFromType (RETYPE (tree)));
2466 tree->right = tree->left = NULL;
2467 TETYPE (tree) = getSpec (TTYPE (tree) =
2468 tree->opval.val->type);
2472 /* if the left & right are equal then zero */
2473 if (isAstEqual (tree->left, tree->right))
2475 tree->type = EX_VALUE;
2476 tree->left = tree->right = NULL;
2477 tree->opval.val = constVal ("0");
2478 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2482 /* if both of them are pointers or arrays then */
2483 /* the result is going to be an integer */
2484 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2485 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2486 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2488 /* if only the left is a pointer */
2489 /* then result is a pointer */
2490 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2491 TETYPE (tree) = getSpec (TTYPE (tree) =
2494 TETYPE (tree) = getSpec (TTYPE (tree) =
2495 computeType (LTYPE (tree),
2497 LRVAL (tree) = RRVAL (tree) = 1;
2500 /*------------------------------------------------------------------*/
2501 /*----------------------------*/
2503 /*----------------------------*/
2505 /* can be only integral type */
2506 if (!IS_INTEGRAL (LTYPE (tree)))
2508 werror (E_UNARY_OP, tree->opval.op);
2509 goto errorTreeReturn;
2512 /* if left is a literal then do it */
2513 if (IS_LITERAL (LTYPE (tree)))
2515 tree->type = EX_VALUE;
2516 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2518 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2522 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2525 /*------------------------------------------------------------------*/
2526 /*----------------------------*/
2528 /*----------------------------*/
2530 /* can be pointer */
2531 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2532 !IS_PTR (LTYPE (tree)) &&
2533 !IS_ARRAY (LTYPE (tree)))
2535 werror (E_UNARY_OP, tree->opval.op);
2536 goto errorTreeReturn;
2539 /* if left is a literal then do it */
2540 if (IS_LITERAL (LTYPE (tree)))
2542 tree->type = EX_VALUE;
2543 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2545 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2549 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2552 /*------------------------------------------------------------------*/
2553 /*----------------------------*/
2555 /*----------------------------*/
2558 TTYPE (tree) = LTYPE (tree);
2559 TETYPE (tree) = LETYPE (tree);
2563 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2568 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2570 werror (E_SHIFT_OP_INVALID);
2571 werror (E_CONTINUE, "left & right types are ");
2572 printTypeChain (LTYPE (tree), stderr);
2573 fprintf (stderr, ",");
2574 printTypeChain (RTYPE (tree), stderr);
2575 fprintf (stderr, "\n");
2576 goto errorTreeReturn;
2579 /* if they are both literal then */
2580 /* rewrite the tree */
2581 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2583 tree->type = EX_VALUE;
2584 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2585 valFromType (RETYPE (tree)),
2586 (tree->opval.op == LEFT_OP ? 1 : 0));
2587 tree->right = tree->left = NULL;
2588 TETYPE (tree) = getSpec (TTYPE (tree) =
2589 tree->opval.val->type);
2592 /* if only the right side is a literal & we are
2593 shifting more than size of the left operand then zero */
2594 if (IS_LITERAL (RTYPE (tree)) &&
2595 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2596 (getSize (LTYPE (tree)) * 8))
2598 werror (W_SHIFT_CHANGED,
2599 (tree->opval.op == LEFT_OP ? "left" : "right"));
2600 tree->type = EX_VALUE;
2601 tree->left = tree->right = NULL;
2602 tree->opval.val = constVal ("0");
2603 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2606 LRVAL (tree) = RRVAL (tree) = 1;
2607 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2609 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2613 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2617 /*------------------------------------------------------------------*/
2618 /*----------------------------*/
2620 /*----------------------------*/
2621 case CAST: /* change the type */
2622 /* cannot cast to an aggregate type */
2623 if (IS_AGGREGATE (LTYPE (tree)))
2625 werror (E_CAST_ILLEGAL);
2626 goto errorTreeReturn;
2629 /* if the right is a literal replace the tree */
2630 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree)))
2632 tree->type = EX_VALUE;
2634 valCastLiteral (LTYPE (tree),
2635 floatFromVal (valFromType (RETYPE (tree))));
2638 TTYPE (tree) = tree->opval.val->type;
2639 tree->values.literalFromCast = 1;
2643 TTYPE (tree) = LTYPE (tree);
2647 TETYPE (tree) = getSpec (TTYPE (tree));
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2653 /* logical &&, || */
2654 /*----------------------------*/
2657 /* each must me arithmetic type or be a pointer */
2658 if (!IS_PTR (LTYPE (tree)) &&
2659 !IS_ARRAY (LTYPE (tree)) &&
2660 !IS_INTEGRAL (LTYPE (tree)))
2662 werror (E_COMPARE_OP);
2663 goto errorTreeReturn;
2666 if (!IS_PTR (RTYPE (tree)) &&
2667 !IS_ARRAY (RTYPE (tree)) &&
2668 !IS_INTEGRAL (RTYPE (tree)))
2670 werror (E_COMPARE_OP);
2671 goto errorTreeReturn;
2673 /* if they are both literal then */
2674 /* rewrite the tree */
2675 if (IS_LITERAL (RTYPE (tree)) &&
2676 IS_LITERAL (LTYPE (tree)))
2678 tree->type = EX_VALUE;
2679 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2680 valFromType (RETYPE (tree)),
2682 tree->right = tree->left = NULL;
2683 TETYPE (tree) = getSpec (TTYPE (tree) =
2684 tree->opval.val->type);
2687 LRVAL (tree) = RRVAL (tree) = 1;
2688 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2691 /*------------------------------------------------------------------*/
2692 /*----------------------------*/
2693 /* comparison operators */
2694 /*----------------------------*/
2702 ast *lt = optimizeCompare (tree);
2708 /* if they are pointers they must be castable */
2709 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2711 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2713 werror (E_COMPARE_OP);
2714 fprintf (stderr, "comparing type ");
2715 printTypeChain (LTYPE (tree), stderr);
2716 fprintf (stderr, "to type ");
2717 printTypeChain (RTYPE (tree), stderr);
2718 fprintf (stderr, "\n");
2719 goto errorTreeReturn;
2722 /* else they should be promotable to one another */
2725 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2726 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2728 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2730 werror (E_COMPARE_OP);
2731 fprintf (stderr, "comparing type ");
2732 printTypeChain (LTYPE (tree), stderr);
2733 fprintf (stderr, "to type ");
2734 printTypeChain (RTYPE (tree), stderr);
2735 fprintf (stderr, "\n");
2736 goto errorTreeReturn;
2740 /* if they are both literal then */
2741 /* rewrite the tree */
2742 if (IS_LITERAL (RTYPE (tree)) &&
2743 IS_LITERAL (LTYPE (tree)))
2745 tree->type = EX_VALUE;
2746 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2747 valFromType (RETYPE (tree)),
2749 tree->right = tree->left = NULL;
2750 TETYPE (tree) = getSpec (TTYPE (tree) =
2751 tree->opval.val->type);
2754 LRVAL (tree) = RRVAL (tree) = 1;
2755 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2758 /*------------------------------------------------------------------*/
2759 /*----------------------------*/
2761 /*----------------------------*/
2762 case SIZEOF: /* evaluate wihout code generation */
2763 /* change the type to a integer */
2764 tree->type = EX_VALUE;
2765 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2766 tree->opval.val = constVal (buffer);
2767 tree->right = tree->left = NULL;
2768 TETYPE (tree) = getSpec (TTYPE (tree) =
2769 tree->opval.val->type);
2772 /*------------------------------------------------------------------*/
2773 /*----------------------------*/
2774 /* conditional operator '?' */
2775 /*----------------------------*/
2777 /* the type is one on the left */
2778 TTYPE (tree) = LTYPE (tree);
2779 TETYPE (tree) = getSpec (TTYPE (tree));
2783 /* if they don't match we have a problem */
2784 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2786 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2787 goto errorTreeReturn;
2790 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2791 TETYPE (tree) = getSpec (TTYPE (tree));
2795 /*------------------------------------------------------------------*/
2796 /*----------------------------*/
2797 /* assignment operators */
2798 /*----------------------------*/
2801 /* for these it must be both must be integral */
2802 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2803 !IS_ARITHMETIC (RTYPE (tree)))
2805 werror (E_OPS_INTEGRAL);
2806 goto errorTreeReturn;
2809 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2811 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2812 werror (E_CODE_WRITE, " ");
2816 werror (E_LVALUE_REQUIRED, "*= or /=");
2817 goto errorTreeReturn;
2830 /* for these it must be both must be integral */
2831 if (!IS_INTEGRAL (LTYPE (tree)) ||
2832 !IS_INTEGRAL (RTYPE (tree)))
2834 werror (E_OPS_INTEGRAL);
2835 goto errorTreeReturn;
2838 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2840 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2841 werror (E_CODE_WRITE, " ");
2845 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2846 goto errorTreeReturn;
2854 /*------------------------------------------------------------------*/
2855 /*----------------------------*/
2857 /*----------------------------*/
2859 if (!(IS_PTR (LTYPE (tree)) ||
2860 IS_ARITHMETIC (LTYPE (tree))))
2862 werror (E_PLUS_INVALID, "-=");
2863 goto errorTreeReturn;
2866 if (!(IS_PTR (RTYPE (tree)) ||
2867 IS_ARITHMETIC (RTYPE (tree))))
2869 werror (E_PLUS_INVALID, "-=");
2870 goto errorTreeReturn;
2873 TETYPE (tree) = getSpec (TTYPE (tree) =
2874 computeType (LTYPE (tree),
2877 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2878 werror (E_CODE_WRITE, " ");
2882 werror (E_LVALUE_REQUIRED, "-=");
2883 goto errorTreeReturn;
2891 /*------------------------------------------------------------------*/
2892 /*----------------------------*/
2894 /*----------------------------*/
2896 /* this is not a unary operation */
2897 /* if both pointers then problem */
2898 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2900 werror (E_PTR_PLUS_PTR);
2901 goto errorTreeReturn;
2904 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2906 werror (E_PLUS_INVALID, "+=");
2907 goto errorTreeReturn;
2910 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2912 werror (E_PLUS_INVALID, "+=");
2913 goto errorTreeReturn;
2916 TETYPE (tree) = getSpec (TTYPE (tree) =
2917 computeType (LTYPE (tree),
2920 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2921 werror (E_CODE_WRITE, " ");
2925 werror (E_LVALUE_REQUIRED, "+=");
2926 goto errorTreeReturn;
2929 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
2930 tree->opval.op = '=';
2936 /*------------------------------------------------------------------*/
2937 /*----------------------------*/
2938 /* straight assignemnt */
2939 /*----------------------------*/
2941 /* cannot be an aggregate */
2942 if (IS_AGGREGATE (LTYPE (tree)))
2944 werror (E_AGGR_ASSIGN);
2945 goto errorTreeReturn;
2948 /* they should either match or be castable */
2949 if (checkType (LTYPE (tree), RTYPE (tree)) == 0)
2951 werror (E_TYPE_MISMATCH, "assignment", " ");
2952 fprintf (stderr, "type --> '");
2953 printTypeChain (RTYPE (tree), stderr);
2954 fprintf (stderr, "' ");
2955 fprintf (stderr, "assigned to type --> '");
2956 printTypeChain (LTYPE (tree), stderr);
2957 fprintf (stderr, "'\n");
2958 goto errorTreeReturn;
2961 /* if the left side of the tree is of type void
2962 then report error */
2963 if (IS_VOID (LTYPE (tree)))
2965 werror (E_CAST_ZERO);
2966 fprintf (stderr, "type --> '");
2967 printTypeChain (RTYPE (tree), stderr);
2968 fprintf (stderr, "' ");
2969 fprintf (stderr, "assigned to type --> '");
2970 printTypeChain (LTYPE (tree), stderr);
2971 fprintf (stderr, "'\n");
2974 /* extra checks for pointer types */
2975 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
2976 !IS_GENPTR (LTYPE (tree)))
2978 if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
2979 werror (W_PTR_ASSIGN);
2982 TETYPE (tree) = getSpec (TTYPE (tree) =
2986 if (!tree->initMode ) {
2987 if (IS_CONSTANT (LETYPE (tree))) {
2988 werror (E_CODE_WRITE, " ");
2993 werror (E_LVALUE_REQUIRED, "=");
2994 goto errorTreeReturn;
3001 /*------------------------------------------------------------------*/
3002 /*----------------------------*/
3003 /* comma operator */
3004 /*----------------------------*/
3006 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3009 /*------------------------------------------------------------------*/
3010 /*----------------------------*/
3012 /*----------------------------*/
3016 if (processParms (tree->left,
3018 tree->right, &parmNumber, TRUE))
3019 goto errorTreeReturn;
3021 if (options.stackAuto || IS_RENT (LETYPE (tree)))
3023 tree->left->args = reverseVal (tree->left->args);
3024 reverseParms (tree->right);
3027 tree->args = tree->left->args;
3028 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3031 /*------------------------------------------------------------------*/
3032 /*----------------------------*/
3033 /* return statement */
3034 /*----------------------------*/
3039 if (checkType (currFunc->type->next, RTYPE (tree)) == 0)
3041 werror (E_RETURN_MISMATCH);
3042 goto errorTreeReturn;
3045 if (IS_VOID (currFunc->type->next)
3047 !IS_VOID (RTYPE (tree)))
3049 werror (E_FUNC_VOID);
3050 goto errorTreeReturn;
3053 /* if there is going to be a casing required then add it */
3054 if (checkType (currFunc->type->next, RTYPE (tree)) < 0)
3056 #if 0 && defined DEMAND_INTEGER_PROMOTION
3057 if (IS_INTEGRAL (currFunc->type->next))
3059 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3065 decorateType (newNode (CAST,
3066 newAst_LINK (copyLinkChain (currFunc->type->next)),
3076 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3078 werror (E_VOID_FUNC, currFunc->name);
3079 goto errorTreeReturn;
3082 TTYPE (tree) = TETYPE (tree) = NULL;
3085 /*------------------------------------------------------------------*/
3086 /*----------------------------*/
3087 /* switch statement */
3088 /*----------------------------*/
3090 /* the switch value must be an integer */
3091 if (!IS_INTEGRAL (LTYPE (tree)))
3093 werror (E_SWITCH_NON_INTEGER);
3094 goto errorTreeReturn;
3097 TTYPE (tree) = TETYPE (tree) = NULL;
3100 /*------------------------------------------------------------------*/
3101 /*----------------------------*/
3103 /*----------------------------*/
3105 tree->left = backPatchLabels (tree->left,
3108 TTYPE (tree) = TETYPE (tree) = NULL;
3111 /*------------------------------------------------------------------*/
3112 /*----------------------------*/
3114 /*----------------------------*/
3117 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3118 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3119 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3121 /* if the for loop is reversible then
3122 reverse it otherwise do what we normally
3128 if (isLoopReversible (tree, &sym, &init, &end))
3129 return reverseLoop (tree, sym, init, end);
3131 return decorateType (createFor (AST_FOR (tree, trueLabel),
3132 AST_FOR (tree, continueLabel),
3133 AST_FOR (tree, falseLabel),
3134 AST_FOR (tree, condLabel),
3135 AST_FOR (tree, initExpr),
3136 AST_FOR (tree, condExpr),
3137 AST_FOR (tree, loopExpr),
3141 TTYPE (tree) = TETYPE (tree) = NULL;
3145 /* some error found this tree will be killed */
3147 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3148 tree->opval.op = NULLOP;
3154 /*-----------------------------------------------------------------*/
3155 /* sizeofOp - processes size of operation */
3156 /*-----------------------------------------------------------------*/
3158 sizeofOp (sym_link * type)
3162 /* get the size and convert it to character */
3163 sprintf (buff, "%d", getSize (type));
3165 /* now convert into value */
3166 return constVal (buff);
3170 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3171 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3172 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3173 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3174 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3175 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3176 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3178 /*-----------------------------------------------------------------*/
3179 /* backPatchLabels - change and or not operators to flow control */
3180 /*-----------------------------------------------------------------*/
3182 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3188 if (!(IS_ANDORNOT (tree)))
3191 /* if this an and */
3194 static int localLbl = 0;
3197 sprintf (buffer, "_and_%d", localLbl++);
3198 localLabel = newSymbol (buffer, NestLevel);
3200 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3202 /* if left is already a IFX then just change the if true label in that */
3203 if (!IS_IFX (tree->left))
3204 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3206 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3207 /* right is a IFX then just join */
3208 if (IS_IFX (tree->right))
3209 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3211 tree->right = createLabel (localLabel, tree->right);
3212 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3214 return newNode (NULLOP, tree->left, tree->right);
3217 /* if this is an or operation */
3220 static int localLbl = 0;
3223 sprintf (buffer, "_or_%d", localLbl++);
3224 localLabel = newSymbol (buffer, NestLevel);
3226 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3228 /* if left is already a IFX then just change the if true label in that */
3229 if (!IS_IFX (tree->left))
3230 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3232 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3233 /* right is a IFX then just join */
3234 if (IS_IFX (tree->right))
3235 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3237 tree->right = createLabel (localLabel, tree->right);
3238 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3240 return newNode (NULLOP, tree->left, tree->right);
3246 int wasnot = IS_NOT (tree->left);
3247 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3249 /* if the left is already a IFX */
3250 if (!IS_IFX (tree->left))
3251 tree->left = newNode (IFX, tree->left, NULL);
3255 tree->left->trueLabel = trueLabel;
3256 tree->left->falseLabel = falseLabel;
3260 tree->left->trueLabel = falseLabel;
3261 tree->left->falseLabel = trueLabel;
3268 tree->trueLabel = trueLabel;
3269 tree->falseLabel = falseLabel;
3276 /*-----------------------------------------------------------------*/
3277 /* createBlock - create expression tree for block */
3278 /*-----------------------------------------------------------------*/
3280 createBlock (symbol * decl, ast * body)
3284 /* if the block has nothing */
3288 ex = newNode (BLOCK, NULL, body);
3289 ex->values.sym = decl;
3291 ex->right = ex->right;
3297 /*-----------------------------------------------------------------*/
3298 /* createLabel - creates the expression tree for labels */
3299 /*-----------------------------------------------------------------*/
3301 createLabel (symbol * label, ast * stmnt)
3304 char name[SDCC_NAME_MAX + 1];
3307 /* must create fresh symbol if the symbol name */
3308 /* exists in the symbol table, since there can */
3309 /* be a variable with the same name as the labl */
3310 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3311 (csym->level == label->level))
3312 label = newSymbol (label->name, label->level);
3314 /* change the name before putting it in add _ */
3315 sprintf (name, "%s", label->name);
3317 /* put the label in the LabelSymbol table */
3318 /* but first check if a label of the same */
3320 if ((csym = findSym (LabelTab, NULL, name)))
3321 werror (E_DUPLICATE_LABEL, label->name);
3323 addSym (LabelTab, label, name, label->level, 0);
3326 label->key = labelKey++;
3327 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3333 /*-----------------------------------------------------------------*/
3334 /* createCase - generates the parsetree for a case statement */
3335 /*-----------------------------------------------------------------*/
3337 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3339 char caseLbl[SDCC_NAME_MAX + 1];
3343 /* if the switch statement does not exist */
3344 /* then case is out of context */
3347 werror (E_CASE_CONTEXT);
3351 caseVal = decorateType (resolveSymbols (caseVal));
3352 /* if not a constant then error */
3353 if (!IS_LITERAL (caseVal->ftype))
3355 werror (E_CASE_CONSTANT);
3359 /* if not a integer than error */
3360 if (!IS_INTEGRAL (caseVal->ftype))
3362 werror (E_CASE_NON_INTEGER);
3366 /* find the end of the switch values chain */
3367 if (!(val = swStat->values.switchVals.swVals))
3368 swStat->values.switchVals.swVals = caseVal->opval.val;
3371 /* also order the cases according to value */
3373 int cVal = (int) floatFromVal (caseVal->opval.val);
3374 while (val && (int) floatFromVal (val) < cVal)
3380 /* if we reached the end then */
3383 pval->next = caseVal->opval.val;
3387 /* we found a value greater than */
3388 /* the current value we must add this */
3389 /* before the value */
3390 caseVal->opval.val->next = val;
3392 /* if this was the first in chain */
3393 if (swStat->values.switchVals.swVals == val)
3394 swStat->values.switchVals.swVals =
3397 pval->next = caseVal->opval.val;
3402 /* create the case label */
3403 sprintf (caseLbl, "_case_%d_%d",
3404 swStat->values.switchVals.swNum,
3405 (int) floatFromVal (caseVal->opval.val));
3407 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3412 /*-----------------------------------------------------------------*/
3413 /* createDefault - creates the parse tree for the default statement */
3414 /*-----------------------------------------------------------------*/
3416 createDefault (ast * swStat, ast * stmnt)
3418 char defLbl[SDCC_NAME_MAX + 1];
3420 /* if the switch statement does not exist */
3421 /* then case is out of context */
3424 werror (E_CASE_CONTEXT);
3428 /* turn on the default flag */
3429 swStat->values.switchVals.swDefault = 1;
3431 /* create the label */
3432 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3433 return createLabel (newSymbol (defLbl, 0), stmnt);
3436 /*-----------------------------------------------------------------*/
3437 /* createIf - creates the parsetree for the if statement */
3438 /*-----------------------------------------------------------------*/
3440 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3442 static int Lblnum = 0;
3444 symbol *ifTrue, *ifFalse, *ifEnd;
3446 /* if neither exists */
3447 if (!elseBody && !ifBody)
3450 /* create the labels */
3451 sprintf (buffer, "_iffalse_%d", Lblnum);
3452 ifFalse = newSymbol (buffer, NestLevel);
3453 /* if no else body then end == false */
3458 sprintf (buffer, "_ifend_%d", Lblnum);
3459 ifEnd = newSymbol (buffer, NestLevel);
3462 sprintf (buffer, "_iftrue_%d", Lblnum);
3463 ifTrue = newSymbol (buffer, NestLevel);
3467 /* attach the ifTrue label to the top of it body */
3468 ifBody = createLabel (ifTrue, ifBody);
3469 /* attach a goto end to the ifBody if else is present */
3472 ifBody = newNode (NULLOP, ifBody,
3474 newAst_VALUE (symbolVal (ifEnd)),
3476 /* put the elseLabel on the else body */
3477 elseBody = createLabel (ifFalse, elseBody);
3478 /* out the end at the end of the body */
3479 elseBody = newNode (NULLOP,
3481 createLabel (ifEnd, NULL));
3485 ifBody = newNode (NULLOP, ifBody,
3486 createLabel (ifFalse, NULL));
3488 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3489 if (IS_IFX (condAst))
3492 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3494 return newNode (NULLOP, ifTree,
3495 newNode (NULLOP, ifBody, elseBody));
3499 /*-----------------------------------------------------------------*/
3500 /* createDo - creates parse tree for do */
3503 /* _docontinue_n: */
3504 /* condition_expression +-> trueLabel -> _dobody_n */
3506 /* +-> falseLabel-> _dobreak_n */
3508 /*-----------------------------------------------------------------*/
3510 createDo (symbol * trueLabel, symbol * continueLabel,
3511 symbol * falseLabel, ast * condAst, ast * doBody)
3516 /* if the body does not exist then it is simple */
3519 condAst = backPatchLabels (condAst, continueLabel, NULL);
3520 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3521 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3522 doTree->trueLabel = continueLabel;
3523 doTree->falseLabel = NULL;
3527 /* otherwise we have a body */
3528 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3530 /* attach the body label to the top */
3531 doBody = createLabel (trueLabel, doBody);
3532 /* attach the continue label to end of body */
3533 doBody = newNode (NULLOP, doBody,
3534 createLabel (continueLabel, NULL));
3536 /* now put the break label at the end */
3537 if (IS_IFX (condAst))
3540 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3542 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3544 /* putting it together */
3545 return newNode (NULLOP, doBody, doTree);
3548 /*-----------------------------------------------------------------*/
3549 /* createFor - creates parse tree for 'for' statement */
3552 /* condExpr +-> trueLabel -> _forbody_n */
3554 /* +-> falseLabel-> _forbreak_n */
3557 /* _forcontinue_n: */
3559 /* goto _forcond_n ; */
3561 /*-----------------------------------------------------------------*/
3563 createFor (symbol * trueLabel, symbol * continueLabel,
3564 symbol * falseLabel, symbol * condLabel,
3565 ast * initExpr, ast * condExpr, ast * loopExpr,
3570 /* if loopexpression not present then we can generate it */
3571 /* the same way as a while */
3573 return newNode (NULLOP, initExpr,
3574 createWhile (trueLabel, continueLabel,
3575 falseLabel, condExpr, forBody));
3576 /* vanilla for statement */
3577 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3579 if (condExpr && !IS_IFX (condExpr))
3580 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3583 /* attach condition label to condition */
3584 condExpr = createLabel (condLabel, condExpr);
3586 /* attach body label to body */
3587 forBody = createLabel (trueLabel, forBody);
3589 /* attach continue to forLoop expression & attach */
3590 /* goto the forcond @ and of loopExpression */
3591 loopExpr = createLabel (continueLabel,
3595 newAst_VALUE (symbolVal (condLabel)),
3597 /* now start putting them together */
3598 forTree = newNode (NULLOP, initExpr, condExpr);
3599 forTree = newNode (NULLOP, forTree, forBody);
3600 forTree = newNode (NULLOP, forTree, loopExpr);
3601 /* finally add the break label */
3602 forTree = newNode (NULLOP, forTree,
3603 createLabel (falseLabel, NULL));
3607 /*-----------------------------------------------------------------*/
3608 /* createWhile - creates parse tree for while statement */
3609 /* the while statement will be created as follows */
3611 /* _while_continue_n: */
3612 /* condition_expression +-> trueLabel -> _while_boby_n */
3614 /* +-> falseLabel -> _while_break_n */
3615 /* _while_body_n: */
3617 /* goto _while_continue_n */
3618 /* _while_break_n: */
3619 /*-----------------------------------------------------------------*/
3621 createWhile (symbol * trueLabel, symbol * continueLabel,
3622 symbol * falseLabel, ast * condExpr, ast * whileBody)
3626 /* put the continue label */
3627 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3628 condExpr = createLabel (continueLabel, condExpr);
3629 condExpr->lineno = 0;
3631 /* put the body label in front of the body */
3632 whileBody = createLabel (trueLabel, whileBody);
3633 whileBody->lineno = 0;
3634 /* put a jump to continue at the end of the body */
3635 /* and put break label at the end of the body */
3636 whileBody = newNode (NULLOP,
3639 newAst_VALUE (symbolVal (continueLabel)),
3640 createLabel (falseLabel, NULL)));
3642 /* put it all together */
3643 if (IS_IFX (condExpr))
3644 whileTree = condExpr;
3647 whileTree = newNode (IFX, condExpr, NULL);
3648 /* put the true & false labels in place */
3649 whileTree->trueLabel = trueLabel;
3650 whileTree->falseLabel = falseLabel;
3653 return newNode (NULLOP, whileTree, whileBody);
3656 /*-----------------------------------------------------------------*/
3657 /* optimizeGetHbit - get highest order bit of the expression */
3658 /*-----------------------------------------------------------------*/
3660 optimizeGetHbit (ast * tree)
3663 /* if this is not a bit and */
3664 if (!IS_BITAND (tree))
3667 /* will look for tree of the form
3668 ( expr >> ((sizeof expr) -1) ) & 1 */
3669 if (!IS_AST_LIT_VALUE (tree->right))
3672 if (AST_LIT_VALUE (tree->right) != 1)
3675 if (!IS_RIGHT_OP (tree->left))
3678 if (!IS_AST_LIT_VALUE (tree->left->right))
3681 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3682 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3685 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3689 /*-----------------------------------------------------------------*/
3690 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3691 /*-----------------------------------------------------------------*/
3693 optimizeRRCRLC (ast * root)
3695 /* will look for trees of the form
3696 (?expr << 1) | (?expr >> 7) or
3697 (?expr >> 7) | (?expr << 1) will make that
3698 into a RLC : operation ..
3700 (?expr >> 1) | (?expr << 7) or
3701 (?expr << 7) | (?expr >> 1) will make that
3702 into a RRC operation
3703 note : by 7 I mean (number of bits required to hold the
3705 /* if the root operations is not a | operation the not */
3706 if (!IS_BITOR (root))
3709 /* I have to think of a better way to match patterns this sucks */
3710 /* that aside let start looking for the first case : I use a the
3711 negative check a lot to improve the efficiency */
3712 /* (?expr << 1) | (?expr >> 7) */
3713 if (IS_LEFT_OP (root->left) &&
3714 IS_RIGHT_OP (root->right))
3717 if (!SPEC_USIGN (TETYPE (root->left->left)))
3720 if (!IS_AST_LIT_VALUE (root->left->right) ||
3721 !IS_AST_LIT_VALUE (root->right->right))
3724 /* make sure it is the same expression */
3725 if (!isAstEqual (root->left->left,
3729 if (AST_LIT_VALUE (root->left->right) != 1)
3732 if (AST_LIT_VALUE (root->right->right) !=
3733 (getSize (TTYPE (root->left->left)) * 8 - 1))
3736 /* whew got the first case : create the AST */
3737 return newNode (RLC, root->left->left, NULL);
3741 /* check for second case */
3742 /* (?expr >> 7) | (?expr << 1) */
3743 if (IS_LEFT_OP (root->right) &&
3744 IS_RIGHT_OP (root->left))
3747 if (!SPEC_USIGN (TETYPE (root->left->left)))
3750 if (!IS_AST_LIT_VALUE (root->left->right) ||
3751 !IS_AST_LIT_VALUE (root->right->right))
3754 /* make sure it is the same symbol */
3755 if (!isAstEqual (root->left->left,
3759 if (AST_LIT_VALUE (root->right->right) != 1)
3762 if (AST_LIT_VALUE (root->left->right) !=
3763 (getSize (TTYPE (root->left->left)) * 8 - 1))
3766 /* whew got the first case : create the AST */
3767 return newNode (RLC, root->left->left, NULL);
3772 /* third case for RRC */
3773 /* (?symbol >> 1) | (?symbol << 7) */
3774 if (IS_LEFT_OP (root->right) &&
3775 IS_RIGHT_OP (root->left))
3778 if (!SPEC_USIGN (TETYPE (root->left->left)))
3781 if (!IS_AST_LIT_VALUE (root->left->right) ||
3782 !IS_AST_LIT_VALUE (root->right->right))
3785 /* make sure it is the same symbol */
3786 if (!isAstEqual (root->left->left,
3790 if (AST_LIT_VALUE (root->left->right) != 1)
3793 if (AST_LIT_VALUE (root->right->right) !=
3794 (getSize (TTYPE (root->left->left)) * 8 - 1))
3797 /* whew got the first case : create the AST */
3798 return newNode (RRC, root->left->left, NULL);
3802 /* fourth and last case for now */
3803 /* (?symbol << 7) | (?symbol >> 1) */
3804 if (IS_RIGHT_OP (root->right) &&
3805 IS_LEFT_OP (root->left))
3808 if (!SPEC_USIGN (TETYPE (root->left->left)))
3811 if (!IS_AST_LIT_VALUE (root->left->right) ||
3812 !IS_AST_LIT_VALUE (root->right->right))
3815 /* make sure it is the same symbol */
3816 if (!isAstEqual (root->left->left,
3820 if (AST_LIT_VALUE (root->right->right) != 1)
3823 if (AST_LIT_VALUE (root->left->right) !=
3824 (getSize (TTYPE (root->left->left)) * 8 - 1))
3827 /* whew got the first case : create the AST */
3828 return newNode (RRC, root->left->left, NULL);
3832 /* not found return root */
3836 /*-----------------------------------------------------------------*/
3837 /* optimizeCompare - otimizes compares for bit variables */
3838 /*-----------------------------------------------------------------*/
3840 optimizeCompare (ast * root)
3842 ast *optExpr = NULL;
3845 unsigned int litValue;
3847 /* if nothing then return nothing */
3851 /* if not a compare op then do leaves */
3852 if (!IS_COMPARE_OP (root))
3854 root->left = optimizeCompare (root->left);
3855 root->right = optimizeCompare (root->right);
3859 /* if left & right are the same then depending
3860 of the operation do */
3861 if (isAstEqual (root->left, root->right))
3863 switch (root->opval.op)
3868 optExpr = newAst_VALUE (constVal ("0"));
3873 optExpr = newAst_VALUE (constVal ("1"));
3877 return decorateType (optExpr);
3880 vleft = (root->left->type == EX_VALUE ?
3881 root->left->opval.val : NULL);
3883 vright = (root->right->type == EX_VALUE ?
3884 root->right->opval.val : NULL);
3886 /* if left is a BITVAR in BITSPACE */
3887 /* and right is a LITERAL then opt- */
3888 /* imize else do nothing */
3889 if (vleft && vright &&
3890 IS_BITVAR (vleft->etype) &&
3891 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3892 IS_LITERAL (vright->etype))
3895 /* if right side > 1 then comparison may never succeed */
3896 if ((litValue = (int) floatFromVal (vright)) > 1)
3898 werror (W_BAD_COMPARE);
3904 switch (root->opval.op)
3906 case '>': /* bit value greater than 1 cannot be */
3907 werror (W_BAD_COMPARE);
3911 case '<': /* bit value < 1 means 0 */
3913 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3916 case LE_OP: /* bit value <= 1 means no check */
3917 optExpr = newAst_VALUE (vright);
3920 case GE_OP: /* bit value >= 1 means only check for = */
3922 optExpr = newAst_VALUE (vleft);
3927 { /* literal is zero */
3928 switch (root->opval.op)
3930 case '<': /* bit value < 0 cannot be */
3931 werror (W_BAD_COMPARE);
3935 case '>': /* bit value > 0 means 1 */
3937 optExpr = newAst_VALUE (vleft);
3940 case LE_OP: /* bit value <= 0 means no check */
3941 case GE_OP: /* bit value >= 0 means no check */
3942 werror (W_BAD_COMPARE);
3946 case EQ_OP: /* bit == 0 means ! of bit */
3947 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3951 return decorateType (resolveSymbols (optExpr));
3952 } /* end-of-if of BITVAR */
3957 /*-----------------------------------------------------------------*/
3958 /* addSymToBlock : adds the symbol to the first block we find */
3959 /*-----------------------------------------------------------------*/
3961 addSymToBlock (symbol * sym, ast * tree)
3963 /* reached end of tree or a leaf */
3964 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
3968 if (IS_AST_OP (tree) &&
3969 tree->opval.op == BLOCK)
3972 symbol *lsym = copySymbol (sym);
3974 lsym->next = AST_VALUES (tree, sym);
3975 AST_VALUES (tree, sym) = lsym;
3979 addSymToBlock (sym, tree->left);
3980 addSymToBlock (sym, tree->right);
3983 /*-----------------------------------------------------------------*/
3984 /* processRegParms - do processing for register parameters */
3985 /*-----------------------------------------------------------------*/
3987 processRegParms (value * args, ast * body)
3991 if (IS_REGPARM (args->etype))
3992 addSymToBlock (args->sym, body);
3997 /*-----------------------------------------------------------------*/
3998 /* resetParmKey - resets the operandkeys for the symbols */
3999 /*-----------------------------------------------------------------*/
4000 DEFSETFUNC (resetParmKey)
4011 /*-----------------------------------------------------------------*/
4012 /* createFunction - This is the key node that calls the iCode for */
4013 /* generating the code for a function. Note code */
4014 /* is generated function by function, later when */
4015 /* add inter-procedural analysis this will change */
4016 /*-----------------------------------------------------------------*/
4018 createFunction (symbol * name, ast * body)
4024 iCode *piCode = NULL;
4026 /* if check function return 0 then some problem */
4027 if (checkFunction (name) == 0)
4030 /* create a dummy block if none exists */
4032 body = newNode (BLOCK, NULL, NULL);
4036 /* check if the function name already in the symbol table */
4037 if ((csym = findSym (SymbolTab, NULL, name->name)))
4040 /* special case for compiler defined functions
4041 we need to add the name to the publics list : this
4042 actually means we are now compiling the compiler
4046 addSet (&publics, name);
4052 allocVariables (name);
4054 name->lastLine = yylineno;
4056 processFuncArgs (currFunc, 0);
4058 /* set the stack pointer */
4059 /* PENDING: check this for the mcs51 */
4060 stackPtr = -port->stack.direction * port->stack.call_overhead;
4061 if (IS_ISR (name->etype))
4062 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4063 if (IS_RENT (name->etype) || options.stackAuto)
4064 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4066 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4068 fetype = getSpec (name->type); /* get the specifier for the function */
4069 /* if this is a reentrant function then */
4070 if (IS_RENT (fetype))
4073 allocParms (name->args); /* allocate the parameters */
4075 /* do processing for parameters that are passed in registers */
4076 processRegParms (name->args, body);
4078 /* set the stack pointer */
4082 /* allocate & autoinit the block variables */
4083 processBlockVars (body, &stack, ALLOCATE);
4085 /* save the stack information */
4086 if (options.useXstack)
4087 name->xstack = SPEC_STAK (fetype) = stack;
4089 name->stack = SPEC_STAK (fetype) = stack;
4091 /* name needs to be mangled */
4092 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4094 body = resolveSymbols (body); /* resolve the symbols */
4095 body = decorateType (body); /* propagateType & do semantic checks */
4097 ex = newAst_VALUE (symbolVal (name)); /* create name */
4098 ex = newNode (FUNCTION, ex, body);
4099 ex->values.args = name->args;
4103 werror (E_FUNC_NO_CODE, name->name);
4107 /* create the node & generate intermediate code */
4109 codeOutFile = code->oFile;
4110 piCode = iCodeFromAst (ex);
4114 werror (E_FUNC_NO_CODE, name->name);
4118 eBBlockFromiCode (piCode);
4120 /* if there are any statics then do them */
4123 GcurMemmap = statsg;
4124 codeOutFile = statsg->oFile;
4125 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4131 /* dealloc the block variables */
4132 processBlockVars (body, &stack, DEALLOCATE);
4133 /* deallocate paramaters */
4134 deallocParms (name->args);
4136 if (IS_RENT (fetype))
4139 /* we are done freeup memory & cleanup */
4144 addSet (&operKeyReset, name);
4145 applyToSet (operKeyReset, resetParmKey);
4147 if (options.debug && !options.nodebug)
4148 cdbStructBlock (1, cdbFile);
4150 cleanUpLevel (LabelTab, 0);
4151 cleanUpBlock (StructTab, 1);
4152 cleanUpBlock (TypedefTab, 1);
4154 xstack->syms = NULL;
4155 istack->syms = NULL;
4160 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4161 /*-----------------------------------------------------------------*/
4162 /* ast_print : prints the ast (for debugging purposes) */
4163 /*-----------------------------------------------------------------*/
4165 void ast_print (ast * tree, FILE *outfile, int indent)
4170 /* can print only decorated trees */
4171 if (!tree->decorated) return;
4173 /* if any child is an error | this one is an error do nothing */
4174 if (tree->isError ||
4175 (tree->left && tree->left->isError) ||
4176 (tree->right && tree->right->isError)) {
4177 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4181 /* print the line */
4182 /* if not block & function */
4183 if (tree->type == EX_OP &&
4184 (tree->opval.op != FUNCTION &&
4185 tree->opval.op != BLOCK &&
4186 tree->opval.op != NULLOP)) {
4189 if (tree->opval.op == FUNCTION) {
4190 fprintf(outfile,"FUNCTION (%p) type (",tree);
4191 printTypeChain (tree->ftype,outfile);
4192 fprintf(outfile,")\n");
4193 ast_print(tree->left,outfile,indent+4);
4194 ast_print(tree->right,outfile,indent+4);
4197 if (tree->opval.op == BLOCK) {
4198 symbol *decls = tree->values.sym;
4199 fprintf(outfile,"{\n");
4201 INDENT(indent+4,outfile);
4202 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4203 printTypeChain(decls->type,outfile);
4204 fprintf(outfile,")\n");
4206 decls = decls->next;
4208 ast_print(tree->right,outfile,indent+4);
4209 fprintf(outfile,"}\n");
4212 if (tree->opval.op == NULLOP) {
4213 fprintf(outfile,"\n");
4214 ast_print(tree->left,outfile,indent);
4215 fprintf(outfile,"\n");
4216 ast_print(tree->right,outfile,indent);
4219 INDENT(indent,outfile);
4221 /*------------------------------------------------------------------*/
4222 /*----------------------------*/
4223 /* leaf has been reached */
4224 /*----------------------------*/
4225 /* if this is of type value */
4226 /* just get the type */
4227 if (tree->type == EX_VALUE) {
4229 if (IS_LITERAL (tree->opval.val->etype)) {
4230 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4231 (int) floatFromVal(tree->opval.val),
4232 (int) floatFromVal(tree->opval.val),
4233 floatFromVal(tree->opval.val));
4234 } else if (tree->opval.val->sym) {
4235 /* if the undefined flag is set then give error message */
4236 if (tree->opval.val->sym->undefined) {
4237 fprintf(outfile,"UNDEFINED SYMBOL ");
4239 fprintf(outfile,"SYMBOL ");
4241 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4244 fprintf(outfile," type (");
4245 printTypeChain(tree->ftype,outfile);
4246 fprintf(outfile,")\n");
4248 fprintf(outfile,"\n");
4253 /* if type link for the case of cast */
4254 if (tree->type == EX_LINK) {
4255 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4256 printTypeChain(tree->opval.lnk,outfile);
4257 fprintf(outfile,")\n");
4262 /* depending on type of operator do */
4264 switch (tree->opval.op) {
4265 /*------------------------------------------------------------------*/
4266 /*----------------------------*/
4268 /*----------------------------*/
4270 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4271 printTypeChain(tree->ftype,outfile);
4272 fprintf(outfile,")\n");
4273 ast_print(tree->left,outfile,indent+4);
4274 ast_print(tree->right,outfile,indent+4);
4277 /*------------------------------------------------------------------*/
4278 /*----------------------------*/
4280 /*----------------------------*/
4282 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4283 printTypeChain(tree->ftype,outfile);
4284 fprintf(outfile,")\n");
4285 ast_print(tree->left,outfile,indent+4);
4286 ast_print(tree->right,outfile,indent+4);
4289 /*------------------------------------------------------------------*/
4290 /*----------------------------*/
4291 /* struct/union pointer */
4292 /*----------------------------*/
4294 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4295 printTypeChain(tree->ftype,outfile);
4296 fprintf(outfile,")\n");
4297 ast_print(tree->left,outfile,indent+4);
4298 ast_print(tree->right,outfile,indent+4);
4301 /*------------------------------------------------------------------*/
4302 /*----------------------------*/
4303 /* ++/-- operation */
4304 /*----------------------------*/
4305 case INC_OP: /* incerement operator unary so left only */
4306 fprintf(outfile,"INC_OP (%p) type (",tree);
4307 printTypeChain(tree->ftype,outfile);
4308 fprintf(outfile,")\n");
4309 ast_print(tree->left,outfile,indent+4);
4313 fprintf(outfile,"DEC_OP (%p) type (",tree);
4314 printTypeChain(tree->ftype,outfile);
4315 fprintf(outfile,")\n");
4316 ast_print(tree->left,outfile,indent+4);
4319 /*------------------------------------------------------------------*/
4320 /*----------------------------*/
4322 /*----------------------------*/
4325 fprintf(outfile,"& (%p) type (",tree);
4326 printTypeChain(tree->ftype,outfile);
4327 fprintf(outfile,")\n");
4328 ast_print(tree->left,outfile,indent+4);
4329 ast_print(tree->right,outfile,indent+4);
4331 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4332 printTypeChain(tree->ftype,outfile);
4333 fprintf(outfile,")\n");
4334 ast_print(tree->left,outfile,indent+4);
4335 ast_print(tree->right,outfile,indent+4);
4338 /*----------------------------*/
4340 /*----------------------------*/
4342 fprintf(outfile,"OR (%p) type (",tree);
4343 printTypeChain(tree->ftype,outfile);
4344 fprintf(outfile,")\n");
4345 ast_print(tree->left,outfile,indent+4);
4346 ast_print(tree->right,outfile,indent+4);
4348 /*------------------------------------------------------------------*/
4349 /*----------------------------*/
4351 /*----------------------------*/
4353 fprintf(outfile,"XOR (%p) type (",tree);
4354 printTypeChain(tree->ftype,outfile);
4355 fprintf(outfile,")\n");
4356 ast_print(tree->left,outfile,indent+4);
4357 ast_print(tree->right,outfile,indent+4);
4360 /*------------------------------------------------------------------*/
4361 /*----------------------------*/
4363 /*----------------------------*/
4365 fprintf(outfile,"DIV (%p) type (",tree);
4366 printTypeChain(tree->ftype,outfile);
4367 fprintf(outfile,")\n");
4368 ast_print(tree->left,outfile,indent+4);
4369 ast_print(tree->right,outfile,indent+4);
4371 /*------------------------------------------------------------------*/
4372 /*----------------------------*/
4374 /*----------------------------*/
4376 fprintf(outfile,"MOD (%p) type (",tree);
4377 printTypeChain(tree->ftype,outfile);
4378 fprintf(outfile,")\n");
4379 ast_print(tree->left,outfile,indent+4);
4380 ast_print(tree->right,outfile,indent+4);
4383 /*------------------------------------------------------------------*/
4384 /*----------------------------*/
4385 /* address dereference */
4386 /*----------------------------*/
4387 case '*': /* can be unary : if right is null then unary operation */
4389 fprintf(outfile,"DEREF (%p) type (",tree);
4390 printTypeChain(tree->ftype,outfile);
4391 fprintf(outfile,")\n");
4392 ast_print(tree->left,outfile,indent+4);
4395 /*------------------------------------------------------------------*/
4396 /*----------------------------*/
4397 /* multiplication */
4398 /*----------------------------*/
4399 fprintf(outfile,"MULT (%p) type (",tree);
4400 printTypeChain(tree->ftype,outfile);
4401 fprintf(outfile,")\n");
4402 ast_print(tree->left,outfile,indent+4);
4403 ast_print(tree->right,outfile,indent+4);
4407 /*------------------------------------------------------------------*/
4408 /*----------------------------*/
4409 /* unary '+' operator */
4410 /*----------------------------*/
4414 fprintf(outfile,"UPLUS (%p) type (",tree);
4415 printTypeChain(tree->ftype,outfile);
4416 fprintf(outfile,")\n");
4417 ast_print(tree->left,outfile,indent+4);
4419 /*------------------------------------------------------------------*/
4420 /*----------------------------*/
4422 /*----------------------------*/
4423 fprintf(outfile,"ADD (%p) type (",tree);
4424 printTypeChain(tree->ftype,outfile);
4425 fprintf(outfile,")\n");
4426 ast_print(tree->left,outfile,indent+4);
4427 ast_print(tree->right,outfile,indent+4);
4430 /*------------------------------------------------------------------*/
4431 /*----------------------------*/
4433 /*----------------------------*/
4434 case '-': /* can be unary */
4436 fprintf(outfile,"UMINUS (%p) type (",tree);
4437 printTypeChain(tree->ftype,outfile);
4438 fprintf(outfile,")\n");
4439 ast_print(tree->left,outfile,indent+4);
4441 /*------------------------------------------------------------------*/
4442 /*----------------------------*/
4444 /*----------------------------*/
4445 fprintf(outfile,"SUB (%p) type (",tree);
4446 printTypeChain(tree->ftype,outfile);
4447 fprintf(outfile,")\n");
4448 ast_print(tree->left,outfile,indent+4);
4449 ast_print(tree->right,outfile,indent+4);
4452 /*------------------------------------------------------------------*/
4453 /*----------------------------*/
4455 /*----------------------------*/
4457 fprintf(outfile,"COMPL (%p) type (",tree);
4458 printTypeChain(tree->ftype,outfile);
4459 fprintf(outfile,")\n");
4460 ast_print(tree->left,outfile,indent+4);
4462 /*------------------------------------------------------------------*/
4463 /*----------------------------*/
4465 /*----------------------------*/
4467 fprintf(outfile,"NOT (%p) type (",tree);
4468 printTypeChain(tree->ftype,outfile);
4469 fprintf(outfile,")\n");
4470 ast_print(tree->left,outfile,indent+4);
4472 /*------------------------------------------------------------------*/
4473 /*----------------------------*/
4475 /*----------------------------*/
4477 fprintf(outfile,"RRC (%p) type (",tree);
4478 printTypeChain(tree->ftype,outfile);
4479 fprintf(outfile,")\n");
4480 ast_print(tree->left,outfile,indent+4);
4484 fprintf(outfile,"RLC (%p) type (",tree);
4485 printTypeChain(tree->ftype,outfile);
4486 fprintf(outfile,")\n");
4487 ast_print(tree->left,outfile,indent+4);
4490 fprintf(outfile,"GETHBIT (%p) type (",tree);
4491 printTypeChain(tree->ftype,outfile);
4492 fprintf(outfile,")\n");
4493 ast_print(tree->left,outfile,indent+4);
4496 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4497 printTypeChain(tree->ftype,outfile);
4498 fprintf(outfile,")\n");
4499 ast_print(tree->left,outfile,indent+4);
4500 ast_print(tree->right,outfile,indent+4);
4503 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4504 printTypeChain(tree->ftype,outfile);
4505 fprintf(outfile,")\n");
4506 ast_print(tree->left,outfile,indent+4);
4507 ast_print(tree->right,outfile,indent+4);
4509 /*------------------------------------------------------------------*/
4510 /*----------------------------*/
4512 /*----------------------------*/
4513 case CAST: /* change the type */
4514 fprintf(outfile,"CAST (%p) type (",tree);
4515 printTypeChain(tree->ftype,outfile);
4516 fprintf(outfile,")\n");
4517 ast_print(tree->right,outfile,indent+4);
4521 fprintf(outfile,"ANDAND (%p) type (",tree);
4522 printTypeChain(tree->ftype,outfile);
4523 fprintf(outfile,")\n");
4524 ast_print(tree->left,outfile,indent+4);
4525 ast_print(tree->right,outfile,indent+4);
4528 fprintf(outfile,"OROR (%p) type (",tree);
4529 printTypeChain(tree->ftype,outfile);
4530 fprintf(outfile,")\n");
4531 ast_print(tree->left,outfile,indent+4);
4532 ast_print(tree->right,outfile,indent+4);
4535 /*------------------------------------------------------------------*/
4536 /*----------------------------*/
4537 /* comparison operators */
4538 /*----------------------------*/
4540 fprintf(outfile,"GT(>) (%p) type (",tree);
4541 printTypeChain(tree->ftype,outfile);
4542 fprintf(outfile,")\n");
4543 ast_print(tree->left,outfile,indent+4);
4544 ast_print(tree->right,outfile,indent+4);
4547 fprintf(outfile,"LT(<) (%p) type (",tree);
4548 printTypeChain(tree->ftype,outfile);
4549 fprintf(outfile,")\n");
4550 ast_print(tree->left,outfile,indent+4);
4551 ast_print(tree->right,outfile,indent+4);
4554 fprintf(outfile,"LE(<=) (%p) type (",tree);
4555 printTypeChain(tree->ftype,outfile);
4556 fprintf(outfile,")\n");
4557 ast_print(tree->left,outfile,indent+4);
4558 ast_print(tree->right,outfile,indent+4);
4561 fprintf(outfile,"GE(>=) (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+4);
4565 ast_print(tree->right,outfile,indent+4);
4568 fprintf(outfile,"EQ(==) (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+4);
4572 ast_print(tree->right,outfile,indent+4);
4575 fprintf(outfile,"NE(!=) (%p) type (",tree);
4576 printTypeChain(tree->ftype,outfile);
4577 fprintf(outfile,")\n");
4578 ast_print(tree->left,outfile,indent+4);
4579 ast_print(tree->right,outfile,indent+4);
4580 /*------------------------------------------------------------------*/
4581 /*----------------------------*/
4583 /*----------------------------*/
4584 case SIZEOF: /* evaluate wihout code generation */
4585 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4588 /*------------------------------------------------------------------*/
4589 /*----------------------------*/
4590 /* conditional operator '?' */
4591 /*----------------------------*/
4593 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4594 printTypeChain(tree->ftype,outfile);
4595 fprintf(outfile,")\n");
4596 ast_print(tree->left,outfile,indent+4);
4597 ast_print(tree->right,outfile,indent+4);
4600 fprintf(outfile,"COLON(:) (%p) type (",tree);
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->left,outfile,indent+4);
4604 ast_print(tree->right,outfile,indent+4);
4607 /*------------------------------------------------------------------*/
4608 /*----------------------------*/
4609 /* assignment operators */
4610 /*----------------------------*/
4612 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4613 printTypeChain(tree->ftype,outfile);
4614 fprintf(outfile,")\n");
4615 ast_print(tree->left,outfile,indent+4);
4616 ast_print(tree->right,outfile,indent+4);
4619 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4620 printTypeChain(tree->ftype,outfile);
4621 fprintf(outfile,")\n");
4622 ast_print(tree->left,outfile,indent+4);
4623 ast_print(tree->right,outfile,indent+4);
4626 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4627 printTypeChain(tree->ftype,outfile);
4628 fprintf(outfile,")\n");
4629 ast_print(tree->left,outfile,indent+4);
4630 ast_print(tree->right,outfile,indent+4);
4633 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4634 printTypeChain(tree->ftype,outfile);
4635 fprintf(outfile,")\n");
4636 ast_print(tree->left,outfile,indent+4);
4637 ast_print(tree->right,outfile,indent+4);
4640 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+4);
4644 ast_print(tree->right,outfile,indent+4);
4647 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+4);
4651 ast_print(tree->right,outfile,indent+4);
4654 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+4);
4658 ast_print(tree->right,outfile,indent+4);
4660 /*------------------------------------------------------------------*/
4661 /*----------------------------*/
4663 /*----------------------------*/
4665 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4666 printTypeChain(tree->ftype,outfile);
4667 fprintf(outfile,")\n");
4668 ast_print(tree->left,outfile,indent+4);
4669 ast_print(tree->right,outfile,indent+4);
4671 /*------------------------------------------------------------------*/
4672 /*----------------------------*/
4674 /*----------------------------*/
4676 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+4);
4680 ast_print(tree->right,outfile,indent+4);
4682 /*------------------------------------------------------------------*/
4683 /*----------------------------*/
4684 /* straight assignemnt */
4685 /*----------------------------*/
4687 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4688 printTypeChain(tree->ftype,outfile);
4689 fprintf(outfile,")\n");
4690 ast_print(tree->left,outfile,indent+4);
4691 ast_print(tree->right,outfile,indent+4);
4693 /*------------------------------------------------------------------*/
4694 /*----------------------------*/
4695 /* comma operator */
4696 /*----------------------------*/
4698 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4699 printTypeChain(tree->ftype,outfile);
4700 fprintf(outfile,")\n");
4701 ast_print(tree->left,outfile,indent+4);
4702 ast_print(tree->right,outfile,indent+4);
4704 /*------------------------------------------------------------------*/
4705 /*----------------------------*/
4707 /*----------------------------*/
4710 fprintf(outfile,"CALL (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+4);
4714 ast_print(tree->right,outfile,indent+4);
4717 fprintf(outfile,"PARM ");
4718 ast_print(tree->left,outfile,indent+4);
4719 if (tree->right && !IS_AST_PARAM(tree->right)) {
4720 fprintf(outfile,"PARM ");
4721 ast_print(tree->right,outfile,indent+4);
4724 /*------------------------------------------------------------------*/
4725 /*----------------------------*/
4726 /* return statement */
4727 /*----------------------------*/
4729 fprintf(outfile,"RETURN (%p) type (",tree);
4730 printTypeChain(tree->right->ftype,outfile);
4731 fprintf(outfile,")\n");
4732 ast_print(tree->right,outfile,indent+4);
4734 /*------------------------------------------------------------------*/
4735 /*----------------------------*/
4736 /* label statement */
4737 /*----------------------------*/
4739 fprintf(outfile,"LABEL (%p)",tree);
4740 ast_print(tree->left,outfile,indent+4);
4741 ast_print(tree->right,outfile,indent);
4743 /*------------------------------------------------------------------*/
4744 /*----------------------------*/
4745 /* switch statement */
4746 /*----------------------------*/
4750 fprintf(outfile,"SWITCH (%p) ",tree);
4751 ast_print(tree->left,outfile,0);
4752 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4753 INDENT(indent+4,outfile);
4754 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4755 (int) floatFromVal(val),
4756 tree->values.switchVals.swNum,
4757 (int) floatFromVal(val));
4759 ast_print(tree->right,outfile,indent);
4762 /*------------------------------------------------------------------*/
4763 /*----------------------------*/
4765 /*----------------------------*/
4767 ast_print(tree->left,outfile,indent);
4768 INDENT(indent,outfile);
4769 fprintf(outfile,"IF (%p) \n",tree);
4770 if (tree->trueLabel) {
4771 INDENT(indent,outfile);
4772 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4774 if (tree->falseLabel) {
4775 INDENT(indent,outfile);
4776 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4778 ast_print(tree->right,outfile,indent);
4780 /*------------------------------------------------------------------*/
4781 /*----------------------------*/
4783 /*----------------------------*/
4785 fprintf(outfile,"FOR (%p) \n",tree);
4786 if (AST_FOR( tree, initExpr)) {
4787 INDENT(indent+4,outfile);
4788 fprintf(outfile,"INIT EXPR ");
4789 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4791 if (AST_FOR( tree, condExpr)) {
4792 INDENT(indent+4,outfile);
4793 fprintf(outfile,"COND EXPR ");
4794 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4796 if (AST_FOR( tree, loopExpr)) {
4797 INDENT(indent+4,outfile);
4798 fprintf(outfile,"LOOP EXPR ");
4799 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4801 fprintf(outfile,"FOR LOOP BODY \n");
4802 ast_print(tree->left,outfile,indent+4);
4811 ast_print(t,stdout,1);