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
970 freeStringSymbol(AST_SYMBOL(iexpr));
972 return decorateType (resolveSymbols (rast));
978 /*-----------------------------------------------------------------*/
979 /* createIvalPtr - generates initial value for pointers */
980 /*-----------------------------------------------------------------*/
982 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
988 if (ilist->type == INIT_DEEP)
989 ilist = ilist->init.deep;
991 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
993 /* if character pointer */
994 if (IS_CHAR (type->next))
995 if ((rast = createIvalCharPtr (sym, type, iexpr)))
998 return newNode ('=', sym, iexpr);
1001 /*-----------------------------------------------------------------*/
1002 /* createIval - generates code for initial value */
1003 /*-----------------------------------------------------------------*/
1005 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1012 /* if structure then */
1013 if (IS_STRUCT (type))
1014 rast = createIvalStruct (sym, type, ilist);
1016 /* if this is a pointer */
1018 rast = createIvalPtr (sym, type, ilist);
1020 /* if this is an array */
1021 if (IS_ARRAY (type))
1022 rast = createIvalArray (sym, type, ilist);
1024 /* if type is SPECIFIER */
1026 rast = createIvalType (sym, type, ilist);
1029 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1031 return decorateType (resolveSymbols (rast));
1034 /*-----------------------------------------------------------------*/
1035 /* initAggregates - initialises aggregate variables with initv */
1036 /*-----------------------------------------------------------------*/
1037 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1038 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1041 /*-----------------------------------------------------------------*/
1042 /* gatherAutoInit - creates assignment expressions for initial */
1044 /*-----------------------------------------------------------------*/
1046 gatherAutoInit (symbol * autoChain)
1053 for (sym = autoChain; sym; sym = sym->next)
1056 /* resolve the symbols in the ival */
1058 resolveIvalSym (sym->ival);
1060 /* if this is a static variable & has an */
1061 /* initial value the code needs to be lifted */
1062 /* here to the main portion since they can be */
1063 /* initialised only once at the start */
1064 if (IS_STATIC (sym->etype) && sym->ival &&
1065 SPEC_SCLS (sym->etype) != S_CODE)
1069 /* insert the symbol into the symbol table */
1070 /* with level = 0 & name = rname */
1071 newSym = copySymbol (sym);
1072 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1074 /* now lift the code to main */
1075 if (IS_AGGREGATE (sym->type)) {
1076 work = initAggregates (sym, sym->ival, NULL);
1078 if (getNelements(sym->type, sym->ival)>1) {
1079 werror (W_EXCESS_INITIALIZERS, "scalar",
1080 sym->name, sym->lineDef);
1082 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1083 list2expr (sym->ival));
1086 setAstLineno (work, sym->lineDef);
1090 staticAutos = newNode (NULLOP, staticAutos, work);
1097 /* if there is an initial value */
1098 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1100 initList *ilist=sym->ival;
1102 while (ilist->type == INIT_DEEP) {
1103 ilist = ilist->init.deep;
1106 /* update lineno for error msg */
1107 lineno=sym->lineDef;
1108 setAstLineno (ilist->init.node, lineno);
1110 if (IS_AGGREGATE (sym->type)) {
1111 work = initAggregates (sym, sym->ival, NULL);
1113 if (getNelements(sym->type, sym->ival)>1) {
1114 werror (W_EXCESS_INITIALIZERS, "scalar",
1115 sym->name, sym->lineDef);
1117 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1118 list2expr (sym->ival));
1122 setAstLineno (work, sym->lineDef);
1126 init = newNode (NULLOP, init, work);
1135 /*-----------------------------------------------------------------*/
1136 /* freeStringSymbol - delete a literal string if no more usage */
1137 /*-----------------------------------------------------------------*/
1138 void freeStringSymbol(symbol *sym) {
1139 /* make sure this is a literal string */
1140 assert (sym->isstrlit);
1141 if (--sym->isstrlit == 0) { // lower the usage count
1142 memmap *segment=SPEC_OCLS(sym->etype);
1144 deleteSetItem(&segment->syms, sym);
1149 /*-----------------------------------------------------------------*/
1150 /* stringToSymbol - creates a symbol from a literal string */
1151 /*-----------------------------------------------------------------*/
1153 stringToSymbol (value * val)
1155 char name[SDCC_NAME_MAX + 1];
1156 static int charLbl = 0;
1160 // have we heard this before?
1161 for (sp=statsg->syms; sp; sp=sp->next) {
1163 if (sym->isstrlit &&
1164 !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
1165 // yes, this is old news. Don't publish it again.
1166 sym->isstrlit++; // but raise the usage count
1167 return symbolVal(sym);
1171 sprintf (name, "_str_%d", charLbl++);
1172 sym = newSymbol (name, 0); /* make it @ level 0 */
1173 strcpy (sym->rname, name);
1175 /* copy the type from the value passed */
1176 sym->type = copyLinkChain (val->type);
1177 sym->etype = getSpec (sym->type);
1178 /* change to storage class & output class */
1179 SPEC_SCLS (sym->etype) = S_CODE;
1180 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1181 SPEC_STAT (sym->etype) = 1;
1182 /* make the level & block = 0 */
1183 sym->block = sym->level = 0;
1185 /* create an ival */
1186 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1191 allocVariables (sym);
1194 return symbolVal (sym);
1198 /*-----------------------------------------------------------------*/
1199 /* processBlockVars - will go thru the ast looking for block if */
1200 /* a block is found then will allocate the syms */
1201 /* will also gather the auto inits present */
1202 /*-----------------------------------------------------------------*/
1204 processBlockVars (ast * tree, int *stack, int action)
1209 /* if this is a block */
1210 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1214 if (action == ALLOCATE)
1216 *stack += allocVariables (tree->values.sym);
1217 autoInit = gatherAutoInit (tree->values.sym);
1219 /* if there are auto inits then do them */
1221 tree->left = newNode (NULLOP, autoInit, tree->left);
1223 else /* action is deallocate */
1224 deallocLocal (tree->values.sym);
1227 processBlockVars (tree->left, stack, action);
1228 processBlockVars (tree->right, stack, action);
1232 /*-------------------------------------------------------------*/
1233 /* constExprTree - returns TRUE if this tree is a constant */
1235 /*-------------------------------------------------------------*/
1236 bool constExprTree (ast *cexpr) {
1242 cexpr = decorateType (resolveSymbols (cexpr));
1244 switch (cexpr->type)
1247 if (IS_AST_LIT_VALUE(cexpr)) {
1248 // this is a literal
1251 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1252 // a function's address will never change
1255 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1256 // an array's address will never change
1259 if (IS_AST_SYM_VALUE(cexpr) &&
1260 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1261 // a symbol in code space will never change
1262 // This is only for the 'char *s="hallo"' case and will have to leave
1267 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1268 "unexpected link in expression tree\n");
1271 if (cexpr->opval.op==ARRAYINIT) {
1272 // this is a list of literals
1275 if (cexpr->opval.op=='=') {
1276 return constExprTree(cexpr->right);
1278 if (cexpr->opval.op==CAST) {
1279 // jwk: cast ignored, maybe we should throw a warning here
1280 return constExprTree(cexpr->right);
1282 if (cexpr->opval.op=='&') {
1285 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1288 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1295 /*-----------------------------------------------------------------*/
1296 /* constExprValue - returns the value of a constant expression */
1297 /* or NULL if it is not a constant expression */
1298 /*-----------------------------------------------------------------*/
1300 constExprValue (ast * cexpr, int check)
1302 cexpr = decorateType (resolveSymbols (cexpr));
1304 /* if this is not a constant then */
1305 if (!IS_LITERAL (cexpr->ftype))
1307 /* then check if this is a literal array
1309 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1310 SPEC_CVAL (cexpr->etype).v_char &&
1311 IS_ARRAY (cexpr->ftype))
1313 value *val = valFromType (cexpr->ftype);
1314 SPEC_SCLS (val->etype) = S_LITERAL;
1315 val->sym = cexpr->opval.val->sym;
1316 val->sym->type = copyLinkChain (cexpr->ftype);
1317 val->sym->etype = getSpec (val->sym->type);
1318 strcpy (val->name, cexpr->opval.val->sym->rname);
1322 /* if we are casting a literal value then */
1323 if (IS_AST_OP (cexpr) &&
1324 cexpr->opval.op == CAST &&
1325 IS_LITERAL (cexpr->right->ftype))
1326 return valCastLiteral (cexpr->ftype,
1327 floatFromVal (cexpr->right->opval.val));
1329 if (IS_AST_VALUE (cexpr))
1330 return cexpr->opval.val;
1333 werror (E_CONST_EXPECTED, "found expression");
1338 /* return the value */
1339 return cexpr->opval.val;
1343 /*-----------------------------------------------------------------*/
1344 /* isLabelInAst - will return true if a given label is found */
1345 /*-----------------------------------------------------------------*/
1347 isLabelInAst (symbol * label, ast * tree)
1349 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1352 if (IS_AST_OP (tree) &&
1353 tree->opval.op == LABEL &&
1354 isSymbolEqual (AST_SYMBOL (tree->left), label))
1357 return isLabelInAst (label, tree->right) &&
1358 isLabelInAst (label, tree->left);
1362 /*-----------------------------------------------------------------*/
1363 /* isLoopCountable - return true if the loop count can be determi- */
1364 /* -ned at compile time . */
1365 /*-----------------------------------------------------------------*/
1367 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1368 symbol ** sym, ast ** init, ast ** end)
1371 /* the loop is considered countable if the following
1372 conditions are true :-
1374 a) initExpr :- <sym> = <const>
1375 b) condExpr :- <sym> < <const1>
1376 c) loopExpr :- <sym> ++
1379 /* first check the initExpr */
1380 if (IS_AST_OP (initExpr) &&
1381 initExpr->opval.op == '=' && /* is assignment */
1382 IS_AST_SYM_VALUE (initExpr->left))
1383 { /* left is a symbol */
1385 *sym = AST_SYMBOL (initExpr->left);
1386 *init = initExpr->right;
1391 /* for now the symbol has to be of
1393 if (!IS_INTEGRAL ((*sym)->type))
1396 /* now check condExpr */
1397 if (IS_AST_OP (condExpr))
1400 switch (condExpr->opval.op)
1403 if (IS_AST_SYM_VALUE (condExpr->left) &&
1404 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1405 IS_AST_LIT_VALUE (condExpr->right))
1407 *end = condExpr->right;
1413 if (IS_AST_OP (condExpr->left) &&
1414 condExpr->left->opval.op == '>' &&
1415 IS_AST_LIT_VALUE (condExpr->left->right) &&
1416 IS_AST_SYM_VALUE (condExpr->left->left) &&
1417 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1420 *end = newNode ('+', condExpr->left->right,
1421 newAst_VALUE (constVal ("1")));
1432 /* check loop expression is of the form <sym>++ */
1433 if (!IS_AST_OP (loopExpr))
1436 /* check if <sym> ++ */
1437 if (loopExpr->opval.op == INC_OP)
1443 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1444 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1451 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1452 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1460 if (loopExpr->opval.op == ADD_ASSIGN)
1463 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1464 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1465 IS_AST_LIT_VALUE (loopExpr->right) &&
1466 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1474 /*-----------------------------------------------------------------*/
1475 /* astHasVolatile - returns true if ast contains any volatile */
1476 /*-----------------------------------------------------------------*/
1478 astHasVolatile (ast * tree)
1483 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1486 if (IS_AST_OP (tree))
1487 return astHasVolatile (tree->left) ||
1488 astHasVolatile (tree->right);
1493 /*-----------------------------------------------------------------*/
1494 /* astHasPointer - return true if the ast contains any ptr variable */
1495 /*-----------------------------------------------------------------*/
1497 astHasPointer (ast * tree)
1502 if (IS_AST_LINK (tree))
1505 /* if we hit an array expression then check
1506 only the left side */
1507 if (IS_AST_OP (tree) && tree->opval.op == '[')
1508 return astHasPointer (tree->left);
1510 if (IS_AST_VALUE (tree))
1511 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1513 return astHasPointer (tree->left) ||
1514 astHasPointer (tree->right);
1518 /*-----------------------------------------------------------------*/
1519 /* astHasSymbol - return true if the ast has the given symbol */
1520 /*-----------------------------------------------------------------*/
1522 astHasSymbol (ast * tree, symbol * sym)
1524 if (!tree || IS_AST_LINK (tree))
1527 if (IS_AST_VALUE (tree))
1529 if (IS_AST_SYM_VALUE (tree))
1530 return isSymbolEqual (AST_SYMBOL (tree), sym);
1535 return astHasSymbol (tree->left, sym) ||
1536 astHasSymbol (tree->right, sym);
1539 /*-----------------------------------------------------------------*/
1540 /* astHasDeref - return true if the ast has an indirect access */
1541 /*-----------------------------------------------------------------*/
1543 astHasDeref (ast * tree)
1545 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1548 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1550 return astHasDeref (tree->left) || astHasDeref (tree->right);
1553 /*-----------------------------------------------------------------*/
1554 /* isConformingBody - the loop body has to conform to a set of rules */
1555 /* for the loop to be considered reversible read on for rules */
1556 /*-----------------------------------------------------------------*/
1558 isConformingBody (ast * pbody, symbol * sym, ast * body)
1561 /* we are going to do a pre-order traversal of the
1562 tree && check for the following conditions. (essentially
1563 a set of very shallow tests )
1564 a) the sym passed does not participate in
1565 any arithmetic operation
1566 b) There are no function calls
1567 c) all jumps are within the body
1568 d) address of loop control variable not taken
1569 e) if an assignment has a pointer on the
1570 left hand side make sure right does not have
1571 loop control variable */
1573 /* if we reach the end or a leaf then true */
1574 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1577 /* if anything else is "volatile" */
1578 if (IS_VOLATILE (TETYPE (pbody)))
1581 /* we will walk the body in a pre-order traversal for
1583 switch (pbody->opval.op)
1585 /*------------------------------------------------------------------*/
1587 // if the loopvar is used as an index
1588 if (astHasSymbol(pbody->right, sym)) {
1591 return isConformingBody (pbody->right, sym, body);
1593 /*------------------------------------------------------------------*/
1598 /*------------------------------------------------------------------*/
1599 case INC_OP: /* incerement operator unary so left only */
1602 /* sure we are not sym is not modified */
1604 IS_AST_SYM_VALUE (pbody->left) &&
1605 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1609 IS_AST_SYM_VALUE (pbody->right) &&
1610 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1615 /*------------------------------------------------------------------*/
1617 case '*': /* can be unary : if right is null then unary operation */
1622 /* if right is NULL then unary operation */
1623 /*------------------------------------------------------------------*/
1624 /*----------------------------*/
1626 /*----------------------------*/
1629 if (IS_AST_SYM_VALUE (pbody->left) &&
1630 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1633 return isConformingBody (pbody->left, sym, body);
1637 if (astHasSymbol (pbody->left, sym) ||
1638 astHasSymbol (pbody->right, sym))
1643 /*------------------------------------------------------------------*/
1651 if (IS_AST_SYM_VALUE (pbody->left) &&
1652 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1655 if (IS_AST_SYM_VALUE (pbody->right) &&
1656 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1659 return isConformingBody (pbody->left, sym, body) &&
1660 isConformingBody (pbody->right, sym, body);
1667 if (IS_AST_SYM_VALUE (pbody->left) &&
1668 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1670 return isConformingBody (pbody->left, sym, body);
1672 /*------------------------------------------------------------------*/
1684 case SIZEOF: /* evaluate wihout code generation */
1686 return isConformingBody (pbody->left, sym, body) &&
1687 isConformingBody (pbody->right, sym, body);
1689 /*------------------------------------------------------------------*/
1692 /* if left has a pointer & right has loop
1693 control variable then we cannot */
1694 if (astHasPointer (pbody->left) &&
1695 astHasSymbol (pbody->right, sym))
1697 if (astHasVolatile (pbody->left))
1700 if (IS_AST_SYM_VALUE (pbody->left)) {
1701 // if the loopvar has an assignment
1702 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1704 // if the loopvar is used in another (maybe conditional) block
1705 if (astHasSymbol (pbody->right, sym) &&
1706 (pbody->level > body->level)) {
1711 if (astHasVolatile (pbody->left))
1714 if (astHasDeref(pbody->right)) return FALSE;
1716 return isConformingBody (pbody->left, sym, body) &&
1717 isConformingBody (pbody->right, sym, body);
1728 assert ("Parser should not have generated this\n");
1730 /*------------------------------------------------------------------*/
1731 /*----------------------------*/
1732 /* comma operator */
1733 /*----------------------------*/
1735 return isConformingBody (pbody->left, sym, body) &&
1736 isConformingBody (pbody->right, sym, body);
1738 /*------------------------------------------------------------------*/
1739 /*----------------------------*/
1741 /*----------------------------*/
1743 /* if local & not passed as paramater then ok */
1744 if (sym->level && !astHasSymbol(pbody->right,sym))
1748 /*------------------------------------------------------------------*/
1749 /*----------------------------*/
1750 /* return statement */
1751 /*----------------------------*/
1756 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1761 if (astHasSymbol (pbody->left, sym))
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1775 /*-----------------------------------------------------------------*/
1776 /* isLoopReversible - takes a for loop as input && returns true */
1777 /* if the for loop is reversible. If yes will set the value of */
1778 /* the loop control var & init value & termination value */
1779 /*-----------------------------------------------------------------*/
1781 isLoopReversible (ast * loop, symbol ** loopCntrl,
1782 ast ** init, ast ** end)
1784 /* if option says don't do it then don't */
1785 if (optimize.noLoopReverse)
1787 /* there are several tests to determine this */
1789 /* for loop has to be of the form
1790 for ( <sym> = <const1> ;
1791 [<sym> < <const2>] ;
1792 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1794 if (!isLoopCountable (AST_FOR (loop, initExpr),
1795 AST_FOR (loop, condExpr),
1796 AST_FOR (loop, loopExpr),
1797 loopCntrl, init, end))
1800 /* now do some serious checking on the body of the loop
1803 return isConformingBody (loop->left, *loopCntrl, loop->left);
1807 /*-----------------------------------------------------------------*/
1808 /* replLoopSym - replace the loop sym by loop sym -1 */
1809 /*-----------------------------------------------------------------*/
1811 replLoopSym (ast * body, symbol * sym)
1814 if (!body || IS_AST_LINK (body))
1817 if (IS_AST_SYM_VALUE (body))
1820 if (isSymbolEqual (AST_SYMBOL (body), sym))
1824 body->opval.op = '-';
1825 body->left = newAst_VALUE (symbolVal (sym));
1826 body->right = newAst_VALUE (constVal ("1"));
1834 replLoopSym (body->left, sym);
1835 replLoopSym (body->right, sym);
1839 /*-----------------------------------------------------------------*/
1840 /* reverseLoop - do the actual loop reversal */
1841 /*-----------------------------------------------------------------*/
1843 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1847 /* create the following tree
1852 if (sym) goto for_continue ;
1855 /* put it together piece by piece */
1856 rloop = newNode (NULLOP,
1857 createIf (newAst_VALUE (symbolVal (sym)),
1859 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1862 newAst_VALUE (symbolVal (sym)),
1865 replLoopSym (loop->left, sym);
1866 setAstLineno (rloop, init->lineno);
1868 rloop = newNode (NULLOP,
1870 newAst_VALUE (symbolVal (sym)),
1871 newNode ('-', end, init)),
1872 createLabel (AST_FOR (loop, continueLabel),
1876 newNode (SUB_ASSIGN,
1877 newAst_VALUE (symbolVal (sym)),
1878 newAst_VALUE (constVal ("1"))),
1881 rloop->lineno=init->lineno;
1882 return decorateType (rloop);
1886 /*-----------------------------------------------------------------*/
1887 /* decorateType - compute type for this tree also does type cheking */
1888 /* this is done bottom up, since type have to flow upwards */
1889 /* it also does constant folding, and paramater checking */
1890 /*-----------------------------------------------------------------*/
1892 decorateType (ast * tree)
1900 /* if already has type then do nothing */
1901 if (tree->decorated)
1904 tree->decorated = 1;
1907 /* print the line */
1908 /* if not block & function */
1909 if (tree->type == EX_OP &&
1910 (tree->opval.op != FUNCTION &&
1911 tree->opval.op != BLOCK &&
1912 tree->opval.op != NULLOP))
1914 filename = tree->filename;
1915 lineno = tree->lineno;
1919 /* if any child is an error | this one is an error do nothing */
1920 if (tree->isError ||
1921 (tree->left && tree->left->isError) ||
1922 (tree->right && tree->right->isError))
1925 /*------------------------------------------------------------------*/
1926 /*----------------------------*/
1927 /* leaf has been reached */
1928 /*----------------------------*/
1929 lineno=tree->lineno;
1930 /* if this is of type value */
1931 /* just get the type */
1932 if (tree->type == EX_VALUE)
1935 if (IS_LITERAL (tree->opval.val->etype))
1938 /* if this is a character array then declare it */
1939 if (IS_ARRAY (tree->opval.val->type))
1940 tree->opval.val = stringToSymbol (tree->opval.val);
1942 /* otherwise just copy the type information */
1943 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1947 if (tree->opval.val->sym)
1949 /* if the undefined flag is set then give error message */
1950 if (tree->opval.val->sym->undefined)
1952 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1954 TTYPE (tree) = TETYPE (tree) =
1955 tree->opval.val->type = tree->opval.val->sym->type =
1956 tree->opval.val->etype = tree->opval.val->sym->etype =
1957 copyLinkChain (INTTYPE);
1962 /* if impilicit i.e. struct/union member then no type */
1963 if (tree->opval.val->sym->implicit)
1964 TTYPE (tree) = TETYPE (tree) = NULL;
1969 /* else copy the type */
1970 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1972 /* and mark it as referenced */
1973 tree->opval.val->sym->isref = 1;
1981 /* if type link for the case of cast */
1982 if (tree->type == EX_LINK)
1984 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1991 dtl = decorateType (tree->left);
1992 /* delay right side for '?' operator since conditional macro expansions might
1994 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1996 /* this is to take care of situations
1997 when the tree gets rewritten */
1998 if (dtl != tree->left)
2000 if (dtr != tree->right)
2003 if (IS_AST_OP(tree) &&
2004 (tree->opval.op == CAST || tree->opval.op == '=') &&
2005 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2006 (getSize(RTYPE(tree)) < INTSIZE)) {
2007 // this is a cast/assign to a bigger type
2008 if (IS_AST_OP(tree->right) &&
2009 IS_INTEGRAL(tree->right->ftype) &&
2010 (tree->right->opval.op == LEFT_OP ||
2011 tree->right->opval.op == '*' ||
2012 tree->right->opval.op == '+' ||
2013 tree->right->opval.op == '-') &&
2014 tree->right->right) {
2015 // we should cast an operand instead of the result
2016 tree->right->decorated = 0;
2017 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2019 tree->right = decorateType(tree->right);
2024 /* depending on type of operator do */
2026 switch (tree->opval.op)
2028 /*------------------------------------------------------------------*/
2029 /*----------------------------*/
2031 /*----------------------------*/
2034 /* determine which is the array & which the index */
2035 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2038 ast *tempTree = tree->left;
2039 tree->left = tree->right;
2040 tree->right = tempTree;
2043 /* first check if this is a array or a pointer */
2044 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2046 werror (E_NEED_ARRAY_PTR, "[]");
2047 goto errorTreeReturn;
2050 /* check if the type of the idx */
2051 if (!IS_INTEGRAL (RTYPE (tree)))
2053 werror (E_IDX_NOT_INT);
2054 goto errorTreeReturn;
2057 /* if the left is an rvalue then error */
2060 werror (E_LVALUE_REQUIRED, "array access");
2061 goto errorTreeReturn;
2064 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2065 if (IS_PTR(LTYPE(tree))) {
2066 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2070 /*------------------------------------------------------------------*/
2071 /*----------------------------*/
2073 /*----------------------------*/
2075 /* if this is not a structure */
2076 if (!IS_STRUCT (LTYPE (tree)))
2078 werror (E_STRUCT_UNION, ".");
2079 goto errorTreeReturn;
2081 TTYPE (tree) = structElemType (LTYPE (tree),
2082 (tree->right->type == EX_VALUE ?
2083 tree->right->opval.val : NULL));
2084 TETYPE (tree) = getSpec (TTYPE (tree));
2087 /*------------------------------------------------------------------*/
2088 /*----------------------------*/
2089 /* struct/union pointer */
2090 /*----------------------------*/
2092 /* if not pointer to a structure */
2093 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2095 werror (E_PTR_REQD);
2096 goto errorTreeReturn;
2099 if (!IS_STRUCT (LTYPE (tree)->next))
2101 werror (E_STRUCT_UNION, "->");
2102 goto errorTreeReturn;
2105 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2106 (tree->right->type == EX_VALUE ?
2107 tree->right->opval.val : NULL));
2108 TETYPE (tree) = getSpec (TTYPE (tree));
2110 /* adjust the storage class */
2111 switch (DCL_TYPE(tree->left->ftype)) {
2115 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2118 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2123 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2126 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2129 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2139 /*------------------------------------------------------------------*/
2140 /*----------------------------*/
2141 /* ++/-- operation */
2142 /*----------------------------*/
2143 case INC_OP: /* incerement operator unary so left only */
2146 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2147 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2148 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2149 werror (E_CODE_WRITE, "++/--");
2158 /*------------------------------------------------------------------*/
2159 /*----------------------------*/
2161 /*----------------------------*/
2162 case '&': /* can be unary */
2163 /* if right is NULL then unary operation */
2164 if (tree->right) /* not an unary operation */
2167 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2169 werror (E_BITWISE_OP);
2170 werror (W_CONTINUE, "left & right types are ");
2171 printTypeChain (LTYPE (tree), stderr);
2172 fprintf (stderr, ",");
2173 printTypeChain (RTYPE (tree), stderr);
2174 fprintf (stderr, "\n");
2175 goto errorTreeReturn;
2178 /* if they are both literal */
2179 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2181 tree->type = EX_VALUE;
2182 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2183 valFromType (RETYPE (tree)), '&');
2185 tree->right = tree->left = NULL;
2186 TETYPE (tree) = tree->opval.val->etype;
2187 TTYPE (tree) = tree->opval.val->type;
2191 /* see if this is a GETHBIT operation if yes
2194 ast *otree = optimizeGetHbit (tree);
2197 return decorateType (otree);
2201 computeType (LTYPE (tree), RTYPE (tree));
2202 TETYPE (tree) = getSpec (TTYPE (tree));
2204 LRVAL (tree) = RRVAL (tree) = 1;
2208 /*------------------------------------------------------------------*/
2209 /*----------------------------*/
2211 /*----------------------------*/
2213 p->class = DECLARATOR;
2214 /* if bit field then error */
2215 if (IS_BITVAR (tree->left->etype))
2217 werror (E_ILLEGAL_ADDR, "address of bit variable");
2218 goto errorTreeReturn;
2221 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2223 werror (E_ILLEGAL_ADDR, "address of register variable");
2224 goto errorTreeReturn;
2227 if (IS_FUNC (LTYPE (tree)))
2229 // this ought to be ignored
2230 return (tree->left);
2233 if (IS_LITERAL(LTYPE(tree)))
2235 werror (E_ILLEGAL_ADDR, "address of literal");
2236 goto errorTreeReturn;
2241 werror (E_LVALUE_REQUIRED, "address of");
2242 goto errorTreeReturn;
2244 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2246 DCL_TYPE (p) = CPOINTER;
2247 DCL_PTR_CONST (p) = port->mem.code_ro;
2249 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2250 DCL_TYPE (p) = FPOINTER;
2251 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2252 DCL_TYPE (p) = PPOINTER;
2253 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2254 DCL_TYPE (p) = IPOINTER;
2255 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2256 DCL_TYPE (p) = EEPPOINTER;
2257 else if (SPEC_OCLS(tree->left->etype))
2258 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2260 DCL_TYPE (p) = POINTER;
2262 if (IS_AST_SYM_VALUE (tree->left))
2264 AST_SYMBOL (tree->left)->addrtaken = 1;
2265 AST_SYMBOL (tree->left)->allocreq = 1;
2268 p->next = LTYPE (tree);
2270 TETYPE (tree) = getSpec (TTYPE (tree));
2271 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2272 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2277 /*------------------------------------------------------------------*/
2278 /*----------------------------*/
2280 /*----------------------------*/
2282 /* if the rewrite succeeds then don't go any furthur */
2284 ast *wtree = optimizeRRCRLC (tree);
2286 return decorateType (wtree);
2289 /*------------------------------------------------------------------*/
2290 /*----------------------------*/
2292 /*----------------------------*/
2294 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2296 werror (E_BITWISE_OP);
2297 werror (W_CONTINUE, "left & right types are ");
2298 printTypeChain (LTYPE (tree), stderr);
2299 fprintf (stderr, ",");
2300 printTypeChain (RTYPE (tree), stderr);
2301 fprintf (stderr, "\n");
2302 goto errorTreeReturn;
2305 /* if they are both literal then */
2306 /* rewrite the tree */
2307 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2309 tree->type = EX_VALUE;
2310 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2311 valFromType (RETYPE (tree)),
2313 tree->right = tree->left = NULL;
2314 TETYPE (tree) = tree->opval.val->etype;
2315 TTYPE (tree) = tree->opval.val->type;
2318 LRVAL (tree) = RRVAL (tree) = 1;
2319 TETYPE (tree) = getSpec (TTYPE (tree) =
2320 computeType (LTYPE (tree),
2323 /*------------------------------------------------------------------*/
2324 /*----------------------------*/
2326 /*----------------------------*/
2328 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2330 werror (E_INVALID_OP, "divide");
2331 goto errorTreeReturn;
2333 /* if they are both literal then */
2334 /* rewrite the tree */
2335 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2337 tree->type = EX_VALUE;
2338 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2339 valFromType (RETYPE (tree)));
2340 tree->right = tree->left = NULL;
2341 TETYPE (tree) = getSpec (TTYPE (tree) =
2342 tree->opval.val->type);
2345 LRVAL (tree) = RRVAL (tree) = 1;
2346 TETYPE (tree) = getSpec (TTYPE (tree) =
2347 computeType (LTYPE (tree),
2351 /*------------------------------------------------------------------*/
2352 /*----------------------------*/
2354 /*----------------------------*/
2356 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2358 werror (E_BITWISE_OP);
2359 werror (W_CONTINUE, "left & right types are ");
2360 printTypeChain (LTYPE (tree), stderr);
2361 fprintf (stderr, ",");
2362 printTypeChain (RTYPE (tree), stderr);
2363 fprintf (stderr, "\n");
2364 goto errorTreeReturn;
2366 /* if they are both literal then */
2367 /* rewrite the tree */
2368 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2370 tree->type = EX_VALUE;
2371 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2372 valFromType (RETYPE (tree)));
2373 tree->right = tree->left = NULL;
2374 TETYPE (tree) = getSpec (TTYPE (tree) =
2375 tree->opval.val->type);
2378 LRVAL (tree) = RRVAL (tree) = 1;
2379 TETYPE (tree) = getSpec (TTYPE (tree) =
2380 computeType (LTYPE (tree),
2384 /*------------------------------------------------------------------*/
2385 /*----------------------------*/
2386 /* address dereference */
2387 /*----------------------------*/
2388 case '*': /* can be unary : if right is null then unary operation */
2391 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2393 werror (E_PTR_REQD);
2394 goto errorTreeReturn;
2399 werror (E_LVALUE_REQUIRED, "pointer deref");
2400 goto errorTreeReturn;
2402 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2403 LTYPE (tree)->next : NULL);
2404 TETYPE (tree) = getSpec (TTYPE (tree));
2405 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2409 /*------------------------------------------------------------------*/
2410 /*----------------------------*/
2411 /* multiplication */
2412 /*----------------------------*/
2413 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2415 werror (E_INVALID_OP, "multiplication");
2416 goto errorTreeReturn;
2419 /* if they are both literal then */
2420 /* rewrite the tree */
2421 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2423 tree->type = EX_VALUE;
2424 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2425 valFromType (RETYPE (tree)));
2426 tree->right = tree->left = NULL;
2427 TETYPE (tree) = getSpec (TTYPE (tree) =
2428 tree->opval.val->type);
2432 /* if left is a literal exchange left & right */
2433 if (IS_LITERAL (LTYPE (tree)))
2435 ast *tTree = tree->left;
2436 tree->left = tree->right;
2437 tree->right = tTree;
2440 LRVAL (tree) = RRVAL (tree) = 1;
2441 TETYPE (tree) = getSpec (TTYPE (tree) =
2442 computeType (LTYPE (tree),
2445 /* promote result to int if left & right are char
2446 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2447 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2448 SPEC_NOUN(TETYPE(tree)) = V_INT;
2453 /*------------------------------------------------------------------*/
2454 /*----------------------------*/
2455 /* unary '+' operator */
2456 /*----------------------------*/
2461 if (!IS_INTEGRAL (LTYPE (tree)))
2463 werror (E_UNARY_OP, '+');
2464 goto errorTreeReturn;
2467 /* if left is a literal then do it */
2468 if (IS_LITERAL (LTYPE (tree)))
2470 tree->type = EX_VALUE;
2471 tree->opval.val = valFromType (LETYPE (tree));
2473 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2477 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2481 /*------------------------------------------------------------------*/
2482 /*----------------------------*/
2484 /*----------------------------*/
2486 /* this is not a unary operation */
2487 /* if both pointers then problem */
2488 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2489 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2491 werror (E_PTR_PLUS_PTR);
2492 goto errorTreeReturn;
2495 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2496 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2498 werror (E_PLUS_INVALID, "+");
2499 goto errorTreeReturn;
2502 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2503 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2505 werror (E_PLUS_INVALID, "+");
2506 goto errorTreeReturn;
2508 /* if they are both literal then */
2509 /* rewrite the tree */
2510 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2512 tree->type = EX_VALUE;
2513 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2514 valFromType (RETYPE (tree)));
2515 tree->right = tree->left = NULL;
2516 TETYPE (tree) = getSpec (TTYPE (tree) =
2517 tree->opval.val->type);
2521 /* if the right is a pointer or left is a literal
2522 xchange left & right */
2523 if (IS_ARRAY (RTYPE (tree)) ||
2524 IS_PTR (RTYPE (tree)) ||
2525 IS_LITERAL (LTYPE (tree)))
2527 ast *tTree = tree->left;
2528 tree->left = tree->right;
2529 tree->right = tTree;
2532 LRVAL (tree) = RRVAL (tree) = 1;
2533 /* if the left is a pointer */
2534 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2535 TETYPE (tree) = getSpec (TTYPE (tree) =
2538 TETYPE (tree) = getSpec (TTYPE (tree) =
2539 computeType (LTYPE (tree),
2543 /*------------------------------------------------------------------*/
2544 /*----------------------------*/
2546 /*----------------------------*/
2547 case '-': /* can be unary */
2548 /* if right is null then unary */
2552 if (!IS_ARITHMETIC (LTYPE (tree)))
2554 werror (E_UNARY_OP, tree->opval.op);
2555 goto errorTreeReturn;
2558 /* if left is a literal then do it */
2559 if (IS_LITERAL (LTYPE (tree)))
2561 tree->type = EX_VALUE;
2562 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2564 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2565 SPEC_USIGN(TETYPE(tree)) = 0;
2569 TTYPE (tree) = LTYPE (tree);
2573 /*------------------------------------------------------------------*/
2574 /*----------------------------*/
2576 /*----------------------------*/
2578 if (!(IS_PTR (LTYPE (tree)) ||
2579 IS_ARRAY (LTYPE (tree)) ||
2580 IS_ARITHMETIC (LTYPE (tree))))
2582 werror (E_PLUS_INVALID, "-");
2583 goto errorTreeReturn;
2586 if (!(IS_PTR (RTYPE (tree)) ||
2587 IS_ARRAY (RTYPE (tree)) ||
2588 IS_ARITHMETIC (RTYPE (tree))))
2590 werror (E_PLUS_INVALID, "-");
2591 goto errorTreeReturn;
2594 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2595 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2596 IS_INTEGRAL (RTYPE (tree))))
2598 werror (E_PLUS_INVALID, "-");
2599 goto errorTreeReturn;
2602 /* if they are both literal then */
2603 /* rewrite the tree */
2604 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2606 tree->type = EX_VALUE;
2607 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2608 valFromType (RETYPE (tree)));
2609 tree->right = tree->left = NULL;
2610 TETYPE (tree) = getSpec (TTYPE (tree) =
2611 tree->opval.val->type);
2615 /* if the left & right are equal then zero */
2616 if (isAstEqual (tree->left, tree->right))
2618 tree->type = EX_VALUE;
2619 tree->left = tree->right = NULL;
2620 tree->opval.val = constVal ("0");
2621 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2625 /* if both of them are pointers or arrays then */
2626 /* the result is going to be an integer */
2627 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2628 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2629 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2631 /* if only the left is a pointer */
2632 /* then result is a pointer */
2633 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2634 TETYPE (tree) = getSpec (TTYPE (tree) =
2637 TETYPE (tree) = getSpec (TTYPE (tree) =
2638 computeType (LTYPE (tree),
2640 LRVAL (tree) = RRVAL (tree) = 1;
2643 /*------------------------------------------------------------------*/
2644 /*----------------------------*/
2646 /*----------------------------*/
2648 /* can be only integral type */
2649 if (!IS_INTEGRAL (LTYPE (tree)))
2651 werror (E_UNARY_OP, tree->opval.op);
2652 goto errorTreeReturn;
2655 /* if left is a literal then do it */
2656 if (IS_LITERAL (LTYPE (tree)))
2658 tree->type = EX_VALUE;
2659 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2661 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2665 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2668 /*------------------------------------------------------------------*/
2669 /*----------------------------*/
2671 /*----------------------------*/
2673 /* can be pointer */
2674 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2675 !IS_PTR (LTYPE (tree)) &&
2676 !IS_ARRAY (LTYPE (tree)))
2678 werror (E_UNARY_OP, tree->opval.op);
2679 goto errorTreeReturn;
2682 /* if left is a literal then do it */
2683 if (IS_LITERAL (LTYPE (tree)))
2685 tree->type = EX_VALUE;
2686 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2688 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2692 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2695 /*------------------------------------------------------------------*/
2696 /*----------------------------*/
2698 /*----------------------------*/
2701 TTYPE (tree) = LTYPE (tree);
2702 TETYPE (tree) = LETYPE (tree);
2706 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2711 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2713 werror (E_SHIFT_OP_INVALID);
2714 werror (W_CONTINUE, "left & right types are ");
2715 printTypeChain (LTYPE (tree), stderr);
2716 fprintf (stderr, ",");
2717 printTypeChain (RTYPE (tree), stderr);
2718 fprintf (stderr, "\n");
2719 goto errorTreeReturn;
2722 /* if they are both literal then */
2723 /* rewrite the tree */
2724 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2726 tree->type = EX_VALUE;
2727 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2728 valFromType (RETYPE (tree)),
2729 (tree->opval.op == LEFT_OP ? 1 : 0));
2730 tree->right = tree->left = NULL;
2731 TETYPE (tree) = getSpec (TTYPE (tree) =
2732 tree->opval.val->type);
2736 /* if only the right side is a literal & we are
2737 shifting more than size of the left operand then zero */
2738 if (IS_LITERAL (RTYPE (tree)) &&
2739 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2740 (getSize (LTYPE (tree)) * 8))
2742 if (tree->opval.op==LEFT_OP ||
2743 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2744 lineno=tree->lineno;
2745 werror (W_SHIFT_CHANGED,
2746 (tree->opval.op == LEFT_OP ? "left" : "right"));
2747 tree->type = EX_VALUE;
2748 tree->left = tree->right = NULL;
2749 tree->opval.val = constVal ("0");
2750 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2754 LRVAL (tree) = RRVAL (tree) = 1;
2755 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2757 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2761 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2765 /*------------------------------------------------------------------*/
2766 /*----------------------------*/
2768 /*----------------------------*/
2769 case CAST: /* change the type */
2770 /* cannot cast to an aggregate type */
2771 if (IS_AGGREGATE (LTYPE (tree)))
2773 werror (E_CAST_ILLEGAL);
2774 goto errorTreeReturn;
2777 /* make sure the type is complete and sane */
2778 checkTypeSanity(LETYPE(tree), "(cast)");
2781 /* if the right is a literal replace the tree */
2782 if (IS_LITERAL (RETYPE (tree))) {
2783 if (!IS_PTR (LTYPE (tree))) {
2784 tree->type = EX_VALUE;
2786 valCastLiteral (LTYPE (tree),
2787 floatFromVal (valFromType (RETYPE (tree))));
2790 TTYPE (tree) = tree->opval.val->type;
2791 tree->values.literalFromCast = 1;
2792 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2793 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2794 sym_link *rest = LTYPE(tree)->next;
2795 werror(W_LITERAL_GENERIC);
2796 TTYPE(tree) = newLink();
2797 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2798 TTYPE(tree)->next = rest;
2799 tree->left->opval.lnk = TTYPE(tree);
2802 TTYPE (tree) = LTYPE (tree);
2806 TTYPE (tree) = LTYPE (tree);
2810 #if 0 // this is already checked, now this could be explicit
2811 /* if pointer to struct then check names */
2812 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2813 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2814 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2816 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2817 SPEC_STRUCT(LETYPE(tree))->tag);
2820 /* if the right is a literal replace the tree */
2821 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2822 tree->type = EX_VALUE;
2824 valCastLiteral (LTYPE (tree),
2825 floatFromVal (valFromType (RETYPE (tree))));
2828 TTYPE (tree) = tree->opval.val->type;
2829 tree->values.literalFromCast = 1;
2831 TTYPE (tree) = LTYPE (tree);
2835 TETYPE (tree) = getSpec (TTYPE (tree));
2839 /*------------------------------------------------------------------*/
2840 /*----------------------------*/
2841 /* logical &&, || */
2842 /*----------------------------*/
2845 /* each must me arithmetic type or be a pointer */
2846 if (!IS_PTR (LTYPE (tree)) &&
2847 !IS_ARRAY (LTYPE (tree)) &&
2848 !IS_INTEGRAL (LTYPE (tree)))
2850 werror (E_COMPARE_OP);
2851 goto errorTreeReturn;
2854 if (!IS_PTR (RTYPE (tree)) &&
2855 !IS_ARRAY (RTYPE (tree)) &&
2856 !IS_INTEGRAL (RTYPE (tree)))
2858 werror (E_COMPARE_OP);
2859 goto errorTreeReturn;
2861 /* if they are both literal then */
2862 /* rewrite the tree */
2863 if (IS_LITERAL (RTYPE (tree)) &&
2864 IS_LITERAL (LTYPE (tree)))
2866 tree->type = EX_VALUE;
2867 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2868 valFromType (RETYPE (tree)),
2870 tree->right = tree->left = NULL;
2871 TETYPE (tree) = getSpec (TTYPE (tree) =
2872 tree->opval.val->type);
2875 LRVAL (tree) = RRVAL (tree) = 1;
2876 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2879 /*------------------------------------------------------------------*/
2880 /*----------------------------*/
2881 /* comparison operators */
2882 /*----------------------------*/
2890 ast *lt = optimizeCompare (tree);
2896 /* if they are pointers they must be castable */
2897 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2899 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2901 werror (E_COMPARE_OP);
2902 fprintf (stderr, "comparing type ");
2903 printTypeChain (LTYPE (tree), stderr);
2904 fprintf (stderr, "to type ");
2905 printTypeChain (RTYPE (tree), stderr);
2906 fprintf (stderr, "\n");
2907 goto errorTreeReturn;
2910 /* else they should be promotable to one another */
2913 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2914 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2916 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2918 werror (E_COMPARE_OP);
2919 fprintf (stderr, "comparing type ");
2920 printTypeChain (LTYPE (tree), stderr);
2921 fprintf (stderr, "to type ");
2922 printTypeChain (RTYPE (tree), stderr);
2923 fprintf (stderr, "\n");
2924 goto errorTreeReturn;
2927 /* if unsigned value < 0 then always false */
2928 /* if (unsigned value) > 0 then (unsigned value) */
2929 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2930 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2932 if (tree->opval.op == '<') {
2935 if (tree->opval.op == '>') {
2939 /* if they are both literal then */
2940 /* rewrite the tree */
2941 if (IS_LITERAL (RTYPE (tree)) &&
2942 IS_LITERAL (LTYPE (tree)))
2944 tree->type = EX_VALUE;
2945 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2946 valFromType (RETYPE (tree)),
2948 tree->right = tree->left = NULL;
2949 TETYPE (tree) = getSpec (TTYPE (tree) =
2950 tree->opval.val->type);
2953 LRVAL (tree) = RRVAL (tree) = 1;
2954 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2957 /*------------------------------------------------------------------*/
2958 /*----------------------------*/
2960 /*----------------------------*/
2961 case SIZEOF: /* evaluate wihout code generation */
2962 /* change the type to a integer */
2963 tree->type = EX_VALUE;
2964 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2965 tree->opval.val = constVal (buffer);
2966 tree->right = tree->left = NULL;
2967 TETYPE (tree) = getSpec (TTYPE (tree) =
2968 tree->opval.val->type);
2971 /*------------------------------------------------------------------*/
2972 /*----------------------------*/
2974 /*----------------------------*/
2976 /* return typeof enum value */
2977 tree->type = EX_VALUE;
2980 if (IS_SPEC(tree->right->ftype)) {
2981 switch (SPEC_NOUN(tree->right->ftype)) {
2983 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2984 else typeofv = TYPEOF_INT;
2987 typeofv = TYPEOF_FLOAT;
2990 typeofv = TYPEOF_CHAR;
2993 typeofv = TYPEOF_VOID;
2996 typeofv = TYPEOF_STRUCT;
2999 typeofv = TYPEOF_BIT;
3002 typeofv = TYPEOF_SBIT;
3008 switch (DCL_TYPE(tree->right->ftype)) {
3010 typeofv = TYPEOF_POINTER;
3013 typeofv = TYPEOF_FPOINTER;
3016 typeofv = TYPEOF_CPOINTER;
3019 typeofv = TYPEOF_GPOINTER;
3022 typeofv = TYPEOF_PPOINTER;
3025 typeofv = TYPEOF_IPOINTER;
3028 typeofv = TYPEOF_ARRAY;
3031 typeofv = TYPEOF_FUNCTION;
3037 sprintf (buffer, "%d", typeofv);
3038 tree->opval.val = constVal (buffer);
3039 tree->right = tree->left = NULL;
3040 TETYPE (tree) = getSpec (TTYPE (tree) =
3041 tree->opval.val->type);
3044 /*------------------------------------------------------------------*/
3045 /*----------------------------*/
3046 /* conditional operator '?' */
3047 /*----------------------------*/
3049 /* the type is value of the colon operator (on the right) */
3050 assert(IS_COLON_OP(tree->right));
3051 /* if already known then replace the tree : optimizer will do it
3052 but faster to do it here */
3053 if (IS_LITERAL (LTYPE(tree))) {
3054 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3055 return decorateType(tree->right->left) ;
3057 return decorateType(tree->right->right) ;
3060 tree->right = decorateType(tree->right);
3061 TTYPE (tree) = RTYPE(tree);
3062 TETYPE (tree) = getSpec (TTYPE (tree));
3067 /* if they don't match we have a problem */
3068 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3070 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3071 goto errorTreeReturn;
3074 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3075 TETYPE (tree) = getSpec (TTYPE (tree));
3079 #if 0 // assignment operators are converted by the parser
3080 /*------------------------------------------------------------------*/
3081 /*----------------------------*/
3082 /* assignment operators */
3083 /*----------------------------*/
3086 /* for these it must be both must be integral */
3087 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3088 !IS_ARITHMETIC (RTYPE (tree)))
3090 werror (E_OPS_INTEGRAL);
3091 goto errorTreeReturn;
3094 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3096 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3097 werror (E_CODE_WRITE, " ");
3101 werror (E_LVALUE_REQUIRED, "*= or /=");
3102 goto errorTreeReturn;
3113 /* for these it must be both must be integral */
3114 if (!IS_INTEGRAL (LTYPE (tree)) ||
3115 !IS_INTEGRAL (RTYPE (tree)))
3117 werror (E_OPS_INTEGRAL);
3118 goto errorTreeReturn;
3121 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3123 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3124 werror (E_CODE_WRITE, " ");
3128 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3129 goto errorTreeReturn;
3135 /*------------------------------------------------------------------*/
3136 /*----------------------------*/
3138 /*----------------------------*/
3140 if (!(IS_PTR (LTYPE (tree)) ||
3141 IS_ARITHMETIC (LTYPE (tree))))
3143 werror (E_PLUS_INVALID, "-=");
3144 goto errorTreeReturn;
3147 if (!(IS_PTR (RTYPE (tree)) ||
3148 IS_ARITHMETIC (RTYPE (tree))))
3150 werror (E_PLUS_INVALID, "-=");
3151 goto errorTreeReturn;
3154 TETYPE (tree) = getSpec (TTYPE (tree) =
3155 computeType (LTYPE (tree),
3158 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3159 werror (E_CODE_WRITE, " ");
3163 werror (E_LVALUE_REQUIRED, "-=");
3164 goto errorTreeReturn;
3170 /*------------------------------------------------------------------*/
3171 /*----------------------------*/
3173 /*----------------------------*/
3175 /* this is not a unary operation */
3176 /* if both pointers then problem */
3177 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3179 werror (E_PTR_PLUS_PTR);
3180 goto errorTreeReturn;
3183 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3185 werror (E_PLUS_INVALID, "+=");
3186 goto errorTreeReturn;
3189 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3191 werror (E_PLUS_INVALID, "+=");
3192 goto errorTreeReturn;
3195 TETYPE (tree) = getSpec (TTYPE (tree) =
3196 computeType (LTYPE (tree),
3199 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3200 werror (E_CODE_WRITE, " ");
3204 werror (E_LVALUE_REQUIRED, "+=");
3205 goto errorTreeReturn;
3208 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3209 tree->opval.op = '=';
3214 /*------------------------------------------------------------------*/
3215 /*----------------------------*/
3216 /* straight assignemnt */
3217 /*----------------------------*/
3219 /* cannot be an aggregate */
3220 if (IS_AGGREGATE (LTYPE (tree)))
3222 werror (E_AGGR_ASSIGN);
3223 goto errorTreeReturn;
3226 /* they should either match or be castable */
3227 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3229 werror (E_TYPE_MISMATCH, "assignment", " ");
3230 printFromToType(RTYPE(tree),LTYPE(tree));
3231 //goto errorTreeReturn;
3234 /* if the left side of the tree is of type void
3235 then report error */
3236 if (IS_VOID (LTYPE (tree)))
3238 werror (E_CAST_ZERO);
3239 printFromToType(RTYPE(tree), LTYPE(tree));
3242 TETYPE (tree) = getSpec (TTYPE (tree) =
3246 if (!tree->initMode ) {
3247 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3248 werror (E_CODE_WRITE, " ");
3252 werror (E_LVALUE_REQUIRED, "=");
3253 goto errorTreeReturn;
3258 /*------------------------------------------------------------------*/
3259 /*----------------------------*/
3260 /* comma operator */
3261 /*----------------------------*/
3263 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3266 /*------------------------------------------------------------------*/
3267 /*----------------------------*/
3269 /*----------------------------*/
3273 if (processParms (tree->left,
3274 FUNC_ARGS(tree->left->ftype),
3275 tree->right, &parmNumber, TRUE)) {
3276 goto errorTreeReturn;
3279 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3280 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3282 //FUNC_ARGS(tree->left->ftype) =
3283 //reverseVal (FUNC_ARGS(tree->left->ftype));
3284 reverseParms (tree->right);
3287 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3290 /*------------------------------------------------------------------*/
3291 /*----------------------------*/
3292 /* return statement */
3293 /*----------------------------*/
3298 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3300 werror (W_RETURN_MISMATCH);
3301 printFromToType (RTYPE(tree), currFunc->type->next);
3302 goto errorTreeReturn;
3305 if (IS_VOID (currFunc->type->next)
3307 !IS_VOID (RTYPE (tree)))
3309 werror (E_FUNC_VOID);
3310 goto errorTreeReturn;
3313 /* if there is going to be a casing required then add it */
3314 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3317 decorateType (newNode (CAST,
3318 newAst_LINK (copyLinkChain (currFunc->type->next)),
3327 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3329 werror (E_VOID_FUNC, currFunc->name);
3330 goto errorTreeReturn;
3333 TTYPE (tree) = TETYPE (tree) = NULL;
3336 /*------------------------------------------------------------------*/
3337 /*----------------------------*/
3338 /* switch statement */
3339 /*----------------------------*/
3341 /* the switch value must be an integer */
3342 if (!IS_INTEGRAL (LTYPE (tree)))
3344 werror (E_SWITCH_NON_INTEGER);
3345 goto errorTreeReturn;
3348 TTYPE (tree) = TETYPE (tree) = NULL;
3351 /*------------------------------------------------------------------*/
3352 /*----------------------------*/
3354 /*----------------------------*/
3356 tree->left = backPatchLabels (tree->left,
3359 TTYPE (tree) = TETYPE (tree) = NULL;
3362 /*------------------------------------------------------------------*/
3363 /*----------------------------*/
3365 /*----------------------------*/
3368 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3369 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3370 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3372 /* if the for loop is reversible then
3373 reverse it otherwise do what we normally
3379 if (isLoopReversible (tree, &sym, &init, &end))
3380 return reverseLoop (tree, sym, init, end);
3382 return decorateType (createFor (AST_FOR (tree, trueLabel),
3383 AST_FOR (tree, continueLabel),
3384 AST_FOR (tree, falseLabel),
3385 AST_FOR (tree, condLabel),
3386 AST_FOR (tree, initExpr),
3387 AST_FOR (tree, condExpr),
3388 AST_FOR (tree, loopExpr),
3392 TTYPE (tree) = TETYPE (tree) = NULL;
3396 /* some error found this tree will be killed */
3398 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3399 tree->opval.op = NULLOP;
3405 /*-----------------------------------------------------------------*/
3406 /* sizeofOp - processes size of operation */
3407 /*-----------------------------------------------------------------*/
3409 sizeofOp (sym_link * type)
3413 /* make sure the type is complete and sane */
3414 checkTypeSanity(type, "(sizeof)");
3416 /* get the size and convert it to character */
3417 sprintf (buff, "%d", getSize (type));
3419 /* now convert into value */
3420 return constVal (buff);
3424 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3425 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3426 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3427 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3428 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3429 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3430 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3432 /*-----------------------------------------------------------------*/
3433 /* backPatchLabels - change and or not operators to flow control */
3434 /*-----------------------------------------------------------------*/
3436 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3442 if (!(IS_ANDORNOT (tree)))
3445 /* if this an and */
3448 static int localLbl = 0;
3451 sprintf (buffer, "_and_%d", localLbl++);
3452 localLabel = newSymbol (buffer, NestLevel);
3454 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3456 /* if left is already a IFX then just change the if true label in that */
3457 if (!IS_IFX (tree->left))
3458 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3460 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3461 /* right is a IFX then just join */
3462 if (IS_IFX (tree->right))
3463 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3465 tree->right = createLabel (localLabel, tree->right);
3466 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3468 return newNode (NULLOP, tree->left, tree->right);
3471 /* if this is an or operation */
3474 static int localLbl = 0;
3477 sprintf (buffer, "_or_%d", localLbl++);
3478 localLabel = newSymbol (buffer, NestLevel);
3480 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3482 /* if left is already a IFX then just change the if true label in that */
3483 if (!IS_IFX (tree->left))
3484 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3486 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3487 /* right is a IFX then just join */
3488 if (IS_IFX (tree->right))
3489 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3491 tree->right = createLabel (localLabel, tree->right);
3492 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3494 return newNode (NULLOP, tree->left, tree->right);
3500 int wasnot = IS_NOT (tree->left);
3501 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3503 /* if the left is already a IFX */
3504 if (!IS_IFX (tree->left))
3505 tree->left = newNode (IFX, tree->left, NULL);
3509 tree->left->trueLabel = trueLabel;
3510 tree->left->falseLabel = falseLabel;
3514 tree->left->trueLabel = falseLabel;
3515 tree->left->falseLabel = trueLabel;
3522 tree->trueLabel = trueLabel;
3523 tree->falseLabel = falseLabel;
3530 /*-----------------------------------------------------------------*/
3531 /* createBlock - create expression tree for block */
3532 /*-----------------------------------------------------------------*/
3534 createBlock (symbol * decl, ast * body)
3538 /* if the block has nothing */
3542 ex = newNode (BLOCK, NULL, body);
3543 ex->values.sym = decl;
3545 ex->right = ex->right;
3551 /*-----------------------------------------------------------------*/
3552 /* createLabel - creates the expression tree for labels */
3553 /*-----------------------------------------------------------------*/
3555 createLabel (symbol * label, ast * stmnt)
3558 char name[SDCC_NAME_MAX + 1];
3561 /* must create fresh symbol if the symbol name */
3562 /* exists in the symbol table, since there can */
3563 /* be a variable with the same name as the labl */
3564 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3565 (csym->level == label->level))
3566 label = newSymbol (label->name, label->level);
3568 /* change the name before putting it in add _ */
3569 sprintf (name, "%s", label->name);
3571 /* put the label in the LabelSymbol table */
3572 /* but first check if a label of the same */
3574 if ((csym = findSym (LabelTab, NULL, name)))
3575 werror (E_DUPLICATE_LABEL, label->name);
3577 addSym (LabelTab, label, name, label->level, 0, 0);
3580 label->key = labelKey++;
3581 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3587 /*-----------------------------------------------------------------*/
3588 /* createCase - generates the parsetree for a case statement */
3589 /*-----------------------------------------------------------------*/
3591 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3593 char caseLbl[SDCC_NAME_MAX + 1];
3597 /* if the switch statement does not exist */
3598 /* then case is out of context */
3601 werror (E_CASE_CONTEXT);
3605 caseVal = decorateType (resolveSymbols (caseVal));
3606 /* if not a constant then error */
3607 if (!IS_LITERAL (caseVal->ftype))
3609 werror (E_CASE_CONSTANT);
3613 /* if not a integer than error */
3614 if (!IS_INTEGRAL (caseVal->ftype))
3616 werror (E_CASE_NON_INTEGER);
3620 /* find the end of the switch values chain */
3621 if (!(val = swStat->values.switchVals.swVals))
3622 swStat->values.switchVals.swVals = caseVal->opval.val;
3625 /* also order the cases according to value */
3627 int cVal = (int) floatFromVal (caseVal->opval.val);
3628 while (val && (int) floatFromVal (val) < cVal)
3634 /* if we reached the end then */
3637 pval->next = caseVal->opval.val;
3641 /* we found a value greater than */
3642 /* the current value we must add this */
3643 /* before the value */
3644 caseVal->opval.val->next = val;
3646 /* if this was the first in chain */
3647 if (swStat->values.switchVals.swVals == val)
3648 swStat->values.switchVals.swVals =
3651 pval->next = caseVal->opval.val;
3656 /* create the case label */
3657 sprintf (caseLbl, "_case_%d_%d",
3658 swStat->values.switchVals.swNum,
3659 (int) floatFromVal (caseVal->opval.val));
3661 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3666 /*-----------------------------------------------------------------*/
3667 /* createDefault - creates the parse tree for the default statement */
3668 /*-----------------------------------------------------------------*/
3670 createDefault (ast * swStat, ast * stmnt)
3672 char defLbl[SDCC_NAME_MAX + 1];
3674 /* if the switch statement does not exist */
3675 /* then case is out of context */
3678 werror (E_CASE_CONTEXT);
3682 /* turn on the default flag */
3683 swStat->values.switchVals.swDefault = 1;
3685 /* create the label */
3686 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3687 return createLabel (newSymbol (defLbl, 0), stmnt);
3690 /*-----------------------------------------------------------------*/
3691 /* createIf - creates the parsetree for the if statement */
3692 /*-----------------------------------------------------------------*/
3694 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3696 static int Lblnum = 0;
3698 symbol *ifTrue, *ifFalse, *ifEnd;
3700 /* if neither exists */
3701 if (!elseBody && !ifBody) {
3702 // if there are no side effects (i++, j() etc)
3703 if (!hasSEFcalls(condAst)) {
3708 /* create the labels */
3709 sprintf (buffer, "_iffalse_%d", Lblnum);
3710 ifFalse = newSymbol (buffer, NestLevel);
3711 /* if no else body then end == false */
3716 sprintf (buffer, "_ifend_%d", Lblnum);
3717 ifEnd = newSymbol (buffer, NestLevel);
3720 sprintf (buffer, "_iftrue_%d", Lblnum);
3721 ifTrue = newSymbol (buffer, NestLevel);
3725 /* attach the ifTrue label to the top of it body */
3726 ifBody = createLabel (ifTrue, ifBody);
3727 /* attach a goto end to the ifBody if else is present */
3730 ifBody = newNode (NULLOP, ifBody,
3732 newAst_VALUE (symbolVal (ifEnd)),
3734 /* put the elseLabel on the else body */
3735 elseBody = createLabel (ifFalse, elseBody);
3736 /* out the end at the end of the body */
3737 elseBody = newNode (NULLOP,
3739 createLabel (ifEnd, NULL));
3743 ifBody = newNode (NULLOP, ifBody,
3744 createLabel (ifFalse, NULL));
3746 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3747 if (IS_IFX (condAst))
3750 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3752 return newNode (NULLOP, ifTree,
3753 newNode (NULLOP, ifBody, elseBody));
3757 /*-----------------------------------------------------------------*/
3758 /* createDo - creates parse tree for do */
3761 /* _docontinue_n: */
3762 /* condition_expression +-> trueLabel -> _dobody_n */
3764 /* +-> falseLabel-> _dobreak_n */
3766 /*-----------------------------------------------------------------*/
3768 createDo (symbol * trueLabel, symbol * continueLabel,
3769 symbol * falseLabel, ast * condAst, ast * doBody)
3774 /* if the body does not exist then it is simple */
3777 condAst = backPatchLabels (condAst, continueLabel, NULL);
3778 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3779 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3780 doTree->trueLabel = continueLabel;
3781 doTree->falseLabel = NULL;
3785 /* otherwise we have a body */
3786 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3788 /* attach the body label to the top */
3789 doBody = createLabel (trueLabel, doBody);
3790 /* attach the continue label to end of body */
3791 doBody = newNode (NULLOP, doBody,
3792 createLabel (continueLabel, NULL));
3794 /* now put the break label at the end */
3795 if (IS_IFX (condAst))
3798 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3800 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3802 /* putting it together */
3803 return newNode (NULLOP, doBody, doTree);
3806 /*-----------------------------------------------------------------*/
3807 /* createFor - creates parse tree for 'for' statement */
3810 /* condExpr +-> trueLabel -> _forbody_n */
3812 /* +-> falseLabel-> _forbreak_n */
3815 /* _forcontinue_n: */
3817 /* goto _forcond_n ; */
3819 /*-----------------------------------------------------------------*/
3821 createFor (symbol * trueLabel, symbol * continueLabel,
3822 symbol * falseLabel, symbol * condLabel,
3823 ast * initExpr, ast * condExpr, ast * loopExpr,
3828 /* if loopexpression not present then we can generate it */
3829 /* the same way as a while */
3831 return newNode (NULLOP, initExpr,
3832 createWhile (trueLabel, continueLabel,
3833 falseLabel, condExpr, forBody));
3834 /* vanilla for statement */
3835 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3837 if (condExpr && !IS_IFX (condExpr))
3838 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3841 /* attach condition label to condition */
3842 condExpr = createLabel (condLabel, condExpr);
3844 /* attach body label to body */
3845 forBody = createLabel (trueLabel, forBody);
3847 /* attach continue to forLoop expression & attach */
3848 /* goto the forcond @ and of loopExpression */
3849 loopExpr = createLabel (continueLabel,
3853 newAst_VALUE (symbolVal (condLabel)),
3855 /* now start putting them together */
3856 forTree = newNode (NULLOP, initExpr, condExpr);
3857 forTree = newNode (NULLOP, forTree, forBody);
3858 forTree = newNode (NULLOP, forTree, loopExpr);
3859 /* finally add the break label */
3860 forTree = newNode (NULLOP, forTree,
3861 createLabel (falseLabel, NULL));
3865 /*-----------------------------------------------------------------*/
3866 /* createWhile - creates parse tree for while statement */
3867 /* the while statement will be created as follows */
3869 /* _while_continue_n: */
3870 /* condition_expression +-> trueLabel -> _while_boby_n */
3872 /* +-> falseLabel -> _while_break_n */
3873 /* _while_body_n: */
3875 /* goto _while_continue_n */
3876 /* _while_break_n: */
3877 /*-----------------------------------------------------------------*/
3879 createWhile (symbol * trueLabel, symbol * continueLabel,
3880 symbol * falseLabel, ast * condExpr, ast * whileBody)
3884 /* put the continue label */
3885 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3886 condExpr = createLabel (continueLabel, condExpr);
3887 condExpr->lineno = 0;
3889 /* put the body label in front of the body */
3890 whileBody = createLabel (trueLabel, whileBody);
3891 whileBody->lineno = 0;
3892 /* put a jump to continue at the end of the body */
3893 /* and put break label at the end of the body */
3894 whileBody = newNode (NULLOP,
3897 newAst_VALUE (symbolVal (continueLabel)),
3898 createLabel (falseLabel, NULL)));
3900 /* put it all together */
3901 if (IS_IFX (condExpr))
3902 whileTree = condExpr;
3905 whileTree = newNode (IFX, condExpr, NULL);
3906 /* put the true & false labels in place */
3907 whileTree->trueLabel = trueLabel;
3908 whileTree->falseLabel = falseLabel;
3911 return newNode (NULLOP, whileTree, whileBody);
3914 /*-----------------------------------------------------------------*/
3915 /* optimizeGetHbit - get highest order bit of the expression */
3916 /*-----------------------------------------------------------------*/
3918 optimizeGetHbit (ast * tree)
3921 /* if this is not a bit and */
3922 if (!IS_BITAND (tree))
3925 /* will look for tree of the form
3926 ( expr >> ((sizeof expr) -1) ) & 1 */
3927 if (!IS_AST_LIT_VALUE (tree->right))
3930 if (AST_LIT_VALUE (tree->right) != 1)
3933 if (!IS_RIGHT_OP (tree->left))
3936 if (!IS_AST_LIT_VALUE (tree->left->right))
3939 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3940 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3943 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3947 /*-----------------------------------------------------------------*/
3948 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3949 /*-----------------------------------------------------------------*/
3951 optimizeRRCRLC (ast * root)
3953 /* will look for trees of the form
3954 (?expr << 1) | (?expr >> 7) or
3955 (?expr >> 7) | (?expr << 1) will make that
3956 into a RLC : operation ..
3958 (?expr >> 1) | (?expr << 7) or
3959 (?expr << 7) | (?expr >> 1) will make that
3960 into a RRC operation
3961 note : by 7 I mean (number of bits required to hold the
3963 /* if the root operations is not a | operation the not */
3964 if (!IS_BITOR (root))
3967 /* I have to think of a better way to match patterns this sucks */
3968 /* that aside let start looking for the first case : I use a the
3969 negative check a lot to improve the efficiency */
3970 /* (?expr << 1) | (?expr >> 7) */
3971 if (IS_LEFT_OP (root->left) &&
3972 IS_RIGHT_OP (root->right))
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 expression */
3983 if (!isAstEqual (root->left->left,
3987 if (AST_LIT_VALUE (root->left->right) != 1)
3990 if (AST_LIT_VALUE (root->right->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);
3999 /* check for second case */
4000 /* (?expr >> 7) | (?expr << 1) */
4001 if (IS_LEFT_OP (root->right) &&
4002 IS_RIGHT_OP (root->left))
4005 if (!SPEC_USIGN (TETYPE (root->left->left)))
4008 if (!IS_AST_LIT_VALUE (root->left->right) ||
4009 !IS_AST_LIT_VALUE (root->right->right))
4012 /* make sure it is the same symbol */
4013 if (!isAstEqual (root->left->left,
4017 if (AST_LIT_VALUE (root->right->right) != 1)
4020 if (AST_LIT_VALUE (root->left->right) !=
4021 (getSize (TTYPE (root->left->left)) * 8 - 1))
4024 /* whew got the first case : create the AST */
4025 return newNode (RLC, root->left->left, NULL);
4030 /* third case for RRC */
4031 /* (?symbol >> 1) | (?symbol << 7) */
4032 if (IS_LEFT_OP (root->right) &&
4033 IS_RIGHT_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->left->right) != 1)
4051 if (AST_LIT_VALUE (root->right->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 /* fourth and last case for now */
4061 /* (?symbol << 7) | (?symbol >> 1) */
4062 if (IS_RIGHT_OP (root->right) &&
4063 IS_LEFT_OP (root->left))
4066 if (!SPEC_USIGN (TETYPE (root->left->left)))
4069 if (!IS_AST_LIT_VALUE (root->left->right) ||
4070 !IS_AST_LIT_VALUE (root->right->right))
4073 /* make sure it is the same symbol */
4074 if (!isAstEqual (root->left->left,
4078 if (AST_LIT_VALUE (root->right->right) != 1)
4081 if (AST_LIT_VALUE (root->left->right) !=
4082 (getSize (TTYPE (root->left->left)) * 8 - 1))
4085 /* whew got the first case : create the AST */
4086 return newNode (RRC, root->left->left, NULL);
4090 /* not found return root */
4094 /*-----------------------------------------------------------------*/
4095 /* optimizeCompare - otimizes compares for bit variables */
4096 /*-----------------------------------------------------------------*/
4098 optimizeCompare (ast * root)
4100 ast *optExpr = NULL;
4103 unsigned int litValue;
4105 /* if nothing then return nothing */
4109 /* if not a compare op then do leaves */
4110 if (!IS_COMPARE_OP (root))
4112 root->left = optimizeCompare (root->left);
4113 root->right = optimizeCompare (root->right);
4117 /* if left & right are the same then depending
4118 of the operation do */
4119 if (isAstEqual (root->left, root->right))
4121 switch (root->opval.op)
4126 optExpr = newAst_VALUE (constVal ("0"));
4131 optExpr = newAst_VALUE (constVal ("1"));
4135 return decorateType (optExpr);
4138 vleft = (root->left->type == EX_VALUE ?
4139 root->left->opval.val : NULL);
4141 vright = (root->right->type == EX_VALUE ?
4142 root->right->opval.val : NULL);
4144 /* if left is a BITVAR in BITSPACE */
4145 /* and right is a LITERAL then opt- */
4146 /* imize else do nothing */
4147 if (vleft && vright &&
4148 IS_BITVAR (vleft->etype) &&
4149 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4150 IS_LITERAL (vright->etype))
4153 /* if right side > 1 then comparison may never succeed */
4154 if ((litValue = (int) floatFromVal (vright)) > 1)
4156 werror (W_BAD_COMPARE);
4162 switch (root->opval.op)
4164 case '>': /* bit value greater than 1 cannot be */
4165 werror (W_BAD_COMPARE);
4169 case '<': /* bit value < 1 means 0 */
4171 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4174 case LE_OP: /* bit value <= 1 means no check */
4175 optExpr = newAst_VALUE (vright);
4178 case GE_OP: /* bit value >= 1 means only check for = */
4180 optExpr = newAst_VALUE (vleft);
4185 { /* literal is zero */
4186 switch (root->opval.op)
4188 case '<': /* bit value < 0 cannot be */
4189 werror (W_BAD_COMPARE);
4193 case '>': /* bit value > 0 means 1 */
4195 optExpr = newAst_VALUE (vleft);
4198 case LE_OP: /* bit value <= 0 means no check */
4199 case GE_OP: /* bit value >= 0 means no check */
4200 werror (W_BAD_COMPARE);
4204 case EQ_OP: /* bit == 0 means ! of bit */
4205 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4209 return decorateType (resolveSymbols (optExpr));
4210 } /* end-of-if of BITVAR */
4215 /*-----------------------------------------------------------------*/
4216 /* addSymToBlock : adds the symbol to the first block we find */
4217 /*-----------------------------------------------------------------*/
4219 addSymToBlock (symbol * sym, ast * tree)
4221 /* reached end of tree or a leaf */
4222 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4226 if (IS_AST_OP (tree) &&
4227 tree->opval.op == BLOCK)
4230 symbol *lsym = copySymbol (sym);
4232 lsym->next = AST_VALUES (tree, sym);
4233 AST_VALUES (tree, sym) = lsym;
4237 addSymToBlock (sym, tree->left);
4238 addSymToBlock (sym, tree->right);
4241 /*-----------------------------------------------------------------*/
4242 /* processRegParms - do processing for register parameters */
4243 /*-----------------------------------------------------------------*/
4245 processRegParms (value * args, ast * body)
4249 if (IS_REGPARM (args->etype))
4250 addSymToBlock (args->sym, body);
4255 /*-----------------------------------------------------------------*/
4256 /* resetParmKey - resets the operandkeys for the symbols */
4257 /*-----------------------------------------------------------------*/
4258 DEFSETFUNC (resetParmKey)
4269 /*-----------------------------------------------------------------*/
4270 /* createFunction - This is the key node that calls the iCode for */
4271 /* generating the code for a function. Note code */
4272 /* is generated function by function, later when */
4273 /* add inter-procedural analysis this will change */
4274 /*-----------------------------------------------------------------*/
4276 createFunction (symbol * name, ast * body)
4282 iCode *piCode = NULL;
4284 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4285 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4287 /* if check function return 0 then some problem */
4288 if (checkFunction (name, NULL) == 0)
4291 /* create a dummy block if none exists */
4293 body = newNode (BLOCK, NULL, NULL);
4297 /* check if the function name already in the symbol table */
4298 if ((csym = findSym (SymbolTab, NULL, name->name)))
4301 /* special case for compiler defined functions
4302 we need to add the name to the publics list : this
4303 actually means we are now compiling the compiler
4307 addSet (&publics, name);
4313 allocVariables (name);
4315 name->lastLine = yylineno;
4318 /* set the stack pointer */
4319 /* PENDING: check this for the mcs51 */
4320 stackPtr = -port->stack.direction * port->stack.call_overhead;
4321 if (IFFUNC_ISISR (name->type))
4322 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4323 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4324 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4326 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4328 fetype = getSpec (name->type); /* get the specifier for the function */
4329 /* if this is a reentrant function then */
4330 if (IFFUNC_ISREENT (name->type))
4333 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4335 /* do processing for parameters that are passed in registers */
4336 processRegParms (FUNC_ARGS(name->type), body);
4338 /* set the stack pointer */
4342 /* allocate & autoinit the block variables */
4343 processBlockVars (body, &stack, ALLOCATE);
4345 /* save the stack information */
4346 if (options.useXstack)
4347 name->xstack = SPEC_STAK (fetype) = stack;
4349 name->stack = SPEC_STAK (fetype) = stack;
4351 /* name needs to be mangled */
4352 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4354 body = resolveSymbols (body); /* resolve the symbols */
4355 body = decorateType (body); /* propagateType & do semantic checks */
4357 ex = newAst_VALUE (symbolVal (name)); /* create name */
4358 ex = newNode (FUNCTION, ex, body);
4359 ex->values.args = FUNC_ARGS(name->type);
4361 if (options.dump_tree) PA(ex);
4364 werror (E_FUNC_NO_CODE, name->name);
4368 /* create the node & generate intermediate code */
4370 codeOutFile = code->oFile;
4371 piCode = iCodeFromAst (ex);
4375 werror (E_FUNC_NO_CODE, name->name);
4379 eBBlockFromiCode (piCode);
4381 /* if there are any statics then do them */
4384 GcurMemmap = statsg;
4385 codeOutFile = statsg->oFile;
4386 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4392 /* dealloc the block variables */
4393 processBlockVars (body, &stack, DEALLOCATE);
4394 /* deallocate paramaters */
4395 deallocParms (FUNC_ARGS(name->type));
4397 if (IFFUNC_ISREENT (name->type))
4400 /* we are done freeup memory & cleanup */
4402 if (port->reset_labelKey) labelKey = 1;
4404 FUNC_HASBODY(name->type) = 1;
4405 addSet (&operKeyReset, name);
4406 applyToSet (operKeyReset, resetParmKey);
4409 cdbStructBlock (1, cdbFile);
4411 cleanUpLevel (LabelTab, 0);
4412 cleanUpBlock (StructTab, 1);
4413 cleanUpBlock (TypedefTab, 1);
4415 xstack->syms = NULL;
4416 istack->syms = NULL;
4421 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4422 /*-----------------------------------------------------------------*/
4423 /* ast_print : prints the ast (for debugging purposes) */
4424 /*-----------------------------------------------------------------*/
4426 void ast_print (ast * tree, FILE *outfile, int indent)
4431 /* can print only decorated trees */
4432 if (!tree->decorated) return;
4434 /* if any child is an error | this one is an error do nothing */
4435 if (tree->isError ||
4436 (tree->left && tree->left->isError) ||
4437 (tree->right && tree->right->isError)) {
4438 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4442 /* print the line */
4443 /* if not block & function */
4444 if (tree->type == EX_OP &&
4445 (tree->opval.op != FUNCTION &&
4446 tree->opval.op != BLOCK &&
4447 tree->opval.op != NULLOP)) {
4450 if (tree->opval.op == FUNCTION) {
4452 value *args=FUNC_ARGS(tree->left->opval.val->type);
4453 fprintf(outfile,"FUNCTION (%s=%p) type (",
4454 tree->left->opval.val->name, tree);
4455 printTypeChain (tree->ftype,outfile);
4456 fprintf(outfile,") args (");
4459 fprintf (outfile, ", ");
4461 printTypeChain (args ? args->type : NULL, outfile);
4463 args= args ? args->next : NULL;
4465 fprintf(outfile,")\n");
4466 ast_print(tree->left,outfile,indent);
4467 ast_print(tree->right,outfile,indent);
4470 if (tree->opval.op == BLOCK) {
4471 symbol *decls = tree->values.sym;
4472 INDENT(indent,outfile);
4473 fprintf(outfile,"{\n");
4475 INDENT(indent+2,outfile);
4476 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4477 decls->name, decls);
4478 printTypeChain(decls->type,outfile);
4479 fprintf(outfile,")\n");
4481 decls = decls->next;
4483 ast_print(tree->right,outfile,indent+2);
4484 INDENT(indent,outfile);
4485 fprintf(outfile,"}\n");
4488 if (tree->opval.op == NULLOP) {
4489 fprintf(outfile,"\n");
4490 ast_print(tree->left,outfile,indent);
4491 fprintf(outfile,"\n");
4492 ast_print(tree->right,outfile,indent);
4495 INDENT(indent,outfile);
4497 /*------------------------------------------------------------------*/
4498 /*----------------------------*/
4499 /* leaf has been reached */
4500 /*----------------------------*/
4501 /* if this is of type value */
4502 /* just get the type */
4503 if (tree->type == EX_VALUE) {
4505 if (IS_LITERAL (tree->opval.val->etype)) {
4506 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4507 (int) floatFromVal(tree->opval.val),
4508 (int) floatFromVal(tree->opval.val),
4509 floatFromVal(tree->opval.val));
4510 } else if (tree->opval.val->sym) {
4511 /* if the undefined flag is set then give error message */
4512 if (tree->opval.val->sym->undefined) {
4513 fprintf(outfile,"UNDEFINED SYMBOL ");
4515 fprintf(outfile,"SYMBOL ");
4517 fprintf(outfile,"(%s=%p)",
4518 tree->opval.val->sym->name,tree);
4521 fprintf(outfile," type (");
4522 printTypeChain(tree->ftype,outfile);
4523 fprintf(outfile,")\n");
4525 fprintf(outfile,"\n");
4530 /* if type link for the case of cast */
4531 if (tree->type == EX_LINK) {
4532 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4533 printTypeChain(tree->opval.lnk,outfile);
4534 fprintf(outfile,")\n");
4539 /* depending on type of operator do */
4541 switch (tree->opval.op) {
4542 /*------------------------------------------------------------------*/
4543 /*----------------------------*/
4545 /*----------------------------*/
4547 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4548 printTypeChain(tree->ftype,outfile);
4549 fprintf(outfile,")\n");
4550 ast_print(tree->left,outfile,indent+2);
4551 ast_print(tree->right,outfile,indent+2);
4554 /*------------------------------------------------------------------*/
4555 /*----------------------------*/
4557 /*----------------------------*/
4559 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4560 printTypeChain(tree->ftype,outfile);
4561 fprintf(outfile,")\n");
4562 ast_print(tree->left,outfile,indent+2);
4563 ast_print(tree->right,outfile,indent+2);
4566 /*------------------------------------------------------------------*/
4567 /*----------------------------*/
4568 /* struct/union pointer */
4569 /*----------------------------*/
4571 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+2);
4575 ast_print(tree->right,outfile,indent+2);
4578 /*------------------------------------------------------------------*/
4579 /*----------------------------*/
4580 /* ++/-- operation */
4581 /*----------------------------*/
4582 case INC_OP: /* incerement operator unary so left only */
4583 fprintf(outfile,"INC_OP (%p) type (",tree);
4584 printTypeChain(tree->ftype,outfile);
4585 fprintf(outfile,")\n");
4586 ast_print(tree->left,outfile,indent+2);
4590 fprintf(outfile,"DEC_OP (%p) type (",tree);
4591 printTypeChain(tree->ftype,outfile);
4592 fprintf(outfile,")\n");
4593 ast_print(tree->left,outfile,indent+2);
4596 /*------------------------------------------------------------------*/
4597 /*----------------------------*/
4599 /*----------------------------*/
4602 fprintf(outfile,"& (%p) type (",tree);
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->left,outfile,indent+2);
4606 ast_print(tree->right,outfile,indent+2);
4608 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4609 printTypeChain(tree->ftype,outfile);
4610 fprintf(outfile,")\n");
4611 ast_print(tree->left,outfile,indent+2);
4612 ast_print(tree->right,outfile,indent+2);
4615 /*----------------------------*/
4617 /*----------------------------*/
4619 fprintf(outfile,"OR (%p) type (",tree);
4620 printTypeChain(tree->ftype,outfile);
4621 fprintf(outfile,")\n");
4622 ast_print(tree->left,outfile,indent+2);
4623 ast_print(tree->right,outfile,indent+2);
4625 /*------------------------------------------------------------------*/
4626 /*----------------------------*/
4628 /*----------------------------*/
4630 fprintf(outfile,"XOR (%p) type (",tree);
4631 printTypeChain(tree->ftype,outfile);
4632 fprintf(outfile,")\n");
4633 ast_print(tree->left,outfile,indent+2);
4634 ast_print(tree->right,outfile,indent+2);
4637 /*------------------------------------------------------------------*/
4638 /*----------------------------*/
4640 /*----------------------------*/
4642 fprintf(outfile,"DIV (%p) type (",tree);
4643 printTypeChain(tree->ftype,outfile);
4644 fprintf(outfile,")\n");
4645 ast_print(tree->left,outfile,indent+2);
4646 ast_print(tree->right,outfile,indent+2);
4648 /*------------------------------------------------------------------*/
4649 /*----------------------------*/
4651 /*----------------------------*/
4653 fprintf(outfile,"MOD (%p) type (",tree);
4654 printTypeChain(tree->ftype,outfile);
4655 fprintf(outfile,")\n");
4656 ast_print(tree->left,outfile,indent+2);
4657 ast_print(tree->right,outfile,indent+2);
4660 /*------------------------------------------------------------------*/
4661 /*----------------------------*/
4662 /* address dereference */
4663 /*----------------------------*/
4664 case '*': /* can be unary : if right is null then unary operation */
4666 fprintf(outfile,"DEREF (%p) type (",tree);
4667 printTypeChain(tree->ftype,outfile);
4668 fprintf(outfile,")\n");
4669 ast_print(tree->left,outfile,indent+2);
4672 /*------------------------------------------------------------------*/
4673 /*----------------------------*/
4674 /* multiplication */
4675 /*----------------------------*/
4676 fprintf(outfile,"MULT (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+2);
4680 ast_print(tree->right,outfile,indent+2);
4684 /*------------------------------------------------------------------*/
4685 /*----------------------------*/
4686 /* unary '+' operator */
4687 /*----------------------------*/
4691 fprintf(outfile,"UPLUS (%p) type (",tree);
4692 printTypeChain(tree->ftype,outfile);
4693 fprintf(outfile,")\n");
4694 ast_print(tree->left,outfile,indent+2);
4696 /*------------------------------------------------------------------*/
4697 /*----------------------------*/
4699 /*----------------------------*/
4700 fprintf(outfile,"ADD (%p) type (",tree);
4701 printTypeChain(tree->ftype,outfile);
4702 fprintf(outfile,")\n");
4703 ast_print(tree->left,outfile,indent+2);
4704 ast_print(tree->right,outfile,indent+2);
4707 /*------------------------------------------------------------------*/
4708 /*----------------------------*/
4710 /*----------------------------*/
4711 case '-': /* can be unary */
4713 fprintf(outfile,"UMINUS (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+2);
4718 /*------------------------------------------------------------------*/
4719 /*----------------------------*/
4721 /*----------------------------*/
4722 fprintf(outfile,"SUB (%p) type (",tree);
4723 printTypeChain(tree->ftype,outfile);
4724 fprintf(outfile,")\n");
4725 ast_print(tree->left,outfile,indent+2);
4726 ast_print(tree->right,outfile,indent+2);
4729 /*------------------------------------------------------------------*/
4730 /*----------------------------*/
4732 /*----------------------------*/
4734 fprintf(outfile,"COMPL (%p) type (",tree);
4735 printTypeChain(tree->ftype,outfile);
4736 fprintf(outfile,")\n");
4737 ast_print(tree->left,outfile,indent+2);
4739 /*------------------------------------------------------------------*/
4740 /*----------------------------*/
4742 /*----------------------------*/
4744 fprintf(outfile,"NOT (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+2);
4749 /*------------------------------------------------------------------*/
4750 /*----------------------------*/
4752 /*----------------------------*/
4754 fprintf(outfile,"RRC (%p) type (",tree);
4755 printTypeChain(tree->ftype,outfile);
4756 fprintf(outfile,")\n");
4757 ast_print(tree->left,outfile,indent+2);
4761 fprintf(outfile,"RLC (%p) type (",tree);
4762 printTypeChain(tree->ftype,outfile);
4763 fprintf(outfile,")\n");
4764 ast_print(tree->left,outfile,indent+2);
4767 fprintf(outfile,"GETHBIT (%p) type (",tree);
4768 printTypeChain(tree->ftype,outfile);
4769 fprintf(outfile,")\n");
4770 ast_print(tree->left,outfile,indent+2);
4773 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4774 printTypeChain(tree->ftype,outfile);
4775 fprintf(outfile,")\n");
4776 ast_print(tree->left,outfile,indent+2);
4777 ast_print(tree->right,outfile,indent+2);
4780 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4781 printTypeChain(tree->ftype,outfile);
4782 fprintf(outfile,")\n");
4783 ast_print(tree->left,outfile,indent+2);
4784 ast_print(tree->right,outfile,indent+2);
4786 /*------------------------------------------------------------------*/
4787 /*----------------------------*/
4789 /*----------------------------*/
4790 case CAST: /* change the type */
4791 fprintf(outfile,"CAST (%p) from type (",tree);
4792 printTypeChain(tree->right->ftype,outfile);
4793 fprintf(outfile,") to type (");
4794 printTypeChain(tree->ftype,outfile);
4795 fprintf(outfile,")\n");
4796 ast_print(tree->right,outfile,indent+2);
4800 fprintf(outfile,"ANDAND (%p) type (",tree);
4801 printTypeChain(tree->ftype,outfile);
4802 fprintf(outfile,")\n");
4803 ast_print(tree->left,outfile,indent+2);
4804 ast_print(tree->right,outfile,indent+2);
4807 fprintf(outfile,"OROR (%p) type (",tree);
4808 printTypeChain(tree->ftype,outfile);
4809 fprintf(outfile,")\n");
4810 ast_print(tree->left,outfile,indent+2);
4811 ast_print(tree->right,outfile,indent+2);
4814 /*------------------------------------------------------------------*/
4815 /*----------------------------*/
4816 /* comparison operators */
4817 /*----------------------------*/
4819 fprintf(outfile,"GT(>) (%p) type (",tree);
4820 printTypeChain(tree->ftype,outfile);
4821 fprintf(outfile,")\n");
4822 ast_print(tree->left,outfile,indent+2);
4823 ast_print(tree->right,outfile,indent+2);
4826 fprintf(outfile,"LT(<) (%p) type (",tree);
4827 printTypeChain(tree->ftype,outfile);
4828 fprintf(outfile,")\n");
4829 ast_print(tree->left,outfile,indent+2);
4830 ast_print(tree->right,outfile,indent+2);
4833 fprintf(outfile,"LE(<=) (%p) type (",tree);
4834 printTypeChain(tree->ftype,outfile);
4835 fprintf(outfile,")\n");
4836 ast_print(tree->left,outfile,indent+2);
4837 ast_print(tree->right,outfile,indent+2);
4840 fprintf(outfile,"GE(>=) (%p) type (",tree);
4841 printTypeChain(tree->ftype,outfile);
4842 fprintf(outfile,")\n");
4843 ast_print(tree->left,outfile,indent+2);
4844 ast_print(tree->right,outfile,indent+2);
4847 fprintf(outfile,"EQ(==) (%p) type (",tree);
4848 printTypeChain(tree->ftype,outfile);
4849 fprintf(outfile,")\n");
4850 ast_print(tree->left,outfile,indent+2);
4851 ast_print(tree->right,outfile,indent+2);
4854 fprintf(outfile,"NE(!=) (%p) type (",tree);
4855 printTypeChain(tree->ftype,outfile);
4856 fprintf(outfile,")\n");
4857 ast_print(tree->left,outfile,indent+2);
4858 ast_print(tree->right,outfile,indent+2);
4859 /*------------------------------------------------------------------*/
4860 /*----------------------------*/
4862 /*----------------------------*/
4863 case SIZEOF: /* evaluate wihout code generation */
4864 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4867 /*------------------------------------------------------------------*/
4868 /*----------------------------*/
4869 /* conditional operator '?' */
4870 /*----------------------------*/
4872 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4873 printTypeChain(tree->ftype,outfile);
4874 fprintf(outfile,")\n");
4875 ast_print(tree->left,outfile,indent+2);
4876 ast_print(tree->right,outfile,indent+2);
4880 fprintf(outfile,"COLON(:) (%p) type (",tree);
4881 printTypeChain(tree->ftype,outfile);
4882 fprintf(outfile,")\n");
4883 ast_print(tree->left,outfile,indent+2);
4884 ast_print(tree->right,outfile,indent+2);
4887 /*------------------------------------------------------------------*/
4888 /*----------------------------*/
4889 /* assignment operators */
4890 /*----------------------------*/
4892 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4893 printTypeChain(tree->ftype,outfile);
4894 fprintf(outfile,")\n");
4895 ast_print(tree->left,outfile,indent+2);
4896 ast_print(tree->right,outfile,indent+2);
4899 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4900 printTypeChain(tree->ftype,outfile);
4901 fprintf(outfile,")\n");
4902 ast_print(tree->left,outfile,indent+2);
4903 ast_print(tree->right,outfile,indent+2);
4906 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4907 printTypeChain(tree->ftype,outfile);
4908 fprintf(outfile,")\n");
4909 ast_print(tree->left,outfile,indent+2);
4910 ast_print(tree->right,outfile,indent+2);
4913 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4914 printTypeChain(tree->ftype,outfile);
4915 fprintf(outfile,")\n");
4916 ast_print(tree->left,outfile,indent+2);
4917 ast_print(tree->right,outfile,indent+2);
4920 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4921 printTypeChain(tree->ftype,outfile);
4922 fprintf(outfile,")\n");
4923 ast_print(tree->left,outfile,indent+2);
4924 ast_print(tree->right,outfile,indent+2);
4927 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4928 printTypeChain(tree->ftype,outfile);
4929 fprintf(outfile,")\n");
4930 ast_print(tree->left,outfile,indent+2);
4931 ast_print(tree->right,outfile,indent+2);
4934 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4935 printTypeChain(tree->ftype,outfile);
4936 fprintf(outfile,")\n");
4937 ast_print(tree->left,outfile,indent+2);
4938 ast_print(tree->right,outfile,indent+2);
4940 /*------------------------------------------------------------------*/
4941 /*----------------------------*/
4943 /*----------------------------*/
4945 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4946 printTypeChain(tree->ftype,outfile);
4947 fprintf(outfile,")\n");
4948 ast_print(tree->left,outfile,indent+2);
4949 ast_print(tree->right,outfile,indent+2);
4951 /*------------------------------------------------------------------*/
4952 /*----------------------------*/
4954 /*----------------------------*/
4956 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4957 printTypeChain(tree->ftype,outfile);
4958 fprintf(outfile,")\n");
4959 ast_print(tree->left,outfile,indent+2);
4960 ast_print(tree->right,outfile,indent+2);
4962 /*------------------------------------------------------------------*/
4963 /*----------------------------*/
4964 /* straight assignemnt */
4965 /*----------------------------*/
4967 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4968 printTypeChain(tree->ftype,outfile);
4969 fprintf(outfile,")\n");
4970 ast_print(tree->left,outfile,indent+2);
4971 ast_print(tree->right,outfile,indent+2);
4973 /*------------------------------------------------------------------*/
4974 /*----------------------------*/
4975 /* comma operator */
4976 /*----------------------------*/
4978 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4979 printTypeChain(tree->ftype,outfile);
4980 fprintf(outfile,")\n");
4981 ast_print(tree->left,outfile,indent+2);
4982 ast_print(tree->right,outfile,indent+2);
4984 /*------------------------------------------------------------------*/
4985 /*----------------------------*/
4987 /*----------------------------*/
4990 fprintf(outfile,"CALL (%p) type (",tree);
4991 printTypeChain(tree->ftype,outfile);
4992 fprintf(outfile,")\n");
4993 ast_print(tree->left,outfile,indent+2);
4994 ast_print(tree->right,outfile,indent+2);
4997 fprintf(outfile,"PARMS\n");
4998 ast_print(tree->left,outfile,indent+2);
4999 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5000 ast_print(tree->right,outfile,indent+2);
5003 /*------------------------------------------------------------------*/
5004 /*----------------------------*/
5005 /* return statement */
5006 /*----------------------------*/
5008 fprintf(outfile,"RETURN (%p) type (",tree);
5010 printTypeChain(tree->right->ftype,outfile);
5012 fprintf(outfile,")\n");
5013 ast_print(tree->right,outfile,indent+2);
5015 /*------------------------------------------------------------------*/
5016 /*----------------------------*/
5017 /* label statement */
5018 /*----------------------------*/
5020 fprintf(outfile,"LABEL (%p)\n",tree);
5021 ast_print(tree->left,outfile,indent+2);
5022 ast_print(tree->right,outfile,indent);
5024 /*------------------------------------------------------------------*/
5025 /*----------------------------*/
5026 /* switch statement */
5027 /*----------------------------*/
5031 fprintf(outfile,"SWITCH (%p) ",tree);
5032 ast_print(tree->left,outfile,0);
5033 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5034 INDENT(indent+2,outfile);
5035 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5036 (int) floatFromVal(val),
5037 tree->values.switchVals.swNum,
5038 (int) floatFromVal(val));
5040 ast_print(tree->right,outfile,indent);
5043 /*------------------------------------------------------------------*/
5044 /*----------------------------*/
5046 /*----------------------------*/
5048 fprintf(outfile,"IF (%p) \n",tree);
5049 ast_print(tree->left,outfile,indent+2);
5050 if (tree->trueLabel) {
5051 INDENT(indent,outfile);
5052 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5054 if (tree->falseLabel) {
5055 INDENT(indent,outfile);
5056 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5058 ast_print(tree->right,outfile,indent+2);
5060 /*------------------------------------------------------------------*/
5061 /*----------------------------*/
5063 /*----------------------------*/
5065 fprintf(outfile,"FOR (%p) \n",tree);
5066 if (AST_FOR( tree, initExpr)) {
5067 INDENT(indent+2,outfile);
5068 fprintf(outfile,"INIT EXPR ");
5069 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5071 if (AST_FOR( tree, condExpr)) {
5072 INDENT(indent+2,outfile);
5073 fprintf(outfile,"COND EXPR ");
5074 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5076 if (AST_FOR( tree, loopExpr)) {
5077 INDENT(indent+2,outfile);
5078 fprintf(outfile,"LOOP EXPR ");
5079 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5081 fprintf(outfile,"FOR LOOP BODY \n");
5082 ast_print(tree->left,outfile,indent+2);
5091 ast_print(t,stdout,0);