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);
975 return decorateType (resolveSymbols (rast));
981 /*-----------------------------------------------------------------*/
982 /* createIvalPtr - generates initial value for pointers */
983 /*-----------------------------------------------------------------*/
985 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
991 if (ilist->type == INIT_DEEP)
992 ilist = ilist->init.deep;
994 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
996 /* if character pointer */
997 if (IS_CHAR (type->next))
998 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1001 return newNode ('=', sym, iexpr);
1004 /*-----------------------------------------------------------------*/
1005 /* createIval - generates code for initial value */
1006 /*-----------------------------------------------------------------*/
1008 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1015 /* if structure then */
1016 if (IS_STRUCT (type))
1017 rast = createIvalStruct (sym, type, ilist);
1019 /* if this is a pointer */
1021 rast = createIvalPtr (sym, type, ilist);
1023 /* if this is an array */
1024 if (IS_ARRAY (type))
1025 rast = createIvalArray (sym, type, ilist);
1027 /* if type is SPECIFIER */
1029 rast = createIvalType (sym, type, ilist);
1032 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1034 return decorateType (resolveSymbols (rast));
1037 /*-----------------------------------------------------------------*/
1038 /* initAggregates - initialises aggregate variables with initv */
1039 /*-----------------------------------------------------------------*/
1040 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1041 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1044 /*-----------------------------------------------------------------*/
1045 /* gatherAutoInit - creates assignment expressions for initial */
1047 /*-----------------------------------------------------------------*/
1049 gatherAutoInit (symbol * autoChain)
1056 for (sym = autoChain; sym; sym = sym->next)
1059 /* resolve the symbols in the ival */
1061 resolveIvalSym (sym->ival);
1063 /* if this is a static variable & has an */
1064 /* initial value the code needs to be lifted */
1065 /* here to the main portion since they can be */
1066 /* initialised only once at the start */
1067 if (IS_STATIC (sym->etype) && sym->ival &&
1068 SPEC_SCLS (sym->etype) != S_CODE)
1072 /* insert the symbol into the symbol table */
1073 /* with level = 0 & name = rname */
1074 newSym = copySymbol (sym);
1075 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1077 /* now lift the code to main */
1078 if (IS_AGGREGATE (sym->type)) {
1079 work = initAggregates (sym, sym->ival, NULL);
1081 if (getNelements(sym->type, sym->ival)>1) {
1082 werror (W_EXCESS_INITIALIZERS, "scalar",
1083 sym->name, sym->lineDef);
1085 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1086 list2expr (sym->ival));
1089 setAstLineno (work, sym->lineDef);
1093 staticAutos = newNode (NULLOP, staticAutos, work);
1100 /* if there is an initial value */
1101 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1103 initList *ilist=sym->ival;
1105 while (ilist->type == INIT_DEEP) {
1106 ilist = ilist->init.deep;
1109 /* update lineno for error msg */
1110 lineno=sym->lineDef;
1111 setAstLineno (ilist->init.node, lineno);
1113 if (IS_AGGREGATE (sym->type)) {
1114 work = initAggregates (sym, sym->ival, NULL);
1116 if (getNelements(sym->type, sym->ival)>1) {
1117 werror (W_EXCESS_INITIALIZERS, "scalar",
1118 sym->name, sym->lineDef);
1120 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1121 list2expr (sym->ival));
1125 setAstLineno (work, sym->lineDef);
1129 init = newNode (NULLOP, init, work);
1138 /*-----------------------------------------------------------------*/
1139 /* stringToSymbol - creates a symbol from a literal string */
1140 /*-----------------------------------------------------------------*/
1142 stringToSymbol (value * val)
1144 char name[SDCC_NAME_MAX + 1];
1145 static int charLbl = 0;
1148 sprintf (name, "_str_%d", charLbl++);
1149 sym = newSymbol (name, 0); /* make it @ level 0 */
1150 strcpy (sym->rname, name);
1152 /* copy the type from the value passed */
1153 sym->type = copyLinkChain (val->type);
1154 sym->etype = getSpec (sym->type);
1155 /* change to storage class & output class */
1156 SPEC_SCLS (sym->etype) = S_CODE;
1157 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1158 SPEC_STAT (sym->etype) = 1;
1159 /* make the level & block = 0 */
1160 sym->block = sym->level = 0;
1162 /* create an ival */
1163 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1168 allocVariables (sym);
1171 return symbolVal (sym);
1175 /*-----------------------------------------------------------------*/
1176 /* processBlockVars - will go thru the ast looking for block if */
1177 /* a block is found then will allocate the syms */
1178 /* will also gather the auto inits present */
1179 /*-----------------------------------------------------------------*/
1181 processBlockVars (ast * tree, int *stack, int action)
1186 /* if this is a block */
1187 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1191 if (action == ALLOCATE)
1193 *stack += allocVariables (tree->values.sym);
1194 autoInit = gatherAutoInit (tree->values.sym);
1196 /* if there are auto inits then do them */
1198 tree->left = newNode (NULLOP, autoInit, tree->left);
1200 else /* action is deallocate */
1201 deallocLocal (tree->values.sym);
1204 processBlockVars (tree->left, stack, action);
1205 processBlockVars (tree->right, stack, action);
1209 /*-------------------------------------------------------------*/
1210 /* constExprTree - returns TRUE if this tree is a constant */
1212 /*-------------------------------------------------------------*/
1213 bool constExprTree (ast *cexpr) {
1219 cexpr = decorateType (resolveSymbols (cexpr));
1221 switch (cexpr->type)
1224 if (IS_AST_LIT_VALUE(cexpr)) {
1225 // this is a literal
1228 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1229 // a function's address will never change
1232 if (IS_AST_SYM_VALUE(cexpr) &&
1233 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1234 // a symbol in code space will never change
1235 // This is only for the 'char *s="hallo"' case and will have to leave
1240 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1241 "unexpected link in expression tree\n");
1244 if (cexpr->opval.op==ARRAYINIT) {
1245 // this is a list of literals
1248 if (cexpr->opval.op=='=') {
1249 return constExprTree(cexpr->right);
1251 if (cexpr->opval.op==CAST) {
1252 // jwk: cast ignored, maybe we should throw a warning here
1253 return constExprTree(cexpr->right);
1255 if (cexpr->opval.op=='&') {
1258 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1261 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1268 /*-----------------------------------------------------------------*/
1269 /* constExprValue - returns the value of a constant expression */
1270 /* or NULL if it is not a constant expression */
1271 /*-----------------------------------------------------------------*/
1273 constExprValue (ast * cexpr, int check)
1275 cexpr = decorateType (resolveSymbols (cexpr));
1277 /* if this is not a constant then */
1278 if (!IS_LITERAL (cexpr->ftype))
1280 /* then check if this is a literal array
1282 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1283 SPEC_CVAL (cexpr->etype).v_char &&
1284 IS_ARRAY (cexpr->ftype))
1286 value *val = valFromType (cexpr->ftype);
1287 SPEC_SCLS (val->etype) = S_LITERAL;
1288 val->sym = cexpr->opval.val->sym;
1289 val->sym->type = copyLinkChain (cexpr->ftype);
1290 val->sym->etype = getSpec (val->sym->type);
1291 strcpy (val->name, cexpr->opval.val->sym->rname);
1295 /* if we are casting a literal value then */
1296 if (IS_AST_OP (cexpr) &&
1297 cexpr->opval.op == CAST &&
1298 IS_LITERAL (cexpr->right->ftype))
1299 return valCastLiteral (cexpr->ftype,
1300 floatFromVal (cexpr->right->opval.val));
1302 if (IS_AST_VALUE (cexpr))
1303 return cexpr->opval.val;
1306 werror (E_CONST_EXPECTED, "found expression");
1311 /* return the value */
1312 return cexpr->opval.val;
1316 /*-----------------------------------------------------------------*/
1317 /* isLabelInAst - will return true if a given label is found */
1318 /*-----------------------------------------------------------------*/
1320 isLabelInAst (symbol * label, ast * tree)
1322 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1325 if (IS_AST_OP (tree) &&
1326 tree->opval.op == LABEL &&
1327 isSymbolEqual (AST_SYMBOL (tree->left), label))
1330 return isLabelInAst (label, tree->right) &&
1331 isLabelInAst (label, tree->left);
1335 /*-----------------------------------------------------------------*/
1336 /* isLoopCountable - return true if the loop count can be determi- */
1337 /* -ned at compile time . */
1338 /*-----------------------------------------------------------------*/
1340 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1341 symbol ** sym, ast ** init, ast ** end)
1344 /* the loop is considered countable if the following
1345 conditions are true :-
1347 a) initExpr :- <sym> = <const>
1348 b) condExpr :- <sym> < <const1>
1349 c) loopExpr :- <sym> ++
1352 /* first check the initExpr */
1353 if (IS_AST_OP (initExpr) &&
1354 initExpr->opval.op == '=' && /* is assignment */
1355 IS_AST_SYM_VALUE (initExpr->left))
1356 { /* left is a symbol */
1358 *sym = AST_SYMBOL (initExpr->left);
1359 *init = initExpr->right;
1364 /* for now the symbol has to be of
1366 if (!IS_INTEGRAL ((*sym)->type))
1369 /* now check condExpr */
1370 if (IS_AST_OP (condExpr))
1373 switch (condExpr->opval.op)
1376 if (IS_AST_SYM_VALUE (condExpr->left) &&
1377 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1378 IS_AST_LIT_VALUE (condExpr->right))
1380 *end = condExpr->right;
1386 if (IS_AST_OP (condExpr->left) &&
1387 condExpr->left->opval.op == '>' &&
1388 IS_AST_LIT_VALUE (condExpr->left->right) &&
1389 IS_AST_SYM_VALUE (condExpr->left->left) &&
1390 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1393 *end = newNode ('+', condExpr->left->right,
1394 newAst_VALUE (constVal ("1")));
1405 /* check loop expression is of the form <sym>++ */
1406 if (!IS_AST_OP (loopExpr))
1409 /* check if <sym> ++ */
1410 if (loopExpr->opval.op == INC_OP)
1416 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1417 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1424 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1425 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1433 if (loopExpr->opval.op == ADD_ASSIGN)
1436 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1437 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1438 IS_AST_LIT_VALUE (loopExpr->right) &&
1439 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1447 /*-----------------------------------------------------------------*/
1448 /* astHasVolatile - returns true if ast contains any volatile */
1449 /*-----------------------------------------------------------------*/
1451 astHasVolatile (ast * tree)
1456 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1459 if (IS_AST_OP (tree))
1460 return astHasVolatile (tree->left) ||
1461 astHasVolatile (tree->right);
1466 /*-----------------------------------------------------------------*/
1467 /* astHasPointer - return true if the ast contains any ptr variable */
1468 /*-----------------------------------------------------------------*/
1470 astHasPointer (ast * tree)
1475 if (IS_AST_LINK (tree))
1478 /* if we hit an array expression then check
1479 only the left side */
1480 if (IS_AST_OP (tree) && tree->opval.op == '[')
1481 return astHasPointer (tree->left);
1483 if (IS_AST_VALUE (tree))
1484 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1486 return astHasPointer (tree->left) ||
1487 astHasPointer (tree->right);
1491 /*-----------------------------------------------------------------*/
1492 /* astHasSymbol - return true if the ast has the given symbol */
1493 /*-----------------------------------------------------------------*/
1495 astHasSymbol (ast * tree, symbol * sym)
1497 if (!tree || IS_AST_LINK (tree))
1500 if (IS_AST_VALUE (tree))
1502 if (IS_AST_SYM_VALUE (tree))
1503 return isSymbolEqual (AST_SYMBOL (tree), sym);
1508 return astHasSymbol (tree->left, sym) ||
1509 astHasSymbol (tree->right, sym);
1512 /*-----------------------------------------------------------------*/
1513 /* astHasDeref - return true if the ast has an indirect access */
1514 /*-----------------------------------------------------------------*/
1516 astHasDeref (ast * tree)
1518 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1521 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1523 return astHasDeref (tree->left) || astHasDeref (tree->right);
1526 /*-----------------------------------------------------------------*/
1527 /* isConformingBody - the loop body has to conform to a set of rules */
1528 /* for the loop to be considered reversible read on for rules */
1529 /*-----------------------------------------------------------------*/
1531 isConformingBody (ast * pbody, symbol * sym, ast * body)
1534 /* we are going to do a pre-order traversal of the
1535 tree && check for the following conditions. (essentially
1536 a set of very shallow tests )
1537 a) the sym passed does not participate in
1538 any arithmetic operation
1539 b) There are no function calls
1540 c) all jumps are within the body
1541 d) address of loop control variable not taken
1542 e) if an assignment has a pointer on the
1543 left hand side make sure right does not have
1544 loop control variable */
1546 /* if we reach the end or a leaf then true */
1547 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1550 /* if anything else is "volatile" */
1551 if (IS_VOLATILE (TETYPE (pbody)))
1554 /* we will walk the body in a pre-order traversal for
1556 switch (pbody->opval.op)
1558 /*------------------------------------------------------------------*/
1560 // if the loopvar is used as an index
1561 if (astHasSymbol(pbody->right, sym)) {
1564 return isConformingBody (pbody->right, sym, body);
1566 /*------------------------------------------------------------------*/
1571 /*------------------------------------------------------------------*/
1572 case INC_OP: /* incerement operator unary so left only */
1575 /* sure we are not sym is not modified */
1577 IS_AST_SYM_VALUE (pbody->left) &&
1578 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1582 IS_AST_SYM_VALUE (pbody->right) &&
1583 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1588 /*------------------------------------------------------------------*/
1590 case '*': /* can be unary : if right is null then unary operation */
1595 /* if right is NULL then unary operation */
1596 /*------------------------------------------------------------------*/
1597 /*----------------------------*/
1599 /*----------------------------*/
1602 if (IS_AST_SYM_VALUE (pbody->left) &&
1603 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1606 return isConformingBody (pbody->left, sym, body);
1610 if (astHasSymbol (pbody->left, sym) ||
1611 astHasSymbol (pbody->right, sym))
1616 /*------------------------------------------------------------------*/
1624 if (IS_AST_SYM_VALUE (pbody->left) &&
1625 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1628 if (IS_AST_SYM_VALUE (pbody->right) &&
1629 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1632 return isConformingBody (pbody->left, sym, body) &&
1633 isConformingBody (pbody->right, sym, body);
1640 if (IS_AST_SYM_VALUE (pbody->left) &&
1641 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1643 return isConformingBody (pbody->left, sym, body);
1645 /*------------------------------------------------------------------*/
1657 case SIZEOF: /* evaluate wihout code generation */
1659 return isConformingBody (pbody->left, sym, body) &&
1660 isConformingBody (pbody->right, sym, body);
1662 /*------------------------------------------------------------------*/
1665 /* if left has a pointer & right has loop
1666 control variable then we cannot */
1667 if (astHasPointer (pbody->left) &&
1668 astHasSymbol (pbody->right, sym))
1670 if (astHasVolatile (pbody->left))
1673 if (IS_AST_SYM_VALUE (pbody->left)) {
1674 // if the loopvar has an assignment
1675 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1677 // if the loopvar is used in another (maybe conditional) block
1678 if (astHasSymbol (pbody->right, sym) &&
1679 (pbody->level > body->level)) {
1684 if (astHasVolatile (pbody->left))
1687 if (astHasDeref(pbody->right)) return FALSE;
1689 return isConformingBody (pbody->left, sym, body) &&
1690 isConformingBody (pbody->right, sym, body);
1701 assert ("Parser should not have generated this\n");
1703 /*------------------------------------------------------------------*/
1704 /*----------------------------*/
1705 /* comma operator */
1706 /*----------------------------*/
1708 return isConformingBody (pbody->left, sym, body) &&
1709 isConformingBody (pbody->right, sym, body);
1711 /*------------------------------------------------------------------*/
1712 /*----------------------------*/
1714 /*----------------------------*/
1716 /* if local & not passed as paramater then ok */
1717 if (sym->level && !astHasSymbol(pbody->right,sym))
1721 /*------------------------------------------------------------------*/
1722 /*----------------------------*/
1723 /* return statement */
1724 /*----------------------------*/
1729 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1734 if (astHasSymbol (pbody->left, sym))
1741 return isConformingBody (pbody->left, sym, body) &&
1742 isConformingBody (pbody->right, sym, body);
1748 /*-----------------------------------------------------------------*/
1749 /* isLoopReversible - takes a for loop as input && returns true */
1750 /* if the for loop is reversible. If yes will set the value of */
1751 /* the loop control var & init value & termination value */
1752 /*-----------------------------------------------------------------*/
1754 isLoopReversible (ast * loop, symbol ** loopCntrl,
1755 ast ** init, ast ** end)
1757 /* if option says don't do it then don't */
1758 if (optimize.noLoopReverse)
1760 /* there are several tests to determine this */
1762 /* for loop has to be of the form
1763 for ( <sym> = <const1> ;
1764 [<sym> < <const2>] ;
1765 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1767 if (!isLoopCountable (AST_FOR (loop, initExpr),
1768 AST_FOR (loop, condExpr),
1769 AST_FOR (loop, loopExpr),
1770 loopCntrl, init, end))
1773 /* now do some serious checking on the body of the loop
1776 return isConformingBody (loop->left, *loopCntrl, loop->left);
1780 /*-----------------------------------------------------------------*/
1781 /* replLoopSym - replace the loop sym by loop sym -1 */
1782 /*-----------------------------------------------------------------*/
1784 replLoopSym (ast * body, symbol * sym)
1787 if (!body || IS_AST_LINK (body))
1790 if (IS_AST_SYM_VALUE (body))
1793 if (isSymbolEqual (AST_SYMBOL (body), sym))
1797 body->opval.op = '-';
1798 body->left = newAst_VALUE (symbolVal (sym));
1799 body->right = newAst_VALUE (constVal ("1"));
1807 replLoopSym (body->left, sym);
1808 replLoopSym (body->right, sym);
1812 /*-----------------------------------------------------------------*/
1813 /* reverseLoop - do the actual loop reversal */
1814 /*-----------------------------------------------------------------*/
1816 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1820 /* create the following tree
1825 if (sym) goto for_continue ;
1828 /* put it together piece by piece */
1829 rloop = newNode (NULLOP,
1830 createIf (newAst_VALUE (symbolVal (sym)),
1832 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1835 newAst_VALUE (symbolVal (sym)),
1838 replLoopSym (loop->left, sym);
1839 setAstLineno (rloop, init->lineno);
1841 rloop = newNode (NULLOP,
1843 newAst_VALUE (symbolVal (sym)),
1844 newNode ('-', end, init)),
1845 createLabel (AST_FOR (loop, continueLabel),
1849 newNode (SUB_ASSIGN,
1850 newAst_VALUE (symbolVal (sym)),
1851 newAst_VALUE (constVal ("1"))),
1854 rloop->lineno=init->lineno;
1855 return decorateType (rloop);
1859 /*-----------------------------------------------------------------*/
1860 /* decorateType - compute type for this tree also does type cheking */
1861 /* this is done bottom up, since type have to flow upwards */
1862 /* it also does constant folding, and paramater checking */
1863 /*-----------------------------------------------------------------*/
1865 decorateType (ast * tree)
1873 /* if already has type then do nothing */
1874 if (tree->decorated)
1877 tree->decorated = 1;
1880 /* print the line */
1881 /* if not block & function */
1882 if (tree->type == EX_OP &&
1883 (tree->opval.op != FUNCTION &&
1884 tree->opval.op != BLOCK &&
1885 tree->opval.op != NULLOP))
1887 filename = tree->filename;
1888 lineno = tree->lineno;
1892 /* if any child is an error | this one is an error do nothing */
1893 if (tree->isError ||
1894 (tree->left && tree->left->isError) ||
1895 (tree->right && tree->right->isError))
1898 /*------------------------------------------------------------------*/
1899 /*----------------------------*/
1900 /* leaf has been reached */
1901 /*----------------------------*/
1902 /* if this is of type value */
1903 /* just get the type */
1904 if (tree->type == EX_VALUE)
1907 if (IS_LITERAL (tree->opval.val->etype))
1910 /* if this is a character array then declare it */
1911 if (IS_ARRAY (tree->opval.val->type))
1912 tree->opval.val = stringToSymbol (tree->opval.val);
1914 /* otherwise just copy the type information */
1915 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1919 if (tree->opval.val->sym)
1921 /* if the undefined flag is set then give error message */
1922 if (tree->opval.val->sym->undefined)
1924 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1926 TTYPE (tree) = TETYPE (tree) =
1927 tree->opval.val->type = tree->opval.val->sym->type =
1928 tree->opval.val->etype = tree->opval.val->sym->etype =
1929 copyLinkChain (INTTYPE);
1934 /* if impilicit i.e. struct/union member then no type */
1935 if (tree->opval.val->sym->implicit)
1936 TTYPE (tree) = TETYPE (tree) = NULL;
1941 /* else copy the type */
1942 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1944 /* and mark it as referenced */
1945 tree->opval.val->sym->isref = 1;
1953 /* if type link for the case of cast */
1954 if (tree->type == EX_LINK)
1956 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1963 dtl = decorateType (tree->left);
1964 /* delay right side for '?' operator since conditional macro expansions might
1966 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1968 /* this is to take care of situations
1969 when the tree gets rewritten */
1970 if (dtl != tree->left)
1972 if (dtr != tree->right)
1975 if (IS_AST_OP(tree) &&
1976 (tree->opval.op == CAST || tree->opval.op == '=') &&
1977 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
1978 (getSize(RTYPE(tree)) < INTSIZE)) {
1979 // this is a cast/assign to a bigger type
1980 if (IS_AST_OP(tree->right) &&
1981 IS_INTEGRAL(tree->right->ftype) &&
1982 (tree->right->opval.op == LEFT_OP ||
1983 tree->right->opval.op == '*' ||
1984 tree->right->opval.op == '+' ||
1985 tree->right->opval.op == '-') &&
1986 tree->right->right) {
1987 // we should cast an operand instead of the result
1988 tree->right->decorated = 0;
1989 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
1991 tree->right = decorateType(tree->right);
1996 /* depending on type of operator do */
1998 switch (tree->opval.op)
2000 /*------------------------------------------------------------------*/
2001 /*----------------------------*/
2003 /*----------------------------*/
2006 /* determine which is the array & which the index */
2007 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2010 ast *tempTree = tree->left;
2011 tree->left = tree->right;
2012 tree->right = tempTree;
2015 /* first check if this is a array or a pointer */
2016 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2018 werror (E_NEED_ARRAY_PTR, "[]");
2019 goto errorTreeReturn;
2022 /* check if the type of the idx */
2023 if (!IS_INTEGRAL (RTYPE (tree)))
2025 werror (E_IDX_NOT_INT);
2026 goto errorTreeReturn;
2029 /* if the left is an rvalue then error */
2032 werror (E_LVALUE_REQUIRED, "array access");
2033 goto errorTreeReturn;
2036 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2037 if (IS_PTR(LTYPE(tree))) {
2038 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2042 /*------------------------------------------------------------------*/
2043 /*----------------------------*/
2045 /*----------------------------*/
2047 /* if this is not a structure */
2048 if (!IS_STRUCT (LTYPE (tree)))
2050 werror (E_STRUCT_UNION, ".");
2051 goto errorTreeReturn;
2053 TTYPE (tree) = structElemType (LTYPE (tree),
2054 (tree->right->type == EX_VALUE ?
2055 tree->right->opval.val : NULL));
2056 TETYPE (tree) = getSpec (TTYPE (tree));
2059 /*------------------------------------------------------------------*/
2060 /*----------------------------*/
2061 /* struct/union pointer */
2062 /*----------------------------*/
2064 /* if not pointer to a structure */
2065 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2067 werror (E_PTR_REQD);
2068 goto errorTreeReturn;
2071 if (!IS_STRUCT (LTYPE (tree)->next))
2073 werror (E_STRUCT_UNION, "->");
2074 goto errorTreeReturn;
2077 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2078 (tree->right->type == EX_VALUE ?
2079 tree->right->opval.val : NULL));
2080 TETYPE (tree) = getSpec (TTYPE (tree));
2082 /* adjust the storage class */
2083 switch (DCL_TYPE(tree->left->ftype)) {
2087 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2090 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2095 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2098 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2101 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2111 /*------------------------------------------------------------------*/
2112 /*----------------------------*/
2113 /* ++/-- operation */
2114 /*----------------------------*/
2115 case INC_OP: /* incerement operator unary so left only */
2118 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2119 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2120 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2121 werror (E_CODE_WRITE, "++/--");
2130 /*------------------------------------------------------------------*/
2131 /*----------------------------*/
2133 /*----------------------------*/
2134 case '&': /* can be unary */
2135 /* if right is NULL then unary operation */
2136 if (tree->right) /* not an unary operation */
2139 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2141 werror (E_BITWISE_OP);
2142 werror (W_CONTINUE, "left & right types are ");
2143 printTypeChain (LTYPE (tree), stderr);
2144 fprintf (stderr, ",");
2145 printTypeChain (RTYPE (tree), stderr);
2146 fprintf (stderr, "\n");
2147 goto errorTreeReturn;
2150 /* if they are both literal */
2151 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2153 tree->type = EX_VALUE;
2154 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2155 valFromType (RETYPE (tree)), '&');
2157 tree->right = tree->left = NULL;
2158 TETYPE (tree) = tree->opval.val->etype;
2159 TTYPE (tree) = tree->opval.val->type;
2163 /* see if this is a GETHBIT operation if yes
2166 ast *otree = optimizeGetHbit (tree);
2169 return decorateType (otree);
2173 computeType (LTYPE (tree), RTYPE (tree));
2174 TETYPE (tree) = getSpec (TTYPE (tree));
2176 LRVAL (tree) = RRVAL (tree) = 1;
2180 /*------------------------------------------------------------------*/
2181 /*----------------------------*/
2183 /*----------------------------*/
2185 p->class = DECLARATOR;
2186 /* if bit field then error */
2187 if (IS_BITVAR (tree->left->etype))
2189 werror (E_ILLEGAL_ADDR, "address of bit variable");
2190 goto errorTreeReturn;
2193 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2195 werror (E_ILLEGAL_ADDR, "address of register variable");
2196 goto errorTreeReturn;
2199 if (IS_FUNC (LTYPE (tree)))
2201 // this ought to be ignored
2202 return (tree->left);
2205 if (IS_LITERAL(LTYPE(tree)))
2207 werror (E_ILLEGAL_ADDR, "address of literal");
2208 goto errorTreeReturn;
2213 werror (E_LVALUE_REQUIRED, "address of");
2214 goto errorTreeReturn;
2216 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2218 DCL_TYPE (p) = CPOINTER;
2219 DCL_PTR_CONST (p) = port->mem.code_ro;
2221 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2222 DCL_TYPE (p) = FPOINTER;
2223 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2224 DCL_TYPE (p) = PPOINTER;
2225 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2226 DCL_TYPE (p) = IPOINTER;
2227 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2228 DCL_TYPE (p) = EEPPOINTER;
2229 else if (SPEC_OCLS(tree->left->etype))
2230 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2232 DCL_TYPE (p) = POINTER;
2234 if (IS_AST_SYM_VALUE (tree->left))
2236 AST_SYMBOL (tree->left)->addrtaken = 1;
2237 AST_SYMBOL (tree->left)->allocreq = 1;
2240 p->next = LTYPE (tree);
2242 TETYPE (tree) = getSpec (TTYPE (tree));
2243 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2244 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2249 /*------------------------------------------------------------------*/
2250 /*----------------------------*/
2252 /*----------------------------*/
2254 /* if the rewrite succeeds then don't go any furthur */
2256 ast *wtree = optimizeRRCRLC (tree);
2258 return decorateType (wtree);
2260 /*------------------------------------------------------------------*/
2261 /*----------------------------*/
2263 /*----------------------------*/
2265 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2267 werror (E_BITWISE_OP);
2268 werror (W_CONTINUE, "left & right types are ");
2269 printTypeChain (LTYPE (tree), stderr);
2270 fprintf (stderr, ",");
2271 printTypeChain (RTYPE (tree), stderr);
2272 fprintf (stderr, "\n");
2273 goto errorTreeReturn;
2276 /* if they are both literal then */
2277 /* rewrite the tree */
2278 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2280 tree->type = EX_VALUE;
2281 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2282 valFromType (RETYPE (tree)),
2284 tree->right = tree->left = NULL;
2285 TETYPE (tree) = tree->opval.val->etype;
2286 TTYPE (tree) = tree->opval.val->type;
2289 LRVAL (tree) = RRVAL (tree) = 1;
2290 TETYPE (tree) = getSpec (TTYPE (tree) =
2291 computeType (LTYPE (tree),
2294 /*------------------------------------------------------------------*/
2295 /*----------------------------*/
2297 /*----------------------------*/
2299 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2301 werror (E_INVALID_OP, "divide");
2302 goto errorTreeReturn;
2304 /* if they are both literal then */
2305 /* rewrite the tree */
2306 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2308 tree->type = EX_VALUE;
2309 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2310 valFromType (RETYPE (tree)));
2311 tree->right = tree->left = NULL;
2312 TETYPE (tree) = getSpec (TTYPE (tree) =
2313 tree->opval.val->type);
2316 LRVAL (tree) = RRVAL (tree) = 1;
2317 TETYPE (tree) = getSpec (TTYPE (tree) =
2318 computeType (LTYPE (tree),
2322 /*------------------------------------------------------------------*/
2323 /*----------------------------*/
2325 /*----------------------------*/
2327 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2329 werror (E_BITWISE_OP);
2330 werror (W_CONTINUE, "left & right types are ");
2331 printTypeChain (LTYPE (tree), stderr);
2332 fprintf (stderr, ",");
2333 printTypeChain (RTYPE (tree), stderr);
2334 fprintf (stderr, "\n");
2335 goto errorTreeReturn;
2337 /* if they are both literal then */
2338 /* rewrite the tree */
2339 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2341 tree->type = EX_VALUE;
2342 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2343 valFromType (RETYPE (tree)));
2344 tree->right = tree->left = NULL;
2345 TETYPE (tree) = getSpec (TTYPE (tree) =
2346 tree->opval.val->type);
2349 LRVAL (tree) = RRVAL (tree) = 1;
2350 TETYPE (tree) = getSpec (TTYPE (tree) =
2351 computeType (LTYPE (tree),
2355 /*------------------------------------------------------------------*/
2356 /*----------------------------*/
2357 /* address dereference */
2358 /*----------------------------*/
2359 case '*': /* can be unary : if right is null then unary operation */
2362 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2364 werror (E_PTR_REQD);
2365 goto errorTreeReturn;
2370 werror (E_LVALUE_REQUIRED, "pointer deref");
2371 goto errorTreeReturn;
2373 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2374 LTYPE (tree)->next : NULL);
2375 TETYPE (tree) = getSpec (TTYPE (tree));
2376 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2380 /*------------------------------------------------------------------*/
2381 /*----------------------------*/
2382 /* multiplication */
2383 /*----------------------------*/
2384 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2386 werror (E_INVALID_OP, "multiplication");
2387 goto errorTreeReturn;
2390 /* if they are both literal then */
2391 /* rewrite the tree */
2392 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2394 tree->type = EX_VALUE;
2395 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2396 valFromType (RETYPE (tree)));
2397 tree->right = tree->left = NULL;
2398 TETYPE (tree) = getSpec (TTYPE (tree) =
2399 tree->opval.val->type);
2403 /* if left is a literal exchange left & right */
2404 if (IS_LITERAL (LTYPE (tree)))
2406 ast *tTree = tree->left;
2407 tree->left = tree->right;
2408 tree->right = tTree;
2411 LRVAL (tree) = RRVAL (tree) = 1;
2412 TETYPE (tree) = getSpec (TTYPE (tree) =
2413 computeType (LTYPE (tree),
2416 /* promote result to int if left & right are char
2417 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2418 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2419 SPEC_NOUN(TETYPE(tree)) = V_INT;
2424 /*------------------------------------------------------------------*/
2425 /*----------------------------*/
2426 /* unary '+' operator */
2427 /*----------------------------*/
2432 if (!IS_INTEGRAL (LTYPE (tree)))
2434 werror (E_UNARY_OP, '+');
2435 goto errorTreeReturn;
2438 /* if left is a literal then do it */
2439 if (IS_LITERAL (LTYPE (tree)))
2441 tree->type = EX_VALUE;
2442 tree->opval.val = valFromType (LETYPE (tree));
2444 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2448 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2452 /*------------------------------------------------------------------*/
2453 /*----------------------------*/
2455 /*----------------------------*/
2457 /* this is not a unary operation */
2458 /* if both pointers then problem */
2459 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2460 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2462 werror (E_PTR_PLUS_PTR);
2463 goto errorTreeReturn;
2466 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2467 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2469 werror (E_PLUS_INVALID, "+");
2470 goto errorTreeReturn;
2473 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2474 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2476 werror (E_PLUS_INVALID, "+");
2477 goto errorTreeReturn;
2479 /* if they are both literal then */
2480 /* rewrite the tree */
2481 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2483 tree->type = EX_VALUE;
2484 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2485 valFromType (RETYPE (tree)));
2486 tree->right = tree->left = NULL;
2487 TETYPE (tree) = getSpec (TTYPE (tree) =
2488 tree->opval.val->type);
2492 /* if the right is a pointer or left is a literal
2493 xchange left & right */
2494 if (IS_ARRAY (RTYPE (tree)) ||
2495 IS_PTR (RTYPE (tree)) ||
2496 IS_LITERAL (LTYPE (tree)))
2498 ast *tTree = tree->left;
2499 tree->left = tree->right;
2500 tree->right = tTree;
2503 LRVAL (tree) = RRVAL (tree) = 1;
2504 /* if the left is a pointer */
2505 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2506 TETYPE (tree) = getSpec (TTYPE (tree) =
2509 TETYPE (tree) = getSpec (TTYPE (tree) =
2510 computeType (LTYPE (tree),
2514 /*------------------------------------------------------------------*/
2515 /*----------------------------*/
2517 /*----------------------------*/
2518 case '-': /* can be unary */
2519 /* if right is null then unary */
2523 if (!IS_ARITHMETIC (LTYPE (tree)))
2525 werror (E_UNARY_OP, tree->opval.op);
2526 goto errorTreeReturn;
2529 /* if left is a literal then do it */
2530 if (IS_LITERAL (LTYPE (tree)))
2532 tree->type = EX_VALUE;
2533 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2535 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2536 SPEC_USIGN(TETYPE(tree)) = 0;
2540 TTYPE (tree) = LTYPE (tree);
2544 /*------------------------------------------------------------------*/
2545 /*----------------------------*/
2547 /*----------------------------*/
2549 if (!(IS_PTR (LTYPE (tree)) ||
2550 IS_ARRAY (LTYPE (tree)) ||
2551 IS_ARITHMETIC (LTYPE (tree))))
2553 werror (E_PLUS_INVALID, "-");
2554 goto errorTreeReturn;
2557 if (!(IS_PTR (RTYPE (tree)) ||
2558 IS_ARRAY (RTYPE (tree)) ||
2559 IS_ARITHMETIC (RTYPE (tree))))
2561 werror (E_PLUS_INVALID, "-");
2562 goto errorTreeReturn;
2565 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2566 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2567 IS_INTEGRAL (RTYPE (tree))))
2569 werror (E_PLUS_INVALID, "-");
2570 goto errorTreeReturn;
2573 /* if they are both literal then */
2574 /* rewrite the tree */
2575 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2577 tree->type = EX_VALUE;
2578 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2579 valFromType (RETYPE (tree)));
2580 tree->right = tree->left = NULL;
2581 TETYPE (tree) = getSpec (TTYPE (tree) =
2582 tree->opval.val->type);
2586 /* if the left & right are equal then zero */
2587 if (isAstEqual (tree->left, tree->right))
2589 tree->type = EX_VALUE;
2590 tree->left = tree->right = NULL;
2591 tree->opval.val = constVal ("0");
2592 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2596 /* if both of them are pointers or arrays then */
2597 /* the result is going to be an integer */
2598 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2599 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2600 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2602 /* if only the left is a pointer */
2603 /* then result is a pointer */
2604 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2605 TETYPE (tree) = getSpec (TTYPE (tree) =
2608 TETYPE (tree) = getSpec (TTYPE (tree) =
2609 computeType (LTYPE (tree),
2611 LRVAL (tree) = RRVAL (tree) = 1;
2614 /*------------------------------------------------------------------*/
2615 /*----------------------------*/
2617 /*----------------------------*/
2619 /* can be only integral type */
2620 if (!IS_INTEGRAL (LTYPE (tree)))
2622 werror (E_UNARY_OP, tree->opval.op);
2623 goto errorTreeReturn;
2626 /* if left is a literal then do it */
2627 if (IS_LITERAL (LTYPE (tree)))
2629 tree->type = EX_VALUE;
2630 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2632 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2636 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2639 /*------------------------------------------------------------------*/
2640 /*----------------------------*/
2642 /*----------------------------*/
2644 /* can be pointer */
2645 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2646 !IS_PTR (LTYPE (tree)) &&
2647 !IS_ARRAY (LTYPE (tree)))
2649 werror (E_UNARY_OP, tree->opval.op);
2650 goto errorTreeReturn;
2653 /* if left is a literal then do it */
2654 if (IS_LITERAL (LTYPE (tree)))
2656 tree->type = EX_VALUE;
2657 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2659 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2663 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2666 /*------------------------------------------------------------------*/
2667 /*----------------------------*/
2669 /*----------------------------*/
2672 TTYPE (tree) = LTYPE (tree);
2673 TETYPE (tree) = LETYPE (tree);
2677 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2682 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2684 werror (E_SHIFT_OP_INVALID);
2685 werror (W_CONTINUE, "left & right types are ");
2686 printTypeChain (LTYPE (tree), stderr);
2687 fprintf (stderr, ",");
2688 printTypeChain (RTYPE (tree), stderr);
2689 fprintf (stderr, "\n");
2690 goto errorTreeReturn;
2693 /* if they are both literal then */
2694 /* rewrite the tree */
2695 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2697 tree->type = EX_VALUE;
2698 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2699 valFromType (RETYPE (tree)),
2700 (tree->opval.op == LEFT_OP ? 1 : 0));
2701 tree->right = tree->left = NULL;
2702 TETYPE (tree) = getSpec (TTYPE (tree) =
2703 tree->opval.val->type);
2707 /* if only the right side is a literal & we are
2708 shifting more than size of the left operand then zero */
2709 if (IS_LITERAL (RTYPE (tree)) &&
2710 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2711 (getSize (LTYPE (tree)) * 8))
2713 if (tree->opval.op==LEFT_OP ||
2714 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2715 lineno=tree->lineno;
2716 werror (W_SHIFT_CHANGED,
2717 (tree->opval.op == LEFT_OP ? "left" : "right"));
2718 tree->type = EX_VALUE;
2719 tree->left = tree->right = NULL;
2720 tree->opval.val = constVal ("0");
2721 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2725 LRVAL (tree) = RRVAL (tree) = 1;
2726 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2728 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2732 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2736 /*------------------------------------------------------------------*/
2737 /*----------------------------*/
2739 /*----------------------------*/
2740 case CAST: /* change the type */
2741 /* cannot cast to an aggregate type */
2742 if (IS_AGGREGATE (LTYPE (tree)))
2744 werror (E_CAST_ILLEGAL);
2745 goto errorTreeReturn;
2748 /* make sure the type is complete and sane */
2749 checkTypeSanity(LETYPE(tree), "(cast)");
2752 /* if the right is a literal replace the tree */
2753 if (IS_LITERAL (RETYPE (tree))) {
2754 if (!IS_PTR (LTYPE (tree))) {
2755 tree->type = EX_VALUE;
2757 valCastLiteral (LTYPE (tree),
2758 floatFromVal (valFromType (RETYPE (tree))));
2761 TTYPE (tree) = tree->opval.val->type;
2762 tree->values.literalFromCast = 1;
2763 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2764 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2765 sym_link *rest = LTYPE(tree)->next;
2766 werror(W_LITERAL_GENERIC);
2767 TTYPE(tree) = newLink();
2768 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2769 TTYPE(tree)->next = rest;
2770 tree->left->opval.lnk = TTYPE(tree);
2773 TTYPE (tree) = LTYPE (tree);
2777 TTYPE (tree) = LTYPE (tree);
2781 #if 0 // this is already checked, now this could be explicit
2782 /* if pointer to struct then check names */
2783 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2784 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2785 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2787 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2788 SPEC_STRUCT(LETYPE(tree))->tag);
2791 /* if the right is a literal replace the tree */
2792 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2793 tree->type = EX_VALUE;
2795 valCastLiteral (LTYPE (tree),
2796 floatFromVal (valFromType (RETYPE (tree))));
2799 TTYPE (tree) = tree->opval.val->type;
2800 tree->values.literalFromCast = 1;
2802 TTYPE (tree) = LTYPE (tree);
2806 TETYPE (tree) = getSpec (TTYPE (tree));
2810 /*------------------------------------------------------------------*/
2811 /*----------------------------*/
2812 /* logical &&, || */
2813 /*----------------------------*/
2816 /* each must me arithmetic type or be a pointer */
2817 if (!IS_PTR (LTYPE (tree)) &&
2818 !IS_ARRAY (LTYPE (tree)) &&
2819 !IS_INTEGRAL (LTYPE (tree)))
2821 werror (E_COMPARE_OP);
2822 goto errorTreeReturn;
2825 if (!IS_PTR (RTYPE (tree)) &&
2826 !IS_ARRAY (RTYPE (tree)) &&
2827 !IS_INTEGRAL (RTYPE (tree)))
2829 werror (E_COMPARE_OP);
2830 goto errorTreeReturn;
2832 /* if they are both literal then */
2833 /* rewrite the tree */
2834 if (IS_LITERAL (RTYPE (tree)) &&
2835 IS_LITERAL (LTYPE (tree)))
2837 tree->type = EX_VALUE;
2838 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2839 valFromType (RETYPE (tree)),
2841 tree->right = tree->left = NULL;
2842 TETYPE (tree) = getSpec (TTYPE (tree) =
2843 tree->opval.val->type);
2846 LRVAL (tree) = RRVAL (tree) = 1;
2847 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2850 /*------------------------------------------------------------------*/
2851 /*----------------------------*/
2852 /* comparison operators */
2853 /*----------------------------*/
2861 ast *lt = optimizeCompare (tree);
2867 /* if they are pointers they must be castable */
2868 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2870 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2872 werror (E_COMPARE_OP);
2873 fprintf (stderr, "comparing type ");
2874 printTypeChain (LTYPE (tree), stderr);
2875 fprintf (stderr, "to type ");
2876 printTypeChain (RTYPE (tree), stderr);
2877 fprintf (stderr, "\n");
2878 goto errorTreeReturn;
2881 /* else they should be promotable to one another */
2884 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2885 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2887 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2889 werror (E_COMPARE_OP);
2890 fprintf (stderr, "comparing type ");
2891 printTypeChain (LTYPE (tree), stderr);
2892 fprintf (stderr, "to type ");
2893 printTypeChain (RTYPE (tree), stderr);
2894 fprintf (stderr, "\n");
2895 goto errorTreeReturn;
2898 /* if unsigned value < 0 then always false */
2899 /* if (unsigned value) > 0 then (unsigned value) */
2900 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2901 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2903 if (tree->opval.op == '<') {
2906 if (tree->opval.op == '>') {
2910 /* if they are both literal then */
2911 /* rewrite the tree */
2912 if (IS_LITERAL (RTYPE (tree)) &&
2913 IS_LITERAL (LTYPE (tree)))
2915 tree->type = EX_VALUE;
2916 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2917 valFromType (RETYPE (tree)),
2919 tree->right = tree->left = NULL;
2920 TETYPE (tree) = getSpec (TTYPE (tree) =
2921 tree->opval.val->type);
2924 LRVAL (tree) = RRVAL (tree) = 1;
2925 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2928 /*------------------------------------------------------------------*/
2929 /*----------------------------*/
2931 /*----------------------------*/
2932 case SIZEOF: /* evaluate wihout code generation */
2933 /* change the type to a integer */
2934 tree->type = EX_VALUE;
2935 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2936 tree->opval.val = constVal (buffer);
2937 tree->right = tree->left = NULL;
2938 TETYPE (tree) = getSpec (TTYPE (tree) =
2939 tree->opval.val->type);
2942 /*------------------------------------------------------------------*/
2943 /*----------------------------*/
2945 /*----------------------------*/
2947 /* return typeof enum value */
2948 tree->type = EX_VALUE;
2951 if (IS_SPEC(tree->right->ftype)) {
2952 switch (SPEC_NOUN(tree->right->ftype)) {
2954 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2955 else typeofv = TYPEOF_INT;
2958 typeofv = TYPEOF_FLOAT;
2961 typeofv = TYPEOF_CHAR;
2964 typeofv = TYPEOF_VOID;
2967 typeofv = TYPEOF_STRUCT;
2970 typeofv = TYPEOF_BIT;
2973 typeofv = TYPEOF_SBIT;
2979 switch (DCL_TYPE(tree->right->ftype)) {
2981 typeofv = TYPEOF_POINTER;
2984 typeofv = TYPEOF_FPOINTER;
2987 typeofv = TYPEOF_CPOINTER;
2990 typeofv = TYPEOF_GPOINTER;
2993 typeofv = TYPEOF_PPOINTER;
2996 typeofv = TYPEOF_IPOINTER;
2999 typeofv = TYPEOF_ARRAY;
3002 typeofv = TYPEOF_FUNCTION;
3008 sprintf (buffer, "%d", typeofv);
3009 tree->opval.val = constVal (buffer);
3010 tree->right = tree->left = NULL;
3011 TETYPE (tree) = getSpec (TTYPE (tree) =
3012 tree->opval.val->type);
3015 /*------------------------------------------------------------------*/
3016 /*----------------------------*/
3017 /* conditional operator '?' */
3018 /*----------------------------*/
3020 /* the type is value of the colon operator (on the right) */
3021 assert(IS_COLON_OP(tree->right));
3022 /* if already known then replace the tree : optimizer will do it
3023 but faster to do it here */
3024 if (IS_LITERAL (LTYPE(tree))) {
3025 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3026 return decorateType(tree->right->left) ;
3028 return decorateType(tree->right->right) ;
3031 tree->right = decorateType(tree->right);
3032 TTYPE (tree) = RTYPE(tree);
3033 TETYPE (tree) = getSpec (TTYPE (tree));
3038 /* if they don't match we have a problem */
3039 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3041 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3042 goto errorTreeReturn;
3045 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3046 TETYPE (tree) = getSpec (TTYPE (tree));
3050 #if 0 // assignment operators are converted by the parser
3051 /*------------------------------------------------------------------*/
3052 /*----------------------------*/
3053 /* assignment operators */
3054 /*----------------------------*/
3057 /* for these it must be both must be integral */
3058 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3059 !IS_ARITHMETIC (RTYPE (tree)))
3061 werror (E_OPS_INTEGRAL);
3062 goto errorTreeReturn;
3065 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3067 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3068 werror (E_CODE_WRITE, " ");
3072 werror (E_LVALUE_REQUIRED, "*= or /=");
3073 goto errorTreeReturn;
3084 /* for these it must be both must be integral */
3085 if (!IS_INTEGRAL (LTYPE (tree)) ||
3086 !IS_INTEGRAL (RTYPE (tree)))
3088 werror (E_OPS_INTEGRAL);
3089 goto errorTreeReturn;
3092 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3094 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3095 werror (E_CODE_WRITE, " ");
3099 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3100 goto errorTreeReturn;
3106 /*------------------------------------------------------------------*/
3107 /*----------------------------*/
3109 /*----------------------------*/
3111 if (!(IS_PTR (LTYPE (tree)) ||
3112 IS_ARITHMETIC (LTYPE (tree))))
3114 werror (E_PLUS_INVALID, "-=");
3115 goto errorTreeReturn;
3118 if (!(IS_PTR (RTYPE (tree)) ||
3119 IS_ARITHMETIC (RTYPE (tree))))
3121 werror (E_PLUS_INVALID, "-=");
3122 goto errorTreeReturn;
3125 TETYPE (tree) = getSpec (TTYPE (tree) =
3126 computeType (LTYPE (tree),
3129 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3130 werror (E_CODE_WRITE, " ");
3134 werror (E_LVALUE_REQUIRED, "-=");
3135 goto errorTreeReturn;
3141 /*------------------------------------------------------------------*/
3142 /*----------------------------*/
3144 /*----------------------------*/
3146 /* this is not a unary operation */
3147 /* if both pointers then problem */
3148 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3150 werror (E_PTR_PLUS_PTR);
3151 goto errorTreeReturn;
3154 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3156 werror (E_PLUS_INVALID, "+=");
3157 goto errorTreeReturn;
3160 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3162 werror (E_PLUS_INVALID, "+=");
3163 goto errorTreeReturn;
3166 TETYPE (tree) = getSpec (TTYPE (tree) =
3167 computeType (LTYPE (tree),
3170 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3171 werror (E_CODE_WRITE, " ");
3175 werror (E_LVALUE_REQUIRED, "+=");
3176 goto errorTreeReturn;
3179 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3180 tree->opval.op = '=';
3185 /*------------------------------------------------------------------*/
3186 /*----------------------------*/
3187 /* straight assignemnt */
3188 /*----------------------------*/
3190 /* cannot be an aggregate */
3191 if (IS_AGGREGATE (LTYPE (tree)))
3193 werror (E_AGGR_ASSIGN);
3194 goto errorTreeReturn;
3197 /* they should either match or be castable */
3198 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3200 werror (E_TYPE_MISMATCH, "assignment", " ");
3201 printFromToType(RTYPE(tree),LTYPE(tree));
3202 //goto errorTreeReturn;
3205 /* if the left side of the tree is of type void
3206 then report error */
3207 if (IS_VOID (LTYPE (tree)))
3209 werror (E_CAST_ZERO);
3210 printFromToType(RTYPE(tree), LTYPE(tree));
3213 TETYPE (tree) = getSpec (TTYPE (tree) =
3217 if (!tree->initMode ) {
3218 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3219 werror (E_CODE_WRITE, " ");
3223 werror (E_LVALUE_REQUIRED, "=");
3224 goto errorTreeReturn;
3229 /*------------------------------------------------------------------*/
3230 /*----------------------------*/
3231 /* comma operator */
3232 /*----------------------------*/
3234 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3237 /*------------------------------------------------------------------*/
3238 /*----------------------------*/
3240 /*----------------------------*/
3244 if (processParms (tree->left,
3245 FUNC_ARGS(tree->left->ftype),
3246 tree->right, &parmNumber, TRUE)) {
3247 goto errorTreeReturn;
3250 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3251 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3253 //FUNC_ARGS(tree->left->ftype) =
3254 //reverseVal (FUNC_ARGS(tree->left->ftype));
3255 reverseParms (tree->right);
3258 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3261 /*------------------------------------------------------------------*/
3262 /*----------------------------*/
3263 /* return statement */
3264 /*----------------------------*/
3269 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3271 werror (W_RETURN_MISMATCH);
3272 printFromToType (RTYPE(tree), currFunc->type->next);
3273 goto errorTreeReturn;
3276 if (IS_VOID (currFunc->type->next)
3278 !IS_VOID (RTYPE (tree)))
3280 werror (E_FUNC_VOID);
3281 goto errorTreeReturn;
3284 /* if there is going to be a casing required then add it */
3285 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3288 decorateType (newNode (CAST,
3289 newAst_LINK (copyLinkChain (currFunc->type->next)),
3298 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3300 werror (E_VOID_FUNC, currFunc->name);
3301 goto errorTreeReturn;
3304 TTYPE (tree) = TETYPE (tree) = NULL;
3307 /*------------------------------------------------------------------*/
3308 /*----------------------------*/
3309 /* switch statement */
3310 /*----------------------------*/
3312 /* the switch value must be an integer */
3313 if (!IS_INTEGRAL (LTYPE (tree)))
3315 werror (E_SWITCH_NON_INTEGER);
3316 goto errorTreeReturn;
3319 TTYPE (tree) = TETYPE (tree) = NULL;
3322 /*------------------------------------------------------------------*/
3323 /*----------------------------*/
3325 /*----------------------------*/
3327 tree->left = backPatchLabels (tree->left,
3330 TTYPE (tree) = TETYPE (tree) = NULL;
3333 /*------------------------------------------------------------------*/
3334 /*----------------------------*/
3336 /*----------------------------*/
3339 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3340 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3341 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3343 /* if the for loop is reversible then
3344 reverse it otherwise do what we normally
3350 if (isLoopReversible (tree, &sym, &init, &end))
3351 return reverseLoop (tree, sym, init, end);
3353 return decorateType (createFor (AST_FOR (tree, trueLabel),
3354 AST_FOR (tree, continueLabel),
3355 AST_FOR (tree, falseLabel),
3356 AST_FOR (tree, condLabel),
3357 AST_FOR (tree, initExpr),
3358 AST_FOR (tree, condExpr),
3359 AST_FOR (tree, loopExpr),
3363 TTYPE (tree) = TETYPE (tree) = NULL;
3367 /* some error found this tree will be killed */
3369 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3370 tree->opval.op = NULLOP;
3376 /*-----------------------------------------------------------------*/
3377 /* sizeofOp - processes size of operation */
3378 /*-----------------------------------------------------------------*/
3380 sizeofOp (sym_link * type)
3384 /* make sure the type is complete and sane */
3385 checkTypeSanity(type, "(sizeof)");
3387 /* get the size and convert it to character */
3388 sprintf (buff, "%d", getSize (type));
3390 /* now convert into value */
3391 return constVal (buff);
3395 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3396 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3397 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3398 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3399 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3400 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3401 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3403 /*-----------------------------------------------------------------*/
3404 /* backPatchLabels - change and or not operators to flow control */
3405 /*-----------------------------------------------------------------*/
3407 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3413 if (!(IS_ANDORNOT (tree)))
3416 /* if this an and */
3419 static int localLbl = 0;
3422 sprintf (buffer, "_and_%d", localLbl++);
3423 localLabel = newSymbol (buffer, NestLevel);
3425 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3427 /* if left is already a IFX then just change the if true label in that */
3428 if (!IS_IFX (tree->left))
3429 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3431 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3432 /* right is a IFX then just join */
3433 if (IS_IFX (tree->right))
3434 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3436 tree->right = createLabel (localLabel, tree->right);
3437 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3439 return newNode (NULLOP, tree->left, tree->right);
3442 /* if this is an or operation */
3445 static int localLbl = 0;
3448 sprintf (buffer, "_or_%d", localLbl++);
3449 localLabel = newSymbol (buffer, NestLevel);
3451 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3453 /* if left is already a IFX then just change the if true label in that */
3454 if (!IS_IFX (tree->left))
3455 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3457 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3458 /* right is a IFX then just join */
3459 if (IS_IFX (tree->right))
3460 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3462 tree->right = createLabel (localLabel, tree->right);
3463 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3465 return newNode (NULLOP, tree->left, tree->right);
3471 int wasnot = IS_NOT (tree->left);
3472 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3474 /* if the left is already a IFX */
3475 if (!IS_IFX (tree->left))
3476 tree->left = newNode (IFX, tree->left, NULL);
3480 tree->left->trueLabel = trueLabel;
3481 tree->left->falseLabel = falseLabel;
3485 tree->left->trueLabel = falseLabel;
3486 tree->left->falseLabel = trueLabel;
3493 tree->trueLabel = trueLabel;
3494 tree->falseLabel = falseLabel;
3501 /*-----------------------------------------------------------------*/
3502 /* createBlock - create expression tree for block */
3503 /*-----------------------------------------------------------------*/
3505 createBlock (symbol * decl, ast * body)
3509 /* if the block has nothing */
3513 ex = newNode (BLOCK, NULL, body);
3514 ex->values.sym = decl;
3516 ex->right = ex->right;
3522 /*-----------------------------------------------------------------*/
3523 /* createLabel - creates the expression tree for labels */
3524 /*-----------------------------------------------------------------*/
3526 createLabel (symbol * label, ast * stmnt)
3529 char name[SDCC_NAME_MAX + 1];
3532 /* must create fresh symbol if the symbol name */
3533 /* exists in the symbol table, since there can */
3534 /* be a variable with the same name as the labl */
3535 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3536 (csym->level == label->level))
3537 label = newSymbol (label->name, label->level);
3539 /* change the name before putting it in add _ */
3540 sprintf (name, "%s", label->name);
3542 /* put the label in the LabelSymbol table */
3543 /* but first check if a label of the same */
3545 if ((csym = findSym (LabelTab, NULL, name)))
3546 werror (E_DUPLICATE_LABEL, label->name);
3548 addSym (LabelTab, label, name, label->level, 0, 0);
3551 label->key = labelKey++;
3552 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3558 /*-----------------------------------------------------------------*/
3559 /* createCase - generates the parsetree for a case statement */
3560 /*-----------------------------------------------------------------*/
3562 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3564 char caseLbl[SDCC_NAME_MAX + 1];
3568 /* if the switch statement does not exist */
3569 /* then case is out of context */
3572 werror (E_CASE_CONTEXT);
3576 caseVal = decorateType (resolveSymbols (caseVal));
3577 /* if not a constant then error */
3578 if (!IS_LITERAL (caseVal->ftype))
3580 werror (E_CASE_CONSTANT);
3584 /* if not a integer than error */
3585 if (!IS_INTEGRAL (caseVal->ftype))
3587 werror (E_CASE_NON_INTEGER);
3591 /* find the end of the switch values chain */
3592 if (!(val = swStat->values.switchVals.swVals))
3593 swStat->values.switchVals.swVals = caseVal->opval.val;
3596 /* also order the cases according to value */
3598 int cVal = (int) floatFromVal (caseVal->opval.val);
3599 while (val && (int) floatFromVal (val) < cVal)
3605 /* if we reached the end then */
3608 pval->next = caseVal->opval.val;
3612 /* we found a value greater than */
3613 /* the current value we must add this */
3614 /* before the value */
3615 caseVal->opval.val->next = val;
3617 /* if this was the first in chain */
3618 if (swStat->values.switchVals.swVals == val)
3619 swStat->values.switchVals.swVals =
3622 pval->next = caseVal->opval.val;
3627 /* create the case label */
3628 sprintf (caseLbl, "_case_%d_%d",
3629 swStat->values.switchVals.swNum,
3630 (int) floatFromVal (caseVal->opval.val));
3632 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3637 /*-----------------------------------------------------------------*/
3638 /* createDefault - creates the parse tree for the default statement */
3639 /*-----------------------------------------------------------------*/
3641 createDefault (ast * swStat, ast * stmnt)
3643 char defLbl[SDCC_NAME_MAX + 1];
3645 /* if the switch statement does not exist */
3646 /* then case is out of context */
3649 werror (E_CASE_CONTEXT);
3653 /* turn on the default flag */
3654 swStat->values.switchVals.swDefault = 1;
3656 /* create the label */
3657 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3658 return createLabel (newSymbol (defLbl, 0), stmnt);
3661 /*-----------------------------------------------------------------*/
3662 /* createIf - creates the parsetree for the if statement */
3663 /*-----------------------------------------------------------------*/
3665 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3667 static int Lblnum = 0;
3669 symbol *ifTrue, *ifFalse, *ifEnd;
3671 /* if neither exists */
3672 if (!elseBody && !ifBody) {
3673 // if there are no side effects (i++, j() etc)
3674 if (!hasSEFcalls(condAst)) {
3679 /* create the labels */
3680 sprintf (buffer, "_iffalse_%d", Lblnum);
3681 ifFalse = newSymbol (buffer, NestLevel);
3682 /* if no else body then end == false */
3687 sprintf (buffer, "_ifend_%d", Lblnum);
3688 ifEnd = newSymbol (buffer, NestLevel);
3691 sprintf (buffer, "_iftrue_%d", Lblnum);
3692 ifTrue = newSymbol (buffer, NestLevel);
3696 /* attach the ifTrue label to the top of it body */
3697 ifBody = createLabel (ifTrue, ifBody);
3698 /* attach a goto end to the ifBody if else is present */
3701 ifBody = newNode (NULLOP, ifBody,
3703 newAst_VALUE (symbolVal (ifEnd)),
3705 /* put the elseLabel on the else body */
3706 elseBody = createLabel (ifFalse, elseBody);
3707 /* out the end at the end of the body */
3708 elseBody = newNode (NULLOP,
3710 createLabel (ifEnd, NULL));
3714 ifBody = newNode (NULLOP, ifBody,
3715 createLabel (ifFalse, NULL));
3717 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3718 if (IS_IFX (condAst))
3721 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3723 return newNode (NULLOP, ifTree,
3724 newNode (NULLOP, ifBody, elseBody));
3728 /*-----------------------------------------------------------------*/
3729 /* createDo - creates parse tree for do */
3732 /* _docontinue_n: */
3733 /* condition_expression +-> trueLabel -> _dobody_n */
3735 /* +-> falseLabel-> _dobreak_n */
3737 /*-----------------------------------------------------------------*/
3739 createDo (symbol * trueLabel, symbol * continueLabel,
3740 symbol * falseLabel, ast * condAst, ast * doBody)
3745 /* if the body does not exist then it is simple */
3748 condAst = backPatchLabels (condAst, continueLabel, NULL);
3749 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3750 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3751 doTree->trueLabel = continueLabel;
3752 doTree->falseLabel = NULL;
3756 /* otherwise we have a body */
3757 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3759 /* attach the body label to the top */
3760 doBody = createLabel (trueLabel, doBody);
3761 /* attach the continue label to end of body */
3762 doBody = newNode (NULLOP, doBody,
3763 createLabel (continueLabel, NULL));
3765 /* now put the break label at the end */
3766 if (IS_IFX (condAst))
3769 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3771 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3773 /* putting it together */
3774 return newNode (NULLOP, doBody, doTree);
3777 /*-----------------------------------------------------------------*/
3778 /* createFor - creates parse tree for 'for' statement */
3781 /* condExpr +-> trueLabel -> _forbody_n */
3783 /* +-> falseLabel-> _forbreak_n */
3786 /* _forcontinue_n: */
3788 /* goto _forcond_n ; */
3790 /*-----------------------------------------------------------------*/
3792 createFor (symbol * trueLabel, symbol * continueLabel,
3793 symbol * falseLabel, symbol * condLabel,
3794 ast * initExpr, ast * condExpr, ast * loopExpr,
3799 /* if loopexpression not present then we can generate it */
3800 /* the same way as a while */
3802 return newNode (NULLOP, initExpr,
3803 createWhile (trueLabel, continueLabel,
3804 falseLabel, condExpr, forBody));
3805 /* vanilla for statement */
3806 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3808 if (condExpr && !IS_IFX (condExpr))
3809 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3812 /* attach condition label to condition */
3813 condExpr = createLabel (condLabel, condExpr);
3815 /* attach body label to body */
3816 forBody = createLabel (trueLabel, forBody);
3818 /* attach continue to forLoop expression & attach */
3819 /* goto the forcond @ and of loopExpression */
3820 loopExpr = createLabel (continueLabel,
3824 newAst_VALUE (symbolVal (condLabel)),
3826 /* now start putting them together */
3827 forTree = newNode (NULLOP, initExpr, condExpr);
3828 forTree = newNode (NULLOP, forTree, forBody);
3829 forTree = newNode (NULLOP, forTree, loopExpr);
3830 /* finally add the break label */
3831 forTree = newNode (NULLOP, forTree,
3832 createLabel (falseLabel, NULL));
3836 /*-----------------------------------------------------------------*/
3837 /* createWhile - creates parse tree for while statement */
3838 /* the while statement will be created as follows */
3840 /* _while_continue_n: */
3841 /* condition_expression +-> trueLabel -> _while_boby_n */
3843 /* +-> falseLabel -> _while_break_n */
3844 /* _while_body_n: */
3846 /* goto _while_continue_n */
3847 /* _while_break_n: */
3848 /*-----------------------------------------------------------------*/
3850 createWhile (symbol * trueLabel, symbol * continueLabel,
3851 symbol * falseLabel, ast * condExpr, ast * whileBody)
3855 /* put the continue label */
3856 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3857 condExpr = createLabel (continueLabel, condExpr);
3858 condExpr->lineno = 0;
3860 /* put the body label in front of the body */
3861 whileBody = createLabel (trueLabel, whileBody);
3862 whileBody->lineno = 0;
3863 /* put a jump to continue at the end of the body */
3864 /* and put break label at the end of the body */
3865 whileBody = newNode (NULLOP,
3868 newAst_VALUE (symbolVal (continueLabel)),
3869 createLabel (falseLabel, NULL)));
3871 /* put it all together */
3872 if (IS_IFX (condExpr))
3873 whileTree = condExpr;
3876 whileTree = newNode (IFX, condExpr, NULL);
3877 /* put the true & false labels in place */
3878 whileTree->trueLabel = trueLabel;
3879 whileTree->falseLabel = falseLabel;
3882 return newNode (NULLOP, whileTree, whileBody);
3885 /*-----------------------------------------------------------------*/
3886 /* optimizeGetHbit - get highest order bit of the expression */
3887 /*-----------------------------------------------------------------*/
3889 optimizeGetHbit (ast * tree)
3892 /* if this is not a bit and */
3893 if (!IS_BITAND (tree))
3896 /* will look for tree of the form
3897 ( expr >> ((sizeof expr) -1) ) & 1 */
3898 if (!IS_AST_LIT_VALUE (tree->right))
3901 if (AST_LIT_VALUE (tree->right) != 1)
3904 if (!IS_RIGHT_OP (tree->left))
3907 if (!IS_AST_LIT_VALUE (tree->left->right))
3910 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3911 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3914 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3918 /*-----------------------------------------------------------------*/
3919 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3920 /*-----------------------------------------------------------------*/
3922 optimizeRRCRLC (ast * root)
3924 /* will look for trees of the form
3925 (?expr << 1) | (?expr >> 7) or
3926 (?expr >> 7) | (?expr << 1) will make that
3927 into a RLC : operation ..
3929 (?expr >> 1) | (?expr << 7) or
3930 (?expr << 7) | (?expr >> 1) will make that
3931 into a RRC operation
3932 note : by 7 I mean (number of bits required to hold the
3934 /* if the root operations is not a | operation the not */
3935 if (!IS_BITOR (root))
3938 /* I have to think of a better way to match patterns this sucks */
3939 /* that aside let start looking for the first case : I use a the
3940 negative check a lot to improve the efficiency */
3941 /* (?expr << 1) | (?expr >> 7) */
3942 if (IS_LEFT_OP (root->left) &&
3943 IS_RIGHT_OP (root->right))
3946 if (!SPEC_USIGN (TETYPE (root->left->left)))
3949 if (!IS_AST_LIT_VALUE (root->left->right) ||
3950 !IS_AST_LIT_VALUE (root->right->right))
3953 /* make sure it is the same expression */
3954 if (!isAstEqual (root->left->left,
3958 if (AST_LIT_VALUE (root->left->right) != 1)
3961 if (AST_LIT_VALUE (root->right->right) !=
3962 (getSize (TTYPE (root->left->left)) * 8 - 1))
3965 /* whew got the first case : create the AST */
3966 return newNode (RLC, root->left->left, NULL);
3970 /* check for second case */
3971 /* (?expr >> 7) | (?expr << 1) */
3972 if (IS_LEFT_OP (root->right) &&
3973 IS_RIGHT_OP (root->left))
3976 if (!SPEC_USIGN (TETYPE (root->left->left)))
3979 if (!IS_AST_LIT_VALUE (root->left->right) ||
3980 !IS_AST_LIT_VALUE (root->right->right))
3983 /* make sure it is the same symbol */
3984 if (!isAstEqual (root->left->left,
3988 if (AST_LIT_VALUE (root->right->right) != 1)
3991 if (AST_LIT_VALUE (root->left->right) !=
3992 (getSize (TTYPE (root->left->left)) * 8 - 1))
3995 /* whew got the first case : create the AST */
3996 return newNode (RLC, root->left->left, NULL);
4001 /* third case for RRC */
4002 /* (?symbol >> 1) | (?symbol << 7) */
4003 if (IS_LEFT_OP (root->right) &&
4004 IS_RIGHT_OP (root->left))
4007 if (!SPEC_USIGN (TETYPE (root->left->left)))
4010 if (!IS_AST_LIT_VALUE (root->left->right) ||
4011 !IS_AST_LIT_VALUE (root->right->right))
4014 /* make sure it is the same symbol */
4015 if (!isAstEqual (root->left->left,
4019 if (AST_LIT_VALUE (root->left->right) != 1)
4022 if (AST_LIT_VALUE (root->right->right) !=
4023 (getSize (TTYPE (root->left->left)) * 8 - 1))
4026 /* whew got the first case : create the AST */
4027 return newNode (RRC, root->left->left, NULL);
4031 /* fourth and last case for now */
4032 /* (?symbol << 7) | (?symbol >> 1) */
4033 if (IS_RIGHT_OP (root->right) &&
4034 IS_LEFT_OP (root->left))
4037 if (!SPEC_USIGN (TETYPE (root->left->left)))
4040 if (!IS_AST_LIT_VALUE (root->left->right) ||
4041 !IS_AST_LIT_VALUE (root->right->right))
4044 /* make sure it is the same symbol */
4045 if (!isAstEqual (root->left->left,
4049 if (AST_LIT_VALUE (root->right->right) != 1)
4052 if (AST_LIT_VALUE (root->left->right) !=
4053 (getSize (TTYPE (root->left->left)) * 8 - 1))
4056 /* whew got the first case : create the AST */
4057 return newNode (RRC, root->left->left, NULL);
4061 /* not found return root */
4065 /*-----------------------------------------------------------------*/
4066 /* optimizeCompare - otimizes compares for bit variables */
4067 /*-----------------------------------------------------------------*/
4069 optimizeCompare (ast * root)
4071 ast *optExpr = NULL;
4074 unsigned int litValue;
4076 /* if nothing then return nothing */
4080 /* if not a compare op then do leaves */
4081 if (!IS_COMPARE_OP (root))
4083 root->left = optimizeCompare (root->left);
4084 root->right = optimizeCompare (root->right);
4088 /* if left & right are the same then depending
4089 of the operation do */
4090 if (isAstEqual (root->left, root->right))
4092 switch (root->opval.op)
4097 optExpr = newAst_VALUE (constVal ("0"));
4102 optExpr = newAst_VALUE (constVal ("1"));
4106 return decorateType (optExpr);
4109 vleft = (root->left->type == EX_VALUE ?
4110 root->left->opval.val : NULL);
4112 vright = (root->right->type == EX_VALUE ?
4113 root->right->opval.val : NULL);
4115 /* if left is a BITVAR in BITSPACE */
4116 /* and right is a LITERAL then opt- */
4117 /* imize else do nothing */
4118 if (vleft && vright &&
4119 IS_BITVAR (vleft->etype) &&
4120 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4121 IS_LITERAL (vright->etype))
4124 /* if right side > 1 then comparison may never succeed */
4125 if ((litValue = (int) floatFromVal (vright)) > 1)
4127 werror (W_BAD_COMPARE);
4133 switch (root->opval.op)
4135 case '>': /* bit value greater than 1 cannot be */
4136 werror (W_BAD_COMPARE);
4140 case '<': /* bit value < 1 means 0 */
4142 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4145 case LE_OP: /* bit value <= 1 means no check */
4146 optExpr = newAst_VALUE (vright);
4149 case GE_OP: /* bit value >= 1 means only check for = */
4151 optExpr = newAst_VALUE (vleft);
4156 { /* literal is zero */
4157 switch (root->opval.op)
4159 case '<': /* bit value < 0 cannot be */
4160 werror (W_BAD_COMPARE);
4164 case '>': /* bit value > 0 means 1 */
4166 optExpr = newAst_VALUE (vleft);
4169 case LE_OP: /* bit value <= 0 means no check */
4170 case GE_OP: /* bit value >= 0 means no check */
4171 werror (W_BAD_COMPARE);
4175 case EQ_OP: /* bit == 0 means ! of bit */
4176 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4180 return decorateType (resolveSymbols (optExpr));
4181 } /* end-of-if of BITVAR */
4186 /*-----------------------------------------------------------------*/
4187 /* addSymToBlock : adds the symbol to the first block we find */
4188 /*-----------------------------------------------------------------*/
4190 addSymToBlock (symbol * sym, ast * tree)
4192 /* reached end of tree or a leaf */
4193 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4197 if (IS_AST_OP (tree) &&
4198 tree->opval.op == BLOCK)
4201 symbol *lsym = copySymbol (sym);
4203 lsym->next = AST_VALUES (tree, sym);
4204 AST_VALUES (tree, sym) = lsym;
4208 addSymToBlock (sym, tree->left);
4209 addSymToBlock (sym, tree->right);
4212 /*-----------------------------------------------------------------*/
4213 /* processRegParms - do processing for register parameters */
4214 /*-----------------------------------------------------------------*/
4216 processRegParms (value * args, ast * body)
4220 if (IS_REGPARM (args->etype))
4221 addSymToBlock (args->sym, body);
4226 /*-----------------------------------------------------------------*/
4227 /* resetParmKey - resets the operandkeys for the symbols */
4228 /*-----------------------------------------------------------------*/
4229 DEFSETFUNC (resetParmKey)
4240 /*-----------------------------------------------------------------*/
4241 /* createFunction - This is the key node that calls the iCode for */
4242 /* generating the code for a function. Note code */
4243 /* is generated function by function, later when */
4244 /* add inter-procedural analysis this will change */
4245 /*-----------------------------------------------------------------*/
4247 createFunction (symbol * name, ast * body)
4253 iCode *piCode = NULL;
4255 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4256 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4258 /* if check function return 0 then some problem */
4259 if (checkFunction (name, NULL) == 0)
4262 /* create a dummy block if none exists */
4264 body = newNode (BLOCK, NULL, NULL);
4268 /* check if the function name already in the symbol table */
4269 if ((csym = findSym (SymbolTab, NULL, name->name)))
4272 /* special case for compiler defined functions
4273 we need to add the name to the publics list : this
4274 actually means we are now compiling the compiler
4278 addSet (&publics, name);
4284 allocVariables (name);
4286 name->lastLine = yylineno;
4289 /* set the stack pointer */
4290 /* PENDING: check this for the mcs51 */
4291 stackPtr = -port->stack.direction * port->stack.call_overhead;
4292 if (IFFUNC_ISISR (name->type))
4293 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4294 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4295 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4297 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4299 fetype = getSpec (name->type); /* get the specifier for the function */
4300 /* if this is a reentrant function then */
4301 if (IFFUNC_ISREENT (name->type))
4304 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4306 /* do processing for parameters that are passed in registers */
4307 processRegParms (FUNC_ARGS(name->type), body);
4309 /* set the stack pointer */
4313 /* allocate & autoinit the block variables */
4314 processBlockVars (body, &stack, ALLOCATE);
4316 /* save the stack information */
4317 if (options.useXstack)
4318 name->xstack = SPEC_STAK (fetype) = stack;
4320 name->stack = SPEC_STAK (fetype) = stack;
4322 /* name needs to be mangled */
4323 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4325 body = resolveSymbols (body); /* resolve the symbols */
4326 body = decorateType (body); /* propagateType & do semantic checks */
4328 ex = newAst_VALUE (symbolVal (name)); /* create name */
4329 ex = newNode (FUNCTION, ex, body);
4330 ex->values.args = FUNC_ARGS(name->type);
4332 if (options.dump_tree) PA(ex);
4335 werror (E_FUNC_NO_CODE, name->name);
4339 /* create the node & generate intermediate code */
4341 codeOutFile = code->oFile;
4342 piCode = iCodeFromAst (ex);
4346 werror (E_FUNC_NO_CODE, name->name);
4350 eBBlockFromiCode (piCode);
4352 /* if there are any statics then do them */
4355 GcurMemmap = statsg;
4356 codeOutFile = statsg->oFile;
4357 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4363 /* dealloc the block variables */
4364 processBlockVars (body, &stack, DEALLOCATE);
4365 /* deallocate paramaters */
4366 deallocParms (FUNC_ARGS(name->type));
4368 if (IFFUNC_ISREENT (name->type))
4371 /* we are done freeup memory & cleanup */
4373 if (port->reset_labelKey) labelKey = 1;
4375 FUNC_HASBODY(name->type) = 1;
4376 addSet (&operKeyReset, name);
4377 applyToSet (operKeyReset, resetParmKey);
4380 cdbStructBlock (1, cdbFile);
4382 cleanUpLevel (LabelTab, 0);
4383 cleanUpBlock (StructTab, 1);
4384 cleanUpBlock (TypedefTab, 1);
4386 xstack->syms = NULL;
4387 istack->syms = NULL;
4392 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4393 /*-----------------------------------------------------------------*/
4394 /* ast_print : prints the ast (for debugging purposes) */
4395 /*-----------------------------------------------------------------*/
4397 void ast_print (ast * tree, FILE *outfile, int indent)
4402 /* can print only decorated trees */
4403 if (!tree->decorated) return;
4405 /* if any child is an error | this one is an error do nothing */
4406 if (tree->isError ||
4407 (tree->left && tree->left->isError) ||
4408 (tree->right && tree->right->isError)) {
4409 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4413 /* print the line */
4414 /* if not block & function */
4415 if (tree->type == EX_OP &&
4416 (tree->opval.op != FUNCTION &&
4417 tree->opval.op != BLOCK &&
4418 tree->opval.op != NULLOP)) {
4421 if (tree->opval.op == FUNCTION) {
4423 value *args=FUNC_ARGS(tree->left->opval.val->type);
4424 fprintf(outfile,"FUNCTION (%s=%p) type (",
4425 tree->left->opval.val->name, tree);
4426 printTypeChain (tree->ftype,outfile);
4427 fprintf(outfile,") args (");
4430 fprintf (outfile, ", ");
4432 printTypeChain (args ? args->type : NULL, outfile);
4434 args= args ? args->next : NULL;
4436 fprintf(outfile,")\n");
4437 ast_print(tree->left,outfile,indent);
4438 ast_print(tree->right,outfile,indent);
4441 if (tree->opval.op == BLOCK) {
4442 symbol *decls = tree->values.sym;
4443 INDENT(indent,outfile);
4444 fprintf(outfile,"{\n");
4446 INDENT(indent+2,outfile);
4447 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4448 decls->name, decls);
4449 printTypeChain(decls->type,outfile);
4450 fprintf(outfile,")\n");
4452 decls = decls->next;
4454 ast_print(tree->right,outfile,indent+2);
4455 INDENT(indent,outfile);
4456 fprintf(outfile,"}\n");
4459 if (tree->opval.op == NULLOP) {
4460 fprintf(outfile,"\n");
4461 ast_print(tree->left,outfile,indent);
4462 fprintf(outfile,"\n");
4463 ast_print(tree->right,outfile,indent);
4466 INDENT(indent,outfile);
4468 /*------------------------------------------------------------------*/
4469 /*----------------------------*/
4470 /* leaf has been reached */
4471 /*----------------------------*/
4472 /* if this is of type value */
4473 /* just get the type */
4474 if (tree->type == EX_VALUE) {
4476 if (IS_LITERAL (tree->opval.val->etype)) {
4477 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4478 (int) floatFromVal(tree->opval.val),
4479 (int) floatFromVal(tree->opval.val),
4480 floatFromVal(tree->opval.val));
4481 } else if (tree->opval.val->sym) {
4482 /* if the undefined flag is set then give error message */
4483 if (tree->opval.val->sym->undefined) {
4484 fprintf(outfile,"UNDEFINED SYMBOL ");
4486 fprintf(outfile,"SYMBOL ");
4488 fprintf(outfile,"(%s=%p)",
4489 tree->opval.val->sym->name,tree);
4492 fprintf(outfile," type (");
4493 printTypeChain(tree->ftype,outfile);
4494 fprintf(outfile,")\n");
4496 fprintf(outfile,"\n");
4501 /* if type link for the case of cast */
4502 if (tree->type == EX_LINK) {
4503 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4504 printTypeChain(tree->opval.lnk,outfile);
4505 fprintf(outfile,")\n");
4510 /* depending on type of operator do */
4512 switch (tree->opval.op) {
4513 /*------------------------------------------------------------------*/
4514 /*----------------------------*/
4516 /*----------------------------*/
4518 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4519 printTypeChain(tree->ftype,outfile);
4520 fprintf(outfile,")\n");
4521 ast_print(tree->left,outfile,indent+2);
4522 ast_print(tree->right,outfile,indent+2);
4525 /*------------------------------------------------------------------*/
4526 /*----------------------------*/
4528 /*----------------------------*/
4530 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4531 printTypeChain(tree->ftype,outfile);
4532 fprintf(outfile,")\n");
4533 ast_print(tree->left,outfile,indent+2);
4534 ast_print(tree->right,outfile,indent+2);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4539 /* struct/union pointer */
4540 /*----------------------------*/
4542 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->left,outfile,indent+2);
4546 ast_print(tree->right,outfile,indent+2);
4549 /*------------------------------------------------------------------*/
4550 /*----------------------------*/
4551 /* ++/-- operation */
4552 /*----------------------------*/
4553 case INC_OP: /* incerement operator unary so left only */
4554 fprintf(outfile,"INC_OP (%p) type (",tree);
4555 printTypeChain(tree->ftype,outfile);
4556 fprintf(outfile,")\n");
4557 ast_print(tree->left,outfile,indent+2);
4561 fprintf(outfile,"DEC_OP (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+2);
4567 /*------------------------------------------------------------------*/
4568 /*----------------------------*/
4570 /*----------------------------*/
4573 fprintf(outfile,"& (%p) type (",tree);
4574 printTypeChain(tree->ftype,outfile);
4575 fprintf(outfile,")\n");
4576 ast_print(tree->left,outfile,indent+2);
4577 ast_print(tree->right,outfile,indent+2);
4579 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4580 printTypeChain(tree->ftype,outfile);
4581 fprintf(outfile,")\n");
4582 ast_print(tree->left,outfile,indent+2);
4583 ast_print(tree->right,outfile,indent+2);
4586 /*----------------------------*/
4588 /*----------------------------*/
4590 fprintf(outfile,"OR (%p) type (",tree);
4591 printTypeChain(tree->ftype,outfile);
4592 fprintf(outfile,")\n");
4593 ast_print(tree->left,outfile,indent+2);
4594 ast_print(tree->right,outfile,indent+2);
4596 /*------------------------------------------------------------------*/
4597 /*----------------------------*/
4599 /*----------------------------*/
4601 fprintf(outfile,"XOR (%p) type (",tree);
4602 printTypeChain(tree->ftype,outfile);
4603 fprintf(outfile,")\n");
4604 ast_print(tree->left,outfile,indent+2);
4605 ast_print(tree->right,outfile,indent+2);
4608 /*------------------------------------------------------------------*/
4609 /*----------------------------*/
4611 /*----------------------------*/
4613 fprintf(outfile,"DIV (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+2);
4617 ast_print(tree->right,outfile,indent+2);
4619 /*------------------------------------------------------------------*/
4620 /*----------------------------*/
4622 /*----------------------------*/
4624 fprintf(outfile,"MOD (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+2);
4628 ast_print(tree->right,outfile,indent+2);
4631 /*------------------------------------------------------------------*/
4632 /*----------------------------*/
4633 /* address dereference */
4634 /*----------------------------*/
4635 case '*': /* can be unary : if right is null then unary operation */
4637 fprintf(outfile,"DEREF (%p) type (",tree);
4638 printTypeChain(tree->ftype,outfile);
4639 fprintf(outfile,")\n");
4640 ast_print(tree->left,outfile,indent+2);
4643 /*------------------------------------------------------------------*/
4644 /*----------------------------*/
4645 /* multiplication */
4646 /*----------------------------*/
4647 fprintf(outfile,"MULT (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+2);
4651 ast_print(tree->right,outfile,indent+2);
4655 /*------------------------------------------------------------------*/
4656 /*----------------------------*/
4657 /* unary '+' operator */
4658 /*----------------------------*/
4662 fprintf(outfile,"UPLUS (%p) type (",tree);
4663 printTypeChain(tree->ftype,outfile);
4664 fprintf(outfile,")\n");
4665 ast_print(tree->left,outfile,indent+2);
4667 /*------------------------------------------------------------------*/
4668 /*----------------------------*/
4670 /*----------------------------*/
4671 fprintf(outfile,"ADD (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+2);
4675 ast_print(tree->right,outfile,indent+2);
4678 /*------------------------------------------------------------------*/
4679 /*----------------------------*/
4681 /*----------------------------*/
4682 case '-': /* can be unary */
4684 fprintf(outfile,"UMINUS (%p) type (",tree);
4685 printTypeChain(tree->ftype,outfile);
4686 fprintf(outfile,")\n");
4687 ast_print(tree->left,outfile,indent+2);
4689 /*------------------------------------------------------------------*/
4690 /*----------------------------*/
4692 /*----------------------------*/
4693 fprintf(outfile,"SUB (%p) type (",tree);
4694 printTypeChain(tree->ftype,outfile);
4695 fprintf(outfile,")\n");
4696 ast_print(tree->left,outfile,indent+2);
4697 ast_print(tree->right,outfile,indent+2);
4700 /*------------------------------------------------------------------*/
4701 /*----------------------------*/
4703 /*----------------------------*/
4705 fprintf(outfile,"COMPL (%p) type (",tree);
4706 printTypeChain(tree->ftype,outfile);
4707 fprintf(outfile,")\n");
4708 ast_print(tree->left,outfile,indent+2);
4710 /*------------------------------------------------------------------*/
4711 /*----------------------------*/
4713 /*----------------------------*/
4715 fprintf(outfile,"NOT (%p) type (",tree);
4716 printTypeChain(tree->ftype,outfile);
4717 fprintf(outfile,")\n");
4718 ast_print(tree->left,outfile,indent+2);
4720 /*------------------------------------------------------------------*/
4721 /*----------------------------*/
4723 /*----------------------------*/
4725 fprintf(outfile,"RRC (%p) type (",tree);
4726 printTypeChain(tree->ftype,outfile);
4727 fprintf(outfile,")\n");
4728 ast_print(tree->left,outfile,indent+2);
4732 fprintf(outfile,"RLC (%p) type (",tree);
4733 printTypeChain(tree->ftype,outfile);
4734 fprintf(outfile,")\n");
4735 ast_print(tree->left,outfile,indent+2);
4738 fprintf(outfile,"GETHBIT (%p) type (",tree);
4739 printTypeChain(tree->ftype,outfile);
4740 fprintf(outfile,")\n");
4741 ast_print(tree->left,outfile,indent+2);
4744 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+2);
4748 ast_print(tree->right,outfile,indent+2);
4751 fprintf(outfile,"RIGHT_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);
4757 /*------------------------------------------------------------------*/
4758 /*----------------------------*/
4760 /*----------------------------*/
4761 case CAST: /* change the type */
4762 fprintf(outfile,"CAST (%p) from type (",tree);
4763 printTypeChain(tree->right->ftype,outfile);
4764 fprintf(outfile,") to type (");
4765 printTypeChain(tree->ftype,outfile);
4766 fprintf(outfile,")\n");
4767 ast_print(tree->right,outfile,indent+2);
4771 fprintf(outfile,"ANDAND (%p) type (",tree);
4772 printTypeChain(tree->ftype,outfile);
4773 fprintf(outfile,")\n");
4774 ast_print(tree->left,outfile,indent+2);
4775 ast_print(tree->right,outfile,indent+2);
4778 fprintf(outfile,"OROR (%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 /*------------------------------------------------------------------*/
4786 /*----------------------------*/
4787 /* comparison operators */
4788 /*----------------------------*/
4790 fprintf(outfile,"GT(>) (%p) type (",tree);
4791 printTypeChain(tree->ftype,outfile);
4792 fprintf(outfile,")\n");
4793 ast_print(tree->left,outfile,indent+2);
4794 ast_print(tree->right,outfile,indent+2);
4797 fprintf(outfile,"LT(<) (%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,"LE(<=) (%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,"GE(>=) (%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,"EQ(==) (%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,"NE(!=) (%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);
4830 /*------------------------------------------------------------------*/
4831 /*----------------------------*/
4833 /*----------------------------*/
4834 case SIZEOF: /* evaluate wihout code generation */
4835 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4838 /*------------------------------------------------------------------*/
4839 /*----------------------------*/
4840 /* conditional operator '?' */
4841 /*----------------------------*/
4843 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4844 printTypeChain(tree->ftype,outfile);
4845 fprintf(outfile,")\n");
4846 ast_print(tree->left,outfile,indent+2);
4847 ast_print(tree->right,outfile,indent+2);
4851 fprintf(outfile,"COLON(:) (%p) type (",tree);
4852 printTypeChain(tree->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 ast_print(tree->right,outfile,indent+2);
4858 /*------------------------------------------------------------------*/
4859 /*----------------------------*/
4860 /* assignment operators */
4861 /*----------------------------*/
4863 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4864 printTypeChain(tree->ftype,outfile);
4865 fprintf(outfile,")\n");
4866 ast_print(tree->left,outfile,indent+2);
4867 ast_print(tree->right,outfile,indent+2);
4870 fprintf(outfile,"DIVASS(/=) (%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,"ANDASS(&=) (%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,"ORASS(*=) (%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,"XORASS(*=) (%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,"RSHFTASS(>>=) (%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,"LSHFTASS(*=) (%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);
4911 /*------------------------------------------------------------------*/
4912 /*----------------------------*/
4914 /*----------------------------*/
4916 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4917 printTypeChain(tree->ftype,outfile);
4918 fprintf(outfile,")\n");
4919 ast_print(tree->left,outfile,indent+2);
4920 ast_print(tree->right,outfile,indent+2);
4922 /*------------------------------------------------------------------*/
4923 /*----------------------------*/
4925 /*----------------------------*/
4927 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4928 printTypeChain(tree->ftype,outfile);
4929 fprintf(outfile,")\n");
4930 ast_print(tree->left,outfile,indent+2);
4931 ast_print(tree->right,outfile,indent+2);
4933 /*------------------------------------------------------------------*/
4934 /*----------------------------*/
4935 /* straight assignemnt */
4936 /*----------------------------*/
4938 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4939 printTypeChain(tree->ftype,outfile);
4940 fprintf(outfile,")\n");
4941 ast_print(tree->left,outfile,indent+2);
4942 ast_print(tree->right,outfile,indent+2);
4944 /*------------------------------------------------------------------*/
4945 /*----------------------------*/
4946 /* comma operator */
4947 /*----------------------------*/
4949 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4950 printTypeChain(tree->ftype,outfile);
4951 fprintf(outfile,")\n");
4952 ast_print(tree->left,outfile,indent+2);
4953 ast_print(tree->right,outfile,indent+2);
4955 /*------------------------------------------------------------------*/
4956 /*----------------------------*/
4958 /*----------------------------*/
4961 fprintf(outfile,"CALL (%p) type (",tree);
4962 printTypeChain(tree->ftype,outfile);
4963 fprintf(outfile,")\n");
4964 ast_print(tree->left,outfile,indent+2);
4965 ast_print(tree->right,outfile,indent+2);
4968 fprintf(outfile,"PARMS\n");
4969 ast_print(tree->left,outfile,indent+2);
4970 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4971 ast_print(tree->right,outfile,indent+2);
4974 /*------------------------------------------------------------------*/
4975 /*----------------------------*/
4976 /* return statement */
4977 /*----------------------------*/
4979 fprintf(outfile,"RETURN (%p) type (",tree);
4981 printTypeChain(tree->right->ftype,outfile);
4983 fprintf(outfile,")\n");
4984 ast_print(tree->right,outfile,indent+2);
4986 /*------------------------------------------------------------------*/
4987 /*----------------------------*/
4988 /* label statement */
4989 /*----------------------------*/
4991 fprintf(outfile,"LABEL (%p)\n",tree);
4992 ast_print(tree->left,outfile,indent+2);
4993 ast_print(tree->right,outfile,indent);
4995 /*------------------------------------------------------------------*/
4996 /*----------------------------*/
4997 /* switch statement */
4998 /*----------------------------*/
5002 fprintf(outfile,"SWITCH (%p) ",tree);
5003 ast_print(tree->left,outfile,0);
5004 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5005 INDENT(indent+2,outfile);
5006 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5007 (int) floatFromVal(val),
5008 tree->values.switchVals.swNum,
5009 (int) floatFromVal(val));
5011 ast_print(tree->right,outfile,indent);
5014 /*------------------------------------------------------------------*/
5015 /*----------------------------*/
5017 /*----------------------------*/
5019 fprintf(outfile,"IF (%p) \n",tree);
5020 ast_print(tree->left,outfile,indent+2);
5021 if (tree->trueLabel) {
5022 INDENT(indent,outfile);
5023 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5025 if (tree->falseLabel) {
5026 INDENT(indent,outfile);
5027 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5029 ast_print(tree->right,outfile,indent+2);
5031 /*------------------------------------------------------------------*/
5032 /*----------------------------*/
5034 /*----------------------------*/
5036 fprintf(outfile,"FOR (%p) \n",tree);
5037 if (AST_FOR( tree, initExpr)) {
5038 INDENT(indent+2,outfile);
5039 fprintf(outfile,"INIT EXPR ");
5040 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5042 if (AST_FOR( tree, condExpr)) {
5043 INDENT(indent+2,outfile);
5044 fprintf(outfile,"COND EXPR ");
5045 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5047 if (AST_FOR( tree, loopExpr)) {
5048 INDENT(indent+2,outfile);
5049 fprintf(outfile,"LOOP EXPR ");
5050 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5052 fprintf(outfile,"FOR LOOP BODY \n");
5053 ast_print(tree->left,outfile,indent+2);
5062 ast_print(t,stdout,0);