1 //#define JWK_FIX_SHIFT_BUG
2 //#define JWK_FIX_IMPLICIT_CAST
3 /*-------------------------------------------------------------------------
4 SDCCast.c - source file for parser support & all ast related routines
6 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeGetHbit (ast *);
58 ast *backPatchLabels (ast *, symbol *, symbol *);
61 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
66 printTypeChain (tree->ftype, stdout);
71 /*-----------------------------------------------------------------*/
72 /* newAst - creates a fresh node for an expression tree */
73 /*-----------------------------------------------------------------*/
75 newAst_ (unsigned type)
78 static int oldLineno = 0;
80 ex = Safe_alloc ( sizeof (ast));
83 ex->lineno = (noLineno ? oldLineno : yylineno);
84 ex->filename = currFname;
85 ex->level = NestLevel;
86 ex->block = currBlockno;
87 ex->initMode = inInitMode;
92 newAst_VALUE (value * val)
94 ast *ex = newAst_ (EX_VALUE);
100 newAst_OP (unsigned op)
102 ast *ex = newAst_ (EX_OP);
108 newAst_LINK (sym_link * val)
110 ast *ex = newAst_ (EX_LINK);
116 newAst_STMNT (unsigned val)
118 ast *ex = newAst_ (EX_STMNT);
119 ex->opval.stmnt = val;
123 /*-----------------------------------------------------------------*/
124 /* newNode - creates a new node */
125 /*-----------------------------------------------------------------*/
127 newNode (long op, ast * left, ast * right)
138 /*-----------------------------------------------------------------*/
139 /* newIfxNode - creates a new Ifx Node */
140 /*-----------------------------------------------------------------*/
142 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
146 /* if this is a literal then we already know the result */
147 if (condAst->etype && IS_LITERAL (condAst->etype))
149 /* then depending on the expression value */
150 if (floatFromVal (condAst->opval.val))
151 ifxNode = newNode (GOTO,
152 newAst_VALUE (symbolVal (trueLabel)),
155 ifxNode = newNode (GOTO,
156 newAst_VALUE (symbolVal (falseLabel)),
161 ifxNode = newNode (IFX, condAst, NULL);
162 ifxNode->trueLabel = trueLabel;
163 ifxNode->falseLabel = falseLabel;
169 /*-----------------------------------------------------------------*/
170 /* copyAstValues - copies value portion of ast if needed */
171 /*-----------------------------------------------------------------*/
173 copyAstValues (ast * dest, ast * src)
175 switch (src->opval.op)
178 dest->values.sym = copySymbolChain (src->values.sym);
182 dest->values.switchVals.swVals =
183 copyValue (src->values.switchVals.swVals);
184 dest->values.switchVals.swDefault =
185 src->values.switchVals.swDefault;
186 dest->values.switchVals.swNum =
187 src->values.switchVals.swNum;
191 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
192 strcpy (dest->values.inlineasm, src->values.inlineasm);
196 dest->values.constlist = copyLiteralList(src->values.constlist);
200 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
201 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
202 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
203 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
204 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
205 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
206 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
211 /*-----------------------------------------------------------------*/
212 /* copyAst - makes a copy of a given astession */
213 /*-----------------------------------------------------------------*/
222 dest = Safe_alloc ( sizeof (ast));
224 dest->type = src->type;
225 dest->lineno = src->lineno;
226 dest->level = src->level;
227 dest->funcName = src->funcName;
230 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
232 /* if this is a leaf */
234 if (src->type == EX_VALUE)
236 dest->opval.val = copyValue (src->opval.val);
241 if (src->type == EX_LINK)
243 dest->opval.lnk = copyLinkChain (src->opval.lnk);
247 dest->opval.op = src->opval.op;
249 /* if this is a node that has special values */
250 copyAstValues (dest, src);
252 dest->trueLabel = copySymbol (src->trueLabel);
253 dest->falseLabel = copySymbol (src->falseLabel);
254 dest->left = copyAst (src->left);
255 dest->right = copyAst (src->right);
261 /*-----------------------------------------------------------------*/
262 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
263 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
264 /*-----------------------------------------------------------------*/
265 ast *removeIncDecOps (ast * tree) {
267 // traverse the tree and remove inc/dec ops
272 if (tree->type == EX_OP &&
273 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
280 tree->left=removeIncDecOps(tree->left);
281 tree->right=removeIncDecOps(tree->right);
286 /*-----------------------------------------------------------------*/
287 /* hasSEFcalls - returns TRUE if tree has a function call */
288 /*-----------------------------------------------------------------*/
290 hasSEFcalls (ast * tree)
295 if (tree->type == EX_OP &&
296 (tree->opval.op == CALL ||
297 tree->opval.op == PCALL ||
298 tree->opval.op == '=' ||
299 tree->opval.op == INC_OP ||
300 tree->opval.op == DEC_OP))
303 return (hasSEFcalls (tree->left) |
304 hasSEFcalls (tree->right));
307 /*-----------------------------------------------------------------*/
308 /* isAstEqual - compares two asts & returns 1 if they are equal */
309 /*-----------------------------------------------------------------*/
311 isAstEqual (ast * t1, ast * t2)
320 if (t1->type != t2->type)
326 if (t1->opval.op != t2->opval.op)
328 return (isAstEqual (t1->left, t2->left) &&
329 isAstEqual (t1->right, t2->right));
333 if (t1->opval.val->sym)
335 if (!t2->opval.val->sym)
338 return isSymbolEqual (t1->opval.val->sym,
343 if (t2->opval.val->sym)
346 return (floatFromVal (t1->opval.val) ==
347 floatFromVal (t2->opval.val));
351 /* only compare these two types */
359 /*-----------------------------------------------------------------*/
360 /* resolveSymbols - resolve symbols from the symbol table */
361 /*-----------------------------------------------------------------*/
363 resolveSymbols (ast * tree)
365 /* walk the entire tree and check for values */
366 /* with symbols if we find one then replace */
367 /* symbol with that from the symbol table */
374 /* if not block & function */
375 if (tree->type == EX_OP &&
376 (tree->opval.op != FUNCTION &&
377 tree->opval.op != BLOCK &&
378 tree->opval.op != NULLOP))
380 filename = tree->filename;
381 lineno = tree->lineno;
385 /* make sure we resolve the true & false labels for ifx */
386 if (tree->type == EX_OP && tree->opval.op == IFX)
392 if ((csym = findSym (LabelTab, tree->trueLabel,
393 tree->trueLabel->name)))
394 tree->trueLabel = csym;
396 werror (E_LABEL_UNDEF, tree->trueLabel->name);
399 if (tree->falseLabel)
401 if ((csym = findSym (LabelTab,
403 tree->falseLabel->name)))
404 tree->falseLabel = csym;
406 werror (E_LABEL_UNDEF, tree->falseLabel->name);
411 /* if this is a label resolve it from the labelTab */
412 if (IS_AST_VALUE (tree) &&
413 tree->opval.val->sym &&
414 tree->opval.val->sym->islbl)
417 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
418 tree->opval.val->sym->name);
421 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
423 tree->opval.val->sym = csym;
425 goto resolveChildren;
428 /* do only for leafs */
429 if (IS_AST_VALUE (tree) &&
430 tree->opval.val->sym &&
431 !tree->opval.val->sym->implicit)
434 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
436 /* if found in the symbol table & they r not the same */
437 if (csym && tree->opval.val->sym != csym)
439 tree->opval.val->sym = csym;
440 tree->opval.val->type = csym->type;
441 tree->opval.val->etype = csym->etype;
444 /* if not found in the symbol table */
445 /* mark it as undefined assume it is */
446 /* an integer in data space */
447 if (!csym && !tree->opval.val->sym->implicit)
450 /* if this is a function name then */
451 /* mark it as returning an int */
454 tree->opval.val->sym->type = newLink ();
455 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
456 tree->opval.val->sym->type->next =
457 tree->opval.val->sym->etype = newIntLink ();
458 tree->opval.val->etype = tree->opval.val->etype;
459 tree->opval.val->type = tree->opval.val->sym->type;
460 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
461 allocVariables (tree->opval.val->sym);
465 tree->opval.val->sym->undefined = 1;
466 tree->opval.val->type =
467 tree->opval.val->etype = newIntLink ();
468 tree->opval.val->sym->type =
469 tree->opval.val->sym->etype = newIntLink ();
475 resolveSymbols (tree->left);
476 resolveSymbols (tree->right);
481 /*-----------------------------------------------------------------*/
482 /* setAstLineno - walks a ast tree & sets the line number */
483 /*-----------------------------------------------------------------*/
484 int setAstLineno (ast * tree, int lineno)
489 tree->lineno = lineno;
490 setAstLineno (tree->left, lineno);
491 setAstLineno (tree->right, lineno);
495 /*-----------------------------------------------------------------*/
496 /* funcOfType :- function of type with name */
497 /*-----------------------------------------------------------------*/
499 funcOfType (char *name, sym_link * type, sym_link * argType,
503 /* create the symbol */
504 sym = newSymbol (name, 0);
506 /* setup return value */
507 sym->type = newLink ();
508 DCL_TYPE (sym->type) = FUNCTION;
509 sym->type->next = copyLinkChain (type);
510 sym->etype = getSpec (sym->type);
511 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
513 /* if arguments required */
517 args = FUNC_ARGS(sym->type) = newValue ();
521 args->type = copyLinkChain (argType);
522 args->etype = getSpec (args->type);
523 SPEC_EXTR(args->etype)=1;
526 args = args->next = newValue ();
533 allocVariables (sym);
538 /*-----------------------------------------------------------------*/
539 /* funcOfTypeVarg :- function of type with name and argtype */
540 /*-----------------------------------------------------------------*/
542 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
547 /* create the symbol */
548 sym = newSymbol (name, 0);
550 /* setup return value */
551 sym->type = newLink ();
552 DCL_TYPE (sym->type) = FUNCTION;
553 sym->type->next = typeFromStr(rtype);
554 sym->etype = getSpec (sym->type);
556 /* if arguments required */
559 args = FUNC_ARGS(sym->type) = newValue ();
561 for ( i = 0 ; i < nArgs ; i++ ) {
562 args->type = typeFromStr(atypes[i]);
563 args->etype = getSpec (args->type);
564 SPEC_EXTR(args->etype)=1;
565 if ((i + 1) == nArgs) break;
566 args = args->next = newValue ();
573 allocVariables (sym);
578 /*-----------------------------------------------------------------*/
579 /* reverseParms - will reverse a parameter tree */
580 /*-----------------------------------------------------------------*/
582 reverseParms (ast * ptree)
588 /* top down if we find a nonParm tree then quit */
589 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
592 ptree->left = ptree->right;
593 ptree->right = ttree;
594 reverseParms (ptree->left);
595 reverseParms (ptree->right);
601 /*-----------------------------------------------------------------*/
602 /* processParms - makes sure the parameters are okay and do some */
603 /* processing with them */
604 /*-----------------------------------------------------------------*/
606 processParms (ast * func,
609 int *parmNumber, // unused, although updated
612 /* if none of them exist */
613 if (!defParm && !actParm)
617 if (getenv("DEBUG_SANITY")) {
618 fprintf (stderr, "processParms: %s ", defParm->name);
620 /* make sure the type is complete and sane */
621 checkTypeSanity(defParm->etype, defParm->name);
624 /* if the function is being called via a pointer & */
625 /* it has not been defined a reentrant then we cannot */
626 /* have parameters */
627 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
629 werror (W_NONRENT_ARGS);
633 /* if defined parameters ended but actual parameters */
634 /* exist and this is not defined as a variable arg */
635 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
637 werror (E_TOO_MANY_PARMS);
641 /* if defined parameters present but no actual parameters */
642 if (defParm && !actParm)
644 werror (E_TOO_FEW_PARMS);
648 if (IS_VOID(actParm->ftype)) {
649 werror (E_VOID_VALUE_USED);
653 /* If this is a varargs function... */
654 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
659 if (IS_CAST_OP (actParm)
660 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
662 /* Parameter was explicitly typecast; don't touch it. */
666 ftype = actParm->ftype;
668 /* If it's a small integer, upcast to int. */
669 if (IS_INTEGRAL (ftype)
670 && (getSize (ftype) < (unsigned) INTSIZE))
672 #ifdef JWK_FIX_IMPLICIT_CAST
673 if (IS_AST_OP(actParm) &&
674 (actParm->opval.op == LEFT_OP ||
675 actParm->opval.op == '*' ||
676 actParm->opval.op == '+' ||
677 actParm->opval.op == '-') &&
679 // we should cast an operand instead of the result
680 actParm->decorated = 0;
681 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
683 actParm = decorateType(actParm);
685 newType = newAst_LINK(INTTYPE);
688 newType = newAst_LINK(INTTYPE);
692 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
694 newType = newAst_LINK (copyLinkChain(ftype));
695 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
698 if (IS_AGGREGATE (ftype))
700 newType = newAst_LINK (copyLinkChain (ftype));
701 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
705 /* cast required; change this op to a cast. */
706 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
708 actParm->type = EX_OP;
709 actParm->opval.op = CAST;
710 actParm->left = newType;
711 actParm->right = parmCopy;
712 decorateType (actParm);
714 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
716 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
717 processParms (func, NULL, actParm->right, parmNumber, rightmost));
722 /* if defined parameters ended but actual has not & */
724 if (!defParm && actParm &&
725 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
728 resolveSymbols (actParm);
729 /* if this is a PARAM node then match left & right */
730 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
732 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
733 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
737 /* If we have found a value node by following only right-hand links,
738 * then we know that there are no more values after us.
740 * Therefore, if there are more defined parameters, the caller didn't
743 if (rightmost && defParm->next)
745 werror (E_TOO_FEW_PARMS);
750 /* the parameter type must be at least castable */
751 if (compareType (defParm->type, actParm->ftype) == 0) {
752 werror (E_INCOMPAT_TYPES);
753 printFromToType (actParm->ftype, defParm->type);
757 /* if the parameter is castable then add the cast */
758 if (compareType (defParm->type, actParm->ftype) < 0)
760 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
762 /* now change the current one to a cast */
763 actParm->type = EX_OP;
764 actParm->opval.op = CAST;
765 actParm->left = newAst_LINK (defParm->type);
766 actParm->right = pTree;
767 actParm->etype = defParm->etype;
768 actParm->ftype = defParm->type;
769 actParm->decorated=0; /* force typechecking */
770 decorateType (actParm);
773 /* make a copy and change the regparm type to the defined parm */
774 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
775 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
776 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
780 /*-----------------------------------------------------------------*/
781 /* createIvalType - generates ival for basic types */
782 /*-----------------------------------------------------------------*/
784 createIvalType (ast * sym, sym_link * type, initList * ilist)
788 /* if initList is deep */
789 if (ilist->type == INIT_DEEP)
790 ilist = ilist->init.deep;
792 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
793 return decorateType (newNode ('=', sym, iExpr));
796 /*-----------------------------------------------------------------*/
797 /* createIvalStruct - generates initial value for structures */
798 /*-----------------------------------------------------------------*/
800 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
807 sflds = SPEC_STRUCT (type)->fields;
808 if (ilist->type != INIT_DEEP)
810 werror (E_INIT_STRUCT, "");
814 iloop = ilist->init.deep;
816 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
818 /* if we have come to end */
822 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
823 lAst = decorateType (resolveSymbols (lAst));
824 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
828 werror (W_EXCESS_INITIALIZERS, "struct",
829 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
836 /*-----------------------------------------------------------------*/
837 /* createIvalArray - generates code for array initialization */
838 /*-----------------------------------------------------------------*/
840 createIvalArray (ast * sym, sym_link * type, initList * ilist)
844 int lcnt = 0, size = 0;
845 literalList *literalL;
847 /* take care of the special case */
848 /* array of characters can be init */
850 if (IS_CHAR (type->next))
851 if ((rast = createIvalCharPtr (sym,
853 decorateType (resolveSymbols (list2expr (ilist))))))
855 return decorateType (resolveSymbols (rast));
857 /* not the special case */
858 if (ilist->type != INIT_DEEP)
860 werror (E_INIT_STRUCT, "");
864 iloop = ilist->init.deep;
865 lcnt = DCL_ELEM (type);
867 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
871 aSym = decorateType (resolveSymbols(sym));
873 rast = newNode(ARRAYINIT, aSym, NULL);
874 rast->values.constlist = literalL;
876 // Make sure size is set to length of initializer list.
883 if (lcnt && size > lcnt)
885 // Array size was specified, and we have more initializers than needed.
886 char *name=sym->opval.val->sym->name;
887 int lineno=sym->opval.val->sym->lineDef;
889 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
898 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
899 aSym = decorateType (resolveSymbols (aSym));
900 rast = createIval (aSym, type->next, iloop, rast);
901 iloop = (iloop ? iloop->next : NULL);
907 /* no of elements given and we */
908 /* have generated for all of them */
911 // there has to be a better way
912 char *name=sym->opval.val->sym->name;
913 int lineno=sym->opval.val->sym->lineDef;
914 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
921 /* if we have not been given a size */
922 if (!DCL_ELEM (type))
924 DCL_ELEM (type) = size;
927 return decorateType (resolveSymbols (rast));
931 /*-----------------------------------------------------------------*/
932 /* createIvalCharPtr - generates initial values for char pointers */
933 /*-----------------------------------------------------------------*/
935 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
939 /* if this is a pointer & right is a literal array then */
940 /* just assignment will do */
941 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
942 SPEC_SCLS (iexpr->etype) == S_CODE)
943 && IS_ARRAY (iexpr->ftype)))
944 return newNode ('=', sym, iexpr);
946 /* left side is an array so we have to assign each */
948 if ((IS_LITERAL (iexpr->etype) ||
949 SPEC_SCLS (iexpr->etype) == S_CODE)
950 && IS_ARRAY (iexpr->ftype))
952 /* for each character generate an assignment */
953 /* to the array element */
954 char *s = SPEC_CVAL (iexpr->etype).v_char;
959 rast = newNode (NULLOP,
963 newAst_VALUE (valueFromLit ((float) i))),
964 newAst_VALUE (valueFromLit (*s))));
968 rast = newNode (NULLOP,
972 newAst_VALUE (valueFromLit ((float) i))),
973 newAst_VALUE (valueFromLit (*s))));
975 // now we don't need iexpr's symbol anymore
977 symbol *sym=AST_SYMBOL(iexpr);
978 memmap *segment=SPEC_OCLS(sym->etype);
979 deleteSetItem(&segment->syms, sym);
981 return decorateType (resolveSymbols (rast));
987 /*-----------------------------------------------------------------*/
988 /* createIvalPtr - generates initial value for pointers */
989 /*-----------------------------------------------------------------*/
991 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
997 if (ilist->type == INIT_DEEP)
998 ilist = ilist->init.deep;
1000 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1002 /* if character pointer */
1003 if (IS_CHAR (type->next))
1004 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1007 return newNode ('=', sym, iexpr);
1010 /*-----------------------------------------------------------------*/
1011 /* createIval - generates code for initial value */
1012 /*-----------------------------------------------------------------*/
1014 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1021 /* if structure then */
1022 if (IS_STRUCT (type))
1023 rast = createIvalStruct (sym, type, ilist);
1025 /* if this is a pointer */
1027 rast = createIvalPtr (sym, type, ilist);
1029 /* if this is an array */
1030 if (IS_ARRAY (type))
1031 rast = createIvalArray (sym, type, ilist);
1033 /* if type is SPECIFIER */
1035 rast = createIvalType (sym, type, ilist);
1038 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1040 return decorateType (resolveSymbols (rast));
1043 /*-----------------------------------------------------------------*/
1044 /* initAggregates - initialises aggregate variables with initv */
1045 /*-----------------------------------------------------------------*/
1046 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1047 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1050 /*-----------------------------------------------------------------*/
1051 /* gatherAutoInit - creates assignment expressions for initial */
1053 /*-----------------------------------------------------------------*/
1055 gatherAutoInit (symbol * autoChain)
1062 for (sym = autoChain; sym; sym = sym->next)
1065 /* resolve the symbols in the ival */
1067 resolveIvalSym (sym->ival);
1069 /* if this is a static variable & has an */
1070 /* initial value the code needs to be lifted */
1071 /* here to the main portion since they can be */
1072 /* initialised only once at the start */
1073 if (IS_STATIC (sym->etype) && sym->ival &&
1074 SPEC_SCLS (sym->etype) != S_CODE)
1078 /* insert the symbol into the symbol table */
1079 /* with level = 0 & name = rname */
1080 newSym = copySymbol (sym);
1081 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1083 /* now lift the code to main */
1084 if (IS_AGGREGATE (sym->type)) {
1085 work = initAggregates (sym, sym->ival, NULL);
1087 if (getNelements(sym->type, sym->ival)>1) {
1088 werror (W_EXCESS_INITIALIZERS, "scalar",
1089 sym->name, sym->lineDef);
1091 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1092 list2expr (sym->ival));
1095 setAstLineno (work, sym->lineDef);
1099 staticAutos = newNode (NULLOP, staticAutos, work);
1106 /* if there is an initial value */
1107 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1109 initList *ilist=sym->ival;
1111 while (ilist->type == INIT_DEEP) {
1112 ilist = ilist->init.deep;
1115 /* update lineno for error msg */
1116 lineno=sym->lineDef;
1117 setAstLineno (ilist->init.node, lineno);
1119 if (IS_AGGREGATE (sym->type)) {
1120 work = initAggregates (sym, sym->ival, NULL);
1122 if (getNelements(sym->type, sym->ival)>1) {
1123 werror (W_EXCESS_INITIALIZERS, "scalar",
1124 sym->name, sym->lineDef);
1126 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1127 list2expr (sym->ival));
1131 setAstLineno (work, sym->lineDef);
1135 init = newNode (NULLOP, init, work);
1144 /*-----------------------------------------------------------------*/
1145 /* stringToSymbol - creates a symbol from a literal string */
1146 /*-----------------------------------------------------------------*/
1148 stringToSymbol (value * val)
1150 char name[SDCC_NAME_MAX + 1];
1151 static int charLbl = 0;
1154 sprintf (name, "_str_%d", charLbl++);
1155 sym = newSymbol (name, 0); /* make it @ level 0 */
1156 strcpy (sym->rname, name);
1158 /* copy the type from the value passed */
1159 sym->type = copyLinkChain (val->type);
1160 sym->etype = getSpec (sym->type);
1161 /* change to storage class & output class */
1162 SPEC_SCLS (sym->etype) = S_CODE;
1163 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1164 SPEC_STAT (sym->etype) = 1;
1165 /* make the level & block = 0 */
1166 sym->block = sym->level = 0;
1168 /* create an ival */
1169 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1174 allocVariables (sym);
1177 return symbolVal (sym);
1181 /*-----------------------------------------------------------------*/
1182 /* processBlockVars - will go thru the ast looking for block if */
1183 /* a block is found then will allocate the syms */
1184 /* will also gather the auto inits present */
1185 /*-----------------------------------------------------------------*/
1187 processBlockVars (ast * tree, int *stack, int action)
1192 /* if this is a block */
1193 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1197 if (action == ALLOCATE)
1199 *stack += allocVariables (tree->values.sym);
1200 autoInit = gatherAutoInit (tree->values.sym);
1202 /* if there are auto inits then do them */
1204 tree->left = newNode (NULLOP, autoInit, tree->left);
1206 else /* action is deallocate */
1207 deallocLocal (tree->values.sym);
1210 processBlockVars (tree->left, stack, action);
1211 processBlockVars (tree->right, stack, action);
1215 /*-------------------------------------------------------------*/
1216 /* constExprTree - returns TRUE if this tree is a constant */
1218 /*-------------------------------------------------------------*/
1219 bool constExprTree (ast *cexpr) {
1225 cexpr = decorateType (resolveSymbols (cexpr));
1227 switch (cexpr->type)
1230 if (IS_AST_LIT_VALUE(cexpr)) {
1231 // this is a literal
1234 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1235 // a function's address will never change
1238 if (IS_AST_SYM_VALUE(cexpr) &&
1239 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1240 // a symbol in code space will never change
1241 // This is only for the 'char *s="hallo"' case and will have to leave
1246 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1247 "unexpected link in expression tree\n");
1250 if (cexpr->opval.op==ARRAYINIT) {
1251 // this is a list of literals
1254 if (cexpr->opval.op=='=') {
1255 return constExprTree(cexpr->right);
1257 if (cexpr->opval.op==CAST) {
1258 // jwk: cast ignored, maybe we should throw a warning here
1259 return constExprTree(cexpr->right);
1261 if (cexpr->opval.op=='&') {
1264 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1267 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1274 /*-----------------------------------------------------------------*/
1275 /* constExprValue - returns the value of a constant expression */
1276 /* or NULL if it is not a constant expression */
1277 /*-----------------------------------------------------------------*/
1279 constExprValue (ast * cexpr, int check)
1281 cexpr = decorateType (resolveSymbols (cexpr));
1283 /* if this is not a constant then */
1284 if (!IS_LITERAL (cexpr->ftype))
1286 /* then check if this is a literal array
1288 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1289 SPEC_CVAL (cexpr->etype).v_char &&
1290 IS_ARRAY (cexpr->ftype))
1292 value *val = valFromType (cexpr->ftype);
1293 SPEC_SCLS (val->etype) = S_LITERAL;
1294 val->sym = cexpr->opval.val->sym;
1295 val->sym->type = copyLinkChain (cexpr->ftype);
1296 val->sym->etype = getSpec (val->sym->type);
1297 strcpy (val->name, cexpr->opval.val->sym->rname);
1301 /* if we are casting a literal value then */
1302 if (IS_AST_OP (cexpr) &&
1303 cexpr->opval.op == CAST &&
1304 IS_LITERAL (cexpr->right->ftype))
1305 return valCastLiteral (cexpr->ftype,
1306 floatFromVal (cexpr->right->opval.val));
1308 if (IS_AST_VALUE (cexpr))
1309 return cexpr->opval.val;
1312 werror (E_CONST_EXPECTED, "found expression");
1317 /* return the value */
1318 return cexpr->opval.val;
1322 /*-----------------------------------------------------------------*/
1323 /* isLabelInAst - will return true if a given label is found */
1324 /*-----------------------------------------------------------------*/
1326 isLabelInAst (symbol * label, ast * tree)
1328 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1331 if (IS_AST_OP (tree) &&
1332 tree->opval.op == LABEL &&
1333 isSymbolEqual (AST_SYMBOL (tree->left), label))
1336 return isLabelInAst (label, tree->right) &&
1337 isLabelInAst (label, tree->left);
1341 /*-----------------------------------------------------------------*/
1342 /* isLoopCountable - return true if the loop count can be determi- */
1343 /* -ned at compile time . */
1344 /*-----------------------------------------------------------------*/
1346 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1347 symbol ** sym, ast ** init, ast ** end)
1350 /* the loop is considered countable if the following
1351 conditions are true :-
1353 a) initExpr :- <sym> = <const>
1354 b) condExpr :- <sym> < <const1>
1355 c) loopExpr :- <sym> ++
1358 /* first check the initExpr */
1359 if (IS_AST_OP (initExpr) &&
1360 initExpr->opval.op == '=' && /* is assignment */
1361 IS_AST_SYM_VALUE (initExpr->left))
1362 { /* left is a symbol */
1364 *sym = AST_SYMBOL (initExpr->left);
1365 *init = initExpr->right;
1370 /* for now the symbol has to be of
1372 if (!IS_INTEGRAL ((*sym)->type))
1375 /* now check condExpr */
1376 if (IS_AST_OP (condExpr))
1379 switch (condExpr->opval.op)
1382 if (IS_AST_SYM_VALUE (condExpr->left) &&
1383 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1384 IS_AST_LIT_VALUE (condExpr->right))
1386 *end = condExpr->right;
1392 if (IS_AST_OP (condExpr->left) &&
1393 condExpr->left->opval.op == '>' &&
1394 IS_AST_LIT_VALUE (condExpr->left->right) &&
1395 IS_AST_SYM_VALUE (condExpr->left->left) &&
1396 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1399 *end = newNode ('+', condExpr->left->right,
1400 newAst_VALUE (constVal ("1")));
1411 /* check loop expression is of the form <sym>++ */
1412 if (!IS_AST_OP (loopExpr))
1415 /* check if <sym> ++ */
1416 if (loopExpr->opval.op == INC_OP)
1422 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1423 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1430 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1431 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1439 if (loopExpr->opval.op == ADD_ASSIGN)
1442 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1443 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1444 IS_AST_LIT_VALUE (loopExpr->right) &&
1445 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1453 /*-----------------------------------------------------------------*/
1454 /* astHasVolatile - returns true if ast contains any volatile */
1455 /*-----------------------------------------------------------------*/
1457 astHasVolatile (ast * tree)
1462 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1465 if (IS_AST_OP (tree))
1466 return astHasVolatile (tree->left) ||
1467 astHasVolatile (tree->right);
1472 /*-----------------------------------------------------------------*/
1473 /* astHasPointer - return true if the ast contains any ptr variable */
1474 /*-----------------------------------------------------------------*/
1476 astHasPointer (ast * tree)
1481 if (IS_AST_LINK (tree))
1484 /* if we hit an array expression then check
1485 only the left side */
1486 if (IS_AST_OP (tree) && tree->opval.op == '[')
1487 return astHasPointer (tree->left);
1489 if (IS_AST_VALUE (tree))
1490 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1492 return astHasPointer (tree->left) ||
1493 astHasPointer (tree->right);
1497 /*-----------------------------------------------------------------*/
1498 /* astHasSymbol - return true if the ast has the given symbol */
1499 /*-----------------------------------------------------------------*/
1501 astHasSymbol (ast * tree, symbol * sym)
1503 if (!tree || IS_AST_LINK (tree))
1506 if (IS_AST_VALUE (tree))
1508 if (IS_AST_SYM_VALUE (tree))
1509 return isSymbolEqual (AST_SYMBOL (tree), sym);
1514 return astHasSymbol (tree->left, sym) ||
1515 astHasSymbol (tree->right, sym);
1518 /*-----------------------------------------------------------------*/
1519 /* astHasDeref - return true if the ast has an indirect access */
1520 /*-----------------------------------------------------------------*/
1522 astHasDeref (ast * tree)
1524 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1527 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1529 return astHasDeref (tree->left) || astHasDeref (tree->right);
1532 /*-----------------------------------------------------------------*/
1533 /* isConformingBody - the loop body has to conform to a set of rules */
1534 /* for the loop to be considered reversible read on for rules */
1535 /*-----------------------------------------------------------------*/
1537 isConformingBody (ast * pbody, symbol * sym, ast * body)
1540 /* we are going to do a pre-order traversal of the
1541 tree && check for the following conditions. (essentially
1542 a set of very shallow tests )
1543 a) the sym passed does not participate in
1544 any arithmetic operation
1545 b) There are no function calls
1546 c) all jumps are within the body
1547 d) address of loop control variable not taken
1548 e) if an assignment has a pointer on the
1549 left hand side make sure right does not have
1550 loop control variable */
1552 /* if we reach the end or a leaf then true */
1553 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1556 /* if anything else is "volatile" */
1557 if (IS_VOLATILE (TETYPE (pbody)))
1560 /* we will walk the body in a pre-order traversal for
1562 switch (pbody->opval.op)
1564 /*------------------------------------------------------------------*/
1566 // if the loopvar is used as an index
1567 if (astHasSymbol(pbody->right, sym)) {
1570 return isConformingBody (pbody->right, sym, body);
1572 /*------------------------------------------------------------------*/
1577 /*------------------------------------------------------------------*/
1578 case INC_OP: /* incerement operator unary so left only */
1581 /* sure we are not sym is not modified */
1583 IS_AST_SYM_VALUE (pbody->left) &&
1584 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1588 IS_AST_SYM_VALUE (pbody->right) &&
1589 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1594 /*------------------------------------------------------------------*/
1596 case '*': /* can be unary : if right is null then unary operation */
1601 /* if right is NULL then unary operation */
1602 /*------------------------------------------------------------------*/
1603 /*----------------------------*/
1605 /*----------------------------*/
1608 if (IS_AST_SYM_VALUE (pbody->left) &&
1609 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1612 return isConformingBody (pbody->left, sym, body);
1616 if (astHasSymbol (pbody->left, sym) ||
1617 astHasSymbol (pbody->right, sym))
1622 /*------------------------------------------------------------------*/
1630 if (IS_AST_SYM_VALUE (pbody->left) &&
1631 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1634 if (IS_AST_SYM_VALUE (pbody->right) &&
1635 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1638 return isConformingBody (pbody->left, sym, body) &&
1639 isConformingBody (pbody->right, sym, body);
1646 if (IS_AST_SYM_VALUE (pbody->left) &&
1647 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1649 return isConformingBody (pbody->left, sym, body);
1651 /*------------------------------------------------------------------*/
1663 case SIZEOF: /* evaluate wihout code generation */
1665 return isConformingBody (pbody->left, sym, body) &&
1666 isConformingBody (pbody->right, sym, body);
1668 /*------------------------------------------------------------------*/
1671 /* if left has a pointer & right has loop
1672 control variable then we cannot */
1673 if (astHasPointer (pbody->left) &&
1674 astHasSymbol (pbody->right, sym))
1676 if (astHasVolatile (pbody->left))
1679 if (IS_AST_SYM_VALUE (pbody->left)) {
1680 // if the loopvar has an assignment
1681 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1683 // if the loopvar is used in another (maybe conditional) block
1684 if (astHasSymbol (pbody->right, sym) &&
1685 (pbody->level > body->level)) {
1690 if (astHasVolatile (pbody->left))
1693 if (astHasDeref(pbody->right)) return FALSE;
1695 return isConformingBody (pbody->left, sym, body) &&
1696 isConformingBody (pbody->right, sym, body);
1707 assert ("Parser should not have generated this\n");
1709 /*------------------------------------------------------------------*/
1710 /*----------------------------*/
1711 /* comma operator */
1712 /*----------------------------*/
1714 return isConformingBody (pbody->left, sym, body) &&
1715 isConformingBody (pbody->right, sym, body);
1717 /*------------------------------------------------------------------*/
1718 /*----------------------------*/
1720 /*----------------------------*/
1722 /* if local & not passed as paramater then ok */
1723 if (sym->level && !astHasSymbol(pbody->right,sym))
1727 /*------------------------------------------------------------------*/
1728 /*----------------------------*/
1729 /* return statement */
1730 /*----------------------------*/
1735 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1740 if (astHasSymbol (pbody->left, sym))
1747 return isConformingBody (pbody->left, sym, body) &&
1748 isConformingBody (pbody->right, sym, body);
1754 /*-----------------------------------------------------------------*/
1755 /* isLoopReversible - takes a for loop as input && returns true */
1756 /* if the for loop is reversible. If yes will set the value of */
1757 /* the loop control var & init value & termination value */
1758 /*-----------------------------------------------------------------*/
1760 isLoopReversible (ast * loop, symbol ** loopCntrl,
1761 ast ** init, ast ** end)
1763 /* if option says don't do it then don't */
1764 if (optimize.noLoopReverse)
1766 /* there are several tests to determine this */
1768 /* for loop has to be of the form
1769 for ( <sym> = <const1> ;
1770 [<sym> < <const2>] ;
1771 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1773 if (!isLoopCountable (AST_FOR (loop, initExpr),
1774 AST_FOR (loop, condExpr),
1775 AST_FOR (loop, loopExpr),
1776 loopCntrl, init, end))
1779 /* now do some serious checking on the body of the loop
1782 return isConformingBody (loop->left, *loopCntrl, loop->left);
1786 /*-----------------------------------------------------------------*/
1787 /* replLoopSym - replace the loop sym by loop sym -1 */
1788 /*-----------------------------------------------------------------*/
1790 replLoopSym (ast * body, symbol * sym)
1793 if (!body || IS_AST_LINK (body))
1796 if (IS_AST_SYM_VALUE (body))
1799 if (isSymbolEqual (AST_SYMBOL (body), sym))
1803 body->opval.op = '-';
1804 body->left = newAst_VALUE (symbolVal (sym));
1805 body->right = newAst_VALUE (constVal ("1"));
1813 replLoopSym (body->left, sym);
1814 replLoopSym (body->right, sym);
1818 /*-----------------------------------------------------------------*/
1819 /* reverseLoop - do the actual loop reversal */
1820 /*-----------------------------------------------------------------*/
1822 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1826 /* create the following tree
1831 if (sym) goto for_continue ;
1834 /* put it together piece by piece */
1835 rloop = newNode (NULLOP,
1836 createIf (newAst_VALUE (symbolVal (sym)),
1838 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1841 newAst_VALUE (symbolVal (sym)),
1844 replLoopSym (loop->left, sym);
1845 setAstLineno (rloop, init->lineno);
1847 rloop = newNode (NULLOP,
1849 newAst_VALUE (symbolVal (sym)),
1850 newNode ('-', end, init)),
1851 createLabel (AST_FOR (loop, continueLabel),
1855 newNode (SUB_ASSIGN,
1856 newAst_VALUE (symbolVal (sym)),
1857 newAst_VALUE (constVal ("1"))),
1860 rloop->lineno=init->lineno;
1861 return decorateType (rloop);
1865 /*-----------------------------------------------------------------*/
1866 /* decorateType - compute type for this tree also does type cheking */
1867 /* this is done bottom up, since type have to flow upwards */
1868 /* it also does constant folding, and paramater checking */
1869 /*-----------------------------------------------------------------*/
1871 decorateType (ast * tree)
1879 /* if already has type then do nothing */
1880 if (tree->decorated)
1883 tree->decorated = 1;
1886 /* print the line */
1887 /* if not block & function */
1888 if (tree->type == EX_OP &&
1889 (tree->opval.op != FUNCTION &&
1890 tree->opval.op != BLOCK &&
1891 tree->opval.op != NULLOP))
1893 filename = tree->filename;
1894 lineno = tree->lineno;
1898 /* if any child is an error | this one is an error do nothing */
1899 if (tree->isError ||
1900 (tree->left && tree->left->isError) ||
1901 (tree->right && tree->right->isError))
1904 /*------------------------------------------------------------------*/
1905 /*----------------------------*/
1906 /* leaf has been reached */
1907 /*----------------------------*/
1908 /* if this is of type value */
1909 /* just get the type */
1910 if (tree->type == EX_VALUE)
1913 if (IS_LITERAL (tree->opval.val->etype))
1916 /* if this is a character array then declare it */
1917 if (IS_ARRAY (tree->opval.val->type))
1918 tree->opval.val = stringToSymbol (tree->opval.val);
1920 /* otherwise just copy the type information */
1921 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1925 if (tree->opval.val->sym)
1927 /* if the undefined flag is set then give error message */
1928 if (tree->opval.val->sym->undefined)
1930 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1932 TTYPE (tree) = TETYPE (tree) =
1933 tree->opval.val->type = tree->opval.val->sym->type =
1934 tree->opval.val->etype = tree->opval.val->sym->etype =
1935 copyLinkChain (INTTYPE);
1940 /* if impilicit i.e. struct/union member then no type */
1941 if (tree->opval.val->sym->implicit)
1942 TTYPE (tree) = TETYPE (tree) = NULL;
1947 /* else copy the type */
1948 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1950 /* and mark it as referenced */
1951 tree->opval.val->sym->isref = 1;
1959 /* if type link for the case of cast */
1960 if (tree->type == EX_LINK)
1962 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1969 dtl = decorateType (tree->left);
1970 /* delay right side for '?' operator since conditional macro expansions might
1972 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1974 /* this is to take care of situations
1975 when the tree gets rewritten */
1976 if (dtl != tree->left)
1978 if (dtr != tree->right)
1981 #ifdef JWK_FIX_IMPLICIT_CAST
1982 if (IS_AST_OP(tree) &&
1983 (tree->opval.op == CAST || tree->opval.op == '=') &&
1984 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
1985 (getSize(RTYPE(tree)) < INTSIZE)) {
1986 // this is a cast/assign to a bigger type
1987 if (IS_AST_OP(tree->right) &&
1988 (tree->right->opval.op == LEFT_OP ||
1989 tree->right->opval.op == '*' ||
1990 tree->right->opval.op == '+' ||
1991 tree->right->opval.op == '-') &&
1992 tree->right->right) {
1993 // we should cast an operand instead of the result
1994 tree->right->decorated = 0;
1995 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
1997 tree->right = decorateType(tree->right);
2001 /* special case for left shift operation : cast up right->left if type
2002 of left has greater size than right */
2003 if (tree->left && tree->right && tree->right->opval.op == LEFT_OP) {
2004 int lsize = getSize(LTYPE(tree));
2005 int rsize = getSize(RTYPE(tree));
2007 if (lsize > rsize) {
2008 tree->right->decorated = 0;
2009 tree->right->left = newNode( CAST, (lsize == 2 ?
2010 newAst_LINK(newIntLink()) :
2011 newAst_LINK(newLongLink())),
2013 tree->right = decorateType(tree->right);
2019 /* depending on type of operator do */
2021 switch (tree->opval.op)
2023 /*------------------------------------------------------------------*/
2024 /*----------------------------*/
2026 /*----------------------------*/
2029 /* determine which is the array & which the index */
2030 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2033 ast *tempTree = tree->left;
2034 tree->left = tree->right;
2035 tree->right = tempTree;
2038 /* first check if this is a array or a pointer */
2039 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2041 werror (E_NEED_ARRAY_PTR, "[]");
2042 goto errorTreeReturn;
2045 /* check if the type of the idx */
2046 if (!IS_INTEGRAL (RTYPE (tree)))
2048 werror (E_IDX_NOT_INT);
2049 goto errorTreeReturn;
2052 /* if the left is an rvalue then error */
2055 werror (E_LVALUE_REQUIRED, "array access");
2056 goto errorTreeReturn;
2059 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2060 if (IS_PTR(LTYPE(tree))) {
2061 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2065 /*------------------------------------------------------------------*/
2066 /*----------------------------*/
2068 /*----------------------------*/
2070 /* if this is not a structure */
2071 if (!IS_STRUCT (LTYPE (tree)))
2073 werror (E_STRUCT_UNION, ".");
2074 goto errorTreeReturn;
2076 TTYPE (tree) = structElemType (LTYPE (tree),
2077 (tree->right->type == EX_VALUE ?
2078 tree->right->opval.val : NULL));
2079 TETYPE (tree) = getSpec (TTYPE (tree));
2082 /*------------------------------------------------------------------*/
2083 /*----------------------------*/
2084 /* struct/union pointer */
2085 /*----------------------------*/
2087 /* if not pointer to a structure */
2088 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2090 werror (E_PTR_REQD);
2091 goto errorTreeReturn;
2094 if (!IS_STRUCT (LTYPE (tree)->next))
2096 werror (E_STRUCT_UNION, "->");
2097 goto errorTreeReturn;
2100 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2101 (tree->right->type == EX_VALUE ?
2102 tree->right->opval.val : NULL));
2103 TETYPE (tree) = getSpec (TTYPE (tree));
2105 /* adjust the storage class */
2106 switch (DCL_TYPE(tree->left->ftype)) {
2110 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2113 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2118 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2121 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2124 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2134 /*------------------------------------------------------------------*/
2135 /*----------------------------*/
2136 /* ++/-- operation */
2137 /*----------------------------*/
2138 case INC_OP: /* incerement operator unary so left only */
2141 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2142 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2143 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2144 werror (E_CODE_WRITE, "++/--");
2153 /*------------------------------------------------------------------*/
2154 /*----------------------------*/
2156 /*----------------------------*/
2157 case '&': /* can be unary */
2158 /* if right is NULL then unary operation */
2159 if (tree->right) /* not an unary operation */
2162 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2164 werror (E_BITWISE_OP);
2165 werror (W_CONTINUE, "left & right types are ");
2166 printTypeChain (LTYPE (tree), stderr);
2167 fprintf (stderr, ",");
2168 printTypeChain (RTYPE (tree), stderr);
2169 fprintf (stderr, "\n");
2170 goto errorTreeReturn;
2173 /* if they are both literal */
2174 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2176 tree->type = EX_VALUE;
2177 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2178 valFromType (RETYPE (tree)), '&');
2180 tree->right = tree->left = NULL;
2181 TETYPE (tree) = tree->opval.val->etype;
2182 TTYPE (tree) = tree->opval.val->type;
2186 /* see if this is a GETHBIT operation if yes
2189 ast *otree = optimizeGetHbit (tree);
2192 return decorateType (otree);
2196 computeType (LTYPE (tree), RTYPE (tree));
2197 TETYPE (tree) = getSpec (TTYPE (tree));
2199 LRVAL (tree) = RRVAL (tree) = 1;
2203 /*------------------------------------------------------------------*/
2204 /*----------------------------*/
2206 /*----------------------------*/
2208 p->class = DECLARATOR;
2209 /* if bit field then error */
2210 if (IS_BITVAR (tree->left->etype))
2212 werror (E_ILLEGAL_ADDR, "address of bit variable");
2213 goto errorTreeReturn;
2216 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2218 werror (E_ILLEGAL_ADDR, "address of register variable");
2219 goto errorTreeReturn;
2222 if (IS_FUNC (LTYPE (tree)))
2224 // this ought to be ignored
2225 return (tree->left);
2228 if (IS_LITERAL(LTYPE(tree)))
2230 werror (E_ILLEGAL_ADDR, "address of literal");
2231 goto errorTreeReturn;
2236 werror (E_LVALUE_REQUIRED, "address of");
2237 goto errorTreeReturn;
2239 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2241 DCL_TYPE (p) = CPOINTER;
2242 DCL_PTR_CONST (p) = port->mem.code_ro;
2244 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2245 DCL_TYPE (p) = FPOINTER;
2246 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2247 DCL_TYPE (p) = PPOINTER;
2248 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2249 DCL_TYPE (p) = IPOINTER;
2250 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2251 DCL_TYPE (p) = EEPPOINTER;
2252 else if (SPEC_OCLS(tree->left->etype))
2253 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2255 DCL_TYPE (p) = POINTER;
2257 if (IS_AST_SYM_VALUE (tree->left))
2259 AST_SYMBOL (tree->left)->addrtaken = 1;
2260 AST_SYMBOL (tree->left)->allocreq = 1;
2263 p->next = LTYPE (tree);
2265 TETYPE (tree) = getSpec (TTYPE (tree));
2266 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2267 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2272 /*------------------------------------------------------------------*/
2273 /*----------------------------*/
2275 /*----------------------------*/
2277 /* if the rewrite succeeds then don't go any furthur */
2279 ast *wtree = optimizeRRCRLC (tree);
2281 return decorateType (wtree);
2283 /*------------------------------------------------------------------*/
2284 /*----------------------------*/
2286 /*----------------------------*/
2288 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2290 werror (E_BITWISE_OP);
2291 werror (W_CONTINUE, "left & right types are ");
2292 printTypeChain (LTYPE (tree), stderr);
2293 fprintf (stderr, ",");
2294 printTypeChain (RTYPE (tree), stderr);
2295 fprintf (stderr, "\n");
2296 goto errorTreeReturn;
2299 /* if they are both literal then */
2300 /* rewrite the tree */
2301 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2303 tree->type = EX_VALUE;
2304 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2305 valFromType (RETYPE (tree)),
2307 tree->right = tree->left = NULL;
2308 TETYPE (tree) = tree->opval.val->etype;
2309 TTYPE (tree) = tree->opval.val->type;
2312 LRVAL (tree) = RRVAL (tree) = 1;
2313 TETYPE (tree) = getSpec (TTYPE (tree) =
2314 computeType (LTYPE (tree),
2317 /*------------------------------------------------------------------*/
2318 /*----------------------------*/
2320 /*----------------------------*/
2322 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2324 werror (E_INVALID_OP, "divide");
2325 goto errorTreeReturn;
2327 /* if they are both literal then */
2328 /* rewrite the tree */
2329 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2331 tree->type = EX_VALUE;
2332 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2333 valFromType (RETYPE (tree)));
2334 tree->right = tree->left = NULL;
2335 TETYPE (tree) = getSpec (TTYPE (tree) =
2336 tree->opval.val->type);
2339 LRVAL (tree) = RRVAL (tree) = 1;
2340 TETYPE (tree) = getSpec (TTYPE (tree) =
2341 computeType (LTYPE (tree),
2345 /*------------------------------------------------------------------*/
2346 /*----------------------------*/
2348 /*----------------------------*/
2350 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2352 werror (E_BITWISE_OP);
2353 werror (W_CONTINUE, "left & right types are ");
2354 printTypeChain (LTYPE (tree), stderr);
2355 fprintf (stderr, ",");
2356 printTypeChain (RTYPE (tree), stderr);
2357 fprintf (stderr, "\n");
2358 goto errorTreeReturn;
2360 /* if they are both literal then */
2361 /* rewrite the tree */
2362 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2364 tree->type = EX_VALUE;
2365 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2366 valFromType (RETYPE (tree)));
2367 tree->right = tree->left = NULL;
2368 TETYPE (tree) = getSpec (TTYPE (tree) =
2369 tree->opval.val->type);
2372 LRVAL (tree) = RRVAL (tree) = 1;
2373 TETYPE (tree) = getSpec (TTYPE (tree) =
2374 computeType (LTYPE (tree),
2378 /*------------------------------------------------------------------*/
2379 /*----------------------------*/
2380 /* address dereference */
2381 /*----------------------------*/
2382 case '*': /* can be unary : if right is null then unary operation */
2385 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2387 werror (E_PTR_REQD);
2388 goto errorTreeReturn;
2393 werror (E_LVALUE_REQUIRED, "pointer deref");
2394 goto errorTreeReturn;
2396 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2397 LTYPE (tree)->next : NULL);
2398 TETYPE (tree) = getSpec (TTYPE (tree));
2399 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2403 /*------------------------------------------------------------------*/
2404 /*----------------------------*/
2405 /* multiplication */
2406 /*----------------------------*/
2407 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2409 werror (E_INVALID_OP, "multiplication");
2410 goto errorTreeReturn;
2413 /* if they are both literal then */
2414 /* rewrite the tree */
2415 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2417 tree->type = EX_VALUE;
2418 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2419 valFromType (RETYPE (tree)));
2420 tree->right = tree->left = NULL;
2421 TETYPE (tree) = getSpec (TTYPE (tree) =
2422 tree->opval.val->type);
2426 /* if left is a literal exchange left & right */
2427 if (IS_LITERAL (LTYPE (tree)))
2429 ast *tTree = tree->left;
2430 tree->left = tree->right;
2431 tree->right = tTree;
2434 LRVAL (tree) = RRVAL (tree) = 1;
2435 TETYPE (tree) = getSpec (TTYPE (tree) =
2436 computeType (LTYPE (tree),
2439 /* promote result to int if left & right are char
2440 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2441 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2442 SPEC_NOUN(TETYPE(tree)) = V_INT;
2447 /*------------------------------------------------------------------*/
2448 /*----------------------------*/
2449 /* unary '+' operator */
2450 /*----------------------------*/
2455 if (!IS_INTEGRAL (LTYPE (tree)))
2457 werror (E_UNARY_OP, '+');
2458 goto errorTreeReturn;
2461 /* if left is a literal then do it */
2462 if (IS_LITERAL (LTYPE (tree)))
2464 tree->type = EX_VALUE;
2465 tree->opval.val = valFromType (LETYPE (tree));
2467 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2471 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2475 /*------------------------------------------------------------------*/
2476 /*----------------------------*/
2478 /*----------------------------*/
2480 /* this is not a unary operation */
2481 /* if both pointers then problem */
2482 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2483 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2485 werror (E_PTR_PLUS_PTR);
2486 goto errorTreeReturn;
2489 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2490 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2492 werror (E_PLUS_INVALID, "+");
2493 goto errorTreeReturn;
2496 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2497 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2499 werror (E_PLUS_INVALID, "+");
2500 goto errorTreeReturn;
2502 /* if they are both literal then */
2503 /* rewrite the tree */
2504 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2506 tree->type = EX_VALUE;
2507 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2508 valFromType (RETYPE (tree)));
2509 tree->right = tree->left = NULL;
2510 TETYPE (tree) = getSpec (TTYPE (tree) =
2511 tree->opval.val->type);
2515 /* if the right is a pointer or left is a literal
2516 xchange left & right */
2517 if (IS_ARRAY (RTYPE (tree)) ||
2518 IS_PTR (RTYPE (tree)) ||
2519 IS_LITERAL (LTYPE (tree)))
2521 ast *tTree = tree->left;
2522 tree->left = tree->right;
2523 tree->right = tTree;
2526 LRVAL (tree) = RRVAL (tree) = 1;
2527 /* if the left is a pointer */
2528 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2532 TETYPE (tree) = getSpec (TTYPE (tree) =
2533 computeType (LTYPE (tree),
2537 /*------------------------------------------------------------------*/
2538 /*----------------------------*/
2540 /*----------------------------*/
2541 case '-': /* can be unary */
2542 /* if right is null then unary */
2546 if (!IS_ARITHMETIC (LTYPE (tree)))
2548 werror (E_UNARY_OP, tree->opval.op);
2549 goto errorTreeReturn;
2552 /* if left is a literal then do it */
2553 if (IS_LITERAL (LTYPE (tree)))
2555 tree->type = EX_VALUE;
2556 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2558 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2559 SPEC_USIGN(TETYPE(tree)) = 0;
2563 TTYPE (tree) = LTYPE (tree);
2567 /*------------------------------------------------------------------*/
2568 /*----------------------------*/
2570 /*----------------------------*/
2572 if (!(IS_PTR (LTYPE (tree)) ||
2573 IS_ARRAY (LTYPE (tree)) ||
2574 IS_ARITHMETIC (LTYPE (tree))))
2576 werror (E_PLUS_INVALID, "-");
2577 goto errorTreeReturn;
2580 if (!(IS_PTR (RTYPE (tree)) ||
2581 IS_ARRAY (RTYPE (tree)) ||
2582 IS_ARITHMETIC (RTYPE (tree))))
2584 werror (E_PLUS_INVALID, "-");
2585 goto errorTreeReturn;
2588 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2589 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2590 IS_INTEGRAL (RTYPE (tree))))
2592 werror (E_PLUS_INVALID, "-");
2593 goto errorTreeReturn;
2596 /* if they are both literal then */
2597 /* rewrite the tree */
2598 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2600 tree->type = EX_VALUE;
2601 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2602 valFromType (RETYPE (tree)));
2603 tree->right = tree->left = NULL;
2604 TETYPE (tree) = getSpec (TTYPE (tree) =
2605 tree->opval.val->type);
2609 /* if the left & right are equal then zero */
2610 if (isAstEqual (tree->left, tree->right))
2612 tree->type = EX_VALUE;
2613 tree->left = tree->right = NULL;
2614 tree->opval.val = constVal ("0");
2615 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2619 /* if both of them are pointers or arrays then */
2620 /* the result is going to be an integer */
2621 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2622 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2623 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2625 /* if only the left is a pointer */
2626 /* then result is a pointer */
2627 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2628 TETYPE (tree) = getSpec (TTYPE (tree) =
2631 TETYPE (tree) = getSpec (TTYPE (tree) =
2632 computeType (LTYPE (tree),
2634 LRVAL (tree) = RRVAL (tree) = 1;
2637 /*------------------------------------------------------------------*/
2638 /*----------------------------*/
2640 /*----------------------------*/
2642 /* can be only integral type */
2643 if (!IS_INTEGRAL (LTYPE (tree)))
2645 werror (E_UNARY_OP, tree->opval.op);
2646 goto errorTreeReturn;
2649 /* if left is a literal then do it */
2650 if (IS_LITERAL (LTYPE (tree)))
2652 tree->type = EX_VALUE;
2653 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2655 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2659 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2662 /*------------------------------------------------------------------*/
2663 /*----------------------------*/
2665 /*----------------------------*/
2667 /* can be pointer */
2668 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2669 !IS_PTR (LTYPE (tree)) &&
2670 !IS_ARRAY (LTYPE (tree)))
2672 werror (E_UNARY_OP, tree->opval.op);
2673 goto errorTreeReturn;
2676 /* if left is a literal then do it */
2677 if (IS_LITERAL (LTYPE (tree)))
2679 tree->type = EX_VALUE;
2680 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2682 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2686 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2689 /*------------------------------------------------------------------*/
2690 /*----------------------------*/
2692 /*----------------------------*/
2695 TTYPE (tree) = LTYPE (tree);
2696 TETYPE (tree) = LETYPE (tree);
2700 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2705 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2707 werror (E_SHIFT_OP_INVALID);
2708 werror (W_CONTINUE, "left & right types are ");
2709 printTypeChain (LTYPE (tree), stderr);
2710 fprintf (stderr, ",");
2711 printTypeChain (RTYPE (tree), stderr);
2712 fprintf (stderr, "\n");
2713 goto errorTreeReturn;
2716 /* if they are both literal then */
2717 /* rewrite the tree */
2718 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2720 tree->type = EX_VALUE;
2721 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2722 valFromType (RETYPE (tree)),
2723 (tree->opval.op == LEFT_OP ? 1 : 0));
2724 tree->right = tree->left = NULL;
2725 TETYPE (tree) = getSpec (TTYPE (tree) =
2726 tree->opval.val->type);
2730 /* if only the right side is a literal & we are
2731 shifting more than size of the left operand then zero */
2732 if (IS_LITERAL (RTYPE (tree)) &&
2733 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2734 (getSize (LTYPE (tree)) * 8))
2736 #ifdef JWK_FIX_SHIFT_BUG
2737 if (tree->opval.op==LEFT_OP ||
2738 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2739 lineno=tree->lineno;
2740 werror (W_SHIFT_CHANGED,
2741 (tree->opval.op == LEFT_OP ? "left" : "right"));
2742 tree->type = EX_VALUE;
2743 tree->left = tree->right = NULL;
2744 tree->opval.val = constVal ("0");
2745 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2749 /* if left shift then cast up */
2750 if (tree->opval.op==LEFT_OP) {
2751 int size = getSize(LTYPE(tree));
2753 decorateType (newNode (CAST,
2754 (size == 1 ? newAst_LINK(newIntLink()) :
2755 (size == 2 ? newAst_LINK(newLongLink()) :
2756 newAst_LINK(newIntLink()))),
2759 werror (W_SHIFT_CHANGED,
2760 (tree->opval.op == LEFT_OP ? "left" : "right"));
2761 tree->type = EX_VALUE;
2762 tree->left = tree->right = NULL;
2763 tree->opval.val = constVal ("0");
2764 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2769 LRVAL (tree) = RRVAL (tree) = 1;
2770 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2772 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2776 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2780 /*------------------------------------------------------------------*/
2781 /*----------------------------*/
2783 /*----------------------------*/
2784 case CAST: /* change the type */
2785 /* cannot cast to an aggregate type */
2786 if (IS_AGGREGATE (LTYPE (tree)))
2788 werror (E_CAST_ILLEGAL);
2789 goto errorTreeReturn;
2792 /* make sure the type is complete and sane */
2793 checkTypeSanity(LETYPE(tree), "(cast)");
2796 /* if the right is a literal replace the tree */
2797 if (IS_LITERAL (RETYPE (tree))) {
2798 if (!IS_PTR (LTYPE (tree))) {
2799 tree->type = EX_VALUE;
2801 valCastLiteral (LTYPE (tree),
2802 floatFromVal (valFromType (RETYPE (tree))));
2805 TTYPE (tree) = tree->opval.val->type;
2806 tree->values.literalFromCast = 1;
2807 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2808 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2809 sym_link *rest = LTYPE(tree)->next;
2810 werror(W_LITERAL_GENERIC);
2811 TTYPE(tree) = newLink();
2812 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2813 TTYPE(tree)->next = rest;
2814 tree->left->opval.lnk = TTYPE(tree);
2817 TTYPE (tree) = LTYPE (tree);
2821 TTYPE (tree) = LTYPE (tree);
2825 #if 0 // this is already checked, now this could be explicit
2826 /* if pointer to struct then check names */
2827 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2828 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2829 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2831 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2832 SPEC_STRUCT(LETYPE(tree))->tag);
2835 /* if the right is a literal replace the tree */
2836 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2837 tree->type = EX_VALUE;
2839 valCastLiteral (LTYPE (tree),
2840 floatFromVal (valFromType (RETYPE (tree))));
2843 TTYPE (tree) = tree->opval.val->type;
2844 tree->values.literalFromCast = 1;
2846 TTYPE (tree) = LTYPE (tree);
2850 TETYPE (tree) = getSpec (TTYPE (tree));
2854 /*------------------------------------------------------------------*/
2855 /*----------------------------*/
2856 /* logical &&, || */
2857 /*----------------------------*/
2860 /* each must me arithmetic type or be a pointer */
2861 if (!IS_PTR (LTYPE (tree)) &&
2862 !IS_ARRAY (LTYPE (tree)) &&
2863 !IS_INTEGRAL (LTYPE (tree)))
2865 werror (E_COMPARE_OP);
2866 goto errorTreeReturn;
2869 if (!IS_PTR (RTYPE (tree)) &&
2870 !IS_ARRAY (RTYPE (tree)) &&
2871 !IS_INTEGRAL (RTYPE (tree)))
2873 werror (E_COMPARE_OP);
2874 goto errorTreeReturn;
2876 /* if they are both literal then */
2877 /* rewrite the tree */
2878 if (IS_LITERAL (RTYPE (tree)) &&
2879 IS_LITERAL (LTYPE (tree)))
2881 tree->type = EX_VALUE;
2882 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2883 valFromType (RETYPE (tree)),
2885 tree->right = tree->left = NULL;
2886 TETYPE (tree) = getSpec (TTYPE (tree) =
2887 tree->opval.val->type);
2890 LRVAL (tree) = RRVAL (tree) = 1;
2891 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2894 /*------------------------------------------------------------------*/
2895 /*----------------------------*/
2896 /* comparison operators */
2897 /*----------------------------*/
2905 ast *lt = optimizeCompare (tree);
2911 /* if they are pointers they must be castable */
2912 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2914 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2916 werror (E_COMPARE_OP);
2917 fprintf (stderr, "comparing type ");
2918 printTypeChain (LTYPE (tree), stderr);
2919 fprintf (stderr, "to type ");
2920 printTypeChain (RTYPE (tree), stderr);
2921 fprintf (stderr, "\n");
2922 goto errorTreeReturn;
2925 /* else they should be promotable to one another */
2928 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2929 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2931 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2933 werror (E_COMPARE_OP);
2934 fprintf (stderr, "comparing type ");
2935 printTypeChain (LTYPE (tree), stderr);
2936 fprintf (stderr, "to type ");
2937 printTypeChain (RTYPE (tree), stderr);
2938 fprintf (stderr, "\n");
2939 goto errorTreeReturn;
2942 /* if unsigned value < 0 then always false */
2943 /* if (unsigned value) > 0 then (unsigned value) */
2944 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2945 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2947 if (tree->opval.op == '<') {
2950 if (tree->opval.op == '>') {
2954 /* if they are both literal then */
2955 /* rewrite the tree */
2956 if (IS_LITERAL (RTYPE (tree)) &&
2957 IS_LITERAL (LTYPE (tree)))
2959 tree->type = EX_VALUE;
2960 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2961 valFromType (RETYPE (tree)),
2963 tree->right = tree->left = NULL;
2964 TETYPE (tree) = getSpec (TTYPE (tree) =
2965 tree->opval.val->type);
2968 LRVAL (tree) = RRVAL (tree) = 1;
2969 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2972 /*------------------------------------------------------------------*/
2973 /*----------------------------*/
2975 /*----------------------------*/
2976 case SIZEOF: /* evaluate wihout code generation */
2977 /* change the type to a integer */
2978 tree->type = EX_VALUE;
2979 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2980 tree->opval.val = constVal (buffer);
2981 tree->right = tree->left = NULL;
2982 TETYPE (tree) = getSpec (TTYPE (tree) =
2983 tree->opval.val->type);
2986 /*------------------------------------------------------------------*/
2987 /*----------------------------*/
2989 /*----------------------------*/
2991 /* return typeof enum value */
2992 tree->type = EX_VALUE;
2995 if (IS_SPEC(tree->right->ftype)) {
2996 switch (SPEC_NOUN(tree->right->ftype)) {
2998 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2999 else typeofv = TYPEOF_INT;
3002 typeofv = TYPEOF_FLOAT;
3005 typeofv = TYPEOF_CHAR;
3008 typeofv = TYPEOF_VOID;
3011 typeofv = TYPEOF_STRUCT;
3014 typeofv = TYPEOF_BIT;
3017 typeofv = TYPEOF_SBIT;
3023 switch (DCL_TYPE(tree->right->ftype)) {
3025 typeofv = TYPEOF_POINTER;
3028 typeofv = TYPEOF_FPOINTER;
3031 typeofv = TYPEOF_CPOINTER;
3034 typeofv = TYPEOF_GPOINTER;
3037 typeofv = TYPEOF_PPOINTER;
3040 typeofv = TYPEOF_IPOINTER;
3043 typeofv = TYPEOF_ARRAY;
3046 typeofv = TYPEOF_FUNCTION;
3052 sprintf (buffer, "%d", typeofv);
3053 tree->opval.val = constVal (buffer);
3054 tree->right = tree->left = NULL;
3055 TETYPE (tree) = getSpec (TTYPE (tree) =
3056 tree->opval.val->type);
3059 /*------------------------------------------------------------------*/
3060 /*----------------------------*/
3061 /* conditional operator '?' */
3062 /*----------------------------*/
3064 /* the type is value of the colon operator (on the right) */
3065 assert(IS_COLON_OP(tree->right));
3066 /* if already known then replace the tree : optimizer will do it
3067 but faster to do it here */
3068 if (IS_LITERAL (LTYPE(tree))) {
3069 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3070 return decorateType(tree->right->left) ;
3072 return decorateType(tree->right->right) ;
3075 tree->right = decorateType(tree->right);
3076 TTYPE (tree) = RTYPE(tree);
3077 TETYPE (tree) = getSpec (TTYPE (tree));
3082 /* if they don't match we have a problem */
3083 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3085 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3086 goto errorTreeReturn;
3089 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3090 TETYPE (tree) = getSpec (TTYPE (tree));
3094 #if 0 // assignment operators are converted by the parser
3095 /*------------------------------------------------------------------*/
3096 /*----------------------------*/
3097 /* assignment operators */
3098 /*----------------------------*/
3101 /* for these it must be both must be integral */
3102 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3103 !IS_ARITHMETIC (RTYPE (tree)))
3105 werror (E_OPS_INTEGRAL);
3106 goto errorTreeReturn;
3109 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3111 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3112 werror (E_CODE_WRITE, " ");
3116 werror (E_LVALUE_REQUIRED, "*= or /=");
3117 goto errorTreeReturn;
3128 /* for these it must be both must be integral */
3129 if (!IS_INTEGRAL (LTYPE (tree)) ||
3130 !IS_INTEGRAL (RTYPE (tree)))
3132 werror (E_OPS_INTEGRAL);
3133 goto errorTreeReturn;
3136 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3138 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3139 werror (E_CODE_WRITE, " ");
3143 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3144 goto errorTreeReturn;
3150 /*------------------------------------------------------------------*/
3151 /*----------------------------*/
3153 /*----------------------------*/
3155 if (!(IS_PTR (LTYPE (tree)) ||
3156 IS_ARITHMETIC (LTYPE (tree))))
3158 werror (E_PLUS_INVALID, "-=");
3159 goto errorTreeReturn;
3162 if (!(IS_PTR (RTYPE (tree)) ||
3163 IS_ARITHMETIC (RTYPE (tree))))
3165 werror (E_PLUS_INVALID, "-=");
3166 goto errorTreeReturn;
3169 TETYPE (tree) = getSpec (TTYPE (tree) =
3170 computeType (LTYPE (tree),
3173 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3174 werror (E_CODE_WRITE, " ");
3178 werror (E_LVALUE_REQUIRED, "-=");
3179 goto errorTreeReturn;
3185 /*------------------------------------------------------------------*/
3186 /*----------------------------*/
3188 /*----------------------------*/
3190 /* this is not a unary operation */
3191 /* if both pointers then problem */
3192 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3194 werror (E_PTR_PLUS_PTR);
3195 goto errorTreeReturn;
3198 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3200 werror (E_PLUS_INVALID, "+=");
3201 goto errorTreeReturn;
3204 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3206 werror (E_PLUS_INVALID, "+=");
3207 goto errorTreeReturn;
3210 TETYPE (tree) = getSpec (TTYPE (tree) =
3211 computeType (LTYPE (tree),
3214 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3215 werror (E_CODE_WRITE, " ");
3219 werror (E_LVALUE_REQUIRED, "+=");
3220 goto errorTreeReturn;
3223 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3224 tree->opval.op = '=';
3229 /*------------------------------------------------------------------*/
3230 /*----------------------------*/
3231 /* straight assignemnt */
3232 /*----------------------------*/
3234 /* cannot be an aggregate */
3235 if (IS_AGGREGATE (LTYPE (tree)))
3237 werror (E_AGGR_ASSIGN);
3238 goto errorTreeReturn;
3241 /* they should either match or be castable */
3242 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3244 werror (E_TYPE_MISMATCH, "assignment", " ");
3245 printFromToType(RTYPE(tree),LTYPE(tree));
3246 //goto errorTreeReturn;
3249 /* if the left side of the tree is of type void
3250 then report error */
3251 if (IS_VOID (LTYPE (tree)))
3253 werror (E_CAST_ZERO);
3254 printFromToType(RTYPE(tree), LTYPE(tree));
3257 TETYPE (tree) = getSpec (TTYPE (tree) =
3261 if (!tree->initMode ) {
3262 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3263 werror (E_CODE_WRITE, " ");
3267 werror (E_LVALUE_REQUIRED, "=");
3268 goto errorTreeReturn;
3273 /*------------------------------------------------------------------*/
3274 /*----------------------------*/
3275 /* comma operator */
3276 /*----------------------------*/
3278 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3281 /*------------------------------------------------------------------*/
3282 /*----------------------------*/
3284 /*----------------------------*/
3288 if (processParms (tree->left,
3289 FUNC_ARGS(tree->left->ftype),
3290 tree->right, &parmNumber, TRUE)) {
3291 goto errorTreeReturn;
3294 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3295 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3297 //FUNC_ARGS(tree->left->ftype) =
3298 //reverseVal (FUNC_ARGS(tree->left->ftype));
3299 reverseParms (tree->right);
3302 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3305 /*------------------------------------------------------------------*/
3306 /*----------------------------*/
3307 /* return statement */
3308 /*----------------------------*/
3313 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3315 werror (W_RETURN_MISMATCH);
3316 printFromToType (RTYPE(tree), currFunc->type->next);
3317 goto errorTreeReturn;
3320 if (IS_VOID (currFunc->type->next)
3322 !IS_VOID (RTYPE (tree)))
3324 werror (E_FUNC_VOID);
3325 goto errorTreeReturn;
3328 /* if there is going to be a casing required then add it */
3329 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3332 decorateType (newNode (CAST,
3333 newAst_LINK (copyLinkChain (currFunc->type->next)),
3342 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3344 werror (E_VOID_FUNC, currFunc->name);
3345 goto errorTreeReturn;
3348 TTYPE (tree) = TETYPE (tree) = NULL;
3351 /*------------------------------------------------------------------*/
3352 /*----------------------------*/
3353 /* switch statement */
3354 /*----------------------------*/
3356 /* the switch value must be an integer */
3357 if (!IS_INTEGRAL (LTYPE (tree)))
3359 werror (E_SWITCH_NON_INTEGER);
3360 goto errorTreeReturn;
3363 TTYPE (tree) = TETYPE (tree) = NULL;
3366 /*------------------------------------------------------------------*/
3367 /*----------------------------*/
3369 /*----------------------------*/
3371 tree->left = backPatchLabels (tree->left,
3374 TTYPE (tree) = TETYPE (tree) = NULL;
3377 /*------------------------------------------------------------------*/
3378 /*----------------------------*/
3380 /*----------------------------*/
3383 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3384 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3385 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3387 /* if the for loop is reversible then
3388 reverse it otherwise do what we normally
3394 if (isLoopReversible (tree, &sym, &init, &end))
3395 return reverseLoop (tree, sym, init, end);
3397 return decorateType (createFor (AST_FOR (tree, trueLabel),
3398 AST_FOR (tree, continueLabel),
3399 AST_FOR (tree, falseLabel),
3400 AST_FOR (tree, condLabel),
3401 AST_FOR (tree, initExpr),
3402 AST_FOR (tree, condExpr),
3403 AST_FOR (tree, loopExpr),
3407 TTYPE (tree) = TETYPE (tree) = NULL;
3411 /* some error found this tree will be killed */
3413 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3414 tree->opval.op = NULLOP;
3420 /*-----------------------------------------------------------------*/
3421 /* sizeofOp - processes size of operation */
3422 /*-----------------------------------------------------------------*/
3424 sizeofOp (sym_link * type)
3428 /* make sure the type is complete and sane */
3429 checkTypeSanity(type, "(sizeof)");
3431 /* get the size and convert it to character */
3432 sprintf (buff, "%d", getSize (type));
3434 /* now convert into value */
3435 return constVal (buff);
3439 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3440 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3441 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3442 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3443 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3444 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3445 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3447 /*-----------------------------------------------------------------*/
3448 /* backPatchLabels - change and or not operators to flow control */
3449 /*-----------------------------------------------------------------*/
3451 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3457 if (!(IS_ANDORNOT (tree)))
3460 /* if this an and */
3463 static int localLbl = 0;
3466 sprintf (buffer, "_and_%d", localLbl++);
3467 localLabel = newSymbol (buffer, NestLevel);
3469 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3471 /* if left is already a IFX then just change the if true label in that */
3472 if (!IS_IFX (tree->left))
3473 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3475 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3476 /* right is a IFX then just join */
3477 if (IS_IFX (tree->right))
3478 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3480 tree->right = createLabel (localLabel, tree->right);
3481 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3483 return newNode (NULLOP, tree->left, tree->right);
3486 /* if this is an or operation */
3489 static int localLbl = 0;
3492 sprintf (buffer, "_or_%d", localLbl++);
3493 localLabel = newSymbol (buffer, NestLevel);
3495 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3497 /* if left is already a IFX then just change the if true label in that */
3498 if (!IS_IFX (tree->left))
3499 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3501 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3502 /* right is a IFX then just join */
3503 if (IS_IFX (tree->right))
3504 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3506 tree->right = createLabel (localLabel, tree->right);
3507 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3509 return newNode (NULLOP, tree->left, tree->right);
3515 int wasnot = IS_NOT (tree->left);
3516 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3518 /* if the left is already a IFX */
3519 if (!IS_IFX (tree->left))
3520 tree->left = newNode (IFX, tree->left, NULL);
3524 tree->left->trueLabel = trueLabel;
3525 tree->left->falseLabel = falseLabel;
3529 tree->left->trueLabel = falseLabel;
3530 tree->left->falseLabel = trueLabel;
3537 tree->trueLabel = trueLabel;
3538 tree->falseLabel = falseLabel;
3545 /*-----------------------------------------------------------------*/
3546 /* createBlock - create expression tree for block */
3547 /*-----------------------------------------------------------------*/
3549 createBlock (symbol * decl, ast * body)
3553 /* if the block has nothing */
3557 ex = newNode (BLOCK, NULL, body);
3558 ex->values.sym = decl;
3560 ex->right = ex->right;
3566 /*-----------------------------------------------------------------*/
3567 /* createLabel - creates the expression tree for labels */
3568 /*-----------------------------------------------------------------*/
3570 createLabel (symbol * label, ast * stmnt)
3573 char name[SDCC_NAME_MAX + 1];
3576 /* must create fresh symbol if the symbol name */
3577 /* exists in the symbol table, since there can */
3578 /* be a variable with the same name as the labl */
3579 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3580 (csym->level == label->level))
3581 label = newSymbol (label->name, label->level);
3583 /* change the name before putting it in add _ */
3584 sprintf (name, "%s", label->name);
3586 /* put the label in the LabelSymbol table */
3587 /* but first check if a label of the same */
3589 if ((csym = findSym (LabelTab, NULL, name)))
3590 werror (E_DUPLICATE_LABEL, label->name);
3592 addSym (LabelTab, label, name, label->level, 0, 0);
3595 label->key = labelKey++;
3596 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3602 /*-----------------------------------------------------------------*/
3603 /* createCase - generates the parsetree for a case statement */
3604 /*-----------------------------------------------------------------*/
3606 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3608 char caseLbl[SDCC_NAME_MAX + 1];
3612 /* if the switch statement does not exist */
3613 /* then case is out of context */
3616 werror (E_CASE_CONTEXT);
3620 caseVal = decorateType (resolveSymbols (caseVal));
3621 /* if not a constant then error */
3622 if (!IS_LITERAL (caseVal->ftype))
3624 werror (E_CASE_CONSTANT);
3628 /* if not a integer than error */
3629 if (!IS_INTEGRAL (caseVal->ftype))
3631 werror (E_CASE_NON_INTEGER);
3635 /* find the end of the switch values chain */
3636 if (!(val = swStat->values.switchVals.swVals))
3637 swStat->values.switchVals.swVals = caseVal->opval.val;
3640 /* also order the cases according to value */
3642 int cVal = (int) floatFromVal (caseVal->opval.val);
3643 while (val && (int) floatFromVal (val) < cVal)
3649 /* if we reached the end then */
3652 pval->next = caseVal->opval.val;
3656 /* we found a value greater than */
3657 /* the current value we must add this */
3658 /* before the value */
3659 caseVal->opval.val->next = val;
3661 /* if this was the first in chain */
3662 if (swStat->values.switchVals.swVals == val)
3663 swStat->values.switchVals.swVals =
3666 pval->next = caseVal->opval.val;
3671 /* create the case label */
3672 sprintf (caseLbl, "_case_%d_%d",
3673 swStat->values.switchVals.swNum,
3674 (int) floatFromVal (caseVal->opval.val));
3676 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3681 /*-----------------------------------------------------------------*/
3682 /* createDefault - creates the parse tree for the default statement */
3683 /*-----------------------------------------------------------------*/
3685 createDefault (ast * swStat, ast * stmnt)
3687 char defLbl[SDCC_NAME_MAX + 1];
3689 /* if the switch statement does not exist */
3690 /* then case is out of context */
3693 werror (E_CASE_CONTEXT);
3697 /* turn on the default flag */
3698 swStat->values.switchVals.swDefault = 1;
3700 /* create the label */
3701 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3702 return createLabel (newSymbol (defLbl, 0), stmnt);
3705 /*-----------------------------------------------------------------*/
3706 /* createIf - creates the parsetree for the if statement */
3707 /*-----------------------------------------------------------------*/
3709 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3711 static int Lblnum = 0;
3713 symbol *ifTrue, *ifFalse, *ifEnd;
3715 /* if neither exists */
3716 if (!elseBody && !ifBody) {
3717 // if there are no side effects (i++, j() etc)
3718 if (!hasSEFcalls(condAst)) {
3723 /* create the labels */
3724 sprintf (buffer, "_iffalse_%d", Lblnum);
3725 ifFalse = newSymbol (buffer, NestLevel);
3726 /* if no else body then end == false */
3731 sprintf (buffer, "_ifend_%d", Lblnum);
3732 ifEnd = newSymbol (buffer, NestLevel);
3735 sprintf (buffer, "_iftrue_%d", Lblnum);
3736 ifTrue = newSymbol (buffer, NestLevel);
3740 /* attach the ifTrue label to the top of it body */
3741 ifBody = createLabel (ifTrue, ifBody);
3742 /* attach a goto end to the ifBody if else is present */
3745 ifBody = newNode (NULLOP, ifBody,
3747 newAst_VALUE (symbolVal (ifEnd)),
3749 /* put the elseLabel on the else body */
3750 elseBody = createLabel (ifFalse, elseBody);
3751 /* out the end at the end of the body */
3752 elseBody = newNode (NULLOP,
3754 createLabel (ifEnd, NULL));
3758 ifBody = newNode (NULLOP, ifBody,
3759 createLabel (ifFalse, NULL));
3761 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3762 if (IS_IFX (condAst))
3765 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3767 return newNode (NULLOP, ifTree,
3768 newNode (NULLOP, ifBody, elseBody));
3772 /*-----------------------------------------------------------------*/
3773 /* createDo - creates parse tree for do */
3776 /* _docontinue_n: */
3777 /* condition_expression +-> trueLabel -> _dobody_n */
3779 /* +-> falseLabel-> _dobreak_n */
3781 /*-----------------------------------------------------------------*/
3783 createDo (symbol * trueLabel, symbol * continueLabel,
3784 symbol * falseLabel, ast * condAst, ast * doBody)
3789 /* if the body does not exist then it is simple */
3792 condAst = backPatchLabels (condAst, continueLabel, NULL);
3793 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3794 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3795 doTree->trueLabel = continueLabel;
3796 doTree->falseLabel = NULL;
3800 /* otherwise we have a body */
3801 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3803 /* attach the body label to the top */
3804 doBody = createLabel (trueLabel, doBody);
3805 /* attach the continue label to end of body */
3806 doBody = newNode (NULLOP, doBody,
3807 createLabel (continueLabel, NULL));
3809 /* now put the break label at the end */
3810 if (IS_IFX (condAst))
3813 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3815 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3817 /* putting it together */
3818 return newNode (NULLOP, doBody, doTree);
3821 /*-----------------------------------------------------------------*/
3822 /* createFor - creates parse tree for 'for' statement */
3825 /* condExpr +-> trueLabel -> _forbody_n */
3827 /* +-> falseLabel-> _forbreak_n */
3830 /* _forcontinue_n: */
3832 /* goto _forcond_n ; */
3834 /*-----------------------------------------------------------------*/
3836 createFor (symbol * trueLabel, symbol * continueLabel,
3837 symbol * falseLabel, symbol * condLabel,
3838 ast * initExpr, ast * condExpr, ast * loopExpr,
3843 /* if loopexpression not present then we can generate it */
3844 /* the same way as a while */
3846 return newNode (NULLOP, initExpr,
3847 createWhile (trueLabel, continueLabel,
3848 falseLabel, condExpr, forBody));
3849 /* vanilla for statement */
3850 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3852 if (condExpr && !IS_IFX (condExpr))
3853 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3856 /* attach condition label to condition */
3857 condExpr = createLabel (condLabel, condExpr);
3859 /* attach body label to body */
3860 forBody = createLabel (trueLabel, forBody);
3862 /* attach continue to forLoop expression & attach */
3863 /* goto the forcond @ and of loopExpression */
3864 loopExpr = createLabel (continueLabel,
3868 newAst_VALUE (symbolVal (condLabel)),
3870 /* now start putting them together */
3871 forTree = newNode (NULLOP, initExpr, condExpr);
3872 forTree = newNode (NULLOP, forTree, forBody);
3873 forTree = newNode (NULLOP, forTree, loopExpr);
3874 /* finally add the break label */
3875 forTree = newNode (NULLOP, forTree,
3876 createLabel (falseLabel, NULL));
3880 /*-----------------------------------------------------------------*/
3881 /* createWhile - creates parse tree for while statement */
3882 /* the while statement will be created as follows */
3884 /* _while_continue_n: */
3885 /* condition_expression +-> trueLabel -> _while_boby_n */
3887 /* +-> falseLabel -> _while_break_n */
3888 /* _while_body_n: */
3890 /* goto _while_continue_n */
3891 /* _while_break_n: */
3892 /*-----------------------------------------------------------------*/
3894 createWhile (symbol * trueLabel, symbol * continueLabel,
3895 symbol * falseLabel, ast * condExpr, ast * whileBody)
3899 /* put the continue label */
3900 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3901 condExpr = createLabel (continueLabel, condExpr);
3902 condExpr->lineno = 0;
3904 /* put the body label in front of the body */
3905 whileBody = createLabel (trueLabel, whileBody);
3906 whileBody->lineno = 0;
3907 /* put a jump to continue at the end of the body */
3908 /* and put break label at the end of the body */
3909 whileBody = newNode (NULLOP,
3912 newAst_VALUE (symbolVal (continueLabel)),
3913 createLabel (falseLabel, NULL)));
3915 /* put it all together */
3916 if (IS_IFX (condExpr))
3917 whileTree = condExpr;
3920 whileTree = newNode (IFX, condExpr, NULL);
3921 /* put the true & false labels in place */
3922 whileTree->trueLabel = trueLabel;
3923 whileTree->falseLabel = falseLabel;
3926 return newNode (NULLOP, whileTree, whileBody);
3929 /*-----------------------------------------------------------------*/
3930 /* optimizeGetHbit - get highest order bit of the expression */
3931 /*-----------------------------------------------------------------*/
3933 optimizeGetHbit (ast * tree)
3936 /* if this is not a bit and */
3937 if (!IS_BITAND (tree))
3940 /* will look for tree of the form
3941 ( expr >> ((sizeof expr) -1) ) & 1 */
3942 if (!IS_AST_LIT_VALUE (tree->right))
3945 if (AST_LIT_VALUE (tree->right) != 1)
3948 if (!IS_RIGHT_OP (tree->left))
3951 if (!IS_AST_LIT_VALUE (tree->left->right))
3954 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3955 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3958 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3962 /*-----------------------------------------------------------------*/
3963 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3964 /*-----------------------------------------------------------------*/
3966 optimizeRRCRLC (ast * root)
3968 /* will look for trees of the form
3969 (?expr << 1) | (?expr >> 7) or
3970 (?expr >> 7) | (?expr << 1) will make that
3971 into a RLC : operation ..
3973 (?expr >> 1) | (?expr << 7) or
3974 (?expr << 7) | (?expr >> 1) will make that
3975 into a RRC operation
3976 note : by 7 I mean (number of bits required to hold the
3978 /* if the root operations is not a | operation the not */
3979 if (!IS_BITOR (root))
3982 /* I have to think of a better way to match patterns this sucks */
3983 /* that aside let start looking for the first case : I use a the
3984 negative check a lot to improve the efficiency */
3985 /* (?expr << 1) | (?expr >> 7) */
3986 if (IS_LEFT_OP (root->left) &&
3987 IS_RIGHT_OP (root->right))
3990 if (!SPEC_USIGN (TETYPE (root->left->left)))
3993 if (!IS_AST_LIT_VALUE (root->left->right) ||
3994 !IS_AST_LIT_VALUE (root->right->right))
3997 /* make sure it is the same expression */
3998 if (!isAstEqual (root->left->left,
4002 if (AST_LIT_VALUE (root->left->right) != 1)
4005 if (AST_LIT_VALUE (root->right->right) !=
4006 (getSize (TTYPE (root->left->left)) * 8 - 1))
4009 /* whew got the first case : create the AST */
4010 return newNode (RLC, root->left->left, NULL);
4014 /* check for second case */
4015 /* (?expr >> 7) | (?expr << 1) */
4016 if (IS_LEFT_OP (root->right) &&
4017 IS_RIGHT_OP (root->left))
4020 if (!SPEC_USIGN (TETYPE (root->left->left)))
4023 if (!IS_AST_LIT_VALUE (root->left->right) ||
4024 !IS_AST_LIT_VALUE (root->right->right))
4027 /* make sure it is the same symbol */
4028 if (!isAstEqual (root->left->left,
4032 if (AST_LIT_VALUE (root->right->right) != 1)
4035 if (AST_LIT_VALUE (root->left->right) !=
4036 (getSize (TTYPE (root->left->left)) * 8 - 1))
4039 /* whew got the first case : create the AST */
4040 return newNode (RLC, root->left->left, NULL);
4045 /* third case for RRC */
4046 /* (?symbol >> 1) | (?symbol << 7) */
4047 if (IS_LEFT_OP (root->right) &&
4048 IS_RIGHT_OP (root->left))
4051 if (!SPEC_USIGN (TETYPE (root->left->left)))
4054 if (!IS_AST_LIT_VALUE (root->left->right) ||
4055 !IS_AST_LIT_VALUE (root->right->right))
4058 /* make sure it is the same symbol */
4059 if (!isAstEqual (root->left->left,
4063 if (AST_LIT_VALUE (root->left->right) != 1)
4066 if (AST_LIT_VALUE (root->right->right) !=
4067 (getSize (TTYPE (root->left->left)) * 8 - 1))
4070 /* whew got the first case : create the AST */
4071 return newNode (RRC, root->left->left, NULL);
4075 /* fourth and last case for now */
4076 /* (?symbol << 7) | (?symbol >> 1) */
4077 if (IS_RIGHT_OP (root->right) &&
4078 IS_LEFT_OP (root->left))
4081 if (!SPEC_USIGN (TETYPE (root->left->left)))
4084 if (!IS_AST_LIT_VALUE (root->left->right) ||
4085 !IS_AST_LIT_VALUE (root->right->right))
4088 /* make sure it is the same symbol */
4089 if (!isAstEqual (root->left->left,
4093 if (AST_LIT_VALUE (root->right->right) != 1)
4096 if (AST_LIT_VALUE (root->left->right) !=
4097 (getSize (TTYPE (root->left->left)) * 8 - 1))
4100 /* whew got the first case : create the AST */
4101 return newNode (RRC, root->left->left, NULL);
4105 /* not found return root */
4109 /*-----------------------------------------------------------------*/
4110 /* optimizeCompare - otimizes compares for bit variables */
4111 /*-----------------------------------------------------------------*/
4113 optimizeCompare (ast * root)
4115 ast *optExpr = NULL;
4118 unsigned int litValue;
4120 /* if nothing then return nothing */
4124 /* if not a compare op then do leaves */
4125 if (!IS_COMPARE_OP (root))
4127 root->left = optimizeCompare (root->left);
4128 root->right = optimizeCompare (root->right);
4132 /* if left & right are the same then depending
4133 of the operation do */
4134 if (isAstEqual (root->left, root->right))
4136 switch (root->opval.op)
4141 optExpr = newAst_VALUE (constVal ("0"));
4146 optExpr = newAst_VALUE (constVal ("1"));
4150 return decorateType (optExpr);
4153 vleft = (root->left->type == EX_VALUE ?
4154 root->left->opval.val : NULL);
4156 vright = (root->right->type == EX_VALUE ?
4157 root->right->opval.val : NULL);
4159 /* if left is a BITVAR in BITSPACE */
4160 /* and right is a LITERAL then opt- */
4161 /* imize else do nothing */
4162 if (vleft && vright &&
4163 IS_BITVAR (vleft->etype) &&
4164 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4165 IS_LITERAL (vright->etype))
4168 /* if right side > 1 then comparison may never succeed */
4169 if ((litValue = (int) floatFromVal (vright)) > 1)
4171 werror (W_BAD_COMPARE);
4177 switch (root->opval.op)
4179 case '>': /* bit value greater than 1 cannot be */
4180 werror (W_BAD_COMPARE);
4184 case '<': /* bit value < 1 means 0 */
4186 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4189 case LE_OP: /* bit value <= 1 means no check */
4190 optExpr = newAst_VALUE (vright);
4193 case GE_OP: /* bit value >= 1 means only check for = */
4195 optExpr = newAst_VALUE (vleft);
4200 { /* literal is zero */
4201 switch (root->opval.op)
4203 case '<': /* bit value < 0 cannot be */
4204 werror (W_BAD_COMPARE);
4208 case '>': /* bit value > 0 means 1 */
4210 optExpr = newAst_VALUE (vleft);
4213 case LE_OP: /* bit value <= 0 means no check */
4214 case GE_OP: /* bit value >= 0 means no check */
4215 werror (W_BAD_COMPARE);
4219 case EQ_OP: /* bit == 0 means ! of bit */
4220 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4224 return decorateType (resolveSymbols (optExpr));
4225 } /* end-of-if of BITVAR */
4230 /*-----------------------------------------------------------------*/
4231 /* addSymToBlock : adds the symbol to the first block we find */
4232 /*-----------------------------------------------------------------*/
4234 addSymToBlock (symbol * sym, ast * tree)
4236 /* reached end of tree or a leaf */
4237 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4241 if (IS_AST_OP (tree) &&
4242 tree->opval.op == BLOCK)
4245 symbol *lsym = copySymbol (sym);
4247 lsym->next = AST_VALUES (tree, sym);
4248 AST_VALUES (tree, sym) = lsym;
4252 addSymToBlock (sym, tree->left);
4253 addSymToBlock (sym, tree->right);
4256 /*-----------------------------------------------------------------*/
4257 /* processRegParms - do processing for register parameters */
4258 /*-----------------------------------------------------------------*/
4260 processRegParms (value * args, ast * body)
4264 if (IS_REGPARM (args->etype))
4265 addSymToBlock (args->sym, body);
4270 /*-----------------------------------------------------------------*/
4271 /* resetParmKey - resets the operandkeys for the symbols */
4272 /*-----------------------------------------------------------------*/
4273 DEFSETFUNC (resetParmKey)
4284 /*-----------------------------------------------------------------*/
4285 /* createFunction - This is the key node that calls the iCode for */
4286 /* generating the code for a function. Note code */
4287 /* is generated function by function, later when */
4288 /* add inter-procedural analysis this will change */
4289 /*-----------------------------------------------------------------*/
4291 createFunction (symbol * name, ast * body)
4297 iCode *piCode = NULL;
4299 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4300 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4302 /* if check function return 0 then some problem */
4303 if (checkFunction (name, NULL) == 0)
4306 /* create a dummy block if none exists */
4308 body = newNode (BLOCK, NULL, NULL);
4312 /* check if the function name already in the symbol table */
4313 if ((csym = findSym (SymbolTab, NULL, name->name)))
4316 /* special case for compiler defined functions
4317 we need to add the name to the publics list : this
4318 actually means we are now compiling the compiler
4322 addSet (&publics, name);
4328 allocVariables (name);
4330 name->lastLine = yylineno;
4333 /* set the stack pointer */
4334 /* PENDING: check this for the mcs51 */
4335 stackPtr = -port->stack.direction * port->stack.call_overhead;
4336 if (IFFUNC_ISISR (name->type))
4337 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4338 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4339 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4341 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4343 fetype = getSpec (name->type); /* get the specifier for the function */
4344 /* if this is a reentrant function then */
4345 if (IFFUNC_ISREENT (name->type))
4348 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4350 /* do processing for parameters that are passed in registers */
4351 processRegParms (FUNC_ARGS(name->type), body);
4353 /* set the stack pointer */
4357 /* allocate & autoinit the block variables */
4358 processBlockVars (body, &stack, ALLOCATE);
4360 /* save the stack information */
4361 if (options.useXstack)
4362 name->xstack = SPEC_STAK (fetype) = stack;
4364 name->stack = SPEC_STAK (fetype) = stack;
4366 /* name needs to be mangled */
4367 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4369 body = resolveSymbols (body); /* resolve the symbols */
4370 body = decorateType (body); /* propagateType & do semantic checks */
4372 ex = newAst_VALUE (symbolVal (name)); /* create name */
4373 ex = newNode (FUNCTION, ex, body);
4374 ex->values.args = FUNC_ARGS(name->type);
4376 if (options.dump_tree) PA(ex);
4379 werror (E_FUNC_NO_CODE, name->name);
4383 /* create the node & generate intermediate code */
4385 codeOutFile = code->oFile;
4386 piCode = iCodeFromAst (ex);
4390 werror (E_FUNC_NO_CODE, name->name);
4394 eBBlockFromiCode (piCode);
4396 /* if there are any statics then do them */
4399 GcurMemmap = statsg;
4400 codeOutFile = statsg->oFile;
4401 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4407 /* dealloc the block variables */
4408 processBlockVars (body, &stack, DEALLOCATE);
4409 /* deallocate paramaters */
4410 deallocParms (FUNC_ARGS(name->type));
4412 if (IFFUNC_ISREENT (name->type))
4415 /* we are done freeup memory & cleanup */
4417 if (port->reset_labelKey) labelKey = 1;
4419 FUNC_HASBODY(name->type) = 1;
4420 addSet (&operKeyReset, name);
4421 applyToSet (operKeyReset, resetParmKey);
4424 cdbStructBlock (1, cdbFile);
4426 cleanUpLevel (LabelTab, 0);
4427 cleanUpBlock (StructTab, 1);
4428 cleanUpBlock (TypedefTab, 1);
4430 xstack->syms = NULL;
4431 istack->syms = NULL;
4436 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4437 /*-----------------------------------------------------------------*/
4438 /* ast_print : prints the ast (for debugging purposes) */
4439 /*-----------------------------------------------------------------*/
4441 void ast_print (ast * tree, FILE *outfile, int indent)
4446 /* can print only decorated trees */
4447 if (!tree->decorated) return;
4449 /* if any child is an error | this one is an error do nothing */
4450 if (tree->isError ||
4451 (tree->left && tree->left->isError) ||
4452 (tree->right && tree->right->isError)) {
4453 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4457 /* print the line */
4458 /* if not block & function */
4459 if (tree->type == EX_OP &&
4460 (tree->opval.op != FUNCTION &&
4461 tree->opval.op != BLOCK &&
4462 tree->opval.op != NULLOP)) {
4465 if (tree->opval.op == FUNCTION) {
4467 value *args=FUNC_ARGS(tree->left->opval.val->type);
4468 fprintf(outfile,"FUNCTION (%s=%p) type (",
4469 tree->left->opval.val->name, tree);
4470 printTypeChain (tree->ftype,outfile);
4471 fprintf(outfile,") args (");
4474 fprintf (outfile, ", ");
4476 printTypeChain (args ? args->type : NULL, outfile);
4478 args= args ? args->next : NULL;
4480 fprintf(outfile,")\n");
4481 ast_print(tree->left,outfile,indent);
4482 ast_print(tree->right,outfile,indent);
4485 if (tree->opval.op == BLOCK) {
4486 symbol *decls = tree->values.sym;
4487 INDENT(indent,outfile);
4488 fprintf(outfile,"{\n");
4490 INDENT(indent+2,outfile);
4491 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4492 decls->name, decls);
4493 printTypeChain(decls->type,outfile);
4494 fprintf(outfile,")\n");
4496 decls = decls->next;
4498 ast_print(tree->right,outfile,indent+2);
4499 INDENT(indent,outfile);
4500 fprintf(outfile,"}\n");
4503 if (tree->opval.op == NULLOP) {
4504 fprintf(outfile,"\n");
4505 ast_print(tree->left,outfile,indent);
4506 fprintf(outfile,"\n");
4507 ast_print(tree->right,outfile,indent);
4510 INDENT(indent,outfile);
4512 /*------------------------------------------------------------------*/
4513 /*----------------------------*/
4514 /* leaf has been reached */
4515 /*----------------------------*/
4516 /* if this is of type value */
4517 /* just get the type */
4518 if (tree->type == EX_VALUE) {
4520 if (IS_LITERAL (tree->opval.val->etype)) {
4521 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4522 (int) floatFromVal(tree->opval.val),
4523 (int) floatFromVal(tree->opval.val),
4524 floatFromVal(tree->opval.val));
4525 } else if (tree->opval.val->sym) {
4526 /* if the undefined flag is set then give error message */
4527 if (tree->opval.val->sym->undefined) {
4528 fprintf(outfile,"UNDEFINED SYMBOL ");
4530 fprintf(outfile,"SYMBOL ");
4532 fprintf(outfile,"(%s=%p)",
4533 tree->opval.val->sym->name,tree);
4536 fprintf(outfile," type (");
4537 printTypeChain(tree->ftype,outfile);
4538 fprintf(outfile,")\n");
4540 fprintf(outfile,"\n");
4545 /* if type link for the case of cast */
4546 if (tree->type == EX_LINK) {
4547 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4548 printTypeChain(tree->opval.lnk,outfile);
4549 fprintf(outfile,")\n");
4554 /* depending on type of operator do */
4556 switch (tree->opval.op) {
4557 /*------------------------------------------------------------------*/
4558 /*----------------------------*/
4560 /*----------------------------*/
4562 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4563 printTypeChain(tree->ftype,outfile);
4564 fprintf(outfile,")\n");
4565 ast_print(tree->left,outfile,indent+2);
4566 ast_print(tree->right,outfile,indent+2);
4569 /*------------------------------------------------------------------*/
4570 /*----------------------------*/
4572 /*----------------------------*/
4574 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4575 printTypeChain(tree->ftype,outfile);
4576 fprintf(outfile,")\n");
4577 ast_print(tree->left,outfile,indent+2);
4578 ast_print(tree->right,outfile,indent+2);
4581 /*------------------------------------------------------------------*/
4582 /*----------------------------*/
4583 /* struct/union pointer */
4584 /*----------------------------*/
4586 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4587 printTypeChain(tree->ftype,outfile);
4588 fprintf(outfile,")\n");
4589 ast_print(tree->left,outfile,indent+2);
4590 ast_print(tree->right,outfile,indent+2);
4593 /*------------------------------------------------------------------*/
4594 /*----------------------------*/
4595 /* ++/-- operation */
4596 /*----------------------------*/
4597 case INC_OP: /* incerement operator unary so left only */
4598 fprintf(outfile,"INC_OP (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+2);
4605 fprintf(outfile,"DEC_OP (%p) type (",tree);
4606 printTypeChain(tree->ftype,outfile);
4607 fprintf(outfile,")\n");
4608 ast_print(tree->left,outfile,indent+2);
4611 /*------------------------------------------------------------------*/
4612 /*----------------------------*/
4614 /*----------------------------*/
4617 fprintf(outfile,"& (%p) type (",tree);
4618 printTypeChain(tree->ftype,outfile);
4619 fprintf(outfile,")\n");
4620 ast_print(tree->left,outfile,indent+2);
4621 ast_print(tree->right,outfile,indent+2);
4623 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+2);
4627 ast_print(tree->right,outfile,indent+2);
4630 /*----------------------------*/
4632 /*----------------------------*/
4634 fprintf(outfile,"OR (%p) type (",tree);
4635 printTypeChain(tree->ftype,outfile);
4636 fprintf(outfile,")\n");
4637 ast_print(tree->left,outfile,indent+2);
4638 ast_print(tree->right,outfile,indent+2);
4640 /*------------------------------------------------------------------*/
4641 /*----------------------------*/
4643 /*----------------------------*/
4645 fprintf(outfile,"XOR (%p) type (",tree);
4646 printTypeChain(tree->ftype,outfile);
4647 fprintf(outfile,")\n");
4648 ast_print(tree->left,outfile,indent+2);
4649 ast_print(tree->right,outfile,indent+2);
4652 /*------------------------------------------------------------------*/
4653 /*----------------------------*/
4655 /*----------------------------*/
4657 fprintf(outfile,"DIV (%p) type (",tree);
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->left,outfile,indent+2);
4661 ast_print(tree->right,outfile,indent+2);
4663 /*------------------------------------------------------------------*/
4664 /*----------------------------*/
4666 /*----------------------------*/
4668 fprintf(outfile,"MOD (%p) type (",tree);
4669 printTypeChain(tree->ftype,outfile);
4670 fprintf(outfile,")\n");
4671 ast_print(tree->left,outfile,indent+2);
4672 ast_print(tree->right,outfile,indent+2);
4675 /*------------------------------------------------------------------*/
4676 /*----------------------------*/
4677 /* address dereference */
4678 /*----------------------------*/
4679 case '*': /* can be unary : if right is null then unary operation */
4681 fprintf(outfile,"DEREF (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->left,outfile,indent+2);
4687 /*------------------------------------------------------------------*/
4688 /*----------------------------*/
4689 /* multiplication */
4690 /*----------------------------*/
4691 fprintf(outfile,"MULT (%p) type (",tree);
4692 printTypeChain(tree->ftype,outfile);
4693 fprintf(outfile,")\n");
4694 ast_print(tree->left,outfile,indent+2);
4695 ast_print(tree->right,outfile,indent+2);
4699 /*------------------------------------------------------------------*/
4700 /*----------------------------*/
4701 /* unary '+' operator */
4702 /*----------------------------*/
4706 fprintf(outfile,"UPLUS (%p) type (",tree);
4707 printTypeChain(tree->ftype,outfile);
4708 fprintf(outfile,")\n");
4709 ast_print(tree->left,outfile,indent+2);
4711 /*------------------------------------------------------------------*/
4712 /*----------------------------*/
4714 /*----------------------------*/
4715 fprintf(outfile,"ADD (%p) type (",tree);
4716 printTypeChain(tree->ftype,outfile);
4717 fprintf(outfile,")\n");
4718 ast_print(tree->left,outfile,indent+2);
4719 ast_print(tree->right,outfile,indent+2);
4722 /*------------------------------------------------------------------*/
4723 /*----------------------------*/
4725 /*----------------------------*/
4726 case '-': /* can be unary */
4728 fprintf(outfile,"UMINUS (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+2);
4733 /*------------------------------------------------------------------*/
4734 /*----------------------------*/
4736 /*----------------------------*/
4737 fprintf(outfile,"SUB (%p) type (",tree);
4738 printTypeChain(tree->ftype,outfile);
4739 fprintf(outfile,")\n");
4740 ast_print(tree->left,outfile,indent+2);
4741 ast_print(tree->right,outfile,indent+2);
4744 /*------------------------------------------------------------------*/
4745 /*----------------------------*/
4747 /*----------------------------*/
4749 fprintf(outfile,"COMPL (%p) type (",tree);
4750 printTypeChain(tree->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->left,outfile,indent+2);
4754 /*------------------------------------------------------------------*/
4755 /*----------------------------*/
4757 /*----------------------------*/
4759 fprintf(outfile,"NOT (%p) type (",tree);
4760 printTypeChain(tree->ftype,outfile);
4761 fprintf(outfile,")\n");
4762 ast_print(tree->left,outfile,indent+2);
4764 /*------------------------------------------------------------------*/
4765 /*----------------------------*/
4767 /*----------------------------*/
4769 fprintf(outfile,"RRC (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+2);
4776 fprintf(outfile,"RLC (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+2);
4782 fprintf(outfile,"GETHBIT (%p) type (",tree);
4783 printTypeChain(tree->ftype,outfile);
4784 fprintf(outfile,")\n");
4785 ast_print(tree->left,outfile,indent+2);
4788 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4789 printTypeChain(tree->ftype,outfile);
4790 fprintf(outfile,")\n");
4791 ast_print(tree->left,outfile,indent+2);
4792 ast_print(tree->right,outfile,indent+2);
4795 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4796 printTypeChain(tree->ftype,outfile);
4797 fprintf(outfile,")\n");
4798 ast_print(tree->left,outfile,indent+2);
4799 ast_print(tree->right,outfile,indent+2);
4801 /*------------------------------------------------------------------*/
4802 /*----------------------------*/
4804 /*----------------------------*/
4805 case CAST: /* change the type */
4806 fprintf(outfile,"CAST (%p) from type (",tree);
4807 printTypeChain(tree->right->ftype,outfile);
4808 fprintf(outfile,") to type (");
4809 printTypeChain(tree->ftype,outfile);
4810 fprintf(outfile,")\n");
4811 ast_print(tree->right,outfile,indent+2);
4815 fprintf(outfile,"ANDAND (%p) type (",tree);
4816 printTypeChain(tree->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->left,outfile,indent+2);
4819 ast_print(tree->right,outfile,indent+2);
4822 fprintf(outfile,"OROR (%p) type (",tree);
4823 printTypeChain(tree->ftype,outfile);
4824 fprintf(outfile,")\n");
4825 ast_print(tree->left,outfile,indent+2);
4826 ast_print(tree->right,outfile,indent+2);
4829 /*------------------------------------------------------------------*/
4830 /*----------------------------*/
4831 /* comparison operators */
4832 /*----------------------------*/
4834 fprintf(outfile,"GT(>) (%p) type (",tree);
4835 printTypeChain(tree->ftype,outfile);
4836 fprintf(outfile,")\n");
4837 ast_print(tree->left,outfile,indent+2);
4838 ast_print(tree->right,outfile,indent+2);
4841 fprintf(outfile,"LT(<) (%p) type (",tree);
4842 printTypeChain(tree->ftype,outfile);
4843 fprintf(outfile,")\n");
4844 ast_print(tree->left,outfile,indent+2);
4845 ast_print(tree->right,outfile,indent+2);
4848 fprintf(outfile,"LE(<=) (%p) type (",tree);
4849 printTypeChain(tree->ftype,outfile);
4850 fprintf(outfile,")\n");
4851 ast_print(tree->left,outfile,indent+2);
4852 ast_print(tree->right,outfile,indent+2);
4855 fprintf(outfile,"GE(>=) (%p) type (",tree);
4856 printTypeChain(tree->ftype,outfile);
4857 fprintf(outfile,")\n");
4858 ast_print(tree->left,outfile,indent+2);
4859 ast_print(tree->right,outfile,indent+2);
4862 fprintf(outfile,"EQ(==) (%p) type (",tree);
4863 printTypeChain(tree->ftype,outfile);
4864 fprintf(outfile,")\n");
4865 ast_print(tree->left,outfile,indent+2);
4866 ast_print(tree->right,outfile,indent+2);
4869 fprintf(outfile,"NE(!=) (%p) type (",tree);
4870 printTypeChain(tree->ftype,outfile);
4871 fprintf(outfile,")\n");
4872 ast_print(tree->left,outfile,indent+2);
4873 ast_print(tree->right,outfile,indent+2);
4874 /*------------------------------------------------------------------*/
4875 /*----------------------------*/
4877 /*----------------------------*/
4878 case SIZEOF: /* evaluate wihout code generation */
4879 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4882 /*------------------------------------------------------------------*/
4883 /*----------------------------*/
4884 /* conditional operator '?' */
4885 /*----------------------------*/
4887 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4888 printTypeChain(tree->ftype,outfile);
4889 fprintf(outfile,")\n");
4890 ast_print(tree->left,outfile,indent+2);
4891 ast_print(tree->right,outfile,indent+2);
4895 fprintf(outfile,"COLON(:) (%p) type (",tree);
4896 printTypeChain(tree->ftype,outfile);
4897 fprintf(outfile,")\n");
4898 ast_print(tree->left,outfile,indent+2);
4899 ast_print(tree->right,outfile,indent+2);
4902 /*------------------------------------------------------------------*/
4903 /*----------------------------*/
4904 /* assignment operators */
4905 /*----------------------------*/
4907 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4908 printTypeChain(tree->ftype,outfile);
4909 fprintf(outfile,")\n");
4910 ast_print(tree->left,outfile,indent+2);
4911 ast_print(tree->right,outfile,indent+2);
4914 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4915 printTypeChain(tree->ftype,outfile);
4916 fprintf(outfile,")\n");
4917 ast_print(tree->left,outfile,indent+2);
4918 ast_print(tree->right,outfile,indent+2);
4921 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4922 printTypeChain(tree->ftype,outfile);
4923 fprintf(outfile,")\n");
4924 ast_print(tree->left,outfile,indent+2);
4925 ast_print(tree->right,outfile,indent+2);
4928 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4929 printTypeChain(tree->ftype,outfile);
4930 fprintf(outfile,")\n");
4931 ast_print(tree->left,outfile,indent+2);
4932 ast_print(tree->right,outfile,indent+2);
4935 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4936 printTypeChain(tree->ftype,outfile);
4937 fprintf(outfile,")\n");
4938 ast_print(tree->left,outfile,indent+2);
4939 ast_print(tree->right,outfile,indent+2);
4942 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4943 printTypeChain(tree->ftype,outfile);
4944 fprintf(outfile,")\n");
4945 ast_print(tree->left,outfile,indent+2);
4946 ast_print(tree->right,outfile,indent+2);
4949 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4950 printTypeChain(tree->ftype,outfile);
4951 fprintf(outfile,")\n");
4952 ast_print(tree->left,outfile,indent+2);
4953 ast_print(tree->right,outfile,indent+2);
4955 /*------------------------------------------------------------------*/
4956 /*----------------------------*/
4958 /*----------------------------*/
4960 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4961 printTypeChain(tree->ftype,outfile);
4962 fprintf(outfile,")\n");
4963 ast_print(tree->left,outfile,indent+2);
4964 ast_print(tree->right,outfile,indent+2);
4966 /*------------------------------------------------------------------*/
4967 /*----------------------------*/
4969 /*----------------------------*/
4971 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4972 printTypeChain(tree->ftype,outfile);
4973 fprintf(outfile,")\n");
4974 ast_print(tree->left,outfile,indent+2);
4975 ast_print(tree->right,outfile,indent+2);
4977 /*------------------------------------------------------------------*/
4978 /*----------------------------*/
4979 /* straight assignemnt */
4980 /*----------------------------*/
4982 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4983 printTypeChain(tree->ftype,outfile);
4984 fprintf(outfile,")\n");
4985 ast_print(tree->left,outfile,indent+2);
4986 ast_print(tree->right,outfile,indent+2);
4988 /*------------------------------------------------------------------*/
4989 /*----------------------------*/
4990 /* comma operator */
4991 /*----------------------------*/
4993 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4994 printTypeChain(tree->ftype,outfile);
4995 fprintf(outfile,")\n");
4996 ast_print(tree->left,outfile,indent+2);
4997 ast_print(tree->right,outfile,indent+2);
4999 /*------------------------------------------------------------------*/
5000 /*----------------------------*/
5002 /*----------------------------*/
5005 fprintf(outfile,"CALL (%p) type (",tree);
5006 printTypeChain(tree->ftype,outfile);
5007 fprintf(outfile,")\n");
5008 ast_print(tree->left,outfile,indent+2);
5009 ast_print(tree->right,outfile,indent+2);
5012 fprintf(outfile,"PARMS\n");
5013 ast_print(tree->left,outfile,indent+2);
5014 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5015 ast_print(tree->right,outfile,indent+2);
5018 /*------------------------------------------------------------------*/
5019 /*----------------------------*/
5020 /* return statement */
5021 /*----------------------------*/
5023 fprintf(outfile,"RETURN (%p) type (",tree);
5025 printTypeChain(tree->right->ftype,outfile);
5027 fprintf(outfile,")\n");
5028 ast_print(tree->right,outfile,indent+2);
5030 /*------------------------------------------------------------------*/
5031 /*----------------------------*/
5032 /* label statement */
5033 /*----------------------------*/
5035 fprintf(outfile,"LABEL (%p)\n",tree);
5036 ast_print(tree->left,outfile,indent+2);
5037 ast_print(tree->right,outfile,indent);
5039 /*------------------------------------------------------------------*/
5040 /*----------------------------*/
5041 /* switch statement */
5042 /*----------------------------*/
5046 fprintf(outfile,"SWITCH (%p) ",tree);
5047 ast_print(tree->left,outfile,0);
5048 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5049 INDENT(indent+2,outfile);
5050 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5051 (int) floatFromVal(val),
5052 tree->values.switchVals.swNum,
5053 (int) floatFromVal(val));
5055 ast_print(tree->right,outfile,indent);
5058 /*------------------------------------------------------------------*/
5059 /*----------------------------*/
5061 /*----------------------------*/
5063 fprintf(outfile,"IF (%p) \n",tree);
5064 ast_print(tree->left,outfile,indent+2);
5065 if (tree->trueLabel) {
5066 INDENT(indent,outfile);
5067 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5069 if (tree->falseLabel) {
5070 INDENT(indent,outfile);
5071 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5073 ast_print(tree->right,outfile,indent+2);
5075 /*------------------------------------------------------------------*/
5076 /*----------------------------*/
5078 /*----------------------------*/
5080 fprintf(outfile,"FOR (%p) \n",tree);
5081 if (AST_FOR( tree, initExpr)) {
5082 INDENT(indent+2,outfile);
5083 fprintf(outfile,"INIT EXPR ");
5084 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5086 if (AST_FOR( tree, condExpr)) {
5087 INDENT(indent+2,outfile);
5088 fprintf(outfile,"COND EXPR ");
5089 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5091 if (AST_FOR( tree, loopExpr)) {
5092 INDENT(indent+2,outfile);
5093 fprintf(outfile,"LOOP EXPR ");
5094 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5096 fprintf(outfile,"FOR LOOP BODY \n");
5097 ast_print(tree->left,outfile,indent+2);
5106 ast_print(t,stdout,0);