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 (tree->right->opval.op == LEFT_OP ||
1982 tree->right->opval.op == '*' ||
1983 tree->right->opval.op == '+' ||
1984 tree->right->opval.op == '-') &&
1985 tree->right->right) {
1986 // we should cast an operand instead of the result
1987 tree->right->decorated = 0;
1988 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
1990 tree->right = decorateType(tree->right);
1995 /* depending on type of operator do */
1997 switch (tree->opval.op)
1999 /*------------------------------------------------------------------*/
2000 /*----------------------------*/
2002 /*----------------------------*/
2005 /* determine which is the array & which the index */
2006 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2009 ast *tempTree = tree->left;
2010 tree->left = tree->right;
2011 tree->right = tempTree;
2014 /* first check if this is a array or a pointer */
2015 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2017 werror (E_NEED_ARRAY_PTR, "[]");
2018 goto errorTreeReturn;
2021 /* check if the type of the idx */
2022 if (!IS_INTEGRAL (RTYPE (tree)))
2024 werror (E_IDX_NOT_INT);
2025 goto errorTreeReturn;
2028 /* if the left is an rvalue then error */
2031 werror (E_LVALUE_REQUIRED, "array access");
2032 goto errorTreeReturn;
2035 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2036 if (IS_PTR(LTYPE(tree))) {
2037 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2041 /*------------------------------------------------------------------*/
2042 /*----------------------------*/
2044 /*----------------------------*/
2046 /* if this is not a structure */
2047 if (!IS_STRUCT (LTYPE (tree)))
2049 werror (E_STRUCT_UNION, ".");
2050 goto errorTreeReturn;
2052 TTYPE (tree) = structElemType (LTYPE (tree),
2053 (tree->right->type == EX_VALUE ?
2054 tree->right->opval.val : NULL));
2055 TETYPE (tree) = getSpec (TTYPE (tree));
2058 /*------------------------------------------------------------------*/
2059 /*----------------------------*/
2060 /* struct/union pointer */
2061 /*----------------------------*/
2063 /* if not pointer to a structure */
2064 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2066 werror (E_PTR_REQD);
2067 goto errorTreeReturn;
2070 if (!IS_STRUCT (LTYPE (tree)->next))
2072 werror (E_STRUCT_UNION, "->");
2073 goto errorTreeReturn;
2076 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2077 (tree->right->type == EX_VALUE ?
2078 tree->right->opval.val : NULL));
2079 TETYPE (tree) = getSpec (TTYPE (tree));
2081 /* adjust the storage class */
2082 switch (DCL_TYPE(tree->left->ftype)) {
2086 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2089 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2094 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2097 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2100 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2110 /*------------------------------------------------------------------*/
2111 /*----------------------------*/
2112 /* ++/-- operation */
2113 /*----------------------------*/
2114 case INC_OP: /* incerement operator unary so left only */
2117 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2118 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2119 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2120 werror (E_CODE_WRITE, "++/--");
2129 /*------------------------------------------------------------------*/
2130 /*----------------------------*/
2132 /*----------------------------*/
2133 case '&': /* can be unary */
2134 /* if right is NULL then unary operation */
2135 if (tree->right) /* not an unary operation */
2138 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2140 werror (E_BITWISE_OP);
2141 werror (W_CONTINUE, "left & right types are ");
2142 printTypeChain (LTYPE (tree), stderr);
2143 fprintf (stderr, ",");
2144 printTypeChain (RTYPE (tree), stderr);
2145 fprintf (stderr, "\n");
2146 goto errorTreeReturn;
2149 /* if they are both literal */
2150 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2152 tree->type = EX_VALUE;
2153 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2154 valFromType (RETYPE (tree)), '&');
2156 tree->right = tree->left = NULL;
2157 TETYPE (tree) = tree->opval.val->etype;
2158 TTYPE (tree) = tree->opval.val->type;
2162 /* see if this is a GETHBIT operation if yes
2165 ast *otree = optimizeGetHbit (tree);
2168 return decorateType (otree);
2172 computeType (LTYPE (tree), RTYPE (tree));
2173 TETYPE (tree) = getSpec (TTYPE (tree));
2175 LRVAL (tree) = RRVAL (tree) = 1;
2179 /*------------------------------------------------------------------*/
2180 /*----------------------------*/
2182 /*----------------------------*/
2184 p->class = DECLARATOR;
2185 /* if bit field then error */
2186 if (IS_BITVAR (tree->left->etype))
2188 werror (E_ILLEGAL_ADDR, "address of bit variable");
2189 goto errorTreeReturn;
2192 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2194 werror (E_ILLEGAL_ADDR, "address of register variable");
2195 goto errorTreeReturn;
2198 if (IS_FUNC (LTYPE (tree)))
2200 // this ought to be ignored
2201 return (tree->left);
2204 if (IS_LITERAL(LTYPE(tree)))
2206 werror (E_ILLEGAL_ADDR, "address of literal");
2207 goto errorTreeReturn;
2212 werror (E_LVALUE_REQUIRED, "address of");
2213 goto errorTreeReturn;
2215 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2217 DCL_TYPE (p) = CPOINTER;
2218 DCL_PTR_CONST (p) = port->mem.code_ro;
2220 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2221 DCL_TYPE (p) = FPOINTER;
2222 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2223 DCL_TYPE (p) = PPOINTER;
2224 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2225 DCL_TYPE (p) = IPOINTER;
2226 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2227 DCL_TYPE (p) = EEPPOINTER;
2228 else if (SPEC_OCLS(tree->left->etype))
2229 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2231 DCL_TYPE (p) = POINTER;
2233 if (IS_AST_SYM_VALUE (tree->left))
2235 AST_SYMBOL (tree->left)->addrtaken = 1;
2236 AST_SYMBOL (tree->left)->allocreq = 1;
2239 p->next = LTYPE (tree);
2241 TETYPE (tree) = getSpec (TTYPE (tree));
2242 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2243 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2248 /*------------------------------------------------------------------*/
2249 /*----------------------------*/
2251 /*----------------------------*/
2253 /* if the rewrite succeeds then don't go any furthur */
2255 ast *wtree = optimizeRRCRLC (tree);
2257 return decorateType (wtree);
2259 /*------------------------------------------------------------------*/
2260 /*----------------------------*/
2262 /*----------------------------*/
2264 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2266 werror (E_BITWISE_OP);
2267 werror (W_CONTINUE, "left & right types are ");
2268 printTypeChain (LTYPE (tree), stderr);
2269 fprintf (stderr, ",");
2270 printTypeChain (RTYPE (tree), stderr);
2271 fprintf (stderr, "\n");
2272 goto errorTreeReturn;
2275 /* if they are both literal then */
2276 /* rewrite the tree */
2277 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2279 tree->type = EX_VALUE;
2280 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2281 valFromType (RETYPE (tree)),
2283 tree->right = tree->left = NULL;
2284 TETYPE (tree) = tree->opval.val->etype;
2285 TTYPE (tree) = tree->opval.val->type;
2288 LRVAL (tree) = RRVAL (tree) = 1;
2289 TETYPE (tree) = getSpec (TTYPE (tree) =
2290 computeType (LTYPE (tree),
2293 /*------------------------------------------------------------------*/
2294 /*----------------------------*/
2296 /*----------------------------*/
2298 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2300 werror (E_INVALID_OP, "divide");
2301 goto errorTreeReturn;
2303 /* if they are both literal then */
2304 /* rewrite the tree */
2305 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2307 tree->type = EX_VALUE;
2308 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2309 valFromType (RETYPE (tree)));
2310 tree->right = tree->left = NULL;
2311 TETYPE (tree) = getSpec (TTYPE (tree) =
2312 tree->opval.val->type);
2315 LRVAL (tree) = RRVAL (tree) = 1;
2316 TETYPE (tree) = getSpec (TTYPE (tree) =
2317 computeType (LTYPE (tree),
2321 /*------------------------------------------------------------------*/
2322 /*----------------------------*/
2324 /*----------------------------*/
2326 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2328 werror (E_BITWISE_OP);
2329 werror (W_CONTINUE, "left & right types are ");
2330 printTypeChain (LTYPE (tree), stderr);
2331 fprintf (stderr, ",");
2332 printTypeChain (RTYPE (tree), stderr);
2333 fprintf (stderr, "\n");
2334 goto errorTreeReturn;
2336 /* if they are both literal then */
2337 /* rewrite the tree */
2338 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2340 tree->type = EX_VALUE;
2341 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2342 valFromType (RETYPE (tree)));
2343 tree->right = tree->left = NULL;
2344 TETYPE (tree) = getSpec (TTYPE (tree) =
2345 tree->opval.val->type);
2348 LRVAL (tree) = RRVAL (tree) = 1;
2349 TETYPE (tree) = getSpec (TTYPE (tree) =
2350 computeType (LTYPE (tree),
2354 /*------------------------------------------------------------------*/
2355 /*----------------------------*/
2356 /* address dereference */
2357 /*----------------------------*/
2358 case '*': /* can be unary : if right is null then unary operation */
2361 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2363 werror (E_PTR_REQD);
2364 goto errorTreeReturn;
2369 werror (E_LVALUE_REQUIRED, "pointer deref");
2370 goto errorTreeReturn;
2372 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2373 LTYPE (tree)->next : NULL);
2374 TETYPE (tree) = getSpec (TTYPE (tree));
2375 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2379 /*------------------------------------------------------------------*/
2380 /*----------------------------*/
2381 /* multiplication */
2382 /*----------------------------*/
2383 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2385 werror (E_INVALID_OP, "multiplication");
2386 goto errorTreeReturn;
2389 /* if they are both literal then */
2390 /* rewrite the tree */
2391 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2393 tree->type = EX_VALUE;
2394 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2395 valFromType (RETYPE (tree)));
2396 tree->right = tree->left = NULL;
2397 TETYPE (tree) = getSpec (TTYPE (tree) =
2398 tree->opval.val->type);
2402 /* if left is a literal exchange left & right */
2403 if (IS_LITERAL (LTYPE (tree)))
2405 ast *tTree = tree->left;
2406 tree->left = tree->right;
2407 tree->right = tTree;
2410 LRVAL (tree) = RRVAL (tree) = 1;
2411 TETYPE (tree) = getSpec (TTYPE (tree) =
2412 computeType (LTYPE (tree),
2415 /* promote result to int if left & right are char
2416 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2417 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2418 SPEC_NOUN(TETYPE(tree)) = V_INT;
2423 /*------------------------------------------------------------------*/
2424 /*----------------------------*/
2425 /* unary '+' operator */
2426 /*----------------------------*/
2431 if (!IS_INTEGRAL (LTYPE (tree)))
2433 werror (E_UNARY_OP, '+');
2434 goto errorTreeReturn;
2437 /* if left is a literal then do it */
2438 if (IS_LITERAL (LTYPE (tree)))
2440 tree->type = EX_VALUE;
2441 tree->opval.val = valFromType (LETYPE (tree));
2443 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2447 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2451 /*------------------------------------------------------------------*/
2452 /*----------------------------*/
2454 /*----------------------------*/
2456 /* this is not a unary operation */
2457 /* if both pointers then problem */
2458 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2459 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2461 werror (E_PTR_PLUS_PTR);
2462 goto errorTreeReturn;
2465 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2466 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2468 werror (E_PLUS_INVALID, "+");
2469 goto errorTreeReturn;
2472 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2473 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2475 werror (E_PLUS_INVALID, "+");
2476 goto errorTreeReturn;
2478 /* if they are both literal then */
2479 /* rewrite the tree */
2480 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2482 tree->type = EX_VALUE;
2483 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2484 valFromType (RETYPE (tree)));
2485 tree->right = tree->left = NULL;
2486 TETYPE (tree) = getSpec (TTYPE (tree) =
2487 tree->opval.val->type);
2491 /* if the right is a pointer or left is a literal
2492 xchange left & right */
2493 if (IS_ARRAY (RTYPE (tree)) ||
2494 IS_PTR (RTYPE (tree)) ||
2495 IS_LITERAL (LTYPE (tree)))
2497 ast *tTree = tree->left;
2498 tree->left = tree->right;
2499 tree->right = tTree;
2502 LRVAL (tree) = RRVAL (tree) = 1;
2503 /* if the left is a pointer */
2504 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2505 TETYPE (tree) = getSpec (TTYPE (tree) =
2508 TETYPE (tree) = getSpec (TTYPE (tree) =
2509 computeType (LTYPE (tree),
2513 /*------------------------------------------------------------------*/
2514 /*----------------------------*/
2516 /*----------------------------*/
2517 case '-': /* can be unary */
2518 /* if right is null then unary */
2522 if (!IS_ARITHMETIC (LTYPE (tree)))
2524 werror (E_UNARY_OP, tree->opval.op);
2525 goto errorTreeReturn;
2528 /* if left is a literal then do it */
2529 if (IS_LITERAL (LTYPE (tree)))
2531 tree->type = EX_VALUE;
2532 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2534 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2535 SPEC_USIGN(TETYPE(tree)) = 0;
2539 TTYPE (tree) = LTYPE (tree);
2543 /*------------------------------------------------------------------*/
2544 /*----------------------------*/
2546 /*----------------------------*/
2548 if (!(IS_PTR (LTYPE (tree)) ||
2549 IS_ARRAY (LTYPE (tree)) ||
2550 IS_ARITHMETIC (LTYPE (tree))))
2552 werror (E_PLUS_INVALID, "-");
2553 goto errorTreeReturn;
2556 if (!(IS_PTR (RTYPE (tree)) ||
2557 IS_ARRAY (RTYPE (tree)) ||
2558 IS_ARITHMETIC (RTYPE (tree))))
2560 werror (E_PLUS_INVALID, "-");
2561 goto errorTreeReturn;
2564 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2565 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2566 IS_INTEGRAL (RTYPE (tree))))
2568 werror (E_PLUS_INVALID, "-");
2569 goto errorTreeReturn;
2572 /* if they are both literal then */
2573 /* rewrite the tree */
2574 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2576 tree->type = EX_VALUE;
2577 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2578 valFromType (RETYPE (tree)));
2579 tree->right = tree->left = NULL;
2580 TETYPE (tree) = getSpec (TTYPE (tree) =
2581 tree->opval.val->type);
2585 /* if the left & right are equal then zero */
2586 if (isAstEqual (tree->left, tree->right))
2588 tree->type = EX_VALUE;
2589 tree->left = tree->right = NULL;
2590 tree->opval.val = constVal ("0");
2591 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2595 /* if both of them are pointers or arrays then */
2596 /* the result is going to be an integer */
2597 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2598 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2599 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2601 /* if only the left is a pointer */
2602 /* then result is a pointer */
2603 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2604 TETYPE (tree) = getSpec (TTYPE (tree) =
2607 TETYPE (tree) = getSpec (TTYPE (tree) =
2608 computeType (LTYPE (tree),
2610 LRVAL (tree) = RRVAL (tree) = 1;
2613 /*------------------------------------------------------------------*/
2614 /*----------------------------*/
2616 /*----------------------------*/
2618 /* can be only integral type */
2619 if (!IS_INTEGRAL (LTYPE (tree)))
2621 werror (E_UNARY_OP, tree->opval.op);
2622 goto errorTreeReturn;
2625 /* if left is a literal then do it */
2626 if (IS_LITERAL (LTYPE (tree)))
2628 tree->type = EX_VALUE;
2629 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2631 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2635 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2638 /*------------------------------------------------------------------*/
2639 /*----------------------------*/
2641 /*----------------------------*/
2643 /* can be pointer */
2644 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2645 !IS_PTR (LTYPE (tree)) &&
2646 !IS_ARRAY (LTYPE (tree)))
2648 werror (E_UNARY_OP, tree->opval.op);
2649 goto errorTreeReturn;
2652 /* if left is a literal then do it */
2653 if (IS_LITERAL (LTYPE (tree)))
2655 tree->type = EX_VALUE;
2656 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2658 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2662 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2665 /*------------------------------------------------------------------*/
2666 /*----------------------------*/
2668 /*----------------------------*/
2671 TTYPE (tree) = LTYPE (tree);
2672 TETYPE (tree) = LETYPE (tree);
2676 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2681 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2683 werror (E_SHIFT_OP_INVALID);
2684 werror (W_CONTINUE, "left & right types are ");
2685 printTypeChain (LTYPE (tree), stderr);
2686 fprintf (stderr, ",");
2687 printTypeChain (RTYPE (tree), stderr);
2688 fprintf (stderr, "\n");
2689 goto errorTreeReturn;
2692 /* if they are both literal then */
2693 /* rewrite the tree */
2694 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2696 tree->type = EX_VALUE;
2697 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2698 valFromType (RETYPE (tree)),
2699 (tree->opval.op == LEFT_OP ? 1 : 0));
2700 tree->right = tree->left = NULL;
2701 TETYPE (tree) = getSpec (TTYPE (tree) =
2702 tree->opval.val->type);
2706 /* if only the right side is a literal & we are
2707 shifting more than size of the left operand then zero */
2708 if (IS_LITERAL (RTYPE (tree)) &&
2709 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2710 (getSize (LTYPE (tree)) * 8))
2712 if (tree->opval.op==LEFT_OP ||
2713 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2714 lineno=tree->lineno;
2715 werror (W_SHIFT_CHANGED,
2716 (tree->opval.op == LEFT_OP ? "left" : "right"));
2717 tree->type = EX_VALUE;
2718 tree->left = tree->right = NULL;
2719 tree->opval.val = constVal ("0");
2720 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2724 LRVAL (tree) = RRVAL (tree) = 1;
2725 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2727 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2731 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2735 /*------------------------------------------------------------------*/
2736 /*----------------------------*/
2738 /*----------------------------*/
2739 case CAST: /* change the type */
2740 /* cannot cast to an aggregate type */
2741 if (IS_AGGREGATE (LTYPE (tree)))
2743 werror (E_CAST_ILLEGAL);
2744 goto errorTreeReturn;
2747 /* make sure the type is complete and sane */
2748 checkTypeSanity(LETYPE(tree), "(cast)");
2751 /* if the right is a literal replace the tree */
2752 if (IS_LITERAL (RETYPE (tree))) {
2753 if (!IS_PTR (LTYPE (tree))) {
2754 tree->type = EX_VALUE;
2756 valCastLiteral (LTYPE (tree),
2757 floatFromVal (valFromType (RETYPE (tree))));
2760 TTYPE (tree) = tree->opval.val->type;
2761 tree->values.literalFromCast = 1;
2762 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2763 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2764 sym_link *rest = LTYPE(tree)->next;
2765 werror(W_LITERAL_GENERIC);
2766 TTYPE(tree) = newLink();
2767 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2768 TTYPE(tree)->next = rest;
2769 tree->left->opval.lnk = TTYPE(tree);
2772 TTYPE (tree) = LTYPE (tree);
2776 TTYPE (tree) = LTYPE (tree);
2780 #if 0 // this is already checked, now this could be explicit
2781 /* if pointer to struct then check names */
2782 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2783 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2784 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2786 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2787 SPEC_STRUCT(LETYPE(tree))->tag);
2790 /* if the right is a literal replace the tree */
2791 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2792 tree->type = EX_VALUE;
2794 valCastLiteral (LTYPE (tree),
2795 floatFromVal (valFromType (RETYPE (tree))));
2798 TTYPE (tree) = tree->opval.val->type;
2799 tree->values.literalFromCast = 1;
2801 TTYPE (tree) = LTYPE (tree);
2805 TETYPE (tree) = getSpec (TTYPE (tree));
2809 /*------------------------------------------------------------------*/
2810 /*----------------------------*/
2811 /* logical &&, || */
2812 /*----------------------------*/
2815 /* each must me arithmetic type or be a pointer */
2816 if (!IS_PTR (LTYPE (tree)) &&
2817 !IS_ARRAY (LTYPE (tree)) &&
2818 !IS_INTEGRAL (LTYPE (tree)))
2820 werror (E_COMPARE_OP);
2821 goto errorTreeReturn;
2824 if (!IS_PTR (RTYPE (tree)) &&
2825 !IS_ARRAY (RTYPE (tree)) &&
2826 !IS_INTEGRAL (RTYPE (tree)))
2828 werror (E_COMPARE_OP);
2829 goto errorTreeReturn;
2831 /* if they are both literal then */
2832 /* rewrite the tree */
2833 if (IS_LITERAL (RTYPE (tree)) &&
2834 IS_LITERAL (LTYPE (tree)))
2836 tree->type = EX_VALUE;
2837 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2838 valFromType (RETYPE (tree)),
2840 tree->right = tree->left = NULL;
2841 TETYPE (tree) = getSpec (TTYPE (tree) =
2842 tree->opval.val->type);
2845 LRVAL (tree) = RRVAL (tree) = 1;
2846 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2849 /*------------------------------------------------------------------*/
2850 /*----------------------------*/
2851 /* comparison operators */
2852 /*----------------------------*/
2860 ast *lt = optimizeCompare (tree);
2866 /* if they are pointers they must be castable */
2867 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2869 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2871 werror (E_COMPARE_OP);
2872 fprintf (stderr, "comparing type ");
2873 printTypeChain (LTYPE (tree), stderr);
2874 fprintf (stderr, "to type ");
2875 printTypeChain (RTYPE (tree), stderr);
2876 fprintf (stderr, "\n");
2877 goto errorTreeReturn;
2880 /* else they should be promotable to one another */
2883 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2884 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2886 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2888 werror (E_COMPARE_OP);
2889 fprintf (stderr, "comparing type ");
2890 printTypeChain (LTYPE (tree), stderr);
2891 fprintf (stderr, "to type ");
2892 printTypeChain (RTYPE (tree), stderr);
2893 fprintf (stderr, "\n");
2894 goto errorTreeReturn;
2897 /* if unsigned value < 0 then always false */
2898 /* if (unsigned value) > 0 then (unsigned value) */
2899 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2900 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2902 if (tree->opval.op == '<') {
2905 if (tree->opval.op == '>') {
2909 /* if they are both literal then */
2910 /* rewrite the tree */
2911 if (IS_LITERAL (RTYPE (tree)) &&
2912 IS_LITERAL (LTYPE (tree)))
2914 tree->type = EX_VALUE;
2915 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2916 valFromType (RETYPE (tree)),
2918 tree->right = tree->left = NULL;
2919 TETYPE (tree) = getSpec (TTYPE (tree) =
2920 tree->opval.val->type);
2923 LRVAL (tree) = RRVAL (tree) = 1;
2924 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2927 /*------------------------------------------------------------------*/
2928 /*----------------------------*/
2930 /*----------------------------*/
2931 case SIZEOF: /* evaluate wihout code generation */
2932 /* change the type to a integer */
2933 tree->type = EX_VALUE;
2934 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2935 tree->opval.val = constVal (buffer);
2936 tree->right = tree->left = NULL;
2937 TETYPE (tree) = getSpec (TTYPE (tree) =
2938 tree->opval.val->type);
2941 /*------------------------------------------------------------------*/
2942 /*----------------------------*/
2944 /*----------------------------*/
2946 /* return typeof enum value */
2947 tree->type = EX_VALUE;
2950 if (IS_SPEC(tree->right->ftype)) {
2951 switch (SPEC_NOUN(tree->right->ftype)) {
2953 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2954 else typeofv = TYPEOF_INT;
2957 typeofv = TYPEOF_FLOAT;
2960 typeofv = TYPEOF_CHAR;
2963 typeofv = TYPEOF_VOID;
2966 typeofv = TYPEOF_STRUCT;
2969 typeofv = TYPEOF_BIT;
2972 typeofv = TYPEOF_SBIT;
2978 switch (DCL_TYPE(tree->right->ftype)) {
2980 typeofv = TYPEOF_POINTER;
2983 typeofv = TYPEOF_FPOINTER;
2986 typeofv = TYPEOF_CPOINTER;
2989 typeofv = TYPEOF_GPOINTER;
2992 typeofv = TYPEOF_PPOINTER;
2995 typeofv = TYPEOF_IPOINTER;
2998 typeofv = TYPEOF_ARRAY;
3001 typeofv = TYPEOF_FUNCTION;
3007 sprintf (buffer, "%d", typeofv);
3008 tree->opval.val = constVal (buffer);
3009 tree->right = tree->left = NULL;
3010 TETYPE (tree) = getSpec (TTYPE (tree) =
3011 tree->opval.val->type);
3014 /*------------------------------------------------------------------*/
3015 /*----------------------------*/
3016 /* conditional operator '?' */
3017 /*----------------------------*/
3019 /* the type is value of the colon operator (on the right) */
3020 assert(IS_COLON_OP(tree->right));
3021 /* if already known then replace the tree : optimizer will do it
3022 but faster to do it here */
3023 if (IS_LITERAL (LTYPE(tree))) {
3024 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3025 return decorateType(tree->right->left) ;
3027 return decorateType(tree->right->right) ;
3030 tree->right = decorateType(tree->right);
3031 TTYPE (tree) = RTYPE(tree);
3032 TETYPE (tree) = getSpec (TTYPE (tree));
3037 /* if they don't match we have a problem */
3038 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3040 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3041 goto errorTreeReturn;
3044 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3045 TETYPE (tree) = getSpec (TTYPE (tree));
3049 #if 0 // assignment operators are converted by the parser
3050 /*------------------------------------------------------------------*/
3051 /*----------------------------*/
3052 /* assignment operators */
3053 /*----------------------------*/
3056 /* for these it must be both must be integral */
3057 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3058 !IS_ARITHMETIC (RTYPE (tree)))
3060 werror (E_OPS_INTEGRAL);
3061 goto errorTreeReturn;
3064 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3066 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3067 werror (E_CODE_WRITE, " ");
3071 werror (E_LVALUE_REQUIRED, "*= or /=");
3072 goto errorTreeReturn;
3083 /* for these it must be both must be integral */
3084 if (!IS_INTEGRAL (LTYPE (tree)) ||
3085 !IS_INTEGRAL (RTYPE (tree)))
3087 werror (E_OPS_INTEGRAL);
3088 goto errorTreeReturn;
3091 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3093 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3094 werror (E_CODE_WRITE, " ");
3098 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3099 goto errorTreeReturn;
3105 /*------------------------------------------------------------------*/
3106 /*----------------------------*/
3108 /*----------------------------*/
3110 if (!(IS_PTR (LTYPE (tree)) ||
3111 IS_ARITHMETIC (LTYPE (tree))))
3113 werror (E_PLUS_INVALID, "-=");
3114 goto errorTreeReturn;
3117 if (!(IS_PTR (RTYPE (tree)) ||
3118 IS_ARITHMETIC (RTYPE (tree))))
3120 werror (E_PLUS_INVALID, "-=");
3121 goto errorTreeReturn;
3124 TETYPE (tree) = getSpec (TTYPE (tree) =
3125 computeType (LTYPE (tree),
3128 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3129 werror (E_CODE_WRITE, " ");
3133 werror (E_LVALUE_REQUIRED, "-=");
3134 goto errorTreeReturn;
3140 /*------------------------------------------------------------------*/
3141 /*----------------------------*/
3143 /*----------------------------*/
3145 /* this is not a unary operation */
3146 /* if both pointers then problem */
3147 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3149 werror (E_PTR_PLUS_PTR);
3150 goto errorTreeReturn;
3153 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3155 werror (E_PLUS_INVALID, "+=");
3156 goto errorTreeReturn;
3159 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3161 werror (E_PLUS_INVALID, "+=");
3162 goto errorTreeReturn;
3165 TETYPE (tree) = getSpec (TTYPE (tree) =
3166 computeType (LTYPE (tree),
3169 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3170 werror (E_CODE_WRITE, " ");
3174 werror (E_LVALUE_REQUIRED, "+=");
3175 goto errorTreeReturn;
3178 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3179 tree->opval.op = '=';
3184 /*------------------------------------------------------------------*/
3185 /*----------------------------*/
3186 /* straight assignemnt */
3187 /*----------------------------*/
3189 /* cannot be an aggregate */
3190 if (IS_AGGREGATE (LTYPE (tree)))
3192 werror (E_AGGR_ASSIGN);
3193 goto errorTreeReturn;
3196 /* they should either match or be castable */
3197 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3199 werror (E_TYPE_MISMATCH, "assignment", " ");
3200 printFromToType(RTYPE(tree),LTYPE(tree));
3201 //goto errorTreeReturn;
3204 /* if the left side of the tree is of type void
3205 then report error */
3206 if (IS_VOID (LTYPE (tree)))
3208 werror (E_CAST_ZERO);
3209 printFromToType(RTYPE(tree), LTYPE(tree));
3212 TETYPE (tree) = getSpec (TTYPE (tree) =
3216 if (!tree->initMode ) {
3217 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3218 werror (E_CODE_WRITE, " ");
3222 werror (E_LVALUE_REQUIRED, "=");
3223 goto errorTreeReturn;
3228 /*------------------------------------------------------------------*/
3229 /*----------------------------*/
3230 /* comma operator */
3231 /*----------------------------*/
3233 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3236 /*------------------------------------------------------------------*/
3237 /*----------------------------*/
3239 /*----------------------------*/
3243 if (processParms (tree->left,
3244 FUNC_ARGS(tree->left->ftype),
3245 tree->right, &parmNumber, TRUE)) {
3246 goto errorTreeReturn;
3249 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3250 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3252 //FUNC_ARGS(tree->left->ftype) =
3253 //reverseVal (FUNC_ARGS(tree->left->ftype));
3254 reverseParms (tree->right);
3257 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3260 /*------------------------------------------------------------------*/
3261 /*----------------------------*/
3262 /* return statement */
3263 /*----------------------------*/
3268 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3270 werror (W_RETURN_MISMATCH);
3271 printFromToType (RTYPE(tree), currFunc->type->next);
3272 goto errorTreeReturn;
3275 if (IS_VOID (currFunc->type->next)
3277 !IS_VOID (RTYPE (tree)))
3279 werror (E_FUNC_VOID);
3280 goto errorTreeReturn;
3283 /* if there is going to be a casing required then add it */
3284 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3287 decorateType (newNode (CAST,
3288 newAst_LINK (copyLinkChain (currFunc->type->next)),
3297 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3299 werror (E_VOID_FUNC, currFunc->name);
3300 goto errorTreeReturn;
3303 TTYPE (tree) = TETYPE (tree) = NULL;
3306 /*------------------------------------------------------------------*/
3307 /*----------------------------*/
3308 /* switch statement */
3309 /*----------------------------*/
3311 /* the switch value must be an integer */
3312 if (!IS_INTEGRAL (LTYPE (tree)))
3314 werror (E_SWITCH_NON_INTEGER);
3315 goto errorTreeReturn;
3318 TTYPE (tree) = TETYPE (tree) = NULL;
3321 /*------------------------------------------------------------------*/
3322 /*----------------------------*/
3324 /*----------------------------*/
3326 tree->left = backPatchLabels (tree->left,
3329 TTYPE (tree) = TETYPE (tree) = NULL;
3332 /*------------------------------------------------------------------*/
3333 /*----------------------------*/
3335 /*----------------------------*/
3338 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3339 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3340 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3342 /* if the for loop is reversible then
3343 reverse it otherwise do what we normally
3349 if (isLoopReversible (tree, &sym, &init, &end))
3350 return reverseLoop (tree, sym, init, end);
3352 return decorateType (createFor (AST_FOR (tree, trueLabel),
3353 AST_FOR (tree, continueLabel),
3354 AST_FOR (tree, falseLabel),
3355 AST_FOR (tree, condLabel),
3356 AST_FOR (tree, initExpr),
3357 AST_FOR (tree, condExpr),
3358 AST_FOR (tree, loopExpr),
3362 TTYPE (tree) = TETYPE (tree) = NULL;
3366 /* some error found this tree will be killed */
3368 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3369 tree->opval.op = NULLOP;
3375 /*-----------------------------------------------------------------*/
3376 /* sizeofOp - processes size of operation */
3377 /*-----------------------------------------------------------------*/
3379 sizeofOp (sym_link * type)
3383 /* make sure the type is complete and sane */
3384 checkTypeSanity(type, "(sizeof)");
3386 /* get the size and convert it to character */
3387 sprintf (buff, "%d", getSize (type));
3389 /* now convert into value */
3390 return constVal (buff);
3394 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3395 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3396 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3397 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3398 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3399 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3400 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3402 /*-----------------------------------------------------------------*/
3403 /* backPatchLabels - change and or not operators to flow control */
3404 /*-----------------------------------------------------------------*/
3406 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3412 if (!(IS_ANDORNOT (tree)))
3415 /* if this an and */
3418 static int localLbl = 0;
3421 sprintf (buffer, "_and_%d", localLbl++);
3422 localLabel = newSymbol (buffer, NestLevel);
3424 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3426 /* if left is already a IFX then just change the if true label in that */
3427 if (!IS_IFX (tree->left))
3428 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3430 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3431 /* right is a IFX then just join */
3432 if (IS_IFX (tree->right))
3433 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3435 tree->right = createLabel (localLabel, tree->right);
3436 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3438 return newNode (NULLOP, tree->left, tree->right);
3441 /* if this is an or operation */
3444 static int localLbl = 0;
3447 sprintf (buffer, "_or_%d", localLbl++);
3448 localLabel = newSymbol (buffer, NestLevel);
3450 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3452 /* if left is already a IFX then just change the if true label in that */
3453 if (!IS_IFX (tree->left))
3454 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3456 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3457 /* right is a IFX then just join */
3458 if (IS_IFX (tree->right))
3459 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3461 tree->right = createLabel (localLabel, tree->right);
3462 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3464 return newNode (NULLOP, tree->left, tree->right);
3470 int wasnot = IS_NOT (tree->left);
3471 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3473 /* if the left is already a IFX */
3474 if (!IS_IFX (tree->left))
3475 tree->left = newNode (IFX, tree->left, NULL);
3479 tree->left->trueLabel = trueLabel;
3480 tree->left->falseLabel = falseLabel;
3484 tree->left->trueLabel = falseLabel;
3485 tree->left->falseLabel = trueLabel;
3492 tree->trueLabel = trueLabel;
3493 tree->falseLabel = falseLabel;
3500 /*-----------------------------------------------------------------*/
3501 /* createBlock - create expression tree for block */
3502 /*-----------------------------------------------------------------*/
3504 createBlock (symbol * decl, ast * body)
3508 /* if the block has nothing */
3512 ex = newNode (BLOCK, NULL, body);
3513 ex->values.sym = decl;
3515 ex->right = ex->right;
3521 /*-----------------------------------------------------------------*/
3522 /* createLabel - creates the expression tree for labels */
3523 /*-----------------------------------------------------------------*/
3525 createLabel (symbol * label, ast * stmnt)
3528 char name[SDCC_NAME_MAX + 1];
3531 /* must create fresh symbol if the symbol name */
3532 /* exists in the symbol table, since there can */
3533 /* be a variable with the same name as the labl */
3534 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3535 (csym->level == label->level))
3536 label = newSymbol (label->name, label->level);
3538 /* change the name before putting it in add _ */
3539 sprintf (name, "%s", label->name);
3541 /* put the label in the LabelSymbol table */
3542 /* but first check if a label of the same */
3544 if ((csym = findSym (LabelTab, NULL, name)))
3545 werror (E_DUPLICATE_LABEL, label->name);
3547 addSym (LabelTab, label, name, label->level, 0, 0);
3550 label->key = labelKey++;
3551 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3557 /*-----------------------------------------------------------------*/
3558 /* createCase - generates the parsetree for a case statement */
3559 /*-----------------------------------------------------------------*/
3561 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3563 char caseLbl[SDCC_NAME_MAX + 1];
3567 /* if the switch statement does not exist */
3568 /* then case is out of context */
3571 werror (E_CASE_CONTEXT);
3575 caseVal = decorateType (resolveSymbols (caseVal));
3576 /* if not a constant then error */
3577 if (!IS_LITERAL (caseVal->ftype))
3579 werror (E_CASE_CONSTANT);
3583 /* if not a integer than error */
3584 if (!IS_INTEGRAL (caseVal->ftype))
3586 werror (E_CASE_NON_INTEGER);
3590 /* find the end of the switch values chain */
3591 if (!(val = swStat->values.switchVals.swVals))
3592 swStat->values.switchVals.swVals = caseVal->opval.val;
3595 /* also order the cases according to value */
3597 int cVal = (int) floatFromVal (caseVal->opval.val);
3598 while (val && (int) floatFromVal (val) < cVal)
3604 /* if we reached the end then */
3607 pval->next = caseVal->opval.val;
3611 /* we found a value greater than */
3612 /* the current value we must add this */
3613 /* before the value */
3614 caseVal->opval.val->next = val;
3616 /* if this was the first in chain */
3617 if (swStat->values.switchVals.swVals == val)
3618 swStat->values.switchVals.swVals =
3621 pval->next = caseVal->opval.val;
3626 /* create the case label */
3627 sprintf (caseLbl, "_case_%d_%d",
3628 swStat->values.switchVals.swNum,
3629 (int) floatFromVal (caseVal->opval.val));
3631 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3636 /*-----------------------------------------------------------------*/
3637 /* createDefault - creates the parse tree for the default statement */
3638 /*-----------------------------------------------------------------*/
3640 createDefault (ast * swStat, ast * stmnt)
3642 char defLbl[SDCC_NAME_MAX + 1];
3644 /* if the switch statement does not exist */
3645 /* then case is out of context */
3648 werror (E_CASE_CONTEXT);
3652 /* turn on the default flag */
3653 swStat->values.switchVals.swDefault = 1;
3655 /* create the label */
3656 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3657 return createLabel (newSymbol (defLbl, 0), stmnt);
3660 /*-----------------------------------------------------------------*/
3661 /* createIf - creates the parsetree for the if statement */
3662 /*-----------------------------------------------------------------*/
3664 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3666 static int Lblnum = 0;
3668 symbol *ifTrue, *ifFalse, *ifEnd;
3670 /* if neither exists */
3671 if (!elseBody && !ifBody) {
3672 // if there are no side effects (i++, j() etc)
3673 if (!hasSEFcalls(condAst)) {
3678 /* create the labels */
3679 sprintf (buffer, "_iffalse_%d", Lblnum);
3680 ifFalse = newSymbol (buffer, NestLevel);
3681 /* if no else body then end == false */
3686 sprintf (buffer, "_ifend_%d", Lblnum);
3687 ifEnd = newSymbol (buffer, NestLevel);
3690 sprintf (buffer, "_iftrue_%d", Lblnum);
3691 ifTrue = newSymbol (buffer, NestLevel);
3695 /* attach the ifTrue label to the top of it body */
3696 ifBody = createLabel (ifTrue, ifBody);
3697 /* attach a goto end to the ifBody if else is present */
3700 ifBody = newNode (NULLOP, ifBody,
3702 newAst_VALUE (symbolVal (ifEnd)),
3704 /* put the elseLabel on the else body */
3705 elseBody = createLabel (ifFalse, elseBody);
3706 /* out the end at the end of the body */
3707 elseBody = newNode (NULLOP,
3709 createLabel (ifEnd, NULL));
3713 ifBody = newNode (NULLOP, ifBody,
3714 createLabel (ifFalse, NULL));
3716 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3717 if (IS_IFX (condAst))
3720 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3722 return newNode (NULLOP, ifTree,
3723 newNode (NULLOP, ifBody, elseBody));
3727 /*-----------------------------------------------------------------*/
3728 /* createDo - creates parse tree for do */
3731 /* _docontinue_n: */
3732 /* condition_expression +-> trueLabel -> _dobody_n */
3734 /* +-> falseLabel-> _dobreak_n */
3736 /*-----------------------------------------------------------------*/
3738 createDo (symbol * trueLabel, symbol * continueLabel,
3739 symbol * falseLabel, ast * condAst, ast * doBody)
3744 /* if the body does not exist then it is simple */
3747 condAst = backPatchLabels (condAst, continueLabel, NULL);
3748 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3749 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3750 doTree->trueLabel = continueLabel;
3751 doTree->falseLabel = NULL;
3755 /* otherwise we have a body */
3756 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3758 /* attach the body label to the top */
3759 doBody = createLabel (trueLabel, doBody);
3760 /* attach the continue label to end of body */
3761 doBody = newNode (NULLOP, doBody,
3762 createLabel (continueLabel, NULL));
3764 /* now put the break label at the end */
3765 if (IS_IFX (condAst))
3768 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3770 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3772 /* putting it together */
3773 return newNode (NULLOP, doBody, doTree);
3776 /*-----------------------------------------------------------------*/
3777 /* createFor - creates parse tree for 'for' statement */
3780 /* condExpr +-> trueLabel -> _forbody_n */
3782 /* +-> falseLabel-> _forbreak_n */
3785 /* _forcontinue_n: */
3787 /* goto _forcond_n ; */
3789 /*-----------------------------------------------------------------*/
3791 createFor (symbol * trueLabel, symbol * continueLabel,
3792 symbol * falseLabel, symbol * condLabel,
3793 ast * initExpr, ast * condExpr, ast * loopExpr,
3798 /* if loopexpression not present then we can generate it */
3799 /* the same way as a while */
3801 return newNode (NULLOP, initExpr,
3802 createWhile (trueLabel, continueLabel,
3803 falseLabel, condExpr, forBody));
3804 /* vanilla for statement */
3805 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3807 if (condExpr && !IS_IFX (condExpr))
3808 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3811 /* attach condition label to condition */
3812 condExpr = createLabel (condLabel, condExpr);
3814 /* attach body label to body */
3815 forBody = createLabel (trueLabel, forBody);
3817 /* attach continue to forLoop expression & attach */
3818 /* goto the forcond @ and of loopExpression */
3819 loopExpr = createLabel (continueLabel,
3823 newAst_VALUE (symbolVal (condLabel)),
3825 /* now start putting them together */
3826 forTree = newNode (NULLOP, initExpr, condExpr);
3827 forTree = newNode (NULLOP, forTree, forBody);
3828 forTree = newNode (NULLOP, forTree, loopExpr);
3829 /* finally add the break label */
3830 forTree = newNode (NULLOP, forTree,
3831 createLabel (falseLabel, NULL));
3835 /*-----------------------------------------------------------------*/
3836 /* createWhile - creates parse tree for while statement */
3837 /* the while statement will be created as follows */
3839 /* _while_continue_n: */
3840 /* condition_expression +-> trueLabel -> _while_boby_n */
3842 /* +-> falseLabel -> _while_break_n */
3843 /* _while_body_n: */
3845 /* goto _while_continue_n */
3846 /* _while_break_n: */
3847 /*-----------------------------------------------------------------*/
3849 createWhile (symbol * trueLabel, symbol * continueLabel,
3850 symbol * falseLabel, ast * condExpr, ast * whileBody)
3854 /* put the continue label */
3855 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3856 condExpr = createLabel (continueLabel, condExpr);
3857 condExpr->lineno = 0;
3859 /* put the body label in front of the body */
3860 whileBody = createLabel (trueLabel, whileBody);
3861 whileBody->lineno = 0;
3862 /* put a jump to continue at the end of the body */
3863 /* and put break label at the end of the body */
3864 whileBody = newNode (NULLOP,
3867 newAst_VALUE (symbolVal (continueLabel)),
3868 createLabel (falseLabel, NULL)));
3870 /* put it all together */
3871 if (IS_IFX (condExpr))
3872 whileTree = condExpr;
3875 whileTree = newNode (IFX, condExpr, NULL);
3876 /* put the true & false labels in place */
3877 whileTree->trueLabel = trueLabel;
3878 whileTree->falseLabel = falseLabel;
3881 return newNode (NULLOP, whileTree, whileBody);
3884 /*-----------------------------------------------------------------*/
3885 /* optimizeGetHbit - get highest order bit of the expression */
3886 /*-----------------------------------------------------------------*/
3888 optimizeGetHbit (ast * tree)
3891 /* if this is not a bit and */
3892 if (!IS_BITAND (tree))
3895 /* will look for tree of the form
3896 ( expr >> ((sizeof expr) -1) ) & 1 */
3897 if (!IS_AST_LIT_VALUE (tree->right))
3900 if (AST_LIT_VALUE (tree->right) != 1)
3903 if (!IS_RIGHT_OP (tree->left))
3906 if (!IS_AST_LIT_VALUE (tree->left->right))
3909 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3910 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3913 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3917 /*-----------------------------------------------------------------*/
3918 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3919 /*-----------------------------------------------------------------*/
3921 optimizeRRCRLC (ast * root)
3923 /* will look for trees of the form
3924 (?expr << 1) | (?expr >> 7) or
3925 (?expr >> 7) | (?expr << 1) will make that
3926 into a RLC : operation ..
3928 (?expr >> 1) | (?expr << 7) or
3929 (?expr << 7) | (?expr >> 1) will make that
3930 into a RRC operation
3931 note : by 7 I mean (number of bits required to hold the
3933 /* if the root operations is not a | operation the not */
3934 if (!IS_BITOR (root))
3937 /* I have to think of a better way to match patterns this sucks */
3938 /* that aside let start looking for the first case : I use a the
3939 negative check a lot to improve the efficiency */
3940 /* (?expr << 1) | (?expr >> 7) */
3941 if (IS_LEFT_OP (root->left) &&
3942 IS_RIGHT_OP (root->right))
3945 if (!SPEC_USIGN (TETYPE (root->left->left)))
3948 if (!IS_AST_LIT_VALUE (root->left->right) ||
3949 !IS_AST_LIT_VALUE (root->right->right))
3952 /* make sure it is the same expression */
3953 if (!isAstEqual (root->left->left,
3957 if (AST_LIT_VALUE (root->left->right) != 1)
3960 if (AST_LIT_VALUE (root->right->right) !=
3961 (getSize (TTYPE (root->left->left)) * 8 - 1))
3964 /* whew got the first case : create the AST */
3965 return newNode (RLC, root->left->left, NULL);
3969 /* check for second case */
3970 /* (?expr >> 7) | (?expr << 1) */
3971 if (IS_LEFT_OP (root->right) &&
3972 IS_RIGHT_OP (root->left))
3975 if (!SPEC_USIGN (TETYPE (root->left->left)))
3978 if (!IS_AST_LIT_VALUE (root->left->right) ||
3979 !IS_AST_LIT_VALUE (root->right->right))
3982 /* make sure it is the same symbol */
3983 if (!isAstEqual (root->left->left,
3987 if (AST_LIT_VALUE (root->right->right) != 1)
3990 if (AST_LIT_VALUE (root->left->right) !=
3991 (getSize (TTYPE (root->left->left)) * 8 - 1))
3994 /* whew got the first case : create the AST */
3995 return newNode (RLC, root->left->left, NULL);
4000 /* third case for RRC */
4001 /* (?symbol >> 1) | (?symbol << 7) */
4002 if (IS_LEFT_OP (root->right) &&
4003 IS_RIGHT_OP (root->left))
4006 if (!SPEC_USIGN (TETYPE (root->left->left)))
4009 if (!IS_AST_LIT_VALUE (root->left->right) ||
4010 !IS_AST_LIT_VALUE (root->right->right))
4013 /* make sure it is the same symbol */
4014 if (!isAstEqual (root->left->left,
4018 if (AST_LIT_VALUE (root->left->right) != 1)
4021 if (AST_LIT_VALUE (root->right->right) !=
4022 (getSize (TTYPE (root->left->left)) * 8 - 1))
4025 /* whew got the first case : create the AST */
4026 return newNode (RRC, root->left->left, NULL);
4030 /* fourth and last case for now */
4031 /* (?symbol << 7) | (?symbol >> 1) */
4032 if (IS_RIGHT_OP (root->right) &&
4033 IS_LEFT_OP (root->left))
4036 if (!SPEC_USIGN (TETYPE (root->left->left)))
4039 if (!IS_AST_LIT_VALUE (root->left->right) ||
4040 !IS_AST_LIT_VALUE (root->right->right))
4043 /* make sure it is the same symbol */
4044 if (!isAstEqual (root->left->left,
4048 if (AST_LIT_VALUE (root->right->right) != 1)
4051 if (AST_LIT_VALUE (root->left->right) !=
4052 (getSize (TTYPE (root->left->left)) * 8 - 1))
4055 /* whew got the first case : create the AST */
4056 return newNode (RRC, root->left->left, NULL);
4060 /* not found return root */
4064 /*-----------------------------------------------------------------*/
4065 /* optimizeCompare - otimizes compares for bit variables */
4066 /*-----------------------------------------------------------------*/
4068 optimizeCompare (ast * root)
4070 ast *optExpr = NULL;
4073 unsigned int litValue;
4075 /* if nothing then return nothing */
4079 /* if not a compare op then do leaves */
4080 if (!IS_COMPARE_OP (root))
4082 root->left = optimizeCompare (root->left);
4083 root->right = optimizeCompare (root->right);
4087 /* if left & right are the same then depending
4088 of the operation do */
4089 if (isAstEqual (root->left, root->right))
4091 switch (root->opval.op)
4096 optExpr = newAst_VALUE (constVal ("0"));
4101 optExpr = newAst_VALUE (constVal ("1"));
4105 return decorateType (optExpr);
4108 vleft = (root->left->type == EX_VALUE ?
4109 root->left->opval.val : NULL);
4111 vright = (root->right->type == EX_VALUE ?
4112 root->right->opval.val : NULL);
4114 /* if left is a BITVAR in BITSPACE */
4115 /* and right is a LITERAL then opt- */
4116 /* imize else do nothing */
4117 if (vleft && vright &&
4118 IS_BITVAR (vleft->etype) &&
4119 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4120 IS_LITERAL (vright->etype))
4123 /* if right side > 1 then comparison may never succeed */
4124 if ((litValue = (int) floatFromVal (vright)) > 1)
4126 werror (W_BAD_COMPARE);
4132 switch (root->opval.op)
4134 case '>': /* bit value greater than 1 cannot be */
4135 werror (W_BAD_COMPARE);
4139 case '<': /* bit value < 1 means 0 */
4141 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4144 case LE_OP: /* bit value <= 1 means no check */
4145 optExpr = newAst_VALUE (vright);
4148 case GE_OP: /* bit value >= 1 means only check for = */
4150 optExpr = newAst_VALUE (vleft);
4155 { /* literal is zero */
4156 switch (root->opval.op)
4158 case '<': /* bit value < 0 cannot be */
4159 werror (W_BAD_COMPARE);
4163 case '>': /* bit value > 0 means 1 */
4165 optExpr = newAst_VALUE (vleft);
4168 case LE_OP: /* bit value <= 0 means no check */
4169 case GE_OP: /* bit value >= 0 means no check */
4170 werror (W_BAD_COMPARE);
4174 case EQ_OP: /* bit == 0 means ! of bit */
4175 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4179 return decorateType (resolveSymbols (optExpr));
4180 } /* end-of-if of BITVAR */
4185 /*-----------------------------------------------------------------*/
4186 /* addSymToBlock : adds the symbol to the first block we find */
4187 /*-----------------------------------------------------------------*/
4189 addSymToBlock (symbol * sym, ast * tree)
4191 /* reached end of tree or a leaf */
4192 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4196 if (IS_AST_OP (tree) &&
4197 tree->opval.op == BLOCK)
4200 symbol *lsym = copySymbol (sym);
4202 lsym->next = AST_VALUES (tree, sym);
4203 AST_VALUES (tree, sym) = lsym;
4207 addSymToBlock (sym, tree->left);
4208 addSymToBlock (sym, tree->right);
4211 /*-----------------------------------------------------------------*/
4212 /* processRegParms - do processing for register parameters */
4213 /*-----------------------------------------------------------------*/
4215 processRegParms (value * args, ast * body)
4219 if (IS_REGPARM (args->etype))
4220 addSymToBlock (args->sym, body);
4225 /*-----------------------------------------------------------------*/
4226 /* resetParmKey - resets the operandkeys for the symbols */
4227 /*-----------------------------------------------------------------*/
4228 DEFSETFUNC (resetParmKey)
4239 /*-----------------------------------------------------------------*/
4240 /* createFunction - This is the key node that calls the iCode for */
4241 /* generating the code for a function. Note code */
4242 /* is generated function by function, later when */
4243 /* add inter-procedural analysis this will change */
4244 /*-----------------------------------------------------------------*/
4246 createFunction (symbol * name, ast * body)
4252 iCode *piCode = NULL;
4254 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4255 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4257 /* if check function return 0 then some problem */
4258 if (checkFunction (name, NULL) == 0)
4261 /* create a dummy block if none exists */
4263 body = newNode (BLOCK, NULL, NULL);
4267 /* check if the function name already in the symbol table */
4268 if ((csym = findSym (SymbolTab, NULL, name->name)))
4271 /* special case for compiler defined functions
4272 we need to add the name to the publics list : this
4273 actually means we are now compiling the compiler
4277 addSet (&publics, name);
4283 allocVariables (name);
4285 name->lastLine = yylineno;
4288 /* set the stack pointer */
4289 /* PENDING: check this for the mcs51 */
4290 stackPtr = -port->stack.direction * port->stack.call_overhead;
4291 if (IFFUNC_ISISR (name->type))
4292 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4293 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4294 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4296 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4298 fetype = getSpec (name->type); /* get the specifier for the function */
4299 /* if this is a reentrant function then */
4300 if (IFFUNC_ISREENT (name->type))
4303 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4305 /* do processing for parameters that are passed in registers */
4306 processRegParms (FUNC_ARGS(name->type), body);
4308 /* set the stack pointer */
4312 /* allocate & autoinit the block variables */
4313 processBlockVars (body, &stack, ALLOCATE);
4315 /* save the stack information */
4316 if (options.useXstack)
4317 name->xstack = SPEC_STAK (fetype) = stack;
4319 name->stack = SPEC_STAK (fetype) = stack;
4321 /* name needs to be mangled */
4322 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4324 body = resolveSymbols (body); /* resolve the symbols */
4325 body = decorateType (body); /* propagateType & do semantic checks */
4327 ex = newAst_VALUE (symbolVal (name)); /* create name */
4328 ex = newNode (FUNCTION, ex, body);
4329 ex->values.args = FUNC_ARGS(name->type);
4331 if (options.dump_tree) PA(ex);
4334 werror (E_FUNC_NO_CODE, name->name);
4338 /* create the node & generate intermediate code */
4340 codeOutFile = code->oFile;
4341 piCode = iCodeFromAst (ex);
4345 werror (E_FUNC_NO_CODE, name->name);
4349 eBBlockFromiCode (piCode);
4351 /* if there are any statics then do them */
4354 GcurMemmap = statsg;
4355 codeOutFile = statsg->oFile;
4356 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4362 /* dealloc the block variables */
4363 processBlockVars (body, &stack, DEALLOCATE);
4364 /* deallocate paramaters */
4365 deallocParms (FUNC_ARGS(name->type));
4367 if (IFFUNC_ISREENT (name->type))
4370 /* we are done freeup memory & cleanup */
4372 if (port->reset_labelKey) labelKey = 1;
4374 FUNC_HASBODY(name->type) = 1;
4375 addSet (&operKeyReset, name);
4376 applyToSet (operKeyReset, resetParmKey);
4379 cdbStructBlock (1, cdbFile);
4381 cleanUpLevel (LabelTab, 0);
4382 cleanUpBlock (StructTab, 1);
4383 cleanUpBlock (TypedefTab, 1);
4385 xstack->syms = NULL;
4386 istack->syms = NULL;
4391 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4392 /*-----------------------------------------------------------------*/
4393 /* ast_print : prints the ast (for debugging purposes) */
4394 /*-----------------------------------------------------------------*/
4396 void ast_print (ast * tree, FILE *outfile, int indent)
4401 /* can print only decorated trees */
4402 if (!tree->decorated) return;
4404 /* if any child is an error | this one is an error do nothing */
4405 if (tree->isError ||
4406 (tree->left && tree->left->isError) ||
4407 (tree->right && tree->right->isError)) {
4408 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4412 /* print the line */
4413 /* if not block & function */
4414 if (tree->type == EX_OP &&
4415 (tree->opval.op != FUNCTION &&
4416 tree->opval.op != BLOCK &&
4417 tree->opval.op != NULLOP)) {
4420 if (tree->opval.op == FUNCTION) {
4422 value *args=FUNC_ARGS(tree->left->opval.val->type);
4423 fprintf(outfile,"FUNCTION (%s=%p) type (",
4424 tree->left->opval.val->name, tree);
4425 printTypeChain (tree->ftype,outfile);
4426 fprintf(outfile,") args (");
4429 fprintf (outfile, ", ");
4431 printTypeChain (args ? args->type : NULL, outfile);
4433 args= args ? args->next : NULL;
4435 fprintf(outfile,")\n");
4436 ast_print(tree->left,outfile,indent);
4437 ast_print(tree->right,outfile,indent);
4440 if (tree->opval.op == BLOCK) {
4441 symbol *decls = tree->values.sym;
4442 INDENT(indent,outfile);
4443 fprintf(outfile,"{\n");
4445 INDENT(indent+2,outfile);
4446 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4447 decls->name, decls);
4448 printTypeChain(decls->type,outfile);
4449 fprintf(outfile,")\n");
4451 decls = decls->next;
4453 ast_print(tree->right,outfile,indent+2);
4454 INDENT(indent,outfile);
4455 fprintf(outfile,"}\n");
4458 if (tree->opval.op == NULLOP) {
4459 fprintf(outfile,"\n");
4460 ast_print(tree->left,outfile,indent);
4461 fprintf(outfile,"\n");
4462 ast_print(tree->right,outfile,indent);
4465 INDENT(indent,outfile);
4467 /*------------------------------------------------------------------*/
4468 /*----------------------------*/
4469 /* leaf has been reached */
4470 /*----------------------------*/
4471 /* if this is of type value */
4472 /* just get the type */
4473 if (tree->type == EX_VALUE) {
4475 if (IS_LITERAL (tree->opval.val->etype)) {
4476 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4477 (int) floatFromVal(tree->opval.val),
4478 (int) floatFromVal(tree->opval.val),
4479 floatFromVal(tree->opval.val));
4480 } else if (tree->opval.val->sym) {
4481 /* if the undefined flag is set then give error message */
4482 if (tree->opval.val->sym->undefined) {
4483 fprintf(outfile,"UNDEFINED SYMBOL ");
4485 fprintf(outfile,"SYMBOL ");
4487 fprintf(outfile,"(%s=%p)",
4488 tree->opval.val->sym->name,tree);
4491 fprintf(outfile," type (");
4492 printTypeChain(tree->ftype,outfile);
4493 fprintf(outfile,")\n");
4495 fprintf(outfile,"\n");
4500 /* if type link for the case of cast */
4501 if (tree->type == EX_LINK) {
4502 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4503 printTypeChain(tree->opval.lnk,outfile);
4504 fprintf(outfile,")\n");
4509 /* depending on type of operator do */
4511 switch (tree->opval.op) {
4512 /*------------------------------------------------------------------*/
4513 /*----------------------------*/
4515 /*----------------------------*/
4517 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4518 printTypeChain(tree->ftype,outfile);
4519 fprintf(outfile,")\n");
4520 ast_print(tree->left,outfile,indent+2);
4521 ast_print(tree->right,outfile,indent+2);
4524 /*------------------------------------------------------------------*/
4525 /*----------------------------*/
4527 /*----------------------------*/
4529 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4530 printTypeChain(tree->ftype,outfile);
4531 fprintf(outfile,")\n");
4532 ast_print(tree->left,outfile,indent+2);
4533 ast_print(tree->right,outfile,indent+2);
4536 /*------------------------------------------------------------------*/
4537 /*----------------------------*/
4538 /* struct/union pointer */
4539 /*----------------------------*/
4541 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4542 printTypeChain(tree->ftype,outfile);
4543 fprintf(outfile,")\n");
4544 ast_print(tree->left,outfile,indent+2);
4545 ast_print(tree->right,outfile,indent+2);
4548 /*------------------------------------------------------------------*/
4549 /*----------------------------*/
4550 /* ++/-- operation */
4551 /*----------------------------*/
4552 case INC_OP: /* incerement operator unary so left only */
4553 fprintf(outfile,"INC_OP (%p) type (",tree);
4554 printTypeChain(tree->ftype,outfile);
4555 fprintf(outfile,")\n");
4556 ast_print(tree->left,outfile,indent+2);
4560 fprintf(outfile,"DEC_OP (%p) type (",tree);
4561 printTypeChain(tree->ftype,outfile);
4562 fprintf(outfile,")\n");
4563 ast_print(tree->left,outfile,indent+2);
4566 /*------------------------------------------------------------------*/
4567 /*----------------------------*/
4569 /*----------------------------*/
4572 fprintf(outfile,"& (%p) type (",tree);
4573 printTypeChain(tree->ftype,outfile);
4574 fprintf(outfile,")\n");
4575 ast_print(tree->left,outfile,indent+2);
4576 ast_print(tree->right,outfile,indent+2);
4578 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+2);
4582 ast_print(tree->right,outfile,indent+2);
4585 /*----------------------------*/
4587 /*----------------------------*/
4589 fprintf(outfile,"OR (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->left,outfile,indent+2);
4593 ast_print(tree->right,outfile,indent+2);
4595 /*------------------------------------------------------------------*/
4596 /*----------------------------*/
4598 /*----------------------------*/
4600 fprintf(outfile,"XOR (%p) type (",tree);
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->left,outfile,indent+2);
4604 ast_print(tree->right,outfile,indent+2);
4607 /*------------------------------------------------------------------*/
4608 /*----------------------------*/
4610 /*----------------------------*/
4612 fprintf(outfile,"DIV (%p) type (",tree);
4613 printTypeChain(tree->ftype,outfile);
4614 fprintf(outfile,")\n");
4615 ast_print(tree->left,outfile,indent+2);
4616 ast_print(tree->right,outfile,indent+2);
4618 /*------------------------------------------------------------------*/
4619 /*----------------------------*/
4621 /*----------------------------*/
4623 fprintf(outfile,"MOD (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+2);
4627 ast_print(tree->right,outfile,indent+2);
4630 /*------------------------------------------------------------------*/
4631 /*----------------------------*/
4632 /* address dereference */
4633 /*----------------------------*/
4634 case '*': /* can be unary : if right is null then unary operation */
4636 fprintf(outfile,"DEREF (%p) type (",tree);
4637 printTypeChain(tree->ftype,outfile);
4638 fprintf(outfile,")\n");
4639 ast_print(tree->left,outfile,indent+2);
4642 /*------------------------------------------------------------------*/
4643 /*----------------------------*/
4644 /* multiplication */
4645 /*----------------------------*/
4646 fprintf(outfile,"MULT (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+2);
4650 ast_print(tree->right,outfile,indent+2);
4654 /*------------------------------------------------------------------*/
4655 /*----------------------------*/
4656 /* unary '+' operator */
4657 /*----------------------------*/
4661 fprintf(outfile,"UPLUS (%p) type (",tree);
4662 printTypeChain(tree->ftype,outfile);
4663 fprintf(outfile,")\n");
4664 ast_print(tree->left,outfile,indent+2);
4666 /*------------------------------------------------------------------*/
4667 /*----------------------------*/
4669 /*----------------------------*/
4670 fprintf(outfile,"ADD (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+2);
4674 ast_print(tree->right,outfile,indent+2);
4677 /*------------------------------------------------------------------*/
4678 /*----------------------------*/
4680 /*----------------------------*/
4681 case '-': /* can be unary */
4683 fprintf(outfile,"UMINUS (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+2);
4688 /*------------------------------------------------------------------*/
4689 /*----------------------------*/
4691 /*----------------------------*/
4692 fprintf(outfile,"SUB (%p) type (",tree);
4693 printTypeChain(tree->ftype,outfile);
4694 fprintf(outfile,")\n");
4695 ast_print(tree->left,outfile,indent+2);
4696 ast_print(tree->right,outfile,indent+2);
4699 /*------------------------------------------------------------------*/
4700 /*----------------------------*/
4702 /*----------------------------*/
4704 fprintf(outfile,"COMPL (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+2);
4709 /*------------------------------------------------------------------*/
4710 /*----------------------------*/
4712 /*----------------------------*/
4714 fprintf(outfile,"NOT (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+2);
4719 /*------------------------------------------------------------------*/
4720 /*----------------------------*/
4722 /*----------------------------*/
4724 fprintf(outfile,"RRC (%p) type (",tree);
4725 printTypeChain(tree->ftype,outfile);
4726 fprintf(outfile,")\n");
4727 ast_print(tree->left,outfile,indent+2);
4731 fprintf(outfile,"RLC (%p) type (",tree);
4732 printTypeChain(tree->ftype,outfile);
4733 fprintf(outfile,")\n");
4734 ast_print(tree->left,outfile,indent+2);
4737 fprintf(outfile,"GETHBIT (%p) type (",tree);
4738 printTypeChain(tree->ftype,outfile);
4739 fprintf(outfile,")\n");
4740 ast_print(tree->left,outfile,indent+2);
4743 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4744 printTypeChain(tree->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->left,outfile,indent+2);
4747 ast_print(tree->right,outfile,indent+2);
4750 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4751 printTypeChain(tree->ftype,outfile);
4752 fprintf(outfile,")\n");
4753 ast_print(tree->left,outfile,indent+2);
4754 ast_print(tree->right,outfile,indent+2);
4756 /*------------------------------------------------------------------*/
4757 /*----------------------------*/
4759 /*----------------------------*/
4760 case CAST: /* change the type */
4761 fprintf(outfile,"CAST (%p) from type (",tree);
4762 printTypeChain(tree->right->ftype,outfile);
4763 fprintf(outfile,") to type (");
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->right,outfile,indent+2);
4770 fprintf(outfile,"ANDAND (%p) type (",tree);
4771 printTypeChain(tree->ftype,outfile);
4772 fprintf(outfile,")\n");
4773 ast_print(tree->left,outfile,indent+2);
4774 ast_print(tree->right,outfile,indent+2);
4777 fprintf(outfile,"OROR (%p) type (",tree);
4778 printTypeChain(tree->ftype,outfile);
4779 fprintf(outfile,")\n");
4780 ast_print(tree->left,outfile,indent+2);
4781 ast_print(tree->right,outfile,indent+2);
4784 /*------------------------------------------------------------------*/
4785 /*----------------------------*/
4786 /* comparison operators */
4787 /*----------------------------*/
4789 fprintf(outfile,"GT(>) (%p) type (",tree);
4790 printTypeChain(tree->ftype,outfile);
4791 fprintf(outfile,")\n");
4792 ast_print(tree->left,outfile,indent+2);
4793 ast_print(tree->right,outfile,indent+2);
4796 fprintf(outfile,"LT(<) (%p) type (",tree);
4797 printTypeChain(tree->ftype,outfile);
4798 fprintf(outfile,")\n");
4799 ast_print(tree->left,outfile,indent+2);
4800 ast_print(tree->right,outfile,indent+2);
4803 fprintf(outfile,"LE(<=) (%p) type (",tree);
4804 printTypeChain(tree->ftype,outfile);
4805 fprintf(outfile,")\n");
4806 ast_print(tree->left,outfile,indent+2);
4807 ast_print(tree->right,outfile,indent+2);
4810 fprintf(outfile,"GE(>=) (%p) type (",tree);
4811 printTypeChain(tree->ftype,outfile);
4812 fprintf(outfile,")\n");
4813 ast_print(tree->left,outfile,indent+2);
4814 ast_print(tree->right,outfile,indent+2);
4817 fprintf(outfile,"EQ(==) (%p) type (",tree);
4818 printTypeChain(tree->ftype,outfile);
4819 fprintf(outfile,")\n");
4820 ast_print(tree->left,outfile,indent+2);
4821 ast_print(tree->right,outfile,indent+2);
4824 fprintf(outfile,"NE(!=) (%p) type (",tree);
4825 printTypeChain(tree->ftype,outfile);
4826 fprintf(outfile,")\n");
4827 ast_print(tree->left,outfile,indent+2);
4828 ast_print(tree->right,outfile,indent+2);
4829 /*------------------------------------------------------------------*/
4830 /*----------------------------*/
4832 /*----------------------------*/
4833 case SIZEOF: /* evaluate wihout code generation */
4834 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4837 /*------------------------------------------------------------------*/
4838 /*----------------------------*/
4839 /* conditional operator '?' */
4840 /*----------------------------*/
4842 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4843 printTypeChain(tree->ftype,outfile);
4844 fprintf(outfile,")\n");
4845 ast_print(tree->left,outfile,indent+2);
4846 ast_print(tree->right,outfile,indent+2);
4850 fprintf(outfile,"COLON(:) (%p) type (",tree);
4851 printTypeChain(tree->ftype,outfile);
4852 fprintf(outfile,")\n");
4853 ast_print(tree->left,outfile,indent+2);
4854 ast_print(tree->right,outfile,indent+2);
4857 /*------------------------------------------------------------------*/
4858 /*----------------------------*/
4859 /* assignment operators */
4860 /*----------------------------*/
4862 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4863 printTypeChain(tree->ftype,outfile);
4864 fprintf(outfile,")\n");
4865 ast_print(tree->left,outfile,indent+2);
4866 ast_print(tree->right,outfile,indent+2);
4869 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4870 printTypeChain(tree->ftype,outfile);
4871 fprintf(outfile,")\n");
4872 ast_print(tree->left,outfile,indent+2);
4873 ast_print(tree->right,outfile,indent+2);
4876 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4877 printTypeChain(tree->ftype,outfile);
4878 fprintf(outfile,")\n");
4879 ast_print(tree->left,outfile,indent+2);
4880 ast_print(tree->right,outfile,indent+2);
4883 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4884 printTypeChain(tree->ftype,outfile);
4885 fprintf(outfile,")\n");
4886 ast_print(tree->left,outfile,indent+2);
4887 ast_print(tree->right,outfile,indent+2);
4890 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4891 printTypeChain(tree->ftype,outfile);
4892 fprintf(outfile,")\n");
4893 ast_print(tree->left,outfile,indent+2);
4894 ast_print(tree->right,outfile,indent+2);
4897 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4898 printTypeChain(tree->ftype,outfile);
4899 fprintf(outfile,")\n");
4900 ast_print(tree->left,outfile,indent+2);
4901 ast_print(tree->right,outfile,indent+2);
4904 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4905 printTypeChain(tree->ftype,outfile);
4906 fprintf(outfile,")\n");
4907 ast_print(tree->left,outfile,indent+2);
4908 ast_print(tree->right,outfile,indent+2);
4910 /*------------------------------------------------------------------*/
4911 /*----------------------------*/
4913 /*----------------------------*/
4915 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4916 printTypeChain(tree->ftype,outfile);
4917 fprintf(outfile,")\n");
4918 ast_print(tree->left,outfile,indent+2);
4919 ast_print(tree->right,outfile,indent+2);
4921 /*------------------------------------------------------------------*/
4922 /*----------------------------*/
4924 /*----------------------------*/
4926 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4927 printTypeChain(tree->ftype,outfile);
4928 fprintf(outfile,")\n");
4929 ast_print(tree->left,outfile,indent+2);
4930 ast_print(tree->right,outfile,indent+2);
4932 /*------------------------------------------------------------------*/
4933 /*----------------------------*/
4934 /* straight assignemnt */
4935 /*----------------------------*/
4937 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4938 printTypeChain(tree->ftype,outfile);
4939 fprintf(outfile,")\n");
4940 ast_print(tree->left,outfile,indent+2);
4941 ast_print(tree->right,outfile,indent+2);
4943 /*------------------------------------------------------------------*/
4944 /*----------------------------*/
4945 /* comma operator */
4946 /*----------------------------*/
4948 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4949 printTypeChain(tree->ftype,outfile);
4950 fprintf(outfile,")\n");
4951 ast_print(tree->left,outfile,indent+2);
4952 ast_print(tree->right,outfile,indent+2);
4954 /*------------------------------------------------------------------*/
4955 /*----------------------------*/
4957 /*----------------------------*/
4960 fprintf(outfile,"CALL (%p) type (",tree);
4961 printTypeChain(tree->ftype,outfile);
4962 fprintf(outfile,")\n");
4963 ast_print(tree->left,outfile,indent+2);
4964 ast_print(tree->right,outfile,indent+2);
4967 fprintf(outfile,"PARMS\n");
4968 ast_print(tree->left,outfile,indent+2);
4969 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4970 ast_print(tree->right,outfile,indent+2);
4973 /*------------------------------------------------------------------*/
4974 /*----------------------------*/
4975 /* return statement */
4976 /*----------------------------*/
4978 fprintf(outfile,"RETURN (%p) type (",tree);
4980 printTypeChain(tree->right->ftype,outfile);
4982 fprintf(outfile,")\n");
4983 ast_print(tree->right,outfile,indent+2);
4985 /*------------------------------------------------------------------*/
4986 /*----------------------------*/
4987 /* label statement */
4988 /*----------------------------*/
4990 fprintf(outfile,"LABEL (%p)\n",tree);
4991 ast_print(tree->left,outfile,indent+2);
4992 ast_print(tree->right,outfile,indent);
4994 /*------------------------------------------------------------------*/
4995 /*----------------------------*/
4996 /* switch statement */
4997 /*----------------------------*/
5001 fprintf(outfile,"SWITCH (%p) ",tree);
5002 ast_print(tree->left,outfile,0);
5003 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5004 INDENT(indent+2,outfile);
5005 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5006 (int) floatFromVal(val),
5007 tree->values.switchVals.swNum,
5008 (int) floatFromVal(val));
5010 ast_print(tree->right,outfile,indent);
5013 /*------------------------------------------------------------------*/
5014 /*----------------------------*/
5016 /*----------------------------*/
5018 fprintf(outfile,"IF (%p) \n",tree);
5019 ast_print(tree->left,outfile,indent+2);
5020 if (tree->trueLabel) {
5021 INDENT(indent,outfile);
5022 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5024 if (tree->falseLabel) {
5025 INDENT(indent,outfile);
5026 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5028 ast_print(tree->right,outfile,indent+2);
5030 /*------------------------------------------------------------------*/
5031 /*----------------------------*/
5033 /*----------------------------*/
5035 fprintf(outfile,"FOR (%p) \n",tree);
5036 if (AST_FOR( tree, initExpr)) {
5037 INDENT(indent+2,outfile);
5038 fprintf(outfile,"INIT EXPR ");
5039 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5041 if (AST_FOR( tree, condExpr)) {
5042 INDENT(indent+2,outfile);
5043 fprintf(outfile,"COND EXPR ");
5044 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5046 if (AST_FOR( tree, loopExpr)) {
5047 INDENT(indent+2,outfile);
5048 fprintf(outfile,"LOOP EXPR ");
5049 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5051 fprintf(outfile,"FOR LOOP BODY \n");
5052 ast_print(tree->left,outfile,indent+2);
5061 ast_print(t,stdout,0);