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 ? 1 : 0;
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);
756 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
760 /*-----------------------------------------------------------------*/
761 /* createIvalType - generates ival for basic types */
762 /*-----------------------------------------------------------------*/
764 createIvalType (ast * sym, sym_link * type, initList * ilist)
768 /* if initList is deep */
769 if (ilist->type == INIT_DEEP)
770 ilist = ilist->init.deep;
772 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
773 return decorateType (newNode ('=', sym, iExpr));
776 /*-----------------------------------------------------------------*/
777 /* createIvalStruct - generates initial value for structures */
778 /*-----------------------------------------------------------------*/
780 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
787 sflds = SPEC_STRUCT (type)->fields;
788 if (ilist->type != INIT_DEEP)
790 werror (E_INIT_STRUCT, "");
794 iloop = ilist->init.deep;
796 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
798 /* if we have come to end */
802 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
803 lAst = decorateType (resolveSymbols (lAst));
804 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
808 werror (W_EXCESS_INITIALIZERS, "struct",
809 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
816 /*-----------------------------------------------------------------*/
817 /* createIvalArray - generates code for array initialization */
818 /*-----------------------------------------------------------------*/
820 createIvalArray (ast * sym, sym_link * type, initList * ilist)
824 int lcnt = 0, size = 0;
825 literalList *literalL;
827 /* take care of the special case */
828 /* array of characters can be init */
830 if (IS_CHAR (type->next))
831 if ((rast = createIvalCharPtr (sym,
833 decorateType (resolveSymbols (list2expr (ilist))))))
835 return decorateType (resolveSymbols (rast));
837 /* not the special case */
838 if (ilist->type != INIT_DEEP)
840 werror (E_INIT_STRUCT, "");
844 iloop = ilist->init.deep;
845 lcnt = DCL_ELEM (type);
847 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
851 aSym = decorateType (resolveSymbols(sym));
853 rast = newNode(ARRAYINIT, aSym, NULL);
854 rast->values.constlist = literalL;
856 // Make sure size is set to length of initializer list.
863 if (lcnt && size > lcnt)
865 // Array size was specified, and we have more initializers than needed.
866 char *name=sym->opval.val->sym->name;
867 int lineno=sym->opval.val->sym->lineDef;
869 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
878 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
879 aSym = decorateType (resolveSymbols (aSym));
880 rast = createIval (aSym, type->next, iloop, rast);
881 iloop = (iloop ? iloop->next : NULL);
887 /* no of elements given and we */
888 /* have generated for all of them */
891 // there has to be a better way
892 char *name=sym->opval.val->sym->name;
893 int lineno=sym->opval.val->sym->lineDef;
894 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
901 /* if we have not been given a size */
902 if (!DCL_ELEM (type))
904 DCL_ELEM (type) = size;
907 return decorateType (resolveSymbols (rast));
911 /*-----------------------------------------------------------------*/
912 /* createIvalCharPtr - generates initial values for char pointers */
913 /*-----------------------------------------------------------------*/
915 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
919 /* if this is a pointer & right is a literal array then */
920 /* just assignment will do */
921 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
922 SPEC_SCLS (iexpr->etype) == S_CODE)
923 && IS_ARRAY (iexpr->ftype)))
924 return newNode ('=', sym, iexpr);
926 /* left side is an array so we have to assign each */
928 if ((IS_LITERAL (iexpr->etype) ||
929 SPEC_SCLS (iexpr->etype) == S_CODE)
930 && IS_ARRAY (iexpr->ftype))
932 /* for each character generate an assignment */
933 /* to the array element */
934 char *s = SPEC_CVAL (iexpr->etype).v_char;
939 rast = newNode (NULLOP,
943 newAst_VALUE (valueFromLit ((float) i))),
944 newAst_VALUE (valueFromLit (*s))));
948 rast = newNode (NULLOP,
952 newAst_VALUE (valueFromLit ((float) i))),
953 newAst_VALUE (valueFromLit (*s))));
955 // now we don't need iexpr's symbol anymore
957 symbol *sym=AST_SYMBOL(iexpr);
958 memmap *segment=SPEC_OCLS(sym->etype);
959 deleteSetItem(&segment->syms, sym);
961 return decorateType (resolveSymbols (rast));
967 /*-----------------------------------------------------------------*/
968 /* createIvalPtr - generates initial value for pointers */
969 /*-----------------------------------------------------------------*/
971 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
977 if (ilist->type == INIT_DEEP)
978 ilist = ilist->init.deep;
980 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
982 /* if character pointer */
983 if (IS_CHAR (type->next))
984 if ((rast = createIvalCharPtr (sym, type, iexpr)))
987 return newNode ('=', sym, iexpr);
990 /*-----------------------------------------------------------------*/
991 /* createIval - generates code for initial value */
992 /*-----------------------------------------------------------------*/
994 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1001 /* if structure then */
1002 if (IS_STRUCT (type))
1003 rast = createIvalStruct (sym, type, ilist);
1005 /* if this is a pointer */
1007 rast = createIvalPtr (sym, type, ilist);
1009 /* if this is an array */
1010 if (IS_ARRAY (type))
1011 rast = createIvalArray (sym, type, ilist);
1013 /* if type is SPECIFIER */
1015 rast = createIvalType (sym, type, ilist);
1018 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1020 return decorateType (resolveSymbols (rast));
1023 /*-----------------------------------------------------------------*/
1024 /* initAggregates - initialises aggregate variables with initv */
1025 /*-----------------------------------------------------------------*/
1026 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1027 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1030 /*-----------------------------------------------------------------*/
1031 /* gatherAutoInit - creates assignment expressions for initial */
1033 /*-----------------------------------------------------------------*/
1035 gatherAutoInit (symbol * autoChain)
1042 for (sym = autoChain; sym; sym = sym->next)
1045 /* resolve the symbols in the ival */
1047 resolveIvalSym (sym->ival);
1049 /* if this is a static variable & has an */
1050 /* initial value the code needs to be lifted */
1051 /* here to the main portion since they can be */
1052 /* initialised only once at the start */
1053 if (IS_STATIC (sym->etype) && sym->ival &&
1054 SPEC_SCLS (sym->etype) != S_CODE)
1058 /* insert the symbol into the symbol table */
1059 /* with level = 0 & name = rname */
1060 newSym = copySymbol (sym);
1061 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1063 /* now lift the code to main */
1064 if (IS_AGGREGATE (sym->type)) {
1065 work = initAggregates (sym, sym->ival, NULL);
1067 if (getNelements(sym->type, sym->ival)>1) {
1068 werror (W_EXCESS_INITIALIZERS, "scalar",
1069 sym->name, sym->lineDef);
1071 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1072 list2expr (sym->ival));
1075 setAstLineno (work, sym->lineDef);
1079 staticAutos = newNode (NULLOP, staticAutos, work);
1086 /* if there is an initial value */
1087 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1089 if (IS_AGGREGATE (sym->type)) {
1090 work = initAggregates (sym, sym->ival, NULL);
1092 if (getNelements(sym->type, sym->ival)>1) {
1093 werror (W_EXCESS_INITIALIZERS, "scalar",
1094 sym->name, sym->lineDef);
1096 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1097 list2expr (sym->ival));
1100 setAstLineno (work, sym->lineDef);
1103 init = newNode (NULLOP, init, work);
1112 /*-----------------------------------------------------------------*/
1113 /* stringToSymbol - creates a symbol from a literal string */
1114 /*-----------------------------------------------------------------*/
1116 stringToSymbol (value * val)
1118 char name[SDCC_NAME_MAX + 1];
1119 static int charLbl = 0;
1122 sprintf (name, "_str_%d", charLbl++);
1123 sym = newSymbol (name, 0); /* make it @ level 0 */
1124 strcpy (sym->rname, name);
1126 /* copy the type from the value passed */
1127 sym->type = copyLinkChain (val->type);
1128 sym->etype = getSpec (sym->type);
1129 /* change to storage class & output class */
1130 SPEC_SCLS (sym->etype) = S_CODE;
1131 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1132 SPEC_STAT (sym->etype) = 1;
1133 /* make the level & block = 0 */
1134 sym->block = sym->level = 0;
1136 /* create an ival */
1137 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1142 allocVariables (sym);
1145 return symbolVal (sym);
1149 /*-----------------------------------------------------------------*/
1150 /* processBlockVars - will go thru the ast looking for block if */
1151 /* a block is found then will allocate the syms */
1152 /* will also gather the auto inits present */
1153 /*-----------------------------------------------------------------*/
1155 processBlockVars (ast * tree, int *stack, int action)
1160 /* if this is a block */
1161 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1165 if (action == ALLOCATE)
1167 *stack += allocVariables (tree->values.sym);
1168 autoInit = gatherAutoInit (tree->values.sym);
1170 /* if there are auto inits then do them */
1172 tree->left = newNode (NULLOP, autoInit, tree->left);
1174 else /* action is deallocate */
1175 deallocLocal (tree->values.sym);
1178 processBlockVars (tree->left, stack, action);
1179 processBlockVars (tree->right, stack, action);
1183 /*-------------------------------------------------------------*/
1184 /* constExprTree - returns TRUE if this tree is a constant */
1186 /*-------------------------------------------------------------*/
1187 bool constExprTree (ast *cexpr) {
1193 cexpr = decorateType (resolveSymbols (cexpr));
1195 switch (cexpr->type)
1198 if (IS_AST_LIT_VALUE(cexpr)) {
1199 // this is a literal
1202 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1203 // a function's address will never change
1206 if (IS_AST_SYM_VALUE(cexpr) &&
1207 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1208 // a symbol in code space will never change
1209 // This is only for the 'char *s="hallo"' case and will have to leave
1214 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1215 "unexpected link in expression tree\n");
1218 if (cexpr->opval.op==ARRAYINIT) {
1219 // this is a list of literals
1222 if (cexpr->opval.op=='=') {
1223 return constExprTree(cexpr->right);
1225 if (cexpr->opval.op==CAST) {
1226 // jwk: cast ignored, maybe we should throw a warning here
1227 return constExprTree(cexpr->right);
1229 if (cexpr->opval.op=='&') {
1232 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1235 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1242 /*-----------------------------------------------------------------*/
1243 /* constExprValue - returns the value of a constant expression */
1244 /* or NULL if it is not a constant expression */
1245 /*-----------------------------------------------------------------*/
1247 constExprValue (ast * cexpr, int check)
1249 cexpr = decorateType (resolveSymbols (cexpr));
1251 /* if this is not a constant then */
1252 if (!IS_LITERAL (cexpr->ftype))
1254 /* then check if this is a literal array
1256 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1257 SPEC_CVAL (cexpr->etype).v_char &&
1258 IS_ARRAY (cexpr->ftype))
1260 value *val = valFromType (cexpr->ftype);
1261 SPEC_SCLS (val->etype) = S_LITERAL;
1262 val->sym = cexpr->opval.val->sym;
1263 val->sym->type = copyLinkChain (cexpr->ftype);
1264 val->sym->etype = getSpec (val->sym->type);
1265 strcpy (val->name, cexpr->opval.val->sym->rname);
1269 /* if we are casting a literal value then */
1270 if (IS_AST_OP (cexpr) &&
1271 cexpr->opval.op == CAST &&
1272 IS_LITERAL (cexpr->right->ftype))
1273 return valCastLiteral (cexpr->ftype,
1274 floatFromVal (cexpr->right->opval.val));
1276 if (IS_AST_VALUE (cexpr))
1277 return cexpr->opval.val;
1280 werror (E_CONST_EXPECTED, "found expression");
1285 /* return the value */
1286 return cexpr->opval.val;
1290 /*-----------------------------------------------------------------*/
1291 /* isLabelInAst - will return true if a given label is found */
1292 /*-----------------------------------------------------------------*/
1294 isLabelInAst (symbol * label, ast * tree)
1296 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1299 if (IS_AST_OP (tree) &&
1300 tree->opval.op == LABEL &&
1301 isSymbolEqual (AST_SYMBOL (tree->left), label))
1304 return isLabelInAst (label, tree->right) &&
1305 isLabelInAst (label, tree->left);
1309 /*-----------------------------------------------------------------*/
1310 /* isLoopCountable - return true if the loop count can be determi- */
1311 /* -ned at compile time . */
1312 /*-----------------------------------------------------------------*/
1314 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1315 symbol ** sym, ast ** init, ast ** end)
1318 /* the loop is considered countable if the following
1319 conditions are true :-
1321 a) initExpr :- <sym> = <const>
1322 b) condExpr :- <sym> < <const1>
1323 c) loopExpr :- <sym> ++
1326 /* first check the initExpr */
1327 if (IS_AST_OP (initExpr) &&
1328 initExpr->opval.op == '=' && /* is assignment */
1329 IS_AST_SYM_VALUE (initExpr->left))
1330 { /* left is a symbol */
1332 *sym = AST_SYMBOL (initExpr->left);
1333 *init = initExpr->right;
1338 /* for now the symbol has to be of
1340 if (!IS_INTEGRAL ((*sym)->type))
1343 /* now check condExpr */
1344 if (IS_AST_OP (condExpr))
1347 switch (condExpr->opval.op)
1350 if (IS_AST_SYM_VALUE (condExpr->left) &&
1351 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1352 IS_AST_LIT_VALUE (condExpr->right))
1354 *end = condExpr->right;
1360 if (IS_AST_OP (condExpr->left) &&
1361 condExpr->left->opval.op == '>' &&
1362 IS_AST_LIT_VALUE (condExpr->left->right) &&
1363 IS_AST_SYM_VALUE (condExpr->left->left) &&
1364 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1367 *end = newNode ('+', condExpr->left->right,
1368 newAst_VALUE (constVal ("1")));
1379 /* check loop expression is of the form <sym>++ */
1380 if (!IS_AST_OP (loopExpr))
1383 /* check if <sym> ++ */
1384 if (loopExpr->opval.op == INC_OP)
1390 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1391 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1398 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1399 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1407 if (loopExpr->opval.op == ADD_ASSIGN)
1410 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1411 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1412 IS_AST_LIT_VALUE (loopExpr->right) &&
1413 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1421 /*-----------------------------------------------------------------*/
1422 /* astHasVolatile - returns true if ast contains any volatile */
1423 /*-----------------------------------------------------------------*/
1425 astHasVolatile (ast * tree)
1430 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1433 if (IS_AST_OP (tree))
1434 return astHasVolatile (tree->left) ||
1435 astHasVolatile (tree->right);
1440 /*-----------------------------------------------------------------*/
1441 /* astHasPointer - return true if the ast contains any ptr variable */
1442 /*-----------------------------------------------------------------*/
1444 astHasPointer (ast * tree)
1449 if (IS_AST_LINK (tree))
1452 /* if we hit an array expression then check
1453 only the left side */
1454 if (IS_AST_OP (tree) && tree->opval.op == '[')
1455 return astHasPointer (tree->left);
1457 if (IS_AST_VALUE (tree))
1458 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1460 return astHasPointer (tree->left) ||
1461 astHasPointer (tree->right);
1465 /*-----------------------------------------------------------------*/
1466 /* astHasSymbol - return true if the ast has the given symbol */
1467 /*-----------------------------------------------------------------*/
1469 astHasSymbol (ast * tree, symbol * sym)
1471 if (!tree || IS_AST_LINK (tree))
1474 if (IS_AST_VALUE (tree))
1476 if (IS_AST_SYM_VALUE (tree))
1477 return isSymbolEqual (AST_SYMBOL (tree), sym);
1482 return astHasSymbol (tree->left, sym) ||
1483 astHasSymbol (tree->right, sym);
1486 /*-----------------------------------------------------------------*/
1487 /* astHasDeref - return true if the ast has an indirect access */
1488 /*-----------------------------------------------------------------*/
1490 astHasDeref (ast * tree)
1492 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1495 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1497 return astHasDeref (tree->left) || astHasDeref (tree->right);
1500 /*-----------------------------------------------------------------*/
1501 /* isConformingBody - the loop body has to conform to a set of rules */
1502 /* for the loop to be considered reversible read on for rules */
1503 /*-----------------------------------------------------------------*/
1505 isConformingBody (ast * pbody, symbol * sym, ast * body)
1508 /* we are going to do a pre-order traversal of the
1509 tree && check for the following conditions. (essentially
1510 a set of very shallow tests )
1511 a) the sym passed does not participate in
1512 any arithmetic operation
1513 b) There are no function calls
1514 c) all jumps are within the body
1515 d) address of loop control variable not taken
1516 e) if an assignment has a pointer on the
1517 left hand side make sure right does not have
1518 loop control variable */
1520 /* if we reach the end or a leaf then true */
1521 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1525 /* if anything else is "volatile" */
1526 if (IS_VOLATILE (TETYPE (pbody)))
1529 /* we will walk the body in a pre-order traversal for
1531 switch (pbody->opval.op)
1533 /*------------------------------------------------------------------*/
1535 return isConformingBody (pbody->right, sym, body);
1537 /*------------------------------------------------------------------*/
1542 /*------------------------------------------------------------------*/
1543 case INC_OP: /* incerement operator unary so left only */
1546 /* sure we are not sym is not modified */
1548 IS_AST_SYM_VALUE (pbody->left) &&
1549 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1553 IS_AST_SYM_VALUE (pbody->right) &&
1554 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1559 /*------------------------------------------------------------------*/
1561 case '*': /* can be unary : if right is null then unary operation */
1566 /* if right is NULL then unary operation */
1567 /*------------------------------------------------------------------*/
1568 /*----------------------------*/
1570 /*----------------------------*/
1573 if (IS_AST_SYM_VALUE (pbody->left) &&
1574 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1577 return isConformingBody (pbody->left, sym, body);
1581 if (astHasSymbol (pbody->left, sym) ||
1582 astHasSymbol (pbody->right, sym))
1587 /*------------------------------------------------------------------*/
1595 if (IS_AST_SYM_VALUE (pbody->left) &&
1596 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1599 if (IS_AST_SYM_VALUE (pbody->right) &&
1600 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1603 return isConformingBody (pbody->left, sym, body) &&
1604 isConformingBody (pbody->right, sym, body);
1611 if (IS_AST_SYM_VALUE (pbody->left) &&
1612 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1614 return isConformingBody (pbody->left, sym, body);
1616 /*------------------------------------------------------------------*/
1628 case SIZEOF: /* evaluate wihout code generation */
1630 return isConformingBody (pbody->left, sym, body) &&
1631 isConformingBody (pbody->right, sym, body);
1633 /*------------------------------------------------------------------*/
1636 /* if left has a pointer & right has loop
1637 control variable then we cannot */
1638 if (astHasPointer (pbody->left) &&
1639 astHasSymbol (pbody->right, sym))
1641 if (astHasVolatile (pbody->left))
1644 if (IS_AST_SYM_VALUE (pbody->left)) {
1645 // if the loopvar has an assignment
1646 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1648 // if the loopvar is used in another (maybe conditional) block
1649 if (astHasSymbol (pbody->right, sym) &&
1650 (pbody->level > body->level)) {
1655 if (astHasVolatile (pbody->left))
1658 if (astHasDeref(pbody->right)) return FALSE;
1660 return isConformingBody (pbody->left, sym, body) &&
1661 isConformingBody (pbody->right, sym, body);
1672 assert ("Parser should not have generated this\n");
1674 /*------------------------------------------------------------------*/
1675 /*----------------------------*/
1676 /* comma operator */
1677 /*----------------------------*/
1679 return isConformingBody (pbody->left, sym, body) &&
1680 isConformingBody (pbody->right, sym, body);
1682 /*------------------------------------------------------------------*/
1683 /*----------------------------*/
1685 /*----------------------------*/
1687 /* if local & not passed as paramater then ok */
1688 if (sym->level && !astHasSymbol(pbody->right,sym))
1692 /*------------------------------------------------------------------*/
1693 /*----------------------------*/
1694 /* return statement */
1695 /*----------------------------*/
1700 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1705 if (astHasSymbol (pbody->left, sym))
1712 return isConformingBody (pbody->left, sym, body) &&
1713 isConformingBody (pbody->right, sym, body);
1719 /*-----------------------------------------------------------------*/
1720 /* isLoopReversible - takes a for loop as input && returns true */
1721 /* if the for loop is reversible. If yes will set the value of */
1722 /* the loop control var & init value & termination value */
1723 /*-----------------------------------------------------------------*/
1725 isLoopReversible (ast * loop, symbol ** loopCntrl,
1726 ast ** init, ast ** end)
1728 /* if option says don't do it then don't */
1729 if (optimize.noLoopReverse)
1731 /* there are several tests to determine this */
1733 /* for loop has to be of the form
1734 for ( <sym> = <const1> ;
1735 [<sym> < <const2>] ;
1736 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1738 if (!isLoopCountable (AST_FOR (loop, initExpr),
1739 AST_FOR (loop, condExpr),
1740 AST_FOR (loop, loopExpr),
1741 loopCntrl, init, end))
1744 /* now do some serious checking on the body of the loop
1747 return isConformingBody (loop->left, *loopCntrl, loop->left);
1751 /*-----------------------------------------------------------------*/
1752 /* replLoopSym - replace the loop sym by loop sym -1 */
1753 /*-----------------------------------------------------------------*/
1755 replLoopSym (ast * body, symbol * sym)
1758 if (!body || IS_AST_LINK (body))
1761 if (IS_AST_SYM_VALUE (body))
1764 if (isSymbolEqual (AST_SYMBOL (body), sym))
1768 body->opval.op = '-';
1769 body->left = newAst_VALUE (symbolVal (sym));
1770 body->right = newAst_VALUE (constVal ("1"));
1778 replLoopSym (body->left, sym);
1779 replLoopSym (body->right, sym);
1783 /*-----------------------------------------------------------------*/
1784 /* reverseLoop - do the actual loop reversal */
1785 /*-----------------------------------------------------------------*/
1787 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1791 /* create the following tree
1796 if (sym) goto for_continue ;
1799 /* put it together piece by piece */
1800 rloop = newNode (NULLOP,
1801 createIf (newAst_VALUE (symbolVal (sym)),
1803 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1806 newAst_VALUE (symbolVal (sym)),
1809 replLoopSym (loop->left, sym);
1811 rloop = newNode (NULLOP,
1813 newAst_VALUE (symbolVal (sym)),
1814 newNode ('-', end, init)),
1815 createLabel (AST_FOR (loop, continueLabel),
1819 newNode (SUB_ASSIGN,
1820 newAst_VALUE (symbolVal (sym)),
1821 newAst_VALUE (constVal ("1"))),
1824 return decorateType (rloop);
1828 /*-----------------------------------------------------------------*/
1829 /* decorateType - compute type for this tree also does type cheking */
1830 /* this is done bottom up, since type have to flow upwards */
1831 /* it also does constant folding, and paramater checking */
1832 /*-----------------------------------------------------------------*/
1834 decorateType (ast * tree)
1842 /* if already has type then do nothing */
1843 if (tree->decorated)
1846 tree->decorated = 1;
1848 /* print the line */
1849 /* if not block & function */
1850 if (tree->type == EX_OP &&
1851 (tree->opval.op != FUNCTION &&
1852 tree->opval.op != BLOCK &&
1853 tree->opval.op != NULLOP))
1855 filename = tree->filename;
1856 lineno = tree->lineno;
1859 /* if any child is an error | this one is an error do nothing */
1860 if (tree->isError ||
1861 (tree->left && tree->left->isError) ||
1862 (tree->right && tree->right->isError))
1865 /*------------------------------------------------------------------*/
1866 /*----------------------------*/
1867 /* leaf has been reached */
1868 /*----------------------------*/
1869 /* if this is of type value */
1870 /* just get the type */
1871 if (tree->type == EX_VALUE)
1874 if (IS_LITERAL (tree->opval.val->etype))
1877 /* if this is a character array then declare it */
1878 if (IS_ARRAY (tree->opval.val->type))
1879 tree->opval.val = stringToSymbol (tree->opval.val);
1881 /* otherwise just copy the type information */
1882 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1886 if (tree->opval.val->sym)
1888 /* if the undefined flag is set then give error message */
1889 if (tree->opval.val->sym->undefined)
1891 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1893 TTYPE (tree) = TETYPE (tree) =
1894 tree->opval.val->type = tree->opval.val->sym->type =
1895 tree->opval.val->etype = tree->opval.val->sym->etype =
1896 copyLinkChain (INTTYPE);
1901 /* if impilicit i.e. struct/union member then no type */
1902 if (tree->opval.val->sym->implicit)
1903 TTYPE (tree) = TETYPE (tree) = NULL;
1908 /* else copy the type */
1909 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1911 /* and mark it as referenced */
1912 tree->opval.val->sym->isref = 1;
1920 /* if type link for the case of cast */
1921 if (tree->type == EX_LINK)
1923 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1930 dtl = decorateType (tree->left);
1931 /* delay right side for '?' operator since conditional macro expansions might
1933 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1935 /* this is to take care of situations
1936 when the tree gets rewritten */
1937 if (dtl != tree->left)
1939 if (dtr != tree->right)
1943 /* depending on type of operator do */
1945 switch (tree->opval.op)
1947 /*------------------------------------------------------------------*/
1948 /*----------------------------*/
1950 /*----------------------------*/
1953 /* determine which is the array & which the index */
1954 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1957 ast *tempTree = tree->left;
1958 tree->left = tree->right;
1959 tree->right = tempTree;
1962 /* first check if this is a array or a pointer */
1963 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1965 werror (E_NEED_ARRAY_PTR, "[]");
1966 goto errorTreeReturn;
1969 /* check if the type of the idx */
1970 if (!IS_INTEGRAL (RTYPE (tree)))
1972 werror (E_IDX_NOT_INT);
1973 goto errorTreeReturn;
1976 /* if the left is an rvalue then error */
1979 werror (E_LVALUE_REQUIRED, "array access");
1980 goto errorTreeReturn;
1983 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1984 if (IS_PTR(LTYPE(tree))) {
1985 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1989 /*------------------------------------------------------------------*/
1990 /*----------------------------*/
1992 /*----------------------------*/
1994 /* if this is not a structure */
1995 if (!IS_STRUCT (LTYPE (tree)))
1997 werror (E_STRUCT_UNION, ".");
1998 goto errorTreeReturn;
2000 TTYPE (tree) = structElemType (LTYPE (tree),
2001 (tree->right->type == EX_VALUE ?
2002 tree->right->opval.val : NULL));
2003 TETYPE (tree) = getSpec (TTYPE (tree));
2006 /*------------------------------------------------------------------*/
2007 /*----------------------------*/
2008 /* struct/union pointer */
2009 /*----------------------------*/
2011 /* if not pointer to a structure */
2012 if (!IS_PTR (LTYPE (tree)))
2014 werror (E_PTR_REQD);
2015 goto errorTreeReturn;
2018 if (!IS_STRUCT (LTYPE (tree)->next))
2020 werror (E_STRUCT_UNION, "->");
2021 goto errorTreeReturn;
2024 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2025 (tree->right->type == EX_VALUE ?
2026 tree->right->opval.val : NULL));
2027 TETYPE (tree) = getSpec (TTYPE (tree));
2029 /* adjust the storage class */
2030 switch (DCL_TYPE(tree->left->ftype)) {
2034 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2037 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2042 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2045 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2048 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2057 /*------------------------------------------------------------------*/
2058 /*----------------------------*/
2059 /* ++/-- operation */
2060 /*----------------------------*/
2061 case INC_OP: /* incerement operator unary so left only */
2064 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2065 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2066 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2067 werror (E_CODE_WRITE, "++/--");
2076 /*------------------------------------------------------------------*/
2077 /*----------------------------*/
2079 /*----------------------------*/
2080 case '&': /* can be unary */
2081 /* if right is NULL then unary operation */
2082 if (tree->right) /* not an unary operation */
2085 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2087 werror (E_BITWISE_OP);
2088 werror (W_CONTINUE, "left & right types are ");
2089 printTypeChain (LTYPE (tree), stderr);
2090 fprintf (stderr, ",");
2091 printTypeChain (RTYPE (tree), stderr);
2092 fprintf (stderr, "\n");
2093 goto errorTreeReturn;
2096 /* if they are both literal */
2097 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2099 tree->type = EX_VALUE;
2100 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2101 valFromType (RETYPE (tree)), '&');
2103 tree->right = tree->left = NULL;
2104 TETYPE (tree) = tree->opval.val->etype;
2105 TTYPE (tree) = tree->opval.val->type;
2109 /* see if this is a GETHBIT operation if yes
2112 ast *otree = optimizeGetHbit (tree);
2115 return decorateType (otree);
2119 computeType (LTYPE (tree), RTYPE (tree));
2120 TETYPE (tree) = getSpec (TTYPE (tree));
2122 LRVAL (tree) = RRVAL (tree) = 1;
2126 /*------------------------------------------------------------------*/
2127 /*----------------------------*/
2129 /*----------------------------*/
2131 p->class = DECLARATOR;
2132 /* if bit field then error */
2133 if (IS_BITVAR (tree->left->etype))
2135 werror (E_ILLEGAL_ADDR, "address of bit variable");
2136 goto errorTreeReturn;
2139 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2141 werror (E_ILLEGAL_ADDR, "address of register variable");
2142 goto errorTreeReturn;
2145 if (IS_FUNC (LTYPE (tree)))
2147 werror (E_ILLEGAL_ADDR, "address of function");
2148 goto errorTreeReturn;
2151 if (IS_LITERAL(LTYPE(tree)))
2153 werror (E_ILLEGAL_ADDR, "address of literal");
2154 goto errorTreeReturn;
2159 werror (E_LVALUE_REQUIRED, "address of");
2160 goto errorTreeReturn;
2162 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2164 DCL_TYPE (p) = CPOINTER;
2165 DCL_PTR_CONST (p) = port->mem.code_ro;
2167 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2168 DCL_TYPE (p) = FPOINTER;
2169 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2170 DCL_TYPE (p) = PPOINTER;
2171 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2172 DCL_TYPE (p) = IPOINTER;
2173 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2174 DCL_TYPE (p) = EEPPOINTER;
2175 else if (SPEC_OCLS(tree->left->etype))
2176 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2178 DCL_TYPE (p) = POINTER;
2180 if (IS_AST_SYM_VALUE (tree->left))
2182 AST_SYMBOL (tree->left)->addrtaken = 1;
2183 AST_SYMBOL (tree->left)->allocreq = 1;
2186 p->next = LTYPE (tree);
2188 TETYPE (tree) = getSpec (TTYPE (tree));
2189 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2190 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2195 /*------------------------------------------------------------------*/
2196 /*----------------------------*/
2198 /*----------------------------*/
2200 /* if the rewrite succeeds then don't go any furthur */
2202 ast *wtree = optimizeRRCRLC (tree);
2204 return decorateType (wtree);
2206 /*------------------------------------------------------------------*/
2207 /*----------------------------*/
2209 /*----------------------------*/
2211 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2213 werror (E_BITWISE_OP);
2214 werror (W_CONTINUE, "left & right types are ");
2215 printTypeChain (LTYPE (tree), stderr);
2216 fprintf (stderr, ",");
2217 printTypeChain (RTYPE (tree), stderr);
2218 fprintf (stderr, "\n");
2219 goto errorTreeReturn;
2222 /* if they are both literal then */
2223 /* rewrite the tree */
2224 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2226 tree->type = EX_VALUE;
2227 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2228 valFromType (RETYPE (tree)),
2230 tree->right = tree->left = NULL;
2231 TETYPE (tree) = tree->opval.val->etype;
2232 TTYPE (tree) = tree->opval.val->type;
2235 LRVAL (tree) = RRVAL (tree) = 1;
2236 TETYPE (tree) = getSpec (TTYPE (tree) =
2237 computeType (LTYPE (tree),
2240 /*------------------------------------------------------------------*/
2241 /*----------------------------*/
2243 /*----------------------------*/
2245 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2247 werror (E_INVALID_OP, "divide");
2248 goto errorTreeReturn;
2250 /* if they are both literal then */
2251 /* rewrite the tree */
2252 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2254 tree->type = EX_VALUE;
2255 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2256 valFromType (RETYPE (tree)));
2257 tree->right = tree->left = NULL;
2258 TETYPE (tree) = getSpec (TTYPE (tree) =
2259 tree->opval.val->type);
2262 LRVAL (tree) = RRVAL (tree) = 1;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 computeType (LTYPE (tree),
2268 /*------------------------------------------------------------------*/
2269 /*----------------------------*/
2271 /*----------------------------*/
2273 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2275 werror (E_BITWISE_OP);
2276 werror (W_CONTINUE, "left & right types are ");
2277 printTypeChain (LTYPE (tree), stderr);
2278 fprintf (stderr, ",");
2279 printTypeChain (RTYPE (tree), stderr);
2280 fprintf (stderr, "\n");
2281 goto errorTreeReturn;
2283 /* if they are both literal then */
2284 /* rewrite the tree */
2285 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2287 tree->type = EX_VALUE;
2288 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2289 valFromType (RETYPE (tree)));
2290 tree->right = tree->left = NULL;
2291 TETYPE (tree) = getSpec (TTYPE (tree) =
2292 tree->opval.val->type);
2295 LRVAL (tree) = RRVAL (tree) = 1;
2296 TETYPE (tree) = getSpec (TTYPE (tree) =
2297 computeType (LTYPE (tree),
2301 /*------------------------------------------------------------------*/
2302 /*----------------------------*/
2303 /* address dereference */
2304 /*----------------------------*/
2305 case '*': /* can be unary : if right is null then unary operation */
2308 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2310 werror (E_PTR_REQD);
2311 goto errorTreeReturn;
2316 werror (E_LVALUE_REQUIRED, "pointer deref");
2317 goto errorTreeReturn;
2319 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2320 LTYPE (tree)->next : NULL);
2321 TETYPE (tree) = getSpec (TTYPE (tree));
2322 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2326 /*------------------------------------------------------------------*/
2327 /*----------------------------*/
2328 /* multiplication */
2329 /*----------------------------*/
2330 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2332 werror (E_INVALID_OP, "multiplication");
2333 goto errorTreeReturn;
2336 /* if they are both literal then */
2337 /* rewrite the tree */
2338 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2340 tree->type = EX_VALUE;
2341 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2342 valFromType (RETYPE (tree)));
2343 tree->right = tree->left = NULL;
2344 TETYPE (tree) = getSpec (TTYPE (tree) =
2345 tree->opval.val->type);
2349 /* if left is a literal exchange left & right */
2350 if (IS_LITERAL (LTYPE (tree)))
2352 ast *tTree = tree->left;
2353 tree->left = tree->right;
2354 tree->right = tTree;
2357 LRVAL (tree) = RRVAL (tree) = 1;
2358 /* promote result to int if left & right are char
2359 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2360 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2361 TETYPE (tree) = getSpec (TTYPE (tree) =
2362 computeType (LTYPE (tree),
2364 SPEC_NOUN(TETYPE(tree)) = V_INT;
2366 TETYPE (tree) = getSpec (TTYPE (tree) =
2367 computeType (LTYPE (tree),
2372 /*------------------------------------------------------------------*/
2373 /*----------------------------*/
2374 /* unary '+' operator */
2375 /*----------------------------*/
2380 if (!IS_INTEGRAL (LTYPE (tree)))
2382 werror (E_UNARY_OP, '+');
2383 goto errorTreeReturn;
2386 /* if left is a literal then do it */
2387 if (IS_LITERAL (LTYPE (tree)))
2389 tree->type = EX_VALUE;
2390 tree->opval.val = valFromType (LETYPE (tree));
2392 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2396 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2400 /*------------------------------------------------------------------*/
2401 /*----------------------------*/
2403 /*----------------------------*/
2405 /* this is not a unary operation */
2406 /* if both pointers then problem */
2407 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2408 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2410 werror (E_PTR_PLUS_PTR);
2411 goto errorTreeReturn;
2414 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2415 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2417 werror (E_PLUS_INVALID, "+");
2418 goto errorTreeReturn;
2421 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2422 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2424 werror (E_PLUS_INVALID, "+");
2425 goto errorTreeReturn;
2427 /* if they are both literal then */
2428 /* rewrite the tree */
2429 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2431 tree->type = EX_VALUE;
2432 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2433 valFromType (RETYPE (tree)));
2434 tree->right = tree->left = NULL;
2435 TETYPE (tree) = getSpec (TTYPE (tree) =
2436 tree->opval.val->type);
2440 /* if the right is a pointer or left is a literal
2441 xchange left & right */
2442 if (IS_ARRAY (RTYPE (tree)) ||
2443 IS_PTR (RTYPE (tree)) ||
2444 IS_LITERAL (LTYPE (tree)))
2446 ast *tTree = tree->left;
2447 tree->left = tree->right;
2448 tree->right = tTree;
2451 LRVAL (tree) = RRVAL (tree) = 1;
2452 /* if the left is a pointer */
2453 if (IS_PTR (LTYPE (tree)))
2454 TETYPE (tree) = getSpec (TTYPE (tree) =
2457 TETYPE (tree) = getSpec (TTYPE (tree) =
2458 computeType (LTYPE (tree),
2462 /*------------------------------------------------------------------*/
2463 /*----------------------------*/
2465 /*----------------------------*/
2466 case '-': /* can be unary */
2467 /* if right is null then unary */
2471 if (!IS_ARITHMETIC (LTYPE (tree)))
2473 werror (E_UNARY_OP, tree->opval.op);
2474 goto errorTreeReturn;
2477 /* if left is a literal then do it */
2478 if (IS_LITERAL (LTYPE (tree)))
2480 tree->type = EX_VALUE;
2481 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2483 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2484 SPEC_USIGN(TETYPE(tree)) = 0;
2488 TTYPE (tree) = LTYPE (tree);
2492 /*------------------------------------------------------------------*/
2493 /*----------------------------*/
2495 /*----------------------------*/
2497 if (!(IS_PTR (LTYPE (tree)) ||
2498 IS_ARRAY (LTYPE (tree)) ||
2499 IS_ARITHMETIC (LTYPE (tree))))
2501 werror (E_PLUS_INVALID, "-");
2502 goto errorTreeReturn;
2505 if (!(IS_PTR (RTYPE (tree)) ||
2506 IS_ARRAY (RTYPE (tree)) ||
2507 IS_ARITHMETIC (RTYPE (tree))))
2509 werror (E_PLUS_INVALID, "-");
2510 goto errorTreeReturn;
2513 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2514 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2515 IS_INTEGRAL (RTYPE (tree))))
2517 werror (E_PLUS_INVALID, "-");
2518 goto errorTreeReturn;
2521 /* if they are both literal then */
2522 /* rewrite the tree */
2523 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2525 tree->type = EX_VALUE;
2526 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2527 valFromType (RETYPE (tree)));
2528 tree->right = tree->left = NULL;
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 tree->opval.val->type);
2534 /* if the left & right are equal then zero */
2535 if (isAstEqual (tree->left, tree->right))
2537 tree->type = EX_VALUE;
2538 tree->left = tree->right = NULL;
2539 tree->opval.val = constVal ("0");
2540 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2544 /* if both of them are pointers or arrays then */
2545 /* the result is going to be an integer */
2546 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2547 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2548 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2550 /* if only the left is a pointer */
2551 /* then result is a pointer */
2552 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2553 TETYPE (tree) = getSpec (TTYPE (tree) =
2556 TETYPE (tree) = getSpec (TTYPE (tree) =
2557 computeType (LTYPE (tree),
2559 LRVAL (tree) = RRVAL (tree) = 1;
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2565 /*----------------------------*/
2567 /* can be only integral type */
2568 if (!IS_INTEGRAL (LTYPE (tree)))
2570 werror (E_UNARY_OP, tree->opval.op);
2571 goto errorTreeReturn;
2574 /* if left is a literal then do it */
2575 if (IS_LITERAL (LTYPE (tree)))
2577 tree->type = EX_VALUE;
2578 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2580 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2584 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2587 /*------------------------------------------------------------------*/
2588 /*----------------------------*/
2590 /*----------------------------*/
2592 /* can be pointer */
2593 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2594 !IS_PTR (LTYPE (tree)) &&
2595 !IS_ARRAY (LTYPE (tree)))
2597 werror (E_UNARY_OP, tree->opval.op);
2598 goto errorTreeReturn;
2601 /* if left is a literal then do it */
2602 if (IS_LITERAL (LTYPE (tree)))
2604 tree->type = EX_VALUE;
2605 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2607 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2611 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2614 /*------------------------------------------------------------------*/
2615 /*----------------------------*/
2617 /*----------------------------*/
2620 TTYPE (tree) = LTYPE (tree);
2621 TETYPE (tree) = LETYPE (tree);
2625 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2630 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2632 werror (E_SHIFT_OP_INVALID);
2633 werror (W_CONTINUE, "left & right types are ");
2634 printTypeChain (LTYPE (tree), stderr);
2635 fprintf (stderr, ",");
2636 printTypeChain (RTYPE (tree), stderr);
2637 fprintf (stderr, "\n");
2638 goto errorTreeReturn;
2641 /* if they are both literal then */
2642 /* rewrite the tree */
2643 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2645 tree->type = EX_VALUE;
2646 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2647 valFromType (RETYPE (tree)),
2648 (tree->opval.op == LEFT_OP ? 1 : 0));
2649 tree->right = tree->left = NULL;
2650 TETYPE (tree) = getSpec (TTYPE (tree) =
2651 tree->opval.val->type);
2654 /* if only the right side is a literal & we are
2655 shifting more than size of the left operand then zero */
2656 if (IS_LITERAL (RTYPE (tree)) &&
2657 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2658 (getSize (LTYPE (tree)) * 8))
2660 werror (W_SHIFT_CHANGED,
2661 (tree->opval.op == LEFT_OP ? "left" : "right"));
2662 tree->type = EX_VALUE;
2663 tree->left = tree->right = NULL;
2664 tree->opval.val = constVal ("0");
2665 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2668 LRVAL (tree) = RRVAL (tree) = 1;
2669 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2671 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2675 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2679 /*------------------------------------------------------------------*/
2680 /*----------------------------*/
2682 /*----------------------------*/
2683 case CAST: /* change the type */
2684 /* cannot cast to an aggregate type */
2685 if (IS_AGGREGATE (LTYPE (tree)))
2687 werror (E_CAST_ILLEGAL);
2688 goto errorTreeReturn;
2691 /* make sure the type is complete and sane */
2692 checkTypeSanity(LETYPE(tree), "(cast)");
2695 /* if the right is a literal replace the tree */
2696 if (IS_LITERAL (RETYPE (tree))) {
2697 if (!IS_PTR (LTYPE (tree))) {
2698 tree->type = EX_VALUE;
2700 valCastLiteral (LTYPE (tree),
2701 floatFromVal (valFromType (RETYPE (tree))));
2704 TTYPE (tree) = tree->opval.val->type;
2705 tree->values.literalFromCast = 1;
2706 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2707 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2708 sym_link *rest = LTYPE(tree)->next;
2709 werror(W_LITERAL_GENERIC);
2710 TTYPE(tree) = newLink();
2711 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2712 TTYPE(tree)->next = rest;
2713 tree->left->opval.lnk = TTYPE(tree);
2716 TTYPE (tree) = LTYPE (tree);
2720 TTYPE (tree) = LTYPE (tree);
2724 /* if pointer to struct then check names */
2725 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2726 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2727 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2728 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2730 /* if the right is a literal replace the tree */
2731 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2732 tree->type = EX_VALUE;
2734 valCastLiteral (LTYPE (tree),
2735 floatFromVal (valFromType (RETYPE (tree))));
2738 TTYPE (tree) = tree->opval.val->type;
2739 tree->values.literalFromCast = 1;
2741 TTYPE (tree) = LTYPE (tree);
2745 TETYPE (tree) = getSpec (TTYPE (tree));
2749 /*------------------------------------------------------------------*/
2750 /*----------------------------*/
2751 /* logical &&, || */
2752 /*----------------------------*/
2755 /* each must me arithmetic type or be a pointer */
2756 if (!IS_PTR (LTYPE (tree)) &&
2757 !IS_ARRAY (LTYPE (tree)) &&
2758 !IS_INTEGRAL (LTYPE (tree)))
2760 werror (E_COMPARE_OP);
2761 goto errorTreeReturn;
2764 if (!IS_PTR (RTYPE (tree)) &&
2765 !IS_ARRAY (RTYPE (tree)) &&
2766 !IS_INTEGRAL (RTYPE (tree)))
2768 werror (E_COMPARE_OP);
2769 goto errorTreeReturn;
2771 /* if they are both literal then */
2772 /* rewrite the tree */
2773 if (IS_LITERAL (RTYPE (tree)) &&
2774 IS_LITERAL (LTYPE (tree)))
2776 tree->type = EX_VALUE;
2777 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2778 valFromType (RETYPE (tree)),
2780 tree->right = tree->left = NULL;
2781 TETYPE (tree) = getSpec (TTYPE (tree) =
2782 tree->opval.val->type);
2785 LRVAL (tree) = RRVAL (tree) = 1;
2786 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2789 /*------------------------------------------------------------------*/
2790 /*----------------------------*/
2791 /* comparison operators */
2792 /*----------------------------*/
2800 ast *lt = optimizeCompare (tree);
2806 /* if they are pointers they must be castable */
2807 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2809 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2811 werror (E_COMPARE_OP);
2812 fprintf (stderr, "comparing type ");
2813 printTypeChain (LTYPE (tree), stderr);
2814 fprintf (stderr, "to type ");
2815 printTypeChain (RTYPE (tree), stderr);
2816 fprintf (stderr, "\n");
2817 goto errorTreeReturn;
2820 /* else they should be promotable to one another */
2823 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2824 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2826 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2828 werror (E_COMPARE_OP);
2829 fprintf (stderr, "comparing type ");
2830 printTypeChain (LTYPE (tree), stderr);
2831 fprintf (stderr, "to type ");
2832 printTypeChain (RTYPE (tree), stderr);
2833 fprintf (stderr, "\n");
2834 goto errorTreeReturn;
2837 /* if unsigned value < 0 then always false */
2838 /* if (unsigned value) > 0 then (unsigned value) */
2839 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2840 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2842 if (tree->opval.op == '<') {
2845 if (tree->opval.op == '>') {
2849 /* if they are both literal then */
2850 /* rewrite the tree */
2851 if (IS_LITERAL (RTYPE (tree)) &&
2852 IS_LITERAL (LTYPE (tree)))
2854 tree->type = EX_VALUE;
2855 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2856 valFromType (RETYPE (tree)),
2858 tree->right = tree->left = NULL;
2859 TETYPE (tree) = getSpec (TTYPE (tree) =
2860 tree->opval.val->type);
2863 LRVAL (tree) = RRVAL (tree) = 1;
2864 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2867 /*------------------------------------------------------------------*/
2868 /*----------------------------*/
2870 /*----------------------------*/
2871 case SIZEOF: /* evaluate wihout code generation */
2872 /* change the type to a integer */
2873 tree->type = EX_VALUE;
2874 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2875 tree->opval.val = constVal (buffer);
2876 tree->right = tree->left = NULL;
2877 TETYPE (tree) = getSpec (TTYPE (tree) =
2878 tree->opval.val->type);
2881 /*------------------------------------------------------------------*/
2882 /*----------------------------*/
2884 /*----------------------------*/
2886 /* return typeof enum value */
2887 tree->type = EX_VALUE;
2890 if (IS_SPEC(tree->right->ftype)) {
2891 switch (SPEC_NOUN(tree->right->ftype)) {
2893 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2894 else typeofv = TYPEOF_INT;
2897 typeofv = TYPEOF_FLOAT;
2900 typeofv = TYPEOF_CHAR;
2903 typeofv = TYPEOF_VOID;
2906 typeofv = TYPEOF_STRUCT;
2909 typeofv = TYPEOF_BIT;
2912 typeofv = TYPEOF_SBIT;
2918 switch (DCL_TYPE(tree->right->ftype)) {
2920 typeofv = TYPEOF_POINTER;
2923 typeofv = TYPEOF_FPOINTER;
2926 typeofv = TYPEOF_CPOINTER;
2929 typeofv = TYPEOF_GPOINTER;
2932 typeofv = TYPEOF_PPOINTER;
2935 typeofv = TYPEOF_IPOINTER;
2938 typeofv = TYPEOF_ARRAY;
2941 typeofv = TYPEOF_FUNCTION;
2947 sprintf (buffer, "%d", typeofv);
2948 tree->opval.val = constVal (buffer);
2949 tree->right = tree->left = NULL;
2950 TETYPE (tree) = getSpec (TTYPE (tree) =
2951 tree->opval.val->type);
2954 /*------------------------------------------------------------------*/
2955 /*----------------------------*/
2956 /* conditional operator '?' */
2957 /*----------------------------*/
2959 /* the type is value of the colon operator (on the right) */
2960 assert(IS_COLON_OP(tree->right));
2961 /* if already known then replace the tree : optimizer will do it
2962 but faster to do it here */
2963 if (IS_LITERAL (LTYPE(tree))) {
2964 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2965 return decorateType(tree->right->left) ;
2967 return decorateType(tree->right->right) ;
2970 tree->right = decorateType(tree->right);
2971 TTYPE (tree) = RTYPE(tree);
2972 TETYPE (tree) = getSpec (TTYPE (tree));
2977 /* if they don't match we have a problem */
2978 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2980 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2981 goto errorTreeReturn;
2984 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2985 TETYPE (tree) = getSpec (TTYPE (tree));
2989 #if 0 // assignment operators are converted by the parser
2990 /*------------------------------------------------------------------*/
2991 /*----------------------------*/
2992 /* assignment operators */
2993 /*----------------------------*/
2996 /* for these it must be both must be integral */
2997 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2998 !IS_ARITHMETIC (RTYPE (tree)))
3000 werror (E_OPS_INTEGRAL);
3001 goto errorTreeReturn;
3004 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3006 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3007 werror (E_CODE_WRITE, " ");
3011 werror (E_LVALUE_REQUIRED, "*= or /=");
3012 goto errorTreeReturn;
3023 /* for these it must be both must be integral */
3024 if (!IS_INTEGRAL (LTYPE (tree)) ||
3025 !IS_INTEGRAL (RTYPE (tree)))
3027 werror (E_OPS_INTEGRAL);
3028 goto errorTreeReturn;
3031 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3033 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3034 werror (E_CODE_WRITE, " ");
3038 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3039 goto errorTreeReturn;
3045 /*------------------------------------------------------------------*/
3046 /*----------------------------*/
3048 /*----------------------------*/
3050 if (!(IS_PTR (LTYPE (tree)) ||
3051 IS_ARITHMETIC (LTYPE (tree))))
3053 werror (E_PLUS_INVALID, "-=");
3054 goto errorTreeReturn;
3057 if (!(IS_PTR (RTYPE (tree)) ||
3058 IS_ARITHMETIC (RTYPE (tree))))
3060 werror (E_PLUS_INVALID, "-=");
3061 goto errorTreeReturn;
3064 TETYPE (tree) = getSpec (TTYPE (tree) =
3065 computeType (LTYPE (tree),
3068 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3069 werror (E_CODE_WRITE, " ");
3073 werror (E_LVALUE_REQUIRED, "-=");
3074 goto errorTreeReturn;
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3083 /*----------------------------*/
3085 /* this is not a unary operation */
3086 /* if both pointers then problem */
3087 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3089 werror (E_PTR_PLUS_PTR);
3090 goto errorTreeReturn;
3093 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3095 werror (E_PLUS_INVALID, "+=");
3096 goto errorTreeReturn;
3099 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3101 werror (E_PLUS_INVALID, "+=");
3102 goto errorTreeReturn;
3105 TETYPE (tree) = getSpec (TTYPE (tree) =
3106 computeType (LTYPE (tree),
3109 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3110 werror (E_CODE_WRITE, " ");
3114 werror (E_LVALUE_REQUIRED, "+=");
3115 goto errorTreeReturn;
3118 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3119 tree->opval.op = '=';
3124 /*------------------------------------------------------------------*/
3125 /*----------------------------*/
3126 /* straight assignemnt */
3127 /*----------------------------*/
3129 /* cannot be an aggregate */
3130 if (IS_AGGREGATE (LTYPE (tree)))
3132 werror (E_AGGR_ASSIGN);
3133 goto errorTreeReturn;
3136 /* they should either match or be castable */
3137 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3139 werror (E_TYPE_MISMATCH, "assignment", " ");
3140 printFromToType(RTYPE(tree),LTYPE(tree));
3141 //goto errorTreeReturn;
3144 /* if the left side of the tree is of type void
3145 then report error */
3146 if (IS_VOID (LTYPE (tree)))
3148 werror (E_CAST_ZERO);
3149 printFromToType(RTYPE(tree), LTYPE(tree));
3152 TETYPE (tree) = getSpec (TTYPE (tree) =
3156 if (!tree->initMode ) {
3157 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3158 werror (E_CODE_WRITE, " ");
3162 werror (E_LVALUE_REQUIRED, "=");
3163 goto errorTreeReturn;
3168 /*------------------------------------------------------------------*/
3169 /*----------------------------*/
3170 /* comma operator */
3171 /*----------------------------*/
3173 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3176 /*------------------------------------------------------------------*/
3177 /*----------------------------*/
3179 /*----------------------------*/
3183 if (processParms (tree->left,
3184 FUNC_ARGS(tree->left->ftype),
3185 tree->right, &parmNumber, TRUE)) {
3186 goto errorTreeReturn;
3189 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3190 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3192 //FUNC_ARGS(tree->left->ftype) =
3193 //reverseVal (FUNC_ARGS(tree->left->ftype));
3194 reverseParms (tree->right);
3197 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3200 /*------------------------------------------------------------------*/
3201 /*----------------------------*/
3202 /* return statement */
3203 /*----------------------------*/
3208 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3210 werror (W_RETURN_MISMATCH);
3211 printFromToType (RTYPE(tree), currFunc->type->next);
3212 goto errorTreeReturn;
3215 if (IS_VOID (currFunc->type->next)
3217 !IS_VOID (RTYPE (tree)))
3219 werror (E_FUNC_VOID);
3220 goto errorTreeReturn;
3223 /* if there is going to be a casing required then add it */
3224 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3227 decorateType (newNode (CAST,
3228 newAst_LINK (copyLinkChain (currFunc->type->next)),
3237 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3239 werror (E_VOID_FUNC, currFunc->name);
3240 goto errorTreeReturn;
3243 TTYPE (tree) = TETYPE (tree) = NULL;
3246 /*------------------------------------------------------------------*/
3247 /*----------------------------*/
3248 /* switch statement */
3249 /*----------------------------*/
3251 /* the switch value must be an integer */
3252 if (!IS_INTEGRAL (LTYPE (tree)))
3254 werror (E_SWITCH_NON_INTEGER);
3255 goto errorTreeReturn;
3258 TTYPE (tree) = TETYPE (tree) = NULL;
3261 /*------------------------------------------------------------------*/
3262 /*----------------------------*/
3264 /*----------------------------*/
3266 tree->left = backPatchLabels (tree->left,
3269 TTYPE (tree) = TETYPE (tree) = NULL;
3272 /*------------------------------------------------------------------*/
3273 /*----------------------------*/
3275 /*----------------------------*/
3278 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3279 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3280 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3282 /* if the for loop is reversible then
3283 reverse it otherwise do what we normally
3289 if (isLoopReversible (tree, &sym, &init, &end))
3290 return reverseLoop (tree, sym, init, end);
3292 return decorateType (createFor (AST_FOR (tree, trueLabel),
3293 AST_FOR (tree, continueLabel),
3294 AST_FOR (tree, falseLabel),
3295 AST_FOR (tree, condLabel),
3296 AST_FOR (tree, initExpr),
3297 AST_FOR (tree, condExpr),
3298 AST_FOR (tree, loopExpr),
3302 TTYPE (tree) = TETYPE (tree) = NULL;
3306 /* some error found this tree will be killed */
3308 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3309 tree->opval.op = NULLOP;
3315 /*-----------------------------------------------------------------*/
3316 /* sizeofOp - processes size of operation */
3317 /*-----------------------------------------------------------------*/
3319 sizeofOp (sym_link * type)
3323 /* make sure the type is complete and sane */
3324 checkTypeSanity(type, "(sizeof)");
3326 /* get the size and convert it to character */
3327 sprintf (buff, "%d", getSize (type));
3329 /* now convert into value */
3330 return constVal (buff);
3334 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3335 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3336 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3337 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3338 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3339 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3340 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3342 /*-----------------------------------------------------------------*/
3343 /* backPatchLabels - change and or not operators to flow control */
3344 /*-----------------------------------------------------------------*/
3346 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3352 if (!(IS_ANDORNOT (tree)))
3355 /* if this an and */
3358 static int localLbl = 0;
3361 sprintf (buffer, "_and_%d", localLbl++);
3362 localLabel = newSymbol (buffer, NestLevel);
3364 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3366 /* if left is already a IFX then just change the if true label in that */
3367 if (!IS_IFX (tree->left))
3368 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3370 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3371 /* right is a IFX then just join */
3372 if (IS_IFX (tree->right))
3373 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3375 tree->right = createLabel (localLabel, tree->right);
3376 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3378 return newNode (NULLOP, tree->left, tree->right);
3381 /* if this is an or operation */
3384 static int localLbl = 0;
3387 sprintf (buffer, "_or_%d", localLbl++);
3388 localLabel = newSymbol (buffer, NestLevel);
3390 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3392 /* if left is already a IFX then just change the if true label in that */
3393 if (!IS_IFX (tree->left))
3394 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3396 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3397 /* right is a IFX then just join */
3398 if (IS_IFX (tree->right))
3399 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3401 tree->right = createLabel (localLabel, tree->right);
3402 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3404 return newNode (NULLOP, tree->left, tree->right);
3410 int wasnot = IS_NOT (tree->left);
3411 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3413 /* if the left is already a IFX */
3414 if (!IS_IFX (tree->left))
3415 tree->left = newNode (IFX, tree->left, NULL);
3419 tree->left->trueLabel = trueLabel;
3420 tree->left->falseLabel = falseLabel;
3424 tree->left->trueLabel = falseLabel;
3425 tree->left->falseLabel = trueLabel;
3432 tree->trueLabel = trueLabel;
3433 tree->falseLabel = falseLabel;
3440 /*-----------------------------------------------------------------*/
3441 /* createBlock - create expression tree for block */
3442 /*-----------------------------------------------------------------*/
3444 createBlock (symbol * decl, ast * body)
3448 /* if the block has nothing */
3452 ex = newNode (BLOCK, NULL, body);
3453 ex->values.sym = decl;
3455 ex->right = ex->right;
3461 /*-----------------------------------------------------------------*/
3462 /* createLabel - creates the expression tree for labels */
3463 /*-----------------------------------------------------------------*/
3465 createLabel (symbol * label, ast * stmnt)
3468 char name[SDCC_NAME_MAX + 1];
3471 /* must create fresh symbol if the symbol name */
3472 /* exists in the symbol table, since there can */
3473 /* be a variable with the same name as the labl */
3474 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3475 (csym->level == label->level))
3476 label = newSymbol (label->name, label->level);
3478 /* change the name before putting it in add _ */
3479 sprintf (name, "%s", label->name);
3481 /* put the label in the LabelSymbol table */
3482 /* but first check if a label of the same */
3484 if ((csym = findSym (LabelTab, NULL, name)))
3485 werror (E_DUPLICATE_LABEL, label->name);
3487 addSym (LabelTab, label, name, label->level, 0, 0);
3490 label->key = labelKey++;
3491 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3497 /*-----------------------------------------------------------------*/
3498 /* createCase - generates the parsetree for a case statement */
3499 /*-----------------------------------------------------------------*/
3501 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3503 char caseLbl[SDCC_NAME_MAX + 1];
3507 /* if the switch statement does not exist */
3508 /* then case is out of context */
3511 werror (E_CASE_CONTEXT);
3515 caseVal = decorateType (resolveSymbols (caseVal));
3516 /* if not a constant then error */
3517 if (!IS_LITERAL (caseVal->ftype))
3519 werror (E_CASE_CONSTANT);
3523 /* if not a integer than error */
3524 if (!IS_INTEGRAL (caseVal->ftype))
3526 werror (E_CASE_NON_INTEGER);
3530 /* find the end of the switch values chain */
3531 if (!(val = swStat->values.switchVals.swVals))
3532 swStat->values.switchVals.swVals = caseVal->opval.val;
3535 /* also order the cases according to value */
3537 int cVal = (int) floatFromVal (caseVal->opval.val);
3538 while (val && (int) floatFromVal (val) < cVal)
3544 /* if we reached the end then */
3547 pval->next = caseVal->opval.val;
3551 /* we found a value greater than */
3552 /* the current value we must add this */
3553 /* before the value */
3554 caseVal->opval.val->next = val;
3556 /* if this was the first in chain */
3557 if (swStat->values.switchVals.swVals == val)
3558 swStat->values.switchVals.swVals =
3561 pval->next = caseVal->opval.val;
3566 /* create the case label */
3567 sprintf (caseLbl, "_case_%d_%d",
3568 swStat->values.switchVals.swNum,
3569 (int) floatFromVal (caseVal->opval.val));
3571 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3576 /*-----------------------------------------------------------------*/
3577 /* createDefault - creates the parse tree for the default statement */
3578 /*-----------------------------------------------------------------*/
3580 createDefault (ast * swStat, ast * stmnt)
3582 char defLbl[SDCC_NAME_MAX + 1];
3584 /* if the switch statement does not exist */
3585 /* then case is out of context */
3588 werror (E_CASE_CONTEXT);
3592 /* turn on the default flag */
3593 swStat->values.switchVals.swDefault = 1;
3595 /* create the label */
3596 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3597 return createLabel (newSymbol (defLbl, 0), stmnt);
3600 /*-----------------------------------------------------------------*/
3601 /* createIf - creates the parsetree for the if statement */
3602 /*-----------------------------------------------------------------*/
3604 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3606 static int Lblnum = 0;
3608 symbol *ifTrue, *ifFalse, *ifEnd;
3610 /* if neither exists */
3611 if (!elseBody && !ifBody) {
3612 // if there are no side effects (i++, j() etc)
3613 if (!hasSEFcalls(condAst)) {
3618 /* create the labels */
3619 sprintf (buffer, "_iffalse_%d", Lblnum);
3620 ifFalse = newSymbol (buffer, NestLevel);
3621 /* if no else body then end == false */
3626 sprintf (buffer, "_ifend_%d", Lblnum);
3627 ifEnd = newSymbol (buffer, NestLevel);
3630 sprintf (buffer, "_iftrue_%d", Lblnum);
3631 ifTrue = newSymbol (buffer, NestLevel);
3635 /* attach the ifTrue label to the top of it body */
3636 ifBody = createLabel (ifTrue, ifBody);
3637 /* attach a goto end to the ifBody if else is present */
3640 ifBody = newNode (NULLOP, ifBody,
3642 newAst_VALUE (symbolVal (ifEnd)),
3644 /* put the elseLabel on the else body */
3645 elseBody = createLabel (ifFalse, elseBody);
3646 /* out the end at the end of the body */
3647 elseBody = newNode (NULLOP,
3649 createLabel (ifEnd, NULL));
3653 ifBody = newNode (NULLOP, ifBody,
3654 createLabel (ifFalse, NULL));
3656 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3657 if (IS_IFX (condAst))
3660 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3662 return newNode (NULLOP, ifTree,
3663 newNode (NULLOP, ifBody, elseBody));
3667 /*-----------------------------------------------------------------*/
3668 /* createDo - creates parse tree for do */
3671 /* _docontinue_n: */
3672 /* condition_expression +-> trueLabel -> _dobody_n */
3674 /* +-> falseLabel-> _dobreak_n */
3676 /*-----------------------------------------------------------------*/
3678 createDo (symbol * trueLabel, symbol * continueLabel,
3679 symbol * falseLabel, ast * condAst, ast * doBody)
3684 /* if the body does not exist then it is simple */
3687 condAst = backPatchLabels (condAst, continueLabel, NULL);
3688 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3689 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3690 doTree->trueLabel = continueLabel;
3691 doTree->falseLabel = NULL;
3695 /* otherwise we have a body */
3696 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3698 /* attach the body label to the top */
3699 doBody = createLabel (trueLabel, doBody);
3700 /* attach the continue label to end of body */
3701 doBody = newNode (NULLOP, doBody,
3702 createLabel (continueLabel, NULL));
3704 /* now put the break label at the end */
3705 if (IS_IFX (condAst))
3708 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3710 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3712 /* putting it together */
3713 return newNode (NULLOP, doBody, doTree);
3716 /*-----------------------------------------------------------------*/
3717 /* createFor - creates parse tree for 'for' statement */
3720 /* condExpr +-> trueLabel -> _forbody_n */
3722 /* +-> falseLabel-> _forbreak_n */
3725 /* _forcontinue_n: */
3727 /* goto _forcond_n ; */
3729 /*-----------------------------------------------------------------*/
3731 createFor (symbol * trueLabel, symbol * continueLabel,
3732 symbol * falseLabel, symbol * condLabel,
3733 ast * initExpr, ast * condExpr, ast * loopExpr,
3738 /* if loopexpression not present then we can generate it */
3739 /* the same way as a while */
3741 return newNode (NULLOP, initExpr,
3742 createWhile (trueLabel, continueLabel,
3743 falseLabel, condExpr, forBody));
3744 /* vanilla for statement */
3745 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3747 if (condExpr && !IS_IFX (condExpr))
3748 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3751 /* attach condition label to condition */
3752 condExpr = createLabel (condLabel, condExpr);
3754 /* attach body label to body */
3755 forBody = createLabel (trueLabel, forBody);
3757 /* attach continue to forLoop expression & attach */
3758 /* goto the forcond @ and of loopExpression */
3759 loopExpr = createLabel (continueLabel,
3763 newAst_VALUE (symbolVal (condLabel)),
3765 /* now start putting them together */
3766 forTree = newNode (NULLOP, initExpr, condExpr);
3767 forTree = newNode (NULLOP, forTree, forBody);
3768 forTree = newNode (NULLOP, forTree, loopExpr);
3769 /* finally add the break label */
3770 forTree = newNode (NULLOP, forTree,
3771 createLabel (falseLabel, NULL));
3775 /*-----------------------------------------------------------------*/
3776 /* createWhile - creates parse tree for while statement */
3777 /* the while statement will be created as follows */
3779 /* _while_continue_n: */
3780 /* condition_expression +-> trueLabel -> _while_boby_n */
3782 /* +-> falseLabel -> _while_break_n */
3783 /* _while_body_n: */
3785 /* goto _while_continue_n */
3786 /* _while_break_n: */
3787 /*-----------------------------------------------------------------*/
3789 createWhile (symbol * trueLabel, symbol * continueLabel,
3790 symbol * falseLabel, ast * condExpr, ast * whileBody)
3794 /* put the continue label */
3795 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3796 condExpr = createLabel (continueLabel, condExpr);
3797 condExpr->lineno = 0;
3799 /* put the body label in front of the body */
3800 whileBody = createLabel (trueLabel, whileBody);
3801 whileBody->lineno = 0;
3802 /* put a jump to continue at the end of the body */
3803 /* and put break label at the end of the body */
3804 whileBody = newNode (NULLOP,
3807 newAst_VALUE (symbolVal (continueLabel)),
3808 createLabel (falseLabel, NULL)));
3810 /* put it all together */
3811 if (IS_IFX (condExpr))
3812 whileTree = condExpr;
3815 whileTree = newNode (IFX, condExpr, NULL);
3816 /* put the true & false labels in place */
3817 whileTree->trueLabel = trueLabel;
3818 whileTree->falseLabel = falseLabel;
3821 return newNode (NULLOP, whileTree, whileBody);
3824 /*-----------------------------------------------------------------*/
3825 /* optimizeGetHbit - get highest order bit of the expression */
3826 /*-----------------------------------------------------------------*/
3828 optimizeGetHbit (ast * tree)
3831 /* if this is not a bit and */
3832 if (!IS_BITAND (tree))
3835 /* will look for tree of the form
3836 ( expr >> ((sizeof expr) -1) ) & 1 */
3837 if (!IS_AST_LIT_VALUE (tree->right))
3840 if (AST_LIT_VALUE (tree->right) != 1)
3843 if (!IS_RIGHT_OP (tree->left))
3846 if (!IS_AST_LIT_VALUE (tree->left->right))
3849 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3850 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3853 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3857 /*-----------------------------------------------------------------*/
3858 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3859 /*-----------------------------------------------------------------*/
3861 optimizeRRCRLC (ast * root)
3863 /* will look for trees of the form
3864 (?expr << 1) | (?expr >> 7) or
3865 (?expr >> 7) | (?expr << 1) will make that
3866 into a RLC : operation ..
3868 (?expr >> 1) | (?expr << 7) or
3869 (?expr << 7) | (?expr >> 1) will make that
3870 into a RRC operation
3871 note : by 7 I mean (number of bits required to hold the
3873 /* if the root operations is not a | operation the not */
3874 if (!IS_BITOR (root))
3877 /* I have to think of a better way to match patterns this sucks */
3878 /* that aside let start looking for the first case : I use a the
3879 negative check a lot to improve the efficiency */
3880 /* (?expr << 1) | (?expr >> 7) */
3881 if (IS_LEFT_OP (root->left) &&
3882 IS_RIGHT_OP (root->right))
3885 if (!SPEC_USIGN (TETYPE (root->left->left)))
3888 if (!IS_AST_LIT_VALUE (root->left->right) ||
3889 !IS_AST_LIT_VALUE (root->right->right))
3892 /* make sure it is the same expression */
3893 if (!isAstEqual (root->left->left,
3897 if (AST_LIT_VALUE (root->left->right) != 1)
3900 if (AST_LIT_VALUE (root->right->right) !=
3901 (getSize (TTYPE (root->left->left)) * 8 - 1))
3904 /* whew got the first case : create the AST */
3905 return newNode (RLC, root->left->left, NULL);
3909 /* check for second case */
3910 /* (?expr >> 7) | (?expr << 1) */
3911 if (IS_LEFT_OP (root->right) &&
3912 IS_RIGHT_OP (root->left))
3915 if (!SPEC_USIGN (TETYPE (root->left->left)))
3918 if (!IS_AST_LIT_VALUE (root->left->right) ||
3919 !IS_AST_LIT_VALUE (root->right->right))
3922 /* make sure it is the same symbol */
3923 if (!isAstEqual (root->left->left,
3927 if (AST_LIT_VALUE (root->right->right) != 1)
3930 if (AST_LIT_VALUE (root->left->right) !=
3931 (getSize (TTYPE (root->left->left)) * 8 - 1))
3934 /* whew got the first case : create the AST */
3935 return newNode (RLC, root->left->left, NULL);
3940 /* third case for RRC */
3941 /* (?symbol >> 1) | (?symbol << 7) */
3942 if (IS_LEFT_OP (root->right) &&
3943 IS_RIGHT_OP (root->left))
3946 if (!SPEC_USIGN (TETYPE (root->left->left)))
3949 if (!IS_AST_LIT_VALUE (root->left->right) ||
3950 !IS_AST_LIT_VALUE (root->right->right))
3953 /* make sure it is the same symbol */
3954 if (!isAstEqual (root->left->left,
3958 if (AST_LIT_VALUE (root->left->right) != 1)
3961 if (AST_LIT_VALUE (root->right->right) !=
3962 (getSize (TTYPE (root->left->left)) * 8 - 1))
3965 /* whew got the first case : create the AST */
3966 return newNode (RRC, root->left->left, NULL);
3970 /* fourth and last case for now */
3971 /* (?symbol << 7) | (?symbol >> 1) */
3972 if (IS_RIGHT_OP (root->right) &&
3973 IS_LEFT_OP (root->left))
3976 if (!SPEC_USIGN (TETYPE (root->left->left)))
3979 if (!IS_AST_LIT_VALUE (root->left->right) ||
3980 !IS_AST_LIT_VALUE (root->right->right))
3983 /* make sure it is the same symbol */
3984 if (!isAstEqual (root->left->left,
3988 if (AST_LIT_VALUE (root->right->right) != 1)
3991 if (AST_LIT_VALUE (root->left->right) !=
3992 (getSize (TTYPE (root->left->left)) * 8 - 1))
3995 /* whew got the first case : create the AST */
3996 return newNode (RRC, root->left->left, NULL);
4000 /* not found return root */
4004 /*-----------------------------------------------------------------*/
4005 /* optimizeCompare - otimizes compares for bit variables */
4006 /*-----------------------------------------------------------------*/
4008 optimizeCompare (ast * root)
4010 ast *optExpr = NULL;
4013 unsigned int litValue;
4015 /* if nothing then return nothing */
4019 /* if not a compare op then do leaves */
4020 if (!IS_COMPARE_OP (root))
4022 root->left = optimizeCompare (root->left);
4023 root->right = optimizeCompare (root->right);
4027 /* if left & right are the same then depending
4028 of the operation do */
4029 if (isAstEqual (root->left, root->right))
4031 switch (root->opval.op)
4036 optExpr = newAst_VALUE (constVal ("0"));
4041 optExpr = newAst_VALUE (constVal ("1"));
4045 return decorateType (optExpr);
4048 vleft = (root->left->type == EX_VALUE ?
4049 root->left->opval.val : NULL);
4051 vright = (root->right->type == EX_VALUE ?
4052 root->right->opval.val : NULL);
4054 /* if left is a BITVAR in BITSPACE */
4055 /* and right is a LITERAL then opt- */
4056 /* imize else do nothing */
4057 if (vleft && vright &&
4058 IS_BITVAR (vleft->etype) &&
4059 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4060 IS_LITERAL (vright->etype))
4063 /* if right side > 1 then comparison may never succeed */
4064 if ((litValue = (int) floatFromVal (vright)) > 1)
4066 werror (W_BAD_COMPARE);
4072 switch (root->opval.op)
4074 case '>': /* bit value greater than 1 cannot be */
4075 werror (W_BAD_COMPARE);
4079 case '<': /* bit value < 1 means 0 */
4081 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4084 case LE_OP: /* bit value <= 1 means no check */
4085 optExpr = newAst_VALUE (vright);
4088 case GE_OP: /* bit value >= 1 means only check for = */
4090 optExpr = newAst_VALUE (vleft);
4095 { /* literal is zero */
4096 switch (root->opval.op)
4098 case '<': /* bit value < 0 cannot be */
4099 werror (W_BAD_COMPARE);
4103 case '>': /* bit value > 0 means 1 */
4105 optExpr = newAst_VALUE (vleft);
4108 case LE_OP: /* bit value <= 0 means no check */
4109 case GE_OP: /* bit value >= 0 means no check */
4110 werror (W_BAD_COMPARE);
4114 case EQ_OP: /* bit == 0 means ! of bit */
4115 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4119 return decorateType (resolveSymbols (optExpr));
4120 } /* end-of-if of BITVAR */
4125 /*-----------------------------------------------------------------*/
4126 /* addSymToBlock : adds the symbol to the first block we find */
4127 /*-----------------------------------------------------------------*/
4129 addSymToBlock (symbol * sym, ast * tree)
4131 /* reached end of tree or a leaf */
4132 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4136 if (IS_AST_OP (tree) &&
4137 tree->opval.op == BLOCK)
4140 symbol *lsym = copySymbol (sym);
4142 lsym->next = AST_VALUES (tree, sym);
4143 AST_VALUES (tree, sym) = lsym;
4147 addSymToBlock (sym, tree->left);
4148 addSymToBlock (sym, tree->right);
4151 /*-----------------------------------------------------------------*/
4152 /* processRegParms - do processing for register parameters */
4153 /*-----------------------------------------------------------------*/
4155 processRegParms (value * args, ast * body)
4159 if (IS_REGPARM (args->etype))
4160 addSymToBlock (args->sym, body);
4165 /*-----------------------------------------------------------------*/
4166 /* resetParmKey - resets the operandkeys for the symbols */
4167 /*-----------------------------------------------------------------*/
4168 DEFSETFUNC (resetParmKey)
4179 /*-----------------------------------------------------------------*/
4180 /* createFunction - This is the key node that calls the iCode for */
4181 /* generating the code for a function. Note code */
4182 /* is generated function by function, later when */
4183 /* add inter-procedural analysis this will change */
4184 /*-----------------------------------------------------------------*/
4186 createFunction (symbol * name, ast * body)
4192 iCode *piCode = NULL;
4194 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4195 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4197 /* if check function return 0 then some problem */
4198 if (checkFunction (name, NULL) == 0)
4201 /* create a dummy block if none exists */
4203 body = newNode (BLOCK, NULL, NULL);
4207 /* check if the function name already in the symbol table */
4208 if ((csym = findSym (SymbolTab, NULL, name->name)))
4211 /* special case for compiler defined functions
4212 we need to add the name to the publics list : this
4213 actually means we are now compiling the compiler
4217 addSet (&publics, name);
4223 allocVariables (name);
4225 name->lastLine = yylineno;
4228 /* set the stack pointer */
4229 /* PENDING: check this for the mcs51 */
4230 stackPtr = -port->stack.direction * port->stack.call_overhead;
4231 if (IFFUNC_ISISR (name->type))
4232 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4233 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4234 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4236 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4238 fetype = getSpec (name->type); /* get the specifier for the function */
4239 /* if this is a reentrant function then */
4240 if (IFFUNC_ISREENT (name->type))
4243 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4245 /* do processing for parameters that are passed in registers */
4246 processRegParms (FUNC_ARGS(name->type), body);
4248 /* set the stack pointer */
4252 /* allocate & autoinit the block variables */
4253 processBlockVars (body, &stack, ALLOCATE);
4255 /* save the stack information */
4256 if (options.useXstack)
4257 name->xstack = SPEC_STAK (fetype) = stack;
4259 name->stack = SPEC_STAK (fetype) = stack;
4261 /* name needs to be mangled */
4262 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4264 body = resolveSymbols (body); /* resolve the symbols */
4265 body = decorateType (body); /* propagateType & do semantic checks */
4267 ex = newAst_VALUE (symbolVal (name)); /* create name */
4268 ex = newNode (FUNCTION, ex, body);
4269 ex->values.args = FUNC_ARGS(name->type);
4271 if (options.dump_tree) PA(ex);
4274 werror (E_FUNC_NO_CODE, name->name);
4278 /* create the node & generate intermediate code */
4280 codeOutFile = code->oFile;
4281 piCode = iCodeFromAst (ex);
4285 werror (E_FUNC_NO_CODE, name->name);
4289 eBBlockFromiCode (piCode);
4291 /* if there are any statics then do them */
4294 GcurMemmap = statsg;
4295 codeOutFile = statsg->oFile;
4296 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4302 /* dealloc the block variables */
4303 processBlockVars (body, &stack, DEALLOCATE);
4304 /* deallocate paramaters */
4305 deallocParms (FUNC_ARGS(name->type));
4307 if (IFFUNC_ISREENT (name->type))
4310 /* we are done freeup memory & cleanup */
4312 if (port->reset_labelKey) labelKey = 1;
4314 FUNC_HASBODY(name->type) = 1;
4315 addSet (&operKeyReset, name);
4316 applyToSet (operKeyReset, resetParmKey);
4319 cdbStructBlock (1, cdbFile);
4321 cleanUpLevel (LabelTab, 0);
4322 cleanUpBlock (StructTab, 1);
4323 cleanUpBlock (TypedefTab, 1);
4325 xstack->syms = NULL;
4326 istack->syms = NULL;
4331 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4332 /*-----------------------------------------------------------------*/
4333 /* ast_print : prints the ast (for debugging purposes) */
4334 /*-----------------------------------------------------------------*/
4336 void ast_print (ast * tree, FILE *outfile, int indent)
4341 /* can print only decorated trees */
4342 if (!tree->decorated) return;
4344 /* if any child is an error | this one is an error do nothing */
4345 if (tree->isError ||
4346 (tree->left && tree->left->isError) ||
4347 (tree->right && tree->right->isError)) {
4348 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4352 /* print the line */
4353 /* if not block & function */
4354 if (tree->type == EX_OP &&
4355 (tree->opval.op != FUNCTION &&
4356 tree->opval.op != BLOCK &&
4357 tree->opval.op != NULLOP)) {
4360 if (tree->opval.op == FUNCTION) {
4362 value *args=FUNC_ARGS(tree->left->opval.val->type);
4363 fprintf(outfile,"FUNCTION (%s=%p) type (",
4364 tree->left->opval.val->name, tree);
4365 printTypeChain (tree->ftype,outfile);
4366 fprintf(outfile,") args (");
4369 fprintf (outfile, ", ");
4371 printTypeChain (args ? args->type : NULL, outfile);
4373 args= args ? args->next : NULL;
4375 fprintf(outfile,")\n");
4376 ast_print(tree->left,outfile,indent);
4377 ast_print(tree->right,outfile,indent);
4380 if (tree->opval.op == BLOCK) {
4381 symbol *decls = tree->values.sym;
4382 INDENT(indent,outfile);
4383 fprintf(outfile,"{\n");
4385 INDENT(indent+2,outfile);
4386 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4387 decls->name, decls);
4388 printTypeChain(decls->type,outfile);
4389 fprintf(outfile,")\n");
4391 decls = decls->next;
4393 ast_print(tree->right,outfile,indent+2);
4394 INDENT(indent,outfile);
4395 fprintf(outfile,"}\n");
4398 if (tree->opval.op == NULLOP) {
4399 fprintf(outfile,"\n");
4400 ast_print(tree->left,outfile,indent);
4401 fprintf(outfile,"\n");
4402 ast_print(tree->right,outfile,indent);
4405 INDENT(indent,outfile);
4407 /*------------------------------------------------------------------*/
4408 /*----------------------------*/
4409 /* leaf has been reached */
4410 /*----------------------------*/
4411 /* if this is of type value */
4412 /* just get the type */
4413 if (tree->type == EX_VALUE) {
4415 if (IS_LITERAL (tree->opval.val->etype)) {
4416 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4417 (int) floatFromVal(tree->opval.val),
4418 (int) floatFromVal(tree->opval.val),
4419 floatFromVal(tree->opval.val));
4420 } else if (tree->opval.val->sym) {
4421 /* if the undefined flag is set then give error message */
4422 if (tree->opval.val->sym->undefined) {
4423 fprintf(outfile,"UNDEFINED SYMBOL ");
4425 fprintf(outfile,"SYMBOL ");
4427 fprintf(outfile,"(%s=%p)",
4428 tree->opval.val->sym->name,tree);
4431 fprintf(outfile," type (");
4432 printTypeChain(tree->ftype,outfile);
4433 fprintf(outfile,")\n");
4435 fprintf(outfile,"\n");
4440 /* if type link for the case of cast */
4441 if (tree->type == EX_LINK) {
4442 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4443 printTypeChain(tree->opval.lnk,outfile);
4444 fprintf(outfile,")\n");
4449 /* depending on type of operator do */
4451 switch (tree->opval.op) {
4452 /*------------------------------------------------------------------*/
4453 /*----------------------------*/
4455 /*----------------------------*/
4457 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4458 printTypeChain(tree->ftype,outfile);
4459 fprintf(outfile,")\n");
4460 ast_print(tree->left,outfile,indent+2);
4461 ast_print(tree->right,outfile,indent+2);
4464 /*------------------------------------------------------------------*/
4465 /*----------------------------*/
4467 /*----------------------------*/
4469 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4470 printTypeChain(tree->ftype,outfile);
4471 fprintf(outfile,")\n");
4472 ast_print(tree->left,outfile,indent+2);
4473 ast_print(tree->right,outfile,indent+2);
4476 /*------------------------------------------------------------------*/
4477 /*----------------------------*/
4478 /* struct/union pointer */
4479 /*----------------------------*/
4481 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4482 printTypeChain(tree->ftype,outfile);
4483 fprintf(outfile,")\n");
4484 ast_print(tree->left,outfile,indent+2);
4485 ast_print(tree->right,outfile,indent+2);
4488 /*------------------------------------------------------------------*/
4489 /*----------------------------*/
4490 /* ++/-- operation */
4491 /*----------------------------*/
4492 case INC_OP: /* incerement operator unary so left only */
4493 fprintf(outfile,"INC_OP (%p) type (",tree);
4494 printTypeChain(tree->ftype,outfile);
4495 fprintf(outfile,")\n");
4496 ast_print(tree->left,outfile,indent+2);
4500 fprintf(outfile,"DEC_OP (%p) type (",tree);
4501 printTypeChain(tree->ftype,outfile);
4502 fprintf(outfile,")\n");
4503 ast_print(tree->left,outfile,indent+2);
4506 /*------------------------------------------------------------------*/
4507 /*----------------------------*/
4509 /*----------------------------*/
4512 fprintf(outfile,"& (%p) type (",tree);
4513 printTypeChain(tree->ftype,outfile);
4514 fprintf(outfile,")\n");
4515 ast_print(tree->left,outfile,indent+2);
4516 ast_print(tree->right,outfile,indent+2);
4518 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4519 printTypeChain(tree->ftype,outfile);
4520 fprintf(outfile,")\n");
4521 ast_print(tree->left,outfile,indent+2);
4522 ast_print(tree->right,outfile,indent+2);
4525 /*----------------------------*/
4527 /*----------------------------*/
4529 fprintf(outfile,"OR (%p) type (",tree);
4530 printTypeChain(tree->ftype,outfile);
4531 fprintf(outfile,")\n");
4532 ast_print(tree->left,outfile,indent+2);
4533 ast_print(tree->right,outfile,indent+2);
4535 /*------------------------------------------------------------------*/
4536 /*----------------------------*/
4538 /*----------------------------*/
4540 fprintf(outfile,"XOR (%p) type (",tree);
4541 printTypeChain(tree->ftype,outfile);
4542 fprintf(outfile,")\n");
4543 ast_print(tree->left,outfile,indent+2);
4544 ast_print(tree->right,outfile,indent+2);
4547 /*------------------------------------------------------------------*/
4548 /*----------------------------*/
4550 /*----------------------------*/
4552 fprintf(outfile,"DIV (%p) type (",tree);
4553 printTypeChain(tree->ftype,outfile);
4554 fprintf(outfile,")\n");
4555 ast_print(tree->left,outfile,indent+2);
4556 ast_print(tree->right,outfile,indent+2);
4558 /*------------------------------------------------------------------*/
4559 /*----------------------------*/
4561 /*----------------------------*/
4563 fprintf(outfile,"MOD (%p) type (",tree);
4564 printTypeChain(tree->ftype,outfile);
4565 fprintf(outfile,")\n");
4566 ast_print(tree->left,outfile,indent+2);
4567 ast_print(tree->right,outfile,indent+2);
4570 /*------------------------------------------------------------------*/
4571 /*----------------------------*/
4572 /* address dereference */
4573 /*----------------------------*/
4574 case '*': /* can be unary : if right is null then unary operation */
4576 fprintf(outfile,"DEREF (%p) type (",tree);
4577 printTypeChain(tree->ftype,outfile);
4578 fprintf(outfile,")\n");
4579 ast_print(tree->left,outfile,indent+2);
4582 /*------------------------------------------------------------------*/
4583 /*----------------------------*/
4584 /* multiplication */
4585 /*----------------------------*/
4586 fprintf(outfile,"MULT (%p) type (",tree);
4587 printTypeChain(tree->ftype,outfile);
4588 fprintf(outfile,")\n");
4589 ast_print(tree->left,outfile,indent+2);
4590 ast_print(tree->right,outfile,indent+2);
4594 /*------------------------------------------------------------------*/
4595 /*----------------------------*/
4596 /* unary '+' operator */
4597 /*----------------------------*/
4601 fprintf(outfile,"UPLUS (%p) type (",tree);
4602 printTypeChain(tree->ftype,outfile);
4603 fprintf(outfile,")\n");
4604 ast_print(tree->left,outfile,indent+2);
4606 /*------------------------------------------------------------------*/
4607 /*----------------------------*/
4609 /*----------------------------*/
4610 fprintf(outfile,"ADD (%p) type (",tree);
4611 printTypeChain(tree->ftype,outfile);
4612 fprintf(outfile,")\n");
4613 ast_print(tree->left,outfile,indent+2);
4614 ast_print(tree->right,outfile,indent+2);
4617 /*------------------------------------------------------------------*/
4618 /*----------------------------*/
4620 /*----------------------------*/
4621 case '-': /* can be unary */
4623 fprintf(outfile,"UMINUS (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+2);
4628 /*------------------------------------------------------------------*/
4629 /*----------------------------*/
4631 /*----------------------------*/
4632 fprintf(outfile,"SUB (%p) type (",tree);
4633 printTypeChain(tree->ftype,outfile);
4634 fprintf(outfile,")\n");
4635 ast_print(tree->left,outfile,indent+2);
4636 ast_print(tree->right,outfile,indent+2);
4639 /*------------------------------------------------------------------*/
4640 /*----------------------------*/
4642 /*----------------------------*/
4644 fprintf(outfile,"COMPL (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+2);
4649 /*------------------------------------------------------------------*/
4650 /*----------------------------*/
4652 /*----------------------------*/
4654 fprintf(outfile,"NOT (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+2);
4659 /*------------------------------------------------------------------*/
4660 /*----------------------------*/
4662 /*----------------------------*/
4664 fprintf(outfile,"RRC (%p) type (",tree);
4665 printTypeChain(tree->ftype,outfile);
4666 fprintf(outfile,")\n");
4667 ast_print(tree->left,outfile,indent+2);
4671 fprintf(outfile,"RLC (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+2);
4677 fprintf(outfile,"GETHBIT (%p) type (",tree);
4678 printTypeChain(tree->ftype,outfile);
4679 fprintf(outfile,")\n");
4680 ast_print(tree->left,outfile,indent+2);
4683 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+2);
4687 ast_print(tree->right,outfile,indent+2);
4690 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+2);
4694 ast_print(tree->right,outfile,indent+2);
4696 /*------------------------------------------------------------------*/
4697 /*----------------------------*/
4699 /*----------------------------*/
4700 case CAST: /* change the type */
4701 fprintf(outfile,"CAST (%p) from type (",tree);
4702 printTypeChain(tree->right->ftype,outfile);
4703 fprintf(outfile,") to type (");
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->right,outfile,indent+2);
4710 fprintf(outfile,"ANDAND (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+2);
4714 ast_print(tree->right,outfile,indent+2);
4717 fprintf(outfile,"OROR (%p) type (",tree);
4718 printTypeChain(tree->ftype,outfile);
4719 fprintf(outfile,")\n");
4720 ast_print(tree->left,outfile,indent+2);
4721 ast_print(tree->right,outfile,indent+2);
4724 /*------------------------------------------------------------------*/
4725 /*----------------------------*/
4726 /* comparison operators */
4727 /*----------------------------*/
4729 fprintf(outfile,"GT(>) (%p) type (",tree);
4730 printTypeChain(tree->ftype,outfile);
4731 fprintf(outfile,")\n");
4732 ast_print(tree->left,outfile,indent+2);
4733 ast_print(tree->right,outfile,indent+2);
4736 fprintf(outfile,"LT(<) (%p) type (",tree);
4737 printTypeChain(tree->ftype,outfile);
4738 fprintf(outfile,")\n");
4739 ast_print(tree->left,outfile,indent+2);
4740 ast_print(tree->right,outfile,indent+2);
4743 fprintf(outfile,"LE(<=) (%p) type (",tree);
4744 printTypeChain(tree->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->left,outfile,indent+2);
4747 ast_print(tree->right,outfile,indent+2);
4750 fprintf(outfile,"GE(>=) (%p) type (",tree);
4751 printTypeChain(tree->ftype,outfile);
4752 fprintf(outfile,")\n");
4753 ast_print(tree->left,outfile,indent+2);
4754 ast_print(tree->right,outfile,indent+2);
4757 fprintf(outfile,"EQ(==) (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+2);
4761 ast_print(tree->right,outfile,indent+2);
4764 fprintf(outfile,"NE(!=) (%p) type (",tree);
4765 printTypeChain(tree->ftype,outfile);
4766 fprintf(outfile,")\n");
4767 ast_print(tree->left,outfile,indent+2);
4768 ast_print(tree->right,outfile,indent+2);
4769 /*------------------------------------------------------------------*/
4770 /*----------------------------*/
4772 /*----------------------------*/
4773 case SIZEOF: /* evaluate wihout code generation */
4774 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4777 /*------------------------------------------------------------------*/
4778 /*----------------------------*/
4779 /* conditional operator '?' */
4780 /*----------------------------*/
4782 fprintf(outfile,"QUEST(?) (%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);
4790 fprintf(outfile,"COLON(:) (%p) type (",tree);
4791 printTypeChain(tree->ftype,outfile);
4792 fprintf(outfile,")\n");
4793 ast_print(tree->left,outfile,indent+2);
4794 ast_print(tree->right,outfile,indent+2);
4797 /*------------------------------------------------------------------*/
4798 /*----------------------------*/
4799 /* assignment operators */
4800 /*----------------------------*/
4802 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4803 printTypeChain(tree->ftype,outfile);
4804 fprintf(outfile,")\n");
4805 ast_print(tree->left,outfile,indent+2);
4806 ast_print(tree->right,outfile,indent+2);
4809 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4810 printTypeChain(tree->ftype,outfile);
4811 fprintf(outfile,")\n");
4812 ast_print(tree->left,outfile,indent+2);
4813 ast_print(tree->right,outfile,indent+2);
4816 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4817 printTypeChain(tree->ftype,outfile);
4818 fprintf(outfile,")\n");
4819 ast_print(tree->left,outfile,indent+2);
4820 ast_print(tree->right,outfile,indent+2);
4823 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4824 printTypeChain(tree->ftype,outfile);
4825 fprintf(outfile,")\n");
4826 ast_print(tree->left,outfile,indent+2);
4827 ast_print(tree->right,outfile,indent+2);
4830 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4831 printTypeChain(tree->ftype,outfile);
4832 fprintf(outfile,")\n");
4833 ast_print(tree->left,outfile,indent+2);
4834 ast_print(tree->right,outfile,indent+2);
4837 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4838 printTypeChain(tree->ftype,outfile);
4839 fprintf(outfile,")\n");
4840 ast_print(tree->left,outfile,indent+2);
4841 ast_print(tree->right,outfile,indent+2);
4844 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4845 printTypeChain(tree->ftype,outfile);
4846 fprintf(outfile,")\n");
4847 ast_print(tree->left,outfile,indent+2);
4848 ast_print(tree->right,outfile,indent+2);
4850 /*------------------------------------------------------------------*/
4851 /*----------------------------*/
4853 /*----------------------------*/
4855 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4856 printTypeChain(tree->ftype,outfile);
4857 fprintf(outfile,")\n");
4858 ast_print(tree->left,outfile,indent+2);
4859 ast_print(tree->right,outfile,indent+2);
4861 /*------------------------------------------------------------------*/
4862 /*----------------------------*/
4864 /*----------------------------*/
4866 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4867 printTypeChain(tree->ftype,outfile);
4868 fprintf(outfile,")\n");
4869 ast_print(tree->left,outfile,indent+2);
4870 ast_print(tree->right,outfile,indent+2);
4872 /*------------------------------------------------------------------*/
4873 /*----------------------------*/
4874 /* straight assignemnt */
4875 /*----------------------------*/
4877 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4878 printTypeChain(tree->ftype,outfile);
4879 fprintf(outfile,")\n");
4880 ast_print(tree->left,outfile,indent+2);
4881 ast_print(tree->right,outfile,indent+2);
4883 /*------------------------------------------------------------------*/
4884 /*----------------------------*/
4885 /* comma operator */
4886 /*----------------------------*/
4888 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4889 printTypeChain(tree->ftype,outfile);
4890 fprintf(outfile,")\n");
4891 ast_print(tree->left,outfile,indent+2);
4892 ast_print(tree->right,outfile,indent+2);
4894 /*------------------------------------------------------------------*/
4895 /*----------------------------*/
4897 /*----------------------------*/
4900 fprintf(outfile,"CALL (%p) type (",tree);
4901 printTypeChain(tree->ftype,outfile);
4902 fprintf(outfile,")\n");
4903 ast_print(tree->left,outfile,indent+2);
4904 ast_print(tree->right,outfile,indent+2);
4907 fprintf(outfile,"PARMS\n");
4908 ast_print(tree->left,outfile,indent+2);
4909 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4910 ast_print(tree->right,outfile,indent+2);
4913 /*------------------------------------------------------------------*/
4914 /*----------------------------*/
4915 /* return statement */
4916 /*----------------------------*/
4918 fprintf(outfile,"RETURN (%p) type (",tree);
4920 printTypeChain(tree->right->ftype,outfile);
4922 fprintf(outfile,")\n");
4923 ast_print(tree->right,outfile,indent+2);
4925 /*------------------------------------------------------------------*/
4926 /*----------------------------*/
4927 /* label statement */
4928 /*----------------------------*/
4930 fprintf(outfile,"LABEL (%p)\n",tree);
4931 ast_print(tree->left,outfile,indent+2);
4932 ast_print(tree->right,outfile,indent);
4934 /*------------------------------------------------------------------*/
4935 /*----------------------------*/
4936 /* switch statement */
4937 /*----------------------------*/
4941 fprintf(outfile,"SWITCH (%p) ",tree);
4942 ast_print(tree->left,outfile,0);
4943 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4944 INDENT(indent+2,outfile);
4945 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4946 (int) floatFromVal(val),
4947 tree->values.switchVals.swNum,
4948 (int) floatFromVal(val));
4950 ast_print(tree->right,outfile,indent);
4953 /*------------------------------------------------------------------*/
4954 /*----------------------------*/
4956 /*----------------------------*/
4958 fprintf(outfile,"IF (%p) \n",tree);
4959 ast_print(tree->left,outfile,indent+2);
4960 if (tree->trueLabel) {
4961 INDENT(indent,outfile);
4962 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4964 if (tree->falseLabel) {
4965 INDENT(indent,outfile);
4966 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4968 ast_print(tree->right,outfile,indent+2);
4970 /*------------------------------------------------------------------*/
4971 /*----------------------------*/
4973 /*----------------------------*/
4975 fprintf(outfile,"FOR (%p) \n",tree);
4976 if (AST_FOR( tree, initExpr)) {
4977 INDENT(indent+2,outfile);
4978 fprintf(outfile,"INIT EXPR ");
4979 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4981 if (AST_FOR( tree, condExpr)) {
4982 INDENT(indent+2,outfile);
4983 fprintf(outfile,"COND EXPR ");
4984 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4986 if (AST_FOR( tree, loopExpr)) {
4987 INDENT(indent+2,outfile);
4988 fprintf(outfile,"LOOP EXPR ");
4989 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4991 fprintf(outfile,"FOR LOOP BODY \n");
4992 ast_print(tree->left,outfile,indent+2);
5001 ast_print(t,stdout,0);