1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190 strcpy (dest->values.inlineasm, src->values.inlineasm);
194 dest->values.constlist = copyLiteralList(src->values.constlist);
198 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession */
211 /*-----------------------------------------------------------------*/
220 dest = Safe_alloc ( sizeof (ast));
222 dest->type = src->type;
223 dest->lineno = src->lineno;
224 dest->level = src->level;
225 dest->funcName = src->funcName;
228 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
230 /* if this is a leaf */
232 if (src->type == EX_VALUE)
234 dest->opval.val = copyValue (src->opval.val);
239 if (src->type == EX_LINK)
241 dest->opval.lnk = copyLinkChain (src->opval.lnk);
245 dest->opval.op = src->opval.op;
247 /* if this is a node that has special values */
248 copyAstValues (dest, src);
250 dest->trueLabel = copySymbol (src->trueLabel);
251 dest->falseLabel = copySymbol (src->falseLabel);
252 dest->left = copyAst (src->left);
253 dest->right = copyAst (src->right);
259 /*-----------------------------------------------------------------*/
260 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
261 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
262 /*-----------------------------------------------------------------*/
263 ast *removeIncDecOps (ast * tree) {
265 // traverse the tree and remove inc/dec ops
270 if (tree->type == EX_OP &&
271 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
278 tree->left=removeIncDecOps(tree->left);
279 tree->right=removeIncDecOps(tree->right);
284 /*-----------------------------------------------------------------*/
285 /* hasSEFcalls - returns TRUE if tree has a function call */
286 /*-----------------------------------------------------------------*/
288 hasSEFcalls (ast * tree)
293 if (tree->type == EX_OP &&
294 (tree->opval.op == CALL ||
295 tree->opval.op == PCALL ||
296 tree->opval.op == '=' ||
297 tree->opval.op == INC_OP ||
298 tree->opval.op == DEC_OP))
301 return (hasSEFcalls (tree->left) |
302 hasSEFcalls (tree->right));
305 /*-----------------------------------------------------------------*/
306 /* isAstEqual - compares two asts & returns 1 if they are equal */
307 /*-----------------------------------------------------------------*/
309 isAstEqual (ast * t1, ast * t2)
318 if (t1->type != t2->type)
324 if (t1->opval.op != t2->opval.op)
326 return (isAstEqual (t1->left, t2->left) &&
327 isAstEqual (t1->right, t2->right));
331 if (t1->opval.val->sym)
333 if (!t2->opval.val->sym)
336 return isSymbolEqual (t1->opval.val->sym,
341 if (t2->opval.val->sym)
344 return (floatFromVal (t1->opval.val) ==
345 floatFromVal (t2->opval.val));
349 /* only compare these two types */
357 /*-----------------------------------------------------------------*/
358 /* resolveSymbols - resolve symbols from the symbol table */
359 /*-----------------------------------------------------------------*/
361 resolveSymbols (ast * tree)
363 /* walk the entire tree and check for values */
364 /* with symbols if we find one then replace */
365 /* symbol with that from the symbol table */
372 /* if not block & function */
373 if (tree->type == EX_OP &&
374 (tree->opval.op != FUNCTION &&
375 tree->opval.op != BLOCK &&
376 tree->opval.op != NULLOP))
378 filename = tree->filename;
379 lineno = tree->lineno;
383 /* make sure we resolve the true & false labels for ifx */
384 if (tree->type == EX_OP && tree->opval.op == IFX)
390 if ((csym = findSym (LabelTab, tree->trueLabel,
391 tree->trueLabel->name)))
392 tree->trueLabel = csym;
394 werror (E_LABEL_UNDEF, tree->trueLabel->name);
397 if (tree->falseLabel)
399 if ((csym = findSym (LabelTab,
401 tree->falseLabel->name)))
402 tree->falseLabel = csym;
404 werror (E_LABEL_UNDEF, tree->falseLabel->name);
409 /* if this is a label resolve it from the labelTab */
410 if (IS_AST_VALUE (tree) &&
411 tree->opval.val->sym &&
412 tree->opval.val->sym->islbl)
415 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
416 tree->opval.val->sym->name);
419 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
421 tree->opval.val->sym = csym;
423 goto resolveChildren;
426 /* do only for leafs */
427 if (IS_AST_VALUE (tree) &&
428 tree->opval.val->sym &&
429 !tree->opval.val->sym->implicit)
432 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
434 /* if found in the symbol table & they r not the same */
435 if (csym && tree->opval.val->sym != csym)
437 tree->opval.val->sym = csym;
438 tree->opval.val->type = csym->type;
439 tree->opval.val->etype = csym->etype;
442 /* if not found in the symbol table */
443 /* mark it as undefined assume it is */
444 /* an integer in data space */
445 if (!csym && !tree->opval.val->sym->implicit)
448 /* if this is a function name then */
449 /* mark it as returning an int */
452 tree->opval.val->sym->type = newLink ();
453 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
454 tree->opval.val->sym->type->next =
455 tree->opval.val->sym->etype = newIntLink ();
456 tree->opval.val->etype = tree->opval.val->etype;
457 tree->opval.val->type = tree->opval.val->sym->type;
458 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
459 allocVariables (tree->opval.val->sym);
463 tree->opval.val->sym->undefined = 1;
464 tree->opval.val->type =
465 tree->opval.val->etype = newIntLink ();
466 tree->opval.val->sym->type =
467 tree->opval.val->sym->etype = newIntLink ();
473 resolveSymbols (tree->left);
474 resolveSymbols (tree->right);
479 /*-----------------------------------------------------------------*/
480 /* setAstLineno - walks a ast tree & sets the line number */
481 /*-----------------------------------------------------------------*/
482 int setAstLineno (ast * tree, int lineno)
487 tree->lineno = lineno;
488 setAstLineno (tree->left, lineno);
489 setAstLineno (tree->right, lineno);
493 /*-----------------------------------------------------------------*/
494 /* funcOfType :- function of type with name */
495 /*-----------------------------------------------------------------*/
497 funcOfType (char *name, sym_link * type, sym_link * argType,
501 /* create the symbol */
502 sym = newSymbol (name, 0);
504 /* setup return value */
505 sym->type = newLink ();
506 DCL_TYPE (sym->type) = FUNCTION;
507 sym->type->next = copyLinkChain (type);
508 sym->etype = getSpec (sym->type);
509 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
511 /* if arguments required */
515 args = FUNC_ARGS(sym->type) = newValue ();
519 args->type = copyLinkChain (argType);
520 args->etype = getSpec (args->type);
521 SPEC_EXTR(args->etype)=1;
524 args = args->next = newValue ();
531 allocVariables (sym);
536 /*-----------------------------------------------------------------*/
537 /* funcOfTypeVarg :- function of type with name and argtype */
538 /*-----------------------------------------------------------------*/
540 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
545 /* create the symbol */
546 sym = newSymbol (name, 0);
548 /* setup return value */
549 sym->type = newLink ();
550 DCL_TYPE (sym->type) = FUNCTION;
551 sym->type->next = typeFromStr(rtype);
552 sym->etype = getSpec (sym->type);
554 /* if arguments required */
557 args = FUNC_ARGS(sym->type) = newValue ();
559 for ( i = 0 ; i < nArgs ; i++ ) {
560 args->type = typeFromStr(atypes[i]);
561 args->etype = getSpec (args->type);
562 SPEC_EXTR(args->etype)=1;
563 if ((i + 1) == nArgs) break;
564 args = args->next = newValue ();
571 allocVariables (sym);
576 /*-----------------------------------------------------------------*/
577 /* reverseParms - will reverse a parameter tree */
578 /*-----------------------------------------------------------------*/
580 reverseParms (ast * ptree)
586 /* top down if we find a nonParm tree then quit */
587 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
590 ptree->left = ptree->right;
591 ptree->right = ttree;
592 reverseParms (ptree->left);
593 reverseParms (ptree->right);
599 /*-----------------------------------------------------------------*/
600 /* processParms - makes sure the parameters are okay and do some */
601 /* processing with them */
602 /*-----------------------------------------------------------------*/
604 processParms (ast * func,
607 int *parmNumber, // unused, although updated
610 /* if none of them exist */
611 if (!defParm && !actParm)
615 if (getenv("DEBUG_SANITY")) {
616 fprintf (stderr, "processParms: %s ", defParm->name);
618 /* make sure the type is complete and sane */
619 checkTypeSanity(defParm->etype, defParm->name);
622 /* if the function is being called via a pointer & */
623 /* it has not been defined a reentrant then we cannot */
624 /* have parameters */
625 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
627 werror (W_NONRENT_ARGS);
631 /* if defined parameters ended but actual parameters */
632 /* exist and this is not defined as a variable arg */
633 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
635 werror (E_TOO_MANY_PARMS);
639 /* if defined parameters present but no actual parameters */
640 if (defParm && !actParm)
642 werror (E_TOO_FEW_PARMS);
646 if (IS_VOID(actParm->ftype)) {
647 werror (E_VOID_VALUE_USED);
651 /* If this is a varargs function... */
652 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
657 if (IS_CAST_OP (actParm)
658 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
660 /* Parameter was explicitly typecast; don't touch it. */
664 ftype = actParm->ftype;
666 /* If it's a small integer, upcast to int. */
667 if (IS_INTEGRAL (ftype)
668 && (getSize (ftype) < (unsigned) INTSIZE))
670 if (IS_AST_OP(actParm) &&
671 (actParm->opval.op == LEFT_OP ||
672 actParm->opval.op == '*' ||
673 actParm->opval.op == '+' ||
674 actParm->opval.op == '-') &&
676 // we should cast an operand instead of the result
677 actParm->decorated = 0;
678 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
680 actParm = decorateType(actParm);
682 newType = newAst_LINK(INTTYPE);
686 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
688 newType = newAst_LINK (copyLinkChain(ftype));
689 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
692 if (IS_AGGREGATE (ftype))
694 newType = newAst_LINK (copyLinkChain (ftype));
695 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
699 /* cast required; change this op to a cast. */
700 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
702 actParm->type = EX_OP;
703 actParm->opval.op = CAST;
704 actParm->left = newType;
705 actParm->right = parmCopy;
706 decorateType (actParm);
708 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
710 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
711 processParms (func, NULL, actParm->right, parmNumber, rightmost));
716 /* if defined parameters ended but actual has not & */
718 if (!defParm && actParm &&
719 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
722 resolveSymbols (actParm);
723 /* if this is a PARAM node then match left & right */
724 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
726 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
727 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
731 /* If we have found a value node by following only right-hand links,
732 * then we know that there are no more values after us.
734 * Therefore, if there are more defined parameters, the caller didn't
737 if (rightmost && defParm->next)
739 werror (E_TOO_FEW_PARMS);
744 /* the parameter type must be at least castable */
745 if (compareType (defParm->type, actParm->ftype) == 0) {
746 werror (E_INCOMPAT_TYPES);
747 printFromToType (actParm->ftype, defParm->type);
751 /* if the parameter is castable then add the cast */
752 if (compareType (defParm->type, actParm->ftype) < 0)
754 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
756 /* now change the current one to a cast */
757 actParm->type = EX_OP;
758 actParm->opval.op = CAST;
759 actParm->left = newAst_LINK (defParm->type);
760 actParm->right = pTree;
761 actParm->etype = defParm->etype;
762 actParm->ftype = defParm->type;
763 actParm->decorated=0; /* force typechecking */
764 decorateType (actParm);
767 /* make a copy and change the regparm type to the defined parm */
768 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
769 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
770 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
774 /*-----------------------------------------------------------------*/
775 /* createIvalType - generates ival for basic types */
776 /*-----------------------------------------------------------------*/
778 createIvalType (ast * sym, sym_link * type, initList * ilist)
782 /* if initList is deep */
783 if (ilist->type == INIT_DEEP)
784 ilist = ilist->init.deep;
786 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
787 return decorateType (newNode ('=', sym, iExpr));
790 /*-----------------------------------------------------------------*/
791 /* createIvalStruct - generates initial value for structures */
792 /*-----------------------------------------------------------------*/
794 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
801 sflds = SPEC_STRUCT (type)->fields;
802 if (ilist->type != INIT_DEEP)
804 werror (E_INIT_STRUCT, "");
808 iloop = ilist->init.deep;
810 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
812 /* if we have come to end */
816 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
817 lAst = decorateType (resolveSymbols (lAst));
818 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
822 werror (W_EXCESS_INITIALIZERS, "struct",
823 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
830 /*-----------------------------------------------------------------*/
831 /* createIvalArray - generates code for array initialization */
832 /*-----------------------------------------------------------------*/
834 createIvalArray (ast * sym, sym_link * type, initList * ilist)
838 int lcnt = 0, size = 0;
839 literalList *literalL;
841 /* take care of the special case */
842 /* array of characters can be init */
844 if (IS_CHAR (type->next))
845 if ((rast = createIvalCharPtr (sym,
847 decorateType (resolveSymbols (list2expr (ilist))))))
849 return decorateType (resolveSymbols (rast));
851 /* not the special case */
852 if (ilist->type != INIT_DEEP)
854 werror (E_INIT_STRUCT, "");
858 iloop = ilist->init.deep;
859 lcnt = DCL_ELEM (type);
861 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
865 aSym = decorateType (resolveSymbols(sym));
867 rast = newNode(ARRAYINIT, aSym, NULL);
868 rast->values.constlist = literalL;
870 // Make sure size is set to length of initializer list.
877 if (lcnt && size > lcnt)
879 // Array size was specified, and we have more initializers than needed.
880 char *name=sym->opval.val->sym->name;
881 int lineno=sym->opval.val->sym->lineDef;
883 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
892 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
893 aSym = decorateType (resolveSymbols (aSym));
894 rast = createIval (aSym, type->next, iloop, rast);
895 iloop = (iloop ? iloop->next : NULL);
901 /* no of elements given and we */
902 /* have generated for all of them */
905 // there has to be a better way
906 char *name=sym->opval.val->sym->name;
907 int lineno=sym->opval.val->sym->lineDef;
908 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
915 /* if we have not been given a size */
916 if (!DCL_ELEM (type))
918 DCL_ELEM (type) = size;
921 return decorateType (resolveSymbols (rast));
925 /*-----------------------------------------------------------------*/
926 /* createIvalCharPtr - generates initial values for char pointers */
927 /*-----------------------------------------------------------------*/
929 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
933 /* if this is a pointer & right is a literal array then */
934 /* just assignment will do */
935 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
936 SPEC_SCLS (iexpr->etype) == S_CODE)
937 && IS_ARRAY (iexpr->ftype)))
938 return newNode ('=', sym, iexpr);
940 /* left side is an array so we have to assign each */
942 if ((IS_LITERAL (iexpr->etype) ||
943 SPEC_SCLS (iexpr->etype) == S_CODE)
944 && IS_ARRAY (iexpr->ftype))
946 /* for each character generate an assignment */
947 /* to the array element */
948 char *s = SPEC_CVAL (iexpr->etype).v_char;
953 rast = newNode (NULLOP,
957 newAst_VALUE (valueFromLit ((float) i))),
958 newAst_VALUE (valueFromLit (*s))));
962 rast = newNode (NULLOP,
966 newAst_VALUE (valueFromLit ((float) i))),
967 newAst_VALUE (valueFromLit (*s))));
969 return decorateType (resolveSymbols (rast));
975 /*-----------------------------------------------------------------*/
976 /* createIvalPtr - generates initial value for pointers */
977 /*-----------------------------------------------------------------*/
979 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
985 if (ilist->type == INIT_DEEP)
986 ilist = ilist->init.deep;
988 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
990 /* if character pointer */
991 if (IS_CHAR (type->next))
992 if ((rast = createIvalCharPtr (sym, type, iexpr)))
995 return newNode ('=', sym, iexpr);
998 /*-----------------------------------------------------------------*/
999 /* createIval - generates code for initial value */
1000 /*-----------------------------------------------------------------*/
1002 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1009 /* if structure then */
1010 if (IS_STRUCT (type))
1011 rast = createIvalStruct (sym, type, ilist);
1013 /* if this is a pointer */
1015 rast = createIvalPtr (sym, type, ilist);
1017 /* if this is an array */
1018 if (IS_ARRAY (type))
1019 rast = createIvalArray (sym, type, ilist);
1021 /* if type is SPECIFIER */
1023 rast = createIvalType (sym, type, ilist);
1026 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1028 return decorateType (resolveSymbols (rast));
1031 /*-----------------------------------------------------------------*/
1032 /* initAggregates - initialises aggregate variables with initv */
1033 /*-----------------------------------------------------------------*/
1034 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1035 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1038 /*-----------------------------------------------------------------*/
1039 /* gatherAutoInit - creates assignment expressions for initial */
1041 /*-----------------------------------------------------------------*/
1043 gatherAutoInit (symbol * autoChain)
1050 for (sym = autoChain; sym; sym = sym->next)
1053 /* resolve the symbols in the ival */
1056 resolveIvalSym (sym->ival);
1060 /* if this is a static variable & has an */
1061 /* initial value the code needs to be lifted */
1062 /* here to the main portion since they can be */
1063 /* initialised only once at the start */
1064 if (IS_STATIC (sym->etype) && sym->ival &&
1065 SPEC_SCLS (sym->etype) != S_CODE)
1069 /* insert the symbol into the symbol table */
1070 /* with level = 0 & name = rname */
1071 newSym = copySymbol (sym);
1072 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1074 /* now lift the code to main */
1075 if (IS_AGGREGATE (sym->type)) {
1076 work = initAggregates (sym, sym->ival, NULL);
1078 if (getNelements(sym->type, sym->ival)>1) {
1079 werror (W_EXCESS_INITIALIZERS, "scalar",
1080 sym->name, sym->lineDef);
1082 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1083 list2expr (sym->ival));
1086 setAstLineno (work, sym->lineDef);
1090 staticAutos = newNode (NULLOP, staticAutos, work);
1097 /* if there is an initial value */
1098 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1100 initList *ilist=sym->ival;
1102 while (ilist->type == INIT_DEEP) {
1103 ilist = ilist->init.deep;
1106 /* update lineno for error msg */
1107 lineno=sym->lineDef;
1108 setAstLineno (ilist->init.node, lineno);
1110 if (IS_AGGREGATE (sym->type)) {
1111 work = initAggregates (sym, sym->ival, NULL);
1113 if (getNelements(sym->type, sym->ival)>1) {
1114 werror (W_EXCESS_INITIALIZERS, "scalar",
1115 sym->name, sym->lineDef);
1117 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1118 list2expr (sym->ival));
1122 setAstLineno (work, sym->lineDef);
1126 init = newNode (NULLOP, init, work);
1135 /*-----------------------------------------------------------------*/
1136 /* stringToSymbol - creates a symbol from a literal string */
1137 /*-----------------------------------------------------------------*/
1139 stringToSymbol (value * val)
1141 char name[SDCC_NAME_MAX + 1];
1142 static int charLbl = 0;
1145 sprintf (name, "_str_%d", charLbl++);
1146 sym = newSymbol (name, 0); /* make it @ level 0 */
1147 strcpy (sym->rname, name);
1149 /* copy the type from the value passed */
1150 sym->type = copyLinkChain (val->type);
1151 sym->etype = getSpec (sym->type);
1152 /* change to storage class & output class */
1153 SPEC_SCLS (sym->etype) = S_CODE;
1154 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1155 SPEC_STAT (sym->etype) = 1;
1156 /* make the level & block = 0 */
1157 sym->block = sym->level = 0;
1159 /* create an ival */
1160 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1165 allocVariables (sym);
1168 return symbolVal (sym);
1172 /*-----------------------------------------------------------------*/
1173 /* processBlockVars - will go thru the ast looking for block if */
1174 /* a block is found then will allocate the syms */
1175 /* will also gather the auto inits present */
1176 /*-----------------------------------------------------------------*/
1178 processBlockVars (ast * tree, int *stack, int action)
1183 /* if this is a block */
1184 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1188 if (action == ALLOCATE)
1190 *stack += allocVariables (tree->values.sym);
1191 autoInit = gatherAutoInit (tree->values.sym);
1193 /* if there are auto inits then do them */
1195 tree->left = newNode (NULLOP, autoInit, tree->left);
1197 else /* action is deallocate */
1198 deallocLocal (tree->values.sym);
1201 processBlockVars (tree->left, stack, action);
1202 processBlockVars (tree->right, stack, action);
1206 /*-------------------------------------------------------------*/
1207 /* constExprTree - returns TRUE if this tree is a constant */
1209 /*-------------------------------------------------------------*/
1210 bool constExprTree (ast *cexpr) {
1216 cexpr = decorateType (resolveSymbols (cexpr));
1218 switch (cexpr->type)
1221 if (IS_AST_LIT_VALUE(cexpr)) {
1222 // this is a literal
1225 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1226 // a function's address will never change
1229 if (IS_AST_SYM_VALUE(cexpr) &&
1230 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1231 // a symbol in code space will never change
1232 // This is only for the 'char *s="hallo"' case and will have to leave
1237 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1238 "unexpected link in expression tree\n");
1241 if (cexpr->opval.op==ARRAYINIT) {
1242 // this is a list of literals
1245 if (cexpr->opval.op=='=') {
1246 return constExprTree(cexpr->right);
1248 if (cexpr->opval.op==CAST) {
1249 // jwk: cast ignored, maybe we should throw a warning here
1250 return constExprTree(cexpr->right);
1252 if (cexpr->opval.op=='&') {
1255 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1258 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1265 /*-----------------------------------------------------------------*/
1266 /* constExprValue - returns the value of a constant expression */
1267 /* or NULL if it is not a constant expression */
1268 /*-----------------------------------------------------------------*/
1270 constExprValue (ast * cexpr, int check)
1272 cexpr = decorateType (resolveSymbols (cexpr));
1274 /* if this is not a constant then */
1275 if (!IS_LITERAL (cexpr->ftype))
1277 /* then check if this is a literal array
1279 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1280 SPEC_CVAL (cexpr->etype).v_char &&
1281 IS_ARRAY (cexpr->ftype))
1283 value *val = valFromType (cexpr->ftype);
1284 SPEC_SCLS (val->etype) = S_LITERAL;
1285 val->sym = cexpr->opval.val->sym;
1286 val->sym->type = copyLinkChain (cexpr->ftype);
1287 val->sym->etype = getSpec (val->sym->type);
1288 strcpy (val->name, cexpr->opval.val->sym->rname);
1292 /* if we are casting a literal value then */
1293 if (IS_AST_OP (cexpr) &&
1294 cexpr->opval.op == CAST &&
1295 IS_LITERAL (cexpr->right->ftype))
1296 return valCastLiteral (cexpr->ftype,
1297 floatFromVal (cexpr->right->opval.val));
1299 if (IS_AST_VALUE (cexpr))
1300 return cexpr->opval.val;
1303 werror (E_CONST_EXPECTED, "found expression");
1308 /* return the value */
1309 return cexpr->opval.val;
1313 /*-----------------------------------------------------------------*/
1314 /* isLabelInAst - will return true if a given label is found */
1315 /*-----------------------------------------------------------------*/
1317 isLabelInAst (symbol * label, ast * tree)
1319 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1322 if (IS_AST_OP (tree) &&
1323 tree->opval.op == LABEL &&
1324 isSymbolEqual (AST_SYMBOL (tree->left), label))
1327 return isLabelInAst (label, tree->right) &&
1328 isLabelInAst (label, tree->left);
1332 /*-----------------------------------------------------------------*/
1333 /* isLoopCountable - return true if the loop count can be determi- */
1334 /* -ned at compile time . */
1335 /*-----------------------------------------------------------------*/
1337 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1338 symbol ** sym, ast ** init, ast ** end)
1341 /* the loop is considered countable if the following
1342 conditions are true :-
1344 a) initExpr :- <sym> = <const>
1345 b) condExpr :- <sym> < <const1>
1346 c) loopExpr :- <sym> ++
1349 /* first check the initExpr */
1350 if (IS_AST_OP (initExpr) &&
1351 initExpr->opval.op == '=' && /* is assignment */
1352 IS_AST_SYM_VALUE (initExpr->left))
1353 { /* left is a symbol */
1355 *sym = AST_SYMBOL (initExpr->left);
1356 *init = initExpr->right;
1361 /* for now the symbol has to be of
1363 if (!IS_INTEGRAL ((*sym)->type))
1366 /* now check condExpr */
1367 if (IS_AST_OP (condExpr))
1370 switch (condExpr->opval.op)
1373 if (IS_AST_SYM_VALUE (condExpr->left) &&
1374 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1375 IS_AST_LIT_VALUE (condExpr->right))
1377 *end = condExpr->right;
1383 if (IS_AST_OP (condExpr->left) &&
1384 condExpr->left->opval.op == '>' &&
1385 IS_AST_LIT_VALUE (condExpr->left->right) &&
1386 IS_AST_SYM_VALUE (condExpr->left->left) &&
1387 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1390 *end = newNode ('+', condExpr->left->right,
1391 newAst_VALUE (constVal ("1")));
1402 /* check loop expression is of the form <sym>++ */
1403 if (!IS_AST_OP (loopExpr))
1406 /* check if <sym> ++ */
1407 if (loopExpr->opval.op == INC_OP)
1413 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1414 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1421 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1422 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1430 if (loopExpr->opval.op == ADD_ASSIGN)
1433 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1434 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1435 IS_AST_LIT_VALUE (loopExpr->right) &&
1436 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1444 /*-----------------------------------------------------------------*/
1445 /* astHasVolatile - returns true if ast contains any volatile */
1446 /*-----------------------------------------------------------------*/
1448 astHasVolatile (ast * tree)
1453 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1456 if (IS_AST_OP (tree))
1457 return astHasVolatile (tree->left) ||
1458 astHasVolatile (tree->right);
1463 /*-----------------------------------------------------------------*/
1464 /* astHasPointer - return true if the ast contains any ptr variable */
1465 /*-----------------------------------------------------------------*/
1467 astHasPointer (ast * tree)
1472 if (IS_AST_LINK (tree))
1475 /* if we hit an array expression then check
1476 only the left side */
1477 if (IS_AST_OP (tree) && tree->opval.op == '[')
1478 return astHasPointer (tree->left);
1480 if (IS_AST_VALUE (tree))
1481 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1483 return astHasPointer (tree->left) ||
1484 astHasPointer (tree->right);
1488 /*-----------------------------------------------------------------*/
1489 /* astHasSymbol - return true if the ast has the given symbol */
1490 /*-----------------------------------------------------------------*/
1492 astHasSymbol (ast * tree, symbol * sym)
1494 if (!tree || IS_AST_LINK (tree))
1497 if (IS_AST_VALUE (tree))
1499 if (IS_AST_SYM_VALUE (tree))
1500 return isSymbolEqual (AST_SYMBOL (tree), sym);
1505 return astHasSymbol (tree->left, sym) ||
1506 astHasSymbol (tree->right, sym);
1509 /*-----------------------------------------------------------------*/
1510 /* astHasDeref - return true if the ast has an indirect access */
1511 /*-----------------------------------------------------------------*/
1513 astHasDeref (ast * tree)
1515 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1518 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1520 return astHasDeref (tree->left) || astHasDeref (tree->right);
1523 /*-----------------------------------------------------------------*/
1524 /* isConformingBody - the loop body has to conform to a set of rules */
1525 /* for the loop to be considered reversible read on for rules */
1526 /*-----------------------------------------------------------------*/
1528 isConformingBody (ast * pbody, symbol * sym, ast * body)
1531 /* we are going to do a pre-order traversal of the
1532 tree && check for the following conditions. (essentially
1533 a set of very shallow tests )
1534 a) the sym passed does not participate in
1535 any arithmetic operation
1536 b) There are no function calls
1537 c) all jumps are within the body
1538 d) address of loop control variable not taken
1539 e) if an assignment has a pointer on the
1540 left hand side make sure right does not have
1541 loop control variable */
1543 /* if we reach the end or a leaf then true */
1544 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1547 /* if anything else is "volatile" */
1548 if (IS_VOLATILE (TETYPE (pbody)))
1551 /* we will walk the body in a pre-order traversal for
1553 switch (pbody->opval.op)
1555 /*------------------------------------------------------------------*/
1557 // if the loopvar is used as an index
1558 if (astHasSymbol(pbody->right, sym)) {
1561 return isConformingBody (pbody->right, sym, body);
1563 /*------------------------------------------------------------------*/
1568 /*------------------------------------------------------------------*/
1569 case INC_OP: /* incerement operator unary so left only */
1572 /* sure we are not sym is not modified */
1574 IS_AST_SYM_VALUE (pbody->left) &&
1575 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1579 IS_AST_SYM_VALUE (pbody->right) &&
1580 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1585 /*------------------------------------------------------------------*/
1587 case '*': /* can be unary : if right is null then unary operation */
1592 /* if right is NULL then unary operation */
1593 /*------------------------------------------------------------------*/
1594 /*----------------------------*/
1596 /*----------------------------*/
1599 if (IS_AST_SYM_VALUE (pbody->left) &&
1600 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1603 return isConformingBody (pbody->left, sym, body);
1607 if (astHasSymbol (pbody->left, sym) ||
1608 astHasSymbol (pbody->right, sym))
1613 /*------------------------------------------------------------------*/
1621 if (IS_AST_SYM_VALUE (pbody->left) &&
1622 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1625 if (IS_AST_SYM_VALUE (pbody->right) &&
1626 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1629 return isConformingBody (pbody->left, sym, body) &&
1630 isConformingBody (pbody->right, sym, body);
1637 if (IS_AST_SYM_VALUE (pbody->left) &&
1638 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1640 return isConformingBody (pbody->left, sym, body);
1642 /*------------------------------------------------------------------*/
1654 case SIZEOF: /* evaluate wihout code generation */
1656 return isConformingBody (pbody->left, sym, body) &&
1657 isConformingBody (pbody->right, sym, body);
1659 /*------------------------------------------------------------------*/
1662 /* if left has a pointer & right has loop
1663 control variable then we cannot */
1664 if (astHasPointer (pbody->left) &&
1665 astHasSymbol (pbody->right, sym))
1667 if (astHasVolatile (pbody->left))
1670 if (IS_AST_SYM_VALUE (pbody->left)) {
1671 // if the loopvar has an assignment
1672 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1674 // if the loopvar is used in another (maybe conditional) block
1675 if (astHasSymbol (pbody->right, sym) &&
1676 (pbody->level > body->level)) {
1681 if (astHasVolatile (pbody->left))
1684 if (astHasDeref(pbody->right)) return FALSE;
1686 return isConformingBody (pbody->left, sym, body) &&
1687 isConformingBody (pbody->right, sym, body);
1698 assert ("Parser should not have generated this\n");
1700 /*------------------------------------------------------------------*/
1701 /*----------------------------*/
1702 /* comma operator */
1703 /*----------------------------*/
1705 return isConformingBody (pbody->left, sym, body) &&
1706 isConformingBody (pbody->right, sym, body);
1708 /*------------------------------------------------------------------*/
1709 /*----------------------------*/
1711 /*----------------------------*/
1713 /* if local & not passed as paramater then ok */
1714 if (sym->level && !astHasSymbol(pbody->right,sym))
1718 /*------------------------------------------------------------------*/
1719 /*----------------------------*/
1720 /* return statement */
1721 /*----------------------------*/
1726 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1731 if (astHasSymbol (pbody->left, sym))
1738 return isConformingBody (pbody->left, sym, body) &&
1739 isConformingBody (pbody->right, sym, body);
1745 /*-----------------------------------------------------------------*/
1746 /* isLoopReversible - takes a for loop as input && returns true */
1747 /* if the for loop is reversible. If yes will set the value of */
1748 /* the loop control var & init value & termination value */
1749 /*-----------------------------------------------------------------*/
1751 isLoopReversible (ast * loop, symbol ** loopCntrl,
1752 ast ** init, ast ** end)
1754 /* if option says don't do it then don't */
1755 if (optimize.noLoopReverse)
1757 /* there are several tests to determine this */
1759 /* for loop has to be of the form
1760 for ( <sym> = <const1> ;
1761 [<sym> < <const2>] ;
1762 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1764 if (!isLoopCountable (AST_FOR (loop, initExpr),
1765 AST_FOR (loop, condExpr),
1766 AST_FOR (loop, loopExpr),
1767 loopCntrl, init, end))
1770 /* now do some serious checking on the body of the loop
1773 return isConformingBody (loop->left, *loopCntrl, loop->left);
1777 /*-----------------------------------------------------------------*/
1778 /* replLoopSym - replace the loop sym by loop sym -1 */
1779 /*-----------------------------------------------------------------*/
1781 replLoopSym (ast * body, symbol * sym)
1784 if (!body || IS_AST_LINK (body))
1787 if (IS_AST_SYM_VALUE (body))
1790 if (isSymbolEqual (AST_SYMBOL (body), sym))
1794 body->opval.op = '-';
1795 body->left = newAst_VALUE (symbolVal (sym));
1796 body->right = newAst_VALUE (constVal ("1"));
1804 replLoopSym (body->left, sym);
1805 replLoopSym (body->right, sym);
1809 /*-----------------------------------------------------------------*/
1810 /* reverseLoop - do the actual loop reversal */
1811 /*-----------------------------------------------------------------*/
1813 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1817 /* create the following tree
1822 if (sym) goto for_continue ;
1825 /* put it together piece by piece */
1826 rloop = newNode (NULLOP,
1827 createIf (newAst_VALUE (symbolVal (sym)),
1829 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1832 newAst_VALUE (symbolVal (sym)),
1835 replLoopSym (loop->left, sym);
1836 setAstLineno (rloop, init->lineno);
1838 rloop = newNode (NULLOP,
1840 newAst_VALUE (symbolVal (sym)),
1841 newNode ('-', end, init)),
1842 createLabel (AST_FOR (loop, continueLabel),
1846 newNode (SUB_ASSIGN,
1847 newAst_VALUE (symbolVal (sym)),
1848 newAst_VALUE (constVal ("1"))),
1851 rloop->lineno=init->lineno;
1852 return decorateType (rloop);
1856 /*-----------------------------------------------------------------*/
1857 /* decorateType - compute type for this tree also does type cheking */
1858 /* this is done bottom up, since type have to flow upwards */
1859 /* it also does constant folding, and paramater checking */
1860 /*-----------------------------------------------------------------*/
1862 decorateType (ast * tree)
1870 /* if already has type then do nothing */
1871 if (tree->decorated)
1874 tree->decorated = 1;
1877 /* print the line */
1878 /* if not block & function */
1879 if (tree->type == EX_OP &&
1880 (tree->opval.op != FUNCTION &&
1881 tree->opval.op != BLOCK &&
1882 tree->opval.op != NULLOP))
1884 filename = tree->filename;
1885 lineno = tree->lineno;
1889 /* if any child is an error | this one is an error do nothing */
1890 if (tree->isError ||
1891 (tree->left && tree->left->isError) ||
1892 (tree->right && tree->right->isError))
1895 /*------------------------------------------------------------------*/
1896 /*----------------------------*/
1897 /* leaf has been reached */
1898 /*----------------------------*/
1899 lineno=tree->lineno;
1900 /* if this is of type value */
1901 /* just get the type */
1902 if (tree->type == EX_VALUE)
1905 if (IS_LITERAL (tree->opval.val->etype))
1908 /* if this is a character array then declare it */
1909 if (IS_ARRAY (tree->opval.val->type))
1910 tree->opval.val = stringToSymbol (tree->opval.val);
1912 /* otherwise just copy the type information */
1913 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1917 if (tree->opval.val->sym)
1919 /* if the undefined flag is set then give error message */
1920 if (tree->opval.val->sym->undefined)
1922 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1924 TTYPE (tree) = TETYPE (tree) =
1925 tree->opval.val->type = tree->opval.val->sym->type =
1926 tree->opval.val->etype = tree->opval.val->sym->etype =
1927 copyLinkChain (INTTYPE);
1932 /* if impilicit i.e. struct/union member then no type */
1933 if (tree->opval.val->sym->implicit)
1934 TTYPE (tree) = TETYPE (tree) = NULL;
1939 /* else copy the type */
1940 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1942 /* and mark it as referenced */
1943 tree->opval.val->sym->isref = 1;
1951 /* if type link for the case of cast */
1952 if (tree->type == EX_LINK)
1954 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1961 dtl = decorateType (tree->left);
1962 /* delay right side for '?' operator since conditional macro expansions might
1964 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1966 /* this is to take care of situations
1967 when the tree gets rewritten */
1968 if (dtl != tree->left)
1970 if (dtr != tree->right)
1973 if (IS_AST_OP(tree) &&
1974 (tree->opval.op == CAST || tree->opval.op == '=') &&
1975 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
1976 (getSize(RTYPE(tree)) < INTSIZE)) {
1977 // this is a cast/assign to a bigger type
1978 if (IS_AST_OP(tree->right) &&
1979 IS_INTEGRAL(tree->right->ftype) &&
1980 (tree->right->opval.op == LEFT_OP ||
1981 tree->right->opval.op == '*' ||
1982 tree->right->opval.op == '+' ||
1983 tree->right->opval.op == '-') &&
1984 tree->right->right) {
1985 // we should cast an operand instead of the result
1986 tree->right->decorated = 0;
1987 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
1989 tree->right = decorateType(tree->right);
1994 /* depending on type of operator do */
1996 switch (tree->opval.op)
1998 /*------------------------------------------------------------------*/
1999 /*----------------------------*/
2001 /*----------------------------*/
2004 /* determine which is the array & which the index */
2005 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2008 ast *tempTree = tree->left;
2009 tree->left = tree->right;
2010 tree->right = tempTree;
2013 /* first check if this is a array or a pointer */
2014 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2016 werror (E_NEED_ARRAY_PTR, "[]");
2017 goto errorTreeReturn;
2020 /* check if the type of the idx */
2021 if (!IS_INTEGRAL (RTYPE (tree)))
2023 werror (E_IDX_NOT_INT);
2024 goto errorTreeReturn;
2027 /* if the left is an rvalue then error */
2030 werror (E_LVALUE_REQUIRED, "array access");
2031 goto errorTreeReturn;
2034 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2035 if (IS_PTR(LTYPE(tree))) {
2036 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2040 /*------------------------------------------------------------------*/
2041 /*----------------------------*/
2043 /*----------------------------*/
2045 /* if this is not a structure */
2046 if (!IS_STRUCT (LTYPE (tree)))
2048 werror (E_STRUCT_UNION, ".");
2049 goto errorTreeReturn;
2051 TTYPE (tree) = structElemType (LTYPE (tree),
2052 (tree->right->type == EX_VALUE ?
2053 tree->right->opval.val : NULL));
2054 TETYPE (tree) = getSpec (TTYPE (tree));
2057 /*------------------------------------------------------------------*/
2058 /*----------------------------*/
2059 /* struct/union pointer */
2060 /*----------------------------*/
2062 /* if not pointer to a structure */
2063 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2065 werror (E_PTR_REQD);
2066 goto errorTreeReturn;
2069 if (!IS_STRUCT (LTYPE (tree)->next))
2071 werror (E_STRUCT_UNION, "->");
2072 goto errorTreeReturn;
2075 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2076 (tree->right->type == EX_VALUE ?
2077 tree->right->opval.val : NULL));
2078 TETYPE (tree) = getSpec (TTYPE (tree));
2080 /* adjust the storage class */
2081 switch (DCL_TYPE(tree->left->ftype)) {
2085 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2088 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2093 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2096 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2099 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2109 /*------------------------------------------------------------------*/
2110 /*----------------------------*/
2111 /* ++/-- operation */
2112 /*----------------------------*/
2113 case INC_OP: /* incerement operator unary so left only */
2116 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2117 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2118 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2119 werror (E_CODE_WRITE, "++/--");
2128 /*------------------------------------------------------------------*/
2129 /*----------------------------*/
2131 /*----------------------------*/
2132 case '&': /* can be unary */
2133 /* if right is NULL then unary operation */
2134 if (tree->right) /* not an unary operation */
2137 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2139 werror (E_BITWISE_OP);
2140 werror (W_CONTINUE, "left & right types are ");
2141 printTypeChain (LTYPE (tree), stderr);
2142 fprintf (stderr, ",");
2143 printTypeChain (RTYPE (tree), stderr);
2144 fprintf (stderr, "\n");
2145 goto errorTreeReturn;
2148 /* if they are both literal */
2149 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2151 tree->type = EX_VALUE;
2152 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2153 valFromType (RETYPE (tree)), '&');
2155 tree->right = tree->left = NULL;
2156 TETYPE (tree) = tree->opval.val->etype;
2157 TTYPE (tree) = tree->opval.val->type;
2161 /* see if this is a GETHBIT operation if yes
2164 ast *otree = optimizeGetHbit (tree);
2167 return decorateType (otree);
2171 computeType (LTYPE (tree), RTYPE (tree));
2172 TETYPE (tree) = getSpec (TTYPE (tree));
2174 LRVAL (tree) = RRVAL (tree) = 1;
2178 /*------------------------------------------------------------------*/
2179 /*----------------------------*/
2181 /*----------------------------*/
2183 p->class = DECLARATOR;
2184 /* if bit field then error */
2185 if (IS_BITVAR (tree->left->etype))
2187 werror (E_ILLEGAL_ADDR, "address of bit variable");
2188 goto errorTreeReturn;
2191 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2193 werror (E_ILLEGAL_ADDR, "address of register variable");
2194 goto errorTreeReturn;
2197 if (IS_FUNC (LTYPE (tree)))
2199 // this ought to be ignored
2200 return (tree->left);
2203 if (IS_LITERAL(LTYPE(tree)))
2205 werror (E_ILLEGAL_ADDR, "address of literal");
2206 goto errorTreeReturn;
2211 werror (E_LVALUE_REQUIRED, "address of");
2212 goto errorTreeReturn;
2214 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2216 DCL_TYPE (p) = CPOINTER;
2217 DCL_PTR_CONST (p) = port->mem.code_ro;
2219 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2220 DCL_TYPE (p) = FPOINTER;
2221 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2222 DCL_TYPE (p) = PPOINTER;
2223 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2224 DCL_TYPE (p) = IPOINTER;
2225 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2226 DCL_TYPE (p) = EEPPOINTER;
2227 else if (SPEC_OCLS(tree->left->etype))
2228 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2230 DCL_TYPE (p) = POINTER;
2232 if (IS_AST_SYM_VALUE (tree->left))
2234 AST_SYMBOL (tree->left)->addrtaken = 1;
2235 AST_SYMBOL (tree->left)->allocreq = 1;
2238 p->next = LTYPE (tree);
2240 TETYPE (tree) = getSpec (TTYPE (tree));
2241 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2242 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2247 /*------------------------------------------------------------------*/
2248 /*----------------------------*/
2250 /*----------------------------*/
2252 /* if the rewrite succeeds then don't go any furthur */
2254 ast *wtree = optimizeRRCRLC (tree);
2256 return decorateType (wtree);
2258 /*------------------------------------------------------------------*/
2259 /*----------------------------*/
2261 /*----------------------------*/
2263 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2265 werror (E_BITWISE_OP);
2266 werror (W_CONTINUE, "left & right types are ");
2267 printTypeChain (LTYPE (tree), stderr);
2268 fprintf (stderr, ",");
2269 printTypeChain (RTYPE (tree), stderr);
2270 fprintf (stderr, "\n");
2271 goto errorTreeReturn;
2274 /* if they are both literal then */
2275 /* rewrite the tree */
2276 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2278 tree->type = EX_VALUE;
2279 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2280 valFromType (RETYPE (tree)),
2282 tree->right = tree->left = NULL;
2283 TETYPE (tree) = tree->opval.val->etype;
2284 TTYPE (tree) = tree->opval.val->type;
2287 LRVAL (tree) = RRVAL (tree) = 1;
2288 TETYPE (tree) = getSpec (TTYPE (tree) =
2289 computeType (LTYPE (tree),
2292 /*------------------------------------------------------------------*/
2293 /*----------------------------*/
2295 /*----------------------------*/
2297 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2299 werror (E_INVALID_OP, "divide");
2300 goto errorTreeReturn;
2302 /* if they are both literal then */
2303 /* rewrite the tree */
2304 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2306 tree->type = EX_VALUE;
2307 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2308 valFromType (RETYPE (tree)));
2309 tree->right = tree->left = NULL;
2310 TETYPE (tree) = getSpec (TTYPE (tree) =
2311 tree->opval.val->type);
2314 LRVAL (tree) = RRVAL (tree) = 1;
2315 TETYPE (tree) = getSpec (TTYPE (tree) =
2316 computeType (LTYPE (tree),
2320 /*------------------------------------------------------------------*/
2321 /*----------------------------*/
2323 /*----------------------------*/
2325 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2327 werror (E_BITWISE_OP);
2328 werror (W_CONTINUE, "left & right types are ");
2329 printTypeChain (LTYPE (tree), stderr);
2330 fprintf (stderr, ",");
2331 printTypeChain (RTYPE (tree), stderr);
2332 fprintf (stderr, "\n");
2333 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 = valMod (valFromType (LETYPE (tree)),
2341 valFromType (RETYPE (tree)));
2342 tree->right = tree->left = NULL;
2343 TETYPE (tree) = getSpec (TTYPE (tree) =
2344 tree->opval.val->type);
2347 LRVAL (tree) = RRVAL (tree) = 1;
2348 TETYPE (tree) = getSpec (TTYPE (tree) =
2349 computeType (LTYPE (tree),
2353 /*------------------------------------------------------------------*/
2354 /*----------------------------*/
2355 /* address dereference */
2356 /*----------------------------*/
2357 case '*': /* can be unary : if right is null then unary operation */
2360 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2362 werror (E_PTR_REQD);
2363 goto errorTreeReturn;
2368 werror (E_LVALUE_REQUIRED, "pointer deref");
2369 goto errorTreeReturn;
2371 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2372 LTYPE (tree)->next : NULL);
2373 TETYPE (tree) = getSpec (TTYPE (tree));
2374 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2378 /*------------------------------------------------------------------*/
2379 /*----------------------------*/
2380 /* multiplication */
2381 /*----------------------------*/
2382 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2384 werror (E_INVALID_OP, "multiplication");
2385 goto errorTreeReturn;
2388 /* if they are both literal then */
2389 /* rewrite the tree */
2390 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2392 tree->type = EX_VALUE;
2393 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2394 valFromType (RETYPE (tree)));
2395 tree->right = tree->left = NULL;
2396 TETYPE (tree) = getSpec (TTYPE (tree) =
2397 tree->opval.val->type);
2401 /* if left is a literal exchange left & right */
2402 if (IS_LITERAL (LTYPE (tree)))
2404 ast *tTree = tree->left;
2405 tree->left = tree->right;
2406 tree->right = tTree;
2409 LRVAL (tree) = RRVAL (tree) = 1;
2410 TETYPE (tree) = getSpec (TTYPE (tree) =
2411 computeType (LTYPE (tree),
2414 /* promote result to int if left & right are char
2415 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2416 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2417 SPEC_NOUN(TETYPE(tree)) = V_INT;
2422 /*------------------------------------------------------------------*/
2423 /*----------------------------*/
2424 /* unary '+' operator */
2425 /*----------------------------*/
2430 if (!IS_INTEGRAL (LTYPE (tree)))
2432 werror (E_UNARY_OP, '+');
2433 goto errorTreeReturn;
2436 /* if left is a literal then do it */
2437 if (IS_LITERAL (LTYPE (tree)))
2439 tree->type = EX_VALUE;
2440 tree->opval.val = valFromType (LETYPE (tree));
2442 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2446 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2450 /*------------------------------------------------------------------*/
2451 /*----------------------------*/
2453 /*----------------------------*/
2455 /* this is not a unary operation */
2456 /* if both pointers then problem */
2457 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2458 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2460 werror (E_PTR_PLUS_PTR);
2461 goto errorTreeReturn;
2464 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2465 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2467 werror (E_PLUS_INVALID, "+");
2468 goto errorTreeReturn;
2471 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2472 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2474 werror (E_PLUS_INVALID, "+");
2475 goto errorTreeReturn;
2477 /* if they are both literal then */
2478 /* rewrite the tree */
2479 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2481 tree->type = EX_VALUE;
2482 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2483 valFromType (RETYPE (tree)));
2484 tree->right = tree->left = NULL;
2485 TETYPE (tree) = getSpec (TTYPE (tree) =
2486 tree->opval.val->type);
2490 /* if the right is a pointer or left is a literal
2491 xchange left & right */
2492 if (IS_ARRAY (RTYPE (tree)) ||
2493 IS_PTR (RTYPE (tree)) ||
2494 IS_LITERAL (LTYPE (tree)))
2496 ast *tTree = tree->left;
2497 tree->left = tree->right;
2498 tree->right = tTree;
2501 LRVAL (tree) = RRVAL (tree) = 1;
2502 /* if the left is a pointer */
2503 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2504 TETYPE (tree) = getSpec (TTYPE (tree) =
2507 TETYPE (tree) = getSpec (TTYPE (tree) =
2508 computeType (LTYPE (tree),
2512 /*------------------------------------------------------------------*/
2513 /*----------------------------*/
2515 /*----------------------------*/
2516 case '-': /* can be unary */
2517 /* if right is null then unary */
2521 if (!IS_ARITHMETIC (LTYPE (tree)))
2523 werror (E_UNARY_OP, tree->opval.op);
2524 goto errorTreeReturn;
2527 /* if left is a literal then do it */
2528 if (IS_LITERAL (LTYPE (tree)))
2530 tree->type = EX_VALUE;
2531 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2533 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2534 SPEC_USIGN(TETYPE(tree)) = 0;
2538 TTYPE (tree) = LTYPE (tree);
2542 /*------------------------------------------------------------------*/
2543 /*----------------------------*/
2545 /*----------------------------*/
2547 if (!(IS_PTR (LTYPE (tree)) ||
2548 IS_ARRAY (LTYPE (tree)) ||
2549 IS_ARITHMETIC (LTYPE (tree))))
2551 werror (E_PLUS_INVALID, "-");
2552 goto errorTreeReturn;
2555 if (!(IS_PTR (RTYPE (tree)) ||
2556 IS_ARRAY (RTYPE (tree)) ||
2557 IS_ARITHMETIC (RTYPE (tree))))
2559 werror (E_PLUS_INVALID, "-");
2560 goto errorTreeReturn;
2563 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2564 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2565 IS_INTEGRAL (RTYPE (tree))))
2567 werror (E_PLUS_INVALID, "-");
2568 goto errorTreeReturn;
2571 /* if they are both literal then */
2572 /* rewrite the tree */
2573 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2575 tree->type = EX_VALUE;
2576 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2577 valFromType (RETYPE (tree)));
2578 tree->right = tree->left = NULL;
2579 TETYPE (tree) = getSpec (TTYPE (tree) =
2580 tree->opval.val->type);
2584 /* if the left & right are equal then zero */
2585 if (isAstEqual (tree->left, tree->right))
2587 tree->type = EX_VALUE;
2588 tree->left = tree->right = NULL;
2589 tree->opval.val = constVal ("0");
2590 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2594 /* if both of them are pointers or arrays then */
2595 /* the result is going to be an integer */
2596 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2597 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2598 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2600 /* if only the left is a pointer */
2601 /* then result is a pointer */
2602 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2603 TETYPE (tree) = getSpec (TTYPE (tree) =
2606 TETYPE (tree) = getSpec (TTYPE (tree) =
2607 computeType (LTYPE (tree),
2609 LRVAL (tree) = RRVAL (tree) = 1;
2612 /*------------------------------------------------------------------*/
2613 /*----------------------------*/
2615 /*----------------------------*/
2617 /* can be only integral type */
2618 if (!IS_INTEGRAL (LTYPE (tree)))
2620 werror (E_UNARY_OP, tree->opval.op);
2621 goto errorTreeReturn;
2624 /* if left is a literal then do it */
2625 if (IS_LITERAL (LTYPE (tree)))
2627 tree->type = EX_VALUE;
2628 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2630 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2634 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2637 /*------------------------------------------------------------------*/
2638 /*----------------------------*/
2640 /*----------------------------*/
2642 /* can be pointer */
2643 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2644 !IS_PTR (LTYPE (tree)) &&
2645 !IS_ARRAY (LTYPE (tree)))
2647 werror (E_UNARY_OP, tree->opval.op);
2648 goto errorTreeReturn;
2651 /* if left is a literal then do it */
2652 if (IS_LITERAL (LTYPE (tree)))
2654 tree->type = EX_VALUE;
2655 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2657 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2661 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2664 /*------------------------------------------------------------------*/
2665 /*----------------------------*/
2667 /*----------------------------*/
2670 TTYPE (tree) = LTYPE (tree);
2671 TETYPE (tree) = LETYPE (tree);
2675 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2680 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2682 werror (E_SHIFT_OP_INVALID);
2683 werror (W_CONTINUE, "left & right types are ");
2684 printTypeChain (LTYPE (tree), stderr);
2685 fprintf (stderr, ",");
2686 printTypeChain (RTYPE (tree), stderr);
2687 fprintf (stderr, "\n");
2688 goto errorTreeReturn;
2691 /* if they are both literal then */
2692 /* rewrite the tree */
2693 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2695 tree->type = EX_VALUE;
2696 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2697 valFromType (RETYPE (tree)),
2698 (tree->opval.op == LEFT_OP ? 1 : 0));
2699 tree->right = tree->left = NULL;
2700 TETYPE (tree) = getSpec (TTYPE (tree) =
2701 tree->opval.val->type);
2705 /* if only the right side is a literal & we are
2706 shifting more than size of the left operand then zero */
2707 if (IS_LITERAL (RTYPE (tree)) &&
2708 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2709 (getSize (LTYPE (tree)) * 8))
2711 if (tree->opval.op==LEFT_OP ||
2712 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2713 lineno=tree->lineno;
2714 werror (W_SHIFT_CHANGED,
2715 (tree->opval.op == LEFT_OP ? "left" : "right"));
2716 tree->type = EX_VALUE;
2717 tree->left = tree->right = NULL;
2718 tree->opval.val = constVal ("0");
2719 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2723 LRVAL (tree) = RRVAL (tree) = 1;
2724 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2726 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2730 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2734 /*------------------------------------------------------------------*/
2735 /*----------------------------*/
2737 /*----------------------------*/
2738 case CAST: /* change the type */
2739 /* cannot cast to an aggregate type */
2740 if (IS_AGGREGATE (LTYPE (tree)))
2742 werror (E_CAST_ILLEGAL);
2743 goto errorTreeReturn;
2746 /* make sure the type is complete and sane */
2747 checkTypeSanity(LETYPE(tree), "(cast)");
2750 /* if the right is a literal replace the tree */
2751 if (IS_LITERAL (RETYPE (tree))) {
2752 if (!IS_PTR (LTYPE (tree))) {
2753 tree->type = EX_VALUE;
2755 valCastLiteral (LTYPE (tree),
2756 floatFromVal (valFromType (RETYPE (tree))));
2759 TTYPE (tree) = tree->opval.val->type;
2760 tree->values.literalFromCast = 1;
2761 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2762 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2763 sym_link *rest = LTYPE(tree)->next;
2764 werror(W_LITERAL_GENERIC);
2765 TTYPE(tree) = newLink();
2766 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2767 TTYPE(tree)->next = rest;
2768 tree->left->opval.lnk = TTYPE(tree);
2771 TTYPE (tree) = LTYPE (tree);
2775 TTYPE (tree) = LTYPE (tree);
2779 #if 0 // this is already checked, now this could be explicit
2780 /* if pointer to struct then check names */
2781 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2782 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2783 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2785 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2786 SPEC_STRUCT(LETYPE(tree))->tag);
2789 /* if the right is a literal replace the tree */
2790 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2791 tree->type = EX_VALUE;
2793 valCastLiteral (LTYPE (tree),
2794 floatFromVal (valFromType (RETYPE (tree))));
2797 TTYPE (tree) = tree->opval.val->type;
2798 tree->values.literalFromCast = 1;
2800 TTYPE (tree) = LTYPE (tree);
2804 TETYPE (tree) = getSpec (TTYPE (tree));
2808 /*------------------------------------------------------------------*/
2809 /*----------------------------*/
2810 /* logical &&, || */
2811 /*----------------------------*/
2814 /* each must me arithmetic type or be a pointer */
2815 if (!IS_PTR (LTYPE (tree)) &&
2816 !IS_ARRAY (LTYPE (tree)) &&
2817 !IS_INTEGRAL (LTYPE (tree)))
2819 werror (E_COMPARE_OP);
2820 goto errorTreeReturn;
2823 if (!IS_PTR (RTYPE (tree)) &&
2824 !IS_ARRAY (RTYPE (tree)) &&
2825 !IS_INTEGRAL (RTYPE (tree)))
2827 werror (E_COMPARE_OP);
2828 goto errorTreeReturn;
2830 /* if they are both literal then */
2831 /* rewrite the tree */
2832 if (IS_LITERAL (RTYPE (tree)) &&
2833 IS_LITERAL (LTYPE (tree)))
2835 tree->type = EX_VALUE;
2836 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2837 valFromType (RETYPE (tree)),
2839 tree->right = tree->left = NULL;
2840 TETYPE (tree) = getSpec (TTYPE (tree) =
2841 tree->opval.val->type);
2844 LRVAL (tree) = RRVAL (tree) = 1;
2845 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2848 /*------------------------------------------------------------------*/
2849 /*----------------------------*/
2850 /* comparison operators */
2851 /*----------------------------*/
2859 ast *lt = optimizeCompare (tree);
2865 /* if they are pointers they must be castable */
2866 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2868 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2870 werror (E_COMPARE_OP);
2871 fprintf (stderr, "comparing type ");
2872 printTypeChain (LTYPE (tree), stderr);
2873 fprintf (stderr, "to type ");
2874 printTypeChain (RTYPE (tree), stderr);
2875 fprintf (stderr, "\n");
2876 goto errorTreeReturn;
2879 /* else they should be promotable to one another */
2882 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2883 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2885 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2887 werror (E_COMPARE_OP);
2888 fprintf (stderr, "comparing type ");
2889 printTypeChain (LTYPE (tree), stderr);
2890 fprintf (stderr, "to type ");
2891 printTypeChain (RTYPE (tree), stderr);
2892 fprintf (stderr, "\n");
2893 goto errorTreeReturn;
2896 /* if unsigned value < 0 then always false */
2897 /* if (unsigned value) > 0 then (unsigned value) */
2898 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2899 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2901 if (tree->opval.op == '<') {
2904 if (tree->opval.op == '>') {
2908 /* if they are both literal then */
2909 /* rewrite the tree */
2910 if (IS_LITERAL (RTYPE (tree)) &&
2911 IS_LITERAL (LTYPE (tree)))
2913 tree->type = EX_VALUE;
2914 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2915 valFromType (RETYPE (tree)),
2917 tree->right = tree->left = NULL;
2918 TETYPE (tree) = getSpec (TTYPE (tree) =
2919 tree->opval.val->type);
2922 LRVAL (tree) = RRVAL (tree) = 1;
2923 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2926 /*------------------------------------------------------------------*/
2927 /*----------------------------*/
2929 /*----------------------------*/
2930 case SIZEOF: /* evaluate wihout code generation */
2931 /* change the type to a integer */
2932 tree->type = EX_VALUE;
2933 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2934 tree->opval.val = constVal (buffer);
2935 tree->right = tree->left = NULL;
2936 TETYPE (tree) = getSpec (TTYPE (tree) =
2937 tree->opval.val->type);
2940 /*------------------------------------------------------------------*/
2941 /*----------------------------*/
2943 /*----------------------------*/
2945 /* return typeof enum value */
2946 tree->type = EX_VALUE;
2949 if (IS_SPEC(tree->right->ftype)) {
2950 switch (SPEC_NOUN(tree->right->ftype)) {
2952 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2953 else typeofv = TYPEOF_INT;
2956 typeofv = TYPEOF_FLOAT;
2959 typeofv = TYPEOF_CHAR;
2962 typeofv = TYPEOF_VOID;
2965 typeofv = TYPEOF_STRUCT;
2968 typeofv = TYPEOF_BIT;
2971 typeofv = TYPEOF_SBIT;
2977 switch (DCL_TYPE(tree->right->ftype)) {
2979 typeofv = TYPEOF_POINTER;
2982 typeofv = TYPEOF_FPOINTER;
2985 typeofv = TYPEOF_CPOINTER;
2988 typeofv = TYPEOF_GPOINTER;
2991 typeofv = TYPEOF_PPOINTER;
2994 typeofv = TYPEOF_IPOINTER;
2997 typeofv = TYPEOF_ARRAY;
3000 typeofv = TYPEOF_FUNCTION;
3006 sprintf (buffer, "%d", typeofv);
3007 tree->opval.val = constVal (buffer);
3008 tree->right = tree->left = NULL;
3009 TETYPE (tree) = getSpec (TTYPE (tree) =
3010 tree->opval.val->type);
3013 /*------------------------------------------------------------------*/
3014 /*----------------------------*/
3015 /* conditional operator '?' */
3016 /*----------------------------*/
3018 /* the type is value of the colon operator (on the right) */
3019 assert(IS_COLON_OP(tree->right));
3020 /* if already known then replace the tree : optimizer will do it
3021 but faster to do it here */
3022 if (IS_LITERAL (LTYPE(tree))) {
3023 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3024 return decorateType(tree->right->left) ;
3026 return decorateType(tree->right->right) ;
3029 tree->right = decorateType(tree->right);
3030 TTYPE (tree) = RTYPE(tree);
3031 TETYPE (tree) = getSpec (TTYPE (tree));
3036 /* if they don't match we have a problem */
3037 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3039 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3040 goto errorTreeReturn;
3043 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3044 TETYPE (tree) = getSpec (TTYPE (tree));
3048 #if 0 // assignment operators are converted by the parser
3049 /*------------------------------------------------------------------*/
3050 /*----------------------------*/
3051 /* assignment operators */
3052 /*----------------------------*/
3055 /* for these it must be both must be integral */
3056 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3057 !IS_ARITHMETIC (RTYPE (tree)))
3059 werror (E_OPS_INTEGRAL);
3060 goto errorTreeReturn;
3063 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3065 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3066 werror (E_CODE_WRITE, " ");
3070 werror (E_LVALUE_REQUIRED, "*= or /=");
3071 goto errorTreeReturn;
3082 /* for these it must be both must be integral */
3083 if (!IS_INTEGRAL (LTYPE (tree)) ||
3084 !IS_INTEGRAL (RTYPE (tree)))
3086 werror (E_OPS_INTEGRAL);
3087 goto errorTreeReturn;
3090 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3092 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3093 werror (E_CODE_WRITE, " ");
3097 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3098 goto errorTreeReturn;
3104 /*------------------------------------------------------------------*/
3105 /*----------------------------*/
3107 /*----------------------------*/
3109 if (!(IS_PTR (LTYPE (tree)) ||
3110 IS_ARITHMETIC (LTYPE (tree))))
3112 werror (E_PLUS_INVALID, "-=");
3113 goto errorTreeReturn;
3116 if (!(IS_PTR (RTYPE (tree)) ||
3117 IS_ARITHMETIC (RTYPE (tree))))
3119 werror (E_PLUS_INVALID, "-=");
3120 goto errorTreeReturn;
3123 TETYPE (tree) = getSpec (TTYPE (tree) =
3124 computeType (LTYPE (tree),
3127 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3128 werror (E_CODE_WRITE, " ");
3132 werror (E_LVALUE_REQUIRED, "-=");
3133 goto errorTreeReturn;
3139 /*------------------------------------------------------------------*/
3140 /*----------------------------*/
3142 /*----------------------------*/
3144 /* this is not a unary operation */
3145 /* if both pointers then problem */
3146 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3148 werror (E_PTR_PLUS_PTR);
3149 goto errorTreeReturn;
3152 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3154 werror (E_PLUS_INVALID, "+=");
3155 goto errorTreeReturn;
3158 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3160 werror (E_PLUS_INVALID, "+=");
3161 goto errorTreeReturn;
3164 TETYPE (tree) = getSpec (TTYPE (tree) =
3165 computeType (LTYPE (tree),
3168 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3169 werror (E_CODE_WRITE, " ");
3173 werror (E_LVALUE_REQUIRED, "+=");
3174 goto errorTreeReturn;
3177 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3178 tree->opval.op = '=';
3183 /*------------------------------------------------------------------*/
3184 /*----------------------------*/
3185 /* straight assignemnt */
3186 /*----------------------------*/
3188 /* cannot be an aggregate */
3189 if (IS_AGGREGATE (LTYPE (tree)))
3191 werror (E_AGGR_ASSIGN);
3192 goto errorTreeReturn;
3195 /* they should either match or be castable */
3196 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3198 werror (E_TYPE_MISMATCH, "assignment", " ");
3199 printFromToType(RTYPE(tree),LTYPE(tree));
3200 //goto errorTreeReturn;
3203 /* if the left side of the tree is of type void
3204 then report error */
3205 if (IS_VOID (LTYPE (tree)))
3207 werror (E_CAST_ZERO);
3208 printFromToType(RTYPE(tree), LTYPE(tree));
3211 TETYPE (tree) = getSpec (TTYPE (tree) =
3215 if (!tree->initMode ) {
3216 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3217 werror (E_CODE_WRITE, " ");
3221 werror (E_LVALUE_REQUIRED, "=");
3222 goto errorTreeReturn;
3227 /*------------------------------------------------------------------*/
3228 /*----------------------------*/
3229 /* comma operator */
3230 /*----------------------------*/
3232 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3235 /*------------------------------------------------------------------*/
3236 /*----------------------------*/
3238 /*----------------------------*/
3242 if (processParms (tree->left,
3243 FUNC_ARGS(tree->left->ftype),
3244 tree->right, &parmNumber, TRUE)) {
3245 goto errorTreeReturn;
3248 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3249 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3251 //FUNC_ARGS(tree->left->ftype) =
3252 //reverseVal (FUNC_ARGS(tree->left->ftype));
3253 reverseParms (tree->right);
3256 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3259 /*------------------------------------------------------------------*/
3260 /*----------------------------*/
3261 /* return statement */
3262 /*----------------------------*/
3267 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3269 werror (W_RETURN_MISMATCH);
3270 printFromToType (RTYPE(tree), currFunc->type->next);
3271 goto errorTreeReturn;
3274 if (IS_VOID (currFunc->type->next)
3276 !IS_VOID (RTYPE (tree)))
3278 werror (E_FUNC_VOID);
3279 goto errorTreeReturn;
3282 /* if there is going to be a casing required then add it */
3283 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3286 decorateType (newNode (CAST,
3287 newAst_LINK (copyLinkChain (currFunc->type->next)),
3296 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3298 werror (E_VOID_FUNC, currFunc->name);
3299 goto errorTreeReturn;
3302 TTYPE (tree) = TETYPE (tree) = NULL;
3305 /*------------------------------------------------------------------*/
3306 /*----------------------------*/
3307 /* switch statement */
3308 /*----------------------------*/
3310 /* the switch value must be an integer */
3311 if (!IS_INTEGRAL (LTYPE (tree)))
3313 werror (E_SWITCH_NON_INTEGER);
3314 goto errorTreeReturn;
3317 TTYPE (tree) = TETYPE (tree) = NULL;
3320 /*------------------------------------------------------------------*/
3321 /*----------------------------*/
3323 /*----------------------------*/
3325 tree->left = backPatchLabels (tree->left,
3328 TTYPE (tree) = TETYPE (tree) = NULL;
3331 /*------------------------------------------------------------------*/
3332 /*----------------------------*/
3334 /*----------------------------*/
3337 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3338 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3339 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3341 /* if the for loop is reversible then
3342 reverse it otherwise do what we normally
3348 if (isLoopReversible (tree, &sym, &init, &end))
3349 return reverseLoop (tree, sym, init, end);
3351 return decorateType (createFor (AST_FOR (tree, trueLabel),
3352 AST_FOR (tree, continueLabel),
3353 AST_FOR (tree, falseLabel),
3354 AST_FOR (tree, condLabel),
3355 AST_FOR (tree, initExpr),
3356 AST_FOR (tree, condExpr),
3357 AST_FOR (tree, loopExpr),
3361 TTYPE (tree) = TETYPE (tree) = NULL;
3365 /* some error found this tree will be killed */
3367 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3368 tree->opval.op = NULLOP;
3374 /*-----------------------------------------------------------------*/
3375 /* sizeofOp - processes size of operation */
3376 /*-----------------------------------------------------------------*/
3378 sizeofOp (sym_link * type)
3382 /* make sure the type is complete and sane */
3383 checkTypeSanity(type, "(sizeof)");
3385 /* get the size and convert it to character */
3386 sprintf (buff, "%d", getSize (type));
3388 /* now convert into value */
3389 return constVal (buff);
3393 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3394 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3395 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3396 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3397 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3398 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3399 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3401 /*-----------------------------------------------------------------*/
3402 /* backPatchLabels - change and or not operators to flow control */
3403 /*-----------------------------------------------------------------*/
3405 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3411 if (!(IS_ANDORNOT (tree)))
3414 /* if this an and */
3417 static int localLbl = 0;
3420 sprintf (buffer, "_and_%d", localLbl++);
3421 localLabel = newSymbol (buffer, NestLevel);
3423 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3425 /* if left is already a IFX then just change the if true label in that */
3426 if (!IS_IFX (tree->left))
3427 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3429 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3430 /* right is a IFX then just join */
3431 if (IS_IFX (tree->right))
3432 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3434 tree->right = createLabel (localLabel, tree->right);
3435 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3437 return newNode (NULLOP, tree->left, tree->right);
3440 /* if this is an or operation */
3443 static int localLbl = 0;
3446 sprintf (buffer, "_or_%d", localLbl++);
3447 localLabel = newSymbol (buffer, NestLevel);
3449 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3451 /* if left is already a IFX then just change the if true label in that */
3452 if (!IS_IFX (tree->left))
3453 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3455 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3456 /* right is a IFX then just join */
3457 if (IS_IFX (tree->right))
3458 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3460 tree->right = createLabel (localLabel, tree->right);
3461 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3463 return newNode (NULLOP, tree->left, tree->right);
3469 int wasnot = IS_NOT (tree->left);
3470 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3472 /* if the left is already a IFX */
3473 if (!IS_IFX (tree->left))
3474 tree->left = newNode (IFX, tree->left, NULL);
3478 tree->left->trueLabel = trueLabel;
3479 tree->left->falseLabel = falseLabel;
3483 tree->left->trueLabel = falseLabel;
3484 tree->left->falseLabel = trueLabel;
3491 tree->trueLabel = trueLabel;
3492 tree->falseLabel = falseLabel;
3499 /*-----------------------------------------------------------------*/
3500 /* createBlock - create expression tree for block */
3501 /*-----------------------------------------------------------------*/
3503 createBlock (symbol * decl, ast * body)
3507 /* if the block has nothing */
3511 ex = newNode (BLOCK, NULL, body);
3512 ex->values.sym = decl;
3514 ex->right = ex->right;
3520 /*-----------------------------------------------------------------*/
3521 /* createLabel - creates the expression tree for labels */
3522 /*-----------------------------------------------------------------*/
3524 createLabel (symbol * label, ast * stmnt)
3527 char name[SDCC_NAME_MAX + 1];
3530 /* must create fresh symbol if the symbol name */
3531 /* exists in the symbol table, since there can */
3532 /* be a variable with the same name as the labl */
3533 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3534 (csym->level == label->level))
3535 label = newSymbol (label->name, label->level);
3537 /* change the name before putting it in add _ */
3538 sprintf (name, "%s", label->name);
3540 /* put the label in the LabelSymbol table */
3541 /* but first check if a label of the same */
3543 if ((csym = findSym (LabelTab, NULL, name)))
3544 werror (E_DUPLICATE_LABEL, label->name);
3546 addSym (LabelTab, label, name, label->level, 0, 0);
3549 label->key = labelKey++;
3550 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3556 /*-----------------------------------------------------------------*/
3557 /* createCase - generates the parsetree for a case statement */
3558 /*-----------------------------------------------------------------*/
3560 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3562 char caseLbl[SDCC_NAME_MAX + 1];
3566 /* if the switch statement does not exist */
3567 /* then case is out of context */
3570 werror (E_CASE_CONTEXT);
3574 caseVal = decorateType (resolveSymbols (caseVal));
3575 /* if not a constant then error */
3576 if (!IS_LITERAL (caseVal->ftype))
3578 werror (E_CASE_CONSTANT);
3582 /* if not a integer than error */
3583 if (!IS_INTEGRAL (caseVal->ftype))
3585 werror (E_CASE_NON_INTEGER);
3589 /* find the end of the switch values chain */
3590 if (!(val = swStat->values.switchVals.swVals))
3591 swStat->values.switchVals.swVals = caseVal->opval.val;
3594 /* also order the cases according to value */
3596 int cVal = (int) floatFromVal (caseVal->opval.val);
3597 while (val && (int) floatFromVal (val) < cVal)
3603 /* if we reached the end then */
3606 pval->next = caseVal->opval.val;
3610 /* we found a value greater than */
3611 /* the current value we must add this */
3612 /* before the value */
3613 caseVal->opval.val->next = val;
3615 /* if this was the first in chain */
3616 if (swStat->values.switchVals.swVals == val)
3617 swStat->values.switchVals.swVals =
3620 pval->next = caseVal->opval.val;
3625 /* create the case label */
3626 sprintf (caseLbl, "_case_%d_%d",
3627 swStat->values.switchVals.swNum,
3628 (int) floatFromVal (caseVal->opval.val));
3630 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3635 /*-----------------------------------------------------------------*/
3636 /* createDefault - creates the parse tree for the default statement */
3637 /*-----------------------------------------------------------------*/
3639 createDefault (ast * swStat, ast * stmnt)
3641 char defLbl[SDCC_NAME_MAX + 1];
3643 /* if the switch statement does not exist */
3644 /* then case is out of context */
3647 werror (E_CASE_CONTEXT);
3651 /* turn on the default flag */
3652 swStat->values.switchVals.swDefault = 1;
3654 /* create the label */
3655 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3656 return createLabel (newSymbol (defLbl, 0), stmnt);
3659 /*-----------------------------------------------------------------*/
3660 /* createIf - creates the parsetree for the if statement */
3661 /*-----------------------------------------------------------------*/
3663 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3665 static int Lblnum = 0;
3667 symbol *ifTrue, *ifFalse, *ifEnd;
3669 /* if neither exists */
3670 if (!elseBody && !ifBody) {
3671 // if there are no side effects (i++, j() etc)
3672 if (!hasSEFcalls(condAst)) {
3677 /* create the labels */
3678 sprintf (buffer, "_iffalse_%d", Lblnum);
3679 ifFalse = newSymbol (buffer, NestLevel);
3680 /* if no else body then end == false */
3685 sprintf (buffer, "_ifend_%d", Lblnum);
3686 ifEnd = newSymbol (buffer, NestLevel);
3689 sprintf (buffer, "_iftrue_%d", Lblnum);
3690 ifTrue = newSymbol (buffer, NestLevel);
3694 /* attach the ifTrue label to the top of it body */
3695 ifBody = createLabel (ifTrue, ifBody);
3696 /* attach a goto end to the ifBody if else is present */
3699 ifBody = newNode (NULLOP, ifBody,
3701 newAst_VALUE (symbolVal (ifEnd)),
3703 /* put the elseLabel on the else body */
3704 elseBody = createLabel (ifFalse, elseBody);
3705 /* out the end at the end of the body */
3706 elseBody = newNode (NULLOP,
3708 createLabel (ifEnd, NULL));
3712 ifBody = newNode (NULLOP, ifBody,
3713 createLabel (ifFalse, NULL));
3715 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3716 if (IS_IFX (condAst))
3719 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3721 return newNode (NULLOP, ifTree,
3722 newNode (NULLOP, ifBody, elseBody));
3726 /*-----------------------------------------------------------------*/
3727 /* createDo - creates parse tree for do */
3730 /* _docontinue_n: */
3731 /* condition_expression +-> trueLabel -> _dobody_n */
3733 /* +-> falseLabel-> _dobreak_n */
3735 /*-----------------------------------------------------------------*/
3737 createDo (symbol * trueLabel, symbol * continueLabel,
3738 symbol * falseLabel, ast * condAst, ast * doBody)
3743 /* if the body does not exist then it is simple */
3746 condAst = backPatchLabels (condAst, continueLabel, NULL);
3747 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3748 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3749 doTree->trueLabel = continueLabel;
3750 doTree->falseLabel = NULL;
3754 /* otherwise we have a body */
3755 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3757 /* attach the body label to the top */
3758 doBody = createLabel (trueLabel, doBody);
3759 /* attach the continue label to end of body */
3760 doBody = newNode (NULLOP, doBody,
3761 createLabel (continueLabel, NULL));
3763 /* now put the break label at the end */
3764 if (IS_IFX (condAst))
3767 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3769 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3771 /* putting it together */
3772 return newNode (NULLOP, doBody, doTree);
3775 /*-----------------------------------------------------------------*/
3776 /* createFor - creates parse tree for 'for' statement */
3779 /* condExpr +-> trueLabel -> _forbody_n */
3781 /* +-> falseLabel-> _forbreak_n */
3784 /* _forcontinue_n: */
3786 /* goto _forcond_n ; */
3788 /*-----------------------------------------------------------------*/
3790 createFor (symbol * trueLabel, symbol * continueLabel,
3791 symbol * falseLabel, symbol * condLabel,
3792 ast * initExpr, ast * condExpr, ast * loopExpr,
3797 /* if loopexpression not present then we can generate it */
3798 /* the same way as a while */
3800 return newNode (NULLOP, initExpr,
3801 createWhile (trueLabel, continueLabel,
3802 falseLabel, condExpr, forBody));
3803 /* vanilla for statement */
3804 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3806 if (condExpr && !IS_IFX (condExpr))
3807 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3810 /* attach condition label to condition */
3811 condExpr = createLabel (condLabel, condExpr);
3813 /* attach body label to body */
3814 forBody = createLabel (trueLabel, forBody);
3816 /* attach continue to forLoop expression & attach */
3817 /* goto the forcond @ and of loopExpression */
3818 loopExpr = createLabel (continueLabel,
3822 newAst_VALUE (symbolVal (condLabel)),
3824 /* now start putting them together */
3825 forTree = newNode (NULLOP, initExpr, condExpr);
3826 forTree = newNode (NULLOP, forTree, forBody);
3827 forTree = newNode (NULLOP, forTree, loopExpr);
3828 /* finally add the break label */
3829 forTree = newNode (NULLOP, forTree,
3830 createLabel (falseLabel, NULL));
3834 /*-----------------------------------------------------------------*/
3835 /* createWhile - creates parse tree for while statement */
3836 /* the while statement will be created as follows */
3838 /* _while_continue_n: */
3839 /* condition_expression +-> trueLabel -> _while_boby_n */
3841 /* +-> falseLabel -> _while_break_n */
3842 /* _while_body_n: */
3844 /* goto _while_continue_n */
3845 /* _while_break_n: */
3846 /*-----------------------------------------------------------------*/
3848 createWhile (symbol * trueLabel, symbol * continueLabel,
3849 symbol * falseLabel, ast * condExpr, ast * whileBody)
3853 /* put the continue label */
3854 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3855 condExpr = createLabel (continueLabel, condExpr);
3856 condExpr->lineno = 0;
3858 /* put the body label in front of the body */
3859 whileBody = createLabel (trueLabel, whileBody);
3860 whileBody->lineno = 0;
3861 /* put a jump to continue at the end of the body */
3862 /* and put break label at the end of the body */
3863 whileBody = newNode (NULLOP,
3866 newAst_VALUE (symbolVal (continueLabel)),
3867 createLabel (falseLabel, NULL)));
3869 /* put it all together */
3870 if (IS_IFX (condExpr))
3871 whileTree = condExpr;
3874 whileTree = newNode (IFX, condExpr, NULL);
3875 /* put the true & false labels in place */
3876 whileTree->trueLabel = trueLabel;
3877 whileTree->falseLabel = falseLabel;
3880 return newNode (NULLOP, whileTree, whileBody);
3883 /*-----------------------------------------------------------------*/
3884 /* optimizeGetHbit - get highest order bit of the expression */
3885 /*-----------------------------------------------------------------*/
3887 optimizeGetHbit (ast * tree)
3890 /* if this is not a bit and */
3891 if (!IS_BITAND (tree))
3894 /* will look for tree of the form
3895 ( expr >> ((sizeof expr) -1) ) & 1 */
3896 if (!IS_AST_LIT_VALUE (tree->right))
3899 if (AST_LIT_VALUE (tree->right) != 1)
3902 if (!IS_RIGHT_OP (tree->left))
3905 if (!IS_AST_LIT_VALUE (tree->left->right))
3908 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3909 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3912 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3916 /*-----------------------------------------------------------------*/
3917 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3918 /*-----------------------------------------------------------------*/
3920 optimizeRRCRLC (ast * root)
3922 /* will look for trees of the form
3923 (?expr << 1) | (?expr >> 7) or
3924 (?expr >> 7) | (?expr << 1) will make that
3925 into a RLC : operation ..
3927 (?expr >> 1) | (?expr << 7) or
3928 (?expr << 7) | (?expr >> 1) will make that
3929 into a RRC operation
3930 note : by 7 I mean (number of bits required to hold the
3932 /* if the root operations is not a | operation the not */
3933 if (!IS_BITOR (root))
3936 /* I have to think of a better way to match patterns this sucks */
3937 /* that aside let start looking for the first case : I use a the
3938 negative check a lot to improve the efficiency */
3939 /* (?expr << 1) | (?expr >> 7) */
3940 if (IS_LEFT_OP (root->left) &&
3941 IS_RIGHT_OP (root->right))
3944 if (!SPEC_USIGN (TETYPE (root->left->left)))
3947 if (!IS_AST_LIT_VALUE (root->left->right) ||
3948 !IS_AST_LIT_VALUE (root->right->right))
3951 /* make sure it is the same expression */
3952 if (!isAstEqual (root->left->left,
3956 if (AST_LIT_VALUE (root->left->right) != 1)
3959 if (AST_LIT_VALUE (root->right->right) !=
3960 (getSize (TTYPE (root->left->left)) * 8 - 1))
3963 /* whew got the first case : create the AST */
3964 return newNode (RLC, root->left->left, NULL);
3968 /* check for second case */
3969 /* (?expr >> 7) | (?expr << 1) */
3970 if (IS_LEFT_OP (root->right) &&
3971 IS_RIGHT_OP (root->left))
3974 if (!SPEC_USIGN (TETYPE (root->left->left)))
3977 if (!IS_AST_LIT_VALUE (root->left->right) ||
3978 !IS_AST_LIT_VALUE (root->right->right))
3981 /* make sure it is the same symbol */
3982 if (!isAstEqual (root->left->left,
3986 if (AST_LIT_VALUE (root->right->right) != 1)
3989 if (AST_LIT_VALUE (root->left->right) !=
3990 (getSize (TTYPE (root->left->left)) * 8 - 1))
3993 /* whew got the first case : create the AST */
3994 return newNode (RLC, root->left->left, NULL);
3999 /* third case for RRC */
4000 /* (?symbol >> 1) | (?symbol << 7) */
4001 if (IS_LEFT_OP (root->right) &&
4002 IS_RIGHT_OP (root->left))
4005 if (!SPEC_USIGN (TETYPE (root->left->left)))
4008 if (!IS_AST_LIT_VALUE (root->left->right) ||
4009 !IS_AST_LIT_VALUE (root->right->right))
4012 /* make sure it is the same symbol */
4013 if (!isAstEqual (root->left->left,
4017 if (AST_LIT_VALUE (root->left->right) != 1)
4020 if (AST_LIT_VALUE (root->right->right) !=
4021 (getSize (TTYPE (root->left->left)) * 8 - 1))
4024 /* whew got the first case : create the AST */
4025 return newNode (RRC, root->left->left, NULL);
4029 /* fourth and last case for now */
4030 /* (?symbol << 7) | (?symbol >> 1) */
4031 if (IS_RIGHT_OP (root->right) &&
4032 IS_LEFT_OP (root->left))
4035 if (!SPEC_USIGN (TETYPE (root->left->left)))
4038 if (!IS_AST_LIT_VALUE (root->left->right) ||
4039 !IS_AST_LIT_VALUE (root->right->right))
4042 /* make sure it is the same symbol */
4043 if (!isAstEqual (root->left->left,
4047 if (AST_LIT_VALUE (root->right->right) != 1)
4050 if (AST_LIT_VALUE (root->left->right) !=
4051 (getSize (TTYPE (root->left->left)) * 8 - 1))
4054 /* whew got the first case : create the AST */
4055 return newNode (RRC, root->left->left, NULL);
4059 /* not found return root */
4063 /*-----------------------------------------------------------------*/
4064 /* optimizeCompare - otimizes compares for bit variables */
4065 /*-----------------------------------------------------------------*/
4067 optimizeCompare (ast * root)
4069 ast *optExpr = NULL;
4072 unsigned int litValue;
4074 /* if nothing then return nothing */
4078 /* if not a compare op then do leaves */
4079 if (!IS_COMPARE_OP (root))
4081 root->left = optimizeCompare (root->left);
4082 root->right = optimizeCompare (root->right);
4086 /* if left & right are the same then depending
4087 of the operation do */
4088 if (isAstEqual (root->left, root->right))
4090 switch (root->opval.op)
4095 optExpr = newAst_VALUE (constVal ("0"));
4100 optExpr = newAst_VALUE (constVal ("1"));
4104 return decorateType (optExpr);
4107 vleft = (root->left->type == EX_VALUE ?
4108 root->left->opval.val : NULL);
4110 vright = (root->right->type == EX_VALUE ?
4111 root->right->opval.val : NULL);
4113 /* if left is a BITVAR in BITSPACE */
4114 /* and right is a LITERAL then opt- */
4115 /* imize else do nothing */
4116 if (vleft && vright &&
4117 IS_BITVAR (vleft->etype) &&
4118 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4119 IS_LITERAL (vright->etype))
4122 /* if right side > 1 then comparison may never succeed */
4123 if ((litValue = (int) floatFromVal (vright)) > 1)
4125 werror (W_BAD_COMPARE);
4131 switch (root->opval.op)
4133 case '>': /* bit value greater than 1 cannot be */
4134 werror (W_BAD_COMPARE);
4138 case '<': /* bit value < 1 means 0 */
4140 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4143 case LE_OP: /* bit value <= 1 means no check */
4144 optExpr = newAst_VALUE (vright);
4147 case GE_OP: /* bit value >= 1 means only check for = */
4149 optExpr = newAst_VALUE (vleft);
4154 { /* literal is zero */
4155 switch (root->opval.op)
4157 case '<': /* bit value < 0 cannot be */
4158 werror (W_BAD_COMPARE);
4162 case '>': /* bit value > 0 means 1 */
4164 optExpr = newAst_VALUE (vleft);
4167 case LE_OP: /* bit value <= 0 means no check */
4168 case GE_OP: /* bit value >= 0 means no check */
4169 werror (W_BAD_COMPARE);
4173 case EQ_OP: /* bit == 0 means ! of bit */
4174 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4178 return decorateType (resolveSymbols (optExpr));
4179 } /* end-of-if of BITVAR */
4184 /*-----------------------------------------------------------------*/
4185 /* addSymToBlock : adds the symbol to the first block we find */
4186 /*-----------------------------------------------------------------*/
4188 addSymToBlock (symbol * sym, ast * tree)
4190 /* reached end of tree or a leaf */
4191 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4195 if (IS_AST_OP (tree) &&
4196 tree->opval.op == BLOCK)
4199 symbol *lsym = copySymbol (sym);
4201 lsym->next = AST_VALUES (tree, sym);
4202 AST_VALUES (tree, sym) = lsym;
4206 addSymToBlock (sym, tree->left);
4207 addSymToBlock (sym, tree->right);
4210 /*-----------------------------------------------------------------*/
4211 /* processRegParms - do processing for register parameters */
4212 /*-----------------------------------------------------------------*/
4214 processRegParms (value * args, ast * body)
4218 if (IS_REGPARM (args->etype))
4219 addSymToBlock (args->sym, body);
4224 /*-----------------------------------------------------------------*/
4225 /* resetParmKey - resets the operandkeys for the symbols */
4226 /*-----------------------------------------------------------------*/
4227 DEFSETFUNC (resetParmKey)
4238 /*-----------------------------------------------------------------*/
4239 /* createFunction - This is the key node that calls the iCode for */
4240 /* generating the code for a function. Note code */
4241 /* is generated function by function, later when */
4242 /* add inter-procedural analysis this will change */
4243 /*-----------------------------------------------------------------*/
4245 createFunction (symbol * name, ast * body)
4251 iCode *piCode = NULL;
4253 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4254 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4256 /* if check function return 0 then some problem */
4257 if (checkFunction (name, NULL) == 0)
4260 /* create a dummy block if none exists */
4262 body = newNode (BLOCK, NULL, NULL);
4266 /* check if the function name already in the symbol table */
4267 if ((csym = findSym (SymbolTab, NULL, name->name)))
4270 /* special case for compiler defined functions
4271 we need to add the name to the publics list : this
4272 actually means we are now compiling the compiler
4276 addSet (&publics, name);
4282 allocVariables (name);
4284 name->lastLine = yylineno;
4287 /* set the stack pointer */
4288 /* PENDING: check this for the mcs51 */
4289 stackPtr = -port->stack.direction * port->stack.call_overhead;
4290 if (IFFUNC_ISISR (name->type))
4291 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4292 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4293 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4295 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4297 fetype = getSpec (name->type); /* get the specifier for the function */
4298 /* if this is a reentrant function then */
4299 if (IFFUNC_ISREENT (name->type))
4302 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4304 /* do processing for parameters that are passed in registers */
4305 processRegParms (FUNC_ARGS(name->type), body);
4307 /* set the stack pointer */
4311 /* allocate & autoinit the block variables */
4312 processBlockVars (body, &stack, ALLOCATE);
4314 /* save the stack information */
4315 if (options.useXstack)
4316 name->xstack = SPEC_STAK (fetype) = stack;
4318 name->stack = SPEC_STAK (fetype) = stack;
4320 /* name needs to be mangled */
4321 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4323 body = resolveSymbols (body); /* resolve the symbols */
4324 body = decorateType (body); /* propagateType & do semantic checks */
4326 ex = newAst_VALUE (symbolVal (name)); /* create name */
4327 ex = newNode (FUNCTION, ex, body);
4328 ex->values.args = FUNC_ARGS(name->type);
4330 if (options.dump_tree) PA(ex);
4333 werror (E_FUNC_NO_CODE, name->name);
4337 /* create the node & generate intermediate code */
4339 codeOutFile = code->oFile;
4340 piCode = iCodeFromAst (ex);
4344 werror (E_FUNC_NO_CODE, name->name);
4348 eBBlockFromiCode (piCode);
4350 /* if there are any statics then do them */
4353 GcurMemmap = statsg;
4354 codeOutFile = statsg->oFile;
4355 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4361 /* dealloc the block variables */
4362 processBlockVars (body, &stack, DEALLOCATE);
4363 /* deallocate paramaters */
4364 deallocParms (FUNC_ARGS(name->type));
4366 if (IFFUNC_ISREENT (name->type))
4369 /* we are done freeup memory & cleanup */
4371 if (port->reset_labelKey) labelKey = 1;
4373 FUNC_HASBODY(name->type) = 1;
4374 addSet (&operKeyReset, name);
4375 applyToSet (operKeyReset, resetParmKey);
4378 cdbStructBlock (1, cdbFile);
4380 cleanUpLevel (LabelTab, 0);
4381 cleanUpBlock (StructTab, 1);
4382 cleanUpBlock (TypedefTab, 1);
4384 xstack->syms = NULL;
4385 istack->syms = NULL;
4390 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4391 /*-----------------------------------------------------------------*/
4392 /* ast_print : prints the ast (for debugging purposes) */
4393 /*-----------------------------------------------------------------*/
4395 void ast_print (ast * tree, FILE *outfile, int indent)
4400 /* can print only decorated trees */
4401 if (!tree->decorated) return;
4403 /* if any child is an error | this one is an error do nothing */
4404 if (tree->isError ||
4405 (tree->left && tree->left->isError) ||
4406 (tree->right && tree->right->isError)) {
4407 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4411 /* print the line */
4412 /* if not block & function */
4413 if (tree->type == EX_OP &&
4414 (tree->opval.op != FUNCTION &&
4415 tree->opval.op != BLOCK &&
4416 tree->opval.op != NULLOP)) {
4419 if (tree->opval.op == FUNCTION) {
4421 value *args=FUNC_ARGS(tree->left->opval.val->type);
4422 fprintf(outfile,"FUNCTION (%s=%p) type (",
4423 tree->left->opval.val->name, tree);
4424 printTypeChain (tree->ftype,outfile);
4425 fprintf(outfile,") args (");
4428 fprintf (outfile, ", ");
4430 printTypeChain (args ? args->type : NULL, outfile);
4432 args= args ? args->next : NULL;
4434 fprintf(outfile,")\n");
4435 ast_print(tree->left,outfile,indent);
4436 ast_print(tree->right,outfile,indent);
4439 if (tree->opval.op == BLOCK) {
4440 symbol *decls = tree->values.sym;
4441 INDENT(indent,outfile);
4442 fprintf(outfile,"{\n");
4444 INDENT(indent+2,outfile);
4445 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4446 decls->name, decls);
4447 printTypeChain(decls->type,outfile);
4448 fprintf(outfile,")\n");
4450 decls = decls->next;
4452 ast_print(tree->right,outfile,indent+2);
4453 INDENT(indent,outfile);
4454 fprintf(outfile,"}\n");
4457 if (tree->opval.op == NULLOP) {
4458 fprintf(outfile,"\n");
4459 ast_print(tree->left,outfile,indent);
4460 fprintf(outfile,"\n");
4461 ast_print(tree->right,outfile,indent);
4464 INDENT(indent,outfile);
4466 /*------------------------------------------------------------------*/
4467 /*----------------------------*/
4468 /* leaf has been reached */
4469 /*----------------------------*/
4470 /* if this is of type value */
4471 /* just get the type */
4472 if (tree->type == EX_VALUE) {
4474 if (IS_LITERAL (tree->opval.val->etype)) {
4475 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4476 (int) floatFromVal(tree->opval.val),
4477 (int) floatFromVal(tree->opval.val),
4478 floatFromVal(tree->opval.val));
4479 } else if (tree->opval.val->sym) {
4480 /* if the undefined flag is set then give error message */
4481 if (tree->opval.val->sym->undefined) {
4482 fprintf(outfile,"UNDEFINED SYMBOL ");
4484 fprintf(outfile,"SYMBOL ");
4486 fprintf(outfile,"(%s=%p)",
4487 tree->opval.val->sym->name,tree);
4490 fprintf(outfile," type (");
4491 printTypeChain(tree->ftype,outfile);
4492 fprintf(outfile,")\n");
4494 fprintf(outfile,"\n");
4499 /* if type link for the case of cast */
4500 if (tree->type == EX_LINK) {
4501 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4502 printTypeChain(tree->opval.lnk,outfile);
4503 fprintf(outfile,")\n");
4508 /* depending on type of operator do */
4510 switch (tree->opval.op) {
4511 /*------------------------------------------------------------------*/
4512 /*----------------------------*/
4514 /*----------------------------*/
4516 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4517 printTypeChain(tree->ftype,outfile);
4518 fprintf(outfile,")\n");
4519 ast_print(tree->left,outfile,indent+2);
4520 ast_print(tree->right,outfile,indent+2);
4523 /*------------------------------------------------------------------*/
4524 /*----------------------------*/
4526 /*----------------------------*/
4528 fprintf(outfile,"STRUCT_ACCESS (%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);
4535 /*------------------------------------------------------------------*/
4536 /*----------------------------*/
4537 /* struct/union pointer */
4538 /*----------------------------*/
4540 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4541 printTypeChain(tree->ftype,outfile);
4542 fprintf(outfile,")\n");
4543 ast_print(tree->left,outfile,indent+2);
4544 ast_print(tree->right,outfile,indent+2);
4547 /*------------------------------------------------------------------*/
4548 /*----------------------------*/
4549 /* ++/-- operation */
4550 /*----------------------------*/
4551 case INC_OP: /* incerement operator unary so left only */
4552 fprintf(outfile,"INC_OP (%p) type (",tree);
4553 printTypeChain(tree->ftype,outfile);
4554 fprintf(outfile,")\n");
4555 ast_print(tree->left,outfile,indent+2);
4559 fprintf(outfile,"DEC_OP (%p) type (",tree);
4560 printTypeChain(tree->ftype,outfile);
4561 fprintf(outfile,")\n");
4562 ast_print(tree->left,outfile,indent+2);
4565 /*------------------------------------------------------------------*/
4566 /*----------------------------*/
4568 /*----------------------------*/
4571 fprintf(outfile,"& (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+2);
4575 ast_print(tree->right,outfile,indent+2);
4577 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4578 printTypeChain(tree->ftype,outfile);
4579 fprintf(outfile,")\n");
4580 ast_print(tree->left,outfile,indent+2);
4581 ast_print(tree->right,outfile,indent+2);
4584 /*----------------------------*/
4586 /*----------------------------*/
4588 fprintf(outfile,"OR (%p) type (",tree);
4589 printTypeChain(tree->ftype,outfile);
4590 fprintf(outfile,")\n");
4591 ast_print(tree->left,outfile,indent+2);
4592 ast_print(tree->right,outfile,indent+2);
4594 /*------------------------------------------------------------------*/
4595 /*----------------------------*/
4597 /*----------------------------*/
4599 fprintf(outfile,"XOR (%p) type (",tree);
4600 printTypeChain(tree->ftype,outfile);
4601 fprintf(outfile,")\n");
4602 ast_print(tree->left,outfile,indent+2);
4603 ast_print(tree->right,outfile,indent+2);
4606 /*------------------------------------------------------------------*/
4607 /*----------------------------*/
4609 /*----------------------------*/
4611 fprintf(outfile,"DIV (%p) type (",tree);
4612 printTypeChain(tree->ftype,outfile);
4613 fprintf(outfile,")\n");
4614 ast_print(tree->left,outfile,indent+2);
4615 ast_print(tree->right,outfile,indent+2);
4617 /*------------------------------------------------------------------*/
4618 /*----------------------------*/
4620 /*----------------------------*/
4622 fprintf(outfile,"MOD (%p) type (",tree);
4623 printTypeChain(tree->ftype,outfile);
4624 fprintf(outfile,")\n");
4625 ast_print(tree->left,outfile,indent+2);
4626 ast_print(tree->right,outfile,indent+2);
4629 /*------------------------------------------------------------------*/
4630 /*----------------------------*/
4631 /* address dereference */
4632 /*----------------------------*/
4633 case '*': /* can be unary : if right is null then unary operation */
4635 fprintf(outfile,"DEREF (%p) type (",tree);
4636 printTypeChain(tree->ftype,outfile);
4637 fprintf(outfile,")\n");
4638 ast_print(tree->left,outfile,indent+2);
4641 /*------------------------------------------------------------------*/
4642 /*----------------------------*/
4643 /* multiplication */
4644 /*----------------------------*/
4645 fprintf(outfile,"MULT (%p) type (",tree);
4646 printTypeChain(tree->ftype,outfile);
4647 fprintf(outfile,")\n");
4648 ast_print(tree->left,outfile,indent+2);
4649 ast_print(tree->right,outfile,indent+2);
4653 /*------------------------------------------------------------------*/
4654 /*----------------------------*/
4655 /* unary '+' operator */
4656 /*----------------------------*/
4660 fprintf(outfile,"UPLUS (%p) type (",tree);
4661 printTypeChain(tree->ftype,outfile);
4662 fprintf(outfile,")\n");
4663 ast_print(tree->left,outfile,indent+2);
4665 /*------------------------------------------------------------------*/
4666 /*----------------------------*/
4668 /*----------------------------*/
4669 fprintf(outfile,"ADD (%p) type (",tree);
4670 printTypeChain(tree->ftype,outfile);
4671 fprintf(outfile,")\n");
4672 ast_print(tree->left,outfile,indent+2);
4673 ast_print(tree->right,outfile,indent+2);
4676 /*------------------------------------------------------------------*/
4677 /*----------------------------*/
4679 /*----------------------------*/
4680 case '-': /* can be unary */
4682 fprintf(outfile,"UMINUS (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+2);
4687 /*------------------------------------------------------------------*/
4688 /*----------------------------*/
4690 /*----------------------------*/
4691 fprintf(outfile,"SUB (%p) type (",tree);
4692 printTypeChain(tree->ftype,outfile);
4693 fprintf(outfile,")\n");
4694 ast_print(tree->left,outfile,indent+2);
4695 ast_print(tree->right,outfile,indent+2);
4698 /*------------------------------------------------------------------*/
4699 /*----------------------------*/
4701 /*----------------------------*/
4703 fprintf(outfile,"COMPL (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+2);
4708 /*------------------------------------------------------------------*/
4709 /*----------------------------*/
4711 /*----------------------------*/
4713 fprintf(outfile,"NOT (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+2);
4718 /*------------------------------------------------------------------*/
4719 /*----------------------------*/
4721 /*----------------------------*/
4723 fprintf(outfile,"RRC (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+2);
4730 fprintf(outfile,"RLC (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+2);
4736 fprintf(outfile,"GETHBIT (%p) type (",tree);
4737 printTypeChain(tree->ftype,outfile);
4738 fprintf(outfile,")\n");
4739 ast_print(tree->left,outfile,indent+2);
4742 fprintf(outfile,"LEFT_SHIFT (%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,"RIGHT_SHIFT (%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);
4755 /*------------------------------------------------------------------*/
4756 /*----------------------------*/
4758 /*----------------------------*/
4759 case CAST: /* change the type */
4760 fprintf(outfile,"CAST (%p) from type (",tree);
4761 printTypeChain(tree->right->ftype,outfile);
4762 fprintf(outfile,") to type (");
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->right,outfile,indent+2);
4769 fprintf(outfile,"ANDAND (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+2);
4773 ast_print(tree->right,outfile,indent+2);
4776 fprintf(outfile,"OROR (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+2);
4780 ast_print(tree->right,outfile,indent+2);
4783 /*------------------------------------------------------------------*/
4784 /*----------------------------*/
4785 /* comparison operators */
4786 /*----------------------------*/
4788 fprintf(outfile,"GT(>) (%p) type (",tree);
4789 printTypeChain(tree->ftype,outfile);
4790 fprintf(outfile,")\n");
4791 ast_print(tree->left,outfile,indent+2);
4792 ast_print(tree->right,outfile,indent+2);
4795 fprintf(outfile,"LT(<) (%p) type (",tree);
4796 printTypeChain(tree->ftype,outfile);
4797 fprintf(outfile,")\n");
4798 ast_print(tree->left,outfile,indent+2);
4799 ast_print(tree->right,outfile,indent+2);
4802 fprintf(outfile,"LE(<=) (%p) type (",tree);
4803 printTypeChain(tree->ftype,outfile);
4804 fprintf(outfile,")\n");
4805 ast_print(tree->left,outfile,indent+2);
4806 ast_print(tree->right,outfile,indent+2);
4809 fprintf(outfile,"GE(>=) (%p) type (",tree);
4810 printTypeChain(tree->ftype,outfile);
4811 fprintf(outfile,")\n");
4812 ast_print(tree->left,outfile,indent+2);
4813 ast_print(tree->right,outfile,indent+2);
4816 fprintf(outfile,"EQ(==) (%p) type (",tree);
4817 printTypeChain(tree->ftype,outfile);
4818 fprintf(outfile,")\n");
4819 ast_print(tree->left,outfile,indent+2);
4820 ast_print(tree->right,outfile,indent+2);
4823 fprintf(outfile,"NE(!=) (%p) type (",tree);
4824 printTypeChain(tree->ftype,outfile);
4825 fprintf(outfile,")\n");
4826 ast_print(tree->left,outfile,indent+2);
4827 ast_print(tree->right,outfile,indent+2);
4828 /*------------------------------------------------------------------*/
4829 /*----------------------------*/
4831 /*----------------------------*/
4832 case SIZEOF: /* evaluate wihout code generation */
4833 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4836 /*------------------------------------------------------------------*/
4837 /*----------------------------*/
4838 /* conditional operator '?' */
4839 /*----------------------------*/
4841 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4842 printTypeChain(tree->ftype,outfile);
4843 fprintf(outfile,")\n");
4844 ast_print(tree->left,outfile,indent+2);
4845 ast_print(tree->right,outfile,indent+2);
4849 fprintf(outfile,"COLON(:) (%p) type (",tree);
4850 printTypeChain(tree->ftype,outfile);
4851 fprintf(outfile,")\n");
4852 ast_print(tree->left,outfile,indent+2);
4853 ast_print(tree->right,outfile,indent+2);
4856 /*------------------------------------------------------------------*/
4857 /*----------------------------*/
4858 /* assignment operators */
4859 /*----------------------------*/
4861 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4862 printTypeChain(tree->ftype,outfile);
4863 fprintf(outfile,")\n");
4864 ast_print(tree->left,outfile,indent+2);
4865 ast_print(tree->right,outfile,indent+2);
4868 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4869 printTypeChain(tree->ftype,outfile);
4870 fprintf(outfile,")\n");
4871 ast_print(tree->left,outfile,indent+2);
4872 ast_print(tree->right,outfile,indent+2);
4875 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4876 printTypeChain(tree->ftype,outfile);
4877 fprintf(outfile,")\n");
4878 ast_print(tree->left,outfile,indent+2);
4879 ast_print(tree->right,outfile,indent+2);
4882 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4883 printTypeChain(tree->ftype,outfile);
4884 fprintf(outfile,")\n");
4885 ast_print(tree->left,outfile,indent+2);
4886 ast_print(tree->right,outfile,indent+2);
4889 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4890 printTypeChain(tree->ftype,outfile);
4891 fprintf(outfile,")\n");
4892 ast_print(tree->left,outfile,indent+2);
4893 ast_print(tree->right,outfile,indent+2);
4896 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4897 printTypeChain(tree->ftype,outfile);
4898 fprintf(outfile,")\n");
4899 ast_print(tree->left,outfile,indent+2);
4900 ast_print(tree->right,outfile,indent+2);
4903 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4904 printTypeChain(tree->ftype,outfile);
4905 fprintf(outfile,")\n");
4906 ast_print(tree->left,outfile,indent+2);
4907 ast_print(tree->right,outfile,indent+2);
4909 /*------------------------------------------------------------------*/
4910 /*----------------------------*/
4912 /*----------------------------*/
4914 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4915 printTypeChain(tree->ftype,outfile);
4916 fprintf(outfile,")\n");
4917 ast_print(tree->left,outfile,indent+2);
4918 ast_print(tree->right,outfile,indent+2);
4920 /*------------------------------------------------------------------*/
4921 /*----------------------------*/
4923 /*----------------------------*/
4925 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4926 printTypeChain(tree->ftype,outfile);
4927 fprintf(outfile,")\n");
4928 ast_print(tree->left,outfile,indent+2);
4929 ast_print(tree->right,outfile,indent+2);
4931 /*------------------------------------------------------------------*/
4932 /*----------------------------*/
4933 /* straight assignemnt */
4934 /*----------------------------*/
4936 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4937 printTypeChain(tree->ftype,outfile);
4938 fprintf(outfile,")\n");
4939 ast_print(tree->left,outfile,indent+2);
4940 ast_print(tree->right,outfile,indent+2);
4942 /*------------------------------------------------------------------*/
4943 /*----------------------------*/
4944 /* comma operator */
4945 /*----------------------------*/
4947 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4948 printTypeChain(tree->ftype,outfile);
4949 fprintf(outfile,")\n");
4950 ast_print(tree->left,outfile,indent+2);
4951 ast_print(tree->right,outfile,indent+2);
4953 /*------------------------------------------------------------------*/
4954 /*----------------------------*/
4956 /*----------------------------*/
4959 fprintf(outfile,"CALL (%p) type (",tree);
4960 printTypeChain(tree->ftype,outfile);
4961 fprintf(outfile,")\n");
4962 ast_print(tree->left,outfile,indent+2);
4963 ast_print(tree->right,outfile,indent+2);
4966 fprintf(outfile,"PARMS\n");
4967 ast_print(tree->left,outfile,indent+2);
4968 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4969 ast_print(tree->right,outfile,indent+2);
4972 /*------------------------------------------------------------------*/
4973 /*----------------------------*/
4974 /* return statement */
4975 /*----------------------------*/
4977 fprintf(outfile,"RETURN (%p) type (",tree);
4979 printTypeChain(tree->right->ftype,outfile);
4981 fprintf(outfile,")\n");
4982 ast_print(tree->right,outfile,indent+2);
4984 /*------------------------------------------------------------------*/
4985 /*----------------------------*/
4986 /* label statement */
4987 /*----------------------------*/
4989 fprintf(outfile,"LABEL (%p)\n",tree);
4990 ast_print(tree->left,outfile,indent+2);
4991 ast_print(tree->right,outfile,indent);
4993 /*------------------------------------------------------------------*/
4994 /*----------------------------*/
4995 /* switch statement */
4996 /*----------------------------*/
5000 fprintf(outfile,"SWITCH (%p) ",tree);
5001 ast_print(tree->left,outfile,0);
5002 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5003 INDENT(indent+2,outfile);
5004 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5005 (int) floatFromVal(val),
5006 tree->values.switchVals.swNum,
5007 (int) floatFromVal(val));
5009 ast_print(tree->right,outfile,indent);
5012 /*------------------------------------------------------------------*/
5013 /*----------------------------*/
5015 /*----------------------------*/
5017 fprintf(outfile,"IF (%p) \n",tree);
5018 ast_print(tree->left,outfile,indent+2);
5019 if (tree->trueLabel) {
5020 INDENT(indent,outfile);
5021 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5023 if (tree->falseLabel) {
5024 INDENT(indent,outfile);
5025 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5027 ast_print(tree->right,outfile,indent+2);
5029 /*------------------------------------------------------------------*/
5030 /*----------------------------*/
5032 /*----------------------------*/
5034 fprintf(outfile,"FOR (%p) \n",tree);
5035 if (AST_FOR( tree, initExpr)) {
5036 INDENT(indent+2,outfile);
5037 fprintf(outfile,"INIT EXPR ");
5038 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5040 if (AST_FOR( tree, condExpr)) {
5041 INDENT(indent+2,outfile);
5042 fprintf(outfile,"COND EXPR ");
5043 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5045 if (AST_FOR( tree, loopExpr)) {
5046 INDENT(indent+2,outfile);
5047 fprintf(outfile,"LOOP EXPR ");
5048 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5050 fprintf(outfile,"FOR LOOP BODY \n");
5051 ast_print(tree->left,outfile,indent+2);
5060 ast_print(t,stdout,0);