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 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 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 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190 strcpy (dest->values.inlineasm, src->values.inlineasm);
194 dest->values.constlist = copyLiteralList(src->values.constlist);
198 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession */
211 /*-----------------------------------------------------------------*/
220 dest = Safe_alloc ( sizeof (ast));
222 dest->type = src->type;
223 dest->lineno = src->lineno;
224 dest->level = src->level;
225 dest->funcName = src->funcName;
228 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
230 /* if this is a leaf */
232 if (src->type == EX_VALUE)
234 dest->opval.val = copyValue (src->opval.val);
239 if (src->type == EX_LINK)
241 dest->opval.lnk = copyLinkChain (src->opval.lnk);
245 dest->opval.op = src->opval.op;
247 /* if this is a node that has special values */
248 copyAstValues (dest, src);
250 dest->trueLabel = copySymbol (src->trueLabel);
251 dest->falseLabel = copySymbol (src->falseLabel);
252 dest->left = copyAst (src->left);
253 dest->right = copyAst (src->right);
259 /*-----------------------------------------------------------------*/
260 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
261 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
262 /*-----------------------------------------------------------------*/
263 ast *removeIncDecOps (ast * tree) {
265 // traverse the tree and remove inc/dec ops
270 if (tree->type == EX_OP &&
271 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
278 tree->left=removeIncDecOps(tree->left);
279 tree->right=removeIncDecOps(tree->right);
284 /*-----------------------------------------------------------------*/
285 /* hasSEFcalls - returns TRUE if tree has a function call */
286 /*-----------------------------------------------------------------*/
288 hasSEFcalls (ast * tree)
293 if (tree->type == EX_OP &&
294 (tree->opval.op == CALL ||
295 tree->opval.op == PCALL ||
296 tree->opval.op == '=' ||
297 tree->opval.op == INC_OP ||
298 tree->opval.op == DEC_OP))
301 return (hasSEFcalls (tree->left) |
302 hasSEFcalls (tree->right));
305 /*-----------------------------------------------------------------*/
306 /* isAstEqual - compares two asts & returns 1 if they are equal */
307 /*-----------------------------------------------------------------*/
309 isAstEqual (ast * t1, ast * t2)
318 if (t1->type != t2->type)
324 if (t1->opval.op != t2->opval.op)
326 return (isAstEqual (t1->left, t2->left) &&
327 isAstEqual (t1->right, t2->right));
331 if (t1->opval.val->sym)
333 if (!t2->opval.val->sym)
336 return isSymbolEqual (t1->opval.val->sym,
341 if (t2->opval.val->sym)
344 return (floatFromVal (t1->opval.val) ==
345 floatFromVal (t2->opval.val));
349 /* only compare these two types */
357 /*-----------------------------------------------------------------*/
358 /* resolveSymbols - resolve symbols from the symbol table */
359 /*-----------------------------------------------------------------*/
361 resolveSymbols (ast * tree)
363 /* walk the entire tree and check for values */
364 /* with symbols if we find one then replace */
365 /* symbol with that from the symbol table */
371 /* if not block & function */
372 if (tree->type == EX_OP &&
373 (tree->opval.op != FUNCTION &&
374 tree->opval.op != BLOCK &&
375 tree->opval.op != NULLOP))
377 filename = tree->filename;
378 lineno = tree->lineno;
381 /* make sure we resolve the true & false labels for ifx */
382 if (tree->type == EX_OP && tree->opval.op == IFX)
388 if ((csym = findSym (LabelTab, tree->trueLabel,
389 tree->trueLabel->name)))
390 tree->trueLabel = csym;
392 werror (E_LABEL_UNDEF, tree->trueLabel->name);
395 if (tree->falseLabel)
397 if ((csym = findSym (LabelTab,
399 tree->falseLabel->name)))
400 tree->falseLabel = csym;
402 werror (E_LABEL_UNDEF, tree->falseLabel->name);
407 /* if this is a label resolve it from the labelTab */
408 if (IS_AST_VALUE (tree) &&
409 tree->opval.val->sym &&
410 tree->opval.val->sym->islbl)
413 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
414 tree->opval.val->sym->name);
417 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
419 tree->opval.val->sym = csym;
421 goto resolveChildren;
424 /* do only for leafs */
425 if (IS_AST_VALUE (tree) &&
426 tree->opval.val->sym &&
427 !tree->opval.val->sym->implicit)
430 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
432 /* if found in the symbol table & they r not the same */
433 if (csym && tree->opval.val->sym != csym)
435 tree->opval.val->sym = csym;
436 tree->opval.val->type = csym->type;
437 tree->opval.val->etype = csym->etype;
440 /* if not found in the symbol table */
441 /* mark it as undefined assume it is */
442 /* an integer in data space */
443 if (!csym && !tree->opval.val->sym->implicit)
446 /* if this is a function name then */
447 /* mark it as returning an int */
450 tree->opval.val->sym->type = newLink ();
451 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
452 tree->opval.val->sym->type->next =
453 tree->opval.val->sym->etype = newIntLink ();
454 tree->opval.val->etype = tree->opval.val->etype;
455 tree->opval.val->type = tree->opval.val->sym->type;
456 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
457 allocVariables (tree->opval.val->sym);
461 tree->opval.val->sym->undefined = 1;
462 tree->opval.val->type =
463 tree->opval.val->etype = newIntLink ();
464 tree->opval.val->sym->type =
465 tree->opval.val->sym->etype = newIntLink ();
471 resolveSymbols (tree->left);
472 resolveSymbols (tree->right);
477 /*-----------------------------------------------------------------*/
478 /* setAstLineno - walks a ast tree & sets the line number */
479 /*-----------------------------------------------------------------*/
481 setAstLineno (ast * tree, int lineno)
486 tree->lineno = lineno;
487 setAstLineno (tree->left, lineno);
488 setAstLineno (tree->right, lineno);
492 /*-----------------------------------------------------------------*/
493 /* funcOfType :- function of type with name */
494 /*-----------------------------------------------------------------*/
496 funcOfType (char *name, sym_link * type, sym_link * argType,
500 /* create the symbol */
501 sym = newSymbol (name, 0);
503 /* setup return value */
504 sym->type = newLink ();
505 DCL_TYPE (sym->type) = FUNCTION;
506 sym->type->next = copyLinkChain (type);
507 sym->etype = getSpec (sym->type);
508 FUNC_ISREENT(sym->type) = rent;
510 /* if arguments required */
514 args = FUNC_ARGS(sym->type) = newValue ();
518 args->type = copyLinkChain (argType);
519 args->etype = getSpec (args->type);
520 SPEC_EXTR(args->etype)=1;
523 args = args->next = newValue ();
530 allocVariables (sym);
535 /*-----------------------------------------------------------------*/
536 /* funcOfTypeVarg :- function of type with name and argtype */
537 /*-----------------------------------------------------------------*/
539 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
544 /* create the symbol */
545 sym = newSymbol (name, 0);
547 /* setup return value */
548 sym->type = newLink ();
549 DCL_TYPE (sym->type) = FUNCTION;
550 sym->type->next = typeFromStr(rtype);
551 sym->etype = getSpec (sym->type);
553 /* if arguments required */
556 args = FUNC_ARGS(sym->type) = newValue ();
558 for ( i = 0 ; i < nArgs ; i++ ) {
559 args->type = typeFromStr(atypes[i]);
560 args->etype = getSpec (args->type);
561 SPEC_EXTR(args->etype)=1;
562 if ((i + 1) == nArgs) break;
563 args = args->next = newValue ();
570 allocVariables (sym);
575 /*-----------------------------------------------------------------*/
576 /* reverseParms - will reverse a parameter tree */
577 /*-----------------------------------------------------------------*/
579 reverseParms (ast * ptree)
585 /* top down if we find a nonParm tree then quit */
586 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
589 ptree->left = ptree->right;
590 ptree->right = ttree;
591 reverseParms (ptree->left);
592 reverseParms (ptree->right);
598 /*-----------------------------------------------------------------*/
599 /* processParms - makes sure the parameters are okay and do some */
600 /* processing with them */
601 /*-----------------------------------------------------------------*/
603 processParms (ast * func,
606 int *parmNumber, // unused, although updated
609 /* if none of them exist */
610 if (!defParm && !actParm)
614 if (getenv("DEBUG_SANITY")) {
615 fprintf (stderr, "processParms: %s ", defParm->name);
617 /* make sure the type is complete and sane */
618 checkTypeSanity(defParm->etype, defParm->name);
621 /* if the function is being called via a pointer & */
622 /* it has not been defined a reentrant then we cannot */
623 /* have parameters */
624 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
626 werror (W_NONRENT_ARGS);
630 /* if defined parameters ended but actual parameters */
631 /* exist and this is not defined as a variable arg */
632 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
634 werror (E_TOO_MANY_PARMS);
638 /* if defined parameters present but no actual parameters */
639 if (defParm && !actParm)
641 werror (E_TOO_FEW_PARMS);
645 if (IS_VOID(actParm->ftype)) {
646 werror (E_VOID_VALUE_USED);
650 /* If this is a varargs function... */
651 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
656 if (IS_CAST_OP (actParm)
657 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
659 /* Parameter was explicitly typecast; don't touch it. */
663 ftype = actParm->ftype;
665 /* If it's a small integer, upcast to int. */
666 if (IS_INTEGRAL (ftype)
667 && (getSize (ftype) < (unsigned) INTSIZE))
669 newType = newAst_LINK(INTTYPE);
672 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
674 newType = newAst_LINK (copyLinkChain(ftype));
675 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
678 if (IS_AGGREGATE (ftype))
680 newType = newAst_LINK (copyLinkChain (ftype));
681 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
685 /* cast required; change this op to a cast. */
686 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
688 actParm->type = EX_OP;
689 actParm->opval.op = CAST;
690 actParm->left = newType;
691 actParm->right = parmCopy;
692 decorateType (actParm);
694 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
696 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
697 processParms (func, NULL, actParm->right, parmNumber, rightmost));
702 /* if defined parameters ended but actual has not & */
704 if (!defParm && actParm &&
705 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
708 resolveSymbols (actParm);
709 /* if this is a PARAM node then match left & right */
710 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
712 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
713 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
717 /* If we have found a value node by following only right-hand links,
718 * then we know that there are no more values after us.
720 * Therefore, if there are more defined parameters, the caller didn't
723 if (rightmost && defParm->next)
725 werror (E_TOO_FEW_PARMS);
730 /* the parameter type must be at least castable */
731 if (compareType (defParm->type, actParm->ftype) == 0) {
732 werror (E_INCOMPAT_TYPES);
733 printFromToType (actParm->ftype, defParm->type);
737 /* if the parameter is castable then add the cast */
738 if (compareType (defParm->type, actParm->ftype) < 0)
740 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
742 /* now change the current one to a cast */
743 actParm->type = EX_OP;
744 actParm->opval.op = CAST;
745 actParm->left = newAst_LINK (defParm->type);
746 actParm->right = pTree;
747 actParm->etype = defParm->etype;
748 actParm->ftype = defParm->type;
749 actParm->decorated=0; /* force typechecking */
750 decorateType (actParm);
753 /* make a copy and change the regparm type to the defined parm */
754 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
755 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
759 /*-----------------------------------------------------------------*/
760 /* createIvalType - generates ival for basic types */
761 /*-----------------------------------------------------------------*/
763 createIvalType (ast * sym, sym_link * type, initList * ilist)
767 /* if initList is deep */
768 if (ilist->type == INIT_DEEP)
769 ilist = ilist->init.deep;
771 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
772 return decorateType (newNode ('=', sym, iExpr));
775 /*-----------------------------------------------------------------*/
776 /* createIvalStruct - generates initial value for structures */
777 /*-----------------------------------------------------------------*/
779 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
786 sflds = SPEC_STRUCT (type)->fields;
787 if (ilist->type != INIT_DEEP)
789 werror (E_INIT_STRUCT, "");
793 iloop = ilist->init.deep;
795 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
797 /* if we have come to end */
801 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
802 lAst = decorateType (resolveSymbols (lAst));
803 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
807 werror (W_EXCESS_INITIALIZERS, "struct",
808 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
815 /*-----------------------------------------------------------------*/
816 /* createIvalArray - generates code for array initialization */
817 /*-----------------------------------------------------------------*/
819 createIvalArray (ast * sym, sym_link * type, initList * ilist)
823 int lcnt = 0, size = 0;
824 literalList *literalL;
826 /* take care of the special case */
827 /* array of characters can be init */
829 if (IS_CHAR (type->next))
830 if ((rast = createIvalCharPtr (sym,
832 decorateType (resolveSymbols (list2expr (ilist))))))
834 return decorateType (resolveSymbols (rast));
836 /* not the special case */
837 if (ilist->type != INIT_DEEP)
839 werror (E_INIT_STRUCT, "");
843 iloop = ilist->init.deep;
844 lcnt = DCL_ELEM (type);
846 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
850 aSym = decorateType (resolveSymbols(sym));
852 rast = newNode(ARRAYINIT, aSym, NULL);
853 rast->values.constlist = literalL;
855 // Make sure size is set to length of initializer list.
862 if (lcnt && size > lcnt)
864 // Array size was specified, and we have more initializers than needed.
865 char *name=sym->opval.val->sym->name;
866 int lineno=sym->opval.val->sym->lineDef;
868 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
877 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
878 aSym = decorateType (resolveSymbols (aSym));
879 rast = createIval (aSym, type->next, iloop, rast);
880 iloop = (iloop ? iloop->next : NULL);
886 /* no of elements given and we */
887 /* have generated for all of them */
890 // there has to be a better way
891 char *name=sym->opval.val->sym->name;
892 int lineno=sym->opval.val->sym->lineDef;
893 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
900 /* if we have not been given a size */
901 if (!DCL_ELEM (type))
903 DCL_ELEM (type) = size;
906 return decorateType (resolveSymbols (rast));
910 /*-----------------------------------------------------------------*/
911 /* createIvalCharPtr - generates initial values for char pointers */
912 /*-----------------------------------------------------------------*/
914 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
918 /* if this is a pointer & right is a literal array then */
919 /* just assignment will do */
920 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
921 SPEC_SCLS (iexpr->etype) == S_CODE)
922 && IS_ARRAY (iexpr->ftype)))
923 return newNode ('=', sym, iexpr);
925 /* left side is an array so we have to assign each */
927 if ((IS_LITERAL (iexpr->etype) ||
928 SPEC_SCLS (iexpr->etype) == S_CODE)
929 && IS_ARRAY (iexpr->ftype))
931 /* for each character generate an assignment */
932 /* to the array element */
933 char *s = SPEC_CVAL (iexpr->etype).v_char;
938 rast = newNode (NULLOP,
942 newAst_VALUE (valueFromLit ((float) i))),
943 newAst_VALUE (valueFromLit (*s))));
947 rast = newNode (NULLOP,
951 newAst_VALUE (valueFromLit ((float) i))),
952 newAst_VALUE (valueFromLit (*s))));
953 return decorateType (resolveSymbols (rast));
959 /*-----------------------------------------------------------------*/
960 /* createIvalPtr - generates initial value for pointers */
961 /*-----------------------------------------------------------------*/
963 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
969 if (ilist->type == INIT_DEEP)
970 ilist = ilist->init.deep;
972 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
974 /* if character pointer */
975 if (IS_CHAR (type->next))
976 if ((rast = createIvalCharPtr (sym, type, iexpr)))
979 return newNode ('=', sym, iexpr);
982 /*-----------------------------------------------------------------*/
983 /* createIval - generates code for initial value */
984 /*-----------------------------------------------------------------*/
986 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
993 /* if structure then */
994 if (IS_STRUCT (type))
995 rast = createIvalStruct (sym, type, ilist);
997 /* if this is a pointer */
999 rast = createIvalPtr (sym, type, ilist);
1001 /* if this is an array */
1002 if (IS_ARRAY (type))
1003 rast = createIvalArray (sym, type, ilist);
1005 /* if type is SPECIFIER */
1007 rast = createIvalType (sym, type, ilist);
1010 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1012 return decorateType (resolveSymbols (rast));
1015 /*-----------------------------------------------------------------*/
1016 /* initAggregates - initialises aggregate variables with initv */
1017 /*-----------------------------------------------------------------*/
1018 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1019 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1022 /*-----------------------------------------------------------------*/
1023 /* gatherAutoInit - creates assignment expressions for initial */
1025 /*-----------------------------------------------------------------*/
1027 gatherAutoInit (symbol * autoChain)
1034 for (sym = autoChain; sym; sym = sym->next)
1037 /* resolve the symbols in the ival */
1039 resolveIvalSym (sym->ival);
1041 /* if this is a static variable & has an */
1042 /* initial value the code needs to be lifted */
1043 /* here to the main portion since they can be */
1044 /* initialised only once at the start */
1045 if (IS_STATIC (sym->etype) && sym->ival &&
1046 SPEC_SCLS (sym->etype) != S_CODE)
1050 /* insert the symbol into the symbol table */
1051 /* with level = 0 & name = rname */
1052 newSym = copySymbol (sym);
1053 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1055 /* now lift the code to main */
1056 if (IS_AGGREGATE (sym->type)) {
1057 work = initAggregates (sym, sym->ival, NULL);
1059 if (getNelements(sym->type, sym->ival)>1) {
1060 werror (W_EXCESS_INITIALIZERS, "scalar",
1061 sym->name, sym->lineDef);
1063 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1064 list2expr (sym->ival));
1067 setAstLineno (work, sym->lineDef);
1071 staticAutos = newNode (NULLOP, staticAutos, work);
1078 /* if there is an initial value */
1079 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1081 if (IS_AGGREGATE (sym->type)) {
1082 work = initAggregates (sym, sym->ival, NULL);
1084 if (getNelements(sym->type, sym->ival)>1) {
1085 werror (W_EXCESS_INITIALIZERS, "scalar",
1086 sym->name, sym->lineDef);
1088 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1089 list2expr (sym->ival));
1092 setAstLineno (work, sym->lineDef);
1095 init = newNode (NULLOP, init, work);
1104 /*-----------------------------------------------------------------*/
1105 /* stringToSymbol - creates a symbol from a literal string */
1106 /*-----------------------------------------------------------------*/
1108 stringToSymbol (value * val)
1110 char name[SDCC_NAME_MAX + 1];
1111 static int charLbl = 0;
1114 sprintf (name, "_str_%d", charLbl++);
1115 sym = newSymbol (name, 0); /* make it @ level 0 */
1116 strcpy (sym->rname, name);
1118 /* copy the type from the value passed */
1119 sym->type = copyLinkChain (val->type);
1120 sym->etype = getSpec (sym->type);
1121 /* change to storage class & output class */
1122 SPEC_SCLS (sym->etype) = S_CODE;
1123 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1124 SPEC_STAT (sym->etype) = 1;
1125 /* make the level & block = 0 */
1126 sym->block = sym->level = 0;
1128 /* create an ival */
1129 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1134 allocVariables (sym);
1137 return symbolVal (sym);
1141 /*-----------------------------------------------------------------*/
1142 /* processBlockVars - will go thru the ast looking for block if */
1143 /* a block is found then will allocate the syms */
1144 /* will also gather the auto inits present */
1145 /*-----------------------------------------------------------------*/
1147 processBlockVars (ast * tree, int *stack, int action)
1152 /* if this is a block */
1153 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1157 if (action == ALLOCATE)
1159 *stack += allocVariables (tree->values.sym);
1160 autoInit = gatherAutoInit (tree->values.sym);
1162 /* if there are auto inits then do them */
1164 tree->left = newNode (NULLOP, autoInit, tree->left);
1166 else /* action is deallocate */
1167 deallocLocal (tree->values.sym);
1170 processBlockVars (tree->left, stack, action);
1171 processBlockVars (tree->right, stack, action);
1175 /*-------------------------------------------------------------*/
1176 /* constExprTree - returns TRUE if this tree is a constant */
1178 /*-------------------------------------------------------------*/
1179 bool constExprTree (ast *cexpr) {
1185 cexpr = decorateType (resolveSymbols (cexpr));
1187 switch (cexpr->type)
1190 if (IS_AST_LIT_VALUE(cexpr)) {
1191 // this is a literal
1194 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1195 // a function's address will never change
1198 if (IS_AST_SYM_VALUE(cexpr) &&
1199 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1200 // a symbol in code space will never change
1201 // This is only for the 'char *s="hallo"' case and will have to leave
1206 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1207 "unexpected link in expression tree\n");
1210 if (cexpr->opval.op==ARRAYINIT) {
1211 // this is a list of literals
1214 if (cexpr->opval.op=='=') {
1215 return constExprTree(cexpr->right);
1217 if (cexpr->opval.op==CAST) {
1218 // jwk: cast ignored, maybe we should throw a warning here
1219 return constExprTree(cexpr->right);
1221 if (cexpr->opval.op=='&') {
1224 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1227 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1234 /*-----------------------------------------------------------------*/
1235 /* constExprValue - returns the value of a constant expression */
1236 /* or NULL if it is not a constant expression */
1237 /*-----------------------------------------------------------------*/
1239 constExprValue (ast * cexpr, int check)
1241 cexpr = decorateType (resolveSymbols (cexpr));
1243 /* if this is not a constant then */
1244 if (!IS_LITERAL (cexpr->ftype))
1246 /* then check if this is a literal array
1248 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1249 SPEC_CVAL (cexpr->etype).v_char &&
1250 IS_ARRAY (cexpr->ftype))
1252 value *val = valFromType (cexpr->ftype);
1253 SPEC_SCLS (val->etype) = S_LITERAL;
1254 val->sym = cexpr->opval.val->sym;
1255 val->sym->type = copyLinkChain (cexpr->ftype);
1256 val->sym->etype = getSpec (val->sym->type);
1257 strcpy (val->name, cexpr->opval.val->sym->rname);
1261 /* if we are casting a literal value then */
1262 if (IS_AST_OP (cexpr) &&
1263 cexpr->opval.op == CAST &&
1264 IS_LITERAL (cexpr->right->ftype))
1265 return valCastLiteral (cexpr->ftype,
1266 floatFromVal (cexpr->right->opval.val));
1268 if (IS_AST_VALUE (cexpr))
1269 return cexpr->opval.val;
1272 werror (E_CONST_EXPECTED, "found expression");
1277 /* return the value */
1278 return cexpr->opval.val;
1282 /*-----------------------------------------------------------------*/
1283 /* isLabelInAst - will return true if a given label is found */
1284 /*-----------------------------------------------------------------*/
1286 isLabelInAst (symbol * label, ast * tree)
1288 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1291 if (IS_AST_OP (tree) &&
1292 tree->opval.op == LABEL &&
1293 isSymbolEqual (AST_SYMBOL (tree->left), label))
1296 return isLabelInAst (label, tree->right) &&
1297 isLabelInAst (label, tree->left);
1301 /*-----------------------------------------------------------------*/
1302 /* isLoopCountable - return true if the loop count can be determi- */
1303 /* -ned at compile time . */
1304 /*-----------------------------------------------------------------*/
1306 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1307 symbol ** sym, ast ** init, ast ** end)
1310 /* the loop is considered countable if the following
1311 conditions are true :-
1313 a) initExpr :- <sym> = <const>
1314 b) condExpr :- <sym> < <const1>
1315 c) loopExpr :- <sym> ++
1318 /* first check the initExpr */
1319 if (IS_AST_OP (initExpr) &&
1320 initExpr->opval.op == '=' && /* is assignment */
1321 IS_AST_SYM_VALUE (initExpr->left))
1322 { /* left is a symbol */
1324 *sym = AST_SYMBOL (initExpr->left);
1325 *init = initExpr->right;
1330 /* for now the symbol has to be of
1332 if (!IS_INTEGRAL ((*sym)->type))
1335 /* now check condExpr */
1336 if (IS_AST_OP (condExpr))
1339 switch (condExpr->opval.op)
1342 if (IS_AST_SYM_VALUE (condExpr->left) &&
1343 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1344 IS_AST_LIT_VALUE (condExpr->right))
1346 *end = condExpr->right;
1352 if (IS_AST_OP (condExpr->left) &&
1353 condExpr->left->opval.op == '>' &&
1354 IS_AST_LIT_VALUE (condExpr->left->right) &&
1355 IS_AST_SYM_VALUE (condExpr->left->left) &&
1356 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1359 *end = newNode ('+', condExpr->left->right,
1360 newAst_VALUE (constVal ("1")));
1371 /* check loop expression is of the form <sym>++ */
1372 if (!IS_AST_OP (loopExpr))
1375 /* check if <sym> ++ */
1376 if (loopExpr->opval.op == INC_OP)
1382 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1383 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1390 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1391 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1399 if (loopExpr->opval.op == ADD_ASSIGN)
1402 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1403 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1404 IS_AST_LIT_VALUE (loopExpr->right) &&
1405 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1413 /*-----------------------------------------------------------------*/
1414 /* astHasVolatile - returns true if ast contains any volatile */
1415 /*-----------------------------------------------------------------*/
1417 astHasVolatile (ast * tree)
1422 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1425 if (IS_AST_OP (tree))
1426 return astHasVolatile (tree->left) ||
1427 astHasVolatile (tree->right);
1432 /*-----------------------------------------------------------------*/
1433 /* astHasPointer - return true if the ast contains any ptr variable */
1434 /*-----------------------------------------------------------------*/
1436 astHasPointer (ast * tree)
1441 if (IS_AST_LINK (tree))
1444 /* if we hit an array expression then check
1445 only the left side */
1446 if (IS_AST_OP (tree) && tree->opval.op == '[')
1447 return astHasPointer (tree->left);
1449 if (IS_AST_VALUE (tree))
1450 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1452 return astHasPointer (tree->left) ||
1453 astHasPointer (tree->right);
1457 /*-----------------------------------------------------------------*/
1458 /* astHasSymbol - return true if the ast has the given symbol */
1459 /*-----------------------------------------------------------------*/
1461 astHasSymbol (ast * tree, symbol * sym)
1463 if (!tree || IS_AST_LINK (tree))
1466 if (IS_AST_VALUE (tree))
1468 if (IS_AST_SYM_VALUE (tree))
1469 return isSymbolEqual (AST_SYMBOL (tree), sym);
1474 return astHasSymbol (tree->left, sym) ||
1475 astHasSymbol (tree->right, sym);
1478 /*-----------------------------------------------------------------*/
1479 /* astHasDeref - return true if the ast has an indirect access */
1480 /*-----------------------------------------------------------------*/
1482 astHasDeref (ast * tree)
1484 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1487 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1489 return astHasDeref (tree->left) || astHasDeref (tree->right);
1492 /*-----------------------------------------------------------------*/
1493 /* isConformingBody - the loop body has to conform to a set of rules */
1494 /* for the loop to be considered reversible read on for rules */
1495 /*-----------------------------------------------------------------*/
1497 isConformingBody (ast * pbody, symbol * sym, ast * body)
1500 /* we are going to do a pre-order traversal of the
1501 tree && check for the following conditions. (essentially
1502 a set of very shallow tests )
1503 a) the sym passed does not participate in
1504 any arithmetic operation
1505 b) There are no function calls
1506 c) all jumps are within the body
1507 d) address of loop control variable not taken
1508 e) if an assignment has a pointer on the
1509 left hand side make sure right does not have
1510 loop control variable */
1512 /* if we reach the end or a leaf then true */
1513 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1517 /* if anything else is "volatile" */
1518 if (IS_VOLATILE (TETYPE (pbody)))
1521 /* we will walk the body in a pre-order traversal for
1523 switch (pbody->opval.op)
1525 /*------------------------------------------------------------------*/
1527 return isConformingBody (pbody->right, sym, body);
1529 /*------------------------------------------------------------------*/
1534 /*------------------------------------------------------------------*/
1535 case INC_OP: /* incerement operator unary so left only */
1538 /* sure we are not sym is not modified */
1540 IS_AST_SYM_VALUE (pbody->left) &&
1541 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1545 IS_AST_SYM_VALUE (pbody->right) &&
1546 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1551 /*------------------------------------------------------------------*/
1553 case '*': /* can be unary : if right is null then unary operation */
1558 /* if right is NULL then unary operation */
1559 /*------------------------------------------------------------------*/
1560 /*----------------------------*/
1562 /*----------------------------*/
1565 if (IS_AST_SYM_VALUE (pbody->left) &&
1566 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1569 return isConformingBody (pbody->left, sym, body);
1573 if (astHasSymbol (pbody->left, sym) ||
1574 astHasSymbol (pbody->right, sym))
1579 /*------------------------------------------------------------------*/
1587 if (IS_AST_SYM_VALUE (pbody->left) &&
1588 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1591 if (IS_AST_SYM_VALUE (pbody->right) &&
1592 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1595 return isConformingBody (pbody->left, sym, body) &&
1596 isConformingBody (pbody->right, sym, body);
1603 if (IS_AST_SYM_VALUE (pbody->left) &&
1604 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1606 return isConformingBody (pbody->left, sym, body);
1608 /*------------------------------------------------------------------*/
1620 case SIZEOF: /* evaluate wihout code generation */
1622 return isConformingBody (pbody->left, sym, body) &&
1623 isConformingBody (pbody->right, sym, body);
1625 /*------------------------------------------------------------------*/
1628 /* if left has a pointer & right has loop
1629 control variable then we cannot */
1630 if (astHasPointer (pbody->left) &&
1631 astHasSymbol (pbody->right, sym))
1633 if (astHasVolatile (pbody->left))
1636 if (IS_AST_SYM_VALUE (pbody->left)) {
1637 // if the loopvar has an assignment
1638 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1640 // if the loopvar is used in another (maybe conditional) block
1641 if (astHasSymbol (pbody->right, sym) &&
1642 (pbody->level > body->level)) {
1647 if (astHasVolatile (pbody->left))
1650 if (astHasDeref(pbody->right)) return FALSE;
1652 return isConformingBody (pbody->left, sym, body) &&
1653 isConformingBody (pbody->right, sym, body);
1664 assert ("Parser should not have generated this\n");
1666 /*------------------------------------------------------------------*/
1667 /*----------------------------*/
1668 /* comma operator */
1669 /*----------------------------*/
1671 return isConformingBody (pbody->left, sym, body) &&
1672 isConformingBody (pbody->right, sym, body);
1674 /*------------------------------------------------------------------*/
1675 /*----------------------------*/
1677 /*----------------------------*/
1679 /* if local & not passed as paramater then ok */
1680 if (sym->level && !astHasSymbol(pbody->right,sym))
1684 /*------------------------------------------------------------------*/
1685 /*----------------------------*/
1686 /* return statement */
1687 /*----------------------------*/
1692 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1697 if (astHasSymbol (pbody->left, sym))
1704 return isConformingBody (pbody->left, sym, body) &&
1705 isConformingBody (pbody->right, sym, body);
1711 /*-----------------------------------------------------------------*/
1712 /* isLoopReversible - takes a for loop as input && returns true */
1713 /* if the for loop is reversible. If yes will set the value of */
1714 /* the loop control var & init value & termination value */
1715 /*-----------------------------------------------------------------*/
1717 isLoopReversible (ast * loop, symbol ** loopCntrl,
1718 ast ** init, ast ** end)
1720 /* if option says don't do it then don't */
1721 if (optimize.noLoopReverse)
1723 /* there are several tests to determine this */
1725 /* for loop has to be of the form
1726 for ( <sym> = <const1> ;
1727 [<sym> < <const2>] ;
1728 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1730 if (!isLoopCountable (AST_FOR (loop, initExpr),
1731 AST_FOR (loop, condExpr),
1732 AST_FOR (loop, loopExpr),
1733 loopCntrl, init, end))
1736 /* now do some serious checking on the body of the loop
1739 return isConformingBody (loop->left, *loopCntrl, loop->left);
1743 /*-----------------------------------------------------------------*/
1744 /* replLoopSym - replace the loop sym by loop sym -1 */
1745 /*-----------------------------------------------------------------*/
1747 replLoopSym (ast * body, symbol * sym)
1750 if (!body || IS_AST_LINK (body))
1753 if (IS_AST_SYM_VALUE (body))
1756 if (isSymbolEqual (AST_SYMBOL (body), sym))
1760 body->opval.op = '-';
1761 body->left = newAst_VALUE (symbolVal (sym));
1762 body->right = newAst_VALUE (constVal ("1"));
1770 replLoopSym (body->left, sym);
1771 replLoopSym (body->right, sym);
1775 /*-----------------------------------------------------------------*/
1776 /* reverseLoop - do the actual loop reversal */
1777 /*-----------------------------------------------------------------*/
1779 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1783 /* create the following tree
1788 if (sym) goto for_continue ;
1791 /* put it together piece by piece */
1792 rloop = newNode (NULLOP,
1793 createIf (newAst_VALUE (symbolVal (sym)),
1795 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1798 newAst_VALUE (symbolVal (sym)),
1801 replLoopSym (loop->left, sym);
1803 rloop = newNode (NULLOP,
1805 newAst_VALUE (symbolVal (sym)),
1806 newNode ('-', end, init)),
1807 createLabel (AST_FOR (loop, continueLabel),
1811 newNode (SUB_ASSIGN,
1812 newAst_VALUE (symbolVal (sym)),
1813 newAst_VALUE (constVal ("1"))),
1816 return decorateType (rloop);
1820 /*-----------------------------------------------------------------*/
1821 /* decorateType - compute type for this tree also does type cheking */
1822 /* this is done bottom up, since type have to flow upwards */
1823 /* it also does constant folding, and paramater checking */
1824 /*-----------------------------------------------------------------*/
1826 decorateType (ast * tree)
1834 /* if already has type then do nothing */
1835 if (tree->decorated)
1838 tree->decorated = 1;
1840 /* print the line */
1841 /* if not block & function */
1842 if (tree->type == EX_OP &&
1843 (tree->opval.op != FUNCTION &&
1844 tree->opval.op != BLOCK &&
1845 tree->opval.op != NULLOP))
1847 filename = tree->filename;
1848 lineno = tree->lineno;
1851 /* if any child is an error | this one is an error do nothing */
1852 if (tree->isError ||
1853 (tree->left && tree->left->isError) ||
1854 (tree->right && tree->right->isError))
1857 /*------------------------------------------------------------------*/
1858 /*----------------------------*/
1859 /* leaf has been reached */
1860 /*----------------------------*/
1861 /* if this is of type value */
1862 /* just get the type */
1863 if (tree->type == EX_VALUE)
1866 if (IS_LITERAL (tree->opval.val->etype))
1869 /* if this is a character array then declare it */
1870 if (IS_ARRAY (tree->opval.val->type))
1871 tree->opval.val = stringToSymbol (tree->opval.val);
1873 /* otherwise just copy the type information */
1874 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1878 if (tree->opval.val->sym)
1880 /* if the undefined flag is set then give error message */
1881 if (tree->opval.val->sym->undefined)
1883 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1885 TTYPE (tree) = TETYPE (tree) =
1886 tree->opval.val->type = tree->opval.val->sym->type =
1887 tree->opval.val->etype = tree->opval.val->sym->etype =
1888 copyLinkChain (INTTYPE);
1893 /* if impilicit i.e. struct/union member then no type */
1894 if (tree->opval.val->sym->implicit)
1895 TTYPE (tree) = TETYPE (tree) = NULL;
1900 /* else copy the type */
1901 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1903 /* and mark it as referenced */
1904 tree->opval.val->sym->isref = 1;
1912 /* if type link for the case of cast */
1913 if (tree->type == EX_LINK)
1915 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1922 dtl = decorateType (tree->left);
1923 /* delay right side for '?' operator since conditional macro expansions might
1925 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1927 /* this is to take care of situations
1928 when the tree gets rewritten */
1929 if (dtl != tree->left)
1931 if (dtr != tree->right)
1935 /* depending on type of operator do */
1937 switch (tree->opval.op)
1939 /*------------------------------------------------------------------*/
1940 /*----------------------------*/
1942 /*----------------------------*/
1945 /* determine which is the array & which the index */
1946 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1949 ast *tempTree = tree->left;
1950 tree->left = tree->right;
1951 tree->right = tempTree;
1954 /* first check if this is a array or a pointer */
1955 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1957 werror (E_NEED_ARRAY_PTR, "[]");
1958 goto errorTreeReturn;
1961 /* check if the type of the idx */
1962 if (!IS_INTEGRAL (RTYPE (tree)))
1964 werror (E_IDX_NOT_INT);
1965 goto errorTreeReturn;
1968 /* if the left is an rvalue then error */
1971 werror (E_LVALUE_REQUIRED, "array access");
1972 goto errorTreeReturn;
1975 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1976 if (IS_PTR(LTYPE(tree))) {
1977 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1981 /*------------------------------------------------------------------*/
1982 /*----------------------------*/
1984 /*----------------------------*/
1986 /* if this is not a structure */
1987 if (!IS_STRUCT (LTYPE (tree)))
1989 werror (E_STRUCT_UNION, ".");
1990 goto errorTreeReturn;
1992 TTYPE (tree) = structElemType (LTYPE (tree),
1993 (tree->right->type == EX_VALUE ?
1994 tree->right->opval.val : NULL));
1995 TETYPE (tree) = getSpec (TTYPE (tree));
1998 /*------------------------------------------------------------------*/
1999 /*----------------------------*/
2000 /* struct/union pointer */
2001 /*----------------------------*/
2003 /* if not pointer to a structure */
2004 if (!IS_PTR (LTYPE (tree)))
2006 werror (E_PTR_REQD);
2007 goto errorTreeReturn;
2010 if (!IS_STRUCT (LTYPE (tree)->next))
2012 werror (E_STRUCT_UNION, "->");
2013 goto errorTreeReturn;
2016 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2017 (tree->right->type == EX_VALUE ?
2018 tree->right->opval.val : NULL));
2019 TETYPE (tree) = getSpec (TTYPE (tree));
2021 /* adjust the storage class */
2022 switch (DCL_TYPE(tree->left->ftype)) {
2026 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2029 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2034 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2037 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2040 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2049 /*------------------------------------------------------------------*/
2050 /*----------------------------*/
2051 /* ++/-- operation */
2052 /*----------------------------*/
2053 case INC_OP: /* incerement operator unary so left only */
2056 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2057 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2058 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2059 werror (E_CODE_WRITE, "++/--");
2068 /*------------------------------------------------------------------*/
2069 /*----------------------------*/
2071 /*----------------------------*/
2072 case '&': /* can be unary */
2073 /* if right is NULL then unary operation */
2074 if (tree->right) /* not an unary operation */
2077 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2079 werror (E_BITWISE_OP);
2080 werror (W_CONTINUE, "left & right types are ");
2081 printTypeChain (LTYPE (tree), stderr);
2082 fprintf (stderr, ",");
2083 printTypeChain (RTYPE (tree), stderr);
2084 fprintf (stderr, "\n");
2085 goto errorTreeReturn;
2088 /* if they are both literal */
2089 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2091 tree->type = EX_VALUE;
2092 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2093 valFromType (RETYPE (tree)), '&');
2095 tree->right = tree->left = NULL;
2096 TETYPE (tree) = tree->opval.val->etype;
2097 TTYPE (tree) = tree->opval.val->type;
2101 /* see if this is a GETHBIT operation if yes
2104 ast *otree = optimizeGetHbit (tree);
2107 return decorateType (otree);
2111 computeType (LTYPE (tree), RTYPE (tree));
2112 TETYPE (tree) = getSpec (TTYPE (tree));
2114 LRVAL (tree) = RRVAL (tree) = 1;
2118 /*------------------------------------------------------------------*/
2119 /*----------------------------*/
2121 /*----------------------------*/
2123 p->class = DECLARATOR;
2124 /* if bit field then error */
2125 if (IS_BITVAR (tree->left->etype))
2127 werror (E_ILLEGAL_ADDR, "address of bit variable");
2128 goto errorTreeReturn;
2131 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2133 werror (E_ILLEGAL_ADDR, "address of register variable");
2134 goto errorTreeReturn;
2137 if (IS_FUNC (LTYPE (tree)))
2139 werror (E_ILLEGAL_ADDR, "address of function");
2140 goto errorTreeReturn;
2143 if (IS_LITERAL(LTYPE(tree)))
2145 werror (E_ILLEGAL_ADDR, "address of literal");
2146 goto errorTreeReturn;
2151 werror (E_LVALUE_REQUIRED, "address of");
2152 goto errorTreeReturn;
2154 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2156 DCL_TYPE (p) = CPOINTER;
2157 DCL_PTR_CONST (p) = port->mem.code_ro;
2159 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2160 DCL_TYPE (p) = FPOINTER;
2161 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2162 DCL_TYPE (p) = PPOINTER;
2163 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2164 DCL_TYPE (p) = IPOINTER;
2165 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2166 DCL_TYPE (p) = EEPPOINTER;
2167 else if (SPEC_OCLS(tree->left->etype))
2168 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2170 DCL_TYPE (p) = POINTER;
2172 if (IS_AST_SYM_VALUE (tree->left))
2174 AST_SYMBOL (tree->left)->addrtaken = 1;
2175 AST_SYMBOL (tree->left)->allocreq = 1;
2178 p->next = LTYPE (tree);
2180 TETYPE (tree) = getSpec (TTYPE (tree));
2181 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2182 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2187 /*------------------------------------------------------------------*/
2188 /*----------------------------*/
2190 /*----------------------------*/
2192 /* if the rewrite succeeds then don't go any furthur */
2194 ast *wtree = optimizeRRCRLC (tree);
2196 return decorateType (wtree);
2198 /*------------------------------------------------------------------*/
2199 /*----------------------------*/
2201 /*----------------------------*/
2203 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2205 werror (E_BITWISE_OP);
2206 werror (W_CONTINUE, "left & right types are ");
2207 printTypeChain (LTYPE (tree), stderr);
2208 fprintf (stderr, ",");
2209 printTypeChain (RTYPE (tree), stderr);
2210 fprintf (stderr, "\n");
2211 goto errorTreeReturn;
2214 /* if they are both literal then */
2215 /* rewrite the tree */
2216 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2218 tree->type = EX_VALUE;
2219 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2220 valFromType (RETYPE (tree)),
2222 tree->right = tree->left = NULL;
2223 TETYPE (tree) = tree->opval.val->etype;
2224 TTYPE (tree) = tree->opval.val->type;
2227 LRVAL (tree) = RRVAL (tree) = 1;
2228 TETYPE (tree) = getSpec (TTYPE (tree) =
2229 computeType (LTYPE (tree),
2232 /*------------------------------------------------------------------*/
2233 /*----------------------------*/
2235 /*----------------------------*/
2237 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2239 werror (E_INVALID_OP, "divide");
2240 goto errorTreeReturn;
2242 /* if they are both literal then */
2243 /* rewrite the tree */
2244 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2246 tree->type = EX_VALUE;
2247 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2248 valFromType (RETYPE (tree)));
2249 tree->right = tree->left = NULL;
2250 TETYPE (tree) = getSpec (TTYPE (tree) =
2251 tree->opval.val->type);
2254 LRVAL (tree) = RRVAL (tree) = 1;
2255 TETYPE (tree) = getSpec (TTYPE (tree) =
2256 computeType (LTYPE (tree),
2260 /*------------------------------------------------------------------*/
2261 /*----------------------------*/
2263 /*----------------------------*/
2265 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2267 werror (E_BITWISE_OP);
2268 werror (W_CONTINUE, "left & right types are ");
2269 printTypeChain (LTYPE (tree), stderr);
2270 fprintf (stderr, ",");
2271 printTypeChain (RTYPE (tree), stderr);
2272 fprintf (stderr, "\n");
2273 goto errorTreeReturn;
2275 /* if they are both literal then */
2276 /* rewrite the tree */
2277 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2279 tree->type = EX_VALUE;
2280 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2281 valFromType (RETYPE (tree)));
2282 tree->right = tree->left = NULL;
2283 TETYPE (tree) = getSpec (TTYPE (tree) =
2284 tree->opval.val->type);
2287 LRVAL (tree) = RRVAL (tree) = 1;
2288 TETYPE (tree) = getSpec (TTYPE (tree) =
2289 computeType (LTYPE (tree),
2293 /*------------------------------------------------------------------*/
2294 /*----------------------------*/
2295 /* address dereference */
2296 /*----------------------------*/
2297 case '*': /* can be unary : if right is null then unary operation */
2300 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2302 werror (E_PTR_REQD);
2303 goto errorTreeReturn;
2308 werror (E_LVALUE_REQUIRED, "pointer deref");
2309 goto errorTreeReturn;
2311 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2312 LTYPE (tree)->next : NULL);
2313 TETYPE (tree) = getSpec (TTYPE (tree));
2314 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2318 /*------------------------------------------------------------------*/
2319 /*----------------------------*/
2320 /* multiplication */
2321 /*----------------------------*/
2322 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2324 werror (E_INVALID_OP, "multiplication");
2325 goto errorTreeReturn;
2328 /* if they are both literal then */
2329 /* rewrite the tree */
2330 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2332 tree->type = EX_VALUE;
2333 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2334 valFromType (RETYPE (tree)));
2335 tree->right = tree->left = NULL;
2336 TETYPE (tree) = getSpec (TTYPE (tree) =
2337 tree->opval.val->type);
2341 /* if left is a literal exchange left & right */
2342 if (IS_LITERAL (LTYPE (tree)))
2344 ast *tTree = tree->left;
2345 tree->left = tree->right;
2346 tree->right = tTree;
2349 LRVAL (tree) = RRVAL (tree) = 1;
2350 /* promote result to int if left & right are char
2351 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2352 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2353 TETYPE (tree) = getSpec (TTYPE (tree) =
2354 computeType (LTYPE (tree),
2356 SPEC_NOUN(TETYPE(tree)) = V_INT;
2358 TETYPE (tree) = getSpec (TTYPE (tree) =
2359 computeType (LTYPE (tree),
2364 /*------------------------------------------------------------------*/
2365 /*----------------------------*/
2366 /* unary '+' operator */
2367 /*----------------------------*/
2372 if (!IS_INTEGRAL (LTYPE (tree)))
2374 werror (E_UNARY_OP, '+');
2375 goto errorTreeReturn;
2378 /* if left is a literal then do it */
2379 if (IS_LITERAL (LTYPE (tree)))
2381 tree->type = EX_VALUE;
2382 tree->opval.val = valFromType (LETYPE (tree));
2384 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2388 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2395 /*----------------------------*/
2397 /* this is not a unary operation */
2398 /* if both pointers then problem */
2399 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2400 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2402 werror (E_PTR_PLUS_PTR);
2403 goto errorTreeReturn;
2406 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2407 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2409 werror (E_PLUS_INVALID, "+");
2410 goto errorTreeReturn;
2413 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2414 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2416 werror (E_PLUS_INVALID, "+");
2417 goto errorTreeReturn;
2419 /* if they are both literal then */
2420 /* rewrite the tree */
2421 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2423 tree->type = EX_VALUE;
2424 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2425 valFromType (RETYPE (tree)));
2426 tree->right = tree->left = NULL;
2427 TETYPE (tree) = getSpec (TTYPE (tree) =
2428 tree->opval.val->type);
2432 /* if the right is a pointer or left is a literal
2433 xchange left & right */
2434 if (IS_ARRAY (RTYPE (tree)) ||
2435 IS_PTR (RTYPE (tree)) ||
2436 IS_LITERAL (LTYPE (tree)))
2438 ast *tTree = tree->left;
2439 tree->left = tree->right;
2440 tree->right = tTree;
2443 LRVAL (tree) = RRVAL (tree) = 1;
2444 /* if the left is a pointer */
2445 if (IS_PTR (LTYPE (tree)))
2446 TETYPE (tree) = getSpec (TTYPE (tree) =
2449 TETYPE (tree) = getSpec (TTYPE (tree) =
2450 computeType (LTYPE (tree),
2454 /*------------------------------------------------------------------*/
2455 /*----------------------------*/
2457 /*----------------------------*/
2458 case '-': /* can be unary */
2459 /* if right is null then unary */
2463 if (!IS_ARITHMETIC (LTYPE (tree)))
2465 werror (E_UNARY_OP, tree->opval.op);
2466 goto errorTreeReturn;
2469 /* if left is a literal then do it */
2470 if (IS_LITERAL (LTYPE (tree)))
2472 tree->type = EX_VALUE;
2473 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2475 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2476 SPEC_USIGN(TETYPE(tree)) = 0;
2480 TTYPE (tree) = LTYPE (tree);
2484 /*------------------------------------------------------------------*/
2485 /*----------------------------*/
2487 /*----------------------------*/
2489 if (!(IS_PTR (LTYPE (tree)) ||
2490 IS_ARRAY (LTYPE (tree)) ||
2491 IS_ARITHMETIC (LTYPE (tree))))
2493 werror (E_PLUS_INVALID, "-");
2494 goto errorTreeReturn;
2497 if (!(IS_PTR (RTYPE (tree)) ||
2498 IS_ARRAY (RTYPE (tree)) ||
2499 IS_ARITHMETIC (RTYPE (tree))))
2501 werror (E_PLUS_INVALID, "-");
2502 goto errorTreeReturn;
2505 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2506 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2507 IS_INTEGRAL (RTYPE (tree))))
2509 werror (E_PLUS_INVALID, "-");
2510 goto errorTreeReturn;
2513 /* if they are both literal then */
2514 /* rewrite the tree */
2515 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2517 tree->type = EX_VALUE;
2518 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2519 valFromType (RETYPE (tree)));
2520 tree->right = tree->left = NULL;
2521 TETYPE (tree) = getSpec (TTYPE (tree) =
2522 tree->opval.val->type);
2526 /* if the left & right are equal then zero */
2527 if (isAstEqual (tree->left, tree->right))
2529 tree->type = EX_VALUE;
2530 tree->left = tree->right = NULL;
2531 tree->opval.val = constVal ("0");
2532 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2536 /* if both of them are pointers or arrays then */
2537 /* the result is going to be an integer */
2538 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2539 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2540 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2542 /* if only the left is a pointer */
2543 /* then result is a pointer */
2544 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2545 TETYPE (tree) = getSpec (TTYPE (tree) =
2548 TETYPE (tree) = getSpec (TTYPE (tree) =
2549 computeType (LTYPE (tree),
2551 LRVAL (tree) = RRVAL (tree) = 1;
2554 /*------------------------------------------------------------------*/
2555 /*----------------------------*/
2557 /*----------------------------*/
2559 /* can be only integral type */
2560 if (!IS_INTEGRAL (LTYPE (tree)))
2562 werror (E_UNARY_OP, tree->opval.op);
2563 goto errorTreeReturn;
2566 /* if left is a literal then do it */
2567 if (IS_LITERAL (LTYPE (tree)))
2569 tree->type = EX_VALUE;
2570 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2572 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2576 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2579 /*------------------------------------------------------------------*/
2580 /*----------------------------*/
2582 /*----------------------------*/
2584 /* can be pointer */
2585 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2586 !IS_PTR (LTYPE (tree)) &&
2587 !IS_ARRAY (LTYPE (tree)))
2589 werror (E_UNARY_OP, tree->opval.op);
2590 goto errorTreeReturn;
2593 /* if left is a literal then do it */
2594 if (IS_LITERAL (LTYPE (tree)))
2596 tree->type = EX_VALUE;
2597 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2599 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2603 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2606 /*------------------------------------------------------------------*/
2607 /*----------------------------*/
2609 /*----------------------------*/
2612 TTYPE (tree) = LTYPE (tree);
2613 TETYPE (tree) = LETYPE (tree);
2617 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2622 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2624 werror (E_SHIFT_OP_INVALID);
2625 werror (W_CONTINUE, "left & right types are ");
2626 printTypeChain (LTYPE (tree), stderr);
2627 fprintf (stderr, ",");
2628 printTypeChain (RTYPE (tree), stderr);
2629 fprintf (stderr, "\n");
2630 goto errorTreeReturn;
2633 /* if they are both literal then */
2634 /* rewrite the tree */
2635 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2637 tree->type = EX_VALUE;
2638 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2639 valFromType (RETYPE (tree)),
2640 (tree->opval.op == LEFT_OP ? 1 : 0));
2641 tree->right = tree->left = NULL;
2642 TETYPE (tree) = getSpec (TTYPE (tree) =
2643 tree->opval.val->type);
2646 /* if only the right side is a literal & we are
2647 shifting more than size of the left operand then zero */
2648 if (IS_LITERAL (RTYPE (tree)) &&
2649 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2650 (getSize (LTYPE (tree)) * 8))
2652 werror (W_SHIFT_CHANGED,
2653 (tree->opval.op == LEFT_OP ? "left" : "right"));
2654 tree->type = EX_VALUE;
2655 tree->left = tree->right = NULL;
2656 tree->opval.val = constVal ("0");
2657 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2660 LRVAL (tree) = RRVAL (tree) = 1;
2661 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2663 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2667 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2671 /*------------------------------------------------------------------*/
2672 /*----------------------------*/
2674 /*----------------------------*/
2675 case CAST: /* change the type */
2676 /* cannot cast to an aggregate type */
2677 if (IS_AGGREGATE (LTYPE (tree)))
2679 werror (E_CAST_ILLEGAL);
2680 goto errorTreeReturn;
2683 /* make sure the type is complete and sane */
2684 checkTypeSanity(LETYPE(tree), "(cast)");
2687 /* if the right is a literal replace the tree */
2688 if (IS_LITERAL (RETYPE (tree))) {
2689 if (!IS_PTR (LTYPE (tree))) {
2690 tree->type = EX_VALUE;
2692 valCastLiteral (LTYPE (tree),
2693 floatFromVal (valFromType (RETYPE (tree))));
2696 TTYPE (tree) = tree->opval.val->type;
2697 tree->values.literalFromCast = 1;
2698 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2699 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2700 sym_link *rest = LTYPE(tree)->next;
2701 werror(W_LITERAL_GENERIC);
2702 TTYPE(tree) = newLink();
2703 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2704 TTYPE(tree)->next = rest;
2705 tree->left->opval.lnk = TTYPE(tree);
2708 TTYPE (tree) = LTYPE (tree);
2712 TTYPE (tree) = LTYPE (tree);
2716 /* if pointer to struct then check names */
2717 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2718 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2719 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2720 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2722 /* if the right is a literal replace the tree */
2723 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2724 tree->type = EX_VALUE;
2726 valCastLiteral (LTYPE (tree),
2727 floatFromVal (valFromType (RETYPE (tree))));
2730 TTYPE (tree) = tree->opval.val->type;
2731 tree->values.literalFromCast = 1;
2733 TTYPE (tree) = LTYPE (tree);
2737 TETYPE (tree) = getSpec (TTYPE (tree));
2741 /*------------------------------------------------------------------*/
2742 /*----------------------------*/
2743 /* logical &&, || */
2744 /*----------------------------*/
2747 /* each must me arithmetic type or be a pointer */
2748 if (!IS_PTR (LTYPE (tree)) &&
2749 !IS_ARRAY (LTYPE (tree)) &&
2750 !IS_INTEGRAL (LTYPE (tree)))
2752 werror (E_COMPARE_OP);
2753 goto errorTreeReturn;
2756 if (!IS_PTR (RTYPE (tree)) &&
2757 !IS_ARRAY (RTYPE (tree)) &&
2758 !IS_INTEGRAL (RTYPE (tree)))
2760 werror (E_COMPARE_OP);
2761 goto errorTreeReturn;
2763 /* if they are both literal then */
2764 /* rewrite the tree */
2765 if (IS_LITERAL (RTYPE (tree)) &&
2766 IS_LITERAL (LTYPE (tree)))
2768 tree->type = EX_VALUE;
2769 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2770 valFromType (RETYPE (tree)),
2772 tree->right = tree->left = NULL;
2773 TETYPE (tree) = getSpec (TTYPE (tree) =
2774 tree->opval.val->type);
2777 LRVAL (tree) = RRVAL (tree) = 1;
2778 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2781 /*------------------------------------------------------------------*/
2782 /*----------------------------*/
2783 /* comparison operators */
2784 /*----------------------------*/
2792 ast *lt = optimizeCompare (tree);
2798 /* if they are pointers they must be castable */
2799 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2801 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2803 werror (E_COMPARE_OP);
2804 fprintf (stderr, "comparing type ");
2805 printTypeChain (LTYPE (tree), stderr);
2806 fprintf (stderr, "to type ");
2807 printTypeChain (RTYPE (tree), stderr);
2808 fprintf (stderr, "\n");
2809 goto errorTreeReturn;
2812 /* else they should be promotable to one another */
2815 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2816 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2818 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2820 werror (E_COMPARE_OP);
2821 fprintf (stderr, "comparing type ");
2822 printTypeChain (LTYPE (tree), stderr);
2823 fprintf (stderr, "to type ");
2824 printTypeChain (RTYPE (tree), stderr);
2825 fprintf (stderr, "\n");
2826 goto errorTreeReturn;
2829 /* if unsigned value < 0 then always false */
2830 /* if (unsigned value) > 0 then (unsigned value) */
2831 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2832 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2834 if (tree->opval.op == '<') {
2837 if (tree->opval.op == '>') {
2841 /* if they are both literal then */
2842 /* rewrite the tree */
2843 if (IS_LITERAL (RTYPE (tree)) &&
2844 IS_LITERAL (LTYPE (tree)))
2846 tree->type = EX_VALUE;
2847 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2848 valFromType (RETYPE (tree)),
2850 tree->right = tree->left = NULL;
2851 TETYPE (tree) = getSpec (TTYPE (tree) =
2852 tree->opval.val->type);
2855 LRVAL (tree) = RRVAL (tree) = 1;
2856 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2859 /*------------------------------------------------------------------*/
2860 /*----------------------------*/
2862 /*----------------------------*/
2863 case SIZEOF: /* evaluate wihout code generation */
2864 /* change the type to a integer */
2865 tree->type = EX_VALUE;
2866 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2867 tree->opval.val = constVal (buffer);
2868 tree->right = tree->left = NULL;
2869 TETYPE (tree) = getSpec (TTYPE (tree) =
2870 tree->opval.val->type);
2873 /*------------------------------------------------------------------*/
2874 /*----------------------------*/
2876 /*----------------------------*/
2878 /* return typeof enum value */
2879 tree->type = EX_VALUE;
2882 if (IS_SPEC(tree->right->ftype)) {
2883 switch (SPEC_NOUN(tree->right->ftype)) {
2885 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2886 else typeofv = TYPEOF_INT;
2889 typeofv = TYPEOF_FLOAT;
2892 typeofv = TYPEOF_CHAR;
2895 typeofv = TYPEOF_VOID;
2898 typeofv = TYPEOF_STRUCT;
2901 typeofv = TYPEOF_BIT;
2904 typeofv = TYPEOF_SBIT;
2910 switch (DCL_TYPE(tree->right->ftype)) {
2912 typeofv = TYPEOF_POINTER;
2915 typeofv = TYPEOF_FPOINTER;
2918 typeofv = TYPEOF_CPOINTER;
2921 typeofv = TYPEOF_GPOINTER;
2924 typeofv = TYPEOF_PPOINTER;
2927 typeofv = TYPEOF_IPOINTER;
2930 typeofv = TYPEOF_ARRAY;
2933 typeofv = TYPEOF_FUNCTION;
2939 sprintf (buffer, "%d", typeofv);
2940 tree->opval.val = constVal (buffer);
2941 tree->right = tree->left = NULL;
2942 TETYPE (tree) = getSpec (TTYPE (tree) =
2943 tree->opval.val->type);
2946 /*------------------------------------------------------------------*/
2947 /*----------------------------*/
2948 /* conditional operator '?' */
2949 /*----------------------------*/
2951 /* the type is value of the colon operator (on the right) */
2952 assert(IS_COLON_OP(tree->right));
2953 /* if already known then replace the tree : optimizer will do it
2954 but faster to do it here */
2955 if (IS_LITERAL (LTYPE(tree))) {
2956 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2957 return decorateType(tree->right->left) ;
2959 return decorateType(tree->right->right) ;
2962 tree->right = decorateType(tree->right);
2963 TTYPE (tree) = RTYPE(tree);
2964 TETYPE (tree) = getSpec (TTYPE (tree));
2969 /* if they don't match we have a problem */
2970 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2972 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2973 goto errorTreeReturn;
2976 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2977 TETYPE (tree) = getSpec (TTYPE (tree));
2981 #if 0 // assignment operators are converted by the parser
2982 /*------------------------------------------------------------------*/
2983 /*----------------------------*/
2984 /* assignment operators */
2985 /*----------------------------*/
2988 /* for these it must be both must be integral */
2989 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2990 !IS_ARITHMETIC (RTYPE (tree)))
2992 werror (E_OPS_INTEGRAL);
2993 goto errorTreeReturn;
2996 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2998 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2999 werror (E_CODE_WRITE, " ");
3003 werror (E_LVALUE_REQUIRED, "*= or /=");
3004 goto errorTreeReturn;
3015 /* for these it must be both must be integral */
3016 if (!IS_INTEGRAL (LTYPE (tree)) ||
3017 !IS_INTEGRAL (RTYPE (tree)))
3019 werror (E_OPS_INTEGRAL);
3020 goto errorTreeReturn;
3023 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3025 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3026 werror (E_CODE_WRITE, " ");
3030 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3031 goto errorTreeReturn;
3037 /*------------------------------------------------------------------*/
3038 /*----------------------------*/
3040 /*----------------------------*/
3042 if (!(IS_PTR (LTYPE (tree)) ||
3043 IS_ARITHMETIC (LTYPE (tree))))
3045 werror (E_PLUS_INVALID, "-=");
3046 goto errorTreeReturn;
3049 if (!(IS_PTR (RTYPE (tree)) ||
3050 IS_ARITHMETIC (RTYPE (tree))))
3052 werror (E_PLUS_INVALID, "-=");
3053 goto errorTreeReturn;
3056 TETYPE (tree) = getSpec (TTYPE (tree) =
3057 computeType (LTYPE (tree),
3060 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3061 werror (E_CODE_WRITE, " ");
3065 werror (E_LVALUE_REQUIRED, "-=");
3066 goto errorTreeReturn;
3072 /*------------------------------------------------------------------*/
3073 /*----------------------------*/
3075 /*----------------------------*/
3077 /* this is not a unary operation */
3078 /* if both pointers then problem */
3079 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3081 werror (E_PTR_PLUS_PTR);
3082 goto errorTreeReturn;
3085 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3087 werror (E_PLUS_INVALID, "+=");
3088 goto errorTreeReturn;
3091 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3093 werror (E_PLUS_INVALID, "+=");
3094 goto errorTreeReturn;
3097 TETYPE (tree) = getSpec (TTYPE (tree) =
3098 computeType (LTYPE (tree),
3101 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3102 werror (E_CODE_WRITE, " ");
3106 werror (E_LVALUE_REQUIRED, "+=");
3107 goto errorTreeReturn;
3110 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3111 tree->opval.op = '=';
3116 /*------------------------------------------------------------------*/
3117 /*----------------------------*/
3118 /* straight assignemnt */
3119 /*----------------------------*/
3121 /* cannot be an aggregate */
3122 if (IS_AGGREGATE (LTYPE (tree)))
3124 werror (E_AGGR_ASSIGN);
3125 goto errorTreeReturn;
3128 /* they should either match or be castable */
3129 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3131 werror (E_TYPE_MISMATCH, "assignment", " ");
3132 printFromToType(RTYPE(tree),LTYPE(tree));
3133 //goto errorTreeReturn;
3136 /* if the left side of the tree is of type void
3137 then report error */
3138 if (IS_VOID (LTYPE (tree)))
3140 werror (E_CAST_ZERO);
3141 printFromToType(RTYPE(tree), LTYPE(tree));
3144 TETYPE (tree) = getSpec (TTYPE (tree) =
3148 if (!tree->initMode ) {
3149 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3150 werror (E_CODE_WRITE, " ");
3154 werror (E_LVALUE_REQUIRED, "=");
3155 goto errorTreeReturn;
3160 /*------------------------------------------------------------------*/
3161 /*----------------------------*/
3162 /* comma operator */
3163 /*----------------------------*/
3165 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3168 /*------------------------------------------------------------------*/
3169 /*----------------------------*/
3171 /*----------------------------*/
3175 if (processParms (tree->left,
3176 FUNC_ARGS(tree->left->ftype),
3177 tree->right, &parmNumber, TRUE)) {
3178 goto errorTreeReturn;
3181 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3182 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3184 //FUNC_ARGS(tree->left->ftype) =
3185 //reverseVal (FUNC_ARGS(tree->left->ftype));
3186 reverseParms (tree->right);
3189 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3192 /*------------------------------------------------------------------*/
3193 /*----------------------------*/
3194 /* return statement */
3195 /*----------------------------*/
3200 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3202 werror (W_RETURN_MISMATCH);
3203 printFromToType (RTYPE(tree), currFunc->type->next);
3204 goto errorTreeReturn;
3207 if (IS_VOID (currFunc->type->next)
3209 !IS_VOID (RTYPE (tree)))
3211 werror (E_FUNC_VOID);
3212 goto errorTreeReturn;
3215 /* if there is going to be a casing required then add it */
3216 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3219 decorateType (newNode (CAST,
3220 newAst_LINK (copyLinkChain (currFunc->type->next)),
3229 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3231 werror (E_VOID_FUNC, currFunc->name);
3232 goto errorTreeReturn;
3235 TTYPE (tree) = TETYPE (tree) = NULL;
3238 /*------------------------------------------------------------------*/
3239 /*----------------------------*/
3240 /* switch statement */
3241 /*----------------------------*/
3243 /* the switch value must be an integer */
3244 if (!IS_INTEGRAL (LTYPE (tree)))
3246 werror (E_SWITCH_NON_INTEGER);
3247 goto errorTreeReturn;
3250 TTYPE (tree) = TETYPE (tree) = NULL;
3253 /*------------------------------------------------------------------*/
3254 /*----------------------------*/
3256 /*----------------------------*/
3258 tree->left = backPatchLabels (tree->left,
3261 TTYPE (tree) = TETYPE (tree) = NULL;
3264 /*------------------------------------------------------------------*/
3265 /*----------------------------*/
3267 /*----------------------------*/
3270 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3271 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3272 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3274 /* if the for loop is reversible then
3275 reverse it otherwise do what we normally
3281 if (isLoopReversible (tree, &sym, &init, &end))
3282 return reverseLoop (tree, sym, init, end);
3284 return decorateType (createFor (AST_FOR (tree, trueLabel),
3285 AST_FOR (tree, continueLabel),
3286 AST_FOR (tree, falseLabel),
3287 AST_FOR (tree, condLabel),
3288 AST_FOR (tree, initExpr),
3289 AST_FOR (tree, condExpr),
3290 AST_FOR (tree, loopExpr),
3294 TTYPE (tree) = TETYPE (tree) = NULL;
3298 /* some error found this tree will be killed */
3300 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3301 tree->opval.op = NULLOP;
3307 /*-----------------------------------------------------------------*/
3308 /* sizeofOp - processes size of operation */
3309 /*-----------------------------------------------------------------*/
3311 sizeofOp (sym_link * type)
3315 /* make sure the type is complete and sane */
3316 checkTypeSanity(type, "(sizeof)");
3318 /* get the size and convert it to character */
3319 sprintf (buff, "%d", getSize (type));
3321 /* now convert into value */
3322 return constVal (buff);
3326 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3327 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3328 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3329 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3330 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3331 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3332 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3334 /*-----------------------------------------------------------------*/
3335 /* backPatchLabels - change and or not operators to flow control */
3336 /*-----------------------------------------------------------------*/
3338 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3344 if (!(IS_ANDORNOT (tree)))
3347 /* if this an and */
3350 static int localLbl = 0;
3353 sprintf (buffer, "_and_%d", localLbl++);
3354 localLabel = newSymbol (buffer, NestLevel);
3356 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3358 /* if left is already a IFX then just change the if true label in that */
3359 if (!IS_IFX (tree->left))
3360 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3362 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3363 /* right is a IFX then just join */
3364 if (IS_IFX (tree->right))
3365 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3367 tree->right = createLabel (localLabel, tree->right);
3368 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3370 return newNode (NULLOP, tree->left, tree->right);
3373 /* if this is an or operation */
3376 static int localLbl = 0;
3379 sprintf (buffer, "_or_%d", localLbl++);
3380 localLabel = newSymbol (buffer, NestLevel);
3382 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3384 /* if left is already a IFX then just change the if true label in that */
3385 if (!IS_IFX (tree->left))
3386 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3388 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3389 /* right is a IFX then just join */
3390 if (IS_IFX (tree->right))
3391 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3393 tree->right = createLabel (localLabel, tree->right);
3394 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3396 return newNode (NULLOP, tree->left, tree->right);
3402 int wasnot = IS_NOT (tree->left);
3403 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3405 /* if the left is already a IFX */
3406 if (!IS_IFX (tree->left))
3407 tree->left = newNode (IFX, tree->left, NULL);
3411 tree->left->trueLabel = trueLabel;
3412 tree->left->falseLabel = falseLabel;
3416 tree->left->trueLabel = falseLabel;
3417 tree->left->falseLabel = trueLabel;
3424 tree->trueLabel = trueLabel;
3425 tree->falseLabel = falseLabel;
3432 /*-----------------------------------------------------------------*/
3433 /* createBlock - create expression tree for block */
3434 /*-----------------------------------------------------------------*/
3436 createBlock (symbol * decl, ast * body)
3440 /* if the block has nothing */
3444 ex = newNode (BLOCK, NULL, body);
3445 ex->values.sym = decl;
3447 ex->right = ex->right;
3453 /*-----------------------------------------------------------------*/
3454 /* createLabel - creates the expression tree for labels */
3455 /*-----------------------------------------------------------------*/
3457 createLabel (symbol * label, ast * stmnt)
3460 char name[SDCC_NAME_MAX + 1];
3463 /* must create fresh symbol if the symbol name */
3464 /* exists in the symbol table, since there can */
3465 /* be a variable with the same name as the labl */
3466 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3467 (csym->level == label->level))
3468 label = newSymbol (label->name, label->level);
3470 /* change the name before putting it in add _ */
3471 sprintf (name, "%s", label->name);
3473 /* put the label in the LabelSymbol table */
3474 /* but first check if a label of the same */
3476 if ((csym = findSym (LabelTab, NULL, name)))
3477 werror (E_DUPLICATE_LABEL, label->name);
3479 addSym (LabelTab, label, name, label->level, 0, 0);
3482 label->key = labelKey++;
3483 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3489 /*-----------------------------------------------------------------*/
3490 /* createCase - generates the parsetree for a case statement */
3491 /*-----------------------------------------------------------------*/
3493 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3495 char caseLbl[SDCC_NAME_MAX + 1];
3499 /* if the switch statement does not exist */
3500 /* then case is out of context */
3503 werror (E_CASE_CONTEXT);
3507 caseVal = decorateType (resolveSymbols (caseVal));
3508 /* if not a constant then error */
3509 if (!IS_LITERAL (caseVal->ftype))
3511 werror (E_CASE_CONSTANT);
3515 /* if not a integer than error */
3516 if (!IS_INTEGRAL (caseVal->ftype))
3518 werror (E_CASE_NON_INTEGER);
3522 /* find the end of the switch values chain */
3523 if (!(val = swStat->values.switchVals.swVals))
3524 swStat->values.switchVals.swVals = caseVal->opval.val;
3527 /* also order the cases according to value */
3529 int cVal = (int) floatFromVal (caseVal->opval.val);
3530 while (val && (int) floatFromVal (val) < cVal)
3536 /* if we reached the end then */
3539 pval->next = caseVal->opval.val;
3543 /* we found a value greater than */
3544 /* the current value we must add this */
3545 /* before the value */
3546 caseVal->opval.val->next = val;
3548 /* if this was the first in chain */
3549 if (swStat->values.switchVals.swVals == val)
3550 swStat->values.switchVals.swVals =
3553 pval->next = caseVal->opval.val;
3558 /* create the case label */
3559 sprintf (caseLbl, "_case_%d_%d",
3560 swStat->values.switchVals.swNum,
3561 (int) floatFromVal (caseVal->opval.val));
3563 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3568 /*-----------------------------------------------------------------*/
3569 /* createDefault - creates the parse tree for the default statement */
3570 /*-----------------------------------------------------------------*/
3572 createDefault (ast * swStat, ast * stmnt)
3574 char defLbl[SDCC_NAME_MAX + 1];
3576 /* if the switch statement does not exist */
3577 /* then case is out of context */
3580 werror (E_CASE_CONTEXT);
3584 /* turn on the default flag */
3585 swStat->values.switchVals.swDefault = 1;
3587 /* create the label */
3588 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3589 return createLabel (newSymbol (defLbl, 0), stmnt);
3592 /*-----------------------------------------------------------------*/
3593 /* createIf - creates the parsetree for the if statement */
3594 /*-----------------------------------------------------------------*/
3596 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3598 static int Lblnum = 0;
3600 symbol *ifTrue, *ifFalse, *ifEnd;
3602 /* if neither exists */
3603 if (!elseBody && !ifBody) {
3604 // if there are no side effects (i++, j() etc)
3605 if (!hasSEFcalls(condAst)) {
3610 /* create the labels */
3611 sprintf (buffer, "_iffalse_%d", Lblnum);
3612 ifFalse = newSymbol (buffer, NestLevel);
3613 /* if no else body then end == false */
3618 sprintf (buffer, "_ifend_%d", Lblnum);
3619 ifEnd = newSymbol (buffer, NestLevel);
3622 sprintf (buffer, "_iftrue_%d", Lblnum);
3623 ifTrue = newSymbol (buffer, NestLevel);
3627 /* attach the ifTrue label to the top of it body */
3628 ifBody = createLabel (ifTrue, ifBody);
3629 /* attach a goto end to the ifBody if else is present */
3632 ifBody = newNode (NULLOP, ifBody,
3634 newAst_VALUE (symbolVal (ifEnd)),
3636 /* put the elseLabel on the else body */
3637 elseBody = createLabel (ifFalse, elseBody);
3638 /* out the end at the end of the body */
3639 elseBody = newNode (NULLOP,
3641 createLabel (ifEnd, NULL));
3645 ifBody = newNode (NULLOP, ifBody,
3646 createLabel (ifFalse, NULL));
3648 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3649 if (IS_IFX (condAst))
3652 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3654 return newNode (NULLOP, ifTree,
3655 newNode (NULLOP, ifBody, elseBody));
3659 /*-----------------------------------------------------------------*/
3660 /* createDo - creates parse tree for do */
3663 /* _docontinue_n: */
3664 /* condition_expression +-> trueLabel -> _dobody_n */
3666 /* +-> falseLabel-> _dobreak_n */
3668 /*-----------------------------------------------------------------*/
3670 createDo (symbol * trueLabel, symbol * continueLabel,
3671 symbol * falseLabel, ast * condAst, ast * doBody)
3676 /* if the body does not exist then it is simple */
3679 condAst = backPatchLabels (condAst, continueLabel, NULL);
3680 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3681 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3682 doTree->trueLabel = continueLabel;
3683 doTree->falseLabel = NULL;
3687 /* otherwise we have a body */
3688 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3690 /* attach the body label to the top */
3691 doBody = createLabel (trueLabel, doBody);
3692 /* attach the continue label to end of body */
3693 doBody = newNode (NULLOP, doBody,
3694 createLabel (continueLabel, NULL));
3696 /* now put the break label at the end */
3697 if (IS_IFX (condAst))
3700 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3702 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3704 /* putting it together */
3705 return newNode (NULLOP, doBody, doTree);
3708 /*-----------------------------------------------------------------*/
3709 /* createFor - creates parse tree for 'for' statement */
3712 /* condExpr +-> trueLabel -> _forbody_n */
3714 /* +-> falseLabel-> _forbreak_n */
3717 /* _forcontinue_n: */
3719 /* goto _forcond_n ; */
3721 /*-----------------------------------------------------------------*/
3723 createFor (symbol * trueLabel, symbol * continueLabel,
3724 symbol * falseLabel, symbol * condLabel,
3725 ast * initExpr, ast * condExpr, ast * loopExpr,
3730 /* if loopexpression not present then we can generate it */
3731 /* the same way as a while */
3733 return newNode (NULLOP, initExpr,
3734 createWhile (trueLabel, continueLabel,
3735 falseLabel, condExpr, forBody));
3736 /* vanilla for statement */
3737 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3739 if (condExpr && !IS_IFX (condExpr))
3740 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3743 /* attach condition label to condition */
3744 condExpr = createLabel (condLabel, condExpr);
3746 /* attach body label to body */
3747 forBody = createLabel (trueLabel, forBody);
3749 /* attach continue to forLoop expression & attach */
3750 /* goto the forcond @ and of loopExpression */
3751 loopExpr = createLabel (continueLabel,
3755 newAst_VALUE (symbolVal (condLabel)),
3757 /* now start putting them together */
3758 forTree = newNode (NULLOP, initExpr, condExpr);
3759 forTree = newNode (NULLOP, forTree, forBody);
3760 forTree = newNode (NULLOP, forTree, loopExpr);
3761 /* finally add the break label */
3762 forTree = newNode (NULLOP, forTree,
3763 createLabel (falseLabel, NULL));
3767 /*-----------------------------------------------------------------*/
3768 /* createWhile - creates parse tree for while statement */
3769 /* the while statement will be created as follows */
3771 /* _while_continue_n: */
3772 /* condition_expression +-> trueLabel -> _while_boby_n */
3774 /* +-> falseLabel -> _while_break_n */
3775 /* _while_body_n: */
3777 /* goto _while_continue_n */
3778 /* _while_break_n: */
3779 /*-----------------------------------------------------------------*/
3781 createWhile (symbol * trueLabel, symbol * continueLabel,
3782 symbol * falseLabel, ast * condExpr, ast * whileBody)
3786 /* put the continue label */
3787 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3788 condExpr = createLabel (continueLabel, condExpr);
3789 condExpr->lineno = 0;
3791 /* put the body label in front of the body */
3792 whileBody = createLabel (trueLabel, whileBody);
3793 whileBody->lineno = 0;
3794 /* put a jump to continue at the end of the body */
3795 /* and put break label at the end of the body */
3796 whileBody = newNode (NULLOP,
3799 newAst_VALUE (symbolVal (continueLabel)),
3800 createLabel (falseLabel, NULL)));
3802 /* put it all together */
3803 if (IS_IFX (condExpr))
3804 whileTree = condExpr;
3807 whileTree = newNode (IFX, condExpr, NULL);
3808 /* put the true & false labels in place */
3809 whileTree->trueLabel = trueLabel;
3810 whileTree->falseLabel = falseLabel;
3813 return newNode (NULLOP, whileTree, whileBody);
3816 /*-----------------------------------------------------------------*/
3817 /* optimizeGetHbit - get highest order bit of the expression */
3818 /*-----------------------------------------------------------------*/
3820 optimizeGetHbit (ast * tree)
3823 /* if this is not a bit and */
3824 if (!IS_BITAND (tree))
3827 /* will look for tree of the form
3828 ( expr >> ((sizeof expr) -1) ) & 1 */
3829 if (!IS_AST_LIT_VALUE (tree->right))
3832 if (AST_LIT_VALUE (tree->right) != 1)
3835 if (!IS_RIGHT_OP (tree->left))
3838 if (!IS_AST_LIT_VALUE (tree->left->right))
3841 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3842 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3845 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3849 /*-----------------------------------------------------------------*/
3850 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3851 /*-----------------------------------------------------------------*/
3853 optimizeRRCRLC (ast * root)
3855 /* will look for trees of the form
3856 (?expr << 1) | (?expr >> 7) or
3857 (?expr >> 7) | (?expr << 1) will make that
3858 into a RLC : operation ..
3860 (?expr >> 1) | (?expr << 7) or
3861 (?expr << 7) | (?expr >> 1) will make that
3862 into a RRC operation
3863 note : by 7 I mean (number of bits required to hold the
3865 /* if the root operations is not a | operation the not */
3866 if (!IS_BITOR (root))
3869 /* I have to think of a better way to match patterns this sucks */
3870 /* that aside let start looking for the first case : I use a the
3871 negative check a lot to improve the efficiency */
3872 /* (?expr << 1) | (?expr >> 7) */
3873 if (IS_LEFT_OP (root->left) &&
3874 IS_RIGHT_OP (root->right))
3877 if (!SPEC_USIGN (TETYPE (root->left->left)))
3880 if (!IS_AST_LIT_VALUE (root->left->right) ||
3881 !IS_AST_LIT_VALUE (root->right->right))
3884 /* make sure it is the same expression */
3885 if (!isAstEqual (root->left->left,
3889 if (AST_LIT_VALUE (root->left->right) != 1)
3892 if (AST_LIT_VALUE (root->right->right) !=
3893 (getSize (TTYPE (root->left->left)) * 8 - 1))
3896 /* whew got the first case : create the AST */
3897 return newNode (RLC, root->left->left, NULL);
3901 /* check for second case */
3902 /* (?expr >> 7) | (?expr << 1) */
3903 if (IS_LEFT_OP (root->right) &&
3904 IS_RIGHT_OP (root->left))
3907 if (!SPEC_USIGN (TETYPE (root->left->left)))
3910 if (!IS_AST_LIT_VALUE (root->left->right) ||
3911 !IS_AST_LIT_VALUE (root->right->right))
3914 /* make sure it is the same symbol */
3915 if (!isAstEqual (root->left->left,
3919 if (AST_LIT_VALUE (root->right->right) != 1)
3922 if (AST_LIT_VALUE (root->left->right) !=
3923 (getSize (TTYPE (root->left->left)) * 8 - 1))
3926 /* whew got the first case : create the AST */
3927 return newNode (RLC, root->left->left, NULL);
3932 /* third case for RRC */
3933 /* (?symbol >> 1) | (?symbol << 7) */
3934 if (IS_LEFT_OP (root->right) &&
3935 IS_RIGHT_OP (root->left))
3938 if (!SPEC_USIGN (TETYPE (root->left->left)))
3941 if (!IS_AST_LIT_VALUE (root->left->right) ||
3942 !IS_AST_LIT_VALUE (root->right->right))
3945 /* make sure it is the same symbol */
3946 if (!isAstEqual (root->left->left,
3950 if (AST_LIT_VALUE (root->left->right) != 1)
3953 if (AST_LIT_VALUE (root->right->right) !=
3954 (getSize (TTYPE (root->left->left)) * 8 - 1))
3957 /* whew got the first case : create the AST */
3958 return newNode (RRC, root->left->left, NULL);
3962 /* fourth and last case for now */
3963 /* (?symbol << 7) | (?symbol >> 1) */
3964 if (IS_RIGHT_OP (root->right) &&
3965 IS_LEFT_OP (root->left))
3968 if (!SPEC_USIGN (TETYPE (root->left->left)))
3971 if (!IS_AST_LIT_VALUE (root->left->right) ||
3972 !IS_AST_LIT_VALUE (root->right->right))
3975 /* make sure it is the same symbol */
3976 if (!isAstEqual (root->left->left,
3980 if (AST_LIT_VALUE (root->right->right) != 1)
3983 if (AST_LIT_VALUE (root->left->right) !=
3984 (getSize (TTYPE (root->left->left)) * 8 - 1))
3987 /* whew got the first case : create the AST */
3988 return newNode (RRC, root->left->left, NULL);
3992 /* not found return root */
3996 /*-----------------------------------------------------------------*/
3997 /* optimizeCompare - otimizes compares for bit variables */
3998 /*-----------------------------------------------------------------*/
4000 optimizeCompare (ast * root)
4002 ast *optExpr = NULL;
4005 unsigned int litValue;
4007 /* if nothing then return nothing */
4011 /* if not a compare op then do leaves */
4012 if (!IS_COMPARE_OP (root))
4014 root->left = optimizeCompare (root->left);
4015 root->right = optimizeCompare (root->right);
4019 /* if left & right are the same then depending
4020 of the operation do */
4021 if (isAstEqual (root->left, root->right))
4023 switch (root->opval.op)
4028 optExpr = newAst_VALUE (constVal ("0"));
4033 optExpr = newAst_VALUE (constVal ("1"));
4037 return decorateType (optExpr);
4040 vleft = (root->left->type == EX_VALUE ?
4041 root->left->opval.val : NULL);
4043 vright = (root->right->type == EX_VALUE ?
4044 root->right->opval.val : NULL);
4046 /* if left is a BITVAR in BITSPACE */
4047 /* and right is a LITERAL then opt- */
4048 /* imize else do nothing */
4049 if (vleft && vright &&
4050 IS_BITVAR (vleft->etype) &&
4051 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4052 IS_LITERAL (vright->etype))
4055 /* if right side > 1 then comparison may never succeed */
4056 if ((litValue = (int) floatFromVal (vright)) > 1)
4058 werror (W_BAD_COMPARE);
4064 switch (root->opval.op)
4066 case '>': /* bit value greater than 1 cannot be */
4067 werror (W_BAD_COMPARE);
4071 case '<': /* bit value < 1 means 0 */
4073 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4076 case LE_OP: /* bit value <= 1 means no check */
4077 optExpr = newAst_VALUE (vright);
4080 case GE_OP: /* bit value >= 1 means only check for = */
4082 optExpr = newAst_VALUE (vleft);
4087 { /* literal is zero */
4088 switch (root->opval.op)
4090 case '<': /* bit value < 0 cannot be */
4091 werror (W_BAD_COMPARE);
4095 case '>': /* bit value > 0 means 1 */
4097 optExpr = newAst_VALUE (vleft);
4100 case LE_OP: /* bit value <= 0 means no check */
4101 case GE_OP: /* bit value >= 0 means no check */
4102 werror (W_BAD_COMPARE);
4106 case EQ_OP: /* bit == 0 means ! of bit */
4107 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4111 return decorateType (resolveSymbols (optExpr));
4112 } /* end-of-if of BITVAR */
4117 /*-----------------------------------------------------------------*/
4118 /* addSymToBlock : adds the symbol to the first block we find */
4119 /*-----------------------------------------------------------------*/
4121 addSymToBlock (symbol * sym, ast * tree)
4123 /* reached end of tree or a leaf */
4124 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4128 if (IS_AST_OP (tree) &&
4129 tree->opval.op == BLOCK)
4132 symbol *lsym = copySymbol (sym);
4134 lsym->next = AST_VALUES (tree, sym);
4135 AST_VALUES (tree, sym) = lsym;
4139 addSymToBlock (sym, tree->left);
4140 addSymToBlock (sym, tree->right);
4143 /*-----------------------------------------------------------------*/
4144 /* processRegParms - do processing for register parameters */
4145 /*-----------------------------------------------------------------*/
4147 processRegParms (value * args, ast * body)
4151 if (IS_REGPARM (args->etype))
4152 addSymToBlock (args->sym, body);
4157 /*-----------------------------------------------------------------*/
4158 /* resetParmKey - resets the operandkeys for the symbols */
4159 /*-----------------------------------------------------------------*/
4160 DEFSETFUNC (resetParmKey)
4171 /*-----------------------------------------------------------------*/
4172 /* createFunction - This is the key node that calls the iCode for */
4173 /* generating the code for a function. Note code */
4174 /* is generated function by function, later when */
4175 /* add inter-procedural analysis this will change */
4176 /*-----------------------------------------------------------------*/
4178 createFunction (symbol * name, ast * body)
4184 iCode *piCode = NULL;
4186 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4187 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4189 /* if check function return 0 then some problem */
4190 if (checkFunction (name, NULL) == 0)
4193 /* create a dummy block if none exists */
4195 body = newNode (BLOCK, NULL, NULL);
4199 /* check if the function name already in the symbol table */
4200 if ((csym = findSym (SymbolTab, NULL, name->name)))
4203 /* special case for compiler defined functions
4204 we need to add the name to the publics list : this
4205 actually means we are now compiling the compiler
4209 addSet (&publics, name);
4215 allocVariables (name);
4217 name->lastLine = yylineno;
4220 /* set the stack pointer */
4221 /* PENDING: check this for the mcs51 */
4222 stackPtr = -port->stack.direction * port->stack.call_overhead;
4223 if (IFFUNC_ISISR (name->type))
4224 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4225 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4226 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4228 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4230 fetype = getSpec (name->type); /* get the specifier for the function */
4231 /* if this is a reentrant function then */
4232 if (IFFUNC_ISREENT (name->type))
4235 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4237 /* do processing for parameters that are passed in registers */
4238 processRegParms (FUNC_ARGS(name->type), body);
4240 /* set the stack pointer */
4244 /* allocate & autoinit the block variables */
4245 processBlockVars (body, &stack, ALLOCATE);
4247 /* save the stack information */
4248 if (options.useXstack)
4249 name->xstack = SPEC_STAK (fetype) = stack;
4251 name->stack = SPEC_STAK (fetype) = stack;
4253 /* name needs to be mangled */
4254 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4256 body = resolveSymbols (body); /* resolve the symbols */
4257 body = decorateType (body); /* propagateType & do semantic checks */
4259 ex = newAst_VALUE (symbolVal (name)); /* create name */
4260 ex = newNode (FUNCTION, ex, body);
4261 ex->values.args = FUNC_ARGS(name->type);
4263 if (options.dump_tree) PA(ex);
4266 werror (E_FUNC_NO_CODE, name->name);
4270 /* create the node & generate intermediate code */
4272 codeOutFile = code->oFile;
4273 piCode = iCodeFromAst (ex);
4277 werror (E_FUNC_NO_CODE, name->name);
4281 eBBlockFromiCode (piCode);
4283 /* if there are any statics then do them */
4286 GcurMemmap = statsg;
4287 codeOutFile = statsg->oFile;
4288 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4294 /* dealloc the block variables */
4295 processBlockVars (body, &stack, DEALLOCATE);
4296 /* deallocate paramaters */
4297 deallocParms (FUNC_ARGS(name->type));
4299 if (IFFUNC_ISREENT (name->type))
4302 /* we are done freeup memory & cleanup */
4304 if (port->reset_labelKey) labelKey = 1;
4306 FUNC_HASBODY(name->type) = 1;
4307 addSet (&operKeyReset, name);
4308 applyToSet (operKeyReset, resetParmKey);
4311 cdbStructBlock (1, cdbFile);
4313 cleanUpLevel (LabelTab, 0);
4314 cleanUpBlock (StructTab, 1);
4315 cleanUpBlock (TypedefTab, 1);
4317 xstack->syms = NULL;
4318 istack->syms = NULL;
4323 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4324 /*-----------------------------------------------------------------*/
4325 /* ast_print : prints the ast (for debugging purposes) */
4326 /*-----------------------------------------------------------------*/
4328 void ast_print (ast * tree, FILE *outfile, int indent)
4333 /* can print only decorated trees */
4334 if (!tree->decorated) return;
4336 /* if any child is an error | this one is an error do nothing */
4337 if (tree->isError ||
4338 (tree->left && tree->left->isError) ||
4339 (tree->right && tree->right->isError)) {
4340 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4344 /* print the line */
4345 /* if not block & function */
4346 if (tree->type == EX_OP &&
4347 (tree->opval.op != FUNCTION &&
4348 tree->opval.op != BLOCK &&
4349 tree->opval.op != NULLOP)) {
4352 if (tree->opval.op == FUNCTION) {
4354 value *args=FUNC_ARGS(tree->left->opval.val->type);
4355 fprintf(outfile,"FUNCTION (%s=%p) type (",
4356 tree->left->opval.val->name, tree);
4357 printTypeChain (tree->ftype,outfile);
4358 fprintf(outfile,") args (");
4361 fprintf (outfile, ", ");
4363 printTypeChain (args ? args->type : NULL, outfile);
4365 args= args ? args->next : NULL;
4367 fprintf(outfile,")\n");
4368 ast_print(tree->left,outfile,indent);
4369 ast_print(tree->right,outfile,indent);
4372 if (tree->opval.op == BLOCK) {
4373 symbol *decls = tree->values.sym;
4374 INDENT(indent,outfile);
4375 fprintf(outfile,"{\n");
4377 INDENT(indent+2,outfile);
4378 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4379 decls->name, decls);
4380 printTypeChain(decls->type,outfile);
4381 fprintf(outfile,")\n");
4383 decls = decls->next;
4385 ast_print(tree->right,outfile,indent+2);
4386 INDENT(indent,outfile);
4387 fprintf(outfile,"}\n");
4390 if (tree->opval.op == NULLOP) {
4391 fprintf(outfile,"\n");
4392 ast_print(tree->left,outfile,indent);
4393 fprintf(outfile,"\n");
4394 ast_print(tree->right,outfile,indent);
4397 INDENT(indent,outfile);
4399 /*------------------------------------------------------------------*/
4400 /*----------------------------*/
4401 /* leaf has been reached */
4402 /*----------------------------*/
4403 /* if this is of type value */
4404 /* just get the type */
4405 if (tree->type == EX_VALUE) {
4407 if (IS_LITERAL (tree->opval.val->etype)) {
4408 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4409 (int) floatFromVal(tree->opval.val),
4410 (int) floatFromVal(tree->opval.val),
4411 floatFromVal(tree->opval.val));
4412 } else if (tree->opval.val->sym) {
4413 /* if the undefined flag is set then give error message */
4414 if (tree->opval.val->sym->undefined) {
4415 fprintf(outfile,"UNDEFINED SYMBOL ");
4417 fprintf(outfile,"SYMBOL ");
4419 fprintf(outfile,"(%s=%p)",
4420 tree->opval.val->sym->name,tree);
4423 fprintf(outfile," type (");
4424 printTypeChain(tree->ftype,outfile);
4425 fprintf(outfile,")\n");
4427 fprintf(outfile,"\n");
4432 /* if type link for the case of cast */
4433 if (tree->type == EX_LINK) {
4434 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4435 printTypeChain(tree->opval.lnk,outfile);
4436 fprintf(outfile,")\n");
4441 /* depending on type of operator do */
4443 switch (tree->opval.op) {
4444 /*------------------------------------------------------------------*/
4445 /*----------------------------*/
4447 /*----------------------------*/
4449 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4450 printTypeChain(tree->ftype,outfile);
4451 fprintf(outfile,")\n");
4452 ast_print(tree->left,outfile,indent+2);
4453 ast_print(tree->right,outfile,indent+2);
4456 /*------------------------------------------------------------------*/
4457 /*----------------------------*/
4459 /*----------------------------*/
4461 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4462 printTypeChain(tree->ftype,outfile);
4463 fprintf(outfile,")\n");
4464 ast_print(tree->left,outfile,indent+2);
4465 ast_print(tree->right,outfile,indent+2);
4468 /*------------------------------------------------------------------*/
4469 /*----------------------------*/
4470 /* struct/union pointer */
4471 /*----------------------------*/
4473 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+2);
4477 ast_print(tree->right,outfile,indent+2);
4480 /*------------------------------------------------------------------*/
4481 /*----------------------------*/
4482 /* ++/-- operation */
4483 /*----------------------------*/
4484 case INC_OP: /* incerement operator unary so left only */
4485 fprintf(outfile,"INC_OP (%p) type (",tree);
4486 printTypeChain(tree->ftype,outfile);
4487 fprintf(outfile,")\n");
4488 ast_print(tree->left,outfile,indent+2);
4492 fprintf(outfile,"DEC_OP (%p) type (",tree);
4493 printTypeChain(tree->ftype,outfile);
4494 fprintf(outfile,")\n");
4495 ast_print(tree->left,outfile,indent+2);
4498 /*------------------------------------------------------------------*/
4499 /*----------------------------*/
4501 /*----------------------------*/
4504 fprintf(outfile,"& (%p) type (",tree);
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4507 ast_print(tree->left,outfile,indent+2);
4508 ast_print(tree->right,outfile,indent+2);
4510 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4511 printTypeChain(tree->ftype,outfile);
4512 fprintf(outfile,")\n");
4513 ast_print(tree->left,outfile,indent+2);
4514 ast_print(tree->right,outfile,indent+2);
4517 /*----------------------------*/
4519 /*----------------------------*/
4521 fprintf(outfile,"OR (%p) type (",tree);
4522 printTypeChain(tree->ftype,outfile);
4523 fprintf(outfile,")\n");
4524 ast_print(tree->left,outfile,indent+2);
4525 ast_print(tree->right,outfile,indent+2);
4527 /*------------------------------------------------------------------*/
4528 /*----------------------------*/
4530 /*----------------------------*/
4532 fprintf(outfile,"XOR (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+2);
4536 ast_print(tree->right,outfile,indent+2);
4539 /*------------------------------------------------------------------*/
4540 /*----------------------------*/
4542 /*----------------------------*/
4544 fprintf(outfile,"DIV (%p) type (",tree);
4545 printTypeChain(tree->ftype,outfile);
4546 fprintf(outfile,")\n");
4547 ast_print(tree->left,outfile,indent+2);
4548 ast_print(tree->right,outfile,indent+2);
4550 /*------------------------------------------------------------------*/
4551 /*----------------------------*/
4553 /*----------------------------*/
4555 fprintf(outfile,"MOD (%p) type (",tree);
4556 printTypeChain(tree->ftype,outfile);
4557 fprintf(outfile,")\n");
4558 ast_print(tree->left,outfile,indent+2);
4559 ast_print(tree->right,outfile,indent+2);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4564 /* address dereference */
4565 /*----------------------------*/
4566 case '*': /* can be unary : if right is null then unary operation */
4568 fprintf(outfile,"DEREF (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+2);
4574 /*------------------------------------------------------------------*/
4575 /*----------------------------*/
4576 /* multiplication */
4577 /*----------------------------*/
4578 fprintf(outfile,"MULT (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+2);
4582 ast_print(tree->right,outfile,indent+2);
4586 /*------------------------------------------------------------------*/
4587 /*----------------------------*/
4588 /* unary '+' operator */
4589 /*----------------------------*/
4593 fprintf(outfile,"UPLUS (%p) type (",tree);
4594 printTypeChain(tree->ftype,outfile);
4595 fprintf(outfile,")\n");
4596 ast_print(tree->left,outfile,indent+2);
4598 /*------------------------------------------------------------------*/
4599 /*----------------------------*/
4601 /*----------------------------*/
4602 fprintf(outfile,"ADD (%p) type (",tree);
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->left,outfile,indent+2);
4606 ast_print(tree->right,outfile,indent+2);
4609 /*------------------------------------------------------------------*/
4610 /*----------------------------*/
4612 /*----------------------------*/
4613 case '-': /* can be unary */
4615 fprintf(outfile,"UMINUS (%p) type (",tree);
4616 printTypeChain(tree->ftype,outfile);
4617 fprintf(outfile,")\n");
4618 ast_print(tree->left,outfile,indent+2);
4620 /*------------------------------------------------------------------*/
4621 /*----------------------------*/
4623 /*----------------------------*/
4624 fprintf(outfile,"SUB (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+2);
4628 ast_print(tree->right,outfile,indent+2);
4631 /*------------------------------------------------------------------*/
4632 /*----------------------------*/
4634 /*----------------------------*/
4636 fprintf(outfile,"COMPL (%p) type (",tree);
4637 printTypeChain(tree->ftype,outfile);
4638 fprintf(outfile,")\n");
4639 ast_print(tree->left,outfile,indent+2);
4641 /*------------------------------------------------------------------*/
4642 /*----------------------------*/
4644 /*----------------------------*/
4646 fprintf(outfile,"NOT (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+2);
4651 /*------------------------------------------------------------------*/
4652 /*----------------------------*/
4654 /*----------------------------*/
4656 fprintf(outfile,"RRC (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->left,outfile,indent+2);
4663 fprintf(outfile,"RLC (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+2);
4669 fprintf(outfile,"GETHBIT (%p) type (",tree);
4670 printTypeChain(tree->ftype,outfile);
4671 fprintf(outfile,")\n");
4672 ast_print(tree->left,outfile,indent+2);
4675 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+2);
4679 ast_print(tree->right,outfile,indent+2);
4682 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+2);
4686 ast_print(tree->right,outfile,indent+2);
4688 /*------------------------------------------------------------------*/
4689 /*----------------------------*/
4691 /*----------------------------*/
4692 case CAST: /* change the type */
4693 fprintf(outfile,"CAST (%p) from type (",tree);
4694 printTypeChain(tree->right->ftype,outfile);
4695 fprintf(outfile,") to type (");
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->right,outfile,indent+2);
4702 fprintf(outfile,"ANDAND (%p) type (",tree);
4703 printTypeChain(tree->ftype,outfile);
4704 fprintf(outfile,")\n");
4705 ast_print(tree->left,outfile,indent+2);
4706 ast_print(tree->right,outfile,indent+2);
4709 fprintf(outfile,"OROR (%p) type (",tree);
4710 printTypeChain(tree->ftype,outfile);
4711 fprintf(outfile,")\n");
4712 ast_print(tree->left,outfile,indent+2);
4713 ast_print(tree->right,outfile,indent+2);
4716 /*------------------------------------------------------------------*/
4717 /*----------------------------*/
4718 /* comparison operators */
4719 /*----------------------------*/
4721 fprintf(outfile,"GT(>) (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+2);
4725 ast_print(tree->right,outfile,indent+2);
4728 fprintf(outfile,"LT(<) (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+2);
4732 ast_print(tree->right,outfile,indent+2);
4735 fprintf(outfile,"LE(<=) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+2);
4739 ast_print(tree->right,outfile,indent+2);
4742 fprintf(outfile,"GE(>=) (%p) type (",tree);
4743 printTypeChain(tree->ftype,outfile);
4744 fprintf(outfile,")\n");
4745 ast_print(tree->left,outfile,indent+2);
4746 ast_print(tree->right,outfile,indent+2);
4749 fprintf(outfile,"EQ(==) (%p) type (",tree);
4750 printTypeChain(tree->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->left,outfile,indent+2);
4753 ast_print(tree->right,outfile,indent+2);
4756 fprintf(outfile,"NE(!=) (%p) type (",tree);
4757 printTypeChain(tree->ftype,outfile);
4758 fprintf(outfile,")\n");
4759 ast_print(tree->left,outfile,indent+2);
4760 ast_print(tree->right,outfile,indent+2);
4761 /*------------------------------------------------------------------*/
4762 /*----------------------------*/
4764 /*----------------------------*/
4765 case SIZEOF: /* evaluate wihout code generation */
4766 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4769 /*------------------------------------------------------------------*/
4770 /*----------------------------*/
4771 /* conditional operator '?' */
4772 /*----------------------------*/
4774 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4775 printTypeChain(tree->ftype,outfile);
4776 fprintf(outfile,")\n");
4777 ast_print(tree->left,outfile,indent+2);
4778 ast_print(tree->right,outfile,indent+2);
4782 fprintf(outfile,"COLON(:) (%p) type (",tree);
4783 printTypeChain(tree->ftype,outfile);
4784 fprintf(outfile,")\n");
4785 ast_print(tree->left,outfile,indent+2);
4786 ast_print(tree->right,outfile,indent+2);
4789 /*------------------------------------------------------------------*/
4790 /*----------------------------*/
4791 /* assignment operators */
4792 /*----------------------------*/
4794 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->left,outfile,indent+2);
4798 ast_print(tree->right,outfile,indent+2);
4801 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4802 printTypeChain(tree->ftype,outfile);
4803 fprintf(outfile,")\n");
4804 ast_print(tree->left,outfile,indent+2);
4805 ast_print(tree->right,outfile,indent+2);
4808 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4809 printTypeChain(tree->ftype,outfile);
4810 fprintf(outfile,")\n");
4811 ast_print(tree->left,outfile,indent+2);
4812 ast_print(tree->right,outfile,indent+2);
4815 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4816 printTypeChain(tree->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->left,outfile,indent+2);
4819 ast_print(tree->right,outfile,indent+2);
4822 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4823 printTypeChain(tree->ftype,outfile);
4824 fprintf(outfile,")\n");
4825 ast_print(tree->left,outfile,indent+2);
4826 ast_print(tree->right,outfile,indent+2);
4829 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4830 printTypeChain(tree->ftype,outfile);
4831 fprintf(outfile,")\n");
4832 ast_print(tree->left,outfile,indent+2);
4833 ast_print(tree->right,outfile,indent+2);
4836 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4837 printTypeChain(tree->ftype,outfile);
4838 fprintf(outfile,")\n");
4839 ast_print(tree->left,outfile,indent+2);
4840 ast_print(tree->right,outfile,indent+2);
4842 /*------------------------------------------------------------------*/
4843 /*----------------------------*/
4845 /*----------------------------*/
4847 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4848 printTypeChain(tree->ftype,outfile);
4849 fprintf(outfile,")\n");
4850 ast_print(tree->left,outfile,indent+2);
4851 ast_print(tree->right,outfile,indent+2);
4853 /*------------------------------------------------------------------*/
4854 /*----------------------------*/
4856 /*----------------------------*/
4858 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4859 printTypeChain(tree->ftype,outfile);
4860 fprintf(outfile,")\n");
4861 ast_print(tree->left,outfile,indent+2);
4862 ast_print(tree->right,outfile,indent+2);
4864 /*------------------------------------------------------------------*/
4865 /*----------------------------*/
4866 /* straight assignemnt */
4867 /*----------------------------*/
4869 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4870 printTypeChain(tree->ftype,outfile);
4871 fprintf(outfile,")\n");
4872 ast_print(tree->left,outfile,indent+2);
4873 ast_print(tree->right,outfile,indent+2);
4875 /*------------------------------------------------------------------*/
4876 /*----------------------------*/
4877 /* comma operator */
4878 /*----------------------------*/
4880 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4881 printTypeChain(tree->ftype,outfile);
4882 fprintf(outfile,")\n");
4883 ast_print(tree->left,outfile,indent+2);
4884 ast_print(tree->right,outfile,indent+2);
4886 /*------------------------------------------------------------------*/
4887 /*----------------------------*/
4889 /*----------------------------*/
4892 fprintf(outfile,"CALL (%p) type (",tree);
4893 printTypeChain(tree->ftype,outfile);
4894 fprintf(outfile,")\n");
4895 ast_print(tree->left,outfile,indent+2);
4896 ast_print(tree->right,outfile,indent+2);
4899 fprintf(outfile,"PARMS\n");
4900 ast_print(tree->left,outfile,indent+2);
4901 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4902 ast_print(tree->right,outfile,indent+2);
4905 /*------------------------------------------------------------------*/
4906 /*----------------------------*/
4907 /* return statement */
4908 /*----------------------------*/
4910 fprintf(outfile,"RETURN (%p) type (",tree);
4912 printTypeChain(tree->right->ftype,outfile);
4914 fprintf(outfile,")\n");
4915 ast_print(tree->right,outfile,indent+2);
4917 /*------------------------------------------------------------------*/
4918 /*----------------------------*/
4919 /* label statement */
4920 /*----------------------------*/
4922 fprintf(outfile,"LABEL (%p)\n",tree);
4923 ast_print(tree->left,outfile,indent+2);
4924 ast_print(tree->right,outfile,indent);
4926 /*------------------------------------------------------------------*/
4927 /*----------------------------*/
4928 /* switch statement */
4929 /*----------------------------*/
4933 fprintf(outfile,"SWITCH (%p) ",tree);
4934 ast_print(tree->left,outfile,0);
4935 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4936 INDENT(indent+2,outfile);
4937 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4938 (int) floatFromVal(val),
4939 tree->values.switchVals.swNum,
4940 (int) floatFromVal(val));
4942 ast_print(tree->right,outfile,indent);
4945 /*------------------------------------------------------------------*/
4946 /*----------------------------*/
4948 /*----------------------------*/
4950 fprintf(outfile,"IF (%p) \n",tree);
4951 ast_print(tree->left,outfile,indent+2);
4952 if (tree->trueLabel) {
4953 INDENT(indent,outfile);
4954 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4956 if (tree->falseLabel) {
4957 INDENT(indent,outfile);
4958 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4960 ast_print(tree->right,outfile,indent+2);
4962 /*------------------------------------------------------------------*/
4963 /*----------------------------*/
4965 /*----------------------------*/
4967 fprintf(outfile,"FOR (%p) \n",tree);
4968 if (AST_FOR( tree, initExpr)) {
4969 INDENT(indent+2,outfile);
4970 fprintf(outfile,"INIT EXPR ");
4971 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4973 if (AST_FOR( tree, condExpr)) {
4974 INDENT(indent+2,outfile);
4975 fprintf(outfile,"COND EXPR ");
4976 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4978 if (AST_FOR( tree, loopExpr)) {
4979 INDENT(indent+2,outfile);
4980 fprintf(outfile,"LOOP EXPR ");
4981 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4983 fprintf(outfile,"FOR LOOP BODY \n");
4984 ast_print(tree->left,outfile,indent+2);
4993 ast_print(t,stdout,0);