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 */
372 /* if not block & function */
373 if (tree->type == EX_OP &&
374 (tree->opval.op != FUNCTION &&
375 tree->opval.op != BLOCK &&
376 tree->opval.op != NULLOP))
378 filename = tree->filename;
379 lineno = tree->lineno;
383 /* make sure we resolve the true & false labels for ifx */
384 if (tree->type == EX_OP && tree->opval.op == IFX)
390 if ((csym = findSym (LabelTab, tree->trueLabel,
391 tree->trueLabel->name)))
392 tree->trueLabel = csym;
394 werror (E_LABEL_UNDEF, tree->trueLabel->name);
397 if (tree->falseLabel)
399 if ((csym = findSym (LabelTab,
401 tree->falseLabel->name)))
402 tree->falseLabel = csym;
404 werror (E_LABEL_UNDEF, tree->falseLabel->name);
409 /* if this is a label resolve it from the labelTab */
410 if (IS_AST_VALUE (tree) &&
411 tree->opval.val->sym &&
412 tree->opval.val->sym->islbl)
415 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
416 tree->opval.val->sym->name);
419 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
421 tree->opval.val->sym = csym;
423 goto resolveChildren;
426 /* do only for leafs */
427 if (IS_AST_VALUE (tree) &&
428 tree->opval.val->sym &&
429 !tree->opval.val->sym->implicit)
432 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
434 /* if found in the symbol table & they r not the same */
435 if (csym && tree->opval.val->sym != csym)
437 tree->opval.val->sym = csym;
438 tree->opval.val->type = csym->type;
439 tree->opval.val->etype = csym->etype;
442 /* if not found in the symbol table */
443 /* mark it as undefined assume it is */
444 /* an integer in data space */
445 if (!csym && !tree->opval.val->sym->implicit)
448 /* if this is a function name then */
449 /* mark it as returning an int */
452 tree->opval.val->sym->type = newLink ();
453 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
454 tree->opval.val->sym->type->next =
455 tree->opval.val->sym->etype = newIntLink ();
456 tree->opval.val->etype = tree->opval.val->etype;
457 tree->opval.val->type = tree->opval.val->sym->type;
458 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
459 allocVariables (tree->opval.val->sym);
463 tree->opval.val->sym->undefined = 1;
464 tree->opval.val->type =
465 tree->opval.val->etype = newIntLink ();
466 tree->opval.val->sym->type =
467 tree->opval.val->sym->etype = newIntLink ();
473 resolveSymbols (tree->left);
474 resolveSymbols (tree->right);
479 /*-----------------------------------------------------------------*/
480 /* setAstLineno - walks a ast tree & sets the line number */
481 /*-----------------------------------------------------------------*/
482 int setAstLineno (ast * tree, int lineno)
487 tree->lineno = lineno;
488 setAstLineno (tree->left, lineno);
489 setAstLineno (tree->right, lineno);
493 /*-----------------------------------------------------------------*/
494 /* funcOfType :- function of type with name */
495 /*-----------------------------------------------------------------*/
497 funcOfType (char *name, sym_link * type, sym_link * argType,
501 /* create the symbol */
502 sym = newSymbol (name, 0);
504 /* setup return value */
505 sym->type = newLink ();
506 DCL_TYPE (sym->type) = FUNCTION;
507 sym->type->next = copyLinkChain (type);
508 sym->etype = getSpec (sym->type);
509 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
511 /* if arguments required */
515 args = FUNC_ARGS(sym->type) = newValue ();
519 args->type = copyLinkChain (argType);
520 args->etype = getSpec (args->type);
521 SPEC_EXTR(args->etype)=1;
524 args = args->next = newValue ();
531 allocVariables (sym);
536 /*-----------------------------------------------------------------*/
537 /* funcOfTypeVarg :- function of type with name and argtype */
538 /*-----------------------------------------------------------------*/
540 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
545 /* create the symbol */
546 sym = newSymbol (name, 0);
548 /* setup return value */
549 sym->type = newLink ();
550 DCL_TYPE (sym->type) = FUNCTION;
551 sym->type->next = typeFromStr(rtype);
552 sym->etype = getSpec (sym->type);
554 /* if arguments required */
557 args = FUNC_ARGS(sym->type) = newValue ();
559 for ( i = 0 ; i < nArgs ; i++ ) {
560 args->type = typeFromStr(atypes[i]);
561 args->etype = getSpec (args->type);
562 SPEC_EXTR(args->etype)=1;
563 if ((i + 1) == nArgs) break;
564 args = args->next = newValue ();
571 allocVariables (sym);
576 /*-----------------------------------------------------------------*/
577 /* reverseParms - will reverse a parameter tree */
578 /*-----------------------------------------------------------------*/
580 reverseParms (ast * ptree)
586 /* top down if we find a nonParm tree then quit */
587 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
590 ptree->left = ptree->right;
591 ptree->right = ttree;
592 reverseParms (ptree->left);
593 reverseParms (ptree->right);
599 /*-----------------------------------------------------------------*/
600 /* processParms - makes sure the parameters are okay and do some */
601 /* processing with them */
602 /*-----------------------------------------------------------------*/
604 processParms (ast * func,
607 int *parmNumber, // unused, although updated
610 /* if none of them exist */
611 if (!defParm && !actParm)
615 if (getenv("DEBUG_SANITY")) {
616 fprintf (stderr, "processParms: %s ", defParm->name);
618 /* make sure the type is complete and sane */
619 checkTypeSanity(defParm->etype, defParm->name);
622 /* if the function is being called via a pointer & */
623 /* it has not been defined a reentrant then we cannot */
624 /* have parameters */
625 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
627 werror (W_NONRENT_ARGS);
631 /* if defined parameters ended but actual parameters */
632 /* exist and this is not defined as a variable arg */
633 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
635 werror (E_TOO_MANY_PARMS);
639 /* if defined parameters present but no actual parameters */
640 if (defParm && !actParm)
642 werror (E_TOO_FEW_PARMS);
646 if (IS_VOID(actParm->ftype)) {
647 werror (E_VOID_VALUE_USED);
651 /* If this is a varargs function... */
652 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
657 if (IS_CAST_OP (actParm)
658 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
660 /* Parameter was explicitly typecast; don't touch it. */
664 ftype = actParm->ftype;
666 /* If it's a small integer, upcast to int. */
667 if (IS_INTEGRAL (ftype)
668 && (getSize (ftype) < (unsigned) INTSIZE))
670 if (IS_AST_OP(actParm) &&
671 (actParm->opval.op == LEFT_OP ||
672 actParm->opval.op == '*' ||
673 actParm->opval.op == '+' ||
674 actParm->opval.op == '-') &&
676 // we should cast an operand instead of the result
677 actParm->decorated = 0;
678 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
680 actParm = decorateType(actParm);
682 newType = newAst_LINK(INTTYPE);
686 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
688 newType = newAst_LINK (copyLinkChain(ftype));
689 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
692 if (IS_AGGREGATE (ftype))
694 newType = newAst_LINK (copyLinkChain (ftype));
695 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
699 /* cast required; change this op to a cast. */
700 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
702 actParm->type = EX_OP;
703 actParm->opval.op = CAST;
704 actParm->left = newType;
705 actParm->right = parmCopy;
706 decorateType (actParm);
708 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
710 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
711 processParms (func, NULL, actParm->right, parmNumber, rightmost));
716 /* if defined parameters ended but actual has not & */
718 if (!defParm && actParm &&
719 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
722 resolveSymbols (actParm);
723 /* if this is a PARAM node then match left & right */
724 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
726 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
727 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
731 /* If we have found a value node by following only right-hand links,
732 * then we know that there are no more values after us.
734 * Therefore, if there are more defined parameters, the caller didn't
737 if (rightmost && defParm->next)
739 werror (E_TOO_FEW_PARMS);
744 /* the parameter type must be at least castable */
745 if (compareType (defParm->type, actParm->ftype) == 0) {
746 werror (E_INCOMPAT_TYPES);
747 printFromToType (actParm->ftype, defParm->type);
751 /* if the parameter is castable then add the cast */
752 if (compareType (defParm->type, actParm->ftype) < 0)
754 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
756 /* now change the current one to a cast */
757 actParm->type = EX_OP;
758 actParm->opval.op = CAST;
759 actParm->left = newAst_LINK (defParm->type);
760 actParm->right = pTree;
761 actParm->etype = defParm->etype;
762 actParm->ftype = defParm->type;
763 actParm->decorated=0; /* force typechecking */
764 decorateType (actParm);
767 /* make a copy and change the regparm type to the defined parm */
768 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
769 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
770 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
774 /*-----------------------------------------------------------------*/
775 /* createIvalType - generates ival for basic types */
776 /*-----------------------------------------------------------------*/
778 createIvalType (ast * sym, sym_link * type, initList * ilist)
782 /* if initList is deep */
783 if (ilist->type == INIT_DEEP)
784 ilist = ilist->init.deep;
786 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
787 return decorateType (newNode ('=', sym, iExpr));
790 /*-----------------------------------------------------------------*/
791 /* createIvalStruct - generates initial value for structures */
792 /*-----------------------------------------------------------------*/
794 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
801 sflds = SPEC_STRUCT (type)->fields;
802 if (ilist->type != INIT_DEEP)
804 werror (E_INIT_STRUCT, "");
808 iloop = ilist->init.deep;
810 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
812 /* if we have come to end */
816 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
817 lAst = decorateType (resolveSymbols (lAst));
818 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
822 werror (W_EXCESS_INITIALIZERS, "struct",
823 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
830 /*-----------------------------------------------------------------*/
831 /* createIvalArray - generates code for array initialization */
832 /*-----------------------------------------------------------------*/
834 createIvalArray (ast * sym, sym_link * type, initList * ilist)
838 int lcnt = 0, size = 0;
839 literalList *literalL;
841 /* take care of the special case */
842 /* array of characters can be init */
844 if (IS_CHAR (type->next))
845 if ((rast = createIvalCharPtr (sym,
847 decorateType (resolveSymbols (list2expr (ilist))))))
849 return decorateType (resolveSymbols (rast));
851 /* not the special case */
852 if (ilist->type != INIT_DEEP)
854 werror (E_INIT_STRUCT, "");
858 iloop = ilist->init.deep;
859 lcnt = DCL_ELEM (type);
861 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
865 aSym = decorateType (resolveSymbols(sym));
867 rast = newNode(ARRAYINIT, aSym, NULL);
868 rast->values.constlist = literalL;
870 // Make sure size is set to length of initializer list.
877 if (lcnt && size > lcnt)
879 // Array size was specified, and we have more initializers than needed.
880 char *name=sym->opval.val->sym->name;
881 int lineno=sym->opval.val->sym->lineDef;
883 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
892 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
893 aSym = decorateType (resolveSymbols (aSym));
894 rast = createIval (aSym, type->next, iloop, rast);
895 iloop = (iloop ? iloop->next : NULL);
901 /* no of elements given and we */
902 /* have generated for all of them */
905 // there has to be a better way
906 char *name=sym->opval.val->sym->name;
907 int lineno=sym->opval.val->sym->lineDef;
908 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
915 /* if we have not been given a size */
916 if (!DCL_ELEM (type))
918 DCL_ELEM (type) = size;
921 return decorateType (resolveSymbols (rast));
925 /*-----------------------------------------------------------------*/
926 /* createIvalCharPtr - generates initial values for char pointers */
927 /*-----------------------------------------------------------------*/
929 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
933 /* if this is a pointer & right is a literal array then */
934 /* just assignment will do */
935 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
936 SPEC_SCLS (iexpr->etype) == S_CODE)
937 && IS_ARRAY (iexpr->ftype)))
938 return newNode ('=', sym, iexpr);
940 /* left side is an array so we have to assign each */
942 if ((IS_LITERAL (iexpr->etype) ||
943 SPEC_SCLS (iexpr->etype) == S_CODE)
944 && IS_ARRAY (iexpr->ftype))
946 /* for each character generate an assignment */
947 /* to the array element */
948 char *s = SPEC_CVAL (iexpr->etype).v_char;
953 rast = newNode (NULLOP,
957 newAst_VALUE (valueFromLit ((float) i))),
958 newAst_VALUE (valueFromLit (*s))));
962 rast = newNode (NULLOP,
966 newAst_VALUE (valueFromLit ((float) i))),
967 newAst_VALUE (valueFromLit (*s))));
969 // now we don't need iexpr's symbol anymore
971 symbol *sym=AST_SYMBOL(iexpr);
972 memmap *segment=SPEC_OCLS(sym->etype);
973 deleteSetItem(&segment->syms, sym);
976 return decorateType(resolveSymbols (rast));
982 /*-----------------------------------------------------------------*/
983 /* createIvalPtr - generates initial value for pointers */
984 /*-----------------------------------------------------------------*/
986 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
992 if (ilist->type == INIT_DEEP)
993 ilist = ilist->init.deep;
995 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
997 /* if character pointer */
998 if (IS_CHAR (type->next))
999 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1002 return newNode ('=', sym, iexpr);
1005 /*-----------------------------------------------------------------*/
1006 /* createIval - generates code for initial value */
1007 /*-----------------------------------------------------------------*/
1009 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1016 /* if structure then */
1017 if (IS_STRUCT (type))
1018 rast = createIvalStruct (sym, type, ilist);
1020 /* if this is a pointer */
1022 rast = createIvalPtr (sym, type, ilist);
1024 /* if this is an array */
1025 if (IS_ARRAY (type))
1026 rast = createIvalArray (sym, type, ilist);
1028 /* if type is SPECIFIER */
1030 rast = createIvalType (sym, type, ilist);
1033 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1035 return decorateType (resolveSymbols (rast));
1038 /*-----------------------------------------------------------------*/
1039 /* initAggregates - initialises aggregate variables with initv */
1040 /*-----------------------------------------------------------------*/
1041 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1042 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1045 /*-----------------------------------------------------------------*/
1046 /* gatherAutoInit - creates assignment expressions for initial */
1048 /*-----------------------------------------------------------------*/
1050 gatherAutoInit (symbol * autoChain)
1057 for (sym = autoChain; sym; sym = sym->next)
1060 /* resolve the symbols in the ival */
1062 resolveIvalSym (sym->ival);
1065 /* if this is a static variable & has an */
1066 /* initial value the code needs to be lifted */
1067 /* here to the main portion since they can be */
1068 /* initialised only once at the start */
1069 if (IS_STATIC (sym->etype) && sym->ival &&
1070 SPEC_SCLS (sym->etype) != S_CODE)
1074 /* insert the symbol into the symbol table */
1075 /* with level = 0 & name = rname */
1076 newSym = copySymbol (sym);
1077 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1079 /* now lift the code to main */
1080 if (IS_AGGREGATE (sym->type)) {
1081 work = initAggregates (sym, sym->ival, NULL);
1083 if (getNelements(sym->type, sym->ival)>1) {
1084 werror (W_EXCESS_INITIALIZERS, "scalar",
1085 sym->name, sym->lineDef);
1087 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1088 list2expr (sym->ival));
1091 setAstLineno (work, sym->lineDef);
1095 staticAutos = newNode (NULLOP, staticAutos, work);
1102 /* if there is an initial value */
1103 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1105 initList *ilist=sym->ival;
1107 while (ilist->type == INIT_DEEP) {
1108 ilist = ilist->init.deep;
1111 /* update lineno for error msg */
1112 lineno=sym->lineDef;
1113 setAstLineno (ilist->init.node, lineno);
1115 if (IS_AGGREGATE (sym->type)) {
1116 work = initAggregates (sym, sym->ival, NULL);
1118 if (getNelements(sym->type, sym->ival)>1) {
1119 werror (W_EXCESS_INITIALIZERS, "scalar",
1120 sym->name, sym->lineDef);
1122 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1123 list2expr (sym->ival));
1127 setAstLineno (work, sym->lineDef);
1131 init = newNode (NULLOP, init, work);
1140 /*-----------------------------------------------------------------*/
1141 /* stringToSymbol - creates a symbol from a literal string */
1142 /*-----------------------------------------------------------------*/
1144 stringToSymbol (value * val)
1146 char name[SDCC_NAME_MAX + 1];
1147 static int charLbl = 0;
1150 sprintf (name, "_str_%d", charLbl++);
1151 sym = newSymbol (name, 0); /* make it @ level 0 */
1152 strcpy (sym->rname, name);
1154 /* copy the type from the value passed */
1155 sym->type = copyLinkChain (val->type);
1156 sym->etype = getSpec (sym->type);
1157 /* change to storage class & output class */
1158 SPEC_SCLS (sym->etype) = S_CODE;
1159 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1160 SPEC_STAT (sym->etype) = 1;
1161 /* make the level & block = 0 */
1162 sym->block = sym->level = 0;
1164 /* create an ival */
1165 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1170 allocVariables (sym);
1173 return symbolVal (sym);
1177 /*-----------------------------------------------------------------*/
1178 /* processBlockVars - will go thru the ast looking for block if */
1179 /* a block is found then will allocate the syms */
1180 /* will also gather the auto inits present */
1181 /*-----------------------------------------------------------------*/
1183 processBlockVars (ast * tree, int *stack, int action)
1188 /* if this is a block */
1189 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1193 if (action == ALLOCATE)
1195 *stack += allocVariables (tree->values.sym);
1196 autoInit = gatherAutoInit (tree->values.sym);
1198 /* if there are auto inits then do them */
1200 tree->left = newNode (NULLOP, autoInit, tree->left);
1202 else /* action is deallocate */
1203 deallocLocal (tree->values.sym);
1206 processBlockVars (tree->left, stack, action);
1207 processBlockVars (tree->right, stack, action);
1211 /*-------------------------------------------------------------*/
1212 /* constExprTree - returns TRUE if this tree is a constant */
1214 /*-------------------------------------------------------------*/
1215 bool constExprTree (ast *cexpr) {
1221 cexpr = decorateType (resolveSymbols (cexpr));
1223 switch (cexpr->type)
1226 if (IS_AST_LIT_VALUE(cexpr)) {
1227 // this is a literal
1230 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1231 // a function's address will never change
1234 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1235 // an array's address will never change
1238 if (IS_AST_SYM_VALUE(cexpr) &&
1239 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1240 // a symbol in code space will never change
1241 // This is only for the 'char *s="hallo"' case and will have to leave
1246 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1247 "unexpected link in expression tree\n");
1250 if (cexpr->opval.op==ARRAYINIT) {
1251 // this is a list of literals
1254 if (cexpr->opval.op=='=') {
1255 return constExprTree(cexpr->right);
1257 if (cexpr->opval.op==CAST) {
1258 // jwk: cast ignored, maybe we should throw a warning here
1259 return constExprTree(cexpr->right);
1261 if (cexpr->opval.op=='&') {
1264 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1267 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1274 /*-----------------------------------------------------------------*/
1275 /* constExprValue - returns the value of a constant expression */
1276 /* or NULL if it is not a constant expression */
1277 /*-----------------------------------------------------------------*/
1279 constExprValue (ast * cexpr, int check)
1281 cexpr = decorateType (resolveSymbols (cexpr));
1283 /* if this is not a constant then */
1284 if (!IS_LITERAL (cexpr->ftype))
1286 /* then check if this is a literal array
1288 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1289 SPEC_CVAL (cexpr->etype).v_char &&
1290 IS_ARRAY (cexpr->ftype))
1292 value *val = valFromType (cexpr->ftype);
1293 SPEC_SCLS (val->etype) = S_LITERAL;
1294 val->sym = cexpr->opval.val->sym;
1295 val->sym->type = copyLinkChain (cexpr->ftype);
1296 val->sym->etype = getSpec (val->sym->type);
1297 strcpy (val->name, cexpr->opval.val->sym->rname);
1301 /* if we are casting a literal value then */
1302 if (IS_AST_OP (cexpr) &&
1303 cexpr->opval.op == CAST &&
1304 IS_LITERAL (cexpr->right->ftype))
1305 return valCastLiteral (cexpr->ftype,
1306 floatFromVal (cexpr->right->opval.val));
1308 if (IS_AST_VALUE (cexpr))
1309 return cexpr->opval.val;
1312 werror (E_CONST_EXPECTED, "found expression");
1317 /* return the value */
1318 return cexpr->opval.val;
1322 /*-----------------------------------------------------------------*/
1323 /* isLabelInAst - will return true if a given label is found */
1324 /*-----------------------------------------------------------------*/
1326 isLabelInAst (symbol * label, ast * tree)
1328 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1331 if (IS_AST_OP (tree) &&
1332 tree->opval.op == LABEL &&
1333 isSymbolEqual (AST_SYMBOL (tree->left), label))
1336 return isLabelInAst (label, tree->right) &&
1337 isLabelInAst (label, tree->left);
1341 /*-----------------------------------------------------------------*/
1342 /* isLoopCountable - return true if the loop count can be determi- */
1343 /* -ned at compile time . */
1344 /*-----------------------------------------------------------------*/
1346 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1347 symbol ** sym, ast ** init, ast ** end)
1350 /* the loop is considered countable if the following
1351 conditions are true :-
1353 a) initExpr :- <sym> = <const>
1354 b) condExpr :- <sym> < <const1>
1355 c) loopExpr :- <sym> ++
1358 /* first check the initExpr */
1359 if (IS_AST_OP (initExpr) &&
1360 initExpr->opval.op == '=' && /* is assignment */
1361 IS_AST_SYM_VALUE (initExpr->left))
1362 { /* left is a symbol */
1364 *sym = AST_SYMBOL (initExpr->left);
1365 *init = initExpr->right;
1370 /* for now the symbol has to be of
1372 if (!IS_INTEGRAL ((*sym)->type))
1375 /* now check condExpr */
1376 if (IS_AST_OP (condExpr))
1379 switch (condExpr->opval.op)
1382 if (IS_AST_SYM_VALUE (condExpr->left) &&
1383 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1384 IS_AST_LIT_VALUE (condExpr->right))
1386 *end = condExpr->right;
1392 if (IS_AST_OP (condExpr->left) &&
1393 condExpr->left->opval.op == '>' &&
1394 IS_AST_LIT_VALUE (condExpr->left->right) &&
1395 IS_AST_SYM_VALUE (condExpr->left->left) &&
1396 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1399 *end = newNode ('+', condExpr->left->right,
1400 newAst_VALUE (constVal ("1")));
1411 /* check loop expression is of the form <sym>++ */
1412 if (!IS_AST_OP (loopExpr))
1415 /* check if <sym> ++ */
1416 if (loopExpr->opval.op == INC_OP)
1422 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1423 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1430 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1431 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1439 if (loopExpr->opval.op == ADD_ASSIGN)
1442 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1443 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1444 IS_AST_LIT_VALUE (loopExpr->right) &&
1445 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1453 /*-----------------------------------------------------------------*/
1454 /* astHasVolatile - returns true if ast contains any volatile */
1455 /*-----------------------------------------------------------------*/
1457 astHasVolatile (ast * tree)
1462 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1465 if (IS_AST_OP (tree))
1466 return astHasVolatile (tree->left) ||
1467 astHasVolatile (tree->right);
1472 /*-----------------------------------------------------------------*/
1473 /* astHasPointer - return true if the ast contains any ptr variable */
1474 /*-----------------------------------------------------------------*/
1476 astHasPointer (ast * tree)
1481 if (IS_AST_LINK (tree))
1484 /* if we hit an array expression then check
1485 only the left side */
1486 if (IS_AST_OP (tree) && tree->opval.op == '[')
1487 return astHasPointer (tree->left);
1489 if (IS_AST_VALUE (tree))
1490 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1492 return astHasPointer (tree->left) ||
1493 astHasPointer (tree->right);
1497 /*-----------------------------------------------------------------*/
1498 /* astHasSymbol - return true if the ast has the given symbol */
1499 /*-----------------------------------------------------------------*/
1501 astHasSymbol (ast * tree, symbol * sym)
1503 if (!tree || IS_AST_LINK (tree))
1506 if (IS_AST_VALUE (tree))
1508 if (IS_AST_SYM_VALUE (tree))
1509 return isSymbolEqual (AST_SYMBOL (tree), sym);
1514 return astHasSymbol (tree->left, sym) ||
1515 astHasSymbol (tree->right, sym);
1518 /*-----------------------------------------------------------------*/
1519 /* astHasDeref - return true if the ast has an indirect access */
1520 /*-----------------------------------------------------------------*/
1522 astHasDeref (ast * tree)
1524 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1527 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1529 return astHasDeref (tree->left) || astHasDeref (tree->right);
1532 /*-----------------------------------------------------------------*/
1533 /* isConformingBody - the loop body has to conform to a set of rules */
1534 /* for the loop to be considered reversible read on for rules */
1535 /*-----------------------------------------------------------------*/
1537 isConformingBody (ast * pbody, symbol * sym, ast * body)
1540 /* we are going to do a pre-order traversal of the
1541 tree && check for the following conditions. (essentially
1542 a set of very shallow tests )
1543 a) the sym passed does not participate in
1544 any arithmetic operation
1545 b) There are no function calls
1546 c) all jumps are within the body
1547 d) address of loop control variable not taken
1548 e) if an assignment has a pointer on the
1549 left hand side make sure right does not have
1550 loop control variable */
1552 /* if we reach the end or a leaf then true */
1553 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1556 /* if anything else is "volatile" */
1557 if (IS_VOLATILE (TETYPE (pbody)))
1560 /* we will walk the body in a pre-order traversal for
1562 switch (pbody->opval.op)
1564 /*------------------------------------------------------------------*/
1566 // if the loopvar is used as an index
1567 if (astHasSymbol(pbody->right, sym)) {
1570 return isConformingBody (pbody->right, sym, body);
1572 /*------------------------------------------------------------------*/
1577 /*------------------------------------------------------------------*/
1578 case INC_OP: /* incerement operator unary so left only */
1581 /* sure we are not sym is not modified */
1583 IS_AST_SYM_VALUE (pbody->left) &&
1584 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1588 IS_AST_SYM_VALUE (pbody->right) &&
1589 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1594 /*------------------------------------------------------------------*/
1596 case '*': /* can be unary : if right is null then unary operation */
1601 /* if right is NULL then unary operation */
1602 /*------------------------------------------------------------------*/
1603 /*----------------------------*/
1605 /*----------------------------*/
1608 if (IS_AST_SYM_VALUE (pbody->left) &&
1609 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1612 return isConformingBody (pbody->left, sym, body);
1616 if (astHasSymbol (pbody->left, sym) ||
1617 astHasSymbol (pbody->right, sym))
1622 /*------------------------------------------------------------------*/
1630 if (IS_AST_SYM_VALUE (pbody->left) &&
1631 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1634 if (IS_AST_SYM_VALUE (pbody->right) &&
1635 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1638 return isConformingBody (pbody->left, sym, body) &&
1639 isConformingBody (pbody->right, sym, body);
1646 if (IS_AST_SYM_VALUE (pbody->left) &&
1647 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1649 return isConformingBody (pbody->left, sym, body);
1651 /*------------------------------------------------------------------*/
1663 case SIZEOF: /* evaluate wihout code generation */
1665 return isConformingBody (pbody->left, sym, body) &&
1666 isConformingBody (pbody->right, sym, body);
1668 /*------------------------------------------------------------------*/
1671 /* if left has a pointer & right has loop
1672 control variable then we cannot */
1673 if (astHasPointer (pbody->left) &&
1674 astHasSymbol (pbody->right, sym))
1676 if (astHasVolatile (pbody->left))
1679 if (IS_AST_SYM_VALUE (pbody->left)) {
1680 // if the loopvar has an assignment
1681 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1683 // if the loopvar is used in another (maybe conditional) block
1684 if (astHasSymbol (pbody->right, sym) &&
1685 (pbody->level > body->level)) {
1690 if (astHasVolatile (pbody->left))
1693 if (astHasDeref(pbody->right)) return FALSE;
1695 return isConformingBody (pbody->left, sym, body) &&
1696 isConformingBody (pbody->right, sym, body);
1707 assert ("Parser should not have generated this\n");
1709 /*------------------------------------------------------------------*/
1710 /*----------------------------*/
1711 /* comma operator */
1712 /*----------------------------*/
1714 return isConformingBody (pbody->left, sym, body) &&
1715 isConformingBody (pbody->right, sym, body);
1717 /*------------------------------------------------------------------*/
1718 /*----------------------------*/
1720 /*----------------------------*/
1722 /* if local & not passed as paramater then ok */
1723 if (sym->level && !astHasSymbol(pbody->right,sym))
1727 /*------------------------------------------------------------------*/
1728 /*----------------------------*/
1729 /* return statement */
1730 /*----------------------------*/
1735 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1740 if (astHasSymbol (pbody->left, sym))
1747 return isConformingBody (pbody->left, sym, body) &&
1748 isConformingBody (pbody->right, sym, body);
1754 /*-----------------------------------------------------------------*/
1755 /* isLoopReversible - takes a for loop as input && returns true */
1756 /* if the for loop is reversible. If yes will set the value of */
1757 /* the loop control var & init value & termination value */
1758 /*-----------------------------------------------------------------*/
1760 isLoopReversible (ast * loop, symbol ** loopCntrl,
1761 ast ** init, ast ** end)
1763 /* if option says don't do it then don't */
1764 if (optimize.noLoopReverse)
1766 /* there are several tests to determine this */
1768 /* for loop has to be of the form
1769 for ( <sym> = <const1> ;
1770 [<sym> < <const2>] ;
1771 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1773 if (!isLoopCountable (AST_FOR (loop, initExpr),
1774 AST_FOR (loop, condExpr),
1775 AST_FOR (loop, loopExpr),
1776 loopCntrl, init, end))
1779 /* now do some serious checking on the body of the loop
1782 return isConformingBody (loop->left, *loopCntrl, loop->left);
1786 /*-----------------------------------------------------------------*/
1787 /* replLoopSym - replace the loop sym by loop sym -1 */
1788 /*-----------------------------------------------------------------*/
1790 replLoopSym (ast * body, symbol * sym)
1793 if (!body || IS_AST_LINK (body))
1796 if (IS_AST_SYM_VALUE (body))
1799 if (isSymbolEqual (AST_SYMBOL (body), sym))
1803 body->opval.op = '-';
1804 body->left = newAst_VALUE (symbolVal (sym));
1805 body->right = newAst_VALUE (constVal ("1"));
1813 replLoopSym (body->left, sym);
1814 replLoopSym (body->right, sym);
1818 /*-----------------------------------------------------------------*/
1819 /* reverseLoop - do the actual loop reversal */
1820 /*-----------------------------------------------------------------*/
1822 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1826 /* create the following tree
1831 if (sym) goto for_continue ;
1834 /* put it together piece by piece */
1835 rloop = newNode (NULLOP,
1836 createIf (newAst_VALUE (symbolVal (sym)),
1838 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1841 newAst_VALUE (symbolVal (sym)),
1844 replLoopSym (loop->left, sym);
1845 setAstLineno (rloop, init->lineno);
1847 rloop = newNode (NULLOP,
1849 newAst_VALUE (symbolVal (sym)),
1850 newNode ('-', end, init)),
1851 createLabel (AST_FOR (loop, continueLabel),
1855 newNode (SUB_ASSIGN,
1856 newAst_VALUE (symbolVal (sym)),
1857 newAst_VALUE (constVal ("1"))),
1860 rloop->lineno=init->lineno;
1861 return decorateType (rloop);
1865 /*-----------------------------------------------------------------*/
1866 /* decorateType - compute type for this tree also does type cheking */
1867 /* this is done bottom up, since type have to flow upwards */
1868 /* it also does constant folding, and paramater checking */
1869 /*-----------------------------------------------------------------*/
1871 decorateType (ast * tree)
1879 /* if already has type then do nothing */
1880 if (tree->decorated)
1883 tree->decorated = 1;
1886 /* print the line */
1887 /* if not block & function */
1888 if (tree->type == EX_OP &&
1889 (tree->opval.op != FUNCTION &&
1890 tree->opval.op != BLOCK &&
1891 tree->opval.op != NULLOP))
1893 filename = tree->filename;
1894 lineno = tree->lineno;
1898 /* if any child is an error | this one is an error do nothing */
1899 if (tree->isError ||
1900 (tree->left && tree->left->isError) ||
1901 (tree->right && tree->right->isError))
1904 /*------------------------------------------------------------------*/
1905 /*----------------------------*/
1906 /* leaf has been reached */
1907 /*----------------------------*/
1908 lineno=tree->lineno;
1909 /* if this is of type value */
1910 /* just get the type */
1911 if (tree->type == EX_VALUE)
1914 if (IS_LITERAL (tree->opval.val->etype))
1917 /* if this is a character array then declare it */
1918 if (IS_ARRAY (tree->opval.val->type))
1919 tree->opval.val = stringToSymbol (tree->opval.val);
1921 /* otherwise just copy the type information */
1922 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1926 if (tree->opval.val->sym)
1928 /* if the undefined flag is set then give error message */
1929 if (tree->opval.val->sym->undefined)
1931 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1933 TTYPE (tree) = TETYPE (tree) =
1934 tree->opval.val->type = tree->opval.val->sym->type =
1935 tree->opval.val->etype = tree->opval.val->sym->etype =
1936 copyLinkChain (INTTYPE);
1941 /* if impilicit i.e. struct/union member then no type */
1942 if (tree->opval.val->sym->implicit)
1943 TTYPE (tree) = TETYPE (tree) = NULL;
1948 /* else copy the type */
1949 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1951 /* and mark it as referenced */
1952 tree->opval.val->sym->isref = 1;
1960 /* if type link for the case of cast */
1961 if (tree->type == EX_LINK)
1963 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1970 dtl = decorateType (tree->left);
1971 /* delay right side for '?' operator since conditional macro expansions might
1973 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1975 /* this is to take care of situations
1976 when the tree gets rewritten */
1977 if (dtl != tree->left)
1979 if (dtr != tree->right)
1982 if (IS_AST_OP(tree) &&
1983 (tree->opval.op == CAST || tree->opval.op == '=') &&
1984 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
1985 (getSize(RTYPE(tree)) < INTSIZE)) {
1986 // this is a cast/assign to a bigger type
1987 if (IS_AST_OP(tree->right) &&
1988 IS_INTEGRAL(tree->right->ftype) &&
1989 (tree->right->opval.op == LEFT_OP ||
1990 tree->right->opval.op == '*' ||
1991 tree->right->opval.op == '+' ||
1992 tree->right->opval.op == '-') &&
1993 tree->right->right) {
1994 // we should cast an operand instead of the result
1995 tree->right->decorated = 0;
1996 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
1998 tree->right = decorateType(tree->right);
2003 /* depending on type of operator do */
2005 switch (tree->opval.op)
2007 /*------------------------------------------------------------------*/
2008 /*----------------------------*/
2010 /*----------------------------*/
2013 /* determine which is the array & which the index */
2014 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2017 ast *tempTree = tree->left;
2018 tree->left = tree->right;
2019 tree->right = tempTree;
2022 /* first check if this is a array or a pointer */
2023 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2025 werror (E_NEED_ARRAY_PTR, "[]");
2026 goto errorTreeReturn;
2029 /* check if the type of the idx */
2030 if (!IS_INTEGRAL (RTYPE (tree)))
2032 werror (E_IDX_NOT_INT);
2033 goto errorTreeReturn;
2036 /* if the left is an rvalue then error */
2039 werror (E_LVALUE_REQUIRED, "array access");
2040 goto errorTreeReturn;
2043 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2044 if (IS_PTR(LTYPE(tree))) {
2045 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2049 /*------------------------------------------------------------------*/
2050 /*----------------------------*/
2052 /*----------------------------*/
2054 /* if this is not a structure */
2055 if (!IS_STRUCT (LTYPE (tree)))
2057 werror (E_STRUCT_UNION, ".");
2058 goto errorTreeReturn;
2060 TTYPE (tree) = structElemType (LTYPE (tree),
2061 (tree->right->type == EX_VALUE ?
2062 tree->right->opval.val : NULL));
2063 TETYPE (tree) = getSpec (TTYPE (tree));
2066 /*------------------------------------------------------------------*/
2067 /*----------------------------*/
2068 /* struct/union pointer */
2069 /*----------------------------*/
2071 /* if not pointer to a structure */
2072 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2074 werror (E_PTR_REQD);
2075 goto errorTreeReturn;
2078 if (!IS_STRUCT (LTYPE (tree)->next))
2080 werror (E_STRUCT_UNION, "->");
2081 goto errorTreeReturn;
2084 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2085 (tree->right->type == EX_VALUE ?
2086 tree->right->opval.val : NULL));
2087 TETYPE (tree) = getSpec (TTYPE (tree));
2089 /* adjust the storage class */
2090 switch (DCL_TYPE(tree->left->ftype)) {
2094 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2097 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2102 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2105 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2108 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2118 /*------------------------------------------------------------------*/
2119 /*----------------------------*/
2120 /* ++/-- operation */
2121 /*----------------------------*/
2122 case INC_OP: /* incerement operator unary so left only */
2125 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2126 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2127 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2128 werror (E_CODE_WRITE, "++/--");
2137 /*------------------------------------------------------------------*/
2138 /*----------------------------*/
2140 /*----------------------------*/
2141 case '&': /* can be unary */
2142 /* if right is NULL then unary operation */
2143 if (tree->right) /* not an unary operation */
2146 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2148 werror (E_BITWISE_OP);
2149 werror (W_CONTINUE, "left & right types are ");
2150 printTypeChain (LTYPE (tree), stderr);
2151 fprintf (stderr, ",");
2152 printTypeChain (RTYPE (tree), stderr);
2153 fprintf (stderr, "\n");
2154 goto errorTreeReturn;
2157 /* if they are both literal */
2158 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2160 tree->type = EX_VALUE;
2161 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2162 valFromType (RETYPE (tree)), '&');
2164 tree->right = tree->left = NULL;
2165 TETYPE (tree) = tree->opval.val->etype;
2166 TTYPE (tree) = tree->opval.val->type;
2170 /* see if this is a GETHBIT operation if yes
2173 ast *otree = optimizeGetHbit (tree);
2176 return decorateType (otree);
2180 computeType (LTYPE (tree), RTYPE (tree));
2181 TETYPE (tree) = getSpec (TTYPE (tree));
2183 LRVAL (tree) = RRVAL (tree) = 1;
2187 /*------------------------------------------------------------------*/
2188 /*----------------------------*/
2190 /*----------------------------*/
2192 p->class = DECLARATOR;
2193 /* if bit field then error */
2194 if (IS_BITVAR (tree->left->etype))
2196 werror (E_ILLEGAL_ADDR, "address of bit variable");
2197 goto errorTreeReturn;
2200 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2202 werror (E_ILLEGAL_ADDR, "address of register variable");
2203 goto errorTreeReturn;
2206 if (IS_FUNC (LTYPE (tree)))
2208 // this ought to be ignored
2209 return (tree->left);
2212 if (IS_LITERAL(LTYPE(tree)))
2214 werror (E_ILLEGAL_ADDR, "address of literal");
2215 goto errorTreeReturn;
2220 werror (E_LVALUE_REQUIRED, "address of");
2221 goto errorTreeReturn;
2223 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2225 DCL_TYPE (p) = CPOINTER;
2226 DCL_PTR_CONST (p) = port->mem.code_ro;
2228 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2229 DCL_TYPE (p) = FPOINTER;
2230 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2231 DCL_TYPE (p) = PPOINTER;
2232 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2233 DCL_TYPE (p) = IPOINTER;
2234 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2235 DCL_TYPE (p) = EEPPOINTER;
2236 else if (SPEC_OCLS(tree->left->etype))
2237 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2239 DCL_TYPE (p) = POINTER;
2241 if (IS_AST_SYM_VALUE (tree->left))
2243 AST_SYMBOL (tree->left)->addrtaken = 1;
2244 AST_SYMBOL (tree->left)->allocreq = 1;
2247 p->next = LTYPE (tree);
2249 TETYPE (tree) = getSpec (TTYPE (tree));
2250 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2251 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2256 /*------------------------------------------------------------------*/
2257 /*----------------------------*/
2259 /*----------------------------*/
2261 /* if the rewrite succeeds then don't go any furthur */
2263 ast *wtree = optimizeRRCRLC (tree);
2265 return decorateType (wtree);
2267 /*------------------------------------------------------------------*/
2268 /*----------------------------*/
2270 /*----------------------------*/
2272 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2274 werror (E_BITWISE_OP);
2275 werror (W_CONTINUE, "left & right types are ");
2276 printTypeChain (LTYPE (tree), stderr);
2277 fprintf (stderr, ",");
2278 printTypeChain (RTYPE (tree), stderr);
2279 fprintf (stderr, "\n");
2280 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 = valBitwise (valFromType (LETYPE (tree)),
2289 valFromType (RETYPE (tree)),
2291 tree->right = tree->left = NULL;
2292 TETYPE (tree) = tree->opval.val->etype;
2293 TTYPE (tree) = tree->opval.val->type;
2296 LRVAL (tree) = RRVAL (tree) = 1;
2297 TETYPE (tree) = getSpec (TTYPE (tree) =
2298 computeType (LTYPE (tree),
2301 /*------------------------------------------------------------------*/
2302 /*----------------------------*/
2304 /*----------------------------*/
2306 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2308 werror (E_INVALID_OP, "divide");
2309 goto errorTreeReturn;
2311 /* if they are both literal then */
2312 /* rewrite the tree */
2313 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2315 tree->type = EX_VALUE;
2316 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2317 valFromType (RETYPE (tree)));
2318 tree->right = tree->left = NULL;
2319 TETYPE (tree) = getSpec (TTYPE (tree) =
2320 tree->opval.val->type);
2323 LRVAL (tree) = RRVAL (tree) = 1;
2324 TETYPE (tree) = getSpec (TTYPE (tree) =
2325 computeType (LTYPE (tree),
2329 /*------------------------------------------------------------------*/
2330 /*----------------------------*/
2332 /*----------------------------*/
2334 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2336 werror (E_BITWISE_OP);
2337 werror (W_CONTINUE, "left & right types are ");
2338 printTypeChain (LTYPE (tree), stderr);
2339 fprintf (stderr, ",");
2340 printTypeChain (RTYPE (tree), stderr);
2341 fprintf (stderr, "\n");
2342 goto errorTreeReturn;
2344 /* if they are both literal then */
2345 /* rewrite the tree */
2346 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2348 tree->type = EX_VALUE;
2349 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2350 valFromType (RETYPE (tree)));
2351 tree->right = tree->left = NULL;
2352 TETYPE (tree) = getSpec (TTYPE (tree) =
2353 tree->opval.val->type);
2356 LRVAL (tree) = RRVAL (tree) = 1;
2357 TETYPE (tree) = getSpec (TTYPE (tree) =
2358 computeType (LTYPE (tree),
2362 /*------------------------------------------------------------------*/
2363 /*----------------------------*/
2364 /* address dereference */
2365 /*----------------------------*/
2366 case '*': /* can be unary : if right is null then unary operation */
2369 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2371 werror (E_PTR_REQD);
2372 goto errorTreeReturn;
2377 werror (E_LVALUE_REQUIRED, "pointer deref");
2378 goto errorTreeReturn;
2380 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2381 LTYPE (tree)->next : NULL);
2382 TETYPE (tree) = getSpec (TTYPE (tree));
2383 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2387 /*------------------------------------------------------------------*/
2388 /*----------------------------*/
2389 /* multiplication */
2390 /*----------------------------*/
2391 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2393 werror (E_INVALID_OP, "multiplication");
2394 goto errorTreeReturn;
2397 /* if they are both literal then */
2398 /* rewrite the tree */
2399 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2401 tree->type = EX_VALUE;
2402 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2403 valFromType (RETYPE (tree)));
2404 tree->right = tree->left = NULL;
2405 TETYPE (tree) = getSpec (TTYPE (tree) =
2406 tree->opval.val->type);
2410 /* if left is a literal exchange left & right */
2411 if (IS_LITERAL (LTYPE (tree)))
2413 ast *tTree = tree->left;
2414 tree->left = tree->right;
2415 tree->right = tTree;
2418 LRVAL (tree) = RRVAL (tree) = 1;
2419 TETYPE (tree) = getSpec (TTYPE (tree) =
2420 computeType (LTYPE (tree),
2423 /* promote result to int if left & right are char
2424 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2425 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2426 SPEC_NOUN(TETYPE(tree)) = V_INT;
2431 /*------------------------------------------------------------------*/
2432 /*----------------------------*/
2433 /* unary '+' operator */
2434 /*----------------------------*/
2439 if (!IS_INTEGRAL (LTYPE (tree)))
2441 werror (E_UNARY_OP, '+');
2442 goto errorTreeReturn;
2445 /* if left is a literal then do it */
2446 if (IS_LITERAL (LTYPE (tree)))
2448 tree->type = EX_VALUE;
2449 tree->opval.val = valFromType (LETYPE (tree));
2451 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2455 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2459 /*------------------------------------------------------------------*/
2460 /*----------------------------*/
2462 /*----------------------------*/
2464 /* this is not a unary operation */
2465 /* if both pointers then problem */
2466 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2467 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2469 werror (E_PTR_PLUS_PTR);
2470 goto errorTreeReturn;
2473 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2474 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2476 werror (E_PLUS_INVALID, "+");
2477 goto errorTreeReturn;
2480 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2481 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2483 werror (E_PLUS_INVALID, "+");
2484 goto errorTreeReturn;
2486 /* if they are both literal then */
2487 /* rewrite the tree */
2488 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2490 tree->type = EX_VALUE;
2491 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2492 valFromType (RETYPE (tree)));
2493 tree->right = tree->left = NULL;
2494 TETYPE (tree) = getSpec (TTYPE (tree) =
2495 tree->opval.val->type);
2499 /* if the right is a pointer or left is a literal
2500 xchange left & right */
2501 if (IS_ARRAY (RTYPE (tree)) ||
2502 IS_PTR (RTYPE (tree)) ||
2503 IS_LITERAL (LTYPE (tree)))
2505 ast *tTree = tree->left;
2506 tree->left = tree->right;
2507 tree->right = tTree;
2510 LRVAL (tree) = RRVAL (tree) = 1;
2511 /* if the left is a pointer */
2512 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2513 TETYPE (tree) = getSpec (TTYPE (tree) =
2516 TETYPE (tree) = getSpec (TTYPE (tree) =
2517 computeType (LTYPE (tree),
2521 /*------------------------------------------------------------------*/
2522 /*----------------------------*/
2524 /*----------------------------*/
2525 case '-': /* can be unary */
2526 /* if right is null then unary */
2530 if (!IS_ARITHMETIC (LTYPE (tree)))
2532 werror (E_UNARY_OP, tree->opval.op);
2533 goto errorTreeReturn;
2536 /* if left is a literal then do it */
2537 if (IS_LITERAL (LTYPE (tree)))
2539 tree->type = EX_VALUE;
2540 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2542 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2543 SPEC_USIGN(TETYPE(tree)) = 0;
2547 TTYPE (tree) = LTYPE (tree);
2551 /*------------------------------------------------------------------*/
2552 /*----------------------------*/
2554 /*----------------------------*/
2556 if (!(IS_PTR (LTYPE (tree)) ||
2557 IS_ARRAY (LTYPE (tree)) ||
2558 IS_ARITHMETIC (LTYPE (tree))))
2560 werror (E_PLUS_INVALID, "-");
2561 goto errorTreeReturn;
2564 if (!(IS_PTR (RTYPE (tree)) ||
2565 IS_ARRAY (RTYPE (tree)) ||
2566 IS_ARITHMETIC (RTYPE (tree))))
2568 werror (E_PLUS_INVALID, "-");
2569 goto errorTreeReturn;
2572 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2573 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2574 IS_INTEGRAL (RTYPE (tree))))
2576 werror (E_PLUS_INVALID, "-");
2577 goto errorTreeReturn;
2580 /* if they are both literal then */
2581 /* rewrite the tree */
2582 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2584 tree->type = EX_VALUE;
2585 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2586 valFromType (RETYPE (tree)));
2587 tree->right = tree->left = NULL;
2588 TETYPE (tree) = getSpec (TTYPE (tree) =
2589 tree->opval.val->type);
2593 /* if the left & right are equal then zero */
2594 if (isAstEqual (tree->left, tree->right))
2596 tree->type = EX_VALUE;
2597 tree->left = tree->right = NULL;
2598 tree->opval.val = constVal ("0");
2599 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2603 /* if both of them are pointers or arrays then */
2604 /* the result is going to be an integer */
2605 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2606 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2607 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2609 /* if only the left is a pointer */
2610 /* then result is a pointer */
2611 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2612 TETYPE (tree) = getSpec (TTYPE (tree) =
2615 TETYPE (tree) = getSpec (TTYPE (tree) =
2616 computeType (LTYPE (tree),
2618 LRVAL (tree) = RRVAL (tree) = 1;
2621 /*------------------------------------------------------------------*/
2622 /*----------------------------*/
2624 /*----------------------------*/
2626 /* can be only integral type */
2627 if (!IS_INTEGRAL (LTYPE (tree)))
2629 werror (E_UNARY_OP, tree->opval.op);
2630 goto errorTreeReturn;
2633 /* if left is a literal then do it */
2634 if (IS_LITERAL (LTYPE (tree)))
2636 tree->type = EX_VALUE;
2637 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2639 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2643 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2646 /*------------------------------------------------------------------*/
2647 /*----------------------------*/
2649 /*----------------------------*/
2651 /* can be pointer */
2652 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2653 !IS_PTR (LTYPE (tree)) &&
2654 !IS_ARRAY (LTYPE (tree)))
2656 werror (E_UNARY_OP, tree->opval.op);
2657 goto errorTreeReturn;
2660 /* if left is a literal then do it */
2661 if (IS_LITERAL (LTYPE (tree)))
2663 tree->type = EX_VALUE;
2664 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2666 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2670 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2673 /*------------------------------------------------------------------*/
2674 /*----------------------------*/
2676 /*----------------------------*/
2679 TTYPE (tree) = LTYPE (tree);
2680 TETYPE (tree) = LETYPE (tree);
2684 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2689 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2691 werror (E_SHIFT_OP_INVALID);
2692 werror (W_CONTINUE, "left & right types are ");
2693 printTypeChain (LTYPE (tree), stderr);
2694 fprintf (stderr, ",");
2695 printTypeChain (RTYPE (tree), stderr);
2696 fprintf (stderr, "\n");
2697 goto errorTreeReturn;
2700 /* if they are both literal then */
2701 /* rewrite the tree */
2702 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2704 tree->type = EX_VALUE;
2705 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2706 valFromType (RETYPE (tree)),
2707 (tree->opval.op == LEFT_OP ? 1 : 0));
2708 tree->right = tree->left = NULL;
2709 TETYPE (tree) = getSpec (TTYPE (tree) =
2710 tree->opval.val->type);
2714 /* if only the right side is a literal & we are
2715 shifting more than size of the left operand then zero */
2716 if (IS_LITERAL (RTYPE (tree)) &&
2717 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2718 (getSize (LTYPE (tree)) * 8))
2720 if (tree->opval.op==LEFT_OP ||
2721 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2722 lineno=tree->lineno;
2723 werror (W_SHIFT_CHANGED,
2724 (tree->opval.op == LEFT_OP ? "left" : "right"));
2725 tree->type = EX_VALUE;
2726 tree->left = tree->right = NULL;
2727 tree->opval.val = constVal ("0");
2728 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2732 LRVAL (tree) = RRVAL (tree) = 1;
2733 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2735 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2739 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2743 /*------------------------------------------------------------------*/
2744 /*----------------------------*/
2746 /*----------------------------*/
2747 case CAST: /* change the type */
2748 /* cannot cast to an aggregate type */
2749 if (IS_AGGREGATE (LTYPE (tree)))
2751 werror (E_CAST_ILLEGAL);
2752 goto errorTreeReturn;
2755 /* make sure the type is complete and sane */
2756 checkTypeSanity(LETYPE(tree), "(cast)");
2759 /* if the right is a literal replace the tree */
2760 if (IS_LITERAL (RETYPE (tree))) {
2761 if (!IS_PTR (LTYPE (tree))) {
2762 tree->type = EX_VALUE;
2764 valCastLiteral (LTYPE (tree),
2765 floatFromVal (valFromType (RETYPE (tree))));
2768 TTYPE (tree) = tree->opval.val->type;
2769 tree->values.literalFromCast = 1;
2770 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2771 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2772 sym_link *rest = LTYPE(tree)->next;
2773 werror(W_LITERAL_GENERIC);
2774 TTYPE(tree) = newLink();
2775 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2776 TTYPE(tree)->next = rest;
2777 tree->left->opval.lnk = TTYPE(tree);
2780 TTYPE (tree) = LTYPE (tree);
2784 TTYPE (tree) = LTYPE (tree);
2788 #if 0 // this is already checked, now this could be explicit
2789 /* if pointer to struct then check names */
2790 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2791 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2792 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2794 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2795 SPEC_STRUCT(LETYPE(tree))->tag);
2798 /* if the right is a literal replace the tree */
2799 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2800 tree->type = EX_VALUE;
2802 valCastLiteral (LTYPE (tree),
2803 floatFromVal (valFromType (RETYPE (tree))));
2806 TTYPE (tree) = tree->opval.val->type;
2807 tree->values.literalFromCast = 1;
2809 TTYPE (tree) = LTYPE (tree);
2813 TETYPE (tree) = getSpec (TTYPE (tree));
2817 /*------------------------------------------------------------------*/
2818 /*----------------------------*/
2819 /* logical &&, || */
2820 /*----------------------------*/
2823 /* each must me arithmetic type or be a pointer */
2824 if (!IS_PTR (LTYPE (tree)) &&
2825 !IS_ARRAY (LTYPE (tree)) &&
2826 !IS_INTEGRAL (LTYPE (tree)))
2828 werror (E_COMPARE_OP);
2829 goto errorTreeReturn;
2832 if (!IS_PTR (RTYPE (tree)) &&
2833 !IS_ARRAY (RTYPE (tree)) &&
2834 !IS_INTEGRAL (RTYPE (tree)))
2836 werror (E_COMPARE_OP);
2837 goto errorTreeReturn;
2839 /* if they are both literal then */
2840 /* rewrite the tree */
2841 if (IS_LITERAL (RTYPE (tree)) &&
2842 IS_LITERAL (LTYPE (tree)))
2844 tree->type = EX_VALUE;
2845 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2846 valFromType (RETYPE (tree)),
2848 tree->right = tree->left = NULL;
2849 TETYPE (tree) = getSpec (TTYPE (tree) =
2850 tree->opval.val->type);
2853 LRVAL (tree) = RRVAL (tree) = 1;
2854 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2857 /*------------------------------------------------------------------*/
2858 /*----------------------------*/
2859 /* comparison operators */
2860 /*----------------------------*/
2868 ast *lt = optimizeCompare (tree);
2874 /* if they are pointers they must be castable */
2875 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2877 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2879 werror (E_COMPARE_OP);
2880 fprintf (stderr, "comparing type ");
2881 printTypeChain (LTYPE (tree), stderr);
2882 fprintf (stderr, "to type ");
2883 printTypeChain (RTYPE (tree), stderr);
2884 fprintf (stderr, "\n");
2885 goto errorTreeReturn;
2888 /* else they should be promotable to one another */
2891 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2892 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2894 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2896 werror (E_COMPARE_OP);
2897 fprintf (stderr, "comparing type ");
2898 printTypeChain (LTYPE (tree), stderr);
2899 fprintf (stderr, "to type ");
2900 printTypeChain (RTYPE (tree), stderr);
2901 fprintf (stderr, "\n");
2902 goto errorTreeReturn;
2905 /* if unsigned value < 0 then always false */
2906 /* if (unsigned value) > 0 then (unsigned value) */
2907 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2908 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2910 if (tree->opval.op == '<') {
2913 if (tree->opval.op == '>') {
2917 /* if they are both literal then */
2918 /* rewrite the tree */
2919 if (IS_LITERAL (RTYPE (tree)) &&
2920 IS_LITERAL (LTYPE (tree)))
2922 tree->type = EX_VALUE;
2923 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2924 valFromType (RETYPE (tree)),
2926 tree->right = tree->left = NULL;
2927 TETYPE (tree) = getSpec (TTYPE (tree) =
2928 tree->opval.val->type);
2931 LRVAL (tree) = RRVAL (tree) = 1;
2932 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2935 /*------------------------------------------------------------------*/
2936 /*----------------------------*/
2938 /*----------------------------*/
2939 case SIZEOF: /* evaluate wihout code generation */
2940 /* change the type to a integer */
2941 tree->type = EX_VALUE;
2942 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2943 tree->opval.val = constVal (buffer);
2944 tree->right = tree->left = NULL;
2945 TETYPE (tree) = getSpec (TTYPE (tree) =
2946 tree->opval.val->type);
2949 /*------------------------------------------------------------------*/
2950 /*----------------------------*/
2952 /*----------------------------*/
2954 /* return typeof enum value */
2955 tree->type = EX_VALUE;
2958 if (IS_SPEC(tree->right->ftype)) {
2959 switch (SPEC_NOUN(tree->right->ftype)) {
2961 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2962 else typeofv = TYPEOF_INT;
2965 typeofv = TYPEOF_FLOAT;
2968 typeofv = TYPEOF_CHAR;
2971 typeofv = TYPEOF_VOID;
2974 typeofv = TYPEOF_STRUCT;
2977 typeofv = TYPEOF_BIT;
2980 typeofv = TYPEOF_SBIT;
2986 switch (DCL_TYPE(tree->right->ftype)) {
2988 typeofv = TYPEOF_POINTER;
2991 typeofv = TYPEOF_FPOINTER;
2994 typeofv = TYPEOF_CPOINTER;
2997 typeofv = TYPEOF_GPOINTER;
3000 typeofv = TYPEOF_PPOINTER;
3003 typeofv = TYPEOF_IPOINTER;
3006 typeofv = TYPEOF_ARRAY;
3009 typeofv = TYPEOF_FUNCTION;
3015 sprintf (buffer, "%d", typeofv);
3016 tree->opval.val = constVal (buffer);
3017 tree->right = tree->left = NULL;
3018 TETYPE (tree) = getSpec (TTYPE (tree) =
3019 tree->opval.val->type);
3022 /*------------------------------------------------------------------*/
3023 /*----------------------------*/
3024 /* conditional operator '?' */
3025 /*----------------------------*/
3027 /* the type is value of the colon operator (on the right) */
3028 assert(IS_COLON_OP(tree->right));
3029 /* if already known then replace the tree : optimizer will do it
3030 but faster to do it here */
3031 if (IS_LITERAL (LTYPE(tree))) {
3032 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3033 return decorateType(tree->right->left) ;
3035 return decorateType(tree->right->right) ;
3038 tree->right = decorateType(tree->right);
3039 TTYPE (tree) = RTYPE(tree);
3040 TETYPE (tree) = getSpec (TTYPE (tree));
3045 /* if they don't match we have a problem */
3046 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3048 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3049 goto errorTreeReturn;
3052 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3053 TETYPE (tree) = getSpec (TTYPE (tree));
3057 #if 0 // assignment operators are converted by the parser
3058 /*------------------------------------------------------------------*/
3059 /*----------------------------*/
3060 /* assignment operators */
3061 /*----------------------------*/
3064 /* for these it must be both must be integral */
3065 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3066 !IS_ARITHMETIC (RTYPE (tree)))
3068 werror (E_OPS_INTEGRAL);
3069 goto errorTreeReturn;
3072 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3074 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3075 werror (E_CODE_WRITE, " ");
3079 werror (E_LVALUE_REQUIRED, "*= or /=");
3080 goto errorTreeReturn;
3091 /* for these it must be both must be integral */
3092 if (!IS_INTEGRAL (LTYPE (tree)) ||
3093 !IS_INTEGRAL (RTYPE (tree)))
3095 werror (E_OPS_INTEGRAL);
3096 goto errorTreeReturn;
3099 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3101 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3102 werror (E_CODE_WRITE, " ");
3106 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3107 goto errorTreeReturn;
3113 /*------------------------------------------------------------------*/
3114 /*----------------------------*/
3116 /*----------------------------*/
3118 if (!(IS_PTR (LTYPE (tree)) ||
3119 IS_ARITHMETIC (LTYPE (tree))))
3121 werror (E_PLUS_INVALID, "-=");
3122 goto errorTreeReturn;
3125 if (!(IS_PTR (RTYPE (tree)) ||
3126 IS_ARITHMETIC (RTYPE (tree))))
3128 werror (E_PLUS_INVALID, "-=");
3129 goto errorTreeReturn;
3132 TETYPE (tree) = getSpec (TTYPE (tree) =
3133 computeType (LTYPE (tree),
3136 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3137 werror (E_CODE_WRITE, " ");
3141 werror (E_LVALUE_REQUIRED, "-=");
3142 goto errorTreeReturn;
3148 /*------------------------------------------------------------------*/
3149 /*----------------------------*/
3151 /*----------------------------*/
3153 /* this is not a unary operation */
3154 /* if both pointers then problem */
3155 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3157 werror (E_PTR_PLUS_PTR);
3158 goto errorTreeReturn;
3161 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3163 werror (E_PLUS_INVALID, "+=");
3164 goto errorTreeReturn;
3167 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3169 werror (E_PLUS_INVALID, "+=");
3170 goto errorTreeReturn;
3173 TETYPE (tree) = getSpec (TTYPE (tree) =
3174 computeType (LTYPE (tree),
3177 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3178 werror (E_CODE_WRITE, " ");
3182 werror (E_LVALUE_REQUIRED, "+=");
3183 goto errorTreeReturn;
3186 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3187 tree->opval.op = '=';
3192 /*------------------------------------------------------------------*/
3193 /*----------------------------*/
3194 /* straight assignemnt */
3195 /*----------------------------*/
3197 /* cannot be an aggregate */
3198 if (IS_AGGREGATE (LTYPE (tree)))
3200 werror (E_AGGR_ASSIGN);
3201 goto errorTreeReturn;
3204 /* they should either match or be castable */
3205 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3207 werror (E_TYPE_MISMATCH, "assignment", " ");
3208 printFromToType(RTYPE(tree),LTYPE(tree));
3209 //goto errorTreeReturn;
3212 /* if the left side of the tree is of type void
3213 then report error */
3214 if (IS_VOID (LTYPE (tree)))
3216 werror (E_CAST_ZERO);
3217 printFromToType(RTYPE(tree), LTYPE(tree));
3220 TETYPE (tree) = getSpec (TTYPE (tree) =
3224 if (!tree->initMode ) {
3225 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3226 werror (E_CODE_WRITE, " ");
3230 werror (E_LVALUE_REQUIRED, "=");
3231 goto errorTreeReturn;
3236 /*------------------------------------------------------------------*/
3237 /*----------------------------*/
3238 /* comma operator */
3239 /*----------------------------*/
3241 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3244 /*------------------------------------------------------------------*/
3245 /*----------------------------*/
3247 /*----------------------------*/
3251 if (processParms (tree->left,
3252 FUNC_ARGS(tree->left->ftype),
3253 tree->right, &parmNumber, TRUE)) {
3254 goto errorTreeReturn;
3257 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3258 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3260 //FUNC_ARGS(tree->left->ftype) =
3261 //reverseVal (FUNC_ARGS(tree->left->ftype));
3262 reverseParms (tree->right);
3265 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3268 /*------------------------------------------------------------------*/
3269 /*----------------------------*/
3270 /* return statement */
3271 /*----------------------------*/
3276 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3278 werror (W_RETURN_MISMATCH);
3279 printFromToType (RTYPE(tree), currFunc->type->next);
3280 goto errorTreeReturn;
3283 if (IS_VOID (currFunc->type->next)
3285 !IS_VOID (RTYPE (tree)))
3287 werror (E_FUNC_VOID);
3288 goto errorTreeReturn;
3291 /* if there is going to be a casing required then add it */
3292 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3295 decorateType (newNode (CAST,
3296 newAst_LINK (copyLinkChain (currFunc->type->next)),
3305 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3307 werror (E_VOID_FUNC, currFunc->name);
3308 goto errorTreeReturn;
3311 TTYPE (tree) = TETYPE (tree) = NULL;
3314 /*------------------------------------------------------------------*/
3315 /*----------------------------*/
3316 /* switch statement */
3317 /*----------------------------*/
3319 /* the switch value must be an integer */
3320 if (!IS_INTEGRAL (LTYPE (tree)))
3322 werror (E_SWITCH_NON_INTEGER);
3323 goto errorTreeReturn;
3326 TTYPE (tree) = TETYPE (tree) = NULL;
3329 /*------------------------------------------------------------------*/
3330 /*----------------------------*/
3332 /*----------------------------*/
3334 tree->left = backPatchLabels (tree->left,
3337 TTYPE (tree) = TETYPE (tree) = NULL;
3340 /*------------------------------------------------------------------*/
3341 /*----------------------------*/
3343 /*----------------------------*/
3346 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3347 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3348 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3350 /* if the for loop is reversible then
3351 reverse it otherwise do what we normally
3357 if (isLoopReversible (tree, &sym, &init, &end))
3358 return reverseLoop (tree, sym, init, end);
3360 return decorateType (createFor (AST_FOR (tree, trueLabel),
3361 AST_FOR (tree, continueLabel),
3362 AST_FOR (tree, falseLabel),
3363 AST_FOR (tree, condLabel),
3364 AST_FOR (tree, initExpr),
3365 AST_FOR (tree, condExpr),
3366 AST_FOR (tree, loopExpr),
3370 TTYPE (tree) = TETYPE (tree) = NULL;
3374 /* some error found this tree will be killed */
3376 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3377 tree->opval.op = NULLOP;
3383 /*-----------------------------------------------------------------*/
3384 /* sizeofOp - processes size of operation */
3385 /*-----------------------------------------------------------------*/
3387 sizeofOp (sym_link * type)
3391 /* make sure the type is complete and sane */
3392 checkTypeSanity(type, "(sizeof)");
3394 /* get the size and convert it to character */
3395 sprintf (buff, "%d", getSize (type));
3397 /* now convert into value */
3398 return constVal (buff);
3402 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3403 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3404 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3405 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3406 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3407 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3408 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3410 /*-----------------------------------------------------------------*/
3411 /* backPatchLabels - change and or not operators to flow control */
3412 /*-----------------------------------------------------------------*/
3414 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3420 if (!(IS_ANDORNOT (tree)))
3423 /* if this an and */
3426 static int localLbl = 0;
3429 sprintf (buffer, "_and_%d", localLbl++);
3430 localLabel = newSymbol (buffer, NestLevel);
3432 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3434 /* if left is already a IFX then just change the if true label in that */
3435 if (!IS_IFX (tree->left))
3436 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3438 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3439 /* right is a IFX then just join */
3440 if (IS_IFX (tree->right))
3441 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3443 tree->right = createLabel (localLabel, tree->right);
3444 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3446 return newNode (NULLOP, tree->left, tree->right);
3449 /* if this is an or operation */
3452 static int localLbl = 0;
3455 sprintf (buffer, "_or_%d", localLbl++);
3456 localLabel = newSymbol (buffer, NestLevel);
3458 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3460 /* if left is already a IFX then just change the if true label in that */
3461 if (!IS_IFX (tree->left))
3462 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3464 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3465 /* right is a IFX then just join */
3466 if (IS_IFX (tree->right))
3467 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3469 tree->right = createLabel (localLabel, tree->right);
3470 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3472 return newNode (NULLOP, tree->left, tree->right);
3478 int wasnot = IS_NOT (tree->left);
3479 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3481 /* if the left is already a IFX */
3482 if (!IS_IFX (tree->left))
3483 tree->left = newNode (IFX, tree->left, NULL);
3487 tree->left->trueLabel = trueLabel;
3488 tree->left->falseLabel = falseLabel;
3492 tree->left->trueLabel = falseLabel;
3493 tree->left->falseLabel = trueLabel;
3500 tree->trueLabel = trueLabel;
3501 tree->falseLabel = falseLabel;
3508 /*-----------------------------------------------------------------*/
3509 /* createBlock - create expression tree for block */
3510 /*-----------------------------------------------------------------*/
3512 createBlock (symbol * decl, ast * body)
3516 /* if the block has nothing */
3520 ex = newNode (BLOCK, NULL, body);
3521 ex->values.sym = decl;
3523 ex->right = ex->right;
3529 /*-----------------------------------------------------------------*/
3530 /* createLabel - creates the expression tree for labels */
3531 /*-----------------------------------------------------------------*/
3533 createLabel (symbol * label, ast * stmnt)
3536 char name[SDCC_NAME_MAX + 1];
3539 /* must create fresh symbol if the symbol name */
3540 /* exists in the symbol table, since there can */
3541 /* be a variable with the same name as the labl */
3542 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3543 (csym->level == label->level))
3544 label = newSymbol (label->name, label->level);
3546 /* change the name before putting it in add _ */
3547 sprintf (name, "%s", label->name);
3549 /* put the label in the LabelSymbol table */
3550 /* but first check if a label of the same */
3552 if ((csym = findSym (LabelTab, NULL, name)))
3553 werror (E_DUPLICATE_LABEL, label->name);
3555 addSym (LabelTab, label, name, label->level, 0, 0);
3558 label->key = labelKey++;
3559 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3565 /*-----------------------------------------------------------------*/
3566 /* createCase - generates the parsetree for a case statement */
3567 /*-----------------------------------------------------------------*/
3569 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3571 char caseLbl[SDCC_NAME_MAX + 1];
3575 /* if the switch statement does not exist */
3576 /* then case is out of context */
3579 werror (E_CASE_CONTEXT);
3583 caseVal = decorateType (resolveSymbols (caseVal));
3584 /* if not a constant then error */
3585 if (!IS_LITERAL (caseVal->ftype))
3587 werror (E_CASE_CONSTANT);
3591 /* if not a integer than error */
3592 if (!IS_INTEGRAL (caseVal->ftype))
3594 werror (E_CASE_NON_INTEGER);
3598 /* find the end of the switch values chain */
3599 if (!(val = swStat->values.switchVals.swVals))
3600 swStat->values.switchVals.swVals = caseVal->opval.val;
3603 /* also order the cases according to value */
3605 int cVal = (int) floatFromVal (caseVal->opval.val);
3606 while (val && (int) floatFromVal (val) < cVal)
3612 /* if we reached the end then */
3615 pval->next = caseVal->opval.val;
3619 /* we found a value greater than */
3620 /* the current value we must add this */
3621 /* before the value */
3622 caseVal->opval.val->next = val;
3624 /* if this was the first in chain */
3625 if (swStat->values.switchVals.swVals == val)
3626 swStat->values.switchVals.swVals =
3629 pval->next = caseVal->opval.val;
3634 /* create the case label */
3635 sprintf (caseLbl, "_case_%d_%d",
3636 swStat->values.switchVals.swNum,
3637 (int) floatFromVal (caseVal->opval.val));
3639 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3644 /*-----------------------------------------------------------------*/
3645 /* createDefault - creates the parse tree for the default statement */
3646 /*-----------------------------------------------------------------*/
3648 createDefault (ast * swStat, ast * stmnt)
3650 char defLbl[SDCC_NAME_MAX + 1];
3652 /* if the switch statement does not exist */
3653 /* then case is out of context */
3656 werror (E_CASE_CONTEXT);
3660 /* turn on the default flag */
3661 swStat->values.switchVals.swDefault = 1;
3663 /* create the label */
3664 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3665 return createLabel (newSymbol (defLbl, 0), stmnt);
3668 /*-----------------------------------------------------------------*/
3669 /* createIf - creates the parsetree for the if statement */
3670 /*-----------------------------------------------------------------*/
3672 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3674 static int Lblnum = 0;
3676 symbol *ifTrue, *ifFalse, *ifEnd;
3678 /* if neither exists */
3679 if (!elseBody && !ifBody) {
3680 // if there are no side effects (i++, j() etc)
3681 if (!hasSEFcalls(condAst)) {
3686 /* create the labels */
3687 sprintf (buffer, "_iffalse_%d", Lblnum);
3688 ifFalse = newSymbol (buffer, NestLevel);
3689 /* if no else body then end == false */
3694 sprintf (buffer, "_ifend_%d", Lblnum);
3695 ifEnd = newSymbol (buffer, NestLevel);
3698 sprintf (buffer, "_iftrue_%d", Lblnum);
3699 ifTrue = newSymbol (buffer, NestLevel);
3703 /* attach the ifTrue label to the top of it body */
3704 ifBody = createLabel (ifTrue, ifBody);
3705 /* attach a goto end to the ifBody if else is present */
3708 ifBody = newNode (NULLOP, ifBody,
3710 newAst_VALUE (symbolVal (ifEnd)),
3712 /* put the elseLabel on the else body */
3713 elseBody = createLabel (ifFalse, elseBody);
3714 /* out the end at the end of the body */
3715 elseBody = newNode (NULLOP,
3717 createLabel (ifEnd, NULL));
3721 ifBody = newNode (NULLOP, ifBody,
3722 createLabel (ifFalse, NULL));
3724 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3725 if (IS_IFX (condAst))
3728 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3730 return newNode (NULLOP, ifTree,
3731 newNode (NULLOP, ifBody, elseBody));
3735 /*-----------------------------------------------------------------*/
3736 /* createDo - creates parse tree for do */
3739 /* _docontinue_n: */
3740 /* condition_expression +-> trueLabel -> _dobody_n */
3742 /* +-> falseLabel-> _dobreak_n */
3744 /*-----------------------------------------------------------------*/
3746 createDo (symbol * trueLabel, symbol * continueLabel,
3747 symbol * falseLabel, ast * condAst, ast * doBody)
3752 /* if the body does not exist then it is simple */
3755 condAst = backPatchLabels (condAst, continueLabel, NULL);
3756 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3757 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3758 doTree->trueLabel = continueLabel;
3759 doTree->falseLabel = NULL;
3763 /* otherwise we have a body */
3764 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3766 /* attach the body label to the top */
3767 doBody = createLabel (trueLabel, doBody);
3768 /* attach the continue label to end of body */
3769 doBody = newNode (NULLOP, doBody,
3770 createLabel (continueLabel, NULL));
3772 /* now put the break label at the end */
3773 if (IS_IFX (condAst))
3776 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3778 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3780 /* putting it together */
3781 return newNode (NULLOP, doBody, doTree);
3784 /*-----------------------------------------------------------------*/
3785 /* createFor - creates parse tree for 'for' statement */
3788 /* condExpr +-> trueLabel -> _forbody_n */
3790 /* +-> falseLabel-> _forbreak_n */
3793 /* _forcontinue_n: */
3795 /* goto _forcond_n ; */
3797 /*-----------------------------------------------------------------*/
3799 createFor (symbol * trueLabel, symbol * continueLabel,
3800 symbol * falseLabel, symbol * condLabel,
3801 ast * initExpr, ast * condExpr, ast * loopExpr,
3806 /* if loopexpression not present then we can generate it */
3807 /* the same way as a while */
3809 return newNode (NULLOP, initExpr,
3810 createWhile (trueLabel, continueLabel,
3811 falseLabel, condExpr, forBody));
3812 /* vanilla for statement */
3813 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3815 if (condExpr && !IS_IFX (condExpr))
3816 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3819 /* attach condition label to condition */
3820 condExpr = createLabel (condLabel, condExpr);
3822 /* attach body label to body */
3823 forBody = createLabel (trueLabel, forBody);
3825 /* attach continue to forLoop expression & attach */
3826 /* goto the forcond @ and of loopExpression */
3827 loopExpr = createLabel (continueLabel,
3831 newAst_VALUE (symbolVal (condLabel)),
3833 /* now start putting them together */
3834 forTree = newNode (NULLOP, initExpr, condExpr);
3835 forTree = newNode (NULLOP, forTree, forBody);
3836 forTree = newNode (NULLOP, forTree, loopExpr);
3837 /* finally add the break label */
3838 forTree = newNode (NULLOP, forTree,
3839 createLabel (falseLabel, NULL));
3843 /*-----------------------------------------------------------------*/
3844 /* createWhile - creates parse tree for while statement */
3845 /* the while statement will be created as follows */
3847 /* _while_continue_n: */
3848 /* condition_expression +-> trueLabel -> _while_boby_n */
3850 /* +-> falseLabel -> _while_break_n */
3851 /* _while_body_n: */
3853 /* goto _while_continue_n */
3854 /* _while_break_n: */
3855 /*-----------------------------------------------------------------*/
3857 createWhile (symbol * trueLabel, symbol * continueLabel,
3858 symbol * falseLabel, ast * condExpr, ast * whileBody)
3862 /* put the continue label */
3863 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3864 condExpr = createLabel (continueLabel, condExpr);
3865 condExpr->lineno = 0;
3867 /* put the body label in front of the body */
3868 whileBody = createLabel (trueLabel, whileBody);
3869 whileBody->lineno = 0;
3870 /* put a jump to continue at the end of the body */
3871 /* and put break label at the end of the body */
3872 whileBody = newNode (NULLOP,
3875 newAst_VALUE (symbolVal (continueLabel)),
3876 createLabel (falseLabel, NULL)));
3878 /* put it all together */
3879 if (IS_IFX (condExpr))
3880 whileTree = condExpr;
3883 whileTree = newNode (IFX, condExpr, NULL);
3884 /* put the true & false labels in place */
3885 whileTree->trueLabel = trueLabel;
3886 whileTree->falseLabel = falseLabel;
3889 return newNode (NULLOP, whileTree, whileBody);
3892 /*-----------------------------------------------------------------*/
3893 /* optimizeGetHbit - get highest order bit of the expression */
3894 /*-----------------------------------------------------------------*/
3896 optimizeGetHbit (ast * tree)
3899 /* if this is not a bit and */
3900 if (!IS_BITAND (tree))
3903 /* will look for tree of the form
3904 ( expr >> ((sizeof expr) -1) ) & 1 */
3905 if (!IS_AST_LIT_VALUE (tree->right))
3908 if (AST_LIT_VALUE (tree->right) != 1)
3911 if (!IS_RIGHT_OP (tree->left))
3914 if (!IS_AST_LIT_VALUE (tree->left->right))
3917 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3918 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3921 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3925 /*-----------------------------------------------------------------*/
3926 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3927 /*-----------------------------------------------------------------*/
3929 optimizeRRCRLC (ast * root)
3931 /* will look for trees of the form
3932 (?expr << 1) | (?expr >> 7) or
3933 (?expr >> 7) | (?expr << 1) will make that
3934 into a RLC : operation ..
3936 (?expr >> 1) | (?expr << 7) or
3937 (?expr << 7) | (?expr >> 1) will make that
3938 into a RRC operation
3939 note : by 7 I mean (number of bits required to hold the
3941 /* if the root operations is not a | operation the not */
3942 if (!IS_BITOR (root))
3945 /* I have to think of a better way to match patterns this sucks */
3946 /* that aside let start looking for the first case : I use a the
3947 negative check a lot to improve the efficiency */
3948 /* (?expr << 1) | (?expr >> 7) */
3949 if (IS_LEFT_OP (root->left) &&
3950 IS_RIGHT_OP (root->right))
3953 if (!SPEC_USIGN (TETYPE (root->left->left)))
3956 if (!IS_AST_LIT_VALUE (root->left->right) ||
3957 !IS_AST_LIT_VALUE (root->right->right))
3960 /* make sure it is the same expression */
3961 if (!isAstEqual (root->left->left,
3965 if (AST_LIT_VALUE (root->left->right) != 1)
3968 if (AST_LIT_VALUE (root->right->right) !=
3969 (getSize (TTYPE (root->left->left)) * 8 - 1))
3972 /* whew got the first case : create the AST */
3973 return newNode (RLC, root->left->left, NULL);
3977 /* check for second case */
3978 /* (?expr >> 7) | (?expr << 1) */
3979 if (IS_LEFT_OP (root->right) &&
3980 IS_RIGHT_OP (root->left))
3983 if (!SPEC_USIGN (TETYPE (root->left->left)))
3986 if (!IS_AST_LIT_VALUE (root->left->right) ||
3987 !IS_AST_LIT_VALUE (root->right->right))
3990 /* make sure it is the same symbol */
3991 if (!isAstEqual (root->left->left,
3995 if (AST_LIT_VALUE (root->right->right) != 1)
3998 if (AST_LIT_VALUE (root->left->right) !=
3999 (getSize (TTYPE (root->left->left)) * 8 - 1))
4002 /* whew got the first case : create the AST */
4003 return newNode (RLC, root->left->left, NULL);
4008 /* third case for RRC */
4009 /* (?symbol >> 1) | (?symbol << 7) */
4010 if (IS_LEFT_OP (root->right) &&
4011 IS_RIGHT_OP (root->left))
4014 if (!SPEC_USIGN (TETYPE (root->left->left)))
4017 if (!IS_AST_LIT_VALUE (root->left->right) ||
4018 !IS_AST_LIT_VALUE (root->right->right))
4021 /* make sure it is the same symbol */
4022 if (!isAstEqual (root->left->left,
4026 if (AST_LIT_VALUE (root->left->right) != 1)
4029 if (AST_LIT_VALUE (root->right->right) !=
4030 (getSize (TTYPE (root->left->left)) * 8 - 1))
4033 /* whew got the first case : create the AST */
4034 return newNode (RRC, root->left->left, NULL);
4038 /* fourth and last case for now */
4039 /* (?symbol << 7) | (?symbol >> 1) */
4040 if (IS_RIGHT_OP (root->right) &&
4041 IS_LEFT_OP (root->left))
4044 if (!SPEC_USIGN (TETYPE (root->left->left)))
4047 if (!IS_AST_LIT_VALUE (root->left->right) ||
4048 !IS_AST_LIT_VALUE (root->right->right))
4051 /* make sure it is the same symbol */
4052 if (!isAstEqual (root->left->left,
4056 if (AST_LIT_VALUE (root->right->right) != 1)
4059 if (AST_LIT_VALUE (root->left->right) !=
4060 (getSize (TTYPE (root->left->left)) * 8 - 1))
4063 /* whew got the first case : create the AST */
4064 return newNode (RRC, root->left->left, NULL);
4068 /* not found return root */
4072 /*-----------------------------------------------------------------*/
4073 /* optimizeCompare - otimizes compares for bit variables */
4074 /*-----------------------------------------------------------------*/
4076 optimizeCompare (ast * root)
4078 ast *optExpr = NULL;
4081 unsigned int litValue;
4083 /* if nothing then return nothing */
4087 /* if not a compare op then do leaves */
4088 if (!IS_COMPARE_OP (root))
4090 root->left = optimizeCompare (root->left);
4091 root->right = optimizeCompare (root->right);
4095 /* if left & right are the same then depending
4096 of the operation do */
4097 if (isAstEqual (root->left, root->right))
4099 switch (root->opval.op)
4104 optExpr = newAst_VALUE (constVal ("0"));
4109 optExpr = newAst_VALUE (constVal ("1"));
4113 return decorateType (optExpr);
4116 vleft = (root->left->type == EX_VALUE ?
4117 root->left->opval.val : NULL);
4119 vright = (root->right->type == EX_VALUE ?
4120 root->right->opval.val : NULL);
4122 /* if left is a BITVAR in BITSPACE */
4123 /* and right is a LITERAL then opt- */
4124 /* imize else do nothing */
4125 if (vleft && vright &&
4126 IS_BITVAR (vleft->etype) &&
4127 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4128 IS_LITERAL (vright->etype))
4131 /* if right side > 1 then comparison may never succeed */
4132 if ((litValue = (int) floatFromVal (vright)) > 1)
4134 werror (W_BAD_COMPARE);
4140 switch (root->opval.op)
4142 case '>': /* bit value greater than 1 cannot be */
4143 werror (W_BAD_COMPARE);
4147 case '<': /* bit value < 1 means 0 */
4149 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4152 case LE_OP: /* bit value <= 1 means no check */
4153 optExpr = newAst_VALUE (vright);
4156 case GE_OP: /* bit value >= 1 means only check for = */
4158 optExpr = newAst_VALUE (vleft);
4163 { /* literal is zero */
4164 switch (root->opval.op)
4166 case '<': /* bit value < 0 cannot be */
4167 werror (W_BAD_COMPARE);
4171 case '>': /* bit value > 0 means 1 */
4173 optExpr = newAst_VALUE (vleft);
4176 case LE_OP: /* bit value <= 0 means no check */
4177 case GE_OP: /* bit value >= 0 means no check */
4178 werror (W_BAD_COMPARE);
4182 case EQ_OP: /* bit == 0 means ! of bit */
4183 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4187 return decorateType (resolveSymbols (optExpr));
4188 } /* end-of-if of BITVAR */
4193 /*-----------------------------------------------------------------*/
4194 /* addSymToBlock : adds the symbol to the first block we find */
4195 /*-----------------------------------------------------------------*/
4197 addSymToBlock (symbol * sym, ast * tree)
4199 /* reached end of tree or a leaf */
4200 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4204 if (IS_AST_OP (tree) &&
4205 tree->opval.op == BLOCK)
4208 symbol *lsym = copySymbol (sym);
4210 lsym->next = AST_VALUES (tree, sym);
4211 AST_VALUES (tree, sym) = lsym;
4215 addSymToBlock (sym, tree->left);
4216 addSymToBlock (sym, tree->right);
4219 /*-----------------------------------------------------------------*/
4220 /* processRegParms - do processing for register parameters */
4221 /*-----------------------------------------------------------------*/
4223 processRegParms (value * args, ast * body)
4227 if (IS_REGPARM (args->etype))
4228 addSymToBlock (args->sym, body);
4233 /*-----------------------------------------------------------------*/
4234 /* resetParmKey - resets the operandkeys for the symbols */
4235 /*-----------------------------------------------------------------*/
4236 DEFSETFUNC (resetParmKey)
4247 /*-----------------------------------------------------------------*/
4248 /* createFunction - This is the key node that calls the iCode for */
4249 /* generating the code for a function. Note code */
4250 /* is generated function by function, later when */
4251 /* add inter-procedural analysis this will change */
4252 /*-----------------------------------------------------------------*/
4254 createFunction (symbol * name, ast * body)
4260 iCode *piCode = NULL;
4262 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4263 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4265 /* if check function return 0 then some problem */
4266 if (checkFunction (name, NULL) == 0)
4269 /* create a dummy block if none exists */
4271 body = newNode (BLOCK, NULL, NULL);
4275 /* check if the function name already in the symbol table */
4276 if ((csym = findSym (SymbolTab, NULL, name->name)))
4279 /* special case for compiler defined functions
4280 we need to add the name to the publics list : this
4281 actually means we are now compiling the compiler
4285 addSet (&publics, name);
4291 allocVariables (name);
4293 name->lastLine = yylineno;
4296 /* set the stack pointer */
4297 /* PENDING: check this for the mcs51 */
4298 stackPtr = -port->stack.direction * port->stack.call_overhead;
4299 if (IFFUNC_ISISR (name->type))
4300 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4301 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4302 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4304 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4306 fetype = getSpec (name->type); /* get the specifier for the function */
4307 /* if this is a reentrant function then */
4308 if (IFFUNC_ISREENT (name->type))
4311 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4313 /* do processing for parameters that are passed in registers */
4314 processRegParms (FUNC_ARGS(name->type), body);
4316 /* set the stack pointer */
4320 /* allocate & autoinit the block variables */
4321 processBlockVars (body, &stack, ALLOCATE);
4323 /* save the stack information */
4324 if (options.useXstack)
4325 name->xstack = SPEC_STAK (fetype) = stack;
4327 name->stack = SPEC_STAK (fetype) = stack;
4329 /* name needs to be mangled */
4330 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4332 body = resolveSymbols (body); /* resolve the symbols */
4333 body = decorateType (body); /* propagateType & do semantic checks */
4335 ex = newAst_VALUE (symbolVal (name)); /* create name */
4336 ex = newNode (FUNCTION, ex, body);
4337 ex->values.args = FUNC_ARGS(name->type);
4339 if (options.dump_tree) PA(ex);
4342 werror (E_FUNC_NO_CODE, name->name);
4346 /* create the node & generate intermediate code */
4348 codeOutFile = code->oFile;
4349 piCode = iCodeFromAst (ex);
4353 werror (E_FUNC_NO_CODE, name->name);
4357 eBBlockFromiCode (piCode);
4359 /* if there are any statics then do them */
4362 GcurMemmap = statsg;
4363 codeOutFile = statsg->oFile;
4364 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4370 /* dealloc the block variables */
4371 processBlockVars (body, &stack, DEALLOCATE);
4372 /* deallocate paramaters */
4373 deallocParms (FUNC_ARGS(name->type));
4375 if (IFFUNC_ISREENT (name->type))
4378 /* we are done freeup memory & cleanup */
4380 if (port->reset_labelKey) labelKey = 1;
4382 FUNC_HASBODY(name->type) = 1;
4383 addSet (&operKeyReset, name);
4384 applyToSet (operKeyReset, resetParmKey);
4387 cdbStructBlock (1, cdbFile);
4389 cleanUpLevel (LabelTab, 0);
4390 cleanUpBlock (StructTab, 1);
4391 cleanUpBlock (TypedefTab, 1);
4393 xstack->syms = NULL;
4394 istack->syms = NULL;
4399 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4400 /*-----------------------------------------------------------------*/
4401 /* ast_print : prints the ast (for debugging purposes) */
4402 /*-----------------------------------------------------------------*/
4404 void ast_print (ast * tree, FILE *outfile, int indent)
4409 /* can print only decorated trees */
4410 if (!tree->decorated) return;
4412 /* if any child is an error | this one is an error do nothing */
4413 if (tree->isError ||
4414 (tree->left && tree->left->isError) ||
4415 (tree->right && tree->right->isError)) {
4416 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4420 /* print the line */
4421 /* if not block & function */
4422 if (tree->type == EX_OP &&
4423 (tree->opval.op != FUNCTION &&
4424 tree->opval.op != BLOCK &&
4425 tree->opval.op != NULLOP)) {
4428 if (tree->opval.op == FUNCTION) {
4430 value *args=FUNC_ARGS(tree->left->opval.val->type);
4431 fprintf(outfile,"FUNCTION (%s=%p) type (",
4432 tree->left->opval.val->name, tree);
4433 printTypeChain (tree->ftype,outfile);
4434 fprintf(outfile,") args (");
4437 fprintf (outfile, ", ");
4439 printTypeChain (args ? args->type : NULL, outfile);
4441 args= args ? args->next : NULL;
4443 fprintf(outfile,")\n");
4444 ast_print(tree->left,outfile,indent);
4445 ast_print(tree->right,outfile,indent);
4448 if (tree->opval.op == BLOCK) {
4449 symbol *decls = tree->values.sym;
4450 INDENT(indent,outfile);
4451 fprintf(outfile,"{\n");
4453 INDENT(indent+2,outfile);
4454 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4455 decls->name, decls);
4456 printTypeChain(decls->type,outfile);
4457 fprintf(outfile,")\n");
4459 decls = decls->next;
4461 ast_print(tree->right,outfile,indent+2);
4462 INDENT(indent,outfile);
4463 fprintf(outfile,"}\n");
4466 if (tree->opval.op == NULLOP) {
4467 fprintf(outfile,"\n");
4468 ast_print(tree->left,outfile,indent);
4469 fprintf(outfile,"\n");
4470 ast_print(tree->right,outfile,indent);
4473 INDENT(indent,outfile);
4475 /*------------------------------------------------------------------*/
4476 /*----------------------------*/
4477 /* leaf has been reached */
4478 /*----------------------------*/
4479 /* if this is of type value */
4480 /* just get the type */
4481 if (tree->type == EX_VALUE) {
4483 if (IS_LITERAL (tree->opval.val->etype)) {
4484 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4485 (int) floatFromVal(tree->opval.val),
4486 (int) floatFromVal(tree->opval.val),
4487 floatFromVal(tree->opval.val));
4488 } else if (tree->opval.val->sym) {
4489 /* if the undefined flag is set then give error message */
4490 if (tree->opval.val->sym->undefined) {
4491 fprintf(outfile,"UNDEFINED SYMBOL ");
4493 fprintf(outfile,"SYMBOL ");
4495 fprintf(outfile,"(%s=%p)",
4496 tree->opval.val->sym->name,tree);
4499 fprintf(outfile," type (");
4500 printTypeChain(tree->ftype,outfile);
4501 fprintf(outfile,")\n");
4503 fprintf(outfile,"\n");
4508 /* if type link for the case of cast */
4509 if (tree->type == EX_LINK) {
4510 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4511 printTypeChain(tree->opval.lnk,outfile);
4512 fprintf(outfile,")\n");
4517 /* depending on type of operator do */
4519 switch (tree->opval.op) {
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4523 /*----------------------------*/
4525 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+2);
4529 ast_print(tree->right,outfile,indent+2);
4532 /*------------------------------------------------------------------*/
4533 /*----------------------------*/
4535 /*----------------------------*/
4537 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4538 printTypeChain(tree->ftype,outfile);
4539 fprintf(outfile,")\n");
4540 ast_print(tree->left,outfile,indent+2);
4541 ast_print(tree->right,outfile,indent+2);
4544 /*------------------------------------------------------------------*/
4545 /*----------------------------*/
4546 /* struct/union pointer */
4547 /*----------------------------*/
4549 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4550 printTypeChain(tree->ftype,outfile);
4551 fprintf(outfile,")\n");
4552 ast_print(tree->left,outfile,indent+2);
4553 ast_print(tree->right,outfile,indent+2);
4556 /*------------------------------------------------------------------*/
4557 /*----------------------------*/
4558 /* ++/-- operation */
4559 /*----------------------------*/
4560 case INC_OP: /* incerement operator unary so left only */
4561 fprintf(outfile,"INC_OP (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+2);
4568 fprintf(outfile,"DEC_OP (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+2);
4574 /*------------------------------------------------------------------*/
4575 /*----------------------------*/
4577 /*----------------------------*/
4580 fprintf(outfile,"& (%p) type (",tree);
4581 printTypeChain(tree->ftype,outfile);
4582 fprintf(outfile,")\n");
4583 ast_print(tree->left,outfile,indent+2);
4584 ast_print(tree->right,outfile,indent+2);
4586 fprintf(outfile,"ADDRESS_OF (%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);
4593 /*----------------------------*/
4595 /*----------------------------*/
4597 fprintf(outfile,"OR (%p) type (",tree);
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->left,outfile,indent+2);
4601 ast_print(tree->right,outfile,indent+2);
4603 /*------------------------------------------------------------------*/
4604 /*----------------------------*/
4606 /*----------------------------*/
4608 fprintf(outfile,"XOR (%p) type (",tree);
4609 printTypeChain(tree->ftype,outfile);
4610 fprintf(outfile,")\n");
4611 ast_print(tree->left,outfile,indent+2);
4612 ast_print(tree->right,outfile,indent+2);
4615 /*------------------------------------------------------------------*/
4616 /*----------------------------*/
4618 /*----------------------------*/
4620 fprintf(outfile,"DIV (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+2);
4624 ast_print(tree->right,outfile,indent+2);
4626 /*------------------------------------------------------------------*/
4627 /*----------------------------*/
4629 /*----------------------------*/
4631 fprintf(outfile,"MOD (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+2);
4635 ast_print(tree->right,outfile,indent+2);
4638 /*------------------------------------------------------------------*/
4639 /*----------------------------*/
4640 /* address dereference */
4641 /*----------------------------*/
4642 case '*': /* can be unary : if right is null then unary operation */
4644 fprintf(outfile,"DEREF (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+2);
4650 /*------------------------------------------------------------------*/
4651 /*----------------------------*/
4652 /* multiplication */
4653 /*----------------------------*/
4654 fprintf(outfile,"MULT (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+2);
4658 ast_print(tree->right,outfile,indent+2);
4662 /*------------------------------------------------------------------*/
4663 /*----------------------------*/
4664 /* unary '+' operator */
4665 /*----------------------------*/
4669 fprintf(outfile,"UPLUS (%p) type (",tree);
4670 printTypeChain(tree->ftype,outfile);
4671 fprintf(outfile,")\n");
4672 ast_print(tree->left,outfile,indent+2);
4674 /*------------------------------------------------------------------*/
4675 /*----------------------------*/
4677 /*----------------------------*/
4678 fprintf(outfile,"ADD (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+2);
4682 ast_print(tree->right,outfile,indent+2);
4685 /*------------------------------------------------------------------*/
4686 /*----------------------------*/
4688 /*----------------------------*/
4689 case '-': /* can be unary */
4691 fprintf(outfile,"UMINUS (%p) type (",tree);
4692 printTypeChain(tree->ftype,outfile);
4693 fprintf(outfile,")\n");
4694 ast_print(tree->left,outfile,indent+2);
4696 /*------------------------------------------------------------------*/
4697 /*----------------------------*/
4699 /*----------------------------*/
4700 fprintf(outfile,"SUB (%p) type (",tree);
4701 printTypeChain(tree->ftype,outfile);
4702 fprintf(outfile,")\n");
4703 ast_print(tree->left,outfile,indent+2);
4704 ast_print(tree->right,outfile,indent+2);
4707 /*------------------------------------------------------------------*/
4708 /*----------------------------*/
4710 /*----------------------------*/
4712 fprintf(outfile,"COMPL (%p) type (",tree);
4713 printTypeChain(tree->ftype,outfile);
4714 fprintf(outfile,")\n");
4715 ast_print(tree->left,outfile,indent+2);
4717 /*------------------------------------------------------------------*/
4718 /*----------------------------*/
4720 /*----------------------------*/
4722 fprintf(outfile,"NOT (%p) type (",tree);
4723 printTypeChain(tree->ftype,outfile);
4724 fprintf(outfile,")\n");
4725 ast_print(tree->left,outfile,indent+2);
4727 /*------------------------------------------------------------------*/
4728 /*----------------------------*/
4730 /*----------------------------*/
4732 fprintf(outfile,"RRC (%p) type (",tree);
4733 printTypeChain(tree->ftype,outfile);
4734 fprintf(outfile,")\n");
4735 ast_print(tree->left,outfile,indent+2);
4739 fprintf(outfile,"RLC (%p) type (",tree);
4740 printTypeChain(tree->ftype,outfile);
4741 fprintf(outfile,")\n");
4742 ast_print(tree->left,outfile,indent+2);
4745 fprintf(outfile,"GETHBIT (%p) type (",tree);
4746 printTypeChain(tree->ftype,outfile);
4747 fprintf(outfile,")\n");
4748 ast_print(tree->left,outfile,indent+2);
4751 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+2);
4755 ast_print(tree->right,outfile,indent+2);
4758 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4759 printTypeChain(tree->ftype,outfile);
4760 fprintf(outfile,")\n");
4761 ast_print(tree->left,outfile,indent+2);
4762 ast_print(tree->right,outfile,indent+2);
4764 /*------------------------------------------------------------------*/
4765 /*----------------------------*/
4767 /*----------------------------*/
4768 case CAST: /* change the type */
4769 fprintf(outfile,"CAST (%p) from type (",tree);
4770 printTypeChain(tree->right->ftype,outfile);
4771 fprintf(outfile,") to type (");
4772 printTypeChain(tree->ftype,outfile);
4773 fprintf(outfile,")\n");
4774 ast_print(tree->right,outfile,indent+2);
4778 fprintf(outfile,"ANDAND (%p) type (",tree);
4779 printTypeChain(tree->ftype,outfile);
4780 fprintf(outfile,")\n");
4781 ast_print(tree->left,outfile,indent+2);
4782 ast_print(tree->right,outfile,indent+2);
4785 fprintf(outfile,"OROR (%p) type (",tree);
4786 printTypeChain(tree->ftype,outfile);
4787 fprintf(outfile,")\n");
4788 ast_print(tree->left,outfile,indent+2);
4789 ast_print(tree->right,outfile,indent+2);
4792 /*------------------------------------------------------------------*/
4793 /*----------------------------*/
4794 /* comparison operators */
4795 /*----------------------------*/
4797 fprintf(outfile,"GT(>) (%p) type (",tree);
4798 printTypeChain(tree->ftype,outfile);
4799 fprintf(outfile,")\n");
4800 ast_print(tree->left,outfile,indent+2);
4801 ast_print(tree->right,outfile,indent+2);
4804 fprintf(outfile,"LT(<) (%p) type (",tree);
4805 printTypeChain(tree->ftype,outfile);
4806 fprintf(outfile,")\n");
4807 ast_print(tree->left,outfile,indent+2);
4808 ast_print(tree->right,outfile,indent+2);
4811 fprintf(outfile,"LE(<=) (%p) type (",tree);
4812 printTypeChain(tree->ftype,outfile);
4813 fprintf(outfile,")\n");
4814 ast_print(tree->left,outfile,indent+2);
4815 ast_print(tree->right,outfile,indent+2);
4818 fprintf(outfile,"GE(>=) (%p) type (",tree);
4819 printTypeChain(tree->ftype,outfile);
4820 fprintf(outfile,")\n");
4821 ast_print(tree->left,outfile,indent+2);
4822 ast_print(tree->right,outfile,indent+2);
4825 fprintf(outfile,"EQ(==) (%p) type (",tree);
4826 printTypeChain(tree->ftype,outfile);
4827 fprintf(outfile,")\n");
4828 ast_print(tree->left,outfile,indent+2);
4829 ast_print(tree->right,outfile,indent+2);
4832 fprintf(outfile,"NE(!=) (%p) type (",tree);
4833 printTypeChain(tree->ftype,outfile);
4834 fprintf(outfile,")\n");
4835 ast_print(tree->left,outfile,indent+2);
4836 ast_print(tree->right,outfile,indent+2);
4837 /*------------------------------------------------------------------*/
4838 /*----------------------------*/
4840 /*----------------------------*/
4841 case SIZEOF: /* evaluate wihout code generation */
4842 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4845 /*------------------------------------------------------------------*/
4846 /*----------------------------*/
4847 /* conditional operator '?' */
4848 /*----------------------------*/
4850 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4851 printTypeChain(tree->ftype,outfile);
4852 fprintf(outfile,")\n");
4853 ast_print(tree->left,outfile,indent+2);
4854 ast_print(tree->right,outfile,indent+2);
4858 fprintf(outfile,"COLON(:) (%p) type (",tree);
4859 printTypeChain(tree->ftype,outfile);
4860 fprintf(outfile,")\n");
4861 ast_print(tree->left,outfile,indent+2);
4862 ast_print(tree->right,outfile,indent+2);
4865 /*------------------------------------------------------------------*/
4866 /*----------------------------*/
4867 /* assignment operators */
4868 /*----------------------------*/
4870 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4871 printTypeChain(tree->ftype,outfile);
4872 fprintf(outfile,")\n");
4873 ast_print(tree->left,outfile,indent+2);
4874 ast_print(tree->right,outfile,indent+2);
4877 fprintf(outfile,"DIVASS(/=) (%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);
4884 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4885 printTypeChain(tree->ftype,outfile);
4886 fprintf(outfile,")\n");
4887 ast_print(tree->left,outfile,indent+2);
4888 ast_print(tree->right,outfile,indent+2);
4891 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4892 printTypeChain(tree->ftype,outfile);
4893 fprintf(outfile,")\n");
4894 ast_print(tree->left,outfile,indent+2);
4895 ast_print(tree->right,outfile,indent+2);
4898 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4899 printTypeChain(tree->ftype,outfile);
4900 fprintf(outfile,")\n");
4901 ast_print(tree->left,outfile,indent+2);
4902 ast_print(tree->right,outfile,indent+2);
4905 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4906 printTypeChain(tree->ftype,outfile);
4907 fprintf(outfile,")\n");
4908 ast_print(tree->left,outfile,indent+2);
4909 ast_print(tree->right,outfile,indent+2);
4912 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4913 printTypeChain(tree->ftype,outfile);
4914 fprintf(outfile,")\n");
4915 ast_print(tree->left,outfile,indent+2);
4916 ast_print(tree->right,outfile,indent+2);
4918 /*------------------------------------------------------------------*/
4919 /*----------------------------*/
4921 /*----------------------------*/
4923 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4924 printTypeChain(tree->ftype,outfile);
4925 fprintf(outfile,")\n");
4926 ast_print(tree->left,outfile,indent+2);
4927 ast_print(tree->right,outfile,indent+2);
4929 /*------------------------------------------------------------------*/
4930 /*----------------------------*/
4932 /*----------------------------*/
4934 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4935 printTypeChain(tree->ftype,outfile);
4936 fprintf(outfile,")\n");
4937 ast_print(tree->left,outfile,indent+2);
4938 ast_print(tree->right,outfile,indent+2);
4940 /*------------------------------------------------------------------*/
4941 /*----------------------------*/
4942 /* straight assignemnt */
4943 /*----------------------------*/
4945 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4946 printTypeChain(tree->ftype,outfile);
4947 fprintf(outfile,")\n");
4948 ast_print(tree->left,outfile,indent+2);
4949 ast_print(tree->right,outfile,indent+2);
4951 /*------------------------------------------------------------------*/
4952 /*----------------------------*/
4953 /* comma operator */
4954 /*----------------------------*/
4956 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4957 printTypeChain(tree->ftype,outfile);
4958 fprintf(outfile,")\n");
4959 ast_print(tree->left,outfile,indent+2);
4960 ast_print(tree->right,outfile,indent+2);
4962 /*------------------------------------------------------------------*/
4963 /*----------------------------*/
4965 /*----------------------------*/
4968 fprintf(outfile,"CALL (%p) type (",tree);
4969 printTypeChain(tree->ftype,outfile);
4970 fprintf(outfile,")\n");
4971 ast_print(tree->left,outfile,indent+2);
4972 ast_print(tree->right,outfile,indent+2);
4975 fprintf(outfile,"PARMS\n");
4976 ast_print(tree->left,outfile,indent+2);
4977 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4978 ast_print(tree->right,outfile,indent+2);
4981 /*------------------------------------------------------------------*/
4982 /*----------------------------*/
4983 /* return statement */
4984 /*----------------------------*/
4986 fprintf(outfile,"RETURN (%p) type (",tree);
4988 printTypeChain(tree->right->ftype,outfile);
4990 fprintf(outfile,")\n");
4991 ast_print(tree->right,outfile,indent+2);
4993 /*------------------------------------------------------------------*/
4994 /*----------------------------*/
4995 /* label statement */
4996 /*----------------------------*/
4998 fprintf(outfile,"LABEL (%p)\n",tree);
4999 ast_print(tree->left,outfile,indent+2);
5000 ast_print(tree->right,outfile,indent);
5002 /*------------------------------------------------------------------*/
5003 /*----------------------------*/
5004 /* switch statement */
5005 /*----------------------------*/
5009 fprintf(outfile,"SWITCH (%p) ",tree);
5010 ast_print(tree->left,outfile,0);
5011 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5012 INDENT(indent+2,outfile);
5013 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5014 (int) floatFromVal(val),
5015 tree->values.switchVals.swNum,
5016 (int) floatFromVal(val));
5018 ast_print(tree->right,outfile,indent);
5021 /*------------------------------------------------------------------*/
5022 /*----------------------------*/
5024 /*----------------------------*/
5026 fprintf(outfile,"IF (%p) \n",tree);
5027 ast_print(tree->left,outfile,indent+2);
5028 if (tree->trueLabel) {
5029 INDENT(indent,outfile);
5030 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5032 if (tree->falseLabel) {
5033 INDENT(indent,outfile);
5034 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5036 ast_print(tree->right,outfile,indent+2);
5038 /*------------------------------------------------------------------*/
5039 /*----------------------------*/
5041 /*----------------------------*/
5043 fprintf(outfile,"FOR (%p) \n",tree);
5044 if (AST_FOR( tree, initExpr)) {
5045 INDENT(indent+2,outfile);
5046 fprintf(outfile,"INIT EXPR ");
5047 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5049 if (AST_FOR( tree, condExpr)) {
5050 INDENT(indent+2,outfile);
5051 fprintf(outfile,"COND EXPR ");
5052 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5054 if (AST_FOR( tree, loopExpr)) {
5055 INDENT(indent+2,outfile);
5056 fprintf(outfile,"LOOP EXPR ");
5057 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5059 fprintf(outfile,"FOR LOOP BODY \n");
5060 ast_print(tree->left,outfile,indent+2);
5069 ast_print(t,stdout,0);