1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190 strcpy (dest->values.inlineasm, src->values.inlineasm);
194 dest->values.constlist = copyLiteralList(src->values.constlist);
198 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession */
211 /*-----------------------------------------------------------------*/
220 dest = Safe_alloc ( sizeof (ast));
222 dest->type = src->type;
223 dest->lineno = src->lineno;
224 dest->level = src->level;
225 dest->funcName = src->funcName;
228 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
230 /* if this is a leaf */
232 if (src->type == EX_VALUE)
234 dest->opval.val = copyValue (src->opval.val);
239 if (src->type == EX_LINK)
241 dest->opval.lnk = copyLinkChain (src->opval.lnk);
245 dest->opval.op = src->opval.op;
247 /* if this is a node that has special values */
248 copyAstValues (dest, src);
250 dest->trueLabel = copySymbol (src->trueLabel);
251 dest->falseLabel = copySymbol (src->falseLabel);
252 dest->left = copyAst (src->left);
253 dest->right = copyAst (src->right);
259 /*-----------------------------------------------------------------*/
260 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
261 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
262 /*-----------------------------------------------------------------*/
263 ast *removeIncDecOps (ast * tree) {
265 // traverse the tree and remove inc/dec ops
270 if (tree->type == EX_OP &&
271 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
278 tree->left=removeIncDecOps(tree->left);
279 tree->right=removeIncDecOps(tree->right);
284 /*-----------------------------------------------------------------*/
285 /* hasSEFcalls - returns TRUE if tree has a function call */
286 /*-----------------------------------------------------------------*/
288 hasSEFcalls (ast * tree)
293 if (tree->type == EX_OP &&
294 (tree->opval.op == CALL ||
295 tree->opval.op == PCALL ||
296 tree->opval.op == '=' ||
297 tree->opval.op == INC_OP ||
298 tree->opval.op == DEC_OP))
301 return (hasSEFcalls (tree->left) |
302 hasSEFcalls (tree->right));
305 /*-----------------------------------------------------------------*/
306 /* isAstEqual - compares two asts & returns 1 if they are equal */
307 /*-----------------------------------------------------------------*/
309 isAstEqual (ast * t1, ast * t2)
318 if (t1->type != t2->type)
324 if (t1->opval.op != t2->opval.op)
326 return (isAstEqual (t1->left, t2->left) &&
327 isAstEqual (t1->right, t2->right));
331 if (t1->opval.val->sym)
333 if (!t2->opval.val->sym)
336 return isSymbolEqual (t1->opval.val->sym,
341 if (t2->opval.val->sym)
344 return (floatFromVal (t1->opval.val) ==
345 floatFromVal (t2->opval.val));
349 /* only compare these two types */
357 /*-----------------------------------------------------------------*/
358 /* resolveSymbols - resolve symbols from the symbol table */
359 /*-----------------------------------------------------------------*/
361 resolveSymbols (ast * tree)
363 /* walk the entire tree and check for values */
364 /* with symbols if we find one then replace */
365 /* symbol with that from the symbol table */
371 /* if not block & function */
372 if (tree->type == EX_OP &&
373 (tree->opval.op != FUNCTION &&
374 tree->opval.op != BLOCK &&
375 tree->opval.op != NULLOP))
377 filename = tree->filename;
378 lineno = tree->lineno;
381 /* make sure we resolve the true & false labels for ifx */
382 if (tree->type == EX_OP && tree->opval.op == IFX)
388 if ((csym = findSym (LabelTab, tree->trueLabel,
389 tree->trueLabel->name)))
390 tree->trueLabel = csym;
392 werror (E_LABEL_UNDEF, tree->trueLabel->name);
395 if (tree->falseLabel)
397 if ((csym = findSym (LabelTab,
399 tree->falseLabel->name)))
400 tree->falseLabel = csym;
402 werror (E_LABEL_UNDEF, tree->falseLabel->name);
407 /* if this is a label resolve it from the labelTab */
408 if (IS_AST_VALUE (tree) &&
409 tree->opval.val->sym &&
410 tree->opval.val->sym->islbl)
413 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
414 tree->opval.val->sym->name);
417 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
419 tree->opval.val->sym = csym;
421 goto resolveChildren;
424 /* do only for leafs */
425 if (IS_AST_VALUE (tree) &&
426 tree->opval.val->sym &&
427 !tree->opval.val->sym->implicit)
430 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
432 /* if found in the symbol table & they r not the same */
433 if (csym && tree->opval.val->sym != csym)
435 tree->opval.val->sym = csym;
436 tree->opval.val->type = csym->type;
437 tree->opval.val->etype = csym->etype;
440 /* if not found in the symbol table */
441 /* mark it as undefined assume it is */
442 /* an integer in data space */
443 if (!csym && !tree->opval.val->sym->implicit)
446 /* if this is a function name then */
447 /* mark it as returning an int */
450 tree->opval.val->sym->type = newLink ();
451 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
452 tree->opval.val->sym->type->next =
453 tree->opval.val->sym->etype = newIntLink ();
454 tree->opval.val->etype = tree->opval.val->etype;
455 tree->opval.val->type = tree->opval.val->sym->type;
456 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
457 allocVariables (tree->opval.val->sym);
461 tree->opval.val->sym->undefined = 1;
462 tree->opval.val->type =
463 tree->opval.val->etype = newIntLink ();
464 tree->opval.val->sym->type =
465 tree->opval.val->sym->etype = newIntLink ();
471 resolveSymbols (tree->left);
472 resolveSymbols (tree->right);
477 /*-----------------------------------------------------------------*/
478 /* setAstLineno - walks a ast tree & sets the line number */
479 /*-----------------------------------------------------------------*/
481 setAstLineno (ast * tree, int lineno)
486 tree->lineno = lineno;
487 setAstLineno (tree->left, lineno);
488 setAstLineno (tree->right, lineno);
492 /*-----------------------------------------------------------------*/
493 /* funcOfType :- function of type with name */
494 /*-----------------------------------------------------------------*/
496 funcOfType (char *name, sym_link * type, sym_link * argType,
500 /* create the symbol */
501 sym = newSymbol (name, 0);
503 /* setup return value */
504 sym->type = newLink ();
505 DCL_TYPE (sym->type) = FUNCTION;
506 sym->type->next = copyLinkChain (type);
507 sym->etype = getSpec (sym->type);
508 FUNC_ISREENT(sym->type) = rent;
510 /* if arguments required */
514 args = FUNC_ARGS(sym->type) = newValue ();
518 args->type = copyLinkChain (argType);
519 args->etype = getSpec (args->type);
520 SPEC_EXTR(args->etype)=1;
523 args = args->next = newValue ();
530 allocVariables (sym);
535 /*-----------------------------------------------------------------*/
536 /* funcOfTypeVarg :- function of type with name and argtype */
537 /*-----------------------------------------------------------------*/
539 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
544 /* create the symbol */
545 sym = newSymbol (name, 0);
547 /* setup return value */
548 sym->type = newLink ();
549 DCL_TYPE (sym->type) = FUNCTION;
550 sym->type->next = typeFromStr(rtype);
551 sym->etype = getSpec (sym->type);
553 /* if arguments required */
556 args = FUNC_ARGS(sym->type) = newValue ();
558 for ( i = 0 ; i < nArgs ; i++ ) {
559 args->type = typeFromStr(atypes[i]);
560 args->etype = getSpec (args->type);
561 SPEC_EXTR(args->etype)=1;
562 if ((i + 1) == nArgs) break;
563 args = args->next = newValue ();
570 allocVariables (sym);
575 /*-----------------------------------------------------------------*/
576 /* reverseParms - will reverse a parameter tree */
577 /*-----------------------------------------------------------------*/
579 reverseParms (ast * ptree)
585 /* top down if we find a nonParm tree then quit */
586 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
589 ptree->left = ptree->right;
590 ptree->right = ttree;
591 reverseParms (ptree->left);
592 reverseParms (ptree->right);
598 /*-----------------------------------------------------------------*/
599 /* processParms - makes sure the parameters are okay and do some */
600 /* processing with them */
601 /*-----------------------------------------------------------------*/
603 processParms (ast * func,
606 int *parmNumber, // unused, although updated
609 /* if none of them exist */
610 if (!defParm && !actParm)
614 if (getenv("DEBUG_SANITY")) {
615 fprintf (stderr, "processParms: %s ", defParm->name);
617 /* make sure the type is complete and sane */
618 checkTypeSanity(defParm->etype, defParm->name);
621 /* if the function is being called via a pointer & */
622 /* it has not been defined a reentrant then we cannot */
623 /* have parameters */
624 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
626 werror (W_NONRENT_ARGS);
630 /* if defined parameters ended but actual parameters */
631 /* exist and this is not defined as a variable arg */
632 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
634 werror (E_TOO_MANY_PARMS);
638 /* if defined parameters present but no actual parameters */
639 if (defParm && !actParm)
641 werror (E_TOO_FEW_PARMS);
645 if (IS_VOID(actParm->ftype)) {
646 werror (E_VOID_VALUE_USED);
650 /* If this is a varargs function... */
651 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
656 if (IS_CAST_OP (actParm)
657 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
659 /* Parameter was explicitly typecast; don't touch it. */
663 ftype = actParm->ftype;
665 /* If it's a small integer, upcast to int. */
666 if (IS_INTEGRAL (ftype)
667 && (getSize (ftype) < (unsigned) INTSIZE))
669 newType = newAst_LINK(INTTYPE);
672 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
674 newType = newAst_LINK (copyLinkChain(ftype));
675 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
678 if (IS_AGGREGATE (ftype))
680 newType = newAst_LINK (copyLinkChain (ftype));
681 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
685 /* cast required; change this op to a cast. */
686 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
688 actParm->type = EX_OP;
689 actParm->opval.op = CAST;
690 actParm->left = newType;
691 actParm->right = parmCopy;
692 decorateType (actParm);
694 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
696 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
697 processParms (func, NULL, actParm->right, parmNumber, rightmost));
702 /* if defined parameters ended but actual has not & */
704 if (!defParm && actParm &&
705 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
708 resolveSymbols (actParm);
709 /* if this is a PARAM node then match left & right */
710 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
712 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
713 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
717 /* If we have found a value node by following only right-hand links,
718 * then we know that there are no more values after us.
720 * Therefore, if there are more defined parameters, the caller didn't
723 if (rightmost && defParm->next)
725 werror (E_TOO_FEW_PARMS);
730 /* the parameter type must be at least castable */
731 if (compareType (defParm->type, actParm->ftype) == 0) {
732 werror (E_INCOMPAT_TYPES);
733 printFromToType (actParm->ftype, defParm->type);
737 /* if the parameter is castable then add the cast */
738 if (compareType (defParm->type, actParm->ftype) < 0)
740 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
742 /* now change the current one to a cast */
743 actParm->type = EX_OP;
744 actParm->opval.op = CAST;
745 actParm->left = newAst_LINK (defParm->type);
746 actParm->right = pTree;
747 actParm->etype = defParm->etype;
748 actParm->ftype = defParm->type;
749 actParm->decorated=0; /* force typechecking */
750 decorateType (actParm);
753 /* make a copy and change the regparm type to the defined parm */
754 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
755 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
759 /*-----------------------------------------------------------------*/
760 /* createIvalType - generates ival for basic types */
761 /*-----------------------------------------------------------------*/
763 createIvalType (ast * sym, sym_link * type, initList * ilist)
767 /* if initList is deep */
768 if (ilist->type == INIT_DEEP)
769 ilist = ilist->init.deep;
771 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
772 return decorateType (newNode ('=', sym, iExpr));
775 /*-----------------------------------------------------------------*/
776 /* createIvalStruct - generates initial value for structures */
777 /*-----------------------------------------------------------------*/
779 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
786 sflds = SPEC_STRUCT (type)->fields;
787 if (ilist->type != INIT_DEEP)
789 werror (E_INIT_STRUCT, "");
793 iloop = ilist->init.deep;
795 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
797 /* if we have come to end */
801 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
802 lAst = decorateType (resolveSymbols (lAst));
803 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
807 werror (W_EXCESS_INITIALIZERS, "struct",
808 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
815 /*-----------------------------------------------------------------*/
816 /* createIvalArray - generates code for array initialization */
817 /*-----------------------------------------------------------------*/
819 createIvalArray (ast * sym, sym_link * type, initList * ilist)
823 int lcnt = 0, size = 0;
824 literalList *literalL;
826 /* take care of the special case */
827 /* array of characters can be init */
829 if (IS_CHAR (type->next))
830 if ((rast = createIvalCharPtr (sym,
832 decorateType (resolveSymbols (list2expr (ilist))))))
834 return decorateType (resolveSymbols (rast));
836 /* not the special case */
837 if (ilist->type != INIT_DEEP)
839 werror (E_INIT_STRUCT, "");
843 iloop = ilist->init.deep;
844 lcnt = DCL_ELEM (type);
846 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
850 aSym = decorateType (resolveSymbols(sym));
852 rast = newNode(ARRAYINIT, aSym, NULL);
853 rast->values.constlist = literalL;
855 // Make sure size is set to length of initializer list.
862 if (lcnt && size > lcnt)
864 // Array size was specified, and we have more initializers than needed.
865 char *name=sym->opval.val->sym->name;
866 int lineno=sym->opval.val->sym->lineDef;
868 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
877 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
878 aSym = decorateType (resolveSymbols (aSym));
879 rast = createIval (aSym, type->next, iloop, rast);
880 iloop = (iloop ? iloop->next : NULL);
886 /* no of elements given and we */
887 /* have generated for all of them */
890 // there has to be a better way
891 char *name=sym->opval.val->sym->name;
892 int lineno=sym->opval.val->sym->lineDef;
893 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
900 /* if we have not been given a size */
901 if (!DCL_ELEM (type))
903 DCL_ELEM (type) = size;
906 return decorateType (resolveSymbols (rast));
910 /*-----------------------------------------------------------------*/
911 /* createIvalCharPtr - generates initial values for char pointers */
912 /*-----------------------------------------------------------------*/
914 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
918 /* if this is a pointer & right is a literal array then */
919 /* just assignment will do */
920 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
921 SPEC_SCLS (iexpr->etype) == S_CODE)
922 && IS_ARRAY (iexpr->ftype)))
923 return newNode ('=', sym, iexpr);
925 /* left side is an array so we have to assign each */
927 if ((IS_LITERAL (iexpr->etype) ||
928 SPEC_SCLS (iexpr->etype) == S_CODE)
929 && IS_ARRAY (iexpr->ftype))
931 /* for each character generate an assignment */
932 /* to the array element */
933 char *s = SPEC_CVAL (iexpr->etype).v_char;
938 rast = newNode (NULLOP,
942 newAst_VALUE (valueFromLit ((float) i))),
943 newAst_VALUE (valueFromLit (*s))));
947 rast = newNode (NULLOP,
951 newAst_VALUE (valueFromLit ((float) i))),
952 newAst_VALUE (valueFromLit (*s))));
953 return decorateType (resolveSymbols (rast));
959 /*-----------------------------------------------------------------*/
960 /* createIvalPtr - generates initial value for pointers */
961 /*-----------------------------------------------------------------*/
963 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
969 if (ilist->type == INIT_DEEP)
970 ilist = ilist->init.deep;
972 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
974 /* if character pointer */
975 if (IS_CHAR (type->next))
976 if ((rast = createIvalCharPtr (sym, type, iexpr)))
979 return newNode ('=', sym, iexpr);
982 /*-----------------------------------------------------------------*/
983 /* createIval - generates code for initial value */
984 /*-----------------------------------------------------------------*/
986 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
993 /* if structure then */
994 if (IS_STRUCT (type))
995 rast = createIvalStruct (sym, type, ilist);
997 /* if this is a pointer */
999 rast = createIvalPtr (sym, type, ilist);
1001 /* if this is an array */
1002 if (IS_ARRAY (type))
1003 rast = createIvalArray (sym, type, ilist);
1005 /* if type is SPECIFIER */
1007 rast = createIvalType (sym, type, ilist);
1010 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1012 return decorateType (resolveSymbols (rast));
1015 /*-----------------------------------------------------------------*/
1016 /* initAggregates - initialises aggregate variables with initv */
1017 /*-----------------------------------------------------------------*/
1018 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1019 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1022 /*-----------------------------------------------------------------*/
1023 /* gatherAutoInit - creates assignment expressions for initial */
1025 /*-----------------------------------------------------------------*/
1027 gatherAutoInit (symbol * autoChain)
1034 for (sym = autoChain; sym; sym = sym->next)
1037 /* resolve the symbols in the ival */
1039 resolveIvalSym (sym->ival);
1041 /* if this is a static variable & has an */
1042 /* initial value the code needs to be lifted */
1043 /* here to the main portion since they can be */
1044 /* initialised only once at the start */
1045 if (IS_STATIC (sym->etype) && sym->ival &&
1046 SPEC_SCLS (sym->etype) != S_CODE)
1050 /* insert the symbol into the symbol table */
1051 /* with level = 0 & name = rname */
1052 newSym = copySymbol (sym);
1053 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1055 /* now lift the code to main */
1056 if (IS_AGGREGATE (sym->type)) {
1057 work = initAggregates (sym, sym->ival, NULL);
1059 if (getNelements(sym->type, sym->ival)>1) {
1060 werror (W_EXCESS_INITIALIZERS, "scalar",
1061 sym->name, sym->lineDef);
1063 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1064 list2expr (sym->ival));
1067 setAstLineno (work, sym->lineDef);
1071 staticAutos = newNode (NULLOP, staticAutos, work);
1078 /* if there is an initial value */
1079 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1081 if (IS_AGGREGATE (sym->type)) {
1082 work = initAggregates (sym, sym->ival, NULL);
1084 if (getNelements(sym->type, sym->ival)>1) {
1085 werror (W_EXCESS_INITIALIZERS, "scalar",
1086 sym->name, sym->lineDef);
1088 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1089 list2expr (sym->ival));
1092 setAstLineno (work, sym->lineDef);
1095 init = newNode (NULLOP, init, work);
1104 /*-----------------------------------------------------------------*/
1105 /* stringToSymbol - creates a symbol from a literal string */
1106 /*-----------------------------------------------------------------*/
1108 stringToSymbol (value * val)
1110 char name[SDCC_NAME_MAX + 1];
1111 static int charLbl = 0;
1114 sprintf (name, "_str_%d", charLbl++);
1115 sym = newSymbol (name, 0); /* make it @ level 0 */
1116 strcpy (sym->rname, name);
1118 /* copy the type from the value passed */
1119 sym->type = copyLinkChain (val->type);
1120 sym->etype = getSpec (sym->type);
1121 /* change to storage class & output class */
1122 SPEC_SCLS (sym->etype) = S_CODE;
1123 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1124 SPEC_STAT (sym->etype) = 1;
1125 /* make the level & block = 0 */
1126 sym->block = sym->level = 0;
1128 /* create an ival */
1129 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1134 allocVariables (sym);
1137 return symbolVal (sym);
1141 /*-----------------------------------------------------------------*/
1142 /* processBlockVars - will go thru the ast looking for block if */
1143 /* a block is found then will allocate the syms */
1144 /* will also gather the auto inits present */
1145 /*-----------------------------------------------------------------*/
1147 processBlockVars (ast * tree, int *stack, int action)
1152 /* if this is a block */
1153 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1157 if (action == ALLOCATE)
1159 *stack += allocVariables (tree->values.sym);
1160 autoInit = gatherAutoInit (tree->values.sym);
1162 /* if there are auto inits then do them */
1164 tree->left = newNode (NULLOP, autoInit, tree->left);
1166 else /* action is deallocate */
1167 deallocLocal (tree->values.sym);
1170 processBlockVars (tree->left, stack, action);
1171 processBlockVars (tree->right, stack, action);
1175 /*-------------------------------------------------------------*/
1176 /* constExprTree - returns TRUE if this tree is a constant */
1178 /*-------------------------------------------------------------*/
1179 bool constExprTree (ast *cexpr) {
1185 cexpr = decorateType (resolveSymbols (cexpr));
1187 switch (cexpr->type)
1190 if (IS_AST_LIT_VALUE(cexpr)) {
1191 // this is a literal
1194 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1195 // a function's address will never change
1198 if (IS_AST_SYM_VALUE(cexpr) &&
1199 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1200 // a symbol in code space will never change
1201 // This is only for the 'char *s="hallo"' case and will have to leave
1206 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1207 "unexpected link in expression tree\n");
1210 if (cexpr->opval.op==ARRAYINIT) {
1211 // this is a list of literals
1214 if (cexpr->opval.op=='=') {
1215 return constExprTree(cexpr->right);
1217 if (cexpr->opval.op==CAST) {
1218 // jwk: cast ignored, maybe we should throw a warning here
1219 return constExprTree(cexpr->right);
1221 if (cexpr->opval.op=='&') {
1224 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1227 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1234 /*-----------------------------------------------------------------*/
1235 /* constExprValue - returns the value of a constant expression */
1236 /* or NULL if it is not a constant expression */
1237 /*-----------------------------------------------------------------*/
1239 constExprValue (ast * cexpr, int check)
1241 cexpr = decorateType (resolveSymbols (cexpr));
1243 /* if this is not a constant then */
1244 if (!IS_LITERAL (cexpr->ftype))
1246 /* then check if this is a literal array
1248 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1249 SPEC_CVAL (cexpr->etype).v_char &&
1250 IS_ARRAY (cexpr->ftype))
1252 value *val = valFromType (cexpr->ftype);
1253 SPEC_SCLS (val->etype) = S_LITERAL;
1254 val->sym = cexpr->opval.val->sym;
1255 val->sym->type = copyLinkChain (cexpr->ftype);
1256 val->sym->etype = getSpec (val->sym->type);
1257 strcpy (val->name, cexpr->opval.val->sym->rname);
1261 /* if we are casting a literal value then */
1262 if (IS_AST_OP (cexpr) &&
1263 cexpr->opval.op == CAST &&
1264 IS_LITERAL (cexpr->right->ftype))
1265 return valCastLiteral (cexpr->ftype,
1266 floatFromVal (cexpr->right->opval.val));
1268 if (IS_AST_VALUE (cexpr))
1269 return cexpr->opval.val;
1272 werror (E_CONST_EXPECTED, "found expression");
1277 /* return the value */
1278 return cexpr->opval.val;
1282 /*-----------------------------------------------------------------*/
1283 /* isLabelInAst - will return true if a given label is found */
1284 /*-----------------------------------------------------------------*/
1286 isLabelInAst (symbol * label, ast * tree)
1288 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1291 if (IS_AST_OP (tree) &&
1292 tree->opval.op == LABEL &&
1293 isSymbolEqual (AST_SYMBOL (tree->left), label))
1296 return isLabelInAst (label, tree->right) &&
1297 isLabelInAst (label, tree->left);
1301 /*-----------------------------------------------------------------*/
1302 /* isLoopCountable - return true if the loop count can be determi- */
1303 /* -ned at compile time . */
1304 /*-----------------------------------------------------------------*/
1306 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1307 symbol ** sym, ast ** init, ast ** end)
1310 /* the loop is considered countable if the following
1311 conditions are true :-
1313 a) initExpr :- <sym> = <const>
1314 b) condExpr :- <sym> < <const1>
1315 c) loopExpr :- <sym> ++
1318 /* first check the initExpr */
1319 if (IS_AST_OP (initExpr) &&
1320 initExpr->opval.op == '=' && /* is assignment */
1321 IS_AST_SYM_VALUE (initExpr->left))
1322 { /* left is a symbol */
1324 *sym = AST_SYMBOL (initExpr->left);
1325 *init = initExpr->right;
1330 /* for now the symbol has to be of
1332 if (!IS_INTEGRAL ((*sym)->type))
1335 /* now check condExpr */
1336 if (IS_AST_OP (condExpr))
1339 switch (condExpr->opval.op)
1342 if (IS_AST_SYM_VALUE (condExpr->left) &&
1343 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1344 IS_AST_LIT_VALUE (condExpr->right))
1346 *end = condExpr->right;
1352 if (IS_AST_OP (condExpr->left) &&
1353 condExpr->left->opval.op == '>' &&
1354 IS_AST_LIT_VALUE (condExpr->left->right) &&
1355 IS_AST_SYM_VALUE (condExpr->left->left) &&
1356 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1359 *end = newNode ('+', condExpr->left->right,
1360 newAst_VALUE (constVal ("1")));
1371 /* check loop expression is of the form <sym>++ */
1372 if (!IS_AST_OP (loopExpr))
1375 /* check if <sym> ++ */
1376 if (loopExpr->opval.op == INC_OP)
1382 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1383 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1390 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1391 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1399 if (loopExpr->opval.op == ADD_ASSIGN)
1402 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1403 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1404 IS_AST_LIT_VALUE (loopExpr->right) &&
1405 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1413 /*-----------------------------------------------------------------*/
1414 /* astHasVolatile - returns true if ast contains any volatile */
1415 /*-----------------------------------------------------------------*/
1417 astHasVolatile (ast * tree)
1422 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1425 if (IS_AST_OP (tree))
1426 return astHasVolatile (tree->left) ||
1427 astHasVolatile (tree->right);
1432 /*-----------------------------------------------------------------*/
1433 /* astHasPointer - return true if the ast contains any ptr variable */
1434 /*-----------------------------------------------------------------*/
1436 astHasPointer (ast * tree)
1441 if (IS_AST_LINK (tree))
1444 /* if we hit an array expression then check
1445 only the left side */
1446 if (IS_AST_OP (tree) && tree->opval.op == '[')
1447 return astHasPointer (tree->left);
1449 if (IS_AST_VALUE (tree))
1450 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1452 return astHasPointer (tree->left) ||
1453 astHasPointer (tree->right);
1457 /*-----------------------------------------------------------------*/
1458 /* astHasSymbol - return true if the ast has the given symbol */
1459 /*-----------------------------------------------------------------*/
1461 astHasSymbol (ast * tree, symbol * sym)
1463 if (!tree || IS_AST_LINK (tree))
1466 if (IS_AST_VALUE (tree))
1468 if (IS_AST_SYM_VALUE (tree))
1469 return isSymbolEqual (AST_SYMBOL (tree), sym);
1474 return astHasSymbol (tree->left, sym) ||
1475 astHasSymbol (tree->right, sym);
1478 /*-----------------------------------------------------------------*/
1479 /* astHasDeref - return true if the ast has an indirect access */
1480 /*-----------------------------------------------------------------*/
1482 astHasDeref (ast * tree)
1484 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1487 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1489 return astHasDeref (tree->left) || astHasDeref (tree->right);
1492 /*-----------------------------------------------------------------*/
1493 /* isConformingBody - the loop body has to conform to a set of rules */
1494 /* for the loop to be considered reversible read on for rules */
1495 /*-----------------------------------------------------------------*/
1497 isConformingBody (ast * pbody, symbol * sym, ast * body)
1500 /* we are going to do a pre-order traversal of the
1501 tree && check for the following conditions. (essentially
1502 a set of very shallow tests )
1503 a) the sym passed does not participate in
1504 any arithmetic operation
1505 b) There are no function calls
1506 c) all jumps are within the body
1507 d) address of loop control variable not taken
1508 e) if an assignment has a pointer on the
1509 left hand side make sure right does not have
1510 loop control variable */
1512 /* if we reach the end or a leaf then true */
1513 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1517 /* if anything else is "volatile" */
1518 if (IS_VOLATILE (TETYPE (pbody)))
1521 /* we will walk the body in a pre-order traversal for
1523 switch (pbody->opval.op)
1525 /*------------------------------------------------------------------*/
1527 return isConformingBody (pbody->right, sym, body);
1529 /*------------------------------------------------------------------*/
1534 /*------------------------------------------------------------------*/
1535 case INC_OP: /* incerement operator unary so left only */
1538 /* sure we are not sym is not modified */
1540 IS_AST_SYM_VALUE (pbody->left) &&
1541 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1545 IS_AST_SYM_VALUE (pbody->right) &&
1546 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1551 /*------------------------------------------------------------------*/
1553 case '*': /* can be unary : if right is null then unary operation */
1558 /* if right is NULL then unary operation */
1559 /*------------------------------------------------------------------*/
1560 /*----------------------------*/
1562 /*----------------------------*/
1565 if (IS_AST_SYM_VALUE (pbody->left) &&
1566 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1569 return isConformingBody (pbody->left, sym, body);
1573 if (astHasSymbol (pbody->left, sym) ||
1574 astHasSymbol (pbody->right, sym))
1579 /*------------------------------------------------------------------*/
1587 if (IS_AST_SYM_VALUE (pbody->left) &&
1588 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1591 if (IS_AST_SYM_VALUE (pbody->right) &&
1592 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1595 return isConformingBody (pbody->left, sym, body) &&
1596 isConformingBody (pbody->right, sym, body);
1603 if (IS_AST_SYM_VALUE (pbody->left) &&
1604 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1606 return isConformingBody (pbody->left, sym, body);
1608 /*------------------------------------------------------------------*/
1620 case SIZEOF: /* evaluate wihout code generation */
1622 return isConformingBody (pbody->left, sym, body) &&
1623 isConformingBody (pbody->right, sym, body);
1625 /*------------------------------------------------------------------*/
1628 /* if left has a pointer & right has loop
1629 control variable then we cannot */
1630 if (astHasPointer (pbody->left) &&
1631 astHasSymbol (pbody->right, sym))
1633 if (astHasVolatile (pbody->left))
1636 if (IS_AST_SYM_VALUE (pbody->left) &&
1637 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1640 if (astHasVolatile (pbody->left))
1643 if (astHasDeref(pbody->right)) return FALSE;
1645 return isConformingBody (pbody->left, sym, body) &&
1646 isConformingBody (pbody->right, sym, body);
1657 assert ("Parser should not have generated this\n");
1659 /*------------------------------------------------------------------*/
1660 /*----------------------------*/
1661 /* comma operator */
1662 /*----------------------------*/
1664 return isConformingBody (pbody->left, sym, body) &&
1665 isConformingBody (pbody->right, sym, body);
1667 /*------------------------------------------------------------------*/
1668 /*----------------------------*/
1670 /*----------------------------*/
1672 /* if local & not passed as paramater then ok */
1673 if (sym->level && !astHasSymbol(pbody->right,sym))
1677 /*------------------------------------------------------------------*/
1678 /*----------------------------*/
1679 /* return statement */
1680 /*----------------------------*/
1685 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1690 if (astHasSymbol (pbody->left, sym))
1697 return isConformingBody (pbody->left, sym, body) &&
1698 isConformingBody (pbody->right, sym, body);
1704 /*-----------------------------------------------------------------*/
1705 /* isLoopReversible - takes a for loop as input && returns true */
1706 /* if the for loop is reversible. If yes will set the value of */
1707 /* the loop control var & init value & termination value */
1708 /*-----------------------------------------------------------------*/
1710 isLoopReversible (ast * loop, symbol ** loopCntrl,
1711 ast ** init, ast ** end)
1713 /* if option says don't do it then don't */
1714 if (optimize.noLoopReverse)
1716 /* there are several tests to determine this */
1718 /* for loop has to be of the form
1719 for ( <sym> = <const1> ;
1720 [<sym> < <const2>] ;
1721 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1723 if (!isLoopCountable (AST_FOR (loop, initExpr),
1724 AST_FOR (loop, condExpr),
1725 AST_FOR (loop, loopExpr),
1726 loopCntrl, init, end))
1729 /* now do some serious checking on the body of the loop
1732 return isConformingBody (loop->left, *loopCntrl, loop->left);
1736 /*-----------------------------------------------------------------*/
1737 /* replLoopSym - replace the loop sym by loop sym -1 */
1738 /*-----------------------------------------------------------------*/
1740 replLoopSym (ast * body, symbol * sym)
1743 if (!body || IS_AST_LINK (body))
1746 if (IS_AST_SYM_VALUE (body))
1749 if (isSymbolEqual (AST_SYMBOL (body), sym))
1753 body->opval.op = '-';
1754 body->left = newAst_VALUE (symbolVal (sym));
1755 body->right = newAst_VALUE (constVal ("1"));
1763 replLoopSym (body->left, sym);
1764 replLoopSym (body->right, sym);
1768 /*-----------------------------------------------------------------*/
1769 /* reverseLoop - do the actual loop reversal */
1770 /*-----------------------------------------------------------------*/
1772 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1776 /* create the following tree
1781 if (sym) goto for_continue ;
1784 /* put it together piece by piece */
1785 rloop = newNode (NULLOP,
1786 createIf (newAst_VALUE (symbolVal (sym)),
1788 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1791 newAst_VALUE (symbolVal (sym)),
1794 replLoopSym (loop->left, sym);
1796 rloop = newNode (NULLOP,
1798 newAst_VALUE (symbolVal (sym)),
1799 newNode ('-', end, init)),
1800 createLabel (AST_FOR (loop, continueLabel),
1804 newNode (SUB_ASSIGN,
1805 newAst_VALUE (symbolVal (sym)),
1806 newAst_VALUE (constVal ("1"))),
1809 return decorateType (rloop);
1813 /*-----------------------------------------------------------------*/
1814 /* decorateType - compute type for this tree also does type cheking */
1815 /* this is done bottom up, since type have to flow upwards */
1816 /* it also does constant folding, and paramater checking */
1817 /*-----------------------------------------------------------------*/
1819 decorateType (ast * tree)
1827 /* if already has type then do nothing */
1828 if (tree->decorated)
1831 tree->decorated = 1;
1833 /* print the line */
1834 /* if not block & function */
1835 if (tree->type == EX_OP &&
1836 (tree->opval.op != FUNCTION &&
1837 tree->opval.op != BLOCK &&
1838 tree->opval.op != NULLOP))
1840 filename = tree->filename;
1841 lineno = tree->lineno;
1844 /* if any child is an error | this one is an error do nothing */
1845 if (tree->isError ||
1846 (tree->left && tree->left->isError) ||
1847 (tree->right && tree->right->isError))
1850 /*------------------------------------------------------------------*/
1851 /*----------------------------*/
1852 /* leaf has been reached */
1853 /*----------------------------*/
1854 /* if this is of type value */
1855 /* just get the type */
1856 if (tree->type == EX_VALUE)
1859 if (IS_LITERAL (tree->opval.val->etype))
1862 /* if this is a character array then declare it */
1863 if (IS_ARRAY (tree->opval.val->type))
1864 tree->opval.val = stringToSymbol (tree->opval.val);
1866 /* otherwise just copy the type information */
1867 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1871 if (tree->opval.val->sym)
1873 /* if the undefined flag is set then give error message */
1874 if (tree->opval.val->sym->undefined)
1876 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1878 TTYPE (tree) = TETYPE (tree) =
1879 tree->opval.val->type = tree->opval.val->sym->type =
1880 tree->opval.val->etype = tree->opval.val->sym->etype =
1881 copyLinkChain (INTTYPE);
1886 /* if impilicit i.e. struct/union member then no type */
1887 if (tree->opval.val->sym->implicit)
1888 TTYPE (tree) = TETYPE (tree) = NULL;
1893 /* else copy the type */
1894 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1896 /* and mark it as referenced */
1897 tree->opval.val->sym->isref = 1;
1905 /* if type link for the case of cast */
1906 if (tree->type == EX_LINK)
1908 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1915 dtl = decorateType (tree->left);
1916 /* delay right side for '?' operator since conditional macro expansions might
1918 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1920 /* this is to take care of situations
1921 when the tree gets rewritten */
1922 if (dtl != tree->left)
1924 if (dtr != tree->right)
1928 /* depending on type of operator do */
1930 switch (tree->opval.op)
1932 /*------------------------------------------------------------------*/
1933 /*----------------------------*/
1935 /*----------------------------*/
1938 /* determine which is the array & which the index */
1939 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1942 ast *tempTree = tree->left;
1943 tree->left = tree->right;
1944 tree->right = tempTree;
1947 /* first check if this is a array or a pointer */
1948 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1950 werror (E_NEED_ARRAY_PTR, "[]");
1951 goto errorTreeReturn;
1954 /* check if the type of the idx */
1955 if (!IS_INTEGRAL (RTYPE (tree)))
1957 werror (E_IDX_NOT_INT);
1958 goto errorTreeReturn;
1961 /* if the left is an rvalue then error */
1964 werror (E_LVALUE_REQUIRED, "array access");
1965 goto errorTreeReturn;
1968 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1969 if (IS_PTR(LTYPE(tree))) {
1970 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1974 /*------------------------------------------------------------------*/
1975 /*----------------------------*/
1977 /*----------------------------*/
1979 /* if this is not a structure */
1980 if (!IS_STRUCT (LTYPE (tree)))
1982 werror (E_STRUCT_UNION, ".");
1983 goto errorTreeReturn;
1985 TTYPE (tree) = structElemType (LTYPE (tree),
1986 (tree->right->type == EX_VALUE ?
1987 tree->right->opval.val : NULL));
1988 TETYPE (tree) = getSpec (TTYPE (tree));
1991 /*------------------------------------------------------------------*/
1992 /*----------------------------*/
1993 /* struct/union pointer */
1994 /*----------------------------*/
1996 /* if not pointer to a structure */
1997 if (!IS_PTR (LTYPE (tree)))
1999 werror (E_PTR_REQD);
2000 goto errorTreeReturn;
2003 if (!IS_STRUCT (LTYPE (tree)->next))
2005 werror (E_STRUCT_UNION, "->");
2006 goto errorTreeReturn;
2009 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2010 (tree->right->type == EX_VALUE ?
2011 tree->right->opval.val : NULL));
2012 TETYPE (tree) = getSpec (TTYPE (tree));
2014 /* adjust the storage class */
2015 switch (DCL_TYPE(tree->left->ftype)) {
2019 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2022 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2027 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2030 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2033 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2042 /*------------------------------------------------------------------*/
2043 /*----------------------------*/
2044 /* ++/-- operation */
2045 /*----------------------------*/
2046 case INC_OP: /* incerement operator unary so left only */
2049 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2050 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2051 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2052 werror (E_CODE_WRITE, "++/--");
2061 /*------------------------------------------------------------------*/
2062 /*----------------------------*/
2064 /*----------------------------*/
2065 case '&': /* can be unary */
2066 /* if right is NULL then unary operation */
2067 if (tree->right) /* not an unary operation */
2070 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2072 werror (E_BITWISE_OP);
2073 werror (W_CONTINUE, "left & right types are ");
2074 printTypeChain (LTYPE (tree), stderr);
2075 fprintf (stderr, ",");
2076 printTypeChain (RTYPE (tree), stderr);
2077 fprintf (stderr, "\n");
2078 goto errorTreeReturn;
2081 /* if they are both literal */
2082 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2084 tree->type = EX_VALUE;
2085 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2086 valFromType (RETYPE (tree)), '&');
2088 tree->right = tree->left = NULL;
2089 TETYPE (tree) = tree->opval.val->etype;
2090 TTYPE (tree) = tree->opval.val->type;
2094 /* see if this is a GETHBIT operation if yes
2097 ast *otree = optimizeGetHbit (tree);
2100 return decorateType (otree);
2104 computeType (LTYPE (tree), RTYPE (tree));
2105 TETYPE (tree) = getSpec (TTYPE (tree));
2107 LRVAL (tree) = RRVAL (tree) = 1;
2111 /*------------------------------------------------------------------*/
2112 /*----------------------------*/
2114 /*----------------------------*/
2116 p->class = DECLARATOR;
2117 /* if bit field then error */
2118 if (IS_BITVAR (tree->left->etype))
2120 werror (E_ILLEGAL_ADDR, "address of bit variable");
2121 goto errorTreeReturn;
2124 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2126 werror (E_ILLEGAL_ADDR, "address of register variable");
2127 goto errorTreeReturn;
2130 if (IS_FUNC (LTYPE (tree)))
2132 werror (E_ILLEGAL_ADDR, "address of function");
2133 goto errorTreeReturn;
2136 if (IS_LITERAL(LTYPE(tree)))
2138 werror (E_ILLEGAL_ADDR, "address of literal");
2139 goto errorTreeReturn;
2144 werror (E_LVALUE_REQUIRED, "address of");
2145 goto errorTreeReturn;
2147 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2149 DCL_TYPE (p) = CPOINTER;
2150 DCL_PTR_CONST (p) = port->mem.code_ro;
2152 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2153 DCL_TYPE (p) = FPOINTER;
2154 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2155 DCL_TYPE (p) = PPOINTER;
2156 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2157 DCL_TYPE (p) = IPOINTER;
2158 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2159 DCL_TYPE (p) = EEPPOINTER;
2160 else if (SPEC_OCLS(tree->left->etype))
2161 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2163 DCL_TYPE (p) = POINTER;
2165 if (IS_AST_SYM_VALUE (tree->left))
2167 AST_SYMBOL (tree->left)->addrtaken = 1;
2168 AST_SYMBOL (tree->left)->allocreq = 1;
2171 p->next = LTYPE (tree);
2173 TETYPE (tree) = getSpec (TTYPE (tree));
2174 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2175 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2180 /*------------------------------------------------------------------*/
2181 /*----------------------------*/
2183 /*----------------------------*/
2185 /* if the rewrite succeeds then don't go any furthur */
2187 ast *wtree = optimizeRRCRLC (tree);
2189 return decorateType (wtree);
2191 /*------------------------------------------------------------------*/
2192 /*----------------------------*/
2194 /*----------------------------*/
2196 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2198 werror (E_BITWISE_OP);
2199 werror (W_CONTINUE, "left & right types are ");
2200 printTypeChain (LTYPE (tree), stderr);
2201 fprintf (stderr, ",");
2202 printTypeChain (RTYPE (tree), stderr);
2203 fprintf (stderr, "\n");
2204 goto errorTreeReturn;
2207 /* if they are both literal then */
2208 /* rewrite the tree */
2209 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2211 tree->type = EX_VALUE;
2212 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2213 valFromType (RETYPE (tree)),
2215 tree->right = tree->left = NULL;
2216 TETYPE (tree) = tree->opval.val->etype;
2217 TTYPE (tree) = tree->opval.val->type;
2220 LRVAL (tree) = RRVAL (tree) = 1;
2221 TETYPE (tree) = getSpec (TTYPE (tree) =
2222 computeType (LTYPE (tree),
2225 /*------------------------------------------------------------------*/
2226 /*----------------------------*/
2228 /*----------------------------*/
2230 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2232 werror (E_INVALID_OP, "divide");
2233 goto errorTreeReturn;
2235 /* if they are both literal then */
2236 /* rewrite the tree */
2237 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2239 tree->type = EX_VALUE;
2240 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2241 valFromType (RETYPE (tree)));
2242 tree->right = tree->left = NULL;
2243 TETYPE (tree) = getSpec (TTYPE (tree) =
2244 tree->opval.val->type);
2247 LRVAL (tree) = RRVAL (tree) = 1;
2248 TETYPE (tree) = getSpec (TTYPE (tree) =
2249 computeType (LTYPE (tree),
2253 /*------------------------------------------------------------------*/
2254 /*----------------------------*/
2256 /*----------------------------*/
2258 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2260 werror (E_BITWISE_OP);
2261 werror (W_CONTINUE, "left & right types are ");
2262 printTypeChain (LTYPE (tree), stderr);
2263 fprintf (stderr, ",");
2264 printTypeChain (RTYPE (tree), stderr);
2265 fprintf (stderr, "\n");
2266 goto errorTreeReturn;
2268 /* if they are both literal then */
2269 /* rewrite the tree */
2270 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2272 tree->type = EX_VALUE;
2273 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2274 valFromType (RETYPE (tree)));
2275 tree->right = tree->left = NULL;
2276 TETYPE (tree) = getSpec (TTYPE (tree) =
2277 tree->opval.val->type);
2280 LRVAL (tree) = RRVAL (tree) = 1;
2281 TETYPE (tree) = getSpec (TTYPE (tree) =
2282 computeType (LTYPE (tree),
2286 /*------------------------------------------------------------------*/
2287 /*----------------------------*/
2288 /* address dereference */
2289 /*----------------------------*/
2290 case '*': /* can be unary : if right is null then unary operation */
2293 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2295 werror (E_PTR_REQD);
2296 goto errorTreeReturn;
2301 werror (E_LVALUE_REQUIRED, "pointer deref");
2302 goto errorTreeReturn;
2304 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2305 LTYPE (tree)->next : NULL);
2306 TETYPE (tree) = getSpec (TTYPE (tree));
2307 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2311 /*------------------------------------------------------------------*/
2312 /*----------------------------*/
2313 /* multiplication */
2314 /*----------------------------*/
2315 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2317 werror (E_INVALID_OP, "multiplication");
2318 goto errorTreeReturn;
2321 /* if they are both literal then */
2322 /* rewrite the tree */
2323 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2325 tree->type = EX_VALUE;
2326 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2327 valFromType (RETYPE (tree)));
2328 tree->right = tree->left = NULL;
2329 TETYPE (tree) = getSpec (TTYPE (tree) =
2330 tree->opval.val->type);
2334 /* if left is a literal exchange left & right */
2335 if (IS_LITERAL (LTYPE (tree)))
2337 ast *tTree = tree->left;
2338 tree->left = tree->right;
2339 tree->right = tTree;
2342 LRVAL (tree) = RRVAL (tree) = 1;
2343 /* promote result to int if left & right are char
2344 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2345 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2346 TETYPE (tree) = getSpec (TTYPE (tree) =
2347 computeType (LTYPE (tree),
2349 SPEC_NOUN(TETYPE(tree)) = V_INT;
2351 TETYPE (tree) = getSpec (TTYPE (tree) =
2352 computeType (LTYPE (tree),
2357 /*------------------------------------------------------------------*/
2358 /*----------------------------*/
2359 /* unary '+' operator */
2360 /*----------------------------*/
2365 if (!IS_INTEGRAL (LTYPE (tree)))
2367 werror (E_UNARY_OP, '+');
2368 goto errorTreeReturn;
2371 /* if left is a literal then do it */
2372 if (IS_LITERAL (LTYPE (tree)))
2374 tree->type = EX_VALUE;
2375 tree->opval.val = valFromType (LETYPE (tree));
2377 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2381 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2385 /*------------------------------------------------------------------*/
2386 /*----------------------------*/
2388 /*----------------------------*/
2390 /* this is not a unary operation */
2391 /* if both pointers then problem */
2392 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2393 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2395 werror (E_PTR_PLUS_PTR);
2396 goto errorTreeReturn;
2399 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2400 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2402 werror (E_PLUS_INVALID, "+");
2403 goto errorTreeReturn;
2406 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2407 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2409 werror (E_PLUS_INVALID, "+");
2410 goto errorTreeReturn;
2412 /* if they are both literal then */
2413 /* rewrite the tree */
2414 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2416 tree->type = EX_VALUE;
2417 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2418 valFromType (RETYPE (tree)));
2419 tree->right = tree->left = NULL;
2420 TETYPE (tree) = getSpec (TTYPE (tree) =
2421 tree->opval.val->type);
2425 /* if the right is a pointer or left is a literal
2426 xchange left & right */
2427 if (IS_ARRAY (RTYPE (tree)) ||
2428 IS_PTR (RTYPE (tree)) ||
2429 IS_LITERAL (LTYPE (tree)))
2431 ast *tTree = tree->left;
2432 tree->left = tree->right;
2433 tree->right = tTree;
2436 LRVAL (tree) = RRVAL (tree) = 1;
2437 /* if the left is a pointer */
2438 if (IS_PTR (LTYPE (tree)))
2439 TETYPE (tree) = getSpec (TTYPE (tree) =
2442 TETYPE (tree) = getSpec (TTYPE (tree) =
2443 computeType (LTYPE (tree),
2447 /*------------------------------------------------------------------*/
2448 /*----------------------------*/
2450 /*----------------------------*/
2451 case '-': /* can be unary */
2452 /* if right is null then unary */
2456 if (!IS_ARITHMETIC (LTYPE (tree)))
2458 werror (E_UNARY_OP, tree->opval.op);
2459 goto errorTreeReturn;
2462 /* if left is a literal then do it */
2463 if (IS_LITERAL (LTYPE (tree)))
2465 tree->type = EX_VALUE;
2466 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2468 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2469 SPEC_USIGN(TETYPE(tree)) = 0;
2473 TTYPE (tree) = LTYPE (tree);
2477 /*------------------------------------------------------------------*/
2478 /*----------------------------*/
2480 /*----------------------------*/
2482 if (!(IS_PTR (LTYPE (tree)) ||
2483 IS_ARRAY (LTYPE (tree)) ||
2484 IS_ARITHMETIC (LTYPE (tree))))
2486 werror (E_PLUS_INVALID, "-");
2487 goto errorTreeReturn;
2490 if (!(IS_PTR (RTYPE (tree)) ||
2491 IS_ARRAY (RTYPE (tree)) ||
2492 IS_ARITHMETIC (RTYPE (tree))))
2494 werror (E_PLUS_INVALID, "-");
2495 goto errorTreeReturn;
2498 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2499 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2500 IS_INTEGRAL (RTYPE (tree))))
2502 werror (E_PLUS_INVALID, "-");
2503 goto errorTreeReturn;
2506 /* if they are both literal then */
2507 /* rewrite the tree */
2508 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2510 tree->type = EX_VALUE;
2511 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2512 valFromType (RETYPE (tree)));
2513 tree->right = tree->left = NULL;
2514 TETYPE (tree) = getSpec (TTYPE (tree) =
2515 tree->opval.val->type);
2519 /* if the left & right are equal then zero */
2520 if (isAstEqual (tree->left, tree->right))
2522 tree->type = EX_VALUE;
2523 tree->left = tree->right = NULL;
2524 tree->opval.val = constVal ("0");
2525 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2529 /* if both of them are pointers or arrays then */
2530 /* the result is going to be an integer */
2531 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2532 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2533 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2535 /* if only the left is a pointer */
2536 /* then result is a pointer */
2537 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2538 TETYPE (tree) = getSpec (TTYPE (tree) =
2541 TETYPE (tree) = getSpec (TTYPE (tree) =
2542 computeType (LTYPE (tree),
2544 LRVAL (tree) = RRVAL (tree) = 1;
2547 /*------------------------------------------------------------------*/
2548 /*----------------------------*/
2550 /*----------------------------*/
2552 /* can be only integral type */
2553 if (!IS_INTEGRAL (LTYPE (tree)))
2555 werror (E_UNARY_OP, tree->opval.op);
2556 goto errorTreeReturn;
2559 /* if left is a literal then do it */
2560 if (IS_LITERAL (LTYPE (tree)))
2562 tree->type = EX_VALUE;
2563 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2565 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2569 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2572 /*------------------------------------------------------------------*/
2573 /*----------------------------*/
2575 /*----------------------------*/
2577 /* can be pointer */
2578 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2579 !IS_PTR (LTYPE (tree)) &&
2580 !IS_ARRAY (LTYPE (tree)))
2582 werror (E_UNARY_OP, tree->opval.op);
2583 goto errorTreeReturn;
2586 /* if left is a literal then do it */
2587 if (IS_LITERAL (LTYPE (tree)))
2589 tree->type = EX_VALUE;
2590 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2592 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2596 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2599 /*------------------------------------------------------------------*/
2600 /*----------------------------*/
2602 /*----------------------------*/
2605 TTYPE (tree) = LTYPE (tree);
2606 TETYPE (tree) = LETYPE (tree);
2610 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2615 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2617 werror (E_SHIFT_OP_INVALID);
2618 werror (W_CONTINUE, "left & right types are ");
2619 printTypeChain (LTYPE (tree), stderr);
2620 fprintf (stderr, ",");
2621 printTypeChain (RTYPE (tree), stderr);
2622 fprintf (stderr, "\n");
2623 goto errorTreeReturn;
2626 /* if they are both literal then */
2627 /* rewrite the tree */
2628 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2630 tree->type = EX_VALUE;
2631 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2632 valFromType (RETYPE (tree)),
2633 (tree->opval.op == LEFT_OP ? 1 : 0));
2634 tree->right = tree->left = NULL;
2635 TETYPE (tree) = getSpec (TTYPE (tree) =
2636 tree->opval.val->type);
2639 /* if only the right side is a literal & we are
2640 shifting more than size of the left operand then zero */
2641 if (IS_LITERAL (RTYPE (tree)) &&
2642 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2643 (getSize (LTYPE (tree)) * 8))
2645 werror (W_SHIFT_CHANGED,
2646 (tree->opval.op == LEFT_OP ? "left" : "right"));
2647 tree->type = EX_VALUE;
2648 tree->left = tree->right = NULL;
2649 tree->opval.val = constVal ("0");
2650 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2653 LRVAL (tree) = RRVAL (tree) = 1;
2654 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2656 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2660 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2664 /*------------------------------------------------------------------*/
2665 /*----------------------------*/
2667 /*----------------------------*/
2668 case CAST: /* change the type */
2669 /* cannot cast to an aggregate type */
2670 if (IS_AGGREGATE (LTYPE (tree)))
2672 werror (E_CAST_ILLEGAL);
2673 goto errorTreeReturn;
2676 /* make sure the type is complete and sane */
2677 checkTypeSanity(LETYPE(tree), "(cast)");
2680 /* if the right is a literal replace the tree */
2681 if (IS_LITERAL (RETYPE (tree))) {
2682 if (!IS_PTR (LTYPE (tree))) {
2683 tree->type = EX_VALUE;
2685 valCastLiteral (LTYPE (tree),
2686 floatFromVal (valFromType (RETYPE (tree))));
2689 TTYPE (tree) = tree->opval.val->type;
2690 tree->values.literalFromCast = 1;
2691 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2692 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2693 sym_link *rest = LTYPE(tree)->next;
2694 werror(W_LITERAL_GENERIC);
2695 TTYPE(tree) = newLink();
2696 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2697 TTYPE(tree)->next = rest;
2698 tree->left->opval.lnk = TTYPE(tree);
2701 TTYPE (tree) = LTYPE (tree);
2705 TTYPE (tree) = LTYPE (tree);
2709 /* if pointer to struct then check names */
2710 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2711 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2712 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2713 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2715 /* if the right is a literal replace the tree */
2716 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2717 tree->type = EX_VALUE;
2719 valCastLiteral (LTYPE (tree),
2720 floatFromVal (valFromType (RETYPE (tree))));
2723 TTYPE (tree) = tree->opval.val->type;
2724 tree->values.literalFromCast = 1;
2726 TTYPE (tree) = LTYPE (tree);
2730 TETYPE (tree) = getSpec (TTYPE (tree));
2734 /*------------------------------------------------------------------*/
2735 /*----------------------------*/
2736 /* logical &&, || */
2737 /*----------------------------*/
2740 /* each must me arithmetic type or be a pointer */
2741 if (!IS_PTR (LTYPE (tree)) &&
2742 !IS_ARRAY (LTYPE (tree)) &&
2743 !IS_INTEGRAL (LTYPE (tree)))
2745 werror (E_COMPARE_OP);
2746 goto errorTreeReturn;
2749 if (!IS_PTR (RTYPE (tree)) &&
2750 !IS_ARRAY (RTYPE (tree)) &&
2751 !IS_INTEGRAL (RTYPE (tree)))
2753 werror (E_COMPARE_OP);
2754 goto errorTreeReturn;
2756 /* if they are both literal then */
2757 /* rewrite the tree */
2758 if (IS_LITERAL (RTYPE (tree)) &&
2759 IS_LITERAL (LTYPE (tree)))
2761 tree->type = EX_VALUE;
2762 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2763 valFromType (RETYPE (tree)),
2765 tree->right = tree->left = NULL;
2766 TETYPE (tree) = getSpec (TTYPE (tree) =
2767 tree->opval.val->type);
2770 LRVAL (tree) = RRVAL (tree) = 1;
2771 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2774 /*------------------------------------------------------------------*/
2775 /*----------------------------*/
2776 /* comparison operators */
2777 /*----------------------------*/
2785 ast *lt = optimizeCompare (tree);
2791 /* if they are pointers they must be castable */
2792 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2794 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2796 werror (E_COMPARE_OP);
2797 fprintf (stderr, "comparing type ");
2798 printTypeChain (LTYPE (tree), stderr);
2799 fprintf (stderr, "to type ");
2800 printTypeChain (RTYPE (tree), stderr);
2801 fprintf (stderr, "\n");
2802 goto errorTreeReturn;
2805 /* else they should be promotable to one another */
2808 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2809 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2811 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2813 werror (E_COMPARE_OP);
2814 fprintf (stderr, "comparing type ");
2815 printTypeChain (LTYPE (tree), stderr);
2816 fprintf (stderr, "to type ");
2817 printTypeChain (RTYPE (tree), stderr);
2818 fprintf (stderr, "\n");
2819 goto errorTreeReturn;
2822 /* if unsigned value < 0 then always false */
2823 /* if (unsigned value) > 0 then (unsigned value) */
2824 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2825 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2827 if (tree->opval.op == '<') {
2830 if (tree->opval.op == '>') {
2834 /* if they are both literal then */
2835 /* rewrite the tree */
2836 if (IS_LITERAL (RTYPE (tree)) &&
2837 IS_LITERAL (LTYPE (tree)))
2839 tree->type = EX_VALUE;
2840 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2841 valFromType (RETYPE (tree)),
2843 tree->right = tree->left = NULL;
2844 TETYPE (tree) = getSpec (TTYPE (tree) =
2845 tree->opval.val->type);
2848 LRVAL (tree) = RRVAL (tree) = 1;
2849 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2852 /*------------------------------------------------------------------*/
2853 /*----------------------------*/
2855 /*----------------------------*/
2856 case SIZEOF: /* evaluate wihout code generation */
2857 /* change the type to a integer */
2858 tree->type = EX_VALUE;
2859 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2860 tree->opval.val = constVal (buffer);
2861 tree->right = tree->left = NULL;
2862 TETYPE (tree) = getSpec (TTYPE (tree) =
2863 tree->opval.val->type);
2866 /*------------------------------------------------------------------*/
2867 /*----------------------------*/
2869 /*----------------------------*/
2871 /* return typeof enum value */
2872 tree->type = EX_VALUE;
2875 if (IS_SPEC(tree->right->ftype)) {
2876 switch (SPEC_NOUN(tree->right->ftype)) {
2878 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2879 else typeofv = TYPEOF_INT;
2882 typeofv = TYPEOF_FLOAT;
2885 typeofv = TYPEOF_CHAR;
2888 typeofv = TYPEOF_VOID;
2891 typeofv = TYPEOF_STRUCT;
2894 typeofv = TYPEOF_BIT;
2897 typeofv = TYPEOF_SBIT;
2903 switch (DCL_TYPE(tree->right->ftype)) {
2905 typeofv = TYPEOF_POINTER;
2908 typeofv = TYPEOF_FPOINTER;
2911 typeofv = TYPEOF_CPOINTER;
2914 typeofv = TYPEOF_GPOINTER;
2917 typeofv = TYPEOF_PPOINTER;
2920 typeofv = TYPEOF_IPOINTER;
2923 typeofv = TYPEOF_ARRAY;
2926 typeofv = TYPEOF_FUNCTION;
2932 sprintf (buffer, "%d", typeofv);
2933 tree->opval.val = constVal (buffer);
2934 tree->right = tree->left = NULL;
2935 TETYPE (tree) = getSpec (TTYPE (tree) =
2936 tree->opval.val->type);
2939 /*------------------------------------------------------------------*/
2940 /*----------------------------*/
2941 /* conditional operator '?' */
2942 /*----------------------------*/
2944 /* the type is value of the colon operator (on the right) */
2945 assert(IS_COLON_OP(tree->right));
2946 /* if already known then replace the tree : optimizer will do it
2947 but faster to do it here */
2948 if (IS_LITERAL (LTYPE(tree))) {
2949 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2950 return decorateType(tree->right->left) ;
2952 return decorateType(tree->right->right) ;
2955 tree->right = decorateType(tree->right);
2956 TTYPE (tree) = RTYPE(tree);
2957 TETYPE (tree) = getSpec (TTYPE (tree));
2962 /* if they don't match we have a problem */
2963 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2965 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2966 goto errorTreeReturn;
2969 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2970 TETYPE (tree) = getSpec (TTYPE (tree));
2974 #if 0 // assignment operators are converted by the parser
2975 /*------------------------------------------------------------------*/
2976 /*----------------------------*/
2977 /* assignment operators */
2978 /*----------------------------*/
2981 /* for these it must be both must be integral */
2982 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2983 !IS_ARITHMETIC (RTYPE (tree)))
2985 werror (E_OPS_INTEGRAL);
2986 goto errorTreeReturn;
2989 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2991 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2992 werror (E_CODE_WRITE, " ");
2996 werror (E_LVALUE_REQUIRED, "*= or /=");
2997 goto errorTreeReturn;
3008 /* for these it must be both must be integral */
3009 if (!IS_INTEGRAL (LTYPE (tree)) ||
3010 !IS_INTEGRAL (RTYPE (tree)))
3012 werror (E_OPS_INTEGRAL);
3013 goto errorTreeReturn;
3016 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3018 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3019 werror (E_CODE_WRITE, " ");
3023 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3024 goto errorTreeReturn;
3030 /*------------------------------------------------------------------*/
3031 /*----------------------------*/
3033 /*----------------------------*/
3035 if (!(IS_PTR (LTYPE (tree)) ||
3036 IS_ARITHMETIC (LTYPE (tree))))
3038 werror (E_PLUS_INVALID, "-=");
3039 goto errorTreeReturn;
3042 if (!(IS_PTR (RTYPE (tree)) ||
3043 IS_ARITHMETIC (RTYPE (tree))))
3045 werror (E_PLUS_INVALID, "-=");
3046 goto errorTreeReturn;
3049 TETYPE (tree) = getSpec (TTYPE (tree) =
3050 computeType (LTYPE (tree),
3053 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3054 werror (E_CODE_WRITE, " ");
3058 werror (E_LVALUE_REQUIRED, "-=");
3059 goto errorTreeReturn;
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3068 /*----------------------------*/
3070 /* this is not a unary operation */
3071 /* if both pointers then problem */
3072 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3074 werror (E_PTR_PLUS_PTR);
3075 goto errorTreeReturn;
3078 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3080 werror (E_PLUS_INVALID, "+=");
3081 goto errorTreeReturn;
3084 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3086 werror (E_PLUS_INVALID, "+=");
3087 goto errorTreeReturn;
3090 TETYPE (tree) = getSpec (TTYPE (tree) =
3091 computeType (LTYPE (tree),
3094 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3095 werror (E_CODE_WRITE, " ");
3099 werror (E_LVALUE_REQUIRED, "+=");
3100 goto errorTreeReturn;
3103 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3104 tree->opval.op = '=';
3109 /*------------------------------------------------------------------*/
3110 /*----------------------------*/
3111 /* straight assignemnt */
3112 /*----------------------------*/
3114 /* cannot be an aggregate */
3115 if (IS_AGGREGATE (LTYPE (tree)))
3117 werror (E_AGGR_ASSIGN);
3118 goto errorTreeReturn;
3121 /* they should either match or be castable */
3122 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3124 werror (E_TYPE_MISMATCH, "assignment", " ");
3125 printFromToType(RTYPE(tree),LTYPE(tree));
3126 //goto errorTreeReturn;
3129 /* if the left side of the tree is of type void
3130 then report error */
3131 if (IS_VOID (LTYPE (tree)))
3133 werror (E_CAST_ZERO);
3134 printFromToType(RTYPE(tree), LTYPE(tree));
3137 TETYPE (tree) = getSpec (TTYPE (tree) =
3141 if (!tree->initMode ) {
3142 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3143 werror (E_CODE_WRITE, " ");
3147 werror (E_LVALUE_REQUIRED, "=");
3148 goto errorTreeReturn;
3153 /*------------------------------------------------------------------*/
3154 /*----------------------------*/
3155 /* comma operator */
3156 /*----------------------------*/
3158 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3164 /*----------------------------*/
3168 if (processParms (tree->left,
3169 FUNC_ARGS(tree->left->ftype),
3170 tree->right, &parmNumber, TRUE)) {
3171 goto errorTreeReturn;
3174 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3175 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3177 //FUNC_ARGS(tree->left->ftype) =
3178 //reverseVal (FUNC_ARGS(tree->left->ftype));
3179 reverseParms (tree->right);
3182 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3185 /*------------------------------------------------------------------*/
3186 /*----------------------------*/
3187 /* return statement */
3188 /*----------------------------*/
3193 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3195 werror (W_RETURN_MISMATCH);
3196 printFromToType (RTYPE(tree), currFunc->type->next);
3197 goto errorTreeReturn;
3200 if (IS_VOID (currFunc->type->next)
3202 !IS_VOID (RTYPE (tree)))
3204 werror (E_FUNC_VOID);
3205 goto errorTreeReturn;
3208 /* if there is going to be a casing required then add it */
3209 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3212 decorateType (newNode (CAST,
3213 newAst_LINK (copyLinkChain (currFunc->type->next)),
3222 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3224 werror (E_VOID_FUNC, currFunc->name);
3225 goto errorTreeReturn;
3228 TTYPE (tree) = TETYPE (tree) = NULL;
3231 /*------------------------------------------------------------------*/
3232 /*----------------------------*/
3233 /* switch statement */
3234 /*----------------------------*/
3236 /* the switch value must be an integer */
3237 if (!IS_INTEGRAL (LTYPE (tree)))
3239 werror (E_SWITCH_NON_INTEGER);
3240 goto errorTreeReturn;
3243 TTYPE (tree) = TETYPE (tree) = NULL;
3246 /*------------------------------------------------------------------*/
3247 /*----------------------------*/
3249 /*----------------------------*/
3251 tree->left = backPatchLabels (tree->left,
3254 TTYPE (tree) = TETYPE (tree) = NULL;
3257 /*------------------------------------------------------------------*/
3258 /*----------------------------*/
3260 /*----------------------------*/
3263 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3264 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3265 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3267 /* if the for loop is reversible then
3268 reverse it otherwise do what we normally
3274 if (isLoopReversible (tree, &sym, &init, &end))
3275 return reverseLoop (tree, sym, init, end);
3277 return decorateType (createFor (AST_FOR (tree, trueLabel),
3278 AST_FOR (tree, continueLabel),
3279 AST_FOR (tree, falseLabel),
3280 AST_FOR (tree, condLabel),
3281 AST_FOR (tree, initExpr),
3282 AST_FOR (tree, condExpr),
3283 AST_FOR (tree, loopExpr),
3287 TTYPE (tree) = TETYPE (tree) = NULL;
3291 /* some error found this tree will be killed */
3293 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3294 tree->opval.op = NULLOP;
3300 /*-----------------------------------------------------------------*/
3301 /* sizeofOp - processes size of operation */
3302 /*-----------------------------------------------------------------*/
3304 sizeofOp (sym_link * type)
3308 /* make sure the type is complete and sane */
3309 checkTypeSanity(type, "(sizeof)");
3311 /* get the size and convert it to character */
3312 sprintf (buff, "%d", getSize (type));
3314 /* now convert into value */
3315 return constVal (buff);
3319 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3320 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3321 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3322 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3323 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3324 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3325 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3327 /*-----------------------------------------------------------------*/
3328 /* backPatchLabels - change and or not operators to flow control */
3329 /*-----------------------------------------------------------------*/
3331 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3337 if (!(IS_ANDORNOT (tree)))
3340 /* if this an and */
3343 static int localLbl = 0;
3346 sprintf (buffer, "_and_%d", localLbl++);
3347 localLabel = newSymbol (buffer, NestLevel);
3349 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3351 /* if left is already a IFX then just change the if true label in that */
3352 if (!IS_IFX (tree->left))
3353 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3355 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3356 /* right is a IFX then just join */
3357 if (IS_IFX (tree->right))
3358 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3360 tree->right = createLabel (localLabel, tree->right);
3361 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3363 return newNode (NULLOP, tree->left, tree->right);
3366 /* if this is an or operation */
3369 static int localLbl = 0;
3372 sprintf (buffer, "_or_%d", localLbl++);
3373 localLabel = newSymbol (buffer, NestLevel);
3375 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3377 /* if left is already a IFX then just change the if true label in that */
3378 if (!IS_IFX (tree->left))
3379 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3381 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3382 /* right is a IFX then just join */
3383 if (IS_IFX (tree->right))
3384 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3386 tree->right = createLabel (localLabel, tree->right);
3387 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3389 return newNode (NULLOP, tree->left, tree->right);
3395 int wasnot = IS_NOT (tree->left);
3396 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3398 /* if the left is already a IFX */
3399 if (!IS_IFX (tree->left))
3400 tree->left = newNode (IFX, tree->left, NULL);
3404 tree->left->trueLabel = trueLabel;
3405 tree->left->falseLabel = falseLabel;
3409 tree->left->trueLabel = falseLabel;
3410 tree->left->falseLabel = trueLabel;
3417 tree->trueLabel = trueLabel;
3418 tree->falseLabel = falseLabel;
3425 /*-----------------------------------------------------------------*/
3426 /* createBlock - create expression tree for block */
3427 /*-----------------------------------------------------------------*/
3429 createBlock (symbol * decl, ast * body)
3433 /* if the block has nothing */
3437 ex = newNode (BLOCK, NULL, body);
3438 ex->values.sym = decl;
3440 ex->right = ex->right;
3446 /*-----------------------------------------------------------------*/
3447 /* createLabel - creates the expression tree for labels */
3448 /*-----------------------------------------------------------------*/
3450 createLabel (symbol * label, ast * stmnt)
3453 char name[SDCC_NAME_MAX + 1];
3456 /* must create fresh symbol if the symbol name */
3457 /* exists in the symbol table, since there can */
3458 /* be a variable with the same name as the labl */
3459 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3460 (csym->level == label->level))
3461 label = newSymbol (label->name, label->level);
3463 /* change the name before putting it in add _ */
3464 sprintf (name, "%s", label->name);
3466 /* put the label in the LabelSymbol table */
3467 /* but first check if a label of the same */
3469 if ((csym = findSym (LabelTab, NULL, name)))
3470 werror (E_DUPLICATE_LABEL, label->name);
3472 addSym (LabelTab, label, name, label->level, 0, 0);
3475 label->key = labelKey++;
3476 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3482 /*-----------------------------------------------------------------*/
3483 /* createCase - generates the parsetree for a case statement */
3484 /*-----------------------------------------------------------------*/
3486 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3488 char caseLbl[SDCC_NAME_MAX + 1];
3492 /* if the switch statement does not exist */
3493 /* then case is out of context */
3496 werror (E_CASE_CONTEXT);
3500 caseVal = decorateType (resolveSymbols (caseVal));
3501 /* if not a constant then error */
3502 if (!IS_LITERAL (caseVal->ftype))
3504 werror (E_CASE_CONSTANT);
3508 /* if not a integer than error */
3509 if (!IS_INTEGRAL (caseVal->ftype))
3511 werror (E_CASE_NON_INTEGER);
3515 /* find the end of the switch values chain */
3516 if (!(val = swStat->values.switchVals.swVals))
3517 swStat->values.switchVals.swVals = caseVal->opval.val;
3520 /* also order the cases according to value */
3522 int cVal = (int) floatFromVal (caseVal->opval.val);
3523 while (val && (int) floatFromVal (val) < cVal)
3529 /* if we reached the end then */
3532 pval->next = caseVal->opval.val;
3536 /* we found a value greater than */
3537 /* the current value we must add this */
3538 /* before the value */
3539 caseVal->opval.val->next = val;
3541 /* if this was the first in chain */
3542 if (swStat->values.switchVals.swVals == val)
3543 swStat->values.switchVals.swVals =
3546 pval->next = caseVal->opval.val;
3551 /* create the case label */
3552 sprintf (caseLbl, "_case_%d_%d",
3553 swStat->values.switchVals.swNum,
3554 (int) floatFromVal (caseVal->opval.val));
3556 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3561 /*-----------------------------------------------------------------*/
3562 /* createDefault - creates the parse tree for the default statement */
3563 /*-----------------------------------------------------------------*/
3565 createDefault (ast * swStat, ast * stmnt)
3567 char defLbl[SDCC_NAME_MAX + 1];
3569 /* if the switch statement does not exist */
3570 /* then case is out of context */
3573 werror (E_CASE_CONTEXT);
3577 /* turn on the default flag */
3578 swStat->values.switchVals.swDefault = 1;
3580 /* create the label */
3581 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3582 return createLabel (newSymbol (defLbl, 0), stmnt);
3585 /*-----------------------------------------------------------------*/
3586 /* createIf - creates the parsetree for the if statement */
3587 /*-----------------------------------------------------------------*/
3589 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3591 static int Lblnum = 0;
3593 symbol *ifTrue, *ifFalse, *ifEnd;
3595 /* if neither exists */
3596 if (!elseBody && !ifBody) {
3597 // if there are no side effects (i++, j() etc)
3598 if (!hasSEFcalls(condAst)) {
3603 /* create the labels */
3604 sprintf (buffer, "_iffalse_%d", Lblnum);
3605 ifFalse = newSymbol (buffer, NestLevel);
3606 /* if no else body then end == false */
3611 sprintf (buffer, "_ifend_%d", Lblnum);
3612 ifEnd = newSymbol (buffer, NestLevel);
3615 sprintf (buffer, "_iftrue_%d", Lblnum);
3616 ifTrue = newSymbol (buffer, NestLevel);
3620 /* attach the ifTrue label to the top of it body */
3621 ifBody = createLabel (ifTrue, ifBody);
3622 /* attach a goto end to the ifBody if else is present */
3625 ifBody = newNode (NULLOP, ifBody,
3627 newAst_VALUE (symbolVal (ifEnd)),
3629 /* put the elseLabel on the else body */
3630 elseBody = createLabel (ifFalse, elseBody);
3631 /* out the end at the end of the body */
3632 elseBody = newNode (NULLOP,
3634 createLabel (ifEnd, NULL));
3638 ifBody = newNode (NULLOP, ifBody,
3639 createLabel (ifFalse, NULL));
3641 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3642 if (IS_IFX (condAst))
3645 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3647 return newNode (NULLOP, ifTree,
3648 newNode (NULLOP, ifBody, elseBody));
3652 /*-----------------------------------------------------------------*/
3653 /* createDo - creates parse tree for do */
3656 /* _docontinue_n: */
3657 /* condition_expression +-> trueLabel -> _dobody_n */
3659 /* +-> falseLabel-> _dobreak_n */
3661 /*-----------------------------------------------------------------*/
3663 createDo (symbol * trueLabel, symbol * continueLabel,
3664 symbol * falseLabel, ast * condAst, ast * doBody)
3669 /* if the body does not exist then it is simple */
3672 condAst = backPatchLabels (condAst, continueLabel, NULL);
3673 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3674 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3675 doTree->trueLabel = continueLabel;
3676 doTree->falseLabel = NULL;
3680 /* otherwise we have a body */
3681 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3683 /* attach the body label to the top */
3684 doBody = createLabel (trueLabel, doBody);
3685 /* attach the continue label to end of body */
3686 doBody = newNode (NULLOP, doBody,
3687 createLabel (continueLabel, NULL));
3689 /* now put the break label at the end */
3690 if (IS_IFX (condAst))
3693 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3695 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3697 /* putting it together */
3698 return newNode (NULLOP, doBody, doTree);
3701 /*-----------------------------------------------------------------*/
3702 /* createFor - creates parse tree for 'for' statement */
3705 /* condExpr +-> trueLabel -> _forbody_n */
3707 /* +-> falseLabel-> _forbreak_n */
3710 /* _forcontinue_n: */
3712 /* goto _forcond_n ; */
3714 /*-----------------------------------------------------------------*/
3716 createFor (symbol * trueLabel, symbol * continueLabel,
3717 symbol * falseLabel, symbol * condLabel,
3718 ast * initExpr, ast * condExpr, ast * loopExpr,
3723 /* if loopexpression not present then we can generate it */
3724 /* the same way as a while */
3726 return newNode (NULLOP, initExpr,
3727 createWhile (trueLabel, continueLabel,
3728 falseLabel, condExpr, forBody));
3729 /* vanilla for statement */
3730 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3732 if (condExpr && !IS_IFX (condExpr))
3733 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3736 /* attach condition label to condition */
3737 condExpr = createLabel (condLabel, condExpr);
3739 /* attach body label to body */
3740 forBody = createLabel (trueLabel, forBody);
3742 /* attach continue to forLoop expression & attach */
3743 /* goto the forcond @ and of loopExpression */
3744 loopExpr = createLabel (continueLabel,
3748 newAst_VALUE (symbolVal (condLabel)),
3750 /* now start putting them together */
3751 forTree = newNode (NULLOP, initExpr, condExpr);
3752 forTree = newNode (NULLOP, forTree, forBody);
3753 forTree = newNode (NULLOP, forTree, loopExpr);
3754 /* finally add the break label */
3755 forTree = newNode (NULLOP, forTree,
3756 createLabel (falseLabel, NULL));
3760 /*-----------------------------------------------------------------*/
3761 /* createWhile - creates parse tree for while statement */
3762 /* the while statement will be created as follows */
3764 /* _while_continue_n: */
3765 /* condition_expression +-> trueLabel -> _while_boby_n */
3767 /* +-> falseLabel -> _while_break_n */
3768 /* _while_body_n: */
3770 /* goto _while_continue_n */
3771 /* _while_break_n: */
3772 /*-----------------------------------------------------------------*/
3774 createWhile (symbol * trueLabel, symbol * continueLabel,
3775 symbol * falseLabel, ast * condExpr, ast * whileBody)
3779 /* put the continue label */
3780 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3781 condExpr = createLabel (continueLabel, condExpr);
3782 condExpr->lineno = 0;
3784 /* put the body label in front of the body */
3785 whileBody = createLabel (trueLabel, whileBody);
3786 whileBody->lineno = 0;
3787 /* put a jump to continue at the end of the body */
3788 /* and put break label at the end of the body */
3789 whileBody = newNode (NULLOP,
3792 newAst_VALUE (symbolVal (continueLabel)),
3793 createLabel (falseLabel, NULL)));
3795 /* put it all together */
3796 if (IS_IFX (condExpr))
3797 whileTree = condExpr;
3800 whileTree = newNode (IFX, condExpr, NULL);
3801 /* put the true & false labels in place */
3802 whileTree->trueLabel = trueLabel;
3803 whileTree->falseLabel = falseLabel;
3806 return newNode (NULLOP, whileTree, whileBody);
3809 /*-----------------------------------------------------------------*/
3810 /* optimizeGetHbit - get highest order bit of the expression */
3811 /*-----------------------------------------------------------------*/
3813 optimizeGetHbit (ast * tree)
3816 /* if this is not a bit and */
3817 if (!IS_BITAND (tree))
3820 /* will look for tree of the form
3821 ( expr >> ((sizeof expr) -1) ) & 1 */
3822 if (!IS_AST_LIT_VALUE (tree->right))
3825 if (AST_LIT_VALUE (tree->right) != 1)
3828 if (!IS_RIGHT_OP (tree->left))
3831 if (!IS_AST_LIT_VALUE (tree->left->right))
3834 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3835 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3838 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3842 /*-----------------------------------------------------------------*/
3843 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3844 /*-----------------------------------------------------------------*/
3846 optimizeRRCRLC (ast * root)
3848 /* will look for trees of the form
3849 (?expr << 1) | (?expr >> 7) or
3850 (?expr >> 7) | (?expr << 1) will make that
3851 into a RLC : operation ..
3853 (?expr >> 1) | (?expr << 7) or
3854 (?expr << 7) | (?expr >> 1) will make that
3855 into a RRC operation
3856 note : by 7 I mean (number of bits required to hold the
3858 /* if the root operations is not a | operation the not */
3859 if (!IS_BITOR (root))
3862 /* I have to think of a better way to match patterns this sucks */
3863 /* that aside let start looking for the first case : I use a the
3864 negative check a lot to improve the efficiency */
3865 /* (?expr << 1) | (?expr >> 7) */
3866 if (IS_LEFT_OP (root->left) &&
3867 IS_RIGHT_OP (root->right))
3870 if (!SPEC_USIGN (TETYPE (root->left->left)))
3873 if (!IS_AST_LIT_VALUE (root->left->right) ||
3874 !IS_AST_LIT_VALUE (root->right->right))
3877 /* make sure it is the same expression */
3878 if (!isAstEqual (root->left->left,
3882 if (AST_LIT_VALUE (root->left->right) != 1)
3885 if (AST_LIT_VALUE (root->right->right) !=
3886 (getSize (TTYPE (root->left->left)) * 8 - 1))
3889 /* whew got the first case : create the AST */
3890 return newNode (RLC, root->left->left, NULL);
3894 /* check for second case */
3895 /* (?expr >> 7) | (?expr << 1) */
3896 if (IS_LEFT_OP (root->right) &&
3897 IS_RIGHT_OP (root->left))
3900 if (!SPEC_USIGN (TETYPE (root->left->left)))
3903 if (!IS_AST_LIT_VALUE (root->left->right) ||
3904 !IS_AST_LIT_VALUE (root->right->right))
3907 /* make sure it is the same symbol */
3908 if (!isAstEqual (root->left->left,
3912 if (AST_LIT_VALUE (root->right->right) != 1)
3915 if (AST_LIT_VALUE (root->left->right) !=
3916 (getSize (TTYPE (root->left->left)) * 8 - 1))
3919 /* whew got the first case : create the AST */
3920 return newNode (RLC, root->left->left, NULL);
3925 /* third case for RRC */
3926 /* (?symbol >> 1) | (?symbol << 7) */
3927 if (IS_LEFT_OP (root->right) &&
3928 IS_RIGHT_OP (root->left))
3931 if (!SPEC_USIGN (TETYPE (root->left->left)))
3934 if (!IS_AST_LIT_VALUE (root->left->right) ||
3935 !IS_AST_LIT_VALUE (root->right->right))
3938 /* make sure it is the same symbol */
3939 if (!isAstEqual (root->left->left,
3943 if (AST_LIT_VALUE (root->left->right) != 1)
3946 if (AST_LIT_VALUE (root->right->right) !=
3947 (getSize (TTYPE (root->left->left)) * 8 - 1))
3950 /* whew got the first case : create the AST */
3951 return newNode (RRC, root->left->left, NULL);
3955 /* fourth and last case for now */
3956 /* (?symbol << 7) | (?symbol >> 1) */
3957 if (IS_RIGHT_OP (root->right) &&
3958 IS_LEFT_OP (root->left))
3961 if (!SPEC_USIGN (TETYPE (root->left->left)))
3964 if (!IS_AST_LIT_VALUE (root->left->right) ||
3965 !IS_AST_LIT_VALUE (root->right->right))
3968 /* make sure it is the same symbol */
3969 if (!isAstEqual (root->left->left,
3973 if (AST_LIT_VALUE (root->right->right) != 1)
3976 if (AST_LIT_VALUE (root->left->right) !=
3977 (getSize (TTYPE (root->left->left)) * 8 - 1))
3980 /* whew got the first case : create the AST */
3981 return newNode (RRC, root->left->left, NULL);
3985 /* not found return root */
3989 /*-----------------------------------------------------------------*/
3990 /* optimizeCompare - otimizes compares for bit variables */
3991 /*-----------------------------------------------------------------*/
3993 optimizeCompare (ast * root)
3995 ast *optExpr = NULL;
3998 unsigned int litValue;
4000 /* if nothing then return nothing */
4004 /* if not a compare op then do leaves */
4005 if (!IS_COMPARE_OP (root))
4007 root->left = optimizeCompare (root->left);
4008 root->right = optimizeCompare (root->right);
4012 /* if left & right are the same then depending
4013 of the operation do */
4014 if (isAstEqual (root->left, root->right))
4016 switch (root->opval.op)
4021 optExpr = newAst_VALUE (constVal ("0"));
4026 optExpr = newAst_VALUE (constVal ("1"));
4030 return decorateType (optExpr);
4033 vleft = (root->left->type == EX_VALUE ?
4034 root->left->opval.val : NULL);
4036 vright = (root->right->type == EX_VALUE ?
4037 root->right->opval.val : NULL);
4039 /* if left is a BITVAR in BITSPACE */
4040 /* and right is a LITERAL then opt- */
4041 /* imize else do nothing */
4042 if (vleft && vright &&
4043 IS_BITVAR (vleft->etype) &&
4044 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4045 IS_LITERAL (vright->etype))
4048 /* if right side > 1 then comparison may never succeed */
4049 if ((litValue = (int) floatFromVal (vright)) > 1)
4051 werror (W_BAD_COMPARE);
4057 switch (root->opval.op)
4059 case '>': /* bit value greater than 1 cannot be */
4060 werror (W_BAD_COMPARE);
4064 case '<': /* bit value < 1 means 0 */
4066 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4069 case LE_OP: /* bit value <= 1 means no check */
4070 optExpr = newAst_VALUE (vright);
4073 case GE_OP: /* bit value >= 1 means only check for = */
4075 optExpr = newAst_VALUE (vleft);
4080 { /* literal is zero */
4081 switch (root->opval.op)
4083 case '<': /* bit value < 0 cannot be */
4084 werror (W_BAD_COMPARE);
4088 case '>': /* bit value > 0 means 1 */
4090 optExpr = newAst_VALUE (vleft);
4093 case LE_OP: /* bit value <= 0 means no check */
4094 case GE_OP: /* bit value >= 0 means no check */
4095 werror (W_BAD_COMPARE);
4099 case EQ_OP: /* bit == 0 means ! of bit */
4100 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4104 return decorateType (resolveSymbols (optExpr));
4105 } /* end-of-if of BITVAR */
4110 /*-----------------------------------------------------------------*/
4111 /* addSymToBlock : adds the symbol to the first block we find */
4112 /*-----------------------------------------------------------------*/
4114 addSymToBlock (symbol * sym, ast * tree)
4116 /* reached end of tree or a leaf */
4117 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4121 if (IS_AST_OP (tree) &&
4122 tree->opval.op == BLOCK)
4125 symbol *lsym = copySymbol (sym);
4127 lsym->next = AST_VALUES (tree, sym);
4128 AST_VALUES (tree, sym) = lsym;
4132 addSymToBlock (sym, tree->left);
4133 addSymToBlock (sym, tree->right);
4136 /*-----------------------------------------------------------------*/
4137 /* processRegParms - do processing for register parameters */
4138 /*-----------------------------------------------------------------*/
4140 processRegParms (value * args, ast * body)
4144 if (IS_REGPARM (args->etype))
4145 addSymToBlock (args->sym, body);
4150 /*-----------------------------------------------------------------*/
4151 /* resetParmKey - resets the operandkeys for the symbols */
4152 /*-----------------------------------------------------------------*/
4153 DEFSETFUNC (resetParmKey)
4164 /*-----------------------------------------------------------------*/
4165 /* createFunction - This is the key node that calls the iCode for */
4166 /* generating the code for a function. Note code */
4167 /* is generated function by function, later when */
4168 /* add inter-procedural analysis this will change */
4169 /*-----------------------------------------------------------------*/
4171 createFunction (symbol * name, ast * body)
4177 iCode *piCode = NULL;
4179 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4180 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4182 /* if check function return 0 then some problem */
4183 if (checkFunction (name, NULL) == 0)
4186 /* create a dummy block if none exists */
4188 body = newNode (BLOCK, NULL, NULL);
4192 /* check if the function name already in the symbol table */
4193 if ((csym = findSym (SymbolTab, NULL, name->name)))
4196 /* special case for compiler defined functions
4197 we need to add the name to the publics list : this
4198 actually means we are now compiling the compiler
4202 addSet (&publics, name);
4208 allocVariables (name);
4210 name->lastLine = yylineno;
4213 /* set the stack pointer */
4214 /* PENDING: check this for the mcs51 */
4215 stackPtr = -port->stack.direction * port->stack.call_overhead;
4216 if (IFFUNC_ISISR (name->type))
4217 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4218 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4219 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4221 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4223 fetype = getSpec (name->type); /* get the specifier for the function */
4224 /* if this is a reentrant function then */
4225 if (IFFUNC_ISREENT (name->type))
4228 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4230 /* do processing for parameters that are passed in registers */
4231 processRegParms (FUNC_ARGS(name->type), body);
4233 /* set the stack pointer */
4237 /* allocate & autoinit the block variables */
4238 processBlockVars (body, &stack, ALLOCATE);
4240 /* save the stack information */
4241 if (options.useXstack)
4242 name->xstack = SPEC_STAK (fetype) = stack;
4244 name->stack = SPEC_STAK (fetype) = stack;
4246 /* name needs to be mangled */
4247 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4249 body = resolveSymbols (body); /* resolve the symbols */
4250 body = decorateType (body); /* propagateType & do semantic checks */
4252 ex = newAst_VALUE (symbolVal (name)); /* create name */
4253 ex = newNode (FUNCTION, ex, body);
4254 ex->values.args = FUNC_ARGS(name->type);
4256 if (options.dump_tree) PA(ex);
4259 werror (E_FUNC_NO_CODE, name->name);
4263 /* create the node & generate intermediate code */
4265 codeOutFile = code->oFile;
4266 piCode = iCodeFromAst (ex);
4270 werror (E_FUNC_NO_CODE, name->name);
4274 eBBlockFromiCode (piCode);
4276 /* if there are any statics then do them */
4279 GcurMemmap = statsg;
4280 codeOutFile = statsg->oFile;
4281 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4287 /* dealloc the block variables */
4288 processBlockVars (body, &stack, DEALLOCATE);
4289 /* deallocate paramaters */
4290 deallocParms (FUNC_ARGS(name->type));
4292 if (IFFUNC_ISREENT (name->type))
4295 /* we are done freeup memory & cleanup */
4297 if (port->reset_labelKey) labelKey = 1;
4299 FUNC_HASBODY(name->type) = 1;
4300 addSet (&operKeyReset, name);
4301 applyToSet (operKeyReset, resetParmKey);
4304 cdbStructBlock (1, cdbFile);
4306 cleanUpLevel (LabelTab, 0);
4307 cleanUpBlock (StructTab, 1);
4308 cleanUpBlock (TypedefTab, 1);
4310 xstack->syms = NULL;
4311 istack->syms = NULL;
4316 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4317 /*-----------------------------------------------------------------*/
4318 /* ast_print : prints the ast (for debugging purposes) */
4319 /*-----------------------------------------------------------------*/
4321 void ast_print (ast * tree, FILE *outfile, int indent)
4326 /* can print only decorated trees */
4327 if (!tree->decorated) return;
4329 /* if any child is an error | this one is an error do nothing */
4330 if (tree->isError ||
4331 (tree->left && tree->left->isError) ||
4332 (tree->right && tree->right->isError)) {
4333 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4337 /* print the line */
4338 /* if not block & function */
4339 if (tree->type == EX_OP &&
4340 (tree->opval.op != FUNCTION &&
4341 tree->opval.op != BLOCK &&
4342 tree->opval.op != NULLOP)) {
4345 if (tree->opval.op == FUNCTION) {
4347 value *args=FUNC_ARGS(tree->left->opval.val->type);
4348 fprintf(outfile,"FUNCTION (%s=%p) type (",
4349 tree->left->opval.val->name, tree);
4350 printTypeChain (tree->ftype,outfile);
4351 fprintf(outfile,") args (");
4354 fprintf (outfile, ", ");
4356 printTypeChain (args ? args->type : NULL, outfile);
4358 args= args ? args->next : NULL;
4360 fprintf(outfile,")\n");
4361 ast_print(tree->left,outfile,indent);
4362 ast_print(tree->right,outfile,indent);
4365 if (tree->opval.op == BLOCK) {
4366 symbol *decls = tree->values.sym;
4367 INDENT(indent,outfile);
4368 fprintf(outfile,"{\n");
4370 INDENT(indent+2,outfile);
4371 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4372 decls->name, decls);
4373 printTypeChain(decls->type,outfile);
4374 fprintf(outfile,")\n");
4376 decls = decls->next;
4378 ast_print(tree->right,outfile,indent+2);
4379 INDENT(indent,outfile);
4380 fprintf(outfile,"}\n");
4383 if (tree->opval.op == NULLOP) {
4384 fprintf(outfile,"\n");
4385 ast_print(tree->left,outfile,indent);
4386 fprintf(outfile,"\n");
4387 ast_print(tree->right,outfile,indent);
4390 INDENT(indent,outfile);
4392 /*------------------------------------------------------------------*/
4393 /*----------------------------*/
4394 /* leaf has been reached */
4395 /*----------------------------*/
4396 /* if this is of type value */
4397 /* just get the type */
4398 if (tree->type == EX_VALUE) {
4400 if (IS_LITERAL (tree->opval.val->etype)) {
4401 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4402 (int) floatFromVal(tree->opval.val),
4403 (int) floatFromVal(tree->opval.val),
4404 floatFromVal(tree->opval.val));
4405 } else if (tree->opval.val->sym) {
4406 /* if the undefined flag is set then give error message */
4407 if (tree->opval.val->sym->undefined) {
4408 fprintf(outfile,"UNDEFINED SYMBOL ");
4410 fprintf(outfile,"SYMBOL ");
4412 fprintf(outfile,"(%s=%p)",
4413 tree->opval.val->sym->name,tree);
4416 fprintf(outfile," type (");
4417 printTypeChain(tree->ftype,outfile);
4418 fprintf(outfile,")\n");
4420 fprintf(outfile,"\n");
4425 /* if type link for the case of cast */
4426 if (tree->type == EX_LINK) {
4427 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4428 printTypeChain(tree->opval.lnk,outfile);
4429 fprintf(outfile,")\n");
4434 /* depending on type of operator do */
4436 switch (tree->opval.op) {
4437 /*------------------------------------------------------------------*/
4438 /*----------------------------*/
4440 /*----------------------------*/
4442 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4443 printTypeChain(tree->ftype,outfile);
4444 fprintf(outfile,")\n");
4445 ast_print(tree->left,outfile,indent+2);
4446 ast_print(tree->right,outfile,indent+2);
4449 /*------------------------------------------------------------------*/
4450 /*----------------------------*/
4452 /*----------------------------*/
4454 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4455 printTypeChain(tree->ftype,outfile);
4456 fprintf(outfile,")\n");
4457 ast_print(tree->left,outfile,indent+2);
4458 ast_print(tree->right,outfile,indent+2);
4461 /*------------------------------------------------------------------*/
4462 /*----------------------------*/
4463 /* struct/union pointer */
4464 /*----------------------------*/
4466 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4467 printTypeChain(tree->ftype,outfile);
4468 fprintf(outfile,")\n");
4469 ast_print(tree->left,outfile,indent+2);
4470 ast_print(tree->right,outfile,indent+2);
4473 /*------------------------------------------------------------------*/
4474 /*----------------------------*/
4475 /* ++/-- operation */
4476 /*----------------------------*/
4477 case INC_OP: /* incerement operator unary so left only */
4478 fprintf(outfile,"INC_OP (%p) type (",tree);
4479 printTypeChain(tree->ftype,outfile);
4480 fprintf(outfile,")\n");
4481 ast_print(tree->left,outfile,indent+2);
4485 fprintf(outfile,"DEC_OP (%p) type (",tree);
4486 printTypeChain(tree->ftype,outfile);
4487 fprintf(outfile,")\n");
4488 ast_print(tree->left,outfile,indent+2);
4491 /*------------------------------------------------------------------*/
4492 /*----------------------------*/
4494 /*----------------------------*/
4497 fprintf(outfile,"& (%p) type (",tree);
4498 printTypeChain(tree->ftype,outfile);
4499 fprintf(outfile,")\n");
4500 ast_print(tree->left,outfile,indent+2);
4501 ast_print(tree->right,outfile,indent+2);
4503 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4504 printTypeChain(tree->ftype,outfile);
4505 fprintf(outfile,")\n");
4506 ast_print(tree->left,outfile,indent+2);
4507 ast_print(tree->right,outfile,indent+2);
4510 /*----------------------------*/
4512 /*----------------------------*/
4514 fprintf(outfile,"OR (%p) type (",tree);
4515 printTypeChain(tree->ftype,outfile);
4516 fprintf(outfile,")\n");
4517 ast_print(tree->left,outfile,indent+2);
4518 ast_print(tree->right,outfile,indent+2);
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4523 /*----------------------------*/
4525 fprintf(outfile,"XOR (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+2);
4529 ast_print(tree->right,outfile,indent+2);
4532 /*------------------------------------------------------------------*/
4533 /*----------------------------*/
4535 /*----------------------------*/
4537 fprintf(outfile,"DIV (%p) type (",tree);
4538 printTypeChain(tree->ftype,outfile);
4539 fprintf(outfile,")\n");
4540 ast_print(tree->left,outfile,indent+2);
4541 ast_print(tree->right,outfile,indent+2);
4543 /*------------------------------------------------------------------*/
4544 /*----------------------------*/
4546 /*----------------------------*/
4548 fprintf(outfile,"MOD (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+2);
4552 ast_print(tree->right,outfile,indent+2);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4557 /* address dereference */
4558 /*----------------------------*/
4559 case '*': /* can be unary : if right is null then unary operation */
4561 fprintf(outfile,"DEREF (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+2);
4567 /*------------------------------------------------------------------*/
4568 /*----------------------------*/
4569 /* multiplication */
4570 /*----------------------------*/
4571 fprintf(outfile,"MULT (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+2);
4575 ast_print(tree->right,outfile,indent+2);
4579 /*------------------------------------------------------------------*/
4580 /*----------------------------*/
4581 /* unary '+' operator */
4582 /*----------------------------*/
4586 fprintf(outfile,"UPLUS (%p) type (",tree);
4587 printTypeChain(tree->ftype,outfile);
4588 fprintf(outfile,")\n");
4589 ast_print(tree->left,outfile,indent+2);
4591 /*------------------------------------------------------------------*/
4592 /*----------------------------*/
4594 /*----------------------------*/
4595 fprintf(outfile,"ADD (%p) type (",tree);
4596 printTypeChain(tree->ftype,outfile);
4597 fprintf(outfile,")\n");
4598 ast_print(tree->left,outfile,indent+2);
4599 ast_print(tree->right,outfile,indent+2);
4602 /*------------------------------------------------------------------*/
4603 /*----------------------------*/
4605 /*----------------------------*/
4606 case '-': /* can be unary */
4608 fprintf(outfile,"UMINUS (%p) type (",tree);
4609 printTypeChain(tree->ftype,outfile);
4610 fprintf(outfile,")\n");
4611 ast_print(tree->left,outfile,indent+2);
4613 /*------------------------------------------------------------------*/
4614 /*----------------------------*/
4616 /*----------------------------*/
4617 fprintf(outfile,"SUB (%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);
4624 /*------------------------------------------------------------------*/
4625 /*----------------------------*/
4627 /*----------------------------*/
4629 fprintf(outfile,"COMPL (%p) type (",tree);
4630 printTypeChain(tree->ftype,outfile);
4631 fprintf(outfile,")\n");
4632 ast_print(tree->left,outfile,indent+2);
4634 /*------------------------------------------------------------------*/
4635 /*----------------------------*/
4637 /*----------------------------*/
4639 fprintf(outfile,"NOT (%p) type (",tree);
4640 printTypeChain(tree->ftype,outfile);
4641 fprintf(outfile,")\n");
4642 ast_print(tree->left,outfile,indent+2);
4644 /*------------------------------------------------------------------*/
4645 /*----------------------------*/
4647 /*----------------------------*/
4649 fprintf(outfile,"RRC (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->left,outfile,indent+2);
4656 fprintf(outfile,"RLC (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->left,outfile,indent+2);
4662 fprintf(outfile,"GETHBIT (%p) type (",tree);
4663 printTypeChain(tree->ftype,outfile);
4664 fprintf(outfile,")\n");
4665 ast_print(tree->left,outfile,indent+2);
4668 fprintf(outfile,"LEFT_SHIFT (%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 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+2);
4679 ast_print(tree->right,outfile,indent+2);
4681 /*------------------------------------------------------------------*/
4682 /*----------------------------*/
4684 /*----------------------------*/
4685 case CAST: /* change the type */
4686 fprintf(outfile,"CAST (%p) from type (",tree);
4687 printTypeChain(tree->right->ftype,outfile);
4688 fprintf(outfile,") to type (");
4689 printTypeChain(tree->ftype,outfile);
4690 fprintf(outfile,")\n");
4691 ast_print(tree->right,outfile,indent+2);
4695 fprintf(outfile,"ANDAND (%p) type (",tree);
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->left,outfile,indent+2);
4699 ast_print(tree->right,outfile,indent+2);
4702 fprintf(outfile,"OROR (%p) type (",tree);
4703 printTypeChain(tree->ftype,outfile);
4704 fprintf(outfile,")\n");
4705 ast_print(tree->left,outfile,indent+2);
4706 ast_print(tree->right,outfile,indent+2);
4709 /*------------------------------------------------------------------*/
4710 /*----------------------------*/
4711 /* comparison operators */
4712 /*----------------------------*/
4714 fprintf(outfile,"GT(>) (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+2);
4718 ast_print(tree->right,outfile,indent+2);
4721 fprintf(outfile,"LT(<) (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+2);
4725 ast_print(tree->right,outfile,indent+2);
4728 fprintf(outfile,"LE(<=) (%p) type (",tree);
4729 printTypeChain(tree->ftype,outfile);
4730 fprintf(outfile,")\n");
4731 ast_print(tree->left,outfile,indent+2);
4732 ast_print(tree->right,outfile,indent+2);
4735 fprintf(outfile,"GE(>=) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+2);
4739 ast_print(tree->right,outfile,indent+2);
4742 fprintf(outfile,"EQ(==) (%p) type (",tree);
4743 printTypeChain(tree->ftype,outfile);
4744 fprintf(outfile,")\n");
4745 ast_print(tree->left,outfile,indent+2);
4746 ast_print(tree->right,outfile,indent+2);
4749 fprintf(outfile,"NE(!=) (%p) type (",tree);
4750 printTypeChain(tree->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->left,outfile,indent+2);
4753 ast_print(tree->right,outfile,indent+2);
4754 /*------------------------------------------------------------------*/
4755 /*----------------------------*/
4757 /*----------------------------*/
4758 case SIZEOF: /* evaluate wihout code generation */
4759 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4762 /*------------------------------------------------------------------*/
4763 /*----------------------------*/
4764 /* conditional operator '?' */
4765 /*----------------------------*/
4767 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4768 printTypeChain(tree->ftype,outfile);
4769 fprintf(outfile,")\n");
4770 ast_print(tree->left,outfile,indent+2);
4771 ast_print(tree->right,outfile,indent+2);
4775 fprintf(outfile,"COLON(:) (%p) type (",tree);
4776 printTypeChain(tree->ftype,outfile);
4777 fprintf(outfile,")\n");
4778 ast_print(tree->left,outfile,indent+2);
4779 ast_print(tree->right,outfile,indent+2);
4782 /*------------------------------------------------------------------*/
4783 /*----------------------------*/
4784 /* assignment operators */
4785 /*----------------------------*/
4787 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4788 printTypeChain(tree->ftype,outfile);
4789 fprintf(outfile,")\n");
4790 ast_print(tree->left,outfile,indent+2);
4791 ast_print(tree->right,outfile,indent+2);
4794 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->left,outfile,indent+2);
4798 ast_print(tree->right,outfile,indent+2);
4801 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4802 printTypeChain(tree->ftype,outfile);
4803 fprintf(outfile,")\n");
4804 ast_print(tree->left,outfile,indent+2);
4805 ast_print(tree->right,outfile,indent+2);
4808 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4809 printTypeChain(tree->ftype,outfile);
4810 fprintf(outfile,")\n");
4811 ast_print(tree->left,outfile,indent+2);
4812 ast_print(tree->right,outfile,indent+2);
4815 fprintf(outfile,"XORASS(*=) (%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,"RSHFTASS(>>=) (%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 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4830 printTypeChain(tree->ftype,outfile);
4831 fprintf(outfile,")\n");
4832 ast_print(tree->left,outfile,indent+2);
4833 ast_print(tree->right,outfile,indent+2);
4835 /*------------------------------------------------------------------*/
4836 /*----------------------------*/
4838 /*----------------------------*/
4840 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4841 printTypeChain(tree->ftype,outfile);
4842 fprintf(outfile,")\n");
4843 ast_print(tree->left,outfile,indent+2);
4844 ast_print(tree->right,outfile,indent+2);
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4849 /*----------------------------*/
4851 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4852 printTypeChain(tree->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 ast_print(tree->right,outfile,indent+2);
4857 /*------------------------------------------------------------------*/
4858 /*----------------------------*/
4859 /* straight assignemnt */
4860 /*----------------------------*/
4862 fprintf(outfile,"ASSIGN(=) (%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);
4868 /*------------------------------------------------------------------*/
4869 /*----------------------------*/
4870 /* comma operator */
4871 /*----------------------------*/
4873 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4874 printTypeChain(tree->ftype,outfile);
4875 fprintf(outfile,")\n");
4876 ast_print(tree->left,outfile,indent+2);
4877 ast_print(tree->right,outfile,indent+2);
4879 /*------------------------------------------------------------------*/
4880 /*----------------------------*/
4882 /*----------------------------*/
4885 fprintf(outfile,"CALL (%p) type (",tree);
4886 printTypeChain(tree->ftype,outfile);
4887 fprintf(outfile,")\n");
4888 ast_print(tree->left,outfile,indent+2);
4889 ast_print(tree->right,outfile,indent+2);
4892 fprintf(outfile,"PARMS\n");
4893 ast_print(tree->left,outfile,indent+2);
4894 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4895 ast_print(tree->right,outfile,indent+2);
4898 /*------------------------------------------------------------------*/
4899 /*----------------------------*/
4900 /* return statement */
4901 /*----------------------------*/
4903 fprintf(outfile,"RETURN (%p) type (",tree);
4905 printTypeChain(tree->right->ftype,outfile);
4907 fprintf(outfile,")\n");
4908 ast_print(tree->right,outfile,indent+2);
4910 /*------------------------------------------------------------------*/
4911 /*----------------------------*/
4912 /* label statement */
4913 /*----------------------------*/
4915 fprintf(outfile,"LABEL (%p)\n",tree);
4916 ast_print(tree->left,outfile,indent+2);
4917 ast_print(tree->right,outfile,indent);
4919 /*------------------------------------------------------------------*/
4920 /*----------------------------*/
4921 /* switch statement */
4922 /*----------------------------*/
4926 fprintf(outfile,"SWITCH (%p) ",tree);
4927 ast_print(tree->left,outfile,0);
4928 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4929 INDENT(indent+2,outfile);
4930 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4931 (int) floatFromVal(val),
4932 tree->values.switchVals.swNum,
4933 (int) floatFromVal(val));
4935 ast_print(tree->right,outfile,indent);
4938 /*------------------------------------------------------------------*/
4939 /*----------------------------*/
4941 /*----------------------------*/
4943 fprintf(outfile,"IF (%p) \n",tree);
4944 ast_print(tree->left,outfile,indent+2);
4945 if (tree->trueLabel) {
4946 INDENT(indent,outfile);
4947 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4949 if (tree->falseLabel) {
4950 INDENT(indent,outfile);
4951 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4953 ast_print(tree->right,outfile,indent+2);
4955 /*------------------------------------------------------------------*/
4956 /*----------------------------*/
4958 /*----------------------------*/
4960 fprintf(outfile,"FOR (%p) \n",tree);
4961 if (AST_FOR( tree, initExpr)) {
4962 INDENT(indent+2,outfile);
4963 fprintf(outfile,"INIT EXPR ");
4964 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4966 if (AST_FOR( tree, condExpr)) {
4967 INDENT(indent+2,outfile);
4968 fprintf(outfile,"COND EXPR ");
4969 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4971 if (AST_FOR( tree, loopExpr)) {
4972 INDENT(indent+2,outfile);
4973 fprintf(outfile,"LOOP EXPR ");
4974 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4976 fprintf(outfile,"FOR LOOP BODY \n");
4977 ast_print(tree->left,outfile,indent+2);
4986 ast_print(t,stdout,0);