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))));
954 // now we don't need iexpr's symbol anymore
956 symbol *sym=AST_SYMBOL(iexpr);
957 memmap *segment=SPEC_OCLS(sym->etype);
958 deleteSetItem(&segment->syms, sym);
960 return decorateType (resolveSymbols (rast));
966 /*-----------------------------------------------------------------*/
967 /* createIvalPtr - generates initial value for pointers */
968 /*-----------------------------------------------------------------*/
970 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
976 if (ilist->type == INIT_DEEP)
977 ilist = ilist->init.deep;
979 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
981 /* if character pointer */
982 if (IS_CHAR (type->next))
983 if ((rast = createIvalCharPtr (sym, type, iexpr)))
986 return newNode ('=', sym, iexpr);
989 /*-----------------------------------------------------------------*/
990 /* createIval - generates code for initial value */
991 /*-----------------------------------------------------------------*/
993 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1000 /* if structure then */
1001 if (IS_STRUCT (type))
1002 rast = createIvalStruct (sym, type, ilist);
1004 /* if this is a pointer */
1006 rast = createIvalPtr (sym, type, ilist);
1008 /* if this is an array */
1009 if (IS_ARRAY (type))
1010 rast = createIvalArray (sym, type, ilist);
1012 /* if type is SPECIFIER */
1014 rast = createIvalType (sym, type, ilist);
1017 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1019 return decorateType (resolveSymbols (rast));
1022 /*-----------------------------------------------------------------*/
1023 /* initAggregates - initialises aggregate variables with initv */
1024 /*-----------------------------------------------------------------*/
1025 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1026 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1029 /*-----------------------------------------------------------------*/
1030 /* gatherAutoInit - creates assignment expressions for initial */
1032 /*-----------------------------------------------------------------*/
1034 gatherAutoInit (symbol * autoChain)
1041 for (sym = autoChain; sym; sym = sym->next)
1044 /* resolve the symbols in the ival */
1046 resolveIvalSym (sym->ival);
1048 /* if this is a static variable & has an */
1049 /* initial value the code needs to be lifted */
1050 /* here to the main portion since they can be */
1051 /* initialised only once at the start */
1052 if (IS_STATIC (sym->etype) && sym->ival &&
1053 SPEC_SCLS (sym->etype) != S_CODE)
1057 /* insert the symbol into the symbol table */
1058 /* with level = 0 & name = rname */
1059 newSym = copySymbol (sym);
1060 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1062 /* now lift the code to main */
1063 if (IS_AGGREGATE (sym->type)) {
1064 work = initAggregates (sym, sym->ival, NULL);
1066 if (getNelements(sym->type, sym->ival)>1) {
1067 werror (W_EXCESS_INITIALIZERS, "scalar",
1068 sym->name, sym->lineDef);
1070 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1071 list2expr (sym->ival));
1074 setAstLineno (work, sym->lineDef);
1078 staticAutos = newNode (NULLOP, staticAutos, work);
1085 /* if there is an initial value */
1086 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1088 if (IS_AGGREGATE (sym->type)) {
1089 work = initAggregates (sym, sym->ival, NULL);
1091 if (getNelements(sym->type, sym->ival)>1) {
1092 werror (W_EXCESS_INITIALIZERS, "scalar",
1093 sym->name, sym->lineDef);
1095 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1096 list2expr (sym->ival));
1099 setAstLineno (work, sym->lineDef);
1102 init = newNode (NULLOP, init, work);
1111 /*-----------------------------------------------------------------*/
1112 /* stringToSymbol - creates a symbol from a literal string */
1113 /*-----------------------------------------------------------------*/
1115 stringToSymbol (value * val)
1117 char name[SDCC_NAME_MAX + 1];
1118 static int charLbl = 0;
1121 sprintf (name, "_str_%d", charLbl++);
1122 sym = newSymbol (name, 0); /* make it @ level 0 */
1123 strcpy (sym->rname, name);
1125 /* copy the type from the value passed */
1126 sym->type = copyLinkChain (val->type);
1127 sym->etype = getSpec (sym->type);
1128 /* change to storage class & output class */
1129 SPEC_SCLS (sym->etype) = S_CODE;
1130 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1131 SPEC_STAT (sym->etype) = 1;
1132 /* make the level & block = 0 */
1133 sym->block = sym->level = 0;
1135 /* create an ival */
1136 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1141 allocVariables (sym);
1144 return symbolVal (sym);
1148 /*-----------------------------------------------------------------*/
1149 /* processBlockVars - will go thru the ast looking for block if */
1150 /* a block is found then will allocate the syms */
1151 /* will also gather the auto inits present */
1152 /*-----------------------------------------------------------------*/
1154 processBlockVars (ast * tree, int *stack, int action)
1159 /* if this is a block */
1160 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1164 if (action == ALLOCATE)
1166 *stack += allocVariables (tree->values.sym);
1167 autoInit = gatherAutoInit (tree->values.sym);
1169 /* if there are auto inits then do them */
1171 tree->left = newNode (NULLOP, autoInit, tree->left);
1173 else /* action is deallocate */
1174 deallocLocal (tree->values.sym);
1177 processBlockVars (tree->left, stack, action);
1178 processBlockVars (tree->right, stack, action);
1182 /*-------------------------------------------------------------*/
1183 /* constExprTree - returns TRUE if this tree is a constant */
1185 /*-------------------------------------------------------------*/
1186 bool constExprTree (ast *cexpr) {
1192 cexpr = decorateType (resolveSymbols (cexpr));
1194 switch (cexpr->type)
1197 if (IS_AST_LIT_VALUE(cexpr)) {
1198 // this is a literal
1201 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1202 // a function's address will never change
1205 if (IS_AST_SYM_VALUE(cexpr) &&
1206 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1207 // a symbol in code space will never change
1208 // This is only for the 'char *s="hallo"' case and will have to leave
1213 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1214 "unexpected link in expression tree\n");
1217 if (cexpr->opval.op==ARRAYINIT) {
1218 // this is a list of literals
1221 if (cexpr->opval.op=='=') {
1222 return constExprTree(cexpr->right);
1224 if (cexpr->opval.op==CAST) {
1225 // jwk: cast ignored, maybe we should throw a warning here
1226 return constExprTree(cexpr->right);
1228 if (cexpr->opval.op=='&') {
1231 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1234 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1241 /*-----------------------------------------------------------------*/
1242 /* constExprValue - returns the value of a constant expression */
1243 /* or NULL if it is not a constant expression */
1244 /*-----------------------------------------------------------------*/
1246 constExprValue (ast * cexpr, int check)
1248 cexpr = decorateType (resolveSymbols (cexpr));
1250 /* if this is not a constant then */
1251 if (!IS_LITERAL (cexpr->ftype))
1253 /* then check if this is a literal array
1255 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1256 SPEC_CVAL (cexpr->etype).v_char &&
1257 IS_ARRAY (cexpr->ftype))
1259 value *val = valFromType (cexpr->ftype);
1260 SPEC_SCLS (val->etype) = S_LITERAL;
1261 val->sym = cexpr->opval.val->sym;
1262 val->sym->type = copyLinkChain (cexpr->ftype);
1263 val->sym->etype = getSpec (val->sym->type);
1264 strcpy (val->name, cexpr->opval.val->sym->rname);
1268 /* if we are casting a literal value then */
1269 if (IS_AST_OP (cexpr) &&
1270 cexpr->opval.op == CAST &&
1271 IS_LITERAL (cexpr->right->ftype))
1272 return valCastLiteral (cexpr->ftype,
1273 floatFromVal (cexpr->right->opval.val));
1275 if (IS_AST_VALUE (cexpr))
1276 return cexpr->opval.val;
1279 werror (E_CONST_EXPECTED, "found expression");
1284 /* return the value */
1285 return cexpr->opval.val;
1289 /*-----------------------------------------------------------------*/
1290 /* isLabelInAst - will return true if a given label is found */
1291 /*-----------------------------------------------------------------*/
1293 isLabelInAst (symbol * label, ast * tree)
1295 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1298 if (IS_AST_OP (tree) &&
1299 tree->opval.op == LABEL &&
1300 isSymbolEqual (AST_SYMBOL (tree->left), label))
1303 return isLabelInAst (label, tree->right) &&
1304 isLabelInAst (label, tree->left);
1308 /*-----------------------------------------------------------------*/
1309 /* isLoopCountable - return true if the loop count can be determi- */
1310 /* -ned at compile time . */
1311 /*-----------------------------------------------------------------*/
1313 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1314 symbol ** sym, ast ** init, ast ** end)
1317 /* the loop is considered countable if the following
1318 conditions are true :-
1320 a) initExpr :- <sym> = <const>
1321 b) condExpr :- <sym> < <const1>
1322 c) loopExpr :- <sym> ++
1325 /* first check the initExpr */
1326 if (IS_AST_OP (initExpr) &&
1327 initExpr->opval.op == '=' && /* is assignment */
1328 IS_AST_SYM_VALUE (initExpr->left))
1329 { /* left is a symbol */
1331 *sym = AST_SYMBOL (initExpr->left);
1332 *init = initExpr->right;
1337 /* for now the symbol has to be of
1339 if (!IS_INTEGRAL ((*sym)->type))
1342 /* now check condExpr */
1343 if (IS_AST_OP (condExpr))
1346 switch (condExpr->opval.op)
1349 if (IS_AST_SYM_VALUE (condExpr->left) &&
1350 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1351 IS_AST_LIT_VALUE (condExpr->right))
1353 *end = condExpr->right;
1359 if (IS_AST_OP (condExpr->left) &&
1360 condExpr->left->opval.op == '>' &&
1361 IS_AST_LIT_VALUE (condExpr->left->right) &&
1362 IS_AST_SYM_VALUE (condExpr->left->left) &&
1363 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1366 *end = newNode ('+', condExpr->left->right,
1367 newAst_VALUE (constVal ("1")));
1378 /* check loop expression is of the form <sym>++ */
1379 if (!IS_AST_OP (loopExpr))
1382 /* check if <sym> ++ */
1383 if (loopExpr->opval.op == INC_OP)
1389 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1390 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1397 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1398 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1406 if (loopExpr->opval.op == ADD_ASSIGN)
1409 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1410 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1411 IS_AST_LIT_VALUE (loopExpr->right) &&
1412 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1420 /*-----------------------------------------------------------------*/
1421 /* astHasVolatile - returns true if ast contains any volatile */
1422 /*-----------------------------------------------------------------*/
1424 astHasVolatile (ast * tree)
1429 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1432 if (IS_AST_OP (tree))
1433 return astHasVolatile (tree->left) ||
1434 astHasVolatile (tree->right);
1439 /*-----------------------------------------------------------------*/
1440 /* astHasPointer - return true if the ast contains any ptr variable */
1441 /*-----------------------------------------------------------------*/
1443 astHasPointer (ast * tree)
1448 if (IS_AST_LINK (tree))
1451 /* if we hit an array expression then check
1452 only the left side */
1453 if (IS_AST_OP (tree) && tree->opval.op == '[')
1454 return astHasPointer (tree->left);
1456 if (IS_AST_VALUE (tree))
1457 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1459 return astHasPointer (tree->left) ||
1460 astHasPointer (tree->right);
1464 /*-----------------------------------------------------------------*/
1465 /* astHasSymbol - return true if the ast has the given symbol */
1466 /*-----------------------------------------------------------------*/
1468 astHasSymbol (ast * tree, symbol * sym)
1470 if (!tree || IS_AST_LINK (tree))
1473 if (IS_AST_VALUE (tree))
1475 if (IS_AST_SYM_VALUE (tree))
1476 return isSymbolEqual (AST_SYMBOL (tree), sym);
1481 return astHasSymbol (tree->left, sym) ||
1482 astHasSymbol (tree->right, sym);
1485 /*-----------------------------------------------------------------*/
1486 /* astHasDeref - return true if the ast has an indirect access */
1487 /*-----------------------------------------------------------------*/
1489 astHasDeref (ast * tree)
1491 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1494 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1496 return astHasDeref (tree->left) || astHasDeref (tree->right);
1499 /*-----------------------------------------------------------------*/
1500 /* isConformingBody - the loop body has to conform to a set of rules */
1501 /* for the loop to be considered reversible read on for rules */
1502 /*-----------------------------------------------------------------*/
1504 isConformingBody (ast * pbody, symbol * sym, ast * body)
1507 /* we are going to do a pre-order traversal of the
1508 tree && check for the following conditions. (essentially
1509 a set of very shallow tests )
1510 a) the sym passed does not participate in
1511 any arithmetic operation
1512 b) There are no function calls
1513 c) all jumps are within the body
1514 d) address of loop control variable not taken
1515 e) if an assignment has a pointer on the
1516 left hand side make sure right does not have
1517 loop control variable */
1519 /* if we reach the end or a leaf then true */
1520 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1524 /* if anything else is "volatile" */
1525 if (IS_VOLATILE (TETYPE (pbody)))
1528 /* we will walk the body in a pre-order traversal for
1530 switch (pbody->opval.op)
1532 /*------------------------------------------------------------------*/
1534 return isConformingBody (pbody->right, sym, body);
1536 /*------------------------------------------------------------------*/
1541 /*------------------------------------------------------------------*/
1542 case INC_OP: /* incerement operator unary so left only */
1545 /* sure we are not sym is not modified */
1547 IS_AST_SYM_VALUE (pbody->left) &&
1548 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1552 IS_AST_SYM_VALUE (pbody->right) &&
1553 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1558 /*------------------------------------------------------------------*/
1560 case '*': /* can be unary : if right is null then unary operation */
1565 /* if right is NULL then unary operation */
1566 /*------------------------------------------------------------------*/
1567 /*----------------------------*/
1569 /*----------------------------*/
1572 if (IS_AST_SYM_VALUE (pbody->left) &&
1573 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1576 return isConformingBody (pbody->left, sym, body);
1580 if (astHasSymbol (pbody->left, sym) ||
1581 astHasSymbol (pbody->right, sym))
1586 /*------------------------------------------------------------------*/
1594 if (IS_AST_SYM_VALUE (pbody->left) &&
1595 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1598 if (IS_AST_SYM_VALUE (pbody->right) &&
1599 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1602 return isConformingBody (pbody->left, sym, body) &&
1603 isConformingBody (pbody->right, sym, body);
1610 if (IS_AST_SYM_VALUE (pbody->left) &&
1611 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1613 return isConformingBody (pbody->left, sym, body);
1615 /*------------------------------------------------------------------*/
1627 case SIZEOF: /* evaluate wihout code generation */
1629 return isConformingBody (pbody->left, sym, body) &&
1630 isConformingBody (pbody->right, sym, body);
1632 /*------------------------------------------------------------------*/
1635 /* if left has a pointer & right has loop
1636 control variable then we cannot */
1637 if (astHasPointer (pbody->left) &&
1638 astHasSymbol (pbody->right, sym))
1640 if (astHasVolatile (pbody->left))
1643 if (IS_AST_SYM_VALUE (pbody->left)) {
1644 // if the loopvar has an assignment
1645 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1647 // if the loopvar is used in another (maybe conditional) block
1648 if (astHasSymbol (pbody->right, sym) &&
1649 (pbody->level > body->level)) {
1654 if (astHasVolatile (pbody->left))
1657 if (astHasDeref(pbody->right)) return FALSE;
1659 return isConformingBody (pbody->left, sym, body) &&
1660 isConformingBody (pbody->right, sym, body);
1671 assert ("Parser should not have generated this\n");
1673 /*------------------------------------------------------------------*/
1674 /*----------------------------*/
1675 /* comma operator */
1676 /*----------------------------*/
1678 return isConformingBody (pbody->left, sym, body) &&
1679 isConformingBody (pbody->right, sym, body);
1681 /*------------------------------------------------------------------*/
1682 /*----------------------------*/
1684 /*----------------------------*/
1686 /* if local & not passed as paramater then ok */
1687 if (sym->level && !astHasSymbol(pbody->right,sym))
1691 /*------------------------------------------------------------------*/
1692 /*----------------------------*/
1693 /* return statement */
1694 /*----------------------------*/
1699 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1704 if (astHasSymbol (pbody->left, sym))
1711 return isConformingBody (pbody->left, sym, body) &&
1712 isConformingBody (pbody->right, sym, body);
1718 /*-----------------------------------------------------------------*/
1719 /* isLoopReversible - takes a for loop as input && returns true */
1720 /* if the for loop is reversible. If yes will set the value of */
1721 /* the loop control var & init value & termination value */
1722 /*-----------------------------------------------------------------*/
1724 isLoopReversible (ast * loop, symbol ** loopCntrl,
1725 ast ** init, ast ** end)
1727 /* if option says don't do it then don't */
1728 if (optimize.noLoopReverse)
1730 /* there are several tests to determine this */
1732 /* for loop has to be of the form
1733 for ( <sym> = <const1> ;
1734 [<sym> < <const2>] ;
1735 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1737 if (!isLoopCountable (AST_FOR (loop, initExpr),
1738 AST_FOR (loop, condExpr),
1739 AST_FOR (loop, loopExpr),
1740 loopCntrl, init, end))
1743 /* now do some serious checking on the body of the loop
1746 return isConformingBody (loop->left, *loopCntrl, loop->left);
1750 /*-----------------------------------------------------------------*/
1751 /* replLoopSym - replace the loop sym by loop sym -1 */
1752 /*-----------------------------------------------------------------*/
1754 replLoopSym (ast * body, symbol * sym)
1757 if (!body || IS_AST_LINK (body))
1760 if (IS_AST_SYM_VALUE (body))
1763 if (isSymbolEqual (AST_SYMBOL (body), sym))
1767 body->opval.op = '-';
1768 body->left = newAst_VALUE (symbolVal (sym));
1769 body->right = newAst_VALUE (constVal ("1"));
1777 replLoopSym (body->left, sym);
1778 replLoopSym (body->right, sym);
1782 /*-----------------------------------------------------------------*/
1783 /* reverseLoop - do the actual loop reversal */
1784 /*-----------------------------------------------------------------*/
1786 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1790 /* create the following tree
1795 if (sym) goto for_continue ;
1798 /* put it together piece by piece */
1799 rloop = newNode (NULLOP,
1800 createIf (newAst_VALUE (symbolVal (sym)),
1802 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1805 newAst_VALUE (symbolVal (sym)),
1808 replLoopSym (loop->left, sym);
1810 rloop = newNode (NULLOP,
1812 newAst_VALUE (symbolVal (sym)),
1813 newNode ('-', end, init)),
1814 createLabel (AST_FOR (loop, continueLabel),
1818 newNode (SUB_ASSIGN,
1819 newAst_VALUE (symbolVal (sym)),
1820 newAst_VALUE (constVal ("1"))),
1823 return decorateType (rloop);
1827 /*-----------------------------------------------------------------*/
1828 /* decorateType - compute type for this tree also does type cheking */
1829 /* this is done bottom up, since type have to flow upwards */
1830 /* it also does constant folding, and paramater checking */
1831 /*-----------------------------------------------------------------*/
1833 decorateType (ast * tree)
1841 /* if already has type then do nothing */
1842 if (tree->decorated)
1845 tree->decorated = 1;
1847 /* print the line */
1848 /* if not block & function */
1849 if (tree->type == EX_OP &&
1850 (tree->opval.op != FUNCTION &&
1851 tree->opval.op != BLOCK &&
1852 tree->opval.op != NULLOP))
1854 filename = tree->filename;
1855 lineno = tree->lineno;
1858 /* if any child is an error | this one is an error do nothing */
1859 if (tree->isError ||
1860 (tree->left && tree->left->isError) ||
1861 (tree->right && tree->right->isError))
1864 /*------------------------------------------------------------------*/
1865 /*----------------------------*/
1866 /* leaf has been reached */
1867 /*----------------------------*/
1868 /* if this is of type value */
1869 /* just get the type */
1870 if (tree->type == EX_VALUE)
1873 if (IS_LITERAL (tree->opval.val->etype))
1876 /* if this is a character array then declare it */
1877 if (IS_ARRAY (tree->opval.val->type))
1878 tree->opval.val = stringToSymbol (tree->opval.val);
1880 /* otherwise just copy the type information */
1881 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1885 if (tree->opval.val->sym)
1887 /* if the undefined flag is set then give error message */
1888 if (tree->opval.val->sym->undefined)
1890 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1892 TTYPE (tree) = TETYPE (tree) =
1893 tree->opval.val->type = tree->opval.val->sym->type =
1894 tree->opval.val->etype = tree->opval.val->sym->etype =
1895 copyLinkChain (INTTYPE);
1900 /* if impilicit i.e. struct/union member then no type */
1901 if (tree->opval.val->sym->implicit)
1902 TTYPE (tree) = TETYPE (tree) = NULL;
1907 /* else copy the type */
1908 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1910 /* and mark it as referenced */
1911 tree->opval.val->sym->isref = 1;
1919 /* if type link for the case of cast */
1920 if (tree->type == EX_LINK)
1922 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1929 dtl = decorateType (tree->left);
1930 /* delay right side for '?' operator since conditional macro expansions might
1932 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1934 /* this is to take care of situations
1935 when the tree gets rewritten */
1936 if (dtl != tree->left)
1938 if (dtr != tree->right)
1942 /* depending on type of operator do */
1944 switch (tree->opval.op)
1946 /*------------------------------------------------------------------*/
1947 /*----------------------------*/
1949 /*----------------------------*/
1952 /* determine which is the array & which the index */
1953 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1956 ast *tempTree = tree->left;
1957 tree->left = tree->right;
1958 tree->right = tempTree;
1961 /* first check if this is a array or a pointer */
1962 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1964 werror (E_NEED_ARRAY_PTR, "[]");
1965 goto errorTreeReturn;
1968 /* check if the type of the idx */
1969 if (!IS_INTEGRAL (RTYPE (tree)))
1971 werror (E_IDX_NOT_INT);
1972 goto errorTreeReturn;
1975 /* if the left is an rvalue then error */
1978 werror (E_LVALUE_REQUIRED, "array access");
1979 goto errorTreeReturn;
1982 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1983 if (IS_PTR(LTYPE(tree))) {
1984 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1988 /*------------------------------------------------------------------*/
1989 /*----------------------------*/
1991 /*----------------------------*/
1993 /* if this is not a structure */
1994 if (!IS_STRUCT (LTYPE (tree)))
1996 werror (E_STRUCT_UNION, ".");
1997 goto errorTreeReturn;
1999 TTYPE (tree) = structElemType (LTYPE (tree),
2000 (tree->right->type == EX_VALUE ?
2001 tree->right->opval.val : NULL));
2002 TETYPE (tree) = getSpec (TTYPE (tree));
2005 /*------------------------------------------------------------------*/
2006 /*----------------------------*/
2007 /* struct/union pointer */
2008 /*----------------------------*/
2010 /* if not pointer to a structure */
2011 if (!IS_PTR (LTYPE (tree)))
2013 werror (E_PTR_REQD);
2014 goto errorTreeReturn;
2017 if (!IS_STRUCT (LTYPE (tree)->next))
2019 werror (E_STRUCT_UNION, "->");
2020 goto errorTreeReturn;
2023 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2024 (tree->right->type == EX_VALUE ?
2025 tree->right->opval.val : NULL));
2026 TETYPE (tree) = getSpec (TTYPE (tree));
2028 /* adjust the storage class */
2029 switch (DCL_TYPE(tree->left->ftype)) {
2033 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2036 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2041 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2044 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2047 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2056 /*------------------------------------------------------------------*/
2057 /*----------------------------*/
2058 /* ++/-- operation */
2059 /*----------------------------*/
2060 case INC_OP: /* incerement operator unary so left only */
2063 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2064 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2065 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2066 werror (E_CODE_WRITE, "++/--");
2075 /*------------------------------------------------------------------*/
2076 /*----------------------------*/
2078 /*----------------------------*/
2079 case '&': /* can be unary */
2080 /* if right is NULL then unary operation */
2081 if (tree->right) /* not an unary operation */
2084 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2086 werror (E_BITWISE_OP);
2087 werror (W_CONTINUE, "left & right types are ");
2088 printTypeChain (LTYPE (tree), stderr);
2089 fprintf (stderr, ",");
2090 printTypeChain (RTYPE (tree), stderr);
2091 fprintf (stderr, "\n");
2092 goto errorTreeReturn;
2095 /* if they are both literal */
2096 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2098 tree->type = EX_VALUE;
2099 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2100 valFromType (RETYPE (tree)), '&');
2102 tree->right = tree->left = NULL;
2103 TETYPE (tree) = tree->opval.val->etype;
2104 TTYPE (tree) = tree->opval.val->type;
2108 /* see if this is a GETHBIT operation if yes
2111 ast *otree = optimizeGetHbit (tree);
2114 return decorateType (otree);
2118 computeType (LTYPE (tree), RTYPE (tree));
2119 TETYPE (tree) = getSpec (TTYPE (tree));
2121 LRVAL (tree) = RRVAL (tree) = 1;
2125 /*------------------------------------------------------------------*/
2126 /*----------------------------*/
2128 /*----------------------------*/
2130 p->class = DECLARATOR;
2131 /* if bit field then error */
2132 if (IS_BITVAR (tree->left->etype))
2134 werror (E_ILLEGAL_ADDR, "address of bit variable");
2135 goto errorTreeReturn;
2138 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2140 werror (E_ILLEGAL_ADDR, "address of register variable");
2141 goto errorTreeReturn;
2144 if (IS_FUNC (LTYPE (tree)))
2146 werror (E_ILLEGAL_ADDR, "address of function");
2147 goto errorTreeReturn;
2150 if (IS_LITERAL(LTYPE(tree)))
2152 werror (E_ILLEGAL_ADDR, "address of literal");
2153 goto errorTreeReturn;
2158 werror (E_LVALUE_REQUIRED, "address of");
2159 goto errorTreeReturn;
2161 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2163 DCL_TYPE (p) = CPOINTER;
2164 DCL_PTR_CONST (p) = port->mem.code_ro;
2166 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2167 DCL_TYPE (p) = FPOINTER;
2168 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2169 DCL_TYPE (p) = PPOINTER;
2170 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2171 DCL_TYPE (p) = IPOINTER;
2172 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2173 DCL_TYPE (p) = EEPPOINTER;
2174 else if (SPEC_OCLS(tree->left->etype))
2175 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2177 DCL_TYPE (p) = POINTER;
2179 if (IS_AST_SYM_VALUE (tree->left))
2181 AST_SYMBOL (tree->left)->addrtaken = 1;
2182 AST_SYMBOL (tree->left)->allocreq = 1;
2185 p->next = LTYPE (tree);
2187 TETYPE (tree) = getSpec (TTYPE (tree));
2188 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2189 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2194 /*------------------------------------------------------------------*/
2195 /*----------------------------*/
2197 /*----------------------------*/
2199 /* if the rewrite succeeds then don't go any furthur */
2201 ast *wtree = optimizeRRCRLC (tree);
2203 return decorateType (wtree);
2205 /*------------------------------------------------------------------*/
2206 /*----------------------------*/
2208 /*----------------------------*/
2210 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2212 werror (E_BITWISE_OP);
2213 werror (W_CONTINUE, "left & right types are ");
2214 printTypeChain (LTYPE (tree), stderr);
2215 fprintf (stderr, ",");
2216 printTypeChain (RTYPE (tree), stderr);
2217 fprintf (stderr, "\n");
2218 goto errorTreeReturn;
2221 /* if they are both literal then */
2222 /* rewrite the tree */
2223 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2225 tree->type = EX_VALUE;
2226 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2227 valFromType (RETYPE (tree)),
2229 tree->right = tree->left = NULL;
2230 TETYPE (tree) = tree->opval.val->etype;
2231 TTYPE (tree) = tree->opval.val->type;
2234 LRVAL (tree) = RRVAL (tree) = 1;
2235 TETYPE (tree) = getSpec (TTYPE (tree) =
2236 computeType (LTYPE (tree),
2239 /*------------------------------------------------------------------*/
2240 /*----------------------------*/
2242 /*----------------------------*/
2244 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2246 werror (E_INVALID_OP, "divide");
2247 goto errorTreeReturn;
2249 /* if they are both literal then */
2250 /* rewrite the tree */
2251 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2253 tree->type = EX_VALUE;
2254 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2255 valFromType (RETYPE (tree)));
2256 tree->right = tree->left = NULL;
2257 TETYPE (tree) = getSpec (TTYPE (tree) =
2258 tree->opval.val->type);
2261 LRVAL (tree) = RRVAL (tree) = 1;
2262 TETYPE (tree) = getSpec (TTYPE (tree) =
2263 computeType (LTYPE (tree),
2267 /*------------------------------------------------------------------*/
2268 /*----------------------------*/
2270 /*----------------------------*/
2272 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2274 werror (E_BITWISE_OP);
2275 werror (W_CONTINUE, "left & right types are ");
2276 printTypeChain (LTYPE (tree), stderr);
2277 fprintf (stderr, ",");
2278 printTypeChain (RTYPE (tree), stderr);
2279 fprintf (stderr, "\n");
2280 goto errorTreeReturn;
2282 /* if they are both literal then */
2283 /* rewrite the tree */
2284 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2286 tree->type = EX_VALUE;
2287 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2288 valFromType (RETYPE (tree)));
2289 tree->right = tree->left = NULL;
2290 TETYPE (tree) = getSpec (TTYPE (tree) =
2291 tree->opval.val->type);
2294 LRVAL (tree) = RRVAL (tree) = 1;
2295 TETYPE (tree) = getSpec (TTYPE (tree) =
2296 computeType (LTYPE (tree),
2300 /*------------------------------------------------------------------*/
2301 /*----------------------------*/
2302 /* address dereference */
2303 /*----------------------------*/
2304 case '*': /* can be unary : if right is null then unary operation */
2307 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2309 werror (E_PTR_REQD);
2310 goto errorTreeReturn;
2315 werror (E_LVALUE_REQUIRED, "pointer deref");
2316 goto errorTreeReturn;
2318 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2319 LTYPE (tree)->next : NULL);
2320 TETYPE (tree) = getSpec (TTYPE (tree));
2321 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2325 /*------------------------------------------------------------------*/
2326 /*----------------------------*/
2327 /* multiplication */
2328 /*----------------------------*/
2329 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2331 werror (E_INVALID_OP, "multiplication");
2332 goto errorTreeReturn;
2335 /* if they are both literal then */
2336 /* rewrite the tree */
2337 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2339 tree->type = EX_VALUE;
2340 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2341 valFromType (RETYPE (tree)));
2342 tree->right = tree->left = NULL;
2343 TETYPE (tree) = getSpec (TTYPE (tree) =
2344 tree->opval.val->type);
2348 /* if left is a literal exchange left & right */
2349 if (IS_LITERAL (LTYPE (tree)))
2351 ast *tTree = tree->left;
2352 tree->left = tree->right;
2353 tree->right = tTree;
2356 LRVAL (tree) = RRVAL (tree) = 1;
2357 /* promote result to int if left & right are char
2358 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2359 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2360 TETYPE (tree) = getSpec (TTYPE (tree) =
2361 computeType (LTYPE (tree),
2363 SPEC_NOUN(TETYPE(tree)) = V_INT;
2365 TETYPE (tree) = getSpec (TTYPE (tree) =
2366 computeType (LTYPE (tree),
2371 /*------------------------------------------------------------------*/
2372 /*----------------------------*/
2373 /* unary '+' operator */
2374 /*----------------------------*/
2379 if (!IS_INTEGRAL (LTYPE (tree)))
2381 werror (E_UNARY_OP, '+');
2382 goto errorTreeReturn;
2385 /* if left is a literal then do it */
2386 if (IS_LITERAL (LTYPE (tree)))
2388 tree->type = EX_VALUE;
2389 tree->opval.val = valFromType (LETYPE (tree));
2391 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2395 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2399 /*------------------------------------------------------------------*/
2400 /*----------------------------*/
2402 /*----------------------------*/
2404 /* this is not a unary operation */
2405 /* if both pointers then problem */
2406 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2407 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2409 werror (E_PTR_PLUS_PTR);
2410 goto errorTreeReturn;
2413 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2414 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2416 werror (E_PLUS_INVALID, "+");
2417 goto errorTreeReturn;
2420 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2421 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2423 werror (E_PLUS_INVALID, "+");
2424 goto errorTreeReturn;
2426 /* if they are both literal then */
2427 /* rewrite the tree */
2428 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2430 tree->type = EX_VALUE;
2431 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2432 valFromType (RETYPE (tree)));
2433 tree->right = tree->left = NULL;
2434 TETYPE (tree) = getSpec (TTYPE (tree) =
2435 tree->opval.val->type);
2439 /* if the right is a pointer or left is a literal
2440 xchange left & right */
2441 if (IS_ARRAY (RTYPE (tree)) ||
2442 IS_PTR (RTYPE (tree)) ||
2443 IS_LITERAL (LTYPE (tree)))
2445 ast *tTree = tree->left;
2446 tree->left = tree->right;
2447 tree->right = tTree;
2450 LRVAL (tree) = RRVAL (tree) = 1;
2451 /* if the left is a pointer */
2452 if (IS_PTR (LTYPE (tree)))
2453 TETYPE (tree) = getSpec (TTYPE (tree) =
2456 TETYPE (tree) = getSpec (TTYPE (tree) =
2457 computeType (LTYPE (tree),
2461 /*------------------------------------------------------------------*/
2462 /*----------------------------*/
2464 /*----------------------------*/
2465 case '-': /* can be unary */
2466 /* if right is null then unary */
2470 if (!IS_ARITHMETIC (LTYPE (tree)))
2472 werror (E_UNARY_OP, tree->opval.op);
2473 goto errorTreeReturn;
2476 /* if left is a literal then do it */
2477 if (IS_LITERAL (LTYPE (tree)))
2479 tree->type = EX_VALUE;
2480 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2482 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2483 SPEC_USIGN(TETYPE(tree)) = 0;
2487 TTYPE (tree) = LTYPE (tree);
2491 /*------------------------------------------------------------------*/
2492 /*----------------------------*/
2494 /*----------------------------*/
2496 if (!(IS_PTR (LTYPE (tree)) ||
2497 IS_ARRAY (LTYPE (tree)) ||
2498 IS_ARITHMETIC (LTYPE (tree))))
2500 werror (E_PLUS_INVALID, "-");
2501 goto errorTreeReturn;
2504 if (!(IS_PTR (RTYPE (tree)) ||
2505 IS_ARRAY (RTYPE (tree)) ||
2506 IS_ARITHMETIC (RTYPE (tree))))
2508 werror (E_PLUS_INVALID, "-");
2509 goto errorTreeReturn;
2512 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2513 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2514 IS_INTEGRAL (RTYPE (tree))))
2516 werror (E_PLUS_INVALID, "-");
2517 goto errorTreeReturn;
2520 /* if they are both literal then */
2521 /* rewrite the tree */
2522 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2524 tree->type = EX_VALUE;
2525 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2526 valFromType (RETYPE (tree)));
2527 tree->right = tree->left = NULL;
2528 TETYPE (tree) = getSpec (TTYPE (tree) =
2529 tree->opval.val->type);
2533 /* if the left & right are equal then zero */
2534 if (isAstEqual (tree->left, tree->right))
2536 tree->type = EX_VALUE;
2537 tree->left = tree->right = NULL;
2538 tree->opval.val = constVal ("0");
2539 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2543 /* if both of them are pointers or arrays then */
2544 /* the result is going to be an integer */
2545 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2546 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2547 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2549 /* if only the left is a pointer */
2550 /* then result is a pointer */
2551 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2552 TETYPE (tree) = getSpec (TTYPE (tree) =
2555 TETYPE (tree) = getSpec (TTYPE (tree) =
2556 computeType (LTYPE (tree),
2558 LRVAL (tree) = RRVAL (tree) = 1;
2561 /*------------------------------------------------------------------*/
2562 /*----------------------------*/
2564 /*----------------------------*/
2566 /* can be only integral type */
2567 if (!IS_INTEGRAL (LTYPE (tree)))
2569 werror (E_UNARY_OP, tree->opval.op);
2570 goto errorTreeReturn;
2573 /* if left is a literal then do it */
2574 if (IS_LITERAL (LTYPE (tree)))
2576 tree->type = EX_VALUE;
2577 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2579 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2583 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2586 /*------------------------------------------------------------------*/
2587 /*----------------------------*/
2589 /*----------------------------*/
2591 /* can be pointer */
2592 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2593 !IS_PTR (LTYPE (tree)) &&
2594 !IS_ARRAY (LTYPE (tree)))
2596 werror (E_UNARY_OP, tree->opval.op);
2597 goto errorTreeReturn;
2600 /* if left is a literal then do it */
2601 if (IS_LITERAL (LTYPE (tree)))
2603 tree->type = EX_VALUE;
2604 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2606 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2610 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2613 /*------------------------------------------------------------------*/
2614 /*----------------------------*/
2616 /*----------------------------*/
2619 TTYPE (tree) = LTYPE (tree);
2620 TETYPE (tree) = LETYPE (tree);
2624 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2629 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2631 werror (E_SHIFT_OP_INVALID);
2632 werror (W_CONTINUE, "left & right types are ");
2633 printTypeChain (LTYPE (tree), stderr);
2634 fprintf (stderr, ",");
2635 printTypeChain (RTYPE (tree), stderr);
2636 fprintf (stderr, "\n");
2637 goto errorTreeReturn;
2640 /* if they are both literal then */
2641 /* rewrite the tree */
2642 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2644 tree->type = EX_VALUE;
2645 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2646 valFromType (RETYPE (tree)),
2647 (tree->opval.op == LEFT_OP ? 1 : 0));
2648 tree->right = tree->left = NULL;
2649 TETYPE (tree) = getSpec (TTYPE (tree) =
2650 tree->opval.val->type);
2653 /* if only the right side is a literal & we are
2654 shifting more than size of the left operand then zero */
2655 if (IS_LITERAL (RTYPE (tree)) &&
2656 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2657 (getSize (LTYPE (tree)) * 8))
2659 werror (W_SHIFT_CHANGED,
2660 (tree->opval.op == LEFT_OP ? "left" : "right"));
2661 tree->type = EX_VALUE;
2662 tree->left = tree->right = NULL;
2663 tree->opval.val = constVal ("0");
2664 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2667 LRVAL (tree) = RRVAL (tree) = 1;
2668 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2670 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2674 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2678 /*------------------------------------------------------------------*/
2679 /*----------------------------*/
2681 /*----------------------------*/
2682 case CAST: /* change the type */
2683 /* cannot cast to an aggregate type */
2684 if (IS_AGGREGATE (LTYPE (tree)))
2686 werror (E_CAST_ILLEGAL);
2687 goto errorTreeReturn;
2690 /* make sure the type is complete and sane */
2691 checkTypeSanity(LETYPE(tree), "(cast)");
2694 /* if the right is a literal replace the tree */
2695 if (IS_LITERAL (RETYPE (tree))) {
2696 if (!IS_PTR (LTYPE (tree))) {
2697 tree->type = EX_VALUE;
2699 valCastLiteral (LTYPE (tree),
2700 floatFromVal (valFromType (RETYPE (tree))));
2703 TTYPE (tree) = tree->opval.val->type;
2704 tree->values.literalFromCast = 1;
2705 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2706 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2707 sym_link *rest = LTYPE(tree)->next;
2708 werror(W_LITERAL_GENERIC);
2709 TTYPE(tree) = newLink();
2710 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2711 TTYPE(tree)->next = rest;
2712 tree->left->opval.lnk = TTYPE(tree);
2715 TTYPE (tree) = LTYPE (tree);
2719 TTYPE (tree) = LTYPE (tree);
2723 /* if pointer to struct then check names */
2724 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2725 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2726 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2727 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2729 /* if the right is a literal replace the tree */
2730 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2731 tree->type = EX_VALUE;
2733 valCastLiteral (LTYPE (tree),
2734 floatFromVal (valFromType (RETYPE (tree))));
2737 TTYPE (tree) = tree->opval.val->type;
2738 tree->values.literalFromCast = 1;
2740 TTYPE (tree) = LTYPE (tree);
2744 TETYPE (tree) = getSpec (TTYPE (tree));
2748 /*------------------------------------------------------------------*/
2749 /*----------------------------*/
2750 /* logical &&, || */
2751 /*----------------------------*/
2754 /* each must me arithmetic type or be a pointer */
2755 if (!IS_PTR (LTYPE (tree)) &&
2756 !IS_ARRAY (LTYPE (tree)) &&
2757 !IS_INTEGRAL (LTYPE (tree)))
2759 werror (E_COMPARE_OP);
2760 goto errorTreeReturn;
2763 if (!IS_PTR (RTYPE (tree)) &&
2764 !IS_ARRAY (RTYPE (tree)) &&
2765 !IS_INTEGRAL (RTYPE (tree)))
2767 werror (E_COMPARE_OP);
2768 goto errorTreeReturn;
2770 /* if they are both literal then */
2771 /* rewrite the tree */
2772 if (IS_LITERAL (RTYPE (tree)) &&
2773 IS_LITERAL (LTYPE (tree)))
2775 tree->type = EX_VALUE;
2776 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2777 valFromType (RETYPE (tree)),
2779 tree->right = tree->left = NULL;
2780 TETYPE (tree) = getSpec (TTYPE (tree) =
2781 tree->opval.val->type);
2784 LRVAL (tree) = RRVAL (tree) = 1;
2785 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2788 /*------------------------------------------------------------------*/
2789 /*----------------------------*/
2790 /* comparison operators */
2791 /*----------------------------*/
2799 ast *lt = optimizeCompare (tree);
2805 /* if they are pointers they must be castable */
2806 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2808 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2810 werror (E_COMPARE_OP);
2811 fprintf (stderr, "comparing type ");
2812 printTypeChain (LTYPE (tree), stderr);
2813 fprintf (stderr, "to type ");
2814 printTypeChain (RTYPE (tree), stderr);
2815 fprintf (stderr, "\n");
2816 goto errorTreeReturn;
2819 /* else they should be promotable to one another */
2822 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2823 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2825 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2827 werror (E_COMPARE_OP);
2828 fprintf (stderr, "comparing type ");
2829 printTypeChain (LTYPE (tree), stderr);
2830 fprintf (stderr, "to type ");
2831 printTypeChain (RTYPE (tree), stderr);
2832 fprintf (stderr, "\n");
2833 goto errorTreeReturn;
2836 /* if unsigned value < 0 then always false */
2837 /* if (unsigned value) > 0 then (unsigned value) */
2838 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2839 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2841 if (tree->opval.op == '<') {
2844 if (tree->opval.op == '>') {
2848 /* if they are both literal then */
2849 /* rewrite the tree */
2850 if (IS_LITERAL (RTYPE (tree)) &&
2851 IS_LITERAL (LTYPE (tree)))
2853 tree->type = EX_VALUE;
2854 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2855 valFromType (RETYPE (tree)),
2857 tree->right = tree->left = NULL;
2858 TETYPE (tree) = getSpec (TTYPE (tree) =
2859 tree->opval.val->type);
2862 LRVAL (tree) = RRVAL (tree) = 1;
2863 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2866 /*------------------------------------------------------------------*/
2867 /*----------------------------*/
2869 /*----------------------------*/
2870 case SIZEOF: /* evaluate wihout code generation */
2871 /* change the type to a integer */
2872 tree->type = EX_VALUE;
2873 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2874 tree->opval.val = constVal (buffer);
2875 tree->right = tree->left = NULL;
2876 TETYPE (tree) = getSpec (TTYPE (tree) =
2877 tree->opval.val->type);
2880 /*------------------------------------------------------------------*/
2881 /*----------------------------*/
2883 /*----------------------------*/
2885 /* return typeof enum value */
2886 tree->type = EX_VALUE;
2889 if (IS_SPEC(tree->right->ftype)) {
2890 switch (SPEC_NOUN(tree->right->ftype)) {
2892 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2893 else typeofv = TYPEOF_INT;
2896 typeofv = TYPEOF_FLOAT;
2899 typeofv = TYPEOF_CHAR;
2902 typeofv = TYPEOF_VOID;
2905 typeofv = TYPEOF_STRUCT;
2908 typeofv = TYPEOF_BIT;
2911 typeofv = TYPEOF_SBIT;
2917 switch (DCL_TYPE(tree->right->ftype)) {
2919 typeofv = TYPEOF_POINTER;
2922 typeofv = TYPEOF_FPOINTER;
2925 typeofv = TYPEOF_CPOINTER;
2928 typeofv = TYPEOF_GPOINTER;
2931 typeofv = TYPEOF_PPOINTER;
2934 typeofv = TYPEOF_IPOINTER;
2937 typeofv = TYPEOF_ARRAY;
2940 typeofv = TYPEOF_FUNCTION;
2946 sprintf (buffer, "%d", typeofv);
2947 tree->opval.val = constVal (buffer);
2948 tree->right = tree->left = NULL;
2949 TETYPE (tree) = getSpec (TTYPE (tree) =
2950 tree->opval.val->type);
2953 /*------------------------------------------------------------------*/
2954 /*----------------------------*/
2955 /* conditional operator '?' */
2956 /*----------------------------*/
2958 /* the type is value of the colon operator (on the right) */
2959 assert(IS_COLON_OP(tree->right));
2960 /* if already known then replace the tree : optimizer will do it
2961 but faster to do it here */
2962 if (IS_LITERAL (LTYPE(tree))) {
2963 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2964 return decorateType(tree->right->left) ;
2966 return decorateType(tree->right->right) ;
2969 tree->right = decorateType(tree->right);
2970 TTYPE (tree) = RTYPE(tree);
2971 TETYPE (tree) = getSpec (TTYPE (tree));
2976 /* if they don't match we have a problem */
2977 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2979 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2980 goto errorTreeReturn;
2983 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2984 TETYPE (tree) = getSpec (TTYPE (tree));
2988 #if 0 // assignment operators are converted by the parser
2989 /*------------------------------------------------------------------*/
2990 /*----------------------------*/
2991 /* assignment operators */
2992 /*----------------------------*/
2995 /* for these it must be both must be integral */
2996 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2997 !IS_ARITHMETIC (RTYPE (tree)))
2999 werror (E_OPS_INTEGRAL);
3000 goto errorTreeReturn;
3003 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3005 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3006 werror (E_CODE_WRITE, " ");
3010 werror (E_LVALUE_REQUIRED, "*= or /=");
3011 goto errorTreeReturn;
3022 /* for these it must be both must be integral */
3023 if (!IS_INTEGRAL (LTYPE (tree)) ||
3024 !IS_INTEGRAL (RTYPE (tree)))
3026 werror (E_OPS_INTEGRAL);
3027 goto errorTreeReturn;
3030 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3032 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3033 werror (E_CODE_WRITE, " ");
3037 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3038 goto errorTreeReturn;
3044 /*------------------------------------------------------------------*/
3045 /*----------------------------*/
3047 /*----------------------------*/
3049 if (!(IS_PTR (LTYPE (tree)) ||
3050 IS_ARITHMETIC (LTYPE (tree))))
3052 werror (E_PLUS_INVALID, "-=");
3053 goto errorTreeReturn;
3056 if (!(IS_PTR (RTYPE (tree)) ||
3057 IS_ARITHMETIC (RTYPE (tree))))
3059 werror (E_PLUS_INVALID, "-=");
3060 goto errorTreeReturn;
3063 TETYPE (tree) = getSpec (TTYPE (tree) =
3064 computeType (LTYPE (tree),
3067 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3068 werror (E_CODE_WRITE, " ");
3072 werror (E_LVALUE_REQUIRED, "-=");
3073 goto errorTreeReturn;
3079 /*------------------------------------------------------------------*/
3080 /*----------------------------*/
3082 /*----------------------------*/
3084 /* this is not a unary operation */
3085 /* if both pointers then problem */
3086 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3088 werror (E_PTR_PLUS_PTR);
3089 goto errorTreeReturn;
3092 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3094 werror (E_PLUS_INVALID, "+=");
3095 goto errorTreeReturn;
3098 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3100 werror (E_PLUS_INVALID, "+=");
3101 goto errorTreeReturn;
3104 TETYPE (tree) = getSpec (TTYPE (tree) =
3105 computeType (LTYPE (tree),
3108 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3109 werror (E_CODE_WRITE, " ");
3113 werror (E_LVALUE_REQUIRED, "+=");
3114 goto errorTreeReturn;
3117 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3118 tree->opval.op = '=';
3123 /*------------------------------------------------------------------*/
3124 /*----------------------------*/
3125 /* straight assignemnt */
3126 /*----------------------------*/
3128 /* cannot be an aggregate */
3129 if (IS_AGGREGATE (LTYPE (tree)))
3131 werror (E_AGGR_ASSIGN);
3132 goto errorTreeReturn;
3135 /* they should either match or be castable */
3136 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3138 werror (E_TYPE_MISMATCH, "assignment", " ");
3139 printFromToType(RTYPE(tree),LTYPE(tree));
3140 //goto errorTreeReturn;
3143 /* if the left side of the tree is of type void
3144 then report error */
3145 if (IS_VOID (LTYPE (tree)))
3147 werror (E_CAST_ZERO);
3148 printFromToType(RTYPE(tree), LTYPE(tree));
3151 TETYPE (tree) = getSpec (TTYPE (tree) =
3155 if (!tree->initMode ) {
3156 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3157 werror (E_CODE_WRITE, " ");
3161 werror (E_LVALUE_REQUIRED, "=");
3162 goto errorTreeReturn;
3167 /*------------------------------------------------------------------*/
3168 /*----------------------------*/
3169 /* comma operator */
3170 /*----------------------------*/
3172 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3175 /*------------------------------------------------------------------*/
3176 /*----------------------------*/
3178 /*----------------------------*/
3182 if (processParms (tree->left,
3183 FUNC_ARGS(tree->left->ftype),
3184 tree->right, &parmNumber, TRUE)) {
3185 goto errorTreeReturn;
3188 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3189 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3191 //FUNC_ARGS(tree->left->ftype) =
3192 //reverseVal (FUNC_ARGS(tree->left->ftype));
3193 reverseParms (tree->right);
3196 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3199 /*------------------------------------------------------------------*/
3200 /*----------------------------*/
3201 /* return statement */
3202 /*----------------------------*/
3207 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3209 werror (W_RETURN_MISMATCH);
3210 printFromToType (RTYPE(tree), currFunc->type->next);
3211 goto errorTreeReturn;
3214 if (IS_VOID (currFunc->type->next)
3216 !IS_VOID (RTYPE (tree)))
3218 werror (E_FUNC_VOID);
3219 goto errorTreeReturn;
3222 /* if there is going to be a casing required then add it */
3223 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3226 decorateType (newNode (CAST,
3227 newAst_LINK (copyLinkChain (currFunc->type->next)),
3236 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3238 werror (E_VOID_FUNC, currFunc->name);
3239 goto errorTreeReturn;
3242 TTYPE (tree) = TETYPE (tree) = NULL;
3245 /*------------------------------------------------------------------*/
3246 /*----------------------------*/
3247 /* switch statement */
3248 /*----------------------------*/
3250 /* the switch value must be an integer */
3251 if (!IS_INTEGRAL (LTYPE (tree)))
3253 werror (E_SWITCH_NON_INTEGER);
3254 goto errorTreeReturn;
3257 TTYPE (tree) = TETYPE (tree) = NULL;
3260 /*------------------------------------------------------------------*/
3261 /*----------------------------*/
3263 /*----------------------------*/
3265 tree->left = backPatchLabels (tree->left,
3268 TTYPE (tree) = TETYPE (tree) = NULL;
3271 /*------------------------------------------------------------------*/
3272 /*----------------------------*/
3274 /*----------------------------*/
3277 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3278 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3279 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3281 /* if the for loop is reversible then
3282 reverse it otherwise do what we normally
3288 if (isLoopReversible (tree, &sym, &init, &end))
3289 return reverseLoop (tree, sym, init, end);
3291 return decorateType (createFor (AST_FOR (tree, trueLabel),
3292 AST_FOR (tree, continueLabel),
3293 AST_FOR (tree, falseLabel),
3294 AST_FOR (tree, condLabel),
3295 AST_FOR (tree, initExpr),
3296 AST_FOR (tree, condExpr),
3297 AST_FOR (tree, loopExpr),
3301 TTYPE (tree) = TETYPE (tree) = NULL;
3305 /* some error found this tree will be killed */
3307 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3308 tree->opval.op = NULLOP;
3314 /*-----------------------------------------------------------------*/
3315 /* sizeofOp - processes size of operation */
3316 /*-----------------------------------------------------------------*/
3318 sizeofOp (sym_link * type)
3322 /* make sure the type is complete and sane */
3323 checkTypeSanity(type, "(sizeof)");
3325 /* get the size and convert it to character */
3326 sprintf (buff, "%d", getSize (type));
3328 /* now convert into value */
3329 return constVal (buff);
3333 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3334 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3335 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3336 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3337 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3338 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3339 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3341 /*-----------------------------------------------------------------*/
3342 /* backPatchLabels - change and or not operators to flow control */
3343 /*-----------------------------------------------------------------*/
3345 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3351 if (!(IS_ANDORNOT (tree)))
3354 /* if this an and */
3357 static int localLbl = 0;
3360 sprintf (buffer, "_and_%d", localLbl++);
3361 localLabel = newSymbol (buffer, NestLevel);
3363 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3365 /* if left is already a IFX then just change the if true label in that */
3366 if (!IS_IFX (tree->left))
3367 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3369 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3370 /* right is a IFX then just join */
3371 if (IS_IFX (tree->right))
3372 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3374 tree->right = createLabel (localLabel, tree->right);
3375 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3377 return newNode (NULLOP, tree->left, tree->right);
3380 /* if this is an or operation */
3383 static int localLbl = 0;
3386 sprintf (buffer, "_or_%d", localLbl++);
3387 localLabel = newSymbol (buffer, NestLevel);
3389 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3391 /* if left is already a IFX then just change the if true label in that */
3392 if (!IS_IFX (tree->left))
3393 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3395 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3396 /* right is a IFX then just join */
3397 if (IS_IFX (tree->right))
3398 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3400 tree->right = createLabel (localLabel, tree->right);
3401 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3403 return newNode (NULLOP, tree->left, tree->right);
3409 int wasnot = IS_NOT (tree->left);
3410 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3412 /* if the left is already a IFX */
3413 if (!IS_IFX (tree->left))
3414 tree->left = newNode (IFX, tree->left, NULL);
3418 tree->left->trueLabel = trueLabel;
3419 tree->left->falseLabel = falseLabel;
3423 tree->left->trueLabel = falseLabel;
3424 tree->left->falseLabel = trueLabel;
3431 tree->trueLabel = trueLabel;
3432 tree->falseLabel = falseLabel;
3439 /*-----------------------------------------------------------------*/
3440 /* createBlock - create expression tree for block */
3441 /*-----------------------------------------------------------------*/
3443 createBlock (symbol * decl, ast * body)
3447 /* if the block has nothing */
3451 ex = newNode (BLOCK, NULL, body);
3452 ex->values.sym = decl;
3454 ex->right = ex->right;
3460 /*-----------------------------------------------------------------*/
3461 /* createLabel - creates the expression tree for labels */
3462 /*-----------------------------------------------------------------*/
3464 createLabel (symbol * label, ast * stmnt)
3467 char name[SDCC_NAME_MAX + 1];
3470 /* must create fresh symbol if the symbol name */
3471 /* exists in the symbol table, since there can */
3472 /* be a variable with the same name as the labl */
3473 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3474 (csym->level == label->level))
3475 label = newSymbol (label->name, label->level);
3477 /* change the name before putting it in add _ */
3478 sprintf (name, "%s", label->name);
3480 /* put the label in the LabelSymbol table */
3481 /* but first check if a label of the same */
3483 if ((csym = findSym (LabelTab, NULL, name)))
3484 werror (E_DUPLICATE_LABEL, label->name);
3486 addSym (LabelTab, label, name, label->level, 0, 0);
3489 label->key = labelKey++;
3490 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3496 /*-----------------------------------------------------------------*/
3497 /* createCase - generates the parsetree for a case statement */
3498 /*-----------------------------------------------------------------*/
3500 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3502 char caseLbl[SDCC_NAME_MAX + 1];
3506 /* if the switch statement does not exist */
3507 /* then case is out of context */
3510 werror (E_CASE_CONTEXT);
3514 caseVal = decorateType (resolveSymbols (caseVal));
3515 /* if not a constant then error */
3516 if (!IS_LITERAL (caseVal->ftype))
3518 werror (E_CASE_CONSTANT);
3522 /* if not a integer than error */
3523 if (!IS_INTEGRAL (caseVal->ftype))
3525 werror (E_CASE_NON_INTEGER);
3529 /* find the end of the switch values chain */
3530 if (!(val = swStat->values.switchVals.swVals))
3531 swStat->values.switchVals.swVals = caseVal->opval.val;
3534 /* also order the cases according to value */
3536 int cVal = (int) floatFromVal (caseVal->opval.val);
3537 while (val && (int) floatFromVal (val) < cVal)
3543 /* if we reached the end then */
3546 pval->next = caseVal->opval.val;
3550 /* we found a value greater than */
3551 /* the current value we must add this */
3552 /* before the value */
3553 caseVal->opval.val->next = val;
3555 /* if this was the first in chain */
3556 if (swStat->values.switchVals.swVals == val)
3557 swStat->values.switchVals.swVals =
3560 pval->next = caseVal->opval.val;
3565 /* create the case label */
3566 sprintf (caseLbl, "_case_%d_%d",
3567 swStat->values.switchVals.swNum,
3568 (int) floatFromVal (caseVal->opval.val));
3570 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3575 /*-----------------------------------------------------------------*/
3576 /* createDefault - creates the parse tree for the default statement */
3577 /*-----------------------------------------------------------------*/
3579 createDefault (ast * swStat, ast * stmnt)
3581 char defLbl[SDCC_NAME_MAX + 1];
3583 /* if the switch statement does not exist */
3584 /* then case is out of context */
3587 werror (E_CASE_CONTEXT);
3591 /* turn on the default flag */
3592 swStat->values.switchVals.swDefault = 1;
3594 /* create the label */
3595 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3596 return createLabel (newSymbol (defLbl, 0), stmnt);
3599 /*-----------------------------------------------------------------*/
3600 /* createIf - creates the parsetree for the if statement */
3601 /*-----------------------------------------------------------------*/
3603 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3605 static int Lblnum = 0;
3607 symbol *ifTrue, *ifFalse, *ifEnd;
3609 /* if neither exists */
3610 if (!elseBody && !ifBody) {
3611 // if there are no side effects (i++, j() etc)
3612 if (!hasSEFcalls(condAst)) {
3617 /* create the labels */
3618 sprintf (buffer, "_iffalse_%d", Lblnum);
3619 ifFalse = newSymbol (buffer, NestLevel);
3620 /* if no else body then end == false */
3625 sprintf (buffer, "_ifend_%d", Lblnum);
3626 ifEnd = newSymbol (buffer, NestLevel);
3629 sprintf (buffer, "_iftrue_%d", Lblnum);
3630 ifTrue = newSymbol (buffer, NestLevel);
3634 /* attach the ifTrue label to the top of it body */
3635 ifBody = createLabel (ifTrue, ifBody);
3636 /* attach a goto end to the ifBody if else is present */
3639 ifBody = newNode (NULLOP, ifBody,
3641 newAst_VALUE (symbolVal (ifEnd)),
3643 /* put the elseLabel on the else body */
3644 elseBody = createLabel (ifFalse, elseBody);
3645 /* out the end at the end of the body */
3646 elseBody = newNode (NULLOP,
3648 createLabel (ifEnd, NULL));
3652 ifBody = newNode (NULLOP, ifBody,
3653 createLabel (ifFalse, NULL));
3655 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3656 if (IS_IFX (condAst))
3659 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3661 return newNode (NULLOP, ifTree,
3662 newNode (NULLOP, ifBody, elseBody));
3666 /*-----------------------------------------------------------------*/
3667 /* createDo - creates parse tree for do */
3670 /* _docontinue_n: */
3671 /* condition_expression +-> trueLabel -> _dobody_n */
3673 /* +-> falseLabel-> _dobreak_n */
3675 /*-----------------------------------------------------------------*/
3677 createDo (symbol * trueLabel, symbol * continueLabel,
3678 symbol * falseLabel, ast * condAst, ast * doBody)
3683 /* if the body does not exist then it is simple */
3686 condAst = backPatchLabels (condAst, continueLabel, NULL);
3687 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3688 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3689 doTree->trueLabel = continueLabel;
3690 doTree->falseLabel = NULL;
3694 /* otherwise we have a body */
3695 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3697 /* attach the body label to the top */
3698 doBody = createLabel (trueLabel, doBody);
3699 /* attach the continue label to end of body */
3700 doBody = newNode (NULLOP, doBody,
3701 createLabel (continueLabel, NULL));
3703 /* now put the break label at the end */
3704 if (IS_IFX (condAst))
3707 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3709 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3711 /* putting it together */
3712 return newNode (NULLOP, doBody, doTree);
3715 /*-----------------------------------------------------------------*/
3716 /* createFor - creates parse tree for 'for' statement */
3719 /* condExpr +-> trueLabel -> _forbody_n */
3721 /* +-> falseLabel-> _forbreak_n */
3724 /* _forcontinue_n: */
3726 /* goto _forcond_n ; */
3728 /*-----------------------------------------------------------------*/
3730 createFor (symbol * trueLabel, symbol * continueLabel,
3731 symbol * falseLabel, symbol * condLabel,
3732 ast * initExpr, ast * condExpr, ast * loopExpr,
3737 /* if loopexpression not present then we can generate it */
3738 /* the same way as a while */
3740 return newNode (NULLOP, initExpr,
3741 createWhile (trueLabel, continueLabel,
3742 falseLabel, condExpr, forBody));
3743 /* vanilla for statement */
3744 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3746 if (condExpr && !IS_IFX (condExpr))
3747 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3750 /* attach condition label to condition */
3751 condExpr = createLabel (condLabel, condExpr);
3753 /* attach body label to body */
3754 forBody = createLabel (trueLabel, forBody);
3756 /* attach continue to forLoop expression & attach */
3757 /* goto the forcond @ and of loopExpression */
3758 loopExpr = createLabel (continueLabel,
3762 newAst_VALUE (symbolVal (condLabel)),
3764 /* now start putting them together */
3765 forTree = newNode (NULLOP, initExpr, condExpr);
3766 forTree = newNode (NULLOP, forTree, forBody);
3767 forTree = newNode (NULLOP, forTree, loopExpr);
3768 /* finally add the break label */
3769 forTree = newNode (NULLOP, forTree,
3770 createLabel (falseLabel, NULL));
3774 /*-----------------------------------------------------------------*/
3775 /* createWhile - creates parse tree for while statement */
3776 /* the while statement will be created as follows */
3778 /* _while_continue_n: */
3779 /* condition_expression +-> trueLabel -> _while_boby_n */
3781 /* +-> falseLabel -> _while_break_n */
3782 /* _while_body_n: */
3784 /* goto _while_continue_n */
3785 /* _while_break_n: */
3786 /*-----------------------------------------------------------------*/
3788 createWhile (symbol * trueLabel, symbol * continueLabel,
3789 symbol * falseLabel, ast * condExpr, ast * whileBody)
3793 /* put the continue label */
3794 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3795 condExpr = createLabel (continueLabel, condExpr);
3796 condExpr->lineno = 0;
3798 /* put the body label in front of the body */
3799 whileBody = createLabel (trueLabel, whileBody);
3800 whileBody->lineno = 0;
3801 /* put a jump to continue at the end of the body */
3802 /* and put break label at the end of the body */
3803 whileBody = newNode (NULLOP,
3806 newAst_VALUE (symbolVal (continueLabel)),
3807 createLabel (falseLabel, NULL)));
3809 /* put it all together */
3810 if (IS_IFX (condExpr))
3811 whileTree = condExpr;
3814 whileTree = newNode (IFX, condExpr, NULL);
3815 /* put the true & false labels in place */
3816 whileTree->trueLabel = trueLabel;
3817 whileTree->falseLabel = falseLabel;
3820 return newNode (NULLOP, whileTree, whileBody);
3823 /*-----------------------------------------------------------------*/
3824 /* optimizeGetHbit - get highest order bit of the expression */
3825 /*-----------------------------------------------------------------*/
3827 optimizeGetHbit (ast * tree)
3830 /* if this is not a bit and */
3831 if (!IS_BITAND (tree))
3834 /* will look for tree of the form
3835 ( expr >> ((sizeof expr) -1) ) & 1 */
3836 if (!IS_AST_LIT_VALUE (tree->right))
3839 if (AST_LIT_VALUE (tree->right) != 1)
3842 if (!IS_RIGHT_OP (tree->left))
3845 if (!IS_AST_LIT_VALUE (tree->left->right))
3848 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3849 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3852 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3856 /*-----------------------------------------------------------------*/
3857 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3858 /*-----------------------------------------------------------------*/
3860 optimizeRRCRLC (ast * root)
3862 /* will look for trees of the form
3863 (?expr << 1) | (?expr >> 7) or
3864 (?expr >> 7) | (?expr << 1) will make that
3865 into a RLC : operation ..
3867 (?expr >> 1) | (?expr << 7) or
3868 (?expr << 7) | (?expr >> 1) will make that
3869 into a RRC operation
3870 note : by 7 I mean (number of bits required to hold the
3872 /* if the root operations is not a | operation the not */
3873 if (!IS_BITOR (root))
3876 /* I have to think of a better way to match patterns this sucks */
3877 /* that aside let start looking for the first case : I use a the
3878 negative check a lot to improve the efficiency */
3879 /* (?expr << 1) | (?expr >> 7) */
3880 if (IS_LEFT_OP (root->left) &&
3881 IS_RIGHT_OP (root->right))
3884 if (!SPEC_USIGN (TETYPE (root->left->left)))
3887 if (!IS_AST_LIT_VALUE (root->left->right) ||
3888 !IS_AST_LIT_VALUE (root->right->right))
3891 /* make sure it is the same expression */
3892 if (!isAstEqual (root->left->left,
3896 if (AST_LIT_VALUE (root->left->right) != 1)
3899 if (AST_LIT_VALUE (root->right->right) !=
3900 (getSize (TTYPE (root->left->left)) * 8 - 1))
3903 /* whew got the first case : create the AST */
3904 return newNode (RLC, root->left->left, NULL);
3908 /* check for second case */
3909 /* (?expr >> 7) | (?expr << 1) */
3910 if (IS_LEFT_OP (root->right) &&
3911 IS_RIGHT_OP (root->left))
3914 if (!SPEC_USIGN (TETYPE (root->left->left)))
3917 if (!IS_AST_LIT_VALUE (root->left->right) ||
3918 !IS_AST_LIT_VALUE (root->right->right))
3921 /* make sure it is the same symbol */
3922 if (!isAstEqual (root->left->left,
3926 if (AST_LIT_VALUE (root->right->right) != 1)
3929 if (AST_LIT_VALUE (root->left->right) !=
3930 (getSize (TTYPE (root->left->left)) * 8 - 1))
3933 /* whew got the first case : create the AST */
3934 return newNode (RLC, root->left->left, NULL);
3939 /* third case for RRC */
3940 /* (?symbol >> 1) | (?symbol << 7) */
3941 if (IS_LEFT_OP (root->right) &&
3942 IS_RIGHT_OP (root->left))
3945 if (!SPEC_USIGN (TETYPE (root->left->left)))
3948 if (!IS_AST_LIT_VALUE (root->left->right) ||
3949 !IS_AST_LIT_VALUE (root->right->right))
3952 /* make sure it is the same symbol */
3953 if (!isAstEqual (root->left->left,
3957 if (AST_LIT_VALUE (root->left->right) != 1)
3960 if (AST_LIT_VALUE (root->right->right) !=
3961 (getSize (TTYPE (root->left->left)) * 8 - 1))
3964 /* whew got the first case : create the AST */
3965 return newNode (RRC, root->left->left, NULL);
3969 /* fourth and last case for now */
3970 /* (?symbol << 7) | (?symbol >> 1) */
3971 if (IS_RIGHT_OP (root->right) &&
3972 IS_LEFT_OP (root->left))
3975 if (!SPEC_USIGN (TETYPE (root->left->left)))
3978 if (!IS_AST_LIT_VALUE (root->left->right) ||
3979 !IS_AST_LIT_VALUE (root->right->right))
3982 /* make sure it is the same symbol */
3983 if (!isAstEqual (root->left->left,
3987 if (AST_LIT_VALUE (root->right->right) != 1)
3990 if (AST_LIT_VALUE (root->left->right) !=
3991 (getSize (TTYPE (root->left->left)) * 8 - 1))
3994 /* whew got the first case : create the AST */
3995 return newNode (RRC, root->left->left, NULL);
3999 /* not found return root */
4003 /*-----------------------------------------------------------------*/
4004 /* optimizeCompare - otimizes compares for bit variables */
4005 /*-----------------------------------------------------------------*/
4007 optimizeCompare (ast * root)
4009 ast *optExpr = NULL;
4012 unsigned int litValue;
4014 /* if nothing then return nothing */
4018 /* if not a compare op then do leaves */
4019 if (!IS_COMPARE_OP (root))
4021 root->left = optimizeCompare (root->left);
4022 root->right = optimizeCompare (root->right);
4026 /* if left & right are the same then depending
4027 of the operation do */
4028 if (isAstEqual (root->left, root->right))
4030 switch (root->opval.op)
4035 optExpr = newAst_VALUE (constVal ("0"));
4040 optExpr = newAst_VALUE (constVal ("1"));
4044 return decorateType (optExpr);
4047 vleft = (root->left->type == EX_VALUE ?
4048 root->left->opval.val : NULL);
4050 vright = (root->right->type == EX_VALUE ?
4051 root->right->opval.val : NULL);
4053 /* if left is a BITVAR in BITSPACE */
4054 /* and right is a LITERAL then opt- */
4055 /* imize else do nothing */
4056 if (vleft && vright &&
4057 IS_BITVAR (vleft->etype) &&
4058 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4059 IS_LITERAL (vright->etype))
4062 /* if right side > 1 then comparison may never succeed */
4063 if ((litValue = (int) floatFromVal (vright)) > 1)
4065 werror (W_BAD_COMPARE);
4071 switch (root->opval.op)
4073 case '>': /* bit value greater than 1 cannot be */
4074 werror (W_BAD_COMPARE);
4078 case '<': /* bit value < 1 means 0 */
4080 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4083 case LE_OP: /* bit value <= 1 means no check */
4084 optExpr = newAst_VALUE (vright);
4087 case GE_OP: /* bit value >= 1 means only check for = */
4089 optExpr = newAst_VALUE (vleft);
4094 { /* literal is zero */
4095 switch (root->opval.op)
4097 case '<': /* bit value < 0 cannot be */
4098 werror (W_BAD_COMPARE);
4102 case '>': /* bit value > 0 means 1 */
4104 optExpr = newAst_VALUE (vleft);
4107 case LE_OP: /* bit value <= 0 means no check */
4108 case GE_OP: /* bit value >= 0 means no check */
4109 werror (W_BAD_COMPARE);
4113 case EQ_OP: /* bit == 0 means ! of bit */
4114 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4118 return decorateType (resolveSymbols (optExpr));
4119 } /* end-of-if of BITVAR */
4124 /*-----------------------------------------------------------------*/
4125 /* addSymToBlock : adds the symbol to the first block we find */
4126 /*-----------------------------------------------------------------*/
4128 addSymToBlock (symbol * sym, ast * tree)
4130 /* reached end of tree or a leaf */
4131 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4135 if (IS_AST_OP (tree) &&
4136 tree->opval.op == BLOCK)
4139 symbol *lsym = copySymbol (sym);
4141 lsym->next = AST_VALUES (tree, sym);
4142 AST_VALUES (tree, sym) = lsym;
4146 addSymToBlock (sym, tree->left);
4147 addSymToBlock (sym, tree->right);
4150 /*-----------------------------------------------------------------*/
4151 /* processRegParms - do processing for register parameters */
4152 /*-----------------------------------------------------------------*/
4154 processRegParms (value * args, ast * body)
4158 if (IS_REGPARM (args->etype))
4159 addSymToBlock (args->sym, body);
4164 /*-----------------------------------------------------------------*/
4165 /* resetParmKey - resets the operandkeys for the symbols */
4166 /*-----------------------------------------------------------------*/
4167 DEFSETFUNC (resetParmKey)
4178 /*-----------------------------------------------------------------*/
4179 /* createFunction - This is the key node that calls the iCode for */
4180 /* generating the code for a function. Note code */
4181 /* is generated function by function, later when */
4182 /* add inter-procedural analysis this will change */
4183 /*-----------------------------------------------------------------*/
4185 createFunction (symbol * name, ast * body)
4191 iCode *piCode = NULL;
4193 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4194 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4196 /* if check function return 0 then some problem */
4197 if (checkFunction (name, NULL) == 0)
4200 /* create a dummy block if none exists */
4202 body = newNode (BLOCK, NULL, NULL);
4206 /* check if the function name already in the symbol table */
4207 if ((csym = findSym (SymbolTab, NULL, name->name)))
4210 /* special case for compiler defined functions
4211 we need to add the name to the publics list : this
4212 actually means we are now compiling the compiler
4216 addSet (&publics, name);
4222 allocVariables (name);
4224 name->lastLine = yylineno;
4227 /* set the stack pointer */
4228 /* PENDING: check this for the mcs51 */
4229 stackPtr = -port->stack.direction * port->stack.call_overhead;
4230 if (IFFUNC_ISISR (name->type))
4231 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4232 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4233 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4235 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4237 fetype = getSpec (name->type); /* get the specifier for the function */
4238 /* if this is a reentrant function then */
4239 if (IFFUNC_ISREENT (name->type))
4242 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4244 /* do processing for parameters that are passed in registers */
4245 processRegParms (FUNC_ARGS(name->type), body);
4247 /* set the stack pointer */
4251 /* allocate & autoinit the block variables */
4252 processBlockVars (body, &stack, ALLOCATE);
4254 /* save the stack information */
4255 if (options.useXstack)
4256 name->xstack = SPEC_STAK (fetype) = stack;
4258 name->stack = SPEC_STAK (fetype) = stack;
4260 /* name needs to be mangled */
4261 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4263 body = resolveSymbols (body); /* resolve the symbols */
4264 body = decorateType (body); /* propagateType & do semantic checks */
4266 ex = newAst_VALUE (symbolVal (name)); /* create name */
4267 ex = newNode (FUNCTION, ex, body);
4268 ex->values.args = FUNC_ARGS(name->type);
4270 if (options.dump_tree) PA(ex);
4273 werror (E_FUNC_NO_CODE, name->name);
4277 /* create the node & generate intermediate code */
4279 codeOutFile = code->oFile;
4280 piCode = iCodeFromAst (ex);
4284 werror (E_FUNC_NO_CODE, name->name);
4288 eBBlockFromiCode (piCode);
4290 /* if there are any statics then do them */
4293 GcurMemmap = statsg;
4294 codeOutFile = statsg->oFile;
4295 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4301 /* dealloc the block variables */
4302 processBlockVars (body, &stack, DEALLOCATE);
4303 /* deallocate paramaters */
4304 deallocParms (FUNC_ARGS(name->type));
4306 if (IFFUNC_ISREENT (name->type))
4309 /* we are done freeup memory & cleanup */
4311 if (port->reset_labelKey) labelKey = 1;
4313 FUNC_HASBODY(name->type) = 1;
4314 addSet (&operKeyReset, name);
4315 applyToSet (operKeyReset, resetParmKey);
4318 cdbStructBlock (1, cdbFile);
4320 cleanUpLevel (LabelTab, 0);
4321 cleanUpBlock (StructTab, 1);
4322 cleanUpBlock (TypedefTab, 1);
4324 xstack->syms = NULL;
4325 istack->syms = NULL;
4330 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4331 /*-----------------------------------------------------------------*/
4332 /* ast_print : prints the ast (for debugging purposes) */
4333 /*-----------------------------------------------------------------*/
4335 void ast_print (ast * tree, FILE *outfile, int indent)
4340 /* can print only decorated trees */
4341 if (!tree->decorated) return;
4343 /* if any child is an error | this one is an error do nothing */
4344 if (tree->isError ||
4345 (tree->left && tree->left->isError) ||
4346 (tree->right && tree->right->isError)) {
4347 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4351 /* print the line */
4352 /* if not block & function */
4353 if (tree->type == EX_OP &&
4354 (tree->opval.op != FUNCTION &&
4355 tree->opval.op != BLOCK &&
4356 tree->opval.op != NULLOP)) {
4359 if (tree->opval.op == FUNCTION) {
4361 value *args=FUNC_ARGS(tree->left->opval.val->type);
4362 fprintf(outfile,"FUNCTION (%s=%p) type (",
4363 tree->left->opval.val->name, tree);
4364 printTypeChain (tree->ftype,outfile);
4365 fprintf(outfile,") args (");
4368 fprintf (outfile, ", ");
4370 printTypeChain (args ? args->type : NULL, outfile);
4372 args= args ? args->next : NULL;
4374 fprintf(outfile,")\n");
4375 ast_print(tree->left,outfile,indent);
4376 ast_print(tree->right,outfile,indent);
4379 if (tree->opval.op == BLOCK) {
4380 symbol *decls = tree->values.sym;
4381 INDENT(indent,outfile);
4382 fprintf(outfile,"{\n");
4384 INDENT(indent+2,outfile);
4385 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4386 decls->name, decls);
4387 printTypeChain(decls->type,outfile);
4388 fprintf(outfile,")\n");
4390 decls = decls->next;
4392 ast_print(tree->right,outfile,indent+2);
4393 INDENT(indent,outfile);
4394 fprintf(outfile,"}\n");
4397 if (tree->opval.op == NULLOP) {
4398 fprintf(outfile,"\n");
4399 ast_print(tree->left,outfile,indent);
4400 fprintf(outfile,"\n");
4401 ast_print(tree->right,outfile,indent);
4404 INDENT(indent,outfile);
4406 /*------------------------------------------------------------------*/
4407 /*----------------------------*/
4408 /* leaf has been reached */
4409 /*----------------------------*/
4410 /* if this is of type value */
4411 /* just get the type */
4412 if (tree->type == EX_VALUE) {
4414 if (IS_LITERAL (tree->opval.val->etype)) {
4415 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4416 (int) floatFromVal(tree->opval.val),
4417 (int) floatFromVal(tree->opval.val),
4418 floatFromVal(tree->opval.val));
4419 } else if (tree->opval.val->sym) {
4420 /* if the undefined flag is set then give error message */
4421 if (tree->opval.val->sym->undefined) {
4422 fprintf(outfile,"UNDEFINED SYMBOL ");
4424 fprintf(outfile,"SYMBOL ");
4426 fprintf(outfile,"(%s=%p)",
4427 tree->opval.val->sym->name,tree);
4430 fprintf(outfile," type (");
4431 printTypeChain(tree->ftype,outfile);
4432 fprintf(outfile,")\n");
4434 fprintf(outfile,"\n");
4439 /* if type link for the case of cast */
4440 if (tree->type == EX_LINK) {
4441 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4442 printTypeChain(tree->opval.lnk,outfile);
4443 fprintf(outfile,")\n");
4448 /* depending on type of operator do */
4450 switch (tree->opval.op) {
4451 /*------------------------------------------------------------------*/
4452 /*----------------------------*/
4454 /*----------------------------*/
4456 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+2);
4460 ast_print(tree->right,outfile,indent+2);
4463 /*------------------------------------------------------------------*/
4464 /*----------------------------*/
4466 /*----------------------------*/
4468 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4469 printTypeChain(tree->ftype,outfile);
4470 fprintf(outfile,")\n");
4471 ast_print(tree->left,outfile,indent+2);
4472 ast_print(tree->right,outfile,indent+2);
4475 /*------------------------------------------------------------------*/
4476 /*----------------------------*/
4477 /* struct/union pointer */
4478 /*----------------------------*/
4480 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4481 printTypeChain(tree->ftype,outfile);
4482 fprintf(outfile,")\n");
4483 ast_print(tree->left,outfile,indent+2);
4484 ast_print(tree->right,outfile,indent+2);
4487 /*------------------------------------------------------------------*/
4488 /*----------------------------*/
4489 /* ++/-- operation */
4490 /*----------------------------*/
4491 case INC_OP: /* incerement operator unary so left only */
4492 fprintf(outfile,"INC_OP (%p) type (",tree);
4493 printTypeChain(tree->ftype,outfile);
4494 fprintf(outfile,")\n");
4495 ast_print(tree->left,outfile,indent+2);
4499 fprintf(outfile,"DEC_OP (%p) type (",tree);
4500 printTypeChain(tree->ftype,outfile);
4501 fprintf(outfile,")\n");
4502 ast_print(tree->left,outfile,indent+2);
4505 /*------------------------------------------------------------------*/
4506 /*----------------------------*/
4508 /*----------------------------*/
4511 fprintf(outfile,"& (%p) type (",tree);
4512 printTypeChain(tree->ftype,outfile);
4513 fprintf(outfile,")\n");
4514 ast_print(tree->left,outfile,indent+2);
4515 ast_print(tree->right,outfile,indent+2);
4517 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4518 printTypeChain(tree->ftype,outfile);
4519 fprintf(outfile,")\n");
4520 ast_print(tree->left,outfile,indent+2);
4521 ast_print(tree->right,outfile,indent+2);
4524 /*----------------------------*/
4526 /*----------------------------*/
4528 fprintf(outfile,"OR (%p) type (",tree);
4529 printTypeChain(tree->ftype,outfile);
4530 fprintf(outfile,")\n");
4531 ast_print(tree->left,outfile,indent+2);
4532 ast_print(tree->right,outfile,indent+2);
4534 /*------------------------------------------------------------------*/
4535 /*----------------------------*/
4537 /*----------------------------*/
4539 fprintf(outfile,"XOR (%p) type (",tree);
4540 printTypeChain(tree->ftype,outfile);
4541 fprintf(outfile,")\n");
4542 ast_print(tree->left,outfile,indent+2);
4543 ast_print(tree->right,outfile,indent+2);
4546 /*------------------------------------------------------------------*/
4547 /*----------------------------*/
4549 /*----------------------------*/
4551 fprintf(outfile,"DIV (%p) type (",tree);
4552 printTypeChain(tree->ftype,outfile);
4553 fprintf(outfile,")\n");
4554 ast_print(tree->left,outfile,indent+2);
4555 ast_print(tree->right,outfile,indent+2);
4557 /*------------------------------------------------------------------*/
4558 /*----------------------------*/
4560 /*----------------------------*/
4562 fprintf(outfile,"MOD (%p) type (",tree);
4563 printTypeChain(tree->ftype,outfile);
4564 fprintf(outfile,")\n");
4565 ast_print(tree->left,outfile,indent+2);
4566 ast_print(tree->right,outfile,indent+2);
4569 /*------------------------------------------------------------------*/
4570 /*----------------------------*/
4571 /* address dereference */
4572 /*----------------------------*/
4573 case '*': /* can be unary : if right is null then unary operation */
4575 fprintf(outfile,"DEREF (%p) type (",tree);
4576 printTypeChain(tree->ftype,outfile);
4577 fprintf(outfile,")\n");
4578 ast_print(tree->left,outfile,indent+2);
4581 /*------------------------------------------------------------------*/
4582 /*----------------------------*/
4583 /* multiplication */
4584 /*----------------------------*/
4585 fprintf(outfile,"MULT (%p) type (",tree);
4586 printTypeChain(tree->ftype,outfile);
4587 fprintf(outfile,")\n");
4588 ast_print(tree->left,outfile,indent+2);
4589 ast_print(tree->right,outfile,indent+2);
4593 /*------------------------------------------------------------------*/
4594 /*----------------------------*/
4595 /* unary '+' operator */
4596 /*----------------------------*/
4600 fprintf(outfile,"UPLUS (%p) type (",tree);
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->left,outfile,indent+2);
4605 /*------------------------------------------------------------------*/
4606 /*----------------------------*/
4608 /*----------------------------*/
4609 fprintf(outfile,"ADD (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+2);
4613 ast_print(tree->right,outfile,indent+2);
4616 /*------------------------------------------------------------------*/
4617 /*----------------------------*/
4619 /*----------------------------*/
4620 case '-': /* can be unary */
4622 fprintf(outfile,"UMINUS (%p) type (",tree);
4623 printTypeChain(tree->ftype,outfile);
4624 fprintf(outfile,")\n");
4625 ast_print(tree->left,outfile,indent+2);
4627 /*------------------------------------------------------------------*/
4628 /*----------------------------*/
4630 /*----------------------------*/
4631 fprintf(outfile,"SUB (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+2);
4635 ast_print(tree->right,outfile,indent+2);
4638 /*------------------------------------------------------------------*/
4639 /*----------------------------*/
4641 /*----------------------------*/
4643 fprintf(outfile,"COMPL (%p) type (",tree);
4644 printTypeChain(tree->ftype,outfile);
4645 fprintf(outfile,")\n");
4646 ast_print(tree->left,outfile,indent+2);
4648 /*------------------------------------------------------------------*/
4649 /*----------------------------*/
4651 /*----------------------------*/
4653 fprintf(outfile,"NOT (%p) type (",tree);
4654 printTypeChain(tree->ftype,outfile);
4655 fprintf(outfile,")\n");
4656 ast_print(tree->left,outfile,indent+2);
4658 /*------------------------------------------------------------------*/
4659 /*----------------------------*/
4661 /*----------------------------*/
4663 fprintf(outfile,"RRC (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+2);
4670 fprintf(outfile,"RLC (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+2);
4676 fprintf(outfile,"GETHBIT (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+2);
4682 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+2);
4686 ast_print(tree->right,outfile,indent+2);
4689 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+2);
4693 ast_print(tree->right,outfile,indent+2);
4695 /*------------------------------------------------------------------*/
4696 /*----------------------------*/
4698 /*----------------------------*/
4699 case CAST: /* change the type */
4700 fprintf(outfile,"CAST (%p) from type (",tree);
4701 printTypeChain(tree->right->ftype,outfile);
4702 fprintf(outfile,") to type (");
4703 printTypeChain(tree->ftype,outfile);
4704 fprintf(outfile,")\n");
4705 ast_print(tree->right,outfile,indent+2);
4709 fprintf(outfile,"ANDAND (%p) type (",tree);
4710 printTypeChain(tree->ftype,outfile);
4711 fprintf(outfile,")\n");
4712 ast_print(tree->left,outfile,indent+2);
4713 ast_print(tree->right,outfile,indent+2);
4716 fprintf(outfile,"OROR (%p) type (",tree);
4717 printTypeChain(tree->ftype,outfile);
4718 fprintf(outfile,")\n");
4719 ast_print(tree->left,outfile,indent+2);
4720 ast_print(tree->right,outfile,indent+2);
4723 /*------------------------------------------------------------------*/
4724 /*----------------------------*/
4725 /* comparison operators */
4726 /*----------------------------*/
4728 fprintf(outfile,"GT(>) (%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,"LT(<) (%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,"LE(<=) (%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,"GE(>=) (%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);
4756 fprintf(outfile,"EQ(==) (%p) type (",tree);
4757 printTypeChain(tree->ftype,outfile);
4758 fprintf(outfile,")\n");
4759 ast_print(tree->left,outfile,indent+2);
4760 ast_print(tree->right,outfile,indent+2);
4763 fprintf(outfile,"NE(!=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+2);
4767 ast_print(tree->right,outfile,indent+2);
4768 /*------------------------------------------------------------------*/
4769 /*----------------------------*/
4771 /*----------------------------*/
4772 case SIZEOF: /* evaluate wihout code generation */
4773 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4776 /*------------------------------------------------------------------*/
4777 /*----------------------------*/
4778 /* conditional operator '?' */
4779 /*----------------------------*/
4781 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4782 printTypeChain(tree->ftype,outfile);
4783 fprintf(outfile,")\n");
4784 ast_print(tree->left,outfile,indent+2);
4785 ast_print(tree->right,outfile,indent+2);
4789 fprintf(outfile,"COLON(:) (%p) type (",tree);
4790 printTypeChain(tree->ftype,outfile);
4791 fprintf(outfile,")\n");
4792 ast_print(tree->left,outfile,indent+2);
4793 ast_print(tree->right,outfile,indent+2);
4796 /*------------------------------------------------------------------*/
4797 /*----------------------------*/
4798 /* assignment operators */
4799 /*----------------------------*/
4801 fprintf(outfile,"MULASS(*=) (%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,"DIVASS(/=) (%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,"ANDASS(&=) (%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,"ORASS(*=) (%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,"XORASS(*=) (%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);
4836 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4837 printTypeChain(tree->ftype,outfile);
4838 fprintf(outfile,")\n");
4839 ast_print(tree->left,outfile,indent+2);
4840 ast_print(tree->right,outfile,indent+2);
4843 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4844 printTypeChain(tree->ftype,outfile);
4845 fprintf(outfile,")\n");
4846 ast_print(tree->left,outfile,indent+2);
4847 ast_print(tree->right,outfile,indent+2);
4849 /*------------------------------------------------------------------*/
4850 /*----------------------------*/
4852 /*----------------------------*/
4854 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4855 printTypeChain(tree->ftype,outfile);
4856 fprintf(outfile,")\n");
4857 ast_print(tree->left,outfile,indent+2);
4858 ast_print(tree->right,outfile,indent+2);
4860 /*------------------------------------------------------------------*/
4861 /*----------------------------*/
4863 /*----------------------------*/
4865 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4866 printTypeChain(tree->ftype,outfile);
4867 fprintf(outfile,")\n");
4868 ast_print(tree->left,outfile,indent+2);
4869 ast_print(tree->right,outfile,indent+2);
4871 /*------------------------------------------------------------------*/
4872 /*----------------------------*/
4873 /* straight assignemnt */
4874 /*----------------------------*/
4876 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4877 printTypeChain(tree->ftype,outfile);
4878 fprintf(outfile,")\n");
4879 ast_print(tree->left,outfile,indent+2);
4880 ast_print(tree->right,outfile,indent+2);
4882 /*------------------------------------------------------------------*/
4883 /*----------------------------*/
4884 /* comma operator */
4885 /*----------------------------*/
4887 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4888 printTypeChain(tree->ftype,outfile);
4889 fprintf(outfile,")\n");
4890 ast_print(tree->left,outfile,indent+2);
4891 ast_print(tree->right,outfile,indent+2);
4893 /*------------------------------------------------------------------*/
4894 /*----------------------------*/
4896 /*----------------------------*/
4899 fprintf(outfile,"CALL (%p) type (",tree);
4900 printTypeChain(tree->ftype,outfile);
4901 fprintf(outfile,")\n");
4902 ast_print(tree->left,outfile,indent+2);
4903 ast_print(tree->right,outfile,indent+2);
4906 fprintf(outfile,"PARMS\n");
4907 ast_print(tree->left,outfile,indent+2);
4908 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4909 ast_print(tree->right,outfile,indent+2);
4912 /*------------------------------------------------------------------*/
4913 /*----------------------------*/
4914 /* return statement */
4915 /*----------------------------*/
4917 fprintf(outfile,"RETURN (%p) type (",tree);
4919 printTypeChain(tree->right->ftype,outfile);
4921 fprintf(outfile,")\n");
4922 ast_print(tree->right,outfile,indent+2);
4924 /*------------------------------------------------------------------*/
4925 /*----------------------------*/
4926 /* label statement */
4927 /*----------------------------*/
4929 fprintf(outfile,"LABEL (%p)\n",tree);
4930 ast_print(tree->left,outfile,indent+2);
4931 ast_print(tree->right,outfile,indent);
4933 /*------------------------------------------------------------------*/
4934 /*----------------------------*/
4935 /* switch statement */
4936 /*----------------------------*/
4940 fprintf(outfile,"SWITCH (%p) ",tree);
4941 ast_print(tree->left,outfile,0);
4942 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4943 INDENT(indent+2,outfile);
4944 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4945 (int) floatFromVal(val),
4946 tree->values.switchVals.swNum,
4947 (int) floatFromVal(val));
4949 ast_print(tree->right,outfile,indent);
4952 /*------------------------------------------------------------------*/
4953 /*----------------------------*/
4955 /*----------------------------*/
4957 fprintf(outfile,"IF (%p) \n",tree);
4958 ast_print(tree->left,outfile,indent+2);
4959 if (tree->trueLabel) {
4960 INDENT(indent,outfile);
4961 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4963 if (tree->falseLabel) {
4964 INDENT(indent,outfile);
4965 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4967 ast_print(tree->right,outfile,indent+2);
4969 /*------------------------------------------------------------------*/
4970 /*----------------------------*/
4972 /*----------------------------*/
4974 fprintf(outfile,"FOR (%p) \n",tree);
4975 if (AST_FOR( tree, initExpr)) {
4976 INDENT(indent+2,outfile);
4977 fprintf(outfile,"INIT EXPR ");
4978 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4980 if (AST_FOR( tree, condExpr)) {
4981 INDENT(indent+2,outfile);
4982 fprintf(outfile,"COND EXPR ");
4983 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4985 if (AST_FOR( tree, loopExpr)) {
4986 INDENT(indent+2,outfile);
4987 fprintf(outfile,"LOOP EXPR ");
4988 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4990 fprintf(outfile,"FOR LOOP BODY \n");
4991 ast_print(tree->left,outfile,indent+2);
5000 ast_print(t,stdout,0);