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)) {
1284 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1289 /*-----------------------------------------------------------------*/
1290 /* constExprValue - returns the value of a constant expression */
1291 /* or NULL if it is not a constant expression */
1292 /*-----------------------------------------------------------------*/
1294 constExprValue (ast * cexpr, int check)
1296 cexpr = decorateType (resolveSymbols (cexpr));
1298 /* if this is not a constant then */
1299 if (!IS_LITERAL (cexpr->ftype))
1301 /* then check if this is a literal array
1303 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1304 SPEC_CVAL (cexpr->etype).v_char &&
1305 IS_ARRAY (cexpr->ftype))
1307 value *val = valFromType (cexpr->ftype);
1308 SPEC_SCLS (val->etype) = S_LITERAL;
1309 val->sym = cexpr->opval.val->sym;
1310 val->sym->type = copyLinkChain (cexpr->ftype);
1311 val->sym->etype = getSpec (val->sym->type);
1312 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1316 /* if we are casting a literal value then */
1317 if (IS_AST_OP (cexpr) &&
1318 cexpr->opval.op == CAST &&
1319 IS_LITERAL (cexpr->right->ftype))
1320 return valCastLiteral (cexpr->ftype,
1321 floatFromVal (cexpr->right->opval.val));
1323 if (IS_AST_VALUE (cexpr))
1324 return cexpr->opval.val;
1327 werror (E_CONST_EXPECTED, "found expression");
1332 /* return the value */
1333 return cexpr->opval.val;
1337 /*-----------------------------------------------------------------*/
1338 /* isLabelInAst - will return true if a given label is found */
1339 /*-----------------------------------------------------------------*/
1341 isLabelInAst (symbol * label, ast * tree)
1343 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1346 if (IS_AST_OP (tree) &&
1347 tree->opval.op == LABEL &&
1348 isSymbolEqual (AST_SYMBOL (tree->left), label))
1351 return isLabelInAst (label, tree->right) &&
1352 isLabelInAst (label, tree->left);
1356 /*-----------------------------------------------------------------*/
1357 /* isLoopCountable - return true if the loop count can be determi- */
1358 /* -ned at compile time . */
1359 /*-----------------------------------------------------------------*/
1361 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1362 symbol ** sym, ast ** init, ast ** end)
1365 /* the loop is considered countable if the following
1366 conditions are true :-
1368 a) initExpr :- <sym> = <const>
1369 b) condExpr :- <sym> < <const1>
1370 c) loopExpr :- <sym> ++
1373 /* first check the initExpr */
1374 if (IS_AST_OP (initExpr) &&
1375 initExpr->opval.op == '=' && /* is assignment */
1376 IS_AST_SYM_VALUE (initExpr->left))
1377 { /* left is a symbol */
1379 *sym = AST_SYMBOL (initExpr->left);
1380 *init = initExpr->right;
1385 /* for now the symbol has to be of
1387 if (!IS_INTEGRAL ((*sym)->type))
1390 /* now check condExpr */
1391 if (IS_AST_OP (condExpr))
1394 switch (condExpr->opval.op)
1397 if (IS_AST_SYM_VALUE (condExpr->left) &&
1398 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1399 IS_AST_LIT_VALUE (condExpr->right))
1401 *end = condExpr->right;
1407 if (IS_AST_OP (condExpr->left) &&
1408 condExpr->left->opval.op == '>' &&
1409 IS_AST_LIT_VALUE (condExpr->left->right) &&
1410 IS_AST_SYM_VALUE (condExpr->left->left) &&
1411 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1414 *end = newNode ('+', condExpr->left->right,
1415 newAst_VALUE (constVal ("1")));
1426 /* check loop expression is of the form <sym>++ */
1427 if (!IS_AST_OP (loopExpr))
1430 /* check if <sym> ++ */
1431 if (loopExpr->opval.op == INC_OP)
1437 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1438 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1445 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1446 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1454 if (loopExpr->opval.op == ADD_ASSIGN)
1457 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1458 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1459 IS_AST_LIT_VALUE (loopExpr->right) &&
1460 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1468 /*-----------------------------------------------------------------*/
1469 /* astHasVolatile - returns true if ast contains any volatile */
1470 /*-----------------------------------------------------------------*/
1472 astHasVolatile (ast * tree)
1477 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1480 if (IS_AST_OP (tree))
1481 return astHasVolatile (tree->left) ||
1482 astHasVolatile (tree->right);
1487 /*-----------------------------------------------------------------*/
1488 /* astHasPointer - return true if the ast contains any ptr variable */
1489 /*-----------------------------------------------------------------*/
1491 astHasPointer (ast * tree)
1496 if (IS_AST_LINK (tree))
1499 /* if we hit an array expression then check
1500 only the left side */
1501 if (IS_AST_OP (tree) && tree->opval.op == '[')
1502 return astHasPointer (tree->left);
1504 if (IS_AST_VALUE (tree))
1505 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1507 return astHasPointer (tree->left) ||
1508 astHasPointer (tree->right);
1512 /*-----------------------------------------------------------------*/
1513 /* astHasSymbol - return true if the ast has the given symbol */
1514 /*-----------------------------------------------------------------*/
1516 astHasSymbol (ast * tree, symbol * sym)
1518 if (!tree || IS_AST_LINK (tree))
1521 if (IS_AST_VALUE (tree))
1523 if (IS_AST_SYM_VALUE (tree))
1524 return isSymbolEqual (AST_SYMBOL (tree), sym);
1529 return astHasSymbol (tree->left, sym) ||
1530 astHasSymbol (tree->right, sym);
1533 /*-----------------------------------------------------------------*/
1534 /* astHasDeref - return true if the ast has an indirect access */
1535 /*-----------------------------------------------------------------*/
1537 astHasDeref (ast * tree)
1539 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1542 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1544 return astHasDeref (tree->left) || astHasDeref (tree->right);
1547 /*-----------------------------------------------------------------*/
1548 /* isConformingBody - the loop body has to conform to a set of rules */
1549 /* for the loop to be considered reversible read on for rules */
1550 /*-----------------------------------------------------------------*/
1552 isConformingBody (ast * pbody, symbol * sym, ast * body)
1555 /* we are going to do a pre-order traversal of the
1556 tree && check for the following conditions. (essentially
1557 a set of very shallow tests )
1558 a) the sym passed does not participate in
1559 any arithmetic operation
1560 b) There are no function calls
1561 c) all jumps are within the body
1562 d) address of loop control variable not taken
1563 e) if an assignment has a pointer on the
1564 left hand side make sure right does not have
1565 loop control variable */
1567 /* if we reach the end or a leaf then true */
1568 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1571 /* if anything else is "volatile" */
1572 if (IS_VOLATILE (TETYPE (pbody)))
1575 /* we will walk the body in a pre-order traversal for
1577 switch (pbody->opval.op)
1579 /*------------------------------------------------------------------*/
1581 // if the loopvar is used as an index
1582 if (astHasSymbol(pbody->right, sym)) {
1585 return isConformingBody (pbody->right, sym, body);
1587 /*------------------------------------------------------------------*/
1592 /*------------------------------------------------------------------*/
1593 case INC_OP: /* incerement operator unary so left only */
1596 /* sure we are not sym is not modified */
1598 IS_AST_SYM_VALUE (pbody->left) &&
1599 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1603 IS_AST_SYM_VALUE (pbody->right) &&
1604 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1609 /*------------------------------------------------------------------*/
1611 case '*': /* can be unary : if right is null then unary operation */
1616 /* if right is NULL then unary operation */
1617 /*------------------------------------------------------------------*/
1618 /*----------------------------*/
1620 /*----------------------------*/
1623 if (IS_AST_SYM_VALUE (pbody->left) &&
1624 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1627 return isConformingBody (pbody->left, sym, body);
1631 if (astHasSymbol (pbody->left, sym) ||
1632 astHasSymbol (pbody->right, sym))
1637 /*------------------------------------------------------------------*/
1645 if (IS_AST_SYM_VALUE (pbody->left) &&
1646 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1649 if (IS_AST_SYM_VALUE (pbody->right) &&
1650 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1653 return isConformingBody (pbody->left, sym, body) &&
1654 isConformingBody (pbody->right, sym, body);
1661 if (IS_AST_SYM_VALUE (pbody->left) &&
1662 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1664 return isConformingBody (pbody->left, sym, body);
1666 /*------------------------------------------------------------------*/
1678 case SIZEOF: /* evaluate wihout code generation */
1680 return isConformingBody (pbody->left, sym, body) &&
1681 isConformingBody (pbody->right, sym, body);
1683 /*------------------------------------------------------------------*/
1686 /* if left has a pointer & right has loop
1687 control variable then we cannot */
1688 if (astHasPointer (pbody->left) &&
1689 astHasSymbol (pbody->right, sym))
1691 if (astHasVolatile (pbody->left))
1694 if (IS_AST_SYM_VALUE (pbody->left)) {
1695 // if the loopvar has an assignment
1696 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1698 // if the loopvar is used in another (maybe conditional) block
1699 if (astHasSymbol (pbody->right, sym) &&
1700 (pbody->level > body->level)) {
1705 if (astHasVolatile (pbody->left))
1708 if (astHasDeref(pbody->right)) return FALSE;
1710 return isConformingBody (pbody->left, sym, body) &&
1711 isConformingBody (pbody->right, sym, body);
1722 assert ("Parser should not have generated this\n");
1724 /*------------------------------------------------------------------*/
1725 /*----------------------------*/
1726 /* comma operator */
1727 /*----------------------------*/
1729 return isConformingBody (pbody->left, sym, body) &&
1730 isConformingBody (pbody->right, sym, body);
1732 /*------------------------------------------------------------------*/
1733 /*----------------------------*/
1735 /*----------------------------*/
1737 /* if local & not passed as paramater then ok */
1738 if (sym->level && !astHasSymbol(pbody->right,sym))
1742 /*------------------------------------------------------------------*/
1743 /*----------------------------*/
1744 /* return statement */
1745 /*----------------------------*/
1750 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1755 if (astHasSymbol (pbody->left, sym))
1762 return isConformingBody (pbody->left, sym, body) &&
1763 isConformingBody (pbody->right, sym, body);
1769 /*-----------------------------------------------------------------*/
1770 /* isLoopReversible - takes a for loop as input && returns true */
1771 /* if the for loop is reversible. If yes will set the value of */
1772 /* the loop control var & init value & termination value */
1773 /*-----------------------------------------------------------------*/
1775 isLoopReversible (ast * loop, symbol ** loopCntrl,
1776 ast ** init, ast ** end)
1778 /* if option says don't do it then don't */
1779 if (optimize.noLoopReverse)
1781 /* there are several tests to determine this */
1783 /* for loop has to be of the form
1784 for ( <sym> = <const1> ;
1785 [<sym> < <const2>] ;
1786 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1788 if (!isLoopCountable (AST_FOR (loop, initExpr),
1789 AST_FOR (loop, condExpr),
1790 AST_FOR (loop, loopExpr),
1791 loopCntrl, init, end))
1794 /* now do some serious checking on the body of the loop
1797 return isConformingBody (loop->left, *loopCntrl, loop->left);
1801 /*-----------------------------------------------------------------*/
1802 /* replLoopSym - replace the loop sym by loop sym -1 */
1803 /*-----------------------------------------------------------------*/
1805 replLoopSym (ast * body, symbol * sym)
1808 if (!body || IS_AST_LINK (body))
1811 if (IS_AST_SYM_VALUE (body))
1814 if (isSymbolEqual (AST_SYMBOL (body), sym))
1818 body->opval.op = '-';
1819 body->left = newAst_VALUE (symbolVal (sym));
1820 body->right = newAst_VALUE (constVal ("1"));
1828 replLoopSym (body->left, sym);
1829 replLoopSym (body->right, sym);
1833 /*-----------------------------------------------------------------*/
1834 /* reverseLoop - do the actual loop reversal */
1835 /*-----------------------------------------------------------------*/
1837 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1841 /* create the following tree
1846 if (sym) goto for_continue ;
1849 /* put it together piece by piece */
1850 rloop = newNode (NULLOP,
1851 createIf (newAst_VALUE (symbolVal (sym)),
1853 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1856 newAst_VALUE (symbolVal (sym)),
1859 replLoopSym (loop->left, sym);
1860 setAstLineno (rloop, init->lineno);
1862 rloop = newNode (NULLOP,
1864 newAst_VALUE (symbolVal (sym)),
1865 newNode ('-', end, init)),
1866 createLabel (AST_FOR (loop, continueLabel),
1870 newNode (SUB_ASSIGN,
1871 newAst_VALUE (symbolVal (sym)),
1872 newAst_VALUE (constVal ("1"))),
1875 rloop->lineno=init->lineno;
1876 return decorateType (rloop);
1880 /*-----------------------------------------------------------------*/
1881 /* decorateType - compute type for this tree also does type cheking */
1882 /* this is done bottom up, since type have to flow upwards */
1883 /* it also does constant folding, and paramater checking */
1884 /*-----------------------------------------------------------------*/
1886 decorateType (ast * tree)
1894 /* if already has type then do nothing */
1895 if (tree->decorated)
1898 tree->decorated = 1;
1901 /* print the line */
1902 /* if not block & function */
1903 if (tree->type == EX_OP &&
1904 (tree->opval.op != FUNCTION &&
1905 tree->opval.op != BLOCK &&
1906 tree->opval.op != NULLOP))
1908 filename = tree->filename;
1909 lineno = tree->lineno;
1913 /* if any child is an error | this one is an error do nothing */
1914 if (tree->isError ||
1915 (tree->left && tree->left->isError) ||
1916 (tree->right && tree->right->isError))
1919 /*------------------------------------------------------------------*/
1920 /*----------------------------*/
1921 /* leaf has been reached */
1922 /*----------------------------*/
1923 lineno=tree->lineno;
1924 /* if this is of type value */
1925 /* just get the type */
1926 if (tree->type == EX_VALUE)
1929 if (IS_LITERAL (tree->opval.val->etype))
1932 /* if this is a character array then declare it */
1933 if (IS_ARRAY (tree->opval.val->type))
1934 tree->opval.val = stringToSymbol (tree->opval.val);
1936 /* otherwise just copy the type information */
1937 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1941 if (tree->opval.val->sym)
1943 /* if the undefined flag is set then give error message */
1944 if (tree->opval.val->sym->undefined)
1946 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1948 TTYPE (tree) = TETYPE (tree) =
1949 tree->opval.val->type = tree->opval.val->sym->type =
1950 tree->opval.val->etype = tree->opval.val->sym->etype =
1951 copyLinkChain (INTTYPE);
1956 /* if impilicit i.e. struct/union member then no type */
1957 if (tree->opval.val->sym->implicit)
1958 TTYPE (tree) = TETYPE (tree) = NULL;
1963 /* else copy the type */
1964 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1966 /* and mark it as referenced */
1967 tree->opval.val->sym->isref = 1;
1975 /* if type link for the case of cast */
1976 if (tree->type == EX_LINK)
1978 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1985 dtl = decorateType (tree->left);
1986 /* delay right side for '?' operator since conditional macro expansions might
1988 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1990 /* this is to take care of situations
1991 when the tree gets rewritten */
1992 if (dtl != tree->left)
1994 if (dtr != tree->right)
1997 if (IS_AST_OP(tree) &&
1998 (tree->opval.op == CAST || tree->opval.op == '=') &&
1999 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2000 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2001 // this is a cast/assign to a bigger type
2002 if (IS_AST_OP(tree->right) &&
2003 IS_INTEGRAL(tree->right->ftype) &&
2004 (tree->right->opval.op == LEFT_OP ||
2005 tree->right->opval.op == '*' ||
2006 tree->right->opval.op == '+' ||
2007 tree->right->opval.op == '-') &&
2008 tree->right->right) {
2009 // we should cast an operand instead of the result
2010 tree->right->decorated = 0;
2011 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2013 tree->right = decorateType(tree->right);
2018 /* depending on type of operator do */
2020 switch (tree->opval.op)
2022 /*------------------------------------------------------------------*/
2023 /*----------------------------*/
2025 /*----------------------------*/
2028 /* determine which is the array & which the index */
2029 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2032 ast *tempTree = tree->left;
2033 tree->left = tree->right;
2034 tree->right = tempTree;
2037 /* first check if this is a array or a pointer */
2038 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2040 werror (E_NEED_ARRAY_PTR, "[]");
2041 goto errorTreeReturn;
2044 /* check if the type of the idx */
2045 if (!IS_INTEGRAL (RTYPE (tree)))
2047 werror (E_IDX_NOT_INT);
2048 goto errorTreeReturn;
2051 /* if the left is an rvalue then error */
2054 werror (E_LVALUE_REQUIRED, "array access");
2055 goto errorTreeReturn;
2058 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2059 if (IS_PTR(LTYPE(tree))) {
2060 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2064 /*------------------------------------------------------------------*/
2065 /*----------------------------*/
2067 /*----------------------------*/
2069 /* if this is not a structure */
2070 if (!IS_STRUCT (LTYPE (tree)))
2072 werror (E_STRUCT_UNION, ".");
2073 goto errorTreeReturn;
2075 TTYPE (tree) = structElemType (LTYPE (tree),
2076 (tree->right->type == EX_VALUE ?
2077 tree->right->opval.val : NULL));
2078 TETYPE (tree) = getSpec (TTYPE (tree));
2081 /*------------------------------------------------------------------*/
2082 /*----------------------------*/
2083 /* struct/union pointer */
2084 /*----------------------------*/
2086 /* if not pointer to a structure */
2087 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2089 werror (E_PTR_REQD);
2090 goto errorTreeReturn;
2093 if (!IS_STRUCT (LTYPE (tree)->next))
2095 werror (E_STRUCT_UNION, "->");
2096 goto errorTreeReturn;
2099 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2100 (tree->right->type == EX_VALUE ?
2101 tree->right->opval.val : NULL));
2102 TETYPE (tree) = getSpec (TTYPE (tree));
2104 /* adjust the storage class */
2105 switch (DCL_TYPE(tree->left->ftype)) {
2109 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2112 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2117 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2120 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2123 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2133 /*------------------------------------------------------------------*/
2134 /*----------------------------*/
2135 /* ++/-- operation */
2136 /*----------------------------*/
2137 case INC_OP: /* incerement operator unary so left only */
2140 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2141 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2142 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2143 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2152 /*------------------------------------------------------------------*/
2153 /*----------------------------*/
2155 /*----------------------------*/
2156 case '&': /* can be unary */
2157 /* if right is NULL then unary operation */
2158 if (tree->right) /* not an unary operation */
2161 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2163 werror (E_BITWISE_OP);
2164 werror (W_CONTINUE, "left & right types are ");
2165 printTypeChain (LTYPE (tree), stderr);
2166 fprintf (stderr, ",");
2167 printTypeChain (RTYPE (tree), stderr);
2168 fprintf (stderr, "\n");
2169 goto errorTreeReturn;
2172 /* if they are both literal */
2173 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2175 tree->type = EX_VALUE;
2176 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2177 valFromType (RETYPE (tree)), '&');
2179 tree->right = tree->left = NULL;
2180 TETYPE (tree) = tree->opval.val->etype;
2181 TTYPE (tree) = tree->opval.val->type;
2185 /* see if this is a GETHBIT operation if yes
2188 ast *otree = optimizeGetHbit (tree);
2191 return decorateType (otree);
2195 computeType (LTYPE (tree), RTYPE (tree));
2196 TETYPE (tree) = getSpec (TTYPE (tree));
2198 LRVAL (tree) = RRVAL (tree) = 1;
2202 /*------------------------------------------------------------------*/
2203 /*----------------------------*/
2205 /*----------------------------*/
2206 p = newLink (DECLARATOR);
2207 /* if bit field then error */
2208 if (IS_BITVAR (tree->left->etype))
2210 werror (E_ILLEGAL_ADDR, "address of bit variable");
2211 goto errorTreeReturn;
2214 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2216 werror (E_ILLEGAL_ADDR, "address of register variable");
2217 goto errorTreeReturn;
2220 if (IS_FUNC (LTYPE (tree)))
2222 // this ought to be ignored
2223 return (tree->left);
2226 if (IS_LITERAL(LTYPE(tree)))
2228 werror (E_ILLEGAL_ADDR, "address of literal");
2229 goto errorTreeReturn;
2234 werror (E_LVALUE_REQUIRED, "address of");
2235 goto errorTreeReturn;
2237 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2239 DCL_TYPE (p) = CPOINTER;
2240 DCL_PTR_CONST (p) = port->mem.code_ro;
2242 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2243 DCL_TYPE (p) = FPOINTER;
2244 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2245 DCL_TYPE (p) = PPOINTER;
2246 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2247 DCL_TYPE (p) = IPOINTER;
2248 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2249 DCL_TYPE (p) = EEPPOINTER;
2250 else if (SPEC_OCLS(tree->left->etype))
2251 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2253 DCL_TYPE (p) = POINTER;
2255 if (IS_AST_SYM_VALUE (tree->left))
2257 AST_SYMBOL (tree->left)->addrtaken = 1;
2258 AST_SYMBOL (tree->left)->allocreq = 1;
2261 p->next = LTYPE (tree);
2263 TETYPE (tree) = getSpec (TTYPE (tree));
2264 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2265 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2270 /*------------------------------------------------------------------*/
2271 /*----------------------------*/
2273 /*----------------------------*/
2275 /* if the rewrite succeeds then don't go any furthur */
2277 ast *wtree = optimizeRRCRLC (tree);
2279 return decorateType (wtree);
2282 /*------------------------------------------------------------------*/
2283 /*----------------------------*/
2285 /*----------------------------*/
2287 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2289 werror (E_BITWISE_OP);
2290 werror (W_CONTINUE, "left & right types are ");
2291 printTypeChain (LTYPE (tree), stderr);
2292 fprintf (stderr, ",");
2293 printTypeChain (RTYPE (tree), stderr);
2294 fprintf (stderr, "\n");
2295 goto errorTreeReturn;
2298 /* if they are both literal then */
2299 /* rewrite the tree */
2300 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2302 tree->type = EX_VALUE;
2303 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2304 valFromType (RETYPE (tree)),
2306 tree->right = tree->left = NULL;
2307 TETYPE (tree) = tree->opval.val->etype;
2308 TTYPE (tree) = tree->opval.val->type;
2311 LRVAL (tree) = RRVAL (tree) = 1;
2312 TETYPE (tree) = getSpec (TTYPE (tree) =
2313 computeType (LTYPE (tree),
2316 /*------------------------------------------------------------------*/
2317 /*----------------------------*/
2319 /*----------------------------*/
2321 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2323 werror (E_INVALID_OP, "divide");
2324 goto errorTreeReturn;
2326 /* if they are both literal then */
2327 /* rewrite the tree */
2328 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2330 tree->type = EX_VALUE;
2331 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2332 valFromType (RETYPE (tree)));
2333 tree->right = tree->left = NULL;
2334 TETYPE (tree) = getSpec (TTYPE (tree) =
2335 tree->opval.val->type);
2338 LRVAL (tree) = RRVAL (tree) = 1;
2339 TETYPE (tree) = getSpec (TTYPE (tree) =
2340 computeType (LTYPE (tree),
2344 /*------------------------------------------------------------------*/
2345 /*----------------------------*/
2347 /*----------------------------*/
2349 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2351 werror (E_BITWISE_OP);
2352 werror (W_CONTINUE, "left & right types are ");
2353 printTypeChain (LTYPE (tree), stderr);
2354 fprintf (stderr, ",");
2355 printTypeChain (RTYPE (tree), stderr);
2356 fprintf (stderr, "\n");
2357 goto errorTreeReturn;
2359 /* if they are both literal then */
2360 /* rewrite the tree */
2361 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2363 tree->type = EX_VALUE;
2364 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2365 valFromType (RETYPE (tree)));
2366 tree->right = tree->left = NULL;
2367 TETYPE (tree) = getSpec (TTYPE (tree) =
2368 tree->opval.val->type);
2371 LRVAL (tree) = RRVAL (tree) = 1;
2372 TETYPE (tree) = getSpec (TTYPE (tree) =
2373 computeType (LTYPE (tree),
2377 /*------------------------------------------------------------------*/
2378 /*----------------------------*/
2379 /* address dereference */
2380 /*----------------------------*/
2381 case '*': /* can be unary : if right is null then unary operation */
2384 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2386 werror (E_PTR_REQD);
2387 goto errorTreeReturn;
2392 werror (E_LVALUE_REQUIRED, "pointer deref");
2393 goto errorTreeReturn;
2395 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2396 TETYPE (tree) = getSpec (TTYPE (tree));
2397 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2401 /*------------------------------------------------------------------*/
2402 /*----------------------------*/
2403 /* multiplication */
2404 /*----------------------------*/
2405 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2407 werror (E_INVALID_OP, "multiplication");
2408 goto errorTreeReturn;
2411 /* if they are both literal then */
2412 /* rewrite the tree */
2413 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2415 tree->type = EX_VALUE;
2416 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2417 valFromType (RETYPE (tree)));
2418 tree->right = tree->left = NULL;
2419 TETYPE (tree) = getSpec (TTYPE (tree) =
2420 tree->opval.val->type);
2424 /* if left is a literal exchange left & right */
2425 if (IS_LITERAL (LTYPE (tree)))
2427 ast *tTree = tree->left;
2428 tree->left = tree->right;
2429 tree->right = tTree;
2432 LRVAL (tree) = RRVAL (tree) = 1;
2433 TETYPE (tree) = getSpec (TTYPE (tree) =
2434 computeType (LTYPE (tree),
2437 /* promote result to int if left & right are char
2438 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2439 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2440 SPEC_NOUN(TETYPE(tree)) = V_INT;
2445 /*------------------------------------------------------------------*/
2446 /*----------------------------*/
2447 /* unary '+' operator */
2448 /*----------------------------*/
2453 if (!IS_INTEGRAL (LTYPE (tree)))
2455 werror (E_UNARY_OP, '+');
2456 goto errorTreeReturn;
2459 /* if left is a literal then do it */
2460 if (IS_LITERAL (LTYPE (tree)))
2462 tree->type = EX_VALUE;
2463 tree->opval.val = valFromType (LETYPE (tree));
2465 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2469 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2473 /*------------------------------------------------------------------*/
2474 /*----------------------------*/
2476 /*----------------------------*/
2478 /* this is not a unary operation */
2479 /* if both pointers then problem */
2480 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2481 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2483 werror (E_PTR_PLUS_PTR);
2484 goto errorTreeReturn;
2487 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2488 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2490 werror (E_PLUS_INVALID, "+");
2491 goto errorTreeReturn;
2494 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2495 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2497 werror (E_PLUS_INVALID, "+");
2498 goto errorTreeReturn;
2500 /* if they are both literal then */
2501 /* rewrite the tree */
2502 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2504 tree->type = EX_VALUE;
2505 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2506 valFromType (RETYPE (tree)));
2507 tree->right = tree->left = NULL;
2508 TETYPE (tree) = getSpec (TTYPE (tree) =
2509 tree->opval.val->type);
2513 /* if the right is a pointer or left is a literal
2514 xchange left & right */
2515 if (IS_ARRAY (RTYPE (tree)) ||
2516 IS_PTR (RTYPE (tree)) ||
2517 IS_LITERAL (LTYPE (tree)))
2519 ast *tTree = tree->left;
2520 tree->left = tree->right;
2521 tree->right = tTree;
2524 LRVAL (tree) = RRVAL (tree) = 1;
2525 /* if the left is a pointer */
2526 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2527 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 TETYPE (tree) = getSpec (TTYPE (tree) =
2531 computeType (LTYPE (tree),
2535 /*------------------------------------------------------------------*/
2536 /*----------------------------*/
2538 /*----------------------------*/
2539 case '-': /* can be unary */
2540 /* if right is null then unary */
2544 if (!IS_ARITHMETIC (LTYPE (tree)))
2546 werror (E_UNARY_OP, tree->opval.op);
2547 goto errorTreeReturn;
2550 /* if left is a literal then do it */
2551 if (IS_LITERAL (LTYPE (tree)))
2553 tree->type = EX_VALUE;
2554 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2556 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2557 SPEC_USIGN(TETYPE(tree)) = 0;
2561 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2565 /*------------------------------------------------------------------*/
2566 /*----------------------------*/
2568 /*----------------------------*/
2570 if (!(IS_PTR (LTYPE (tree)) ||
2571 IS_ARRAY (LTYPE (tree)) ||
2572 IS_ARITHMETIC (LTYPE (tree))))
2574 werror (E_PLUS_INVALID, "-");
2575 goto errorTreeReturn;
2578 if (!(IS_PTR (RTYPE (tree)) ||
2579 IS_ARRAY (RTYPE (tree)) ||
2580 IS_ARITHMETIC (RTYPE (tree))))
2582 werror (E_PLUS_INVALID, "-");
2583 goto errorTreeReturn;
2586 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2587 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2588 IS_INTEGRAL (RTYPE (tree))))
2590 werror (E_PLUS_INVALID, "-");
2591 goto errorTreeReturn;
2594 /* if they are both literal then */
2595 /* rewrite the tree */
2596 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2598 tree->type = EX_VALUE;
2599 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2600 valFromType (RETYPE (tree)));
2601 tree->right = tree->left = NULL;
2602 TETYPE (tree) = getSpec (TTYPE (tree) =
2603 tree->opval.val->type);
2607 /* if the left & right are equal then zero */
2608 if (isAstEqual (tree->left, tree->right))
2610 tree->type = EX_VALUE;
2611 tree->left = tree->right = NULL;
2612 tree->opval.val = constVal ("0");
2613 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2617 /* if both of them are pointers or arrays then */
2618 /* the result is going to be an integer */
2619 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2620 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2621 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2623 /* if only the left is a pointer */
2624 /* then result is a pointer */
2625 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2626 TETYPE (tree) = getSpec (TTYPE (tree) =
2629 TETYPE (tree) = getSpec (TTYPE (tree) =
2630 computeType (LTYPE (tree),
2632 LRVAL (tree) = RRVAL (tree) = 1;
2635 /*------------------------------------------------------------------*/
2636 /*----------------------------*/
2638 /*----------------------------*/
2640 /* can be only integral type */
2641 if (!IS_INTEGRAL (LTYPE (tree)))
2643 werror (E_UNARY_OP, tree->opval.op);
2644 goto errorTreeReturn;
2647 /* if left is a literal then do it */
2648 if (IS_LITERAL (LTYPE (tree)))
2650 tree->type = EX_VALUE;
2651 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2653 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2657 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2660 /*------------------------------------------------------------------*/
2661 /*----------------------------*/
2663 /*----------------------------*/
2665 /* can be pointer */
2666 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2667 !IS_PTR (LTYPE (tree)) &&
2668 !IS_ARRAY (LTYPE (tree)))
2670 werror (E_UNARY_OP, tree->opval.op);
2671 goto errorTreeReturn;
2674 /* if left is a literal then do it */
2675 if (IS_LITERAL (LTYPE (tree)))
2677 tree->type = EX_VALUE;
2678 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2680 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2684 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2687 /*------------------------------------------------------------------*/
2688 /*----------------------------*/
2690 /*----------------------------*/
2693 TTYPE (tree) = LTYPE (tree);
2694 TETYPE (tree) = LETYPE (tree);
2698 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2703 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2705 werror (E_SHIFT_OP_INVALID);
2706 werror (W_CONTINUE, "left & right types are ");
2707 printTypeChain (LTYPE (tree), stderr);
2708 fprintf (stderr, ",");
2709 printTypeChain (RTYPE (tree), stderr);
2710 fprintf (stderr, "\n");
2711 goto errorTreeReturn;
2714 /* if they are both literal then */
2715 /* rewrite the tree */
2716 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2718 tree->type = EX_VALUE;
2719 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2720 valFromType (RETYPE (tree)),
2721 (tree->opval.op == LEFT_OP ? 1 : 0));
2722 tree->right = tree->left = NULL;
2723 TETYPE (tree) = getSpec (TTYPE (tree) =
2724 tree->opval.val->type);
2728 /* if only the right side is a literal & we are
2729 shifting more than size of the left operand then zero */
2730 if (IS_LITERAL (RTYPE (tree)) &&
2731 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2732 (getSize (LTYPE (tree)) * 8))
2734 if (tree->opval.op==LEFT_OP ||
2735 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2736 lineno=tree->lineno;
2737 werror (W_SHIFT_CHANGED,
2738 (tree->opval.op == LEFT_OP ? "left" : "right"));
2739 tree->type = EX_VALUE;
2740 tree->left = tree->right = NULL;
2741 tree->opval.val = constVal ("0");
2742 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2746 LRVAL (tree) = RRVAL (tree) = 1;
2747 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2749 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2753 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2757 /*------------------------------------------------------------------*/
2758 /*----------------------------*/
2760 /*----------------------------*/
2761 case CAST: /* change the type */
2762 /* cannot cast to an aggregate type */
2763 if (IS_AGGREGATE (LTYPE (tree)))
2765 werror (E_CAST_ILLEGAL);
2766 goto errorTreeReturn;
2769 /* make sure the type is complete and sane */
2770 checkTypeSanity(LETYPE(tree), "(cast)");
2773 /* if the right is a literal replace the tree */
2774 if (IS_LITERAL (RETYPE (tree))) {
2775 if (!IS_PTR (LTYPE (tree))) {
2776 tree->type = EX_VALUE;
2778 valCastLiteral (LTYPE (tree),
2779 floatFromVal (valFromType (RETYPE (tree))));
2782 TTYPE (tree) = tree->opval.val->type;
2783 tree->values.literalFromCast = 1;
2784 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2785 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2786 sym_link *rest = LTYPE(tree)->next;
2787 werror(W_LITERAL_GENERIC);
2788 TTYPE(tree) = newLink(DECLARATOR);
2789 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2790 TTYPE(tree)->next = rest;
2791 tree->left->opval.lnk = TTYPE(tree);
2794 TTYPE (tree) = LTYPE (tree);
2798 TTYPE (tree) = LTYPE (tree);
2802 #if 0 // this is already checked, now this could be explicit
2803 /* if pointer to struct then check names */
2804 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2805 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2806 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2808 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2809 SPEC_STRUCT(LETYPE(tree))->tag);
2812 /* if the right is a literal replace the tree */
2813 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2814 tree->type = EX_VALUE;
2816 valCastLiteral (LTYPE (tree),
2817 floatFromVal (valFromType (RETYPE (tree))));
2820 TTYPE (tree) = tree->opval.val->type;
2821 tree->values.literalFromCast = 1;
2823 TTYPE (tree) = LTYPE (tree);
2827 TETYPE (tree) = getSpec (TTYPE (tree));
2831 /*------------------------------------------------------------------*/
2832 /*----------------------------*/
2833 /* logical &&, || */
2834 /*----------------------------*/
2837 /* each must me arithmetic type or be a pointer */
2838 if (!IS_PTR (LTYPE (tree)) &&
2839 !IS_ARRAY (LTYPE (tree)) &&
2840 !IS_INTEGRAL (LTYPE (tree)))
2842 werror (E_COMPARE_OP);
2843 goto errorTreeReturn;
2846 if (!IS_PTR (RTYPE (tree)) &&
2847 !IS_ARRAY (RTYPE (tree)) &&
2848 !IS_INTEGRAL (RTYPE (tree)))
2850 werror (E_COMPARE_OP);
2851 goto errorTreeReturn;
2853 /* if they are both literal then */
2854 /* rewrite the tree */
2855 if (IS_LITERAL (RTYPE (tree)) &&
2856 IS_LITERAL (LTYPE (tree)))
2858 tree->type = EX_VALUE;
2859 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2860 valFromType (RETYPE (tree)),
2862 tree->right = tree->left = NULL;
2863 TETYPE (tree) = getSpec (TTYPE (tree) =
2864 tree->opval.val->type);
2867 LRVAL (tree) = RRVAL (tree) = 1;
2868 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2871 /*------------------------------------------------------------------*/
2872 /*----------------------------*/
2873 /* comparison operators */
2874 /*----------------------------*/
2882 ast *lt = optimizeCompare (tree);
2888 /* if they are pointers they must be castable */
2889 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2891 if (tree->opval.op==EQ_OP &&
2892 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
2893 // we cannot cast a gptr to a !gptr: switch the leaves
2894 struct ast *s=tree->left;
2895 tree->left=tree->right;
2898 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2900 werror (E_COMPARE_OP);
2901 fprintf (stderr, "comparring type ");
2902 printTypeChain (LTYPE (tree), stderr);
2903 fprintf (stderr, "to type ");
2904 printTypeChain (RTYPE (tree), stderr);
2905 fprintf (stderr, "\n");
2906 goto errorTreeReturn;
2909 /* else they should be promotable to one another */
2912 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2913 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2915 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2917 werror (E_COMPARE_OP);
2918 fprintf (stderr, "comparing type ");
2919 printTypeChain (LTYPE (tree), stderr);
2920 fprintf (stderr, "to type ");
2921 printTypeChain (RTYPE (tree), stderr);
2922 fprintf (stderr, "\n");
2923 goto errorTreeReturn;
2926 /* if unsigned value < 0 then always false */
2927 /* if (unsigned value) > 0 then (unsigned value) */
2928 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2929 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2931 if (tree->opval.op == '<') {
2934 if (tree->opval.op == '>') {
2938 /* if they are both literal then */
2939 /* rewrite the tree */
2940 if (IS_LITERAL (RTYPE (tree)) &&
2941 IS_LITERAL (LTYPE (tree)))
2943 tree->type = EX_VALUE;
2944 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2945 valFromType (RETYPE (tree)),
2947 tree->right = tree->left = NULL;
2948 TETYPE (tree) = getSpec (TTYPE (tree) =
2949 tree->opval.val->type);
2952 LRVAL (tree) = RRVAL (tree) = 1;
2953 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2956 /*------------------------------------------------------------------*/
2957 /*----------------------------*/
2959 /*----------------------------*/
2960 case SIZEOF: /* evaluate wihout code generation */
2961 /* change the type to a integer */
2962 tree->type = EX_VALUE;
2963 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2964 tree->opval.val = constVal (buffer);
2965 tree->right = tree->left = NULL;
2966 TETYPE (tree) = getSpec (TTYPE (tree) =
2967 tree->opval.val->type);
2970 /*------------------------------------------------------------------*/
2971 /*----------------------------*/
2973 /*----------------------------*/
2975 /* return typeof enum value */
2976 tree->type = EX_VALUE;
2979 if (IS_SPEC(tree->right->ftype)) {
2980 switch (SPEC_NOUN(tree->right->ftype)) {
2982 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2983 else typeofv = TYPEOF_INT;
2986 typeofv = TYPEOF_FLOAT;
2989 typeofv = TYPEOF_CHAR;
2992 typeofv = TYPEOF_VOID;
2995 typeofv = TYPEOF_STRUCT;
2998 typeofv = TYPEOF_BITFIELD;
3001 typeofv = TYPEOF_BIT;
3004 typeofv = TYPEOF_SBIT;
3010 switch (DCL_TYPE(tree->right->ftype)) {
3012 typeofv = TYPEOF_POINTER;
3015 typeofv = TYPEOF_FPOINTER;
3018 typeofv = TYPEOF_CPOINTER;
3021 typeofv = TYPEOF_GPOINTER;
3024 typeofv = TYPEOF_PPOINTER;
3027 typeofv = TYPEOF_IPOINTER;
3030 typeofv = TYPEOF_ARRAY;
3033 typeofv = TYPEOF_FUNCTION;
3039 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3040 tree->opval.val = constVal (buffer);
3041 tree->right = tree->left = NULL;
3042 TETYPE (tree) = getSpec (TTYPE (tree) =
3043 tree->opval.val->type);
3046 /*------------------------------------------------------------------*/
3047 /*----------------------------*/
3048 /* conditional operator '?' */
3049 /*----------------------------*/
3051 /* the type is value of the colon operator (on the right) */
3052 assert(IS_COLON_OP(tree->right));
3053 /* if already known then replace the tree : optimizer will do it
3054 but faster to do it here */
3055 if (IS_LITERAL (LTYPE(tree))) {
3056 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3057 return decorateType(tree->right->left) ;
3059 return decorateType(tree->right->right) ;
3062 tree->right = decorateType(tree->right);
3063 TTYPE (tree) = RTYPE(tree);
3064 TETYPE (tree) = getSpec (TTYPE (tree));
3069 /* if they don't match we have a problem */
3070 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3072 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3073 goto errorTreeReturn;
3076 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3077 TETYPE (tree) = getSpec (TTYPE (tree));
3081 #if 0 // assignment operators are converted by the parser
3082 /*------------------------------------------------------------------*/
3083 /*----------------------------*/
3084 /* assignment operators */
3085 /*----------------------------*/
3088 /* for these it must be both must be integral */
3089 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3090 !IS_ARITHMETIC (RTYPE (tree)))
3092 werror (E_OPS_INTEGRAL);
3093 goto errorTreeReturn;
3096 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3098 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3099 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3103 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3104 goto errorTreeReturn;
3115 /* for these it must be both must be integral */
3116 if (!IS_INTEGRAL (LTYPE (tree)) ||
3117 !IS_INTEGRAL (RTYPE (tree)))
3119 werror (E_OPS_INTEGRAL);
3120 goto errorTreeReturn;
3123 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3125 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3126 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3130 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3131 goto errorTreeReturn;
3137 /*------------------------------------------------------------------*/
3138 /*----------------------------*/
3140 /*----------------------------*/
3142 if (!(IS_PTR (LTYPE (tree)) ||
3143 IS_ARITHMETIC (LTYPE (tree))))
3145 werror (E_PLUS_INVALID, "-=");
3146 goto errorTreeReturn;
3149 if (!(IS_PTR (RTYPE (tree)) ||
3150 IS_ARITHMETIC (RTYPE (tree))))
3152 werror (E_PLUS_INVALID, "-=");
3153 goto errorTreeReturn;
3156 TETYPE (tree) = getSpec (TTYPE (tree) =
3157 computeType (LTYPE (tree),
3160 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3161 werror (E_CODE_WRITE, "-=");
3165 werror (E_LVALUE_REQUIRED, "-=");
3166 goto errorTreeReturn;
3172 /*------------------------------------------------------------------*/
3173 /*----------------------------*/
3175 /*----------------------------*/
3177 /* this is not a unary operation */
3178 /* if both pointers then problem */
3179 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3181 werror (E_PTR_PLUS_PTR);
3182 goto errorTreeReturn;
3185 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3187 werror (E_PLUS_INVALID, "+=");
3188 goto errorTreeReturn;
3191 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3193 werror (E_PLUS_INVALID, "+=");
3194 goto errorTreeReturn;
3197 TETYPE (tree) = getSpec (TTYPE (tree) =
3198 computeType (LTYPE (tree),
3201 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3202 werror (E_CODE_WRITE, "+=");
3206 werror (E_LVALUE_REQUIRED, "+=");
3207 goto errorTreeReturn;
3210 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3211 tree->opval.op = '=';
3216 /*------------------------------------------------------------------*/
3217 /*----------------------------*/
3218 /* straight assignemnt */
3219 /*----------------------------*/
3221 /* cannot be an aggregate */
3222 if (IS_AGGREGATE (LTYPE (tree)))
3224 werror (E_AGGR_ASSIGN);
3225 goto errorTreeReturn;
3228 /* they should either match or be castable */
3229 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3231 werror (E_TYPE_MISMATCH, "assignment", " ");
3232 printFromToType(RTYPE(tree),LTYPE(tree));
3235 /* if the left side of the tree is of type void
3236 then report error */
3237 if (IS_VOID (LTYPE (tree)))
3239 werror (E_CAST_ZERO);
3240 printFromToType(RTYPE(tree), LTYPE(tree));
3243 TETYPE (tree) = getSpec (TTYPE (tree) =
3247 if (!tree->initMode ) {
3248 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3249 werror (E_CODE_WRITE, "=");
3253 werror (E_LVALUE_REQUIRED, "=");
3254 goto errorTreeReturn;
3259 /*------------------------------------------------------------------*/
3260 /*----------------------------*/
3261 /* comma operator */
3262 /*----------------------------*/
3264 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3267 /*------------------------------------------------------------------*/
3268 /*----------------------------*/
3270 /*----------------------------*/
3274 if (processParms (tree->left,
3275 FUNC_ARGS(tree->left->ftype),
3276 tree->right, &parmNumber, TRUE)) {
3277 goto errorTreeReturn;
3280 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3281 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3283 reverseParms (tree->right);
3286 if (IS_CODEPTR(LTYPE(tree))) {
3287 TTYPE(tree) = LTYPE(tree)->next->next;
3289 TTYPE(tree) = LTYPE(tree)->next;
3291 TETYPE (tree) = getSpec (TTYPE (tree));
3294 /*------------------------------------------------------------------*/
3295 /*----------------------------*/
3296 /* return statement */
3297 /*----------------------------*/
3302 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3304 werror (W_RETURN_MISMATCH);
3305 printFromToType (RTYPE(tree), currFunc->type->next);
3306 goto errorTreeReturn;
3309 if (IS_VOID (currFunc->type->next)
3311 !IS_VOID (RTYPE (tree)))
3313 werror (E_FUNC_VOID);
3314 goto errorTreeReturn;
3317 /* if there is going to be a casing required then add it */
3318 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3321 decorateType (newNode (CAST,
3322 newAst_LINK (copyLinkChain (currFunc->type->next)),
3331 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3333 werror (W_VOID_FUNC, currFunc->name);
3334 goto errorTreeReturn;
3337 TTYPE (tree) = TETYPE (tree) = NULL;
3340 /*------------------------------------------------------------------*/
3341 /*----------------------------*/
3342 /* switch statement */
3343 /*----------------------------*/
3345 /* the switch value must be an integer */
3346 if (!IS_INTEGRAL (LTYPE (tree)))
3348 werror (E_SWITCH_NON_INTEGER);
3349 goto errorTreeReturn;
3352 TTYPE (tree) = TETYPE (tree) = NULL;
3355 /*------------------------------------------------------------------*/
3356 /*----------------------------*/
3358 /*----------------------------*/
3360 tree->left = backPatchLabels (tree->left,
3363 TTYPE (tree) = TETYPE (tree) = NULL;
3366 /*------------------------------------------------------------------*/
3367 /*----------------------------*/
3369 /*----------------------------*/
3372 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3373 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3374 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3376 /* if the for loop is reversible then
3377 reverse it otherwise do what we normally
3383 if (isLoopReversible (tree, &sym, &init, &end))
3384 return reverseLoop (tree, sym, init, end);
3386 return decorateType (createFor (AST_FOR (tree, trueLabel),
3387 AST_FOR (tree, continueLabel),
3388 AST_FOR (tree, falseLabel),
3389 AST_FOR (tree, condLabel),
3390 AST_FOR (tree, initExpr),
3391 AST_FOR (tree, condExpr),
3392 AST_FOR (tree, loopExpr),
3396 TTYPE (tree) = TETYPE (tree) = NULL;
3400 /* some error found this tree will be killed */
3402 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3403 tree->opval.op = NULLOP;
3409 /*-----------------------------------------------------------------*/
3410 /* sizeofOp - processes size of operation */
3411 /*-----------------------------------------------------------------*/
3413 sizeofOp (sym_link * type)
3417 /* make sure the type is complete and sane */
3418 checkTypeSanity(type, "(sizeof)");
3420 /* get the size and convert it to character */
3421 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3423 /* now convert into value */
3424 return constVal (buff);
3428 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3429 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3430 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3431 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3432 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3433 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3434 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3436 /*-----------------------------------------------------------------*/
3437 /* backPatchLabels - change and or not operators to flow control */
3438 /*-----------------------------------------------------------------*/
3440 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3446 if (!(IS_ANDORNOT (tree)))
3449 /* if this an and */
3452 static int localLbl = 0;
3455 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3456 localLabel = newSymbol (buffer, NestLevel);
3458 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3460 /* if left is already a IFX then just change the if true label in that */
3461 if (!IS_IFX (tree->left))
3462 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3464 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3465 /* right is a IFX then just join */
3466 if (IS_IFX (tree->right))
3467 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3469 tree->right = createLabel (localLabel, tree->right);
3470 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3472 return newNode (NULLOP, tree->left, tree->right);
3475 /* if this is an or operation */
3478 static int localLbl = 0;
3481 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3482 localLabel = newSymbol (buffer, NestLevel);
3484 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3486 /* if left is already a IFX then just change the if true label in that */
3487 if (!IS_IFX (tree->left))
3488 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3490 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3491 /* right is a IFX then just join */
3492 if (IS_IFX (tree->right))
3493 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3495 tree->right = createLabel (localLabel, tree->right);
3496 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3498 return newNode (NULLOP, tree->left, tree->right);
3504 int wasnot = IS_NOT (tree->left);
3505 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3507 /* if the left is already a IFX */
3508 if (!IS_IFX (tree->left))
3509 tree->left = newNode (IFX, tree->left, NULL);
3513 tree->left->trueLabel = trueLabel;
3514 tree->left->falseLabel = falseLabel;
3518 tree->left->trueLabel = falseLabel;
3519 tree->left->falseLabel = trueLabel;
3526 tree->trueLabel = trueLabel;
3527 tree->falseLabel = falseLabel;
3534 /*-----------------------------------------------------------------*/
3535 /* createBlock - create expression tree for block */
3536 /*-----------------------------------------------------------------*/
3538 createBlock (symbol * decl, ast * body)
3542 /* if the block has nothing */
3546 ex = newNode (BLOCK, NULL, body);
3547 ex->values.sym = decl;
3549 ex->right = ex->right;
3555 /*-----------------------------------------------------------------*/
3556 /* createLabel - creates the expression tree for labels */
3557 /*-----------------------------------------------------------------*/
3559 createLabel (symbol * label, ast * stmnt)
3562 char name[SDCC_NAME_MAX + 1];
3565 /* must create fresh symbol if the symbol name */
3566 /* exists in the symbol table, since there can */
3567 /* be a variable with the same name as the labl */
3568 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3569 (csym->level == label->level))
3570 label = newSymbol (label->name, label->level);
3572 /* change the name before putting it in add _ */
3573 SNPRINTF(name, sizeof(name), "%s", label->name);
3575 /* put the label in the LabelSymbol table */
3576 /* but first check if a label of the same */
3578 if ((csym = findSym (LabelTab, NULL, name)))
3579 werror (E_DUPLICATE_LABEL, label->name);
3581 addSym (LabelTab, label, name, label->level, 0, 0);
3584 label->key = labelKey++;
3585 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3591 /*-----------------------------------------------------------------*/
3592 /* createCase - generates the parsetree for a case statement */
3593 /*-----------------------------------------------------------------*/
3595 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3597 char caseLbl[SDCC_NAME_MAX + 1];
3601 /* if the switch statement does not exist */
3602 /* then case is out of context */
3605 werror (E_CASE_CONTEXT);
3609 caseVal = decorateType (resolveSymbols (caseVal));
3610 /* if not a constant then error */
3611 if (!IS_LITERAL (caseVal->ftype))
3613 werror (E_CASE_CONSTANT);
3617 /* if not a integer than error */
3618 if (!IS_INTEGRAL (caseVal->ftype))
3620 werror (E_CASE_NON_INTEGER);
3624 /* find the end of the switch values chain */
3625 if (!(val = swStat->values.switchVals.swVals))
3626 swStat->values.switchVals.swVals = caseVal->opval.val;
3629 /* also order the cases according to value */
3631 int cVal = (int) floatFromVal (caseVal->opval.val);
3632 while (val && (int) floatFromVal (val) < cVal)
3638 /* if we reached the end then */
3641 pval->next = caseVal->opval.val;
3645 /* we found a value greater than */
3646 /* the current value we must add this */
3647 /* before the value */
3648 caseVal->opval.val->next = val;
3650 /* if this was the first in chain */
3651 if (swStat->values.switchVals.swVals == val)
3652 swStat->values.switchVals.swVals =
3655 pval->next = caseVal->opval.val;
3660 /* create the case label */
3661 SNPRINTF(caseLbl, sizeof(caseLbl),
3663 swStat->values.switchVals.swNum,
3664 (int) floatFromVal (caseVal->opval.val));
3666 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3671 /*-----------------------------------------------------------------*/
3672 /* createDefault - creates the parse tree for the default statement */
3673 /*-----------------------------------------------------------------*/
3675 createDefault (ast * swStat, ast * stmnt)
3677 char defLbl[SDCC_NAME_MAX + 1];
3679 /* if the switch statement does not exist */
3680 /* then case is out of context */
3683 werror (E_CASE_CONTEXT);
3687 /* turn on the default flag */
3688 swStat->values.switchVals.swDefault = 1;
3690 /* create the label */
3691 SNPRINTF (defLbl, sizeof(defLbl),
3692 "_default_%d", swStat->values.switchVals.swNum);
3693 return createLabel (newSymbol (defLbl, 0), stmnt);
3696 /*-----------------------------------------------------------------*/
3697 /* createIf - creates the parsetree for the if statement */
3698 /*-----------------------------------------------------------------*/
3700 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3702 static int Lblnum = 0;
3704 symbol *ifTrue, *ifFalse, *ifEnd;
3706 /* if neither exists */
3707 if (!elseBody && !ifBody) {
3708 // if there are no side effects (i++, j() etc)
3709 if (!hasSEFcalls(condAst)) {
3714 /* create the labels */
3715 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3716 ifFalse = newSymbol (buffer, NestLevel);
3717 /* if no else body then end == false */
3722 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3723 ifEnd = newSymbol (buffer, NestLevel);
3726 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3727 ifTrue = newSymbol (buffer, NestLevel);
3731 /* attach the ifTrue label to the top of it body */
3732 ifBody = createLabel (ifTrue, ifBody);
3733 /* attach a goto end to the ifBody if else is present */
3736 ifBody = newNode (NULLOP, ifBody,
3738 newAst_VALUE (symbolVal (ifEnd)),
3740 /* put the elseLabel on the else body */
3741 elseBody = createLabel (ifFalse, elseBody);
3742 /* out the end at the end of the body */
3743 elseBody = newNode (NULLOP,
3745 createLabel (ifEnd, NULL));
3749 ifBody = newNode (NULLOP, ifBody,
3750 createLabel (ifFalse, NULL));
3752 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3753 if (IS_IFX (condAst))
3756 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3758 return newNode (NULLOP, ifTree,
3759 newNode (NULLOP, ifBody, elseBody));
3763 /*-----------------------------------------------------------------*/
3764 /* createDo - creates parse tree for do */
3767 /* _docontinue_n: */
3768 /* condition_expression +-> trueLabel -> _dobody_n */
3770 /* +-> falseLabel-> _dobreak_n */
3772 /*-----------------------------------------------------------------*/
3774 createDo (symbol * trueLabel, symbol * continueLabel,
3775 symbol * falseLabel, ast * condAst, ast * doBody)
3780 /* if the body does not exist then it is simple */
3783 condAst = backPatchLabels (condAst, continueLabel, NULL);
3784 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3785 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3786 doTree->trueLabel = continueLabel;
3787 doTree->falseLabel = NULL;
3791 /* otherwise we have a body */
3792 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3794 /* attach the body label to the top */
3795 doBody = createLabel (trueLabel, doBody);
3796 /* attach the continue label to end of body */
3797 doBody = newNode (NULLOP, doBody,
3798 createLabel (continueLabel, NULL));
3800 /* now put the break label at the end */
3801 if (IS_IFX (condAst))
3804 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3806 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3808 /* putting it together */
3809 return newNode (NULLOP, doBody, doTree);
3812 /*-----------------------------------------------------------------*/
3813 /* createFor - creates parse tree for 'for' statement */
3816 /* condExpr +-> trueLabel -> _forbody_n */
3818 /* +-> falseLabel-> _forbreak_n */
3821 /* _forcontinue_n: */
3823 /* goto _forcond_n ; */
3825 /*-----------------------------------------------------------------*/
3827 createFor (symbol * trueLabel, symbol * continueLabel,
3828 symbol * falseLabel, symbol * condLabel,
3829 ast * initExpr, ast * condExpr, ast * loopExpr,
3834 /* if loopexpression not present then we can generate it */
3835 /* the same way as a while */
3837 return newNode (NULLOP, initExpr,
3838 createWhile (trueLabel, continueLabel,
3839 falseLabel, condExpr, forBody));
3840 /* vanilla for statement */
3841 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3843 if (condExpr && !IS_IFX (condExpr))
3844 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3847 /* attach condition label to condition */
3848 condExpr = createLabel (condLabel, condExpr);
3850 /* attach body label to body */
3851 forBody = createLabel (trueLabel, forBody);
3853 /* attach continue to forLoop expression & attach */
3854 /* goto the forcond @ and of loopExpression */
3855 loopExpr = createLabel (continueLabel,
3859 newAst_VALUE (symbolVal (condLabel)),
3861 /* now start putting them together */
3862 forTree = newNode (NULLOP, initExpr, condExpr);
3863 forTree = newNode (NULLOP, forTree, forBody);
3864 forTree = newNode (NULLOP, forTree, loopExpr);
3865 /* finally add the break label */
3866 forTree = newNode (NULLOP, forTree,
3867 createLabel (falseLabel, NULL));
3871 /*-----------------------------------------------------------------*/
3872 /* createWhile - creates parse tree for while statement */
3873 /* the while statement will be created as follows */
3875 /* _while_continue_n: */
3876 /* condition_expression +-> trueLabel -> _while_boby_n */
3878 /* +-> falseLabel -> _while_break_n */
3879 /* _while_body_n: */
3881 /* goto _while_continue_n */
3882 /* _while_break_n: */
3883 /*-----------------------------------------------------------------*/
3885 createWhile (symbol * trueLabel, symbol * continueLabel,
3886 symbol * falseLabel, ast * condExpr, ast * whileBody)
3890 /* put the continue label */
3891 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3892 condExpr = createLabel (continueLabel, condExpr);
3893 condExpr->lineno = 0;
3895 /* put the body label in front of the body */
3896 whileBody = createLabel (trueLabel, whileBody);
3897 whileBody->lineno = 0;
3898 /* put a jump to continue at the end of the body */
3899 /* and put break label at the end of the body */
3900 whileBody = newNode (NULLOP,
3903 newAst_VALUE (symbolVal (continueLabel)),
3904 createLabel (falseLabel, NULL)));
3906 /* put it all together */
3907 if (IS_IFX (condExpr))
3908 whileTree = condExpr;
3911 whileTree = newNode (IFX, condExpr, NULL);
3912 /* put the true & false labels in place */
3913 whileTree->trueLabel = trueLabel;
3914 whileTree->falseLabel = falseLabel;
3917 return newNode (NULLOP, whileTree, whileBody);
3920 /*-----------------------------------------------------------------*/
3921 /* optimizeGetHbit - get highest order bit of the expression */
3922 /*-----------------------------------------------------------------*/
3924 optimizeGetHbit (ast * tree)
3927 /* if this is not a bit and */
3928 if (!IS_BITAND (tree))
3931 /* will look for tree of the form
3932 ( expr >> ((sizeof expr) -1) ) & 1 */
3933 if (!IS_AST_LIT_VALUE (tree->right))
3936 if (AST_LIT_VALUE (tree->right) != 1)
3939 if (!IS_RIGHT_OP (tree->left))
3942 if (!IS_AST_LIT_VALUE (tree->left->right))
3945 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3946 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3949 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3953 /*-----------------------------------------------------------------*/
3954 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3955 /*-----------------------------------------------------------------*/
3957 optimizeRRCRLC (ast * root)
3959 /* will look for trees of the form
3960 (?expr << 1) | (?expr >> 7) or
3961 (?expr >> 7) | (?expr << 1) will make that
3962 into a RLC : operation ..
3964 (?expr >> 1) | (?expr << 7) or
3965 (?expr << 7) | (?expr >> 1) will make that
3966 into a RRC operation
3967 note : by 7 I mean (number of bits required to hold the
3969 /* if the root operations is not a | operation the not */
3970 if (!IS_BITOR (root))
3973 /* I have to think of a better way to match patterns this sucks */
3974 /* that aside let start looking for the first case : I use a the
3975 negative check a lot to improve the efficiency */
3976 /* (?expr << 1) | (?expr >> 7) */
3977 if (IS_LEFT_OP (root->left) &&
3978 IS_RIGHT_OP (root->right))
3981 if (!SPEC_USIGN (TETYPE (root->left->left)))
3984 if (!IS_AST_LIT_VALUE (root->left->right) ||
3985 !IS_AST_LIT_VALUE (root->right->right))
3988 /* make sure it is the same expression */
3989 if (!isAstEqual (root->left->left,
3993 if (AST_LIT_VALUE (root->left->right) != 1)
3996 if (AST_LIT_VALUE (root->right->right) !=
3997 (getSize (TTYPE (root->left->left)) * 8 - 1))
4000 /* whew got the first case : create the AST */
4001 return newNode (RLC, root->left->left, NULL);
4005 /* check for second case */
4006 /* (?expr >> 7) | (?expr << 1) */
4007 if (IS_LEFT_OP (root->right) &&
4008 IS_RIGHT_OP (root->left))
4011 if (!SPEC_USIGN (TETYPE (root->left->left)))
4014 if (!IS_AST_LIT_VALUE (root->left->right) ||
4015 !IS_AST_LIT_VALUE (root->right->right))
4018 /* make sure it is the same symbol */
4019 if (!isAstEqual (root->left->left,
4023 if (AST_LIT_VALUE (root->right->right) != 1)
4026 if (AST_LIT_VALUE (root->left->right) !=
4027 (getSize (TTYPE (root->left->left)) * 8 - 1))
4030 /* whew got the first case : create the AST */
4031 return newNode (RLC, root->left->left, NULL);
4036 /* third case for RRC */
4037 /* (?symbol >> 1) | (?symbol << 7) */
4038 if (IS_LEFT_OP (root->right) &&
4039 IS_RIGHT_OP (root->left))
4042 if (!SPEC_USIGN (TETYPE (root->left->left)))
4045 if (!IS_AST_LIT_VALUE (root->left->right) ||
4046 !IS_AST_LIT_VALUE (root->right->right))
4049 /* make sure it is the same symbol */
4050 if (!isAstEqual (root->left->left,
4054 if (AST_LIT_VALUE (root->left->right) != 1)
4057 if (AST_LIT_VALUE (root->right->right) !=
4058 (getSize (TTYPE (root->left->left)) * 8 - 1))
4061 /* whew got the first case : create the AST */
4062 return newNode (RRC, root->left->left, NULL);
4066 /* fourth and last case for now */
4067 /* (?symbol << 7) | (?symbol >> 1) */
4068 if (IS_RIGHT_OP (root->right) &&
4069 IS_LEFT_OP (root->left))
4072 if (!SPEC_USIGN (TETYPE (root->left->left)))
4075 if (!IS_AST_LIT_VALUE (root->left->right) ||
4076 !IS_AST_LIT_VALUE (root->right->right))
4079 /* make sure it is the same symbol */
4080 if (!isAstEqual (root->left->left,
4084 if (AST_LIT_VALUE (root->right->right) != 1)
4087 if (AST_LIT_VALUE (root->left->right) !=
4088 (getSize (TTYPE (root->left->left)) * 8 - 1))
4091 /* whew got the first case : create the AST */
4092 return newNode (RRC, root->left->left, NULL);
4096 /* not found return root */
4100 /*-----------------------------------------------------------------*/
4101 /* optimizeCompare - otimizes compares for bit variables */
4102 /*-----------------------------------------------------------------*/
4104 optimizeCompare (ast * root)
4106 ast *optExpr = NULL;
4109 unsigned int litValue;
4111 /* if nothing then return nothing */
4115 /* if not a compare op then do leaves */
4116 if (!IS_COMPARE_OP (root))
4118 root->left = optimizeCompare (root->left);
4119 root->right = optimizeCompare (root->right);
4123 /* if left & right are the same then depending
4124 of the operation do */
4125 if (isAstEqual (root->left, root->right))
4127 switch (root->opval.op)
4132 optExpr = newAst_VALUE (constVal ("0"));
4137 optExpr = newAst_VALUE (constVal ("1"));
4141 return decorateType (optExpr);
4144 vleft = (root->left->type == EX_VALUE ?
4145 root->left->opval.val : NULL);
4147 vright = (root->right->type == EX_VALUE ?
4148 root->right->opval.val : NULL);
4150 /* if left is a BITVAR in BITSPACE */
4151 /* and right is a LITERAL then opt- */
4152 /* imize else do nothing */
4153 if (vleft && vright &&
4154 IS_BITVAR (vleft->etype) &&
4155 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4156 IS_LITERAL (vright->etype))
4159 /* if right side > 1 then comparison may never succeed */
4160 if ((litValue = (int) floatFromVal (vright)) > 1)
4162 werror (W_BAD_COMPARE);
4168 switch (root->opval.op)
4170 case '>': /* bit value greater than 1 cannot be */
4171 werror (W_BAD_COMPARE);
4175 case '<': /* bit value < 1 means 0 */
4177 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4180 case LE_OP: /* bit value <= 1 means no check */
4181 optExpr = newAst_VALUE (vright);
4184 case GE_OP: /* bit value >= 1 means only check for = */
4186 optExpr = newAst_VALUE (vleft);
4191 { /* literal is zero */
4192 switch (root->opval.op)
4194 case '<': /* bit value < 0 cannot be */
4195 werror (W_BAD_COMPARE);
4199 case '>': /* bit value > 0 means 1 */
4201 optExpr = newAst_VALUE (vleft);
4204 case LE_OP: /* bit value <= 0 means no check */
4205 case GE_OP: /* bit value >= 0 means no check */
4206 werror (W_BAD_COMPARE);
4210 case EQ_OP: /* bit == 0 means ! of bit */
4211 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4215 return decorateType (resolveSymbols (optExpr));
4216 } /* end-of-if of BITVAR */
4221 /*-----------------------------------------------------------------*/
4222 /* addSymToBlock : adds the symbol to the first block we find */
4223 /*-----------------------------------------------------------------*/
4225 addSymToBlock (symbol * sym, ast * tree)
4227 /* reached end of tree or a leaf */
4228 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4232 if (IS_AST_OP (tree) &&
4233 tree->opval.op == BLOCK)
4236 symbol *lsym = copySymbol (sym);
4238 lsym->next = AST_VALUES (tree, sym);
4239 AST_VALUES (tree, sym) = lsym;
4243 addSymToBlock (sym, tree->left);
4244 addSymToBlock (sym, tree->right);
4247 /*-----------------------------------------------------------------*/
4248 /* processRegParms - do processing for register parameters */
4249 /*-----------------------------------------------------------------*/
4251 processRegParms (value * args, ast * body)
4255 if (IS_REGPARM (args->etype))
4256 addSymToBlock (args->sym, body);
4261 /*-----------------------------------------------------------------*/
4262 /* resetParmKey - resets the operandkeys for the symbols */
4263 /*-----------------------------------------------------------------*/
4264 DEFSETFUNC (resetParmKey)
4275 /*-----------------------------------------------------------------*/
4276 /* createFunction - This is the key node that calls the iCode for */
4277 /* generating the code for a function. Note code */
4278 /* is generated function by function, later when */
4279 /* add inter-procedural analysis this will change */
4280 /*-----------------------------------------------------------------*/
4282 createFunction (symbol * name, ast * body)
4288 iCode *piCode = NULL;
4290 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4291 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4293 /* if check function return 0 then some problem */
4294 if (checkFunction (name, NULL) == 0)
4297 /* create a dummy block if none exists */
4299 body = newNode (BLOCK, NULL, NULL);
4303 /* check if the function name already in the symbol table */
4304 if ((csym = findSym (SymbolTab, NULL, name->name)))
4307 /* special case for compiler defined functions
4308 we need to add the name to the publics list : this
4309 actually means we are now compiling the compiler
4313 addSet (&publics, name);
4319 allocVariables (name);
4321 name->lastLine = mylineno;
4324 /* set the stack pointer */
4325 /* PENDING: check this for the mcs51 */
4326 stackPtr = -port->stack.direction * port->stack.call_overhead;
4327 if (IFFUNC_ISISR (name->type))
4328 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4329 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4330 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4332 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4334 fetype = getSpec (name->type); /* get the specifier for the function */
4335 /* if this is a reentrant function then */
4336 if (IFFUNC_ISREENT (name->type))
4339 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4341 /* do processing for parameters that are passed in registers */
4342 processRegParms (FUNC_ARGS(name->type), body);
4344 /* set the stack pointer */
4348 /* allocate & autoinit the block variables */
4349 processBlockVars (body, &stack, ALLOCATE);
4351 /* save the stack information */
4352 if (options.useXstack)
4353 name->xstack = SPEC_STAK (fetype) = stack;
4355 name->stack = SPEC_STAK (fetype) = stack;
4357 /* name needs to be mangled */
4358 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4360 body = resolveSymbols (body); /* resolve the symbols */
4361 body = decorateType (body); /* propagateType & do semantic checks */
4363 ex = newAst_VALUE (symbolVal (name)); /* create name */
4364 ex = newNode (FUNCTION, ex, body);
4365 ex->values.args = FUNC_ARGS(name->type);
4367 if (options.dump_tree) PA(ex);
4370 werror (E_FUNC_NO_CODE, name->name);
4374 /* create the node & generate intermediate code */
4376 codeOutFile = code->oFile;
4377 piCode = iCodeFromAst (ex);
4381 werror (E_FUNC_NO_CODE, name->name);
4385 eBBlockFromiCode (piCode);
4387 /* if there are any statics then do them */
4390 GcurMemmap = statsg;
4391 codeOutFile = statsg->oFile;
4392 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4398 /* dealloc the block variables */
4399 processBlockVars (body, &stack, DEALLOCATE);
4400 outputDebugStackSymbols();
4401 /* deallocate paramaters */
4402 deallocParms (FUNC_ARGS(name->type));
4404 if (IFFUNC_ISREENT (name->type))
4407 /* we are done freeup memory & cleanup */
4409 if (port->reset_labelKey) labelKey = 1;
4411 FUNC_HASBODY(name->type) = 1;
4412 addSet (&operKeyReset, name);
4413 applyToSet (operKeyReset, resetParmKey);
4418 cleanUpLevel (LabelTab, 0);
4419 cleanUpBlock (StructTab, 1);
4420 cleanUpBlock (TypedefTab, 1);
4422 xstack->syms = NULL;
4423 istack->syms = NULL;
4428 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4429 /*-----------------------------------------------------------------*/
4430 /* ast_print : prints the ast (for debugging purposes) */
4431 /*-----------------------------------------------------------------*/
4433 void ast_print (ast * tree, FILE *outfile, int indent)
4438 /* can print only decorated trees */
4439 if (!tree->decorated) return;
4441 /* if any child is an error | this one is an error do nothing */
4442 if (tree->isError ||
4443 (tree->left && tree->left->isError) ||
4444 (tree->right && tree->right->isError)) {
4445 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4449 /* print the line */
4450 /* if not block & function */
4451 if (tree->type == EX_OP &&
4452 (tree->opval.op != FUNCTION &&
4453 tree->opval.op != BLOCK &&
4454 tree->opval.op != NULLOP)) {
4457 if (tree->opval.op == FUNCTION) {
4459 value *args=FUNC_ARGS(tree->left->opval.val->type);
4460 fprintf(outfile,"FUNCTION (%s=%p) type (",
4461 tree->left->opval.val->name, tree);
4462 printTypeChain (tree->left->opval.val->type->next,outfile);
4463 fprintf(outfile,") args (");
4466 fprintf (outfile, ", ");
4468 printTypeChain (args ? args->type : NULL, outfile);
4470 args= args ? args->next : NULL;
4472 fprintf(outfile,")\n");
4473 ast_print(tree->left,outfile,indent);
4474 ast_print(tree->right,outfile,indent);
4477 if (tree->opval.op == BLOCK) {
4478 symbol *decls = tree->values.sym;
4479 INDENT(indent,outfile);
4480 fprintf(outfile,"{\n");
4482 INDENT(indent+2,outfile);
4483 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4484 decls->name, decls);
4485 printTypeChain(decls->type,outfile);
4486 fprintf(outfile,")\n");
4488 decls = decls->next;
4490 ast_print(tree->right,outfile,indent+2);
4491 INDENT(indent,outfile);
4492 fprintf(outfile,"}\n");
4495 if (tree->opval.op == NULLOP) {
4496 ast_print(tree->left,outfile,indent);
4497 ast_print(tree->right,outfile,indent);
4500 INDENT(indent,outfile);
4502 /*------------------------------------------------------------------*/
4503 /*----------------------------*/
4504 /* leaf has been reached */
4505 /*----------------------------*/
4506 /* if this is of type value */
4507 /* just get the type */
4508 if (tree->type == EX_VALUE) {
4510 if (IS_LITERAL (tree->opval.val->etype)) {
4511 fprintf(outfile,"CONSTANT (%p) value = ", tree);
4512 if (SPEC_USIGN (tree->opval.val->etype))
4513 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
4515 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
4516 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
4517 floatFromVal(tree->opval.val));
4518 } else if (tree->opval.val->sym) {
4519 /* if the undefined flag is set then give error message */
4520 if (tree->opval.val->sym->undefined) {
4521 fprintf(outfile,"UNDEFINED SYMBOL ");
4523 fprintf(outfile,"SYMBOL ");
4525 fprintf(outfile,"(%s=%p)",
4526 tree->opval.val->sym->name,tree);
4529 fprintf(outfile," type (");
4530 printTypeChain(tree->ftype,outfile);
4531 fprintf(outfile,")\n");
4533 fprintf(outfile,"\n");
4538 /* if type link for the case of cast */
4539 if (tree->type == EX_LINK) {
4540 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4541 printTypeChain(tree->opval.lnk,outfile);
4542 fprintf(outfile,")\n");
4547 /* depending on type of operator do */
4549 switch (tree->opval.op) {
4550 /*------------------------------------------------------------------*/
4551 /*----------------------------*/
4553 /*----------------------------*/
4555 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4556 printTypeChain(tree->ftype,outfile);
4557 fprintf(outfile,")\n");
4558 ast_print(tree->left,outfile,indent+2);
4559 ast_print(tree->right,outfile,indent+2);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4565 /*----------------------------*/
4567 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+2);
4571 ast_print(tree->right,outfile,indent+2);
4574 /*------------------------------------------------------------------*/
4575 /*----------------------------*/
4576 /* struct/union pointer */
4577 /*----------------------------*/
4579 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4580 printTypeChain(tree->ftype,outfile);
4581 fprintf(outfile,")\n");
4582 ast_print(tree->left,outfile,indent+2);
4583 ast_print(tree->right,outfile,indent+2);
4586 /*------------------------------------------------------------------*/
4587 /*----------------------------*/
4588 /* ++/-- operation */
4589 /*----------------------------*/
4590 case INC_OP: /* incerement operator unary so left only */
4591 fprintf(outfile,"INC_OP (%p) type (",tree);
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->left,outfile,indent+2);
4598 fprintf(outfile,"DEC_OP (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+2);
4604 /*------------------------------------------------------------------*/
4605 /*----------------------------*/
4607 /*----------------------------*/
4610 fprintf(outfile,"& (%p) type (",tree);
4611 printTypeChain(tree->ftype,outfile);
4612 fprintf(outfile,")\n");
4613 ast_print(tree->left,outfile,indent+2);
4614 ast_print(tree->right,outfile,indent+2);
4616 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4617 printTypeChain(tree->ftype,outfile);
4618 fprintf(outfile,")\n");
4619 ast_print(tree->left,outfile,indent+2);
4620 ast_print(tree->right,outfile,indent+2);
4623 /*----------------------------*/
4625 /*----------------------------*/
4627 fprintf(outfile,"OR (%p) type (",tree);
4628 printTypeChain(tree->ftype,outfile);
4629 fprintf(outfile,")\n");
4630 ast_print(tree->left,outfile,indent+2);
4631 ast_print(tree->right,outfile,indent+2);
4633 /*------------------------------------------------------------------*/
4634 /*----------------------------*/
4636 /*----------------------------*/
4638 fprintf(outfile,"XOR (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+2);
4642 ast_print(tree->right,outfile,indent+2);
4645 /*------------------------------------------------------------------*/
4646 /*----------------------------*/
4648 /*----------------------------*/
4650 fprintf(outfile,"DIV (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+2);
4654 ast_print(tree->right,outfile,indent+2);
4656 /*------------------------------------------------------------------*/
4657 /*----------------------------*/
4659 /*----------------------------*/
4661 fprintf(outfile,"MOD (%p) type (",tree);
4662 printTypeChain(tree->ftype,outfile);
4663 fprintf(outfile,")\n");
4664 ast_print(tree->left,outfile,indent+2);
4665 ast_print(tree->right,outfile,indent+2);
4668 /*------------------------------------------------------------------*/
4669 /*----------------------------*/
4670 /* address dereference */
4671 /*----------------------------*/
4672 case '*': /* can be unary : if right is null then unary operation */
4674 fprintf(outfile,"DEREF (%p) type (",tree);
4675 printTypeChain(tree->ftype,outfile);
4676 fprintf(outfile,")\n");
4677 ast_print(tree->left,outfile,indent+2);
4680 /*------------------------------------------------------------------*/
4681 /*----------------------------*/
4682 /* multiplication */
4683 /*----------------------------*/
4684 fprintf(outfile,"MULT (%p) type (",tree);
4685 printTypeChain(tree->ftype,outfile);
4686 fprintf(outfile,")\n");
4687 ast_print(tree->left,outfile,indent+2);
4688 ast_print(tree->right,outfile,indent+2);
4692 /*------------------------------------------------------------------*/
4693 /*----------------------------*/
4694 /* unary '+' operator */
4695 /*----------------------------*/
4699 fprintf(outfile,"UPLUS (%p) type (",tree);
4700 printTypeChain(tree->ftype,outfile);
4701 fprintf(outfile,")\n");
4702 ast_print(tree->left,outfile,indent+2);
4704 /*------------------------------------------------------------------*/
4705 /*----------------------------*/
4707 /*----------------------------*/
4708 fprintf(outfile,"ADD (%p) type (",tree);
4709 printTypeChain(tree->ftype,outfile);
4710 fprintf(outfile,")\n");
4711 ast_print(tree->left,outfile,indent+2);
4712 ast_print(tree->right,outfile,indent+2);
4715 /*------------------------------------------------------------------*/
4716 /*----------------------------*/
4718 /*----------------------------*/
4719 case '-': /* can be unary */
4721 fprintf(outfile,"UMINUS (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+2);
4726 /*------------------------------------------------------------------*/
4727 /*----------------------------*/
4729 /*----------------------------*/
4730 fprintf(outfile,"SUB (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+2);
4734 ast_print(tree->right,outfile,indent+2);
4737 /*------------------------------------------------------------------*/
4738 /*----------------------------*/
4740 /*----------------------------*/
4742 fprintf(outfile,"COMPL (%p) type (",tree);
4743 printTypeChain(tree->ftype,outfile);
4744 fprintf(outfile,")\n");
4745 ast_print(tree->left,outfile,indent+2);
4747 /*------------------------------------------------------------------*/
4748 /*----------------------------*/
4750 /*----------------------------*/
4752 fprintf(outfile,"NOT (%p) type (",tree);
4753 printTypeChain(tree->ftype,outfile);
4754 fprintf(outfile,")\n");
4755 ast_print(tree->left,outfile,indent+2);
4757 /*------------------------------------------------------------------*/
4758 /*----------------------------*/
4760 /*----------------------------*/
4762 fprintf(outfile,"RRC (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+2);
4769 fprintf(outfile,"RLC (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+2);
4775 fprintf(outfile,"GETHBIT (%p) type (",tree);
4776 printTypeChain(tree->ftype,outfile);
4777 fprintf(outfile,")\n");
4778 ast_print(tree->left,outfile,indent+2);
4781 fprintf(outfile,"LEFT_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);
4788 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4789 printTypeChain(tree->ftype,outfile);
4790 fprintf(outfile,")\n");
4791 ast_print(tree->left,outfile,indent+2);
4792 ast_print(tree->right,outfile,indent+2);
4794 /*------------------------------------------------------------------*/
4795 /*----------------------------*/
4797 /*----------------------------*/
4798 case CAST: /* change the type */
4799 fprintf(outfile,"CAST (%p) from type (",tree);
4800 printTypeChain(tree->right->ftype,outfile);
4801 fprintf(outfile,") to type (");
4802 printTypeChain(tree->ftype,outfile);
4803 fprintf(outfile,")\n");
4804 ast_print(tree->right,outfile,indent+2);
4808 fprintf(outfile,"ANDAND (%p) type (",tree);
4809 printTypeChain(tree->ftype,outfile);
4810 fprintf(outfile,")\n");
4811 ast_print(tree->left,outfile,indent+2);
4812 ast_print(tree->right,outfile,indent+2);
4815 fprintf(outfile,"OROR (%p) type (",tree);
4816 printTypeChain(tree->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->left,outfile,indent+2);
4819 ast_print(tree->right,outfile,indent+2);
4822 /*------------------------------------------------------------------*/
4823 /*----------------------------*/
4824 /* comparison operators */
4825 /*----------------------------*/
4827 fprintf(outfile,"GT(>) (%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,"LT(<) (%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,"LE(<=) (%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,"GE(>=) (%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,"EQ(==) (%p) type (",tree);
4856 printTypeChain(tree->ftype,outfile);
4857 fprintf(outfile,")\n");
4858 ast_print(tree->left,outfile,indent+2);
4859 ast_print(tree->right,outfile,indent+2);
4862 fprintf(outfile,"NE(!=) (%p) type (",tree);
4863 printTypeChain(tree->ftype,outfile);
4864 fprintf(outfile,")\n");
4865 ast_print(tree->left,outfile,indent+2);
4866 ast_print(tree->right,outfile,indent+2);
4867 /*------------------------------------------------------------------*/
4868 /*----------------------------*/
4870 /*----------------------------*/
4871 case SIZEOF: /* evaluate wihout code generation */
4872 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4875 /*------------------------------------------------------------------*/
4876 /*----------------------------*/
4877 /* conditional operator '?' */
4878 /*----------------------------*/
4880 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4881 printTypeChain(tree->ftype,outfile);
4882 fprintf(outfile,")\n");
4883 ast_print(tree->left,outfile,indent+2);
4884 ast_print(tree->right,outfile,indent+2);
4888 fprintf(outfile,"COLON(:) (%p) type (",tree);
4889 printTypeChain(tree->ftype,outfile);
4890 fprintf(outfile,")\n");
4891 ast_print(tree->left,outfile,indent+2);
4892 ast_print(tree->right,outfile,indent+2);
4895 /*------------------------------------------------------------------*/
4896 /*----------------------------*/
4897 /* assignment operators */
4898 /*----------------------------*/
4900 fprintf(outfile,"MULASS(*=) (%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,"DIVASS(/=) (%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,"ANDASS(&=) (%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,"ORASS(|=) (%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,"XORASS(^=) (%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,"RSHFTASS(>>=) (%p) type (",tree);
4936 printTypeChain(tree->ftype,outfile);
4937 fprintf(outfile,")\n");
4938 ast_print(tree->left,outfile,indent+2);
4939 ast_print(tree->right,outfile,indent+2);
4942 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
4943 printTypeChain(tree->ftype,outfile);
4944 fprintf(outfile,")\n");
4945 ast_print(tree->left,outfile,indent+2);
4946 ast_print(tree->right,outfile,indent+2);
4948 /*------------------------------------------------------------------*/
4949 /*----------------------------*/
4951 /*----------------------------*/
4953 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4954 printTypeChain(tree->ftype,outfile);
4955 fprintf(outfile,")\n");
4956 ast_print(tree->left,outfile,indent+2);
4957 ast_print(tree->right,outfile,indent+2);
4959 /*------------------------------------------------------------------*/
4960 /*----------------------------*/
4962 /*----------------------------*/
4964 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4965 printTypeChain(tree->ftype,outfile);
4966 fprintf(outfile,")\n");
4967 ast_print(tree->left,outfile,indent+2);
4968 ast_print(tree->right,outfile,indent+2);
4970 /*------------------------------------------------------------------*/
4971 /*----------------------------*/
4972 /* straight assignemnt */
4973 /*----------------------------*/
4975 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4976 printTypeChain(tree->ftype,outfile);
4977 fprintf(outfile,")\n");
4978 ast_print(tree->left,outfile,indent+2);
4979 ast_print(tree->right,outfile,indent+2);
4981 /*------------------------------------------------------------------*/
4982 /*----------------------------*/
4983 /* comma operator */
4984 /*----------------------------*/
4986 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4987 printTypeChain(tree->ftype,outfile);
4988 fprintf(outfile,")\n");
4989 ast_print(tree->left,outfile,indent+2);
4990 ast_print(tree->right,outfile,indent+2);
4992 /*------------------------------------------------------------------*/
4993 /*----------------------------*/
4995 /*----------------------------*/
4998 fprintf(outfile,"CALL (%p) type (",tree);
4999 printTypeChain(tree->ftype,outfile);
5000 fprintf(outfile,")\n");
5001 ast_print(tree->left,outfile,indent+2);
5002 ast_print(tree->right,outfile,indent+2);
5005 fprintf(outfile,"PARMS\n");
5006 ast_print(tree->left,outfile,indent+2);
5007 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5008 ast_print(tree->right,outfile,indent+2);
5011 /*------------------------------------------------------------------*/
5012 /*----------------------------*/
5013 /* return statement */
5014 /*----------------------------*/
5016 fprintf(outfile,"RETURN (%p) type (",tree);
5018 printTypeChain(tree->right->ftype,outfile);
5020 fprintf(outfile,")\n");
5021 ast_print(tree->right,outfile,indent+2);
5023 /*------------------------------------------------------------------*/
5024 /*----------------------------*/
5025 /* label statement */
5026 /*----------------------------*/
5028 fprintf(outfile,"LABEL (%p)\n",tree);
5029 ast_print(tree->left,outfile,indent+2);
5030 ast_print(tree->right,outfile,indent);
5032 /*------------------------------------------------------------------*/
5033 /*----------------------------*/
5034 /* switch statement */
5035 /*----------------------------*/
5039 fprintf(outfile,"SWITCH (%p) ",tree);
5040 ast_print(tree->left,outfile,0);
5041 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5042 INDENT(indent+2,outfile);
5043 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5044 (int) floatFromVal(val),
5045 tree->values.switchVals.swNum,
5046 (int) floatFromVal(val));
5048 ast_print(tree->right,outfile,indent);
5051 /*------------------------------------------------------------------*/
5052 /*----------------------------*/
5054 /*----------------------------*/
5056 fprintf(outfile,"IF (%p) \n",tree);
5057 ast_print(tree->left,outfile,indent+2);
5058 if (tree->trueLabel) {
5059 INDENT(indent+2,outfile);
5060 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5062 if (tree->falseLabel) {
5063 INDENT(indent+2,outfile);
5064 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5066 ast_print(tree->right,outfile,indent+2);
5068 /*----------------------------*/
5069 /* goto Statement */
5070 /*----------------------------*/
5072 fprintf(outfile,"GOTO (%p) \n",tree);
5073 ast_print(tree->left,outfile,indent+2);
5074 fprintf(outfile,"\n");
5076 /*------------------------------------------------------------------*/
5077 /*----------------------------*/
5079 /*----------------------------*/
5081 fprintf(outfile,"FOR (%p) \n",tree);
5082 if (AST_FOR( tree, initExpr)) {
5083 INDENT(indent+2,outfile);
5084 fprintf(outfile,"INIT EXPR ");
5085 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5087 if (AST_FOR( tree, condExpr)) {
5088 INDENT(indent+2,outfile);
5089 fprintf(outfile,"COND EXPR ");
5090 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5092 if (AST_FOR( tree, loopExpr)) {
5093 INDENT(indent+2,outfile);
5094 fprintf(outfile,"LOOP EXPR ");
5095 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5097 fprintf(outfile,"FOR LOOP BODY \n");
5098 ast_print(tree->left,outfile,indent+2);
5107 ast_print(t,stdout,0);