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
50 symbol *currFunc=NULL;
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 : mylineno);
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);
113 /*-----------------------------------------------------------------*/
114 /* newNode - creates a new node */
115 /*-----------------------------------------------------------------*/
117 newNode (long op, ast * left, ast * right)
128 /*-----------------------------------------------------------------*/
129 /* newIfxNode - creates a new Ifx Node */
130 /*-----------------------------------------------------------------*/
132 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
136 /* if this is a literal then we already know the result */
137 if (condAst->etype && IS_LITERAL (condAst->etype))
139 /* then depending on the expression value */
140 if (floatFromVal (condAst->opval.val))
141 ifxNode = newNode (GOTO,
142 newAst_VALUE (symbolVal (trueLabel)),
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (falseLabel)),
151 ifxNode = newNode (IFX, condAst, NULL);
152 ifxNode->trueLabel = trueLabel;
153 ifxNode->falseLabel = falseLabel;
159 /*-----------------------------------------------------------------*/
160 /* copyAstValues - copies value portion of ast if needed */
161 /*-----------------------------------------------------------------*/
163 copyAstValues (ast * dest, ast * src)
165 switch (src->opval.op)
168 dest->values.sym = copySymbolChain (src->values.sym);
172 dest->values.switchVals.swVals =
173 copyValue (src->values.switchVals.swVals);
174 dest->values.switchVals.swDefault =
175 src->values.switchVals.swDefault;
176 dest->values.switchVals.swNum =
177 src->values.switchVals.swNum;
181 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
185 dest->values.constlist = copyLiteralList(src->values.constlist);
189 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
190 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
191 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
192 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
193 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
194 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
195 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
200 /*-----------------------------------------------------------------*/
201 /* copyAst - makes a copy of a given astession */
202 /*-----------------------------------------------------------------*/
211 dest = Safe_alloc ( sizeof (ast));
213 dest->type = src->type;
214 dest->lineno = src->lineno;
215 dest->level = src->level;
216 dest->funcName = src->funcName;
219 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
221 /* if this is a leaf */
223 if (src->type == EX_VALUE)
225 dest->opval.val = copyValue (src->opval.val);
230 if (src->type == EX_LINK)
232 dest->opval.lnk = copyLinkChain (src->opval.lnk);
236 dest->opval.op = src->opval.op;
238 /* if this is a node that has special values */
239 copyAstValues (dest, src);
241 dest->trueLabel = copySymbol (src->trueLabel);
242 dest->falseLabel = copySymbol (src->falseLabel);
243 dest->left = copyAst (src->left);
244 dest->right = copyAst (src->right);
250 /*-----------------------------------------------------------------*/
251 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
252 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
253 /*-----------------------------------------------------------------*/
254 ast *removeIncDecOps (ast * tree) {
256 // traverse the tree and remove inc/dec ops
261 if (tree->type == EX_OP &&
262 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
269 tree->left=removeIncDecOps(tree->left);
270 tree->right=removeIncDecOps(tree->right);
275 /*-----------------------------------------------------------------*/
276 /* hasSEFcalls - returns TRUE if tree has a function call */
277 /*-----------------------------------------------------------------*/
279 hasSEFcalls (ast * tree)
284 if (tree->type == EX_OP &&
285 (tree->opval.op == CALL ||
286 tree->opval.op == PCALL ||
287 tree->opval.op == '=' ||
288 tree->opval.op == INC_OP ||
289 tree->opval.op == DEC_OP))
292 return (hasSEFcalls (tree->left) |
293 hasSEFcalls (tree->right));
296 /*-----------------------------------------------------------------*/
297 /* isAstEqual - compares two asts & returns 1 if they are equal */
298 /*-----------------------------------------------------------------*/
300 isAstEqual (ast * t1, ast * t2)
309 if (t1->type != t2->type)
315 if (t1->opval.op != t2->opval.op)
317 return (isAstEqual (t1->left, t2->left) &&
318 isAstEqual (t1->right, t2->right));
322 if (t1->opval.val->sym)
324 if (!t2->opval.val->sym)
327 return isSymbolEqual (t1->opval.val->sym,
332 if (t2->opval.val->sym)
335 return (floatFromVal (t1->opval.val) ==
336 floatFromVal (t2->opval.val));
340 /* only compare these two types */
348 /*-----------------------------------------------------------------*/
349 /* resolveSymbols - resolve symbols from the symbol table */
350 /*-----------------------------------------------------------------*/
352 resolveSymbols (ast * tree)
354 /* walk the entire tree and check for values */
355 /* with symbols if we find one then replace */
356 /* symbol with that from the symbol table */
363 /* if not block & function */
364 if (tree->type == EX_OP &&
365 (tree->opval.op != FUNCTION &&
366 tree->opval.op != BLOCK &&
367 tree->opval.op != NULLOP))
369 filename = tree->filename;
370 lineno = tree->lineno;
374 /* make sure we resolve the true & false labels for ifx */
375 if (tree->type == EX_OP && tree->opval.op == IFX)
381 if ((csym = findSym (LabelTab, tree->trueLabel,
382 tree->trueLabel->name)))
383 tree->trueLabel = csym;
385 werror (E_LABEL_UNDEF, tree->trueLabel->name);
388 if (tree->falseLabel)
390 if ((csym = findSym (LabelTab,
392 tree->falseLabel->name)))
393 tree->falseLabel = csym;
395 werror (E_LABEL_UNDEF, tree->falseLabel->name);
400 /* if this is a label resolve it from the labelTab */
401 if (IS_AST_VALUE (tree) &&
402 tree->opval.val->sym &&
403 tree->opval.val->sym->islbl)
406 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
407 tree->opval.val->sym->name);
410 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
412 tree->opval.val->sym = csym;
414 goto resolveChildren;
417 /* do only for leafs */
418 if (IS_AST_VALUE (tree) &&
419 tree->opval.val->sym &&
420 !tree->opval.val->sym->implicit)
423 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
425 /* if found in the symbol table & they r not the same */
426 if (csym && tree->opval.val->sym != csym)
428 tree->opval.val->sym = csym;
429 tree->opval.val->type = csym->type;
430 tree->opval.val->etype = csym->etype;
433 /* if not found in the symbol table */
434 /* mark it as undefined assume it is */
435 /* an integer in data space */
436 if (!csym && !tree->opval.val->sym->implicit)
439 /* if this is a function name then */
440 /* mark it as returning an int */
443 tree->opval.val->sym->type = newLink (DECLARATOR);
444 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
445 tree->opval.val->sym->type->next =
446 tree->opval.val->sym->etype = newIntLink ();
447 tree->opval.val->etype = tree->opval.val->etype;
448 tree->opval.val->type = tree->opval.val->sym->type;
449 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
450 allocVariables (tree->opval.val->sym);
454 tree->opval.val->sym->undefined = 1;
455 tree->opval.val->type =
456 tree->opval.val->etype = newIntLink ();
457 tree->opval.val->sym->type =
458 tree->opval.val->sym->etype = newIntLink ();
464 resolveSymbols (tree->left);
465 resolveSymbols (tree->right);
470 /*-----------------------------------------------------------------*/
471 /* setAstLineno - walks a ast tree & sets the line number */
472 /*-----------------------------------------------------------------*/
473 int setAstLineno (ast * tree, int lineno)
478 tree->lineno = lineno;
479 setAstLineno (tree->left, lineno);
480 setAstLineno (tree->right, lineno);
484 /*-----------------------------------------------------------------*/
485 /* funcOfType :- function of type with name */
486 /*-----------------------------------------------------------------*/
488 funcOfType (char *name, sym_link * type, sym_link * argType,
492 /* create the symbol */
493 sym = newSymbol (name, 0);
495 /* setup return value */
496 sym->type = newLink (DECLARATOR);
497 DCL_TYPE (sym->type) = FUNCTION;
498 sym->type->next = copyLinkChain (type);
499 sym->etype = getSpec (sym->type);
500 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
502 /* if arguments required */
506 args = FUNC_ARGS(sym->type) = newValue ();
510 args->type = copyLinkChain (argType);
511 args->etype = getSpec (args->type);
512 SPEC_EXTR(args->etype)=1;
515 args = args->next = newValue ();
522 allocVariables (sym);
527 /*-----------------------------------------------------------------*/
528 /* funcOfTypeVarg :- function of type with name and argtype */
529 /*-----------------------------------------------------------------*/
531 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
536 /* create the symbol */
537 sym = newSymbol (name, 0);
539 /* setup return value */
540 sym->type = newLink (DECLARATOR);
541 DCL_TYPE (sym->type) = FUNCTION;
542 sym->type->next = typeFromStr(rtype);
543 sym->etype = getSpec (sym->type);
545 /* if arguments required */
548 args = FUNC_ARGS(sym->type) = newValue ();
550 for ( i = 0 ; i < nArgs ; i++ ) {
551 args->type = typeFromStr(atypes[i]);
552 args->etype = getSpec (args->type);
553 SPEC_EXTR(args->etype)=1;
554 if ((i + 1) == nArgs) break;
555 args = args->next = newValue ();
562 allocVariables (sym);
567 /*-----------------------------------------------------------------*/
568 /* reverseParms - will reverse a parameter tree */
569 /*-----------------------------------------------------------------*/
571 reverseParms (ast * ptree)
577 /* top down if we find a nonParm tree then quit */
578 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
581 ptree->left = ptree->right;
582 ptree->right = ttree;
583 reverseParms (ptree->left);
584 reverseParms (ptree->right);
590 /*-----------------------------------------------------------------*/
591 /* processParms - makes sure the parameters are okay and do some */
592 /* processing with them */
593 /*-----------------------------------------------------------------*/
595 processParms (ast * func,
598 int *parmNumber, // unused, although updated
601 /* if none of them exist */
602 if (!defParm && !actParm)
606 if (getenv("DEBUG_SANITY")) {
607 fprintf (stderr, "processParms: %s ", defParm->name);
609 /* make sure the type is complete and sane */
610 checkTypeSanity(defParm->etype, defParm->name);
613 /* if the function is being called via a pointer & */
614 /* it has not been defined a reentrant then we cannot */
615 /* have parameters */
616 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
618 werror (W_NONRENT_ARGS);
622 /* if defined parameters ended but actual parameters */
623 /* exist and this is not defined as a variable arg */
624 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
626 werror (E_TOO_MANY_PARMS);
630 /* if defined parameters present but no actual parameters */
631 if (defParm && !actParm)
633 werror (E_TOO_FEW_PARMS);
637 if (IS_VOID(actParm->ftype)) {
638 werror (E_VOID_VALUE_USED);
642 /* If this is a varargs function... */
643 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
648 if (IS_CAST_OP (actParm)
649 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
651 /* Parameter was explicitly typecast; don't touch it. */
655 ftype = actParm->ftype;
657 /* If it's a small integer, upcast to int. */
658 if (IS_INTEGRAL (ftype)
659 && (getSize (ftype) < (unsigned) INTSIZE))
661 if (IS_AST_OP(actParm) &&
662 (actParm->opval.op == LEFT_OP ||
663 actParm->opval.op == '*' ||
664 actParm->opval.op == '+' ||
665 actParm->opval.op == '-') &&
667 // we should cast an operand instead of the result
668 actParm->decorated = 0;
669 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
671 actParm = decorateType(actParm);
673 newType = newAst_LINK(INTTYPE);
677 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
679 newType = newAst_LINK (copyLinkChain(ftype));
680 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
683 if (IS_AGGREGATE (ftype))
685 newType = newAst_LINK (copyLinkChain (ftype));
686 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
690 /* cast required; change this op to a cast. */
691 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
693 actParm->type = EX_OP;
694 actParm->opval.op = CAST;
695 actParm->left = newType;
696 actParm->right = parmCopy;
697 decorateType (actParm);
699 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
701 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
702 processParms (func, NULL, actParm->right, parmNumber, rightmost));
707 /* if defined parameters ended but actual has not & */
709 if (!defParm && actParm &&
710 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
713 resolveSymbols (actParm);
714 /* if this is a PARAM node then match left & right */
715 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
717 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
718 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
722 /* If we have found a value node by following only right-hand links,
723 * then we know that there are no more values after us.
725 * Therefore, if there are more defined parameters, the caller didn't
728 if (rightmost && defParm->next)
730 werror (E_TOO_FEW_PARMS);
735 /* the parameter type must be at least castable */
736 if (compareType (defParm->type, actParm->ftype) == 0) {
737 werror (E_INCOMPAT_TYPES);
738 printFromToType (actParm->ftype, defParm->type);
742 /* if the parameter is castable then add the cast */
743 if (compareType (defParm->type, actParm->ftype) < 0)
745 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
747 /* now change the current one to a cast */
748 actParm->type = EX_OP;
749 actParm->opval.op = CAST;
750 actParm->left = newAst_LINK (defParm->type);
751 actParm->right = pTree;
752 actParm->etype = defParm->etype;
753 actParm->ftype = defParm->type;
754 actParm->decorated=0; /* force typechecking */
755 decorateType (actParm);
758 /* make a copy and change the regparm type to the defined parm */
759 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
760 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
761 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
765 /*-----------------------------------------------------------------*/
766 /* createIvalType - generates ival for basic types */
767 /*-----------------------------------------------------------------*/
769 createIvalType (ast * sym, sym_link * type, initList * ilist)
773 /* if initList is deep */
774 if (ilist->type == INIT_DEEP)
775 ilist = ilist->init.deep;
777 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
778 return decorateType (newNode ('=', sym, iExpr));
781 /*-----------------------------------------------------------------*/
782 /* createIvalStruct - generates initial value for structures */
783 /*-----------------------------------------------------------------*/
785 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
792 sflds = SPEC_STRUCT (type)->fields;
793 if (ilist->type != INIT_DEEP)
795 werror (E_INIT_STRUCT, "");
799 iloop = ilist->init.deep;
801 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
803 /* if we have come to end */
807 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
808 lAst = decorateType (resolveSymbols (lAst));
809 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
813 werror (W_EXCESS_INITIALIZERS, "struct",
814 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
821 /*-----------------------------------------------------------------*/
822 /* createIvalArray - generates code for array initialization */
823 /*-----------------------------------------------------------------*/
825 createIvalArray (ast * sym, sym_link * type, initList * ilist)
829 int lcnt = 0, size = 0;
830 literalList *literalL;
832 /* take care of the special case */
833 /* array of characters can be init */
835 if (IS_CHAR (type->next))
836 if ((rast = createIvalCharPtr (sym,
838 decorateType (resolveSymbols (list2expr (ilist))))))
840 return decorateType (resolveSymbols (rast));
842 /* not the special case */
843 if (ilist->type != INIT_DEEP)
845 werror (E_INIT_STRUCT, "");
849 iloop = ilist->init.deep;
850 lcnt = DCL_ELEM (type);
852 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
856 aSym = decorateType (resolveSymbols(sym));
858 rast = newNode(ARRAYINIT, aSym, NULL);
859 rast->values.constlist = literalL;
861 // Make sure size is set to length of initializer list.
868 if (lcnt && size > lcnt)
870 // Array size was specified, and we have more initializers than needed.
871 char *name=sym->opval.val->sym->name;
872 int lineno=sym->opval.val->sym->lineDef;
874 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
883 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
884 aSym = decorateType (resolveSymbols (aSym));
885 rast = createIval (aSym, type->next, iloop, rast);
886 iloop = (iloop ? iloop->next : NULL);
892 /* no of elements given and we */
893 /* have generated for all of them */
896 // there has to be a better way
897 char *name=sym->opval.val->sym->name;
898 int lineno=sym->opval.val->sym->lineDef;
899 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
906 /* if we have not been given a size */
907 if (!DCL_ELEM (type))
909 DCL_ELEM (type) = size;
912 return decorateType (resolveSymbols (rast));
916 /*-----------------------------------------------------------------*/
917 /* createIvalCharPtr - generates initial values for char pointers */
918 /*-----------------------------------------------------------------*/
920 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
924 /* if this is a pointer & right is a literal array then */
925 /* just assignment will do */
926 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
927 SPEC_SCLS (iexpr->etype) == S_CODE)
928 && IS_ARRAY (iexpr->ftype)))
929 return newNode ('=', sym, iexpr);
931 /* left side is an array so we have to assign each */
933 if ((IS_LITERAL (iexpr->etype) ||
934 SPEC_SCLS (iexpr->etype) == S_CODE)
935 && IS_ARRAY (iexpr->ftype))
937 /* for each character generate an assignment */
938 /* to the array element */
939 char *s = SPEC_CVAL (iexpr->etype).v_char;
944 rast = newNode (NULLOP,
948 newAst_VALUE (valueFromLit ((float) i))),
949 newAst_VALUE (valueFromLit (*s))));
953 rast = newNode (NULLOP,
957 newAst_VALUE (valueFromLit ((float) i))),
958 newAst_VALUE (valueFromLit (*s))));
960 // now WE don't need iexpr's symbol anymore
961 freeStringSymbol(AST_SYMBOL(iexpr));
963 return decorateType (resolveSymbols (rast));
969 /*-----------------------------------------------------------------*/
970 /* createIvalPtr - generates initial value for pointers */
971 /*-----------------------------------------------------------------*/
973 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
979 if (ilist->type == INIT_DEEP)
980 ilist = ilist->init.deep;
982 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
984 /* if character pointer */
985 if (IS_CHAR (type->next))
986 if ((rast = createIvalCharPtr (sym, type, iexpr)))
989 return newNode ('=', sym, iexpr);
992 /*-----------------------------------------------------------------*/
993 /* createIval - generates code for initial value */
994 /*-----------------------------------------------------------------*/
996 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1003 /* if structure then */
1004 if (IS_STRUCT (type))
1005 rast = createIvalStruct (sym, type, ilist);
1007 /* if this is a pointer */
1009 rast = createIvalPtr (sym, type, ilist);
1011 /* if this is an array */
1012 if (IS_ARRAY (type))
1013 rast = createIvalArray (sym, type, ilist);
1015 /* if type is SPECIFIER */
1017 rast = createIvalType (sym, type, ilist);
1020 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1022 return decorateType (resolveSymbols (rast));
1025 /*-----------------------------------------------------------------*/
1026 /* initAggregates - initialises aggregate variables with initv */
1027 /*-----------------------------------------------------------------*/
1028 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1029 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1032 /*-----------------------------------------------------------------*/
1033 /* gatherAutoInit - creates assignment expressions for initial */
1035 /*-----------------------------------------------------------------*/
1037 gatherAutoInit (symbol * autoChain)
1044 for (sym = autoChain; sym; sym = sym->next)
1047 /* resolve the symbols in the ival */
1049 resolveIvalSym (sym->ival);
1051 /* if this is a static variable & has an */
1052 /* initial value the code needs to be lifted */
1053 /* here to the main portion since they can be */
1054 /* initialised only once at the start */
1055 if (IS_STATIC (sym->etype) && sym->ival &&
1056 SPEC_SCLS (sym->etype) != S_CODE)
1060 /* insert the symbol into the symbol table */
1061 /* with level = 0 & name = rname */
1062 newSym = copySymbol (sym);
1063 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1065 /* now lift the code to main */
1066 if (IS_AGGREGATE (sym->type)) {
1067 work = initAggregates (sym, sym->ival, NULL);
1069 if (getNelements(sym->type, sym->ival)>1) {
1070 werror (W_EXCESS_INITIALIZERS, "scalar",
1071 sym->name, sym->lineDef);
1073 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1074 list2expr (sym->ival));
1077 setAstLineno (work, sym->lineDef);
1081 staticAutos = newNode (NULLOP, staticAutos, work);
1088 /* if there is an initial value */
1089 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1091 initList *ilist=sym->ival;
1093 while (ilist->type == INIT_DEEP) {
1094 ilist = ilist->init.deep;
1097 /* update lineno for error msg */
1098 lineno=sym->lineDef;
1099 setAstLineno (ilist->init.node, lineno);
1101 if (IS_AGGREGATE (sym->type)) {
1102 work = initAggregates (sym, sym->ival, NULL);
1104 if (getNelements(sym->type, sym->ival)>1) {
1105 werror (W_EXCESS_INITIALIZERS, "scalar",
1106 sym->name, sym->lineDef);
1108 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1109 list2expr (sym->ival));
1113 setAstLineno (work, sym->lineDef);
1117 init = newNode (NULLOP, init, work);
1126 /*-----------------------------------------------------------------*/
1127 /* freeStringSymbol - delete a literal string if no more usage */
1128 /*-----------------------------------------------------------------*/
1129 void freeStringSymbol(symbol *sym) {
1130 /* make sure this is a literal string */
1131 assert (sym->isstrlit);
1132 if (--sym->isstrlit == 0) { // lower the usage count
1133 memmap *segment=SPEC_OCLS(sym->etype);
1135 deleteSetItem(&segment->syms, sym);
1140 /*-----------------------------------------------------------------*/
1141 /* stringToSymbol - creates a symbol from a literal string */
1142 /*-----------------------------------------------------------------*/
1144 stringToSymbol (value * val)
1146 char name[SDCC_NAME_MAX + 1];
1147 static int charLbl = 0;
1151 // have we heard this before?
1152 for (sp=statsg->syms; sp; sp=sp->next) {
1154 if (sym->isstrlit &&
1155 !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
1156 // yes, this is old news. Don't publish it again.
1157 sym->isstrlit++; // but raise the usage count
1158 return symbolVal(sym);
1162 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1163 sym = newSymbol (name, 0); /* make it @ level 0 */
1164 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1166 /* copy the type from the value passed */
1167 sym->type = copyLinkChain (val->type);
1168 sym->etype = getSpec (sym->type);
1169 /* change to storage class & output class */
1170 SPEC_SCLS (sym->etype) = S_CODE;
1171 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1172 SPEC_STAT (sym->etype) = 1;
1173 /* make the level & block = 0 */
1174 sym->block = sym->level = 0;
1176 /* create an ival */
1177 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1182 allocVariables (sym);
1185 return symbolVal (sym);
1189 /*-----------------------------------------------------------------*/
1190 /* processBlockVars - will go thru the ast looking for block if */
1191 /* a block is found then will allocate the syms */
1192 /* will also gather the auto inits present */
1193 /*-----------------------------------------------------------------*/
1195 processBlockVars (ast * tree, int *stack, int action)
1200 /* if this is a block */
1201 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1205 if (action == ALLOCATE)
1207 *stack += allocVariables (tree->values.sym);
1208 autoInit = gatherAutoInit (tree->values.sym);
1210 /* if there are auto inits then do them */
1212 tree->left = newNode (NULLOP, autoInit, tree->left);
1214 else /* action is deallocate */
1215 deallocLocal (tree->values.sym);
1218 processBlockVars (tree->left, stack, action);
1219 processBlockVars (tree->right, stack, action);
1223 /*-------------------------------------------------------------*/
1224 /* constExprTree - returns TRUE if this tree is a constant */
1226 /*-------------------------------------------------------------*/
1227 bool constExprTree (ast *cexpr) {
1233 cexpr = decorateType (resolveSymbols (cexpr));
1235 switch (cexpr->type)
1238 if (IS_AST_LIT_VALUE(cexpr)) {
1239 // this is a literal
1242 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1243 // a function's address will never change
1246 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1247 // an array's address will never change
1250 if (IS_AST_SYM_VALUE(cexpr) &&
1251 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1252 // a symbol in code space will never change
1253 // This is only for the 'char *s="hallo"' case and will have to leave
1258 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1259 "unexpected link in expression tree\n");
1262 if (cexpr->opval.op==ARRAYINIT) {
1263 // this is a list of literals
1266 if (cexpr->opval.op=='=') {
1267 return constExprTree(cexpr->right);
1269 if (cexpr->opval.op==CAST) {
1270 // cast ignored, maybe we should throw a warning here?
1271 return constExprTree(cexpr->right);
1273 if (cexpr->opval.op=='&') {
1276 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1279 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1283 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1288 /*-----------------------------------------------------------------*/
1289 /* constExprValue - returns the value of a constant expression */
1290 /* or NULL if it is not a constant expression */
1291 /*-----------------------------------------------------------------*/
1293 constExprValue (ast * cexpr, int check)
1295 cexpr = decorateType (resolveSymbols (cexpr));
1297 /* if this is not a constant then */
1298 if (!IS_LITERAL (cexpr->ftype))
1300 /* then check if this is a literal array
1302 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1303 SPEC_CVAL (cexpr->etype).v_char &&
1304 IS_ARRAY (cexpr->ftype))
1306 value *val = valFromType (cexpr->ftype);
1307 SPEC_SCLS (val->etype) = S_LITERAL;
1308 val->sym = cexpr->opval.val->sym;
1309 val->sym->type = copyLinkChain (cexpr->ftype);
1310 val->sym->etype = getSpec (val->sym->type);
1311 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1315 /* if we are casting a literal value then */
1316 if (IS_AST_OP (cexpr) &&
1317 cexpr->opval.op == CAST &&
1318 IS_LITERAL (cexpr->right->ftype))
1319 return valCastLiteral (cexpr->ftype,
1320 floatFromVal (cexpr->right->opval.val));
1322 if (IS_AST_VALUE (cexpr))
1323 return cexpr->opval.val;
1326 werror (E_CONST_EXPECTED, "found expression");
1331 /* return the value */
1332 return cexpr->opval.val;
1336 /*-----------------------------------------------------------------*/
1337 /* isLabelInAst - will return true if a given label is found */
1338 /*-----------------------------------------------------------------*/
1340 isLabelInAst (symbol * label, ast * tree)
1342 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1345 if (IS_AST_OP (tree) &&
1346 tree->opval.op == LABEL &&
1347 isSymbolEqual (AST_SYMBOL (tree->left), label))
1350 return isLabelInAst (label, tree->right) &&
1351 isLabelInAst (label, tree->left);
1355 /*-----------------------------------------------------------------*/
1356 /* isLoopCountable - return true if the loop count can be determi- */
1357 /* -ned at compile time . */
1358 /*-----------------------------------------------------------------*/
1360 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1361 symbol ** sym, ast ** init, ast ** end)
1364 /* the loop is considered countable if the following
1365 conditions are true :-
1367 a) initExpr :- <sym> = <const>
1368 b) condExpr :- <sym> < <const1>
1369 c) loopExpr :- <sym> ++
1372 /* first check the initExpr */
1373 if (IS_AST_OP (initExpr) &&
1374 initExpr->opval.op == '=' && /* is assignment */
1375 IS_AST_SYM_VALUE (initExpr->left))
1376 { /* left is a symbol */
1378 *sym = AST_SYMBOL (initExpr->left);
1379 *init = initExpr->right;
1384 /* for now the symbol has to be of
1386 if (!IS_INTEGRAL ((*sym)->type))
1389 /* now check condExpr */
1390 if (IS_AST_OP (condExpr))
1393 switch (condExpr->opval.op)
1396 if (IS_AST_SYM_VALUE (condExpr->left) &&
1397 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1398 IS_AST_LIT_VALUE (condExpr->right))
1400 *end = condExpr->right;
1406 if (IS_AST_OP (condExpr->left) &&
1407 condExpr->left->opval.op == '>' &&
1408 IS_AST_LIT_VALUE (condExpr->left->right) &&
1409 IS_AST_SYM_VALUE (condExpr->left->left) &&
1410 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1413 *end = newNode ('+', condExpr->left->right,
1414 newAst_VALUE (constVal ("1")));
1425 /* check loop expression is of the form <sym>++ */
1426 if (!IS_AST_OP (loopExpr))
1429 /* check if <sym> ++ */
1430 if (loopExpr->opval.op == INC_OP)
1436 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1437 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1444 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1445 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1453 if (loopExpr->opval.op == ADD_ASSIGN)
1456 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1457 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1458 IS_AST_LIT_VALUE (loopExpr->right) &&
1459 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1467 /*-----------------------------------------------------------------*/
1468 /* astHasVolatile - returns true if ast contains any volatile */
1469 /*-----------------------------------------------------------------*/
1471 astHasVolatile (ast * tree)
1476 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1479 if (IS_AST_OP (tree))
1480 return astHasVolatile (tree->left) ||
1481 astHasVolatile (tree->right);
1486 /*-----------------------------------------------------------------*/
1487 /* astHasPointer - return true if the ast contains any ptr variable */
1488 /*-----------------------------------------------------------------*/
1490 astHasPointer (ast * tree)
1495 if (IS_AST_LINK (tree))
1498 /* if we hit an array expression then check
1499 only the left side */
1500 if (IS_AST_OP (tree) && tree->opval.op == '[')
1501 return astHasPointer (tree->left);
1503 if (IS_AST_VALUE (tree))
1504 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1506 return astHasPointer (tree->left) ||
1507 astHasPointer (tree->right);
1511 /*-----------------------------------------------------------------*/
1512 /* astHasSymbol - return true if the ast has the given symbol */
1513 /*-----------------------------------------------------------------*/
1515 astHasSymbol (ast * tree, symbol * sym)
1517 if (!tree || IS_AST_LINK (tree))
1520 if (IS_AST_VALUE (tree))
1522 if (IS_AST_SYM_VALUE (tree))
1523 return isSymbolEqual (AST_SYMBOL (tree), sym);
1528 return astHasSymbol (tree->left, sym) ||
1529 astHasSymbol (tree->right, sym);
1532 /*-----------------------------------------------------------------*/
1533 /* astHasDeref - return true if the ast has an indirect access */
1534 /*-----------------------------------------------------------------*/
1536 astHasDeref (ast * tree)
1538 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1541 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1543 return astHasDeref (tree->left) || astHasDeref (tree->right);
1546 /*-----------------------------------------------------------------*/
1547 /* isConformingBody - the loop body has to conform to a set of rules */
1548 /* for the loop to be considered reversible read on for rules */
1549 /*-----------------------------------------------------------------*/
1551 isConformingBody (ast * pbody, symbol * sym, ast * body)
1554 /* we are going to do a pre-order traversal of the
1555 tree && check for the following conditions. (essentially
1556 a set of very shallow tests )
1557 a) the sym passed does not participate in
1558 any arithmetic operation
1559 b) There are no function calls
1560 c) all jumps are within the body
1561 d) address of loop control variable not taken
1562 e) if an assignment has a pointer on the
1563 left hand side make sure right does not have
1564 loop control variable */
1566 /* if we reach the end or a leaf then true */
1567 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1570 /* if anything else is "volatile" */
1571 if (IS_VOLATILE (TETYPE (pbody)))
1574 /* we will walk the body in a pre-order traversal for
1576 switch (pbody->opval.op)
1578 /*------------------------------------------------------------------*/
1580 // if the loopvar is used as an index
1581 if (astHasSymbol(pbody->right, sym)) {
1584 return isConformingBody (pbody->right, sym, body);
1586 /*------------------------------------------------------------------*/
1591 /*------------------------------------------------------------------*/
1592 case INC_OP: /* incerement operator unary so left only */
1595 /* sure we are not sym is not modified */
1597 IS_AST_SYM_VALUE (pbody->left) &&
1598 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1602 IS_AST_SYM_VALUE (pbody->right) &&
1603 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1608 /*------------------------------------------------------------------*/
1610 case '*': /* can be unary : if right is null then unary operation */
1615 /* if right is NULL then unary operation */
1616 /*------------------------------------------------------------------*/
1617 /*----------------------------*/
1619 /*----------------------------*/
1622 if (IS_AST_SYM_VALUE (pbody->left) &&
1623 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1626 return isConformingBody (pbody->left, sym, body);
1630 if (astHasSymbol (pbody->left, sym) ||
1631 astHasSymbol (pbody->right, sym))
1636 /*------------------------------------------------------------------*/
1644 if (IS_AST_SYM_VALUE (pbody->left) &&
1645 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1648 if (IS_AST_SYM_VALUE (pbody->right) &&
1649 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1652 return isConformingBody (pbody->left, sym, body) &&
1653 isConformingBody (pbody->right, sym, body);
1660 if (IS_AST_SYM_VALUE (pbody->left) &&
1661 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1663 return isConformingBody (pbody->left, sym, body);
1665 /*------------------------------------------------------------------*/
1677 case SIZEOF: /* evaluate wihout code generation */
1679 return isConformingBody (pbody->left, sym, body) &&
1680 isConformingBody (pbody->right, sym, body);
1682 /*------------------------------------------------------------------*/
1685 /* if left has a pointer & right has loop
1686 control variable then we cannot */
1687 if (astHasPointer (pbody->left) &&
1688 astHasSymbol (pbody->right, sym))
1690 if (astHasVolatile (pbody->left))
1693 if (IS_AST_SYM_VALUE (pbody->left)) {
1694 // if the loopvar has an assignment
1695 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1697 // if the loopvar is used in another (maybe conditional) block
1698 if (astHasSymbol (pbody->right, sym) &&
1699 (pbody->level > body->level)) {
1704 if (astHasVolatile (pbody->left))
1707 if (astHasDeref(pbody->right)) return FALSE;
1709 return isConformingBody (pbody->left, sym, body) &&
1710 isConformingBody (pbody->right, sym, body);
1721 assert ("Parser should not have generated this\n");
1723 /*------------------------------------------------------------------*/
1724 /*----------------------------*/
1725 /* comma operator */
1726 /*----------------------------*/
1728 return isConformingBody (pbody->left, sym, body) &&
1729 isConformingBody (pbody->right, sym, body);
1731 /*------------------------------------------------------------------*/
1732 /*----------------------------*/
1734 /*----------------------------*/
1736 /* if local & not passed as paramater then ok */
1737 if (sym->level && !astHasSymbol(pbody->right,sym))
1741 /*------------------------------------------------------------------*/
1742 /*----------------------------*/
1743 /* return statement */
1744 /*----------------------------*/
1749 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1754 if (astHasSymbol (pbody->left, sym))
1761 return isConformingBody (pbody->left, sym, body) &&
1762 isConformingBody (pbody->right, sym, body);
1768 /*-----------------------------------------------------------------*/
1769 /* isLoopReversible - takes a for loop as input && returns true */
1770 /* if the for loop is reversible. If yes will set the value of */
1771 /* the loop control var & init value & termination value */
1772 /*-----------------------------------------------------------------*/
1774 isLoopReversible (ast * loop, symbol ** loopCntrl,
1775 ast ** init, ast ** end)
1777 /* if option says don't do it then don't */
1778 if (optimize.noLoopReverse)
1780 /* there are several tests to determine this */
1782 /* for loop has to be of the form
1783 for ( <sym> = <const1> ;
1784 [<sym> < <const2>] ;
1785 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1787 if (!isLoopCountable (AST_FOR (loop, initExpr),
1788 AST_FOR (loop, condExpr),
1789 AST_FOR (loop, loopExpr),
1790 loopCntrl, init, end))
1793 /* now do some serious checking on the body of the loop
1796 return isConformingBody (loop->left, *loopCntrl, loop->left);
1800 /*-----------------------------------------------------------------*/
1801 /* replLoopSym - replace the loop sym by loop sym -1 */
1802 /*-----------------------------------------------------------------*/
1804 replLoopSym (ast * body, symbol * sym)
1807 if (!body || IS_AST_LINK (body))
1810 if (IS_AST_SYM_VALUE (body))
1813 if (isSymbolEqual (AST_SYMBOL (body), sym))
1817 body->opval.op = '-';
1818 body->left = newAst_VALUE (symbolVal (sym));
1819 body->right = newAst_VALUE (constVal ("1"));
1827 replLoopSym (body->left, sym);
1828 replLoopSym (body->right, sym);
1832 /*-----------------------------------------------------------------*/
1833 /* reverseLoop - do the actual loop reversal */
1834 /*-----------------------------------------------------------------*/
1836 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1840 /* create the following tree
1845 if (sym) goto for_continue ;
1848 /* put it together piece by piece */
1849 rloop = newNode (NULLOP,
1850 createIf (newAst_VALUE (symbolVal (sym)),
1852 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1855 newAst_VALUE (symbolVal (sym)),
1858 replLoopSym (loop->left, sym);
1859 setAstLineno (rloop, init->lineno);
1861 rloop = newNode (NULLOP,
1863 newAst_VALUE (symbolVal (sym)),
1864 newNode ('-', end, init)),
1865 createLabel (AST_FOR (loop, continueLabel),
1869 newNode (SUB_ASSIGN,
1870 newAst_VALUE (symbolVal (sym)),
1871 newAst_VALUE (constVal ("1"))),
1874 rloop->lineno=init->lineno;
1875 return decorateType (rloop);
1879 /*-----------------------------------------------------------------*/
1880 /* decorateType - compute type for this tree also does type cheking */
1881 /* this is done bottom up, since type have to flow upwards */
1882 /* it also does constant folding, and paramater checking */
1883 /*-----------------------------------------------------------------*/
1885 decorateType (ast * tree)
1893 /* if already has type then do nothing */
1894 if (tree->decorated)
1897 tree->decorated = 1;
1900 /* print the line */
1901 /* if not block & function */
1902 if (tree->type == EX_OP &&
1903 (tree->opval.op != FUNCTION &&
1904 tree->opval.op != BLOCK &&
1905 tree->opval.op != NULLOP))
1907 filename = tree->filename;
1908 lineno = tree->lineno;
1912 /* if any child is an error | this one is an error do nothing */
1913 if (tree->isError ||
1914 (tree->left && tree->left->isError) ||
1915 (tree->right && tree->right->isError))
1918 /*------------------------------------------------------------------*/
1919 /*----------------------------*/
1920 /* leaf has been reached */
1921 /*----------------------------*/
1922 lineno=tree->lineno;
1923 /* if this is of type value */
1924 /* just get the type */
1925 if (tree->type == EX_VALUE)
1928 if (IS_LITERAL (tree->opval.val->etype))
1931 /* if this is a character array then declare it */
1932 if (IS_ARRAY (tree->opval.val->type))
1933 tree->opval.val = stringToSymbol (tree->opval.val);
1935 /* otherwise just copy the type information */
1936 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1940 if (tree->opval.val->sym)
1942 /* if the undefined flag is set then give error message */
1943 if (tree->opval.val->sym->undefined)
1945 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1947 TTYPE (tree) = TETYPE (tree) =
1948 tree->opval.val->type = tree->opval.val->sym->type =
1949 tree->opval.val->etype = tree->opval.val->sym->etype =
1950 copyLinkChain (INTTYPE);
1955 /* if impilicit i.e. struct/union member then no type */
1956 if (tree->opval.val->sym->implicit)
1957 TTYPE (tree) = TETYPE (tree) = NULL;
1962 /* else copy the type */
1963 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1965 /* and mark it as referenced */
1966 tree->opval.val->sym->isref = 1;
1974 /* if type link for the case of cast */
1975 if (tree->type == EX_LINK)
1977 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1984 dtl = decorateType (tree->left);
1985 /* delay right side for '?' operator since conditional macro expansions might
1987 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1989 /* this is to take care of situations
1990 when the tree gets rewritten */
1991 if (dtl != tree->left)
1993 if (dtr != tree->right)
1996 if (IS_AST_OP(tree) &&
1997 (tree->opval.op == CAST || tree->opval.op == '=') &&
1998 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
1999 (getSize(RTYPE(tree)) < INTSIZE)) {
2000 // this is a cast/assign to a bigger type
2001 if (IS_AST_OP(tree->right) &&
2002 IS_INTEGRAL(tree->right->ftype) &&
2003 (tree->right->opval.op == LEFT_OP ||
2004 tree->right->opval.op == '*' ||
2005 tree->right->opval.op == '+' ||
2006 tree->right->opval.op == '-') &&
2007 tree->right->right) {
2008 // we should cast an operand instead of the result
2009 tree->right->decorated = 0;
2010 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2012 tree->right = decorateType(tree->right);
2017 /* depending on type of operator do */
2019 switch (tree->opval.op)
2021 /*------------------------------------------------------------------*/
2022 /*----------------------------*/
2024 /*----------------------------*/
2027 /* determine which is the array & which the index */
2028 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2031 ast *tempTree = tree->left;
2032 tree->left = tree->right;
2033 tree->right = tempTree;
2036 /* first check if this is a array or a pointer */
2037 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2039 werror (E_NEED_ARRAY_PTR, "[]");
2040 goto errorTreeReturn;
2043 /* check if the type of the idx */
2044 if (!IS_INTEGRAL (RTYPE (tree)))
2046 werror (E_IDX_NOT_INT);
2047 goto errorTreeReturn;
2050 /* if the left is an rvalue then error */
2053 werror (E_LVALUE_REQUIRED, "array access");
2054 goto errorTreeReturn;
2057 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2058 if (IS_PTR(LTYPE(tree))) {
2059 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2063 /*------------------------------------------------------------------*/
2064 /*----------------------------*/
2066 /*----------------------------*/
2068 /* if this is not a structure */
2069 if (!IS_STRUCT (LTYPE (tree)))
2071 werror (E_STRUCT_UNION, ".");
2072 goto errorTreeReturn;
2074 TTYPE (tree) = structElemType (LTYPE (tree),
2075 (tree->right->type == EX_VALUE ?
2076 tree->right->opval.val : NULL));
2077 TETYPE (tree) = getSpec (TTYPE (tree));
2080 /*------------------------------------------------------------------*/
2081 /*----------------------------*/
2082 /* struct/union pointer */
2083 /*----------------------------*/
2085 /* if not pointer to a structure */
2086 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2088 werror (E_PTR_REQD);
2089 goto errorTreeReturn;
2092 if (!IS_STRUCT (LTYPE (tree)->next))
2094 werror (E_STRUCT_UNION, "->");
2095 goto errorTreeReturn;
2098 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2099 (tree->right->type == EX_VALUE ?
2100 tree->right->opval.val : NULL));
2101 TETYPE (tree) = getSpec (TTYPE (tree));
2103 /* adjust the storage class */
2104 switch (DCL_TYPE(tree->left->ftype)) {
2108 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2111 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2116 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2119 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2122 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2132 /*------------------------------------------------------------------*/
2133 /*----------------------------*/
2134 /* ++/-- operation */
2135 /*----------------------------*/
2136 case INC_OP: /* incerement operator unary so left only */
2139 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2140 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2141 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2142 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2151 /*------------------------------------------------------------------*/
2152 /*----------------------------*/
2154 /*----------------------------*/
2155 case '&': /* can be unary */
2156 /* if right is NULL then unary operation */
2157 if (tree->right) /* not an unary operation */
2160 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2162 werror (E_BITWISE_OP);
2163 werror (W_CONTINUE, "left & right types are ");
2164 printTypeChain (LTYPE (tree), stderr);
2165 fprintf (stderr, ",");
2166 printTypeChain (RTYPE (tree), stderr);
2167 fprintf (stderr, "\n");
2168 goto errorTreeReturn;
2171 /* if they are both literal */
2172 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2174 tree->type = EX_VALUE;
2175 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2176 valFromType (RETYPE (tree)), '&');
2178 tree->right = tree->left = NULL;
2179 TETYPE (tree) = tree->opval.val->etype;
2180 TTYPE (tree) = tree->opval.val->type;
2184 /* see if this is a GETHBIT operation if yes
2187 ast *otree = optimizeGetHbit (tree);
2190 return decorateType (otree);
2194 computeType (LTYPE (tree), RTYPE (tree));
2195 TETYPE (tree) = getSpec (TTYPE (tree));
2197 LRVAL (tree) = RRVAL (tree) = 1;
2201 /*------------------------------------------------------------------*/
2202 /*----------------------------*/
2204 /*----------------------------*/
2205 p = newLink (DECLARATOR);
2206 /* if bit field then error */
2207 if (IS_BITVAR (tree->left->etype))
2209 werror (E_ILLEGAL_ADDR, "address of bit variable");
2210 goto errorTreeReturn;
2213 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2215 werror (E_ILLEGAL_ADDR, "address of register variable");
2216 goto errorTreeReturn;
2219 if (IS_FUNC (LTYPE (tree)))
2221 // this ought to be ignored
2222 return (tree->left);
2225 if (IS_LITERAL(LTYPE(tree)))
2227 werror (E_ILLEGAL_ADDR, "address of literal");
2228 goto errorTreeReturn;
2233 werror (E_LVALUE_REQUIRED, "address of");
2234 goto errorTreeReturn;
2236 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2238 DCL_TYPE (p) = CPOINTER;
2239 DCL_PTR_CONST (p) = port->mem.code_ro;
2241 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2242 DCL_TYPE (p) = FPOINTER;
2243 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2244 DCL_TYPE (p) = PPOINTER;
2245 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2246 DCL_TYPE (p) = IPOINTER;
2247 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2248 DCL_TYPE (p) = EEPPOINTER;
2249 else if (SPEC_OCLS(tree->left->etype))
2250 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2252 DCL_TYPE (p) = POINTER;
2254 if (IS_AST_SYM_VALUE (tree->left))
2256 AST_SYMBOL (tree->left)->addrtaken = 1;
2257 AST_SYMBOL (tree->left)->allocreq = 1;
2260 p->next = LTYPE (tree);
2262 TETYPE (tree) = getSpec (TTYPE (tree));
2263 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2264 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2269 /*------------------------------------------------------------------*/
2270 /*----------------------------*/
2272 /*----------------------------*/
2274 /* if the rewrite succeeds then don't go any furthur */
2276 ast *wtree = optimizeRRCRLC (tree);
2278 return decorateType (wtree);
2281 /*------------------------------------------------------------------*/
2282 /*----------------------------*/
2284 /*----------------------------*/
2286 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2288 werror (E_BITWISE_OP);
2289 werror (W_CONTINUE, "left & right types are ");
2290 printTypeChain (LTYPE (tree), stderr);
2291 fprintf (stderr, ",");
2292 printTypeChain (RTYPE (tree), stderr);
2293 fprintf (stderr, "\n");
2294 goto errorTreeReturn;
2297 /* if they are both literal then */
2298 /* rewrite the tree */
2299 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2301 tree->type = EX_VALUE;
2302 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2303 valFromType (RETYPE (tree)),
2305 tree->right = tree->left = NULL;
2306 TETYPE (tree) = tree->opval.val->etype;
2307 TTYPE (tree) = tree->opval.val->type;
2310 LRVAL (tree) = RRVAL (tree) = 1;
2311 TETYPE (tree) = getSpec (TTYPE (tree) =
2312 computeType (LTYPE (tree),
2315 /*------------------------------------------------------------------*/
2316 /*----------------------------*/
2318 /*----------------------------*/
2320 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2322 werror (E_INVALID_OP, "divide");
2323 goto errorTreeReturn;
2325 /* if they are both literal then */
2326 /* rewrite the tree */
2327 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2329 tree->type = EX_VALUE;
2330 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2331 valFromType (RETYPE (tree)));
2332 tree->right = tree->left = NULL;
2333 TETYPE (tree) = getSpec (TTYPE (tree) =
2334 tree->opval.val->type);
2337 LRVAL (tree) = RRVAL (tree) = 1;
2338 TETYPE (tree) = getSpec (TTYPE (tree) =
2339 computeType (LTYPE (tree),
2343 /*------------------------------------------------------------------*/
2344 /*----------------------------*/
2346 /*----------------------------*/
2348 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2350 werror (E_BITWISE_OP);
2351 werror (W_CONTINUE, "left & right types are ");
2352 printTypeChain (LTYPE (tree), stderr);
2353 fprintf (stderr, ",");
2354 printTypeChain (RTYPE (tree), stderr);
2355 fprintf (stderr, "\n");
2356 goto errorTreeReturn;
2358 /* if they are both literal then */
2359 /* rewrite the tree */
2360 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2362 tree->type = EX_VALUE;
2363 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2364 valFromType (RETYPE (tree)));
2365 tree->right = tree->left = NULL;
2366 TETYPE (tree) = getSpec (TTYPE (tree) =
2367 tree->opval.val->type);
2370 LRVAL (tree) = RRVAL (tree) = 1;
2371 TETYPE (tree) = getSpec (TTYPE (tree) =
2372 computeType (LTYPE (tree),
2376 /*------------------------------------------------------------------*/
2377 /*----------------------------*/
2378 /* address dereference */
2379 /*----------------------------*/
2380 case '*': /* can be unary : if right is null then unary operation */
2383 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2385 werror (E_PTR_REQD);
2386 goto errorTreeReturn;
2391 werror (E_LVALUE_REQUIRED, "pointer deref");
2392 goto errorTreeReturn;
2394 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2395 TETYPE (tree) = getSpec (TTYPE (tree));
2396 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2400 /*------------------------------------------------------------------*/
2401 /*----------------------------*/
2402 /* multiplication */
2403 /*----------------------------*/
2404 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2406 werror (E_INVALID_OP, "multiplication");
2407 goto errorTreeReturn;
2410 /* if they are both literal then */
2411 /* rewrite the tree */
2412 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2414 tree->type = EX_VALUE;
2415 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2416 valFromType (RETYPE (tree)));
2417 tree->right = tree->left = NULL;
2418 TETYPE (tree) = getSpec (TTYPE (tree) =
2419 tree->opval.val->type);
2423 /* if left is a literal exchange left & right */
2424 if (IS_LITERAL (LTYPE (tree)))
2426 ast *tTree = tree->left;
2427 tree->left = tree->right;
2428 tree->right = tTree;
2431 LRVAL (tree) = RRVAL (tree) = 1;
2432 TETYPE (tree) = getSpec (TTYPE (tree) =
2433 computeType (LTYPE (tree),
2436 /* promote result to int if left & right are char
2437 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2438 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2439 SPEC_NOUN(TETYPE(tree)) = V_INT;
2444 /*------------------------------------------------------------------*/
2445 /*----------------------------*/
2446 /* unary '+' operator */
2447 /*----------------------------*/
2452 if (!IS_INTEGRAL (LTYPE (tree)))
2454 werror (E_UNARY_OP, '+');
2455 goto errorTreeReturn;
2458 /* if left is a literal then do it */
2459 if (IS_LITERAL (LTYPE (tree)))
2461 tree->type = EX_VALUE;
2462 tree->opval.val = valFromType (LETYPE (tree));
2464 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2468 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2472 /*------------------------------------------------------------------*/
2473 /*----------------------------*/
2475 /*----------------------------*/
2477 /* this is not a unary operation */
2478 /* if both pointers then problem */
2479 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2480 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2482 werror (E_PTR_PLUS_PTR);
2483 goto errorTreeReturn;
2486 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2487 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2489 werror (E_PLUS_INVALID, "+");
2490 goto errorTreeReturn;
2493 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2494 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2496 werror (E_PLUS_INVALID, "+");
2497 goto errorTreeReturn;
2499 /* if they are both literal then */
2500 /* rewrite the tree */
2501 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2503 tree->type = EX_VALUE;
2504 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2505 valFromType (RETYPE (tree)));
2506 tree->right = tree->left = NULL;
2507 TETYPE (tree) = getSpec (TTYPE (tree) =
2508 tree->opval.val->type);
2512 /* if the right is a pointer or left is a literal
2513 xchange left & right */
2514 if (IS_ARRAY (RTYPE (tree)) ||
2515 IS_PTR (RTYPE (tree)) ||
2516 IS_LITERAL (LTYPE (tree)))
2518 ast *tTree = tree->left;
2519 tree->left = tree->right;
2520 tree->right = tTree;
2523 LRVAL (tree) = RRVAL (tree) = 1;
2524 /* if the left is a pointer */
2525 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2526 TETYPE (tree) = getSpec (TTYPE (tree) =
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 computeType (LTYPE (tree),
2534 /*------------------------------------------------------------------*/
2535 /*----------------------------*/
2537 /*----------------------------*/
2538 case '-': /* can be unary */
2539 /* if right is null then unary */
2543 if (!IS_ARITHMETIC (LTYPE (tree)))
2545 werror (E_UNARY_OP, tree->opval.op);
2546 goto errorTreeReturn;
2549 /* if left is a literal then do it */
2550 if (IS_LITERAL (LTYPE (tree)))
2552 tree->type = EX_VALUE;
2553 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2555 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2556 SPEC_USIGN(TETYPE(tree)) = 0;
2560 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2564 /*------------------------------------------------------------------*/
2565 /*----------------------------*/
2567 /*----------------------------*/
2569 if (!(IS_PTR (LTYPE (tree)) ||
2570 IS_ARRAY (LTYPE (tree)) ||
2571 IS_ARITHMETIC (LTYPE (tree))))
2573 werror (E_PLUS_INVALID, "-");
2574 goto errorTreeReturn;
2577 if (!(IS_PTR (RTYPE (tree)) ||
2578 IS_ARRAY (RTYPE (tree)) ||
2579 IS_ARITHMETIC (RTYPE (tree))))
2581 werror (E_PLUS_INVALID, "-");
2582 goto errorTreeReturn;
2585 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2586 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2587 IS_INTEGRAL (RTYPE (tree))))
2589 werror (E_PLUS_INVALID, "-");
2590 goto errorTreeReturn;
2593 /* if they are both literal then */
2594 /* rewrite the tree */
2595 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2597 tree->type = EX_VALUE;
2598 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2599 valFromType (RETYPE (tree)));
2600 tree->right = tree->left = NULL;
2601 TETYPE (tree) = getSpec (TTYPE (tree) =
2602 tree->opval.val->type);
2606 /* if the left & right are equal then zero */
2607 if (isAstEqual (tree->left, tree->right))
2609 tree->type = EX_VALUE;
2610 tree->left = tree->right = NULL;
2611 tree->opval.val = constVal ("0");
2612 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2616 /* if both of them are pointers or arrays then */
2617 /* the result is going to be an integer */
2618 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2619 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2620 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2622 /* if only the left is a pointer */
2623 /* then result is a pointer */
2624 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2625 TETYPE (tree) = getSpec (TTYPE (tree) =
2628 TETYPE (tree) = getSpec (TTYPE (tree) =
2629 computeType (LTYPE (tree),
2631 LRVAL (tree) = RRVAL (tree) = 1;
2634 /*------------------------------------------------------------------*/
2635 /*----------------------------*/
2637 /*----------------------------*/
2639 /* can be only integral type */
2640 if (!IS_INTEGRAL (LTYPE (tree)))
2642 werror (E_UNARY_OP, tree->opval.op);
2643 goto errorTreeReturn;
2646 /* if left is a literal then do it */
2647 if (IS_LITERAL (LTYPE (tree)))
2649 tree->type = EX_VALUE;
2650 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2652 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2656 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2659 /*------------------------------------------------------------------*/
2660 /*----------------------------*/
2662 /*----------------------------*/
2664 /* can be pointer */
2665 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2666 !IS_PTR (LTYPE (tree)) &&
2667 !IS_ARRAY (LTYPE (tree)))
2669 werror (E_UNARY_OP, tree->opval.op);
2670 goto errorTreeReturn;
2673 /* if left is a literal then do it */
2674 if (IS_LITERAL (LTYPE (tree)))
2676 tree->type = EX_VALUE;
2677 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2679 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2683 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2686 /*------------------------------------------------------------------*/
2687 /*----------------------------*/
2689 /*----------------------------*/
2692 TTYPE (tree) = LTYPE (tree);
2693 TETYPE (tree) = LETYPE (tree);
2697 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2702 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2704 werror (E_SHIFT_OP_INVALID);
2705 werror (W_CONTINUE, "left & right types are ");
2706 printTypeChain (LTYPE (tree), stderr);
2707 fprintf (stderr, ",");
2708 printTypeChain (RTYPE (tree), stderr);
2709 fprintf (stderr, "\n");
2710 goto errorTreeReturn;
2713 /* if they are both literal then */
2714 /* rewrite the tree */
2715 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2717 tree->type = EX_VALUE;
2718 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2719 valFromType (RETYPE (tree)),
2720 (tree->opval.op == LEFT_OP ? 1 : 0));
2721 tree->right = tree->left = NULL;
2722 TETYPE (tree) = getSpec (TTYPE (tree) =
2723 tree->opval.val->type);
2727 /* if only the right side is a literal & we are
2728 shifting more than size of the left operand then zero */
2729 if (IS_LITERAL (RTYPE (tree)) &&
2730 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2731 (getSize (LTYPE (tree)) * 8))
2733 if (tree->opval.op==LEFT_OP ||
2734 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2735 lineno=tree->lineno;
2736 werror (W_SHIFT_CHANGED,
2737 (tree->opval.op == LEFT_OP ? "left" : "right"));
2738 tree->type = EX_VALUE;
2739 tree->left = tree->right = NULL;
2740 tree->opval.val = constVal ("0");
2741 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2745 LRVAL (tree) = RRVAL (tree) = 1;
2746 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2748 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2752 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2756 /*------------------------------------------------------------------*/
2757 /*----------------------------*/
2759 /*----------------------------*/
2760 case CAST: /* change the type */
2761 /* cannot cast to an aggregate type */
2762 if (IS_AGGREGATE (LTYPE (tree)))
2764 werror (E_CAST_ILLEGAL);
2765 goto errorTreeReturn;
2768 /* make sure the type is complete and sane */
2769 checkTypeSanity(LETYPE(tree), "(cast)");
2772 /* if the right is a literal replace the tree */
2773 if (IS_LITERAL (RETYPE (tree))) {
2774 if (!IS_PTR (LTYPE (tree))) {
2775 tree->type = EX_VALUE;
2777 valCastLiteral (LTYPE (tree),
2778 floatFromVal (valFromType (RETYPE (tree))));
2781 TTYPE (tree) = tree->opval.val->type;
2782 tree->values.literalFromCast = 1;
2783 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2784 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2785 sym_link *rest = LTYPE(tree)->next;
2786 werror(W_LITERAL_GENERIC);
2787 TTYPE(tree) = newLink(DECLARATOR);
2788 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2789 TTYPE(tree)->next = rest;
2790 tree->left->opval.lnk = TTYPE(tree);
2793 TTYPE (tree) = LTYPE (tree);
2797 TTYPE (tree) = LTYPE (tree);
2801 #if 0 // this is already checked, now this could be explicit
2802 /* if pointer to struct then check names */
2803 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2804 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2805 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2807 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2808 SPEC_STRUCT(LETYPE(tree))->tag);
2811 /* if the right is a literal replace the tree */
2812 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2813 tree->type = EX_VALUE;
2815 valCastLiteral (LTYPE (tree),
2816 floatFromVal (valFromType (RETYPE (tree))));
2819 TTYPE (tree) = tree->opval.val->type;
2820 tree->values.literalFromCast = 1;
2822 TTYPE (tree) = LTYPE (tree);
2826 TETYPE (tree) = getSpec (TTYPE (tree));
2830 /*------------------------------------------------------------------*/
2831 /*----------------------------*/
2832 /* logical &&, || */
2833 /*----------------------------*/
2836 /* each must me arithmetic type or be a pointer */
2837 if (!IS_PTR (LTYPE (tree)) &&
2838 !IS_ARRAY (LTYPE (tree)) &&
2839 !IS_INTEGRAL (LTYPE (tree)))
2841 werror (E_COMPARE_OP);
2842 goto errorTreeReturn;
2845 if (!IS_PTR (RTYPE (tree)) &&
2846 !IS_ARRAY (RTYPE (tree)) &&
2847 !IS_INTEGRAL (RTYPE (tree)))
2849 werror (E_COMPARE_OP);
2850 goto errorTreeReturn;
2852 /* if they are both literal then */
2853 /* rewrite the tree */
2854 if (IS_LITERAL (RTYPE (tree)) &&
2855 IS_LITERAL (LTYPE (tree)))
2857 tree->type = EX_VALUE;
2858 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2859 valFromType (RETYPE (tree)),
2861 tree->right = tree->left = NULL;
2862 TETYPE (tree) = getSpec (TTYPE (tree) =
2863 tree->opval.val->type);
2866 LRVAL (tree) = RRVAL (tree) = 1;
2867 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2870 /*------------------------------------------------------------------*/
2871 /*----------------------------*/
2872 /* comparison operators */
2873 /*----------------------------*/
2881 ast *lt = optimizeCompare (tree);
2887 /* if they are pointers they must be castable */
2888 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2890 if (tree->opval.op==EQ_OP &&
2891 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
2892 // we cannot cast a gptr to a !gptr: switch the leaves
2893 struct ast *s=tree->left;
2894 tree->left=tree->right;
2897 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2899 werror (E_COMPARE_OP);
2900 fprintf (stderr, "comparring type ");
2901 printTypeChain (LTYPE (tree), stderr);
2902 fprintf (stderr, "to type ");
2903 printTypeChain (RTYPE (tree), stderr);
2904 fprintf (stderr, "\n");
2905 goto errorTreeReturn;
2908 /* else they should be promotable to one another */
2911 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2912 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2914 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2916 werror (E_COMPARE_OP);
2917 fprintf (stderr, "comparing type ");
2918 printTypeChain (LTYPE (tree), stderr);
2919 fprintf (stderr, "to type ");
2920 printTypeChain (RTYPE (tree), stderr);
2921 fprintf (stderr, "\n");
2922 goto errorTreeReturn;
2925 /* if unsigned value < 0 then always false */
2926 /* if (unsigned value) > 0 then (unsigned value) */
2927 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2928 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2930 if (tree->opval.op == '<') {
2933 if (tree->opval.op == '>') {
2937 /* if they are both literal then */
2938 /* rewrite the tree */
2939 if (IS_LITERAL (RTYPE (tree)) &&
2940 IS_LITERAL (LTYPE (tree)))
2942 tree->type = EX_VALUE;
2943 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2944 valFromType (RETYPE (tree)),
2946 tree->right = tree->left = NULL;
2947 TETYPE (tree) = getSpec (TTYPE (tree) =
2948 tree->opval.val->type);
2951 LRVAL (tree) = RRVAL (tree) = 1;
2952 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2955 /*------------------------------------------------------------------*/
2956 /*----------------------------*/
2958 /*----------------------------*/
2959 case SIZEOF: /* evaluate wihout code generation */
2960 /* change the type to a integer */
2961 tree->type = EX_VALUE;
2962 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2963 tree->opval.val = constVal (buffer);
2964 tree->right = tree->left = NULL;
2965 TETYPE (tree) = getSpec (TTYPE (tree) =
2966 tree->opval.val->type);
2969 /*------------------------------------------------------------------*/
2970 /*----------------------------*/
2972 /*----------------------------*/
2974 /* return typeof enum value */
2975 tree->type = EX_VALUE;
2978 if (IS_SPEC(tree->right->ftype)) {
2979 switch (SPEC_NOUN(tree->right->ftype)) {
2981 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2982 else typeofv = TYPEOF_INT;
2985 typeofv = TYPEOF_FLOAT;
2988 typeofv = TYPEOF_CHAR;
2991 typeofv = TYPEOF_VOID;
2994 typeofv = TYPEOF_STRUCT;
2997 typeofv = TYPEOF_BIT;
3000 typeofv = TYPEOF_SBIT;
3006 switch (DCL_TYPE(tree->right->ftype)) {
3008 typeofv = TYPEOF_POINTER;
3011 typeofv = TYPEOF_FPOINTER;
3014 typeofv = TYPEOF_CPOINTER;
3017 typeofv = TYPEOF_GPOINTER;
3020 typeofv = TYPEOF_PPOINTER;
3023 typeofv = TYPEOF_IPOINTER;
3026 typeofv = TYPEOF_ARRAY;
3029 typeofv = TYPEOF_FUNCTION;
3035 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3036 tree->opval.val = constVal (buffer);
3037 tree->right = tree->left = NULL;
3038 TETYPE (tree) = getSpec (TTYPE (tree) =
3039 tree->opval.val->type);
3042 /*------------------------------------------------------------------*/
3043 /*----------------------------*/
3044 /* conditional operator '?' */
3045 /*----------------------------*/
3047 /* the type is value of the colon operator (on the right) */
3048 assert(IS_COLON_OP(tree->right));
3049 /* if already known then replace the tree : optimizer will do it
3050 but faster to do it here */
3051 if (IS_LITERAL (LTYPE(tree))) {
3052 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3053 return decorateType(tree->right->left) ;
3055 return decorateType(tree->right->right) ;
3058 tree->right = decorateType(tree->right);
3059 TTYPE (tree) = RTYPE(tree);
3060 TETYPE (tree) = getSpec (TTYPE (tree));
3065 /* if they don't match we have a problem */
3066 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3068 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3069 goto errorTreeReturn;
3072 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3073 TETYPE (tree) = getSpec (TTYPE (tree));
3077 #if 0 // assignment operators are converted by the parser
3078 /*------------------------------------------------------------------*/
3079 /*----------------------------*/
3080 /* assignment operators */
3081 /*----------------------------*/
3084 /* for these it must be both must be integral */
3085 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3086 !IS_ARITHMETIC (RTYPE (tree)))
3088 werror (E_OPS_INTEGRAL);
3089 goto errorTreeReturn;
3092 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3094 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3095 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3099 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3100 goto errorTreeReturn;
3111 /* for these it must be both must be integral */
3112 if (!IS_INTEGRAL (LTYPE (tree)) ||
3113 !IS_INTEGRAL (RTYPE (tree)))
3115 werror (E_OPS_INTEGRAL);
3116 goto errorTreeReturn;
3119 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3121 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3122 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3126 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3127 goto errorTreeReturn;
3133 /*------------------------------------------------------------------*/
3134 /*----------------------------*/
3136 /*----------------------------*/
3138 if (!(IS_PTR (LTYPE (tree)) ||
3139 IS_ARITHMETIC (LTYPE (tree))))
3141 werror (E_PLUS_INVALID, "-=");
3142 goto errorTreeReturn;
3145 if (!(IS_PTR (RTYPE (tree)) ||
3146 IS_ARITHMETIC (RTYPE (tree))))
3148 werror (E_PLUS_INVALID, "-=");
3149 goto errorTreeReturn;
3152 TETYPE (tree) = getSpec (TTYPE (tree) =
3153 computeType (LTYPE (tree),
3156 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3157 werror (E_CODE_WRITE, "-=");
3161 werror (E_LVALUE_REQUIRED, "-=");
3162 goto errorTreeReturn;
3168 /*------------------------------------------------------------------*/
3169 /*----------------------------*/
3171 /*----------------------------*/
3173 /* this is not a unary operation */
3174 /* if both pointers then problem */
3175 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3177 werror (E_PTR_PLUS_PTR);
3178 goto errorTreeReturn;
3181 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3183 werror (E_PLUS_INVALID, "+=");
3184 goto errorTreeReturn;
3187 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3189 werror (E_PLUS_INVALID, "+=");
3190 goto errorTreeReturn;
3193 TETYPE (tree) = getSpec (TTYPE (tree) =
3194 computeType (LTYPE (tree),
3197 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3198 werror (E_CODE_WRITE, "+=");
3202 werror (E_LVALUE_REQUIRED, "+=");
3203 goto errorTreeReturn;
3206 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3207 tree->opval.op = '=';
3212 /*------------------------------------------------------------------*/
3213 /*----------------------------*/
3214 /* straight assignemnt */
3215 /*----------------------------*/
3217 /* cannot be an aggregate */
3218 if (IS_AGGREGATE (LTYPE (tree)))
3220 werror (E_AGGR_ASSIGN);
3221 goto errorTreeReturn;
3224 /* they should either match or be castable */
3225 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3227 werror (E_TYPE_MISMATCH, "assignment", " ");
3228 printFromToType(RTYPE(tree),LTYPE(tree));
3231 /* if the left side of the tree is of type void
3232 then report error */
3233 if (IS_VOID (LTYPE (tree)))
3235 werror (E_CAST_ZERO);
3236 printFromToType(RTYPE(tree), LTYPE(tree));
3239 TETYPE (tree) = getSpec (TTYPE (tree) =
3243 if (!tree->initMode ) {
3244 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3245 werror (E_CODE_WRITE, "=");
3249 werror (E_LVALUE_REQUIRED, "=");
3250 goto errorTreeReturn;
3255 /*------------------------------------------------------------------*/
3256 /*----------------------------*/
3257 /* comma operator */
3258 /*----------------------------*/
3260 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3263 /*------------------------------------------------------------------*/
3264 /*----------------------------*/
3266 /*----------------------------*/
3270 if (processParms (tree->left,
3271 FUNC_ARGS(tree->left->ftype),
3272 tree->right, &parmNumber, TRUE)) {
3273 goto errorTreeReturn;
3276 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3277 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3279 reverseParms (tree->right);
3282 if (IS_CODEPTR(LTYPE(tree))) {
3283 TTYPE(tree) = LTYPE(tree)->next->next;
3285 TTYPE(tree) = LTYPE(tree)->next;
3287 TETYPE (tree) = getSpec (TTYPE (tree));
3290 /*------------------------------------------------------------------*/
3291 /*----------------------------*/
3292 /* return statement */
3293 /*----------------------------*/
3298 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3300 werror (W_RETURN_MISMATCH);
3301 printFromToType (RTYPE(tree), currFunc->type->next);
3302 goto errorTreeReturn;
3305 if (IS_VOID (currFunc->type->next)
3307 !IS_VOID (RTYPE (tree)))
3309 werror (E_FUNC_VOID);
3310 goto errorTreeReturn;
3313 /* if there is going to be a casing required then add it */
3314 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3317 decorateType (newNode (CAST,
3318 newAst_LINK (copyLinkChain (currFunc->type->next)),
3327 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3329 werror (W_VOID_FUNC, currFunc->name);
3330 goto errorTreeReturn;
3333 TTYPE (tree) = TETYPE (tree) = NULL;
3336 /*------------------------------------------------------------------*/
3337 /*----------------------------*/
3338 /* switch statement */
3339 /*----------------------------*/
3341 /* the switch value must be an integer */
3342 if (!IS_INTEGRAL (LTYPE (tree)))
3344 werror (E_SWITCH_NON_INTEGER);
3345 goto errorTreeReturn;
3348 TTYPE (tree) = TETYPE (tree) = NULL;
3351 /*------------------------------------------------------------------*/
3352 /*----------------------------*/
3354 /*----------------------------*/
3356 tree->left = backPatchLabels (tree->left,
3359 TTYPE (tree) = TETYPE (tree) = NULL;
3362 /*------------------------------------------------------------------*/
3363 /*----------------------------*/
3365 /*----------------------------*/
3368 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3369 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3370 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3372 /* if the for loop is reversible then
3373 reverse it otherwise do what we normally
3379 if (isLoopReversible (tree, &sym, &init, &end))
3380 return reverseLoop (tree, sym, init, end);
3382 return decorateType (createFor (AST_FOR (tree, trueLabel),
3383 AST_FOR (tree, continueLabel),
3384 AST_FOR (tree, falseLabel),
3385 AST_FOR (tree, condLabel),
3386 AST_FOR (tree, initExpr),
3387 AST_FOR (tree, condExpr),
3388 AST_FOR (tree, loopExpr),
3392 TTYPE (tree) = TETYPE (tree) = NULL;
3396 /* some error found this tree will be killed */
3398 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3399 tree->opval.op = NULLOP;
3405 /*-----------------------------------------------------------------*/
3406 /* sizeofOp - processes size of operation */
3407 /*-----------------------------------------------------------------*/
3409 sizeofOp (sym_link * type)
3413 /* make sure the type is complete and sane */
3414 checkTypeSanity(type, "(sizeof)");
3416 /* get the size and convert it to character */
3417 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3419 /* now convert into value */
3420 return constVal (buff);
3424 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3425 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3426 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3427 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3428 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3429 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3430 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3432 /*-----------------------------------------------------------------*/
3433 /* backPatchLabels - change and or not operators to flow control */
3434 /*-----------------------------------------------------------------*/
3436 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3442 if (!(IS_ANDORNOT (tree)))
3445 /* if this an and */
3448 static int localLbl = 0;
3451 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3452 localLabel = newSymbol (buffer, NestLevel);
3454 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3456 /* if left is already a IFX then just change the if true label in that */
3457 if (!IS_IFX (tree->left))
3458 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3460 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3461 /* right is a IFX then just join */
3462 if (IS_IFX (tree->right))
3463 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3465 tree->right = createLabel (localLabel, tree->right);
3466 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3468 return newNode (NULLOP, tree->left, tree->right);
3471 /* if this is an or operation */
3474 static int localLbl = 0;
3477 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3478 localLabel = newSymbol (buffer, NestLevel);
3480 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3482 /* if left is already a IFX then just change the if true label in that */
3483 if (!IS_IFX (tree->left))
3484 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3486 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3487 /* right is a IFX then just join */
3488 if (IS_IFX (tree->right))
3489 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3491 tree->right = createLabel (localLabel, tree->right);
3492 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3494 return newNode (NULLOP, tree->left, tree->right);
3500 int wasnot = IS_NOT (tree->left);
3501 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3503 /* if the left is already a IFX */
3504 if (!IS_IFX (tree->left))
3505 tree->left = newNode (IFX, tree->left, NULL);
3509 tree->left->trueLabel = trueLabel;
3510 tree->left->falseLabel = falseLabel;
3514 tree->left->trueLabel = falseLabel;
3515 tree->left->falseLabel = trueLabel;
3522 tree->trueLabel = trueLabel;
3523 tree->falseLabel = falseLabel;
3530 /*-----------------------------------------------------------------*/
3531 /* createBlock - create expression tree for block */
3532 /*-----------------------------------------------------------------*/
3534 createBlock (symbol * decl, ast * body)
3538 /* if the block has nothing */
3542 ex = newNode (BLOCK, NULL, body);
3543 ex->values.sym = decl;
3545 ex->right = ex->right;
3551 /*-----------------------------------------------------------------*/
3552 /* createLabel - creates the expression tree for labels */
3553 /*-----------------------------------------------------------------*/
3555 createLabel (symbol * label, ast * stmnt)
3558 char name[SDCC_NAME_MAX + 1];
3561 /* must create fresh symbol if the symbol name */
3562 /* exists in the symbol table, since there can */
3563 /* be a variable with the same name as the labl */
3564 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3565 (csym->level == label->level))
3566 label = newSymbol (label->name, label->level);
3568 /* change the name before putting it in add _ */
3569 SNPRINTF(name, sizeof(name), "%s", label->name);
3571 /* put the label in the LabelSymbol table */
3572 /* but first check if a label of the same */
3574 if ((csym = findSym (LabelTab, NULL, name)))
3575 werror (E_DUPLICATE_LABEL, label->name);
3577 addSym (LabelTab, label, name, label->level, 0, 0);
3580 label->key = labelKey++;
3581 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3587 /*-----------------------------------------------------------------*/
3588 /* createCase - generates the parsetree for a case statement */
3589 /*-----------------------------------------------------------------*/
3591 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3593 char caseLbl[SDCC_NAME_MAX + 1];
3597 /* if the switch statement does not exist */
3598 /* then case is out of context */
3601 werror (E_CASE_CONTEXT);
3605 caseVal = decorateType (resolveSymbols (caseVal));
3606 /* if not a constant then error */
3607 if (!IS_LITERAL (caseVal->ftype))
3609 werror (E_CASE_CONSTANT);
3613 /* if not a integer than error */
3614 if (!IS_INTEGRAL (caseVal->ftype))
3616 werror (E_CASE_NON_INTEGER);
3620 /* find the end of the switch values chain */
3621 if (!(val = swStat->values.switchVals.swVals))
3622 swStat->values.switchVals.swVals = caseVal->opval.val;
3625 /* also order the cases according to value */
3627 int cVal = (int) floatFromVal (caseVal->opval.val);
3628 while (val && (int) floatFromVal (val) < cVal)
3634 /* if we reached the end then */
3637 pval->next = caseVal->opval.val;
3641 /* we found a value greater than */
3642 /* the current value we must add this */
3643 /* before the value */
3644 caseVal->opval.val->next = val;
3646 /* if this was the first in chain */
3647 if (swStat->values.switchVals.swVals == val)
3648 swStat->values.switchVals.swVals =
3651 pval->next = caseVal->opval.val;
3656 /* create the case label */
3657 SNPRINTF(caseLbl, sizeof(caseLbl),
3659 swStat->values.switchVals.swNum,
3660 (int) floatFromVal (caseVal->opval.val));
3662 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3667 /*-----------------------------------------------------------------*/
3668 /* createDefault - creates the parse tree for the default statement */
3669 /*-----------------------------------------------------------------*/
3671 createDefault (ast * swStat, ast * stmnt)
3673 char defLbl[SDCC_NAME_MAX + 1];
3675 /* if the switch statement does not exist */
3676 /* then case is out of context */
3679 werror (E_CASE_CONTEXT);
3683 /* turn on the default flag */
3684 swStat->values.switchVals.swDefault = 1;
3686 /* create the label */
3687 SNPRINTF (defLbl, sizeof(defLbl),
3688 "_default_%d", swStat->values.switchVals.swNum);
3689 return createLabel (newSymbol (defLbl, 0), stmnt);
3692 /*-----------------------------------------------------------------*/
3693 /* createIf - creates the parsetree for the if statement */
3694 /*-----------------------------------------------------------------*/
3696 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3698 static int Lblnum = 0;
3700 symbol *ifTrue, *ifFalse, *ifEnd;
3702 /* if neither exists */
3703 if (!elseBody && !ifBody) {
3704 // if there are no side effects (i++, j() etc)
3705 if (!hasSEFcalls(condAst)) {
3710 /* create the labels */
3711 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3712 ifFalse = newSymbol (buffer, NestLevel);
3713 /* if no else body then end == false */
3718 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3719 ifEnd = newSymbol (buffer, NestLevel);
3722 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3723 ifTrue = newSymbol (buffer, NestLevel);
3727 /* attach the ifTrue label to the top of it body */
3728 ifBody = createLabel (ifTrue, ifBody);
3729 /* attach a goto end to the ifBody if else is present */
3732 ifBody = newNode (NULLOP, ifBody,
3734 newAst_VALUE (symbolVal (ifEnd)),
3736 /* put the elseLabel on the else body */
3737 elseBody = createLabel (ifFalse, elseBody);
3738 /* out the end at the end of the body */
3739 elseBody = newNode (NULLOP,
3741 createLabel (ifEnd, NULL));
3745 ifBody = newNode (NULLOP, ifBody,
3746 createLabel (ifFalse, NULL));
3748 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3749 if (IS_IFX (condAst))
3752 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3754 return newNode (NULLOP, ifTree,
3755 newNode (NULLOP, ifBody, elseBody));
3759 /*-----------------------------------------------------------------*/
3760 /* createDo - creates parse tree for do */
3763 /* _docontinue_n: */
3764 /* condition_expression +-> trueLabel -> _dobody_n */
3766 /* +-> falseLabel-> _dobreak_n */
3768 /*-----------------------------------------------------------------*/
3770 createDo (symbol * trueLabel, symbol * continueLabel,
3771 symbol * falseLabel, ast * condAst, ast * doBody)
3776 /* if the body does not exist then it is simple */
3779 condAst = backPatchLabels (condAst, continueLabel, NULL);
3780 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3781 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3782 doTree->trueLabel = continueLabel;
3783 doTree->falseLabel = NULL;
3787 /* otherwise we have a body */
3788 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3790 /* attach the body label to the top */
3791 doBody = createLabel (trueLabel, doBody);
3792 /* attach the continue label to end of body */
3793 doBody = newNode (NULLOP, doBody,
3794 createLabel (continueLabel, NULL));
3796 /* now put the break label at the end */
3797 if (IS_IFX (condAst))
3800 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3802 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3804 /* putting it together */
3805 return newNode (NULLOP, doBody, doTree);
3808 /*-----------------------------------------------------------------*/
3809 /* createFor - creates parse tree for 'for' statement */
3812 /* condExpr +-> trueLabel -> _forbody_n */
3814 /* +-> falseLabel-> _forbreak_n */
3817 /* _forcontinue_n: */
3819 /* goto _forcond_n ; */
3821 /*-----------------------------------------------------------------*/
3823 createFor (symbol * trueLabel, symbol * continueLabel,
3824 symbol * falseLabel, symbol * condLabel,
3825 ast * initExpr, ast * condExpr, ast * loopExpr,
3830 /* if loopexpression not present then we can generate it */
3831 /* the same way as a while */
3833 return newNode (NULLOP, initExpr,
3834 createWhile (trueLabel, continueLabel,
3835 falseLabel, condExpr, forBody));
3836 /* vanilla for statement */
3837 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3839 if (condExpr && !IS_IFX (condExpr))
3840 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3843 /* attach condition label to condition */
3844 condExpr = createLabel (condLabel, condExpr);
3846 /* attach body label to body */
3847 forBody = createLabel (trueLabel, forBody);
3849 /* attach continue to forLoop expression & attach */
3850 /* goto the forcond @ and of loopExpression */
3851 loopExpr = createLabel (continueLabel,
3855 newAst_VALUE (symbolVal (condLabel)),
3857 /* now start putting them together */
3858 forTree = newNode (NULLOP, initExpr, condExpr);
3859 forTree = newNode (NULLOP, forTree, forBody);
3860 forTree = newNode (NULLOP, forTree, loopExpr);
3861 /* finally add the break label */
3862 forTree = newNode (NULLOP, forTree,
3863 createLabel (falseLabel, NULL));
3867 /*-----------------------------------------------------------------*/
3868 /* createWhile - creates parse tree for while statement */
3869 /* the while statement will be created as follows */
3871 /* _while_continue_n: */
3872 /* condition_expression +-> trueLabel -> _while_boby_n */
3874 /* +-> falseLabel -> _while_break_n */
3875 /* _while_body_n: */
3877 /* goto _while_continue_n */
3878 /* _while_break_n: */
3879 /*-----------------------------------------------------------------*/
3881 createWhile (symbol * trueLabel, symbol * continueLabel,
3882 symbol * falseLabel, ast * condExpr, ast * whileBody)
3886 /* put the continue label */
3887 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3888 condExpr = createLabel (continueLabel, condExpr);
3889 condExpr->lineno = 0;
3891 /* put the body label in front of the body */
3892 whileBody = createLabel (trueLabel, whileBody);
3893 whileBody->lineno = 0;
3894 /* put a jump to continue at the end of the body */
3895 /* and put break label at the end of the body */
3896 whileBody = newNode (NULLOP,
3899 newAst_VALUE (symbolVal (continueLabel)),
3900 createLabel (falseLabel, NULL)));
3902 /* put it all together */
3903 if (IS_IFX (condExpr))
3904 whileTree = condExpr;
3907 whileTree = newNode (IFX, condExpr, NULL);
3908 /* put the true & false labels in place */
3909 whileTree->trueLabel = trueLabel;
3910 whileTree->falseLabel = falseLabel;
3913 return newNode (NULLOP, whileTree, whileBody);
3916 /*-----------------------------------------------------------------*/
3917 /* optimizeGetHbit - get highest order bit of the expression */
3918 /*-----------------------------------------------------------------*/
3920 optimizeGetHbit (ast * tree)
3923 /* if this is not a bit and */
3924 if (!IS_BITAND (tree))
3927 /* will look for tree of the form
3928 ( expr >> ((sizeof expr) -1) ) & 1 */
3929 if (!IS_AST_LIT_VALUE (tree->right))
3932 if (AST_LIT_VALUE (tree->right) != 1)
3935 if (!IS_RIGHT_OP (tree->left))
3938 if (!IS_AST_LIT_VALUE (tree->left->right))
3941 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3942 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3945 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3949 /*-----------------------------------------------------------------*/
3950 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3951 /*-----------------------------------------------------------------*/
3953 optimizeRRCRLC (ast * root)
3955 /* will look for trees of the form
3956 (?expr << 1) | (?expr >> 7) or
3957 (?expr >> 7) | (?expr << 1) will make that
3958 into a RLC : operation ..
3960 (?expr >> 1) | (?expr << 7) or
3961 (?expr << 7) | (?expr >> 1) will make that
3962 into a RRC operation
3963 note : by 7 I mean (number of bits required to hold the
3965 /* if the root operations is not a | operation the not */
3966 if (!IS_BITOR (root))
3969 /* I have to think of a better way to match patterns this sucks */
3970 /* that aside let start looking for the first case : I use a the
3971 negative check a lot to improve the efficiency */
3972 /* (?expr << 1) | (?expr >> 7) */
3973 if (IS_LEFT_OP (root->left) &&
3974 IS_RIGHT_OP (root->right))
3977 if (!SPEC_USIGN (TETYPE (root->left->left)))
3980 if (!IS_AST_LIT_VALUE (root->left->right) ||
3981 !IS_AST_LIT_VALUE (root->right->right))
3984 /* make sure it is the same expression */
3985 if (!isAstEqual (root->left->left,
3989 if (AST_LIT_VALUE (root->left->right) != 1)
3992 if (AST_LIT_VALUE (root->right->right) !=
3993 (getSize (TTYPE (root->left->left)) * 8 - 1))
3996 /* whew got the first case : create the AST */
3997 return newNode (RLC, root->left->left, NULL);
4001 /* check for second case */
4002 /* (?expr >> 7) | (?expr << 1) */
4003 if (IS_LEFT_OP (root->right) &&
4004 IS_RIGHT_OP (root->left))
4007 if (!SPEC_USIGN (TETYPE (root->left->left)))
4010 if (!IS_AST_LIT_VALUE (root->left->right) ||
4011 !IS_AST_LIT_VALUE (root->right->right))
4014 /* make sure it is the same symbol */
4015 if (!isAstEqual (root->left->left,
4019 if (AST_LIT_VALUE (root->right->right) != 1)
4022 if (AST_LIT_VALUE (root->left->right) !=
4023 (getSize (TTYPE (root->left->left)) * 8 - 1))
4026 /* whew got the first case : create the AST */
4027 return newNode (RLC, root->left->left, NULL);
4032 /* third case for RRC */
4033 /* (?symbol >> 1) | (?symbol << 7) */
4034 if (IS_LEFT_OP (root->right) &&
4035 IS_RIGHT_OP (root->left))
4038 if (!SPEC_USIGN (TETYPE (root->left->left)))
4041 if (!IS_AST_LIT_VALUE (root->left->right) ||
4042 !IS_AST_LIT_VALUE (root->right->right))
4045 /* make sure it is the same symbol */
4046 if (!isAstEqual (root->left->left,
4050 if (AST_LIT_VALUE (root->left->right) != 1)
4053 if (AST_LIT_VALUE (root->right->right) !=
4054 (getSize (TTYPE (root->left->left)) * 8 - 1))
4057 /* whew got the first case : create the AST */
4058 return newNode (RRC, root->left->left, NULL);
4062 /* fourth and last case for now */
4063 /* (?symbol << 7) | (?symbol >> 1) */
4064 if (IS_RIGHT_OP (root->right) &&
4065 IS_LEFT_OP (root->left))
4068 if (!SPEC_USIGN (TETYPE (root->left->left)))
4071 if (!IS_AST_LIT_VALUE (root->left->right) ||
4072 !IS_AST_LIT_VALUE (root->right->right))
4075 /* make sure it is the same symbol */
4076 if (!isAstEqual (root->left->left,
4080 if (AST_LIT_VALUE (root->right->right) != 1)
4083 if (AST_LIT_VALUE (root->left->right) !=
4084 (getSize (TTYPE (root->left->left)) * 8 - 1))
4087 /* whew got the first case : create the AST */
4088 return newNode (RRC, root->left->left, NULL);
4092 /* not found return root */
4096 /*-----------------------------------------------------------------*/
4097 /* optimizeCompare - otimizes compares for bit variables */
4098 /*-----------------------------------------------------------------*/
4100 optimizeCompare (ast * root)
4102 ast *optExpr = NULL;
4105 unsigned int litValue;
4107 /* if nothing then return nothing */
4111 /* if not a compare op then do leaves */
4112 if (!IS_COMPARE_OP (root))
4114 root->left = optimizeCompare (root->left);
4115 root->right = optimizeCompare (root->right);
4119 /* if left & right are the same then depending
4120 of the operation do */
4121 if (isAstEqual (root->left, root->right))
4123 switch (root->opval.op)
4128 optExpr = newAst_VALUE (constVal ("0"));
4133 optExpr = newAst_VALUE (constVal ("1"));
4137 return decorateType (optExpr);
4140 vleft = (root->left->type == EX_VALUE ?
4141 root->left->opval.val : NULL);
4143 vright = (root->right->type == EX_VALUE ?
4144 root->right->opval.val : NULL);
4146 /* if left is a BITVAR in BITSPACE */
4147 /* and right is a LITERAL then opt- */
4148 /* imize else do nothing */
4149 if (vleft && vright &&
4150 IS_BITVAR (vleft->etype) &&
4151 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4152 IS_LITERAL (vright->etype))
4155 /* if right side > 1 then comparison may never succeed */
4156 if ((litValue = (int) floatFromVal (vright)) > 1)
4158 werror (W_BAD_COMPARE);
4164 switch (root->opval.op)
4166 case '>': /* bit value greater than 1 cannot be */
4167 werror (W_BAD_COMPARE);
4171 case '<': /* bit value < 1 means 0 */
4173 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4176 case LE_OP: /* bit value <= 1 means no check */
4177 optExpr = newAst_VALUE (vright);
4180 case GE_OP: /* bit value >= 1 means only check for = */
4182 optExpr = newAst_VALUE (vleft);
4187 { /* literal is zero */
4188 switch (root->opval.op)
4190 case '<': /* bit value < 0 cannot be */
4191 werror (W_BAD_COMPARE);
4195 case '>': /* bit value > 0 means 1 */
4197 optExpr = newAst_VALUE (vleft);
4200 case LE_OP: /* bit value <= 0 means no check */
4201 case GE_OP: /* bit value >= 0 means no check */
4202 werror (W_BAD_COMPARE);
4206 case EQ_OP: /* bit == 0 means ! of bit */
4207 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4211 return decorateType (resolveSymbols (optExpr));
4212 } /* end-of-if of BITVAR */
4217 /*-----------------------------------------------------------------*/
4218 /* addSymToBlock : adds the symbol to the first block we find */
4219 /*-----------------------------------------------------------------*/
4221 addSymToBlock (symbol * sym, ast * tree)
4223 /* reached end of tree or a leaf */
4224 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4228 if (IS_AST_OP (tree) &&
4229 tree->opval.op == BLOCK)
4232 symbol *lsym = copySymbol (sym);
4234 lsym->next = AST_VALUES (tree, sym);
4235 AST_VALUES (tree, sym) = lsym;
4239 addSymToBlock (sym, tree->left);
4240 addSymToBlock (sym, tree->right);
4243 /*-----------------------------------------------------------------*/
4244 /* processRegParms - do processing for register parameters */
4245 /*-----------------------------------------------------------------*/
4247 processRegParms (value * args, ast * body)
4251 if (IS_REGPARM (args->etype))
4252 addSymToBlock (args->sym, body);
4257 /*-----------------------------------------------------------------*/
4258 /* resetParmKey - resets the operandkeys for the symbols */
4259 /*-----------------------------------------------------------------*/
4260 DEFSETFUNC (resetParmKey)
4271 /*-----------------------------------------------------------------*/
4272 /* createFunction - This is the key node that calls the iCode for */
4273 /* generating the code for a function. Note code */
4274 /* is generated function by function, later when */
4275 /* add inter-procedural analysis this will change */
4276 /*-----------------------------------------------------------------*/
4278 createFunction (symbol * name, ast * body)
4284 iCode *piCode = NULL;
4286 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4287 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4289 /* if check function return 0 then some problem */
4290 if (checkFunction (name, NULL) == 0)
4293 /* create a dummy block if none exists */
4295 body = newNode (BLOCK, NULL, NULL);
4299 /* check if the function name already in the symbol table */
4300 if ((csym = findSym (SymbolTab, NULL, name->name)))
4303 /* special case for compiler defined functions
4304 we need to add the name to the publics list : this
4305 actually means we are now compiling the compiler
4309 addSet (&publics, name);
4315 allocVariables (name);
4317 name->lastLine = mylineno;
4320 /* set the stack pointer */
4321 /* PENDING: check this for the mcs51 */
4322 stackPtr = -port->stack.direction * port->stack.call_overhead;
4323 if (IFFUNC_ISISR (name->type))
4324 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4325 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4326 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4328 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4330 fetype = getSpec (name->type); /* get the specifier for the function */
4331 /* if this is a reentrant function then */
4332 if (IFFUNC_ISREENT (name->type))
4335 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4337 /* do processing for parameters that are passed in registers */
4338 processRegParms (FUNC_ARGS(name->type), body);
4340 /* set the stack pointer */
4344 /* allocate & autoinit the block variables */
4345 processBlockVars (body, &stack, ALLOCATE);
4347 /* save the stack information */
4348 if (options.useXstack)
4349 name->xstack = SPEC_STAK (fetype) = stack;
4351 name->stack = SPEC_STAK (fetype) = stack;
4353 /* name needs to be mangled */
4354 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4356 body = resolveSymbols (body); /* resolve the symbols */
4357 body = decorateType (body); /* propagateType & do semantic checks */
4359 ex = newAst_VALUE (symbolVal (name)); /* create name */
4360 ex = newNode (FUNCTION, ex, body);
4361 ex->values.args = FUNC_ARGS(name->type);
4363 if (options.dump_tree) PA(ex);
4366 werror (E_FUNC_NO_CODE, name->name);
4370 /* create the node & generate intermediate code */
4372 codeOutFile = code->oFile;
4373 piCode = iCodeFromAst (ex);
4377 werror (E_FUNC_NO_CODE, name->name);
4381 eBBlockFromiCode (piCode);
4383 /* if there are any statics then do them */
4386 GcurMemmap = statsg;
4387 codeOutFile = statsg->oFile;
4388 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4394 /* dealloc the block variables */
4395 processBlockVars (body, &stack, DEALLOCATE);
4396 outputDebugStackSymbols();
4397 /* deallocate paramaters */
4398 deallocParms (FUNC_ARGS(name->type));
4400 if (IFFUNC_ISREENT (name->type))
4403 /* we are done freeup memory & cleanup */
4405 if (port->reset_labelKey) labelKey = 1;
4407 FUNC_HASBODY(name->type) = 1;
4408 addSet (&operKeyReset, name);
4409 applyToSet (operKeyReset, resetParmKey);
4414 cleanUpLevel (LabelTab, 0);
4415 cleanUpBlock (StructTab, 1);
4416 cleanUpBlock (TypedefTab, 1);
4418 xstack->syms = NULL;
4419 istack->syms = NULL;
4424 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4425 /*-----------------------------------------------------------------*/
4426 /* ast_print : prints the ast (for debugging purposes) */
4427 /*-----------------------------------------------------------------*/
4429 void ast_print (ast * tree, FILE *outfile, int indent)
4434 /* can print only decorated trees */
4435 if (!tree->decorated) return;
4437 /* if any child is an error | this one is an error do nothing */
4438 if (tree->isError ||
4439 (tree->left && tree->left->isError) ||
4440 (tree->right && tree->right->isError)) {
4441 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4445 /* print the line */
4446 /* if not block & function */
4447 if (tree->type == EX_OP &&
4448 (tree->opval.op != FUNCTION &&
4449 tree->opval.op != BLOCK &&
4450 tree->opval.op != NULLOP)) {
4453 if (tree->opval.op == FUNCTION) {
4455 value *args=FUNC_ARGS(tree->left->opval.val->type);
4456 fprintf(outfile,"FUNCTION (%s=%p) type (",
4457 tree->left->opval.val->name, tree);
4458 printTypeChain (tree->left->opval.val->type->next,outfile);
4459 fprintf(outfile,") args (");
4462 fprintf (outfile, ", ");
4464 printTypeChain (args ? args->type : NULL, outfile);
4466 args= args ? args->next : NULL;
4468 fprintf(outfile,")\n");
4469 ast_print(tree->left,outfile,indent);
4470 ast_print(tree->right,outfile,indent);
4473 if (tree->opval.op == BLOCK) {
4474 symbol *decls = tree->values.sym;
4475 INDENT(indent,outfile);
4476 fprintf(outfile,"{\n");
4478 INDENT(indent+2,outfile);
4479 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4480 decls->name, decls);
4481 printTypeChain(decls->type,outfile);
4482 fprintf(outfile,")\n");
4484 decls = decls->next;
4486 ast_print(tree->right,outfile,indent+2);
4487 INDENT(indent,outfile);
4488 fprintf(outfile,"}\n");
4491 if (tree->opval.op == NULLOP) {
4492 ast_print(tree->left,outfile,indent);
4493 ast_print(tree->right,outfile,indent);
4496 INDENT(indent,outfile);
4498 /*------------------------------------------------------------------*/
4499 /*----------------------------*/
4500 /* leaf has been reached */
4501 /*----------------------------*/
4502 /* if this is of type value */
4503 /* just get the type */
4504 if (tree->type == EX_VALUE) {
4506 if (IS_LITERAL (tree->opval.val->etype)) {
4507 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4508 (int) floatFromVal(tree->opval.val),
4509 (int) floatFromVal(tree->opval.val),
4510 floatFromVal(tree->opval.val));
4511 } else if (tree->opval.val->sym) {
4512 /* if the undefined flag is set then give error message */
4513 if (tree->opval.val->sym->undefined) {
4514 fprintf(outfile,"UNDEFINED SYMBOL ");
4516 fprintf(outfile,"SYMBOL ");
4518 fprintf(outfile,"(%s=%p)",
4519 tree->opval.val->sym->name,tree);
4522 fprintf(outfile," type (");
4523 printTypeChain(tree->ftype,outfile);
4524 fprintf(outfile,")\n");
4526 fprintf(outfile,"\n");
4531 /* if type link for the case of cast */
4532 if (tree->type == EX_LINK) {
4533 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4534 printTypeChain(tree->opval.lnk,outfile);
4535 fprintf(outfile,")\n");
4540 /* depending on type of operator do */
4542 switch (tree->opval.op) {
4543 /*------------------------------------------------------------------*/
4544 /*----------------------------*/
4546 /*----------------------------*/
4548 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+2);
4552 ast_print(tree->right,outfile,indent+2);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4558 /*----------------------------*/
4560 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4561 printTypeChain(tree->ftype,outfile);
4562 fprintf(outfile,")\n");
4563 ast_print(tree->left,outfile,indent+2);
4564 ast_print(tree->right,outfile,indent+2);
4567 /*------------------------------------------------------------------*/
4568 /*----------------------------*/
4569 /* struct/union pointer */
4570 /*----------------------------*/
4572 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4573 printTypeChain(tree->ftype,outfile);
4574 fprintf(outfile,")\n");
4575 ast_print(tree->left,outfile,indent+2);
4576 ast_print(tree->right,outfile,indent+2);
4579 /*------------------------------------------------------------------*/
4580 /*----------------------------*/
4581 /* ++/-- operation */
4582 /*----------------------------*/
4583 case INC_OP: /* incerement operator unary so left only */
4584 fprintf(outfile,"INC_OP (%p) type (",tree);
4585 printTypeChain(tree->ftype,outfile);
4586 fprintf(outfile,")\n");
4587 ast_print(tree->left,outfile,indent+2);
4591 fprintf(outfile,"DEC_OP (%p) type (",tree);
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->left,outfile,indent+2);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4600 /*----------------------------*/
4603 fprintf(outfile,"& (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+2);
4607 ast_print(tree->right,outfile,indent+2);
4609 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+2);
4613 ast_print(tree->right,outfile,indent+2);
4616 /*----------------------------*/
4618 /*----------------------------*/
4620 fprintf(outfile,"OR (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+2);
4624 ast_print(tree->right,outfile,indent+2);
4626 /*------------------------------------------------------------------*/
4627 /*----------------------------*/
4629 /*----------------------------*/
4631 fprintf(outfile,"XOR (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+2);
4635 ast_print(tree->right,outfile,indent+2);
4638 /*------------------------------------------------------------------*/
4639 /*----------------------------*/
4641 /*----------------------------*/
4643 fprintf(outfile,"DIV (%p) type (",tree);
4644 printTypeChain(tree->ftype,outfile);
4645 fprintf(outfile,")\n");
4646 ast_print(tree->left,outfile,indent+2);
4647 ast_print(tree->right,outfile,indent+2);
4649 /*------------------------------------------------------------------*/
4650 /*----------------------------*/
4652 /*----------------------------*/
4654 fprintf(outfile,"MOD (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+2);
4658 ast_print(tree->right,outfile,indent+2);
4661 /*------------------------------------------------------------------*/
4662 /*----------------------------*/
4663 /* address dereference */
4664 /*----------------------------*/
4665 case '*': /* can be unary : if right is null then unary operation */
4667 fprintf(outfile,"DEREF (%p) type (",tree);
4668 printTypeChain(tree->ftype,outfile);
4669 fprintf(outfile,")\n");
4670 ast_print(tree->left,outfile,indent+2);
4673 /*------------------------------------------------------------------*/
4674 /*----------------------------*/
4675 /* multiplication */
4676 /*----------------------------*/
4677 fprintf(outfile,"MULT (%p) type (",tree);
4678 printTypeChain(tree->ftype,outfile);
4679 fprintf(outfile,")\n");
4680 ast_print(tree->left,outfile,indent+2);
4681 ast_print(tree->right,outfile,indent+2);
4685 /*------------------------------------------------------------------*/
4686 /*----------------------------*/
4687 /* unary '+' operator */
4688 /*----------------------------*/
4692 fprintf(outfile,"UPLUS (%p) type (",tree);
4693 printTypeChain(tree->ftype,outfile);
4694 fprintf(outfile,")\n");
4695 ast_print(tree->left,outfile,indent+2);
4697 /*------------------------------------------------------------------*/
4698 /*----------------------------*/
4700 /*----------------------------*/
4701 fprintf(outfile,"ADD (%p) type (",tree);
4702 printTypeChain(tree->ftype,outfile);
4703 fprintf(outfile,")\n");
4704 ast_print(tree->left,outfile,indent+2);
4705 ast_print(tree->right,outfile,indent+2);
4708 /*------------------------------------------------------------------*/
4709 /*----------------------------*/
4711 /*----------------------------*/
4712 case '-': /* can be unary */
4714 fprintf(outfile,"UMINUS (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+2);
4719 /*------------------------------------------------------------------*/
4720 /*----------------------------*/
4722 /*----------------------------*/
4723 fprintf(outfile,"SUB (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+2);
4727 ast_print(tree->right,outfile,indent+2);
4730 /*------------------------------------------------------------------*/
4731 /*----------------------------*/
4733 /*----------------------------*/
4735 fprintf(outfile,"COMPL (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+2);
4740 /*------------------------------------------------------------------*/
4741 /*----------------------------*/
4743 /*----------------------------*/
4745 fprintf(outfile,"NOT (%p) type (",tree);
4746 printTypeChain(tree->ftype,outfile);
4747 fprintf(outfile,")\n");
4748 ast_print(tree->left,outfile,indent+2);
4750 /*------------------------------------------------------------------*/
4751 /*----------------------------*/
4753 /*----------------------------*/
4755 fprintf(outfile,"RRC (%p) type (",tree);
4756 printTypeChain(tree->ftype,outfile);
4757 fprintf(outfile,")\n");
4758 ast_print(tree->left,outfile,indent+2);
4762 fprintf(outfile,"RLC (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+2);
4768 fprintf(outfile,"GETHBIT (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+2);
4774 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4775 printTypeChain(tree->ftype,outfile);
4776 fprintf(outfile,")\n");
4777 ast_print(tree->left,outfile,indent+2);
4778 ast_print(tree->right,outfile,indent+2);
4781 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4782 printTypeChain(tree->ftype,outfile);
4783 fprintf(outfile,")\n");
4784 ast_print(tree->left,outfile,indent+2);
4785 ast_print(tree->right,outfile,indent+2);
4787 /*------------------------------------------------------------------*/
4788 /*----------------------------*/
4790 /*----------------------------*/
4791 case CAST: /* change the type */
4792 fprintf(outfile,"CAST (%p) from type (",tree);
4793 printTypeChain(tree->right->ftype,outfile);
4794 fprintf(outfile,") to type (");
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->right,outfile,indent+2);
4801 fprintf(outfile,"ANDAND (%p) type (",tree);
4802 printTypeChain(tree->ftype,outfile);
4803 fprintf(outfile,")\n");
4804 ast_print(tree->left,outfile,indent+2);
4805 ast_print(tree->right,outfile,indent+2);
4808 fprintf(outfile,"OROR (%p) type (",tree);
4809 printTypeChain(tree->ftype,outfile);
4810 fprintf(outfile,")\n");
4811 ast_print(tree->left,outfile,indent+2);
4812 ast_print(tree->right,outfile,indent+2);
4815 /*------------------------------------------------------------------*/
4816 /*----------------------------*/
4817 /* comparison operators */
4818 /*----------------------------*/
4820 fprintf(outfile,"GT(>) (%p) type (",tree);
4821 printTypeChain(tree->ftype,outfile);
4822 fprintf(outfile,")\n");
4823 ast_print(tree->left,outfile,indent+2);
4824 ast_print(tree->right,outfile,indent+2);
4827 fprintf(outfile,"LT(<) (%p) type (",tree);
4828 printTypeChain(tree->ftype,outfile);
4829 fprintf(outfile,")\n");
4830 ast_print(tree->left,outfile,indent+2);
4831 ast_print(tree->right,outfile,indent+2);
4834 fprintf(outfile,"LE(<=) (%p) type (",tree);
4835 printTypeChain(tree->ftype,outfile);
4836 fprintf(outfile,")\n");
4837 ast_print(tree->left,outfile,indent+2);
4838 ast_print(tree->right,outfile,indent+2);
4841 fprintf(outfile,"GE(>=) (%p) type (",tree);
4842 printTypeChain(tree->ftype,outfile);
4843 fprintf(outfile,")\n");
4844 ast_print(tree->left,outfile,indent+2);
4845 ast_print(tree->right,outfile,indent+2);
4848 fprintf(outfile,"EQ(==) (%p) type (",tree);
4849 printTypeChain(tree->ftype,outfile);
4850 fprintf(outfile,")\n");
4851 ast_print(tree->left,outfile,indent+2);
4852 ast_print(tree->right,outfile,indent+2);
4855 fprintf(outfile,"NE(!=) (%p) type (",tree);
4856 printTypeChain(tree->ftype,outfile);
4857 fprintf(outfile,")\n");
4858 ast_print(tree->left,outfile,indent+2);
4859 ast_print(tree->right,outfile,indent+2);
4860 /*------------------------------------------------------------------*/
4861 /*----------------------------*/
4863 /*----------------------------*/
4864 case SIZEOF: /* evaluate wihout code generation */
4865 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4868 /*------------------------------------------------------------------*/
4869 /*----------------------------*/
4870 /* conditional operator '?' */
4871 /*----------------------------*/
4873 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4874 printTypeChain(tree->ftype,outfile);
4875 fprintf(outfile,")\n");
4876 ast_print(tree->left,outfile,indent+2);
4877 ast_print(tree->right,outfile,indent+2);
4881 fprintf(outfile,"COLON(:) (%p) type (",tree);
4882 printTypeChain(tree->ftype,outfile);
4883 fprintf(outfile,")\n");
4884 ast_print(tree->left,outfile,indent+2);
4885 ast_print(tree->right,outfile,indent+2);
4888 /*------------------------------------------------------------------*/
4889 /*----------------------------*/
4890 /* assignment operators */
4891 /*----------------------------*/
4893 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4894 printTypeChain(tree->ftype,outfile);
4895 fprintf(outfile,")\n");
4896 ast_print(tree->left,outfile,indent+2);
4897 ast_print(tree->right,outfile,indent+2);
4900 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4901 printTypeChain(tree->ftype,outfile);
4902 fprintf(outfile,")\n");
4903 ast_print(tree->left,outfile,indent+2);
4904 ast_print(tree->right,outfile,indent+2);
4907 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4908 printTypeChain(tree->ftype,outfile);
4909 fprintf(outfile,")\n");
4910 ast_print(tree->left,outfile,indent+2);
4911 ast_print(tree->right,outfile,indent+2);
4914 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
4915 printTypeChain(tree->ftype,outfile);
4916 fprintf(outfile,")\n");
4917 ast_print(tree->left,outfile,indent+2);
4918 ast_print(tree->right,outfile,indent+2);
4921 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
4922 printTypeChain(tree->ftype,outfile);
4923 fprintf(outfile,")\n");
4924 ast_print(tree->left,outfile,indent+2);
4925 ast_print(tree->right,outfile,indent+2);
4928 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4929 printTypeChain(tree->ftype,outfile);
4930 fprintf(outfile,")\n");
4931 ast_print(tree->left,outfile,indent+2);
4932 ast_print(tree->right,outfile,indent+2);
4935 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
4936 printTypeChain(tree->ftype,outfile);
4937 fprintf(outfile,")\n");
4938 ast_print(tree->left,outfile,indent+2);
4939 ast_print(tree->right,outfile,indent+2);
4941 /*------------------------------------------------------------------*/
4942 /*----------------------------*/
4944 /*----------------------------*/
4946 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4947 printTypeChain(tree->ftype,outfile);
4948 fprintf(outfile,")\n");
4949 ast_print(tree->left,outfile,indent+2);
4950 ast_print(tree->right,outfile,indent+2);
4952 /*------------------------------------------------------------------*/
4953 /*----------------------------*/
4955 /*----------------------------*/
4957 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4958 printTypeChain(tree->ftype,outfile);
4959 fprintf(outfile,")\n");
4960 ast_print(tree->left,outfile,indent+2);
4961 ast_print(tree->right,outfile,indent+2);
4963 /*------------------------------------------------------------------*/
4964 /*----------------------------*/
4965 /* straight assignemnt */
4966 /*----------------------------*/
4968 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4969 printTypeChain(tree->ftype,outfile);
4970 fprintf(outfile,")\n");
4971 ast_print(tree->left,outfile,indent+2);
4972 ast_print(tree->right,outfile,indent+2);
4974 /*------------------------------------------------------------------*/
4975 /*----------------------------*/
4976 /* comma operator */
4977 /*----------------------------*/
4979 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4980 printTypeChain(tree->ftype,outfile);
4981 fprintf(outfile,")\n");
4982 ast_print(tree->left,outfile,indent+2);
4983 ast_print(tree->right,outfile,indent+2);
4985 /*------------------------------------------------------------------*/
4986 /*----------------------------*/
4988 /*----------------------------*/
4991 fprintf(outfile,"CALL (%p) type (",tree);
4992 printTypeChain(tree->ftype,outfile);
4993 fprintf(outfile,")\n");
4994 ast_print(tree->left,outfile,indent+2);
4995 ast_print(tree->right,outfile,indent+2);
4998 fprintf(outfile,"PARMS\n");
4999 ast_print(tree->left,outfile,indent+2);
5000 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5001 ast_print(tree->right,outfile,indent+2);
5004 /*------------------------------------------------------------------*/
5005 /*----------------------------*/
5006 /* return statement */
5007 /*----------------------------*/
5009 fprintf(outfile,"RETURN (%p) type (",tree);
5011 printTypeChain(tree->right->ftype,outfile);
5013 fprintf(outfile,")\n");
5014 ast_print(tree->right,outfile,indent+2);
5016 /*------------------------------------------------------------------*/
5017 /*----------------------------*/
5018 /* label statement */
5019 /*----------------------------*/
5021 fprintf(outfile,"LABEL (%p)\n",tree);
5022 ast_print(tree->left,outfile,indent+2);
5023 ast_print(tree->right,outfile,indent);
5025 /*------------------------------------------------------------------*/
5026 /*----------------------------*/
5027 /* switch statement */
5028 /*----------------------------*/
5032 fprintf(outfile,"SWITCH (%p) ",tree);
5033 ast_print(tree->left,outfile,0);
5034 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5035 INDENT(indent+2,outfile);
5036 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5037 (int) floatFromVal(val),
5038 tree->values.switchVals.swNum,
5039 (int) floatFromVal(val));
5041 ast_print(tree->right,outfile,indent);
5044 /*------------------------------------------------------------------*/
5045 /*----------------------------*/
5047 /*----------------------------*/
5049 fprintf(outfile,"IF (%p) \n",tree);
5050 ast_print(tree->left,outfile,indent+2);
5051 if (tree->trueLabel) {
5052 INDENT(indent+2,outfile);
5053 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5055 if (tree->falseLabel) {
5056 INDENT(indent+2,outfile);
5057 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5059 ast_print(tree->right,outfile,indent+2);
5061 /*----------------------------*/
5062 /* goto Statement */
5063 /*----------------------------*/
5065 fprintf(outfile,"GOTO (%p) \n",tree);
5066 ast_print(tree->left,outfile,indent+2);
5067 fprintf(outfile,"\n");
5069 /*------------------------------------------------------------------*/
5070 /*----------------------------*/
5072 /*----------------------------*/
5074 fprintf(outfile,"FOR (%p) \n",tree);
5075 if (AST_FOR( tree, initExpr)) {
5076 INDENT(indent+2,outfile);
5077 fprintf(outfile,"INIT EXPR ");
5078 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5080 if (AST_FOR( tree, condExpr)) {
5081 INDENT(indent+2,outfile);
5082 fprintf(outfile,"COND EXPR ");
5083 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5085 if (AST_FOR( tree, loopExpr)) {
5086 INDENT(indent+2,outfile);
5087 fprintf(outfile,"LOOP EXPR ");
5088 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5090 fprintf(outfile,"FOR LOOP BODY \n");
5091 ast_print(tree->left,outfile,indent+2);
5100 ast_print(t,stdout,0);