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);
2061 /*------------------------------------------------------------------*/
2062 /*----------------------------*/
2064 /*----------------------------*/
2066 /* if this is not a structure */
2067 if (!IS_STRUCT (LTYPE (tree)))
2069 werror (E_STRUCT_UNION, ".");
2070 goto errorTreeReturn;
2072 TTYPE (tree) = structElemType (LTYPE (tree),
2073 (tree->right->type == EX_VALUE ?
2074 tree->right->opval.val : NULL));
2075 TETYPE (tree) = getSpec (TTYPE (tree));
2078 /*------------------------------------------------------------------*/
2079 /*----------------------------*/
2080 /* struct/union pointer */
2081 /*----------------------------*/
2083 /* if not pointer to a structure */
2084 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2086 werror (E_PTR_REQD);
2087 goto errorTreeReturn;
2090 if (!IS_STRUCT (LTYPE (tree)->next))
2092 werror (E_STRUCT_UNION, "->");
2093 goto errorTreeReturn;
2096 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2097 (tree->right->type == EX_VALUE ?
2098 tree->right->opval.val : NULL));
2099 TETYPE (tree) = getSpec (TTYPE (tree));
2101 /* adjust the storage class */
2102 switch (DCL_TYPE(tree->left->ftype)) {
2106 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2109 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2114 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2117 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2120 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2130 /*------------------------------------------------------------------*/
2131 /*----------------------------*/
2132 /* ++/-- operation */
2133 /*----------------------------*/
2134 case INC_OP: /* increment operator unary so left only */
2137 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2138 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2139 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2140 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2149 /*------------------------------------------------------------------*/
2150 /*----------------------------*/
2152 /*----------------------------*/
2153 case '&': /* can be unary */
2154 /* if right is NULL then unary operation */
2155 if (tree->right) /* not an unary operation */
2158 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2160 werror (E_BITWISE_OP);
2161 werror (W_CONTINUE, "left & right types are ");
2162 printTypeChain (LTYPE (tree), stderr);
2163 fprintf (stderr, ",");
2164 printTypeChain (RTYPE (tree), stderr);
2165 fprintf (stderr, "\n");
2166 goto errorTreeReturn;
2169 /* if they are both literal */
2170 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2172 tree->type = EX_VALUE;
2173 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2174 valFromType (RETYPE (tree)), '&');
2176 tree->right = tree->left = NULL;
2177 TETYPE (tree) = tree->opval.val->etype;
2178 TTYPE (tree) = tree->opval.val->type;
2182 /* see if this is a GETHBIT operation if yes
2185 ast *otree = optimizeGetHbit (tree);
2188 return decorateType (otree);
2192 computeType (LTYPE (tree), RTYPE (tree));
2193 TETYPE (tree) = getSpec (TTYPE (tree));
2195 LRVAL (tree) = RRVAL (tree) = 1;
2199 /*------------------------------------------------------------------*/
2200 /*----------------------------*/
2202 /*----------------------------*/
2203 p = newLink (DECLARATOR);
2204 /* if bit field then error */
2205 if (IS_BITVAR (tree->left->etype))
2207 werror (E_ILLEGAL_ADDR, "address of bit variable");
2208 goto errorTreeReturn;
2211 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2213 werror (E_ILLEGAL_ADDR, "address of register variable");
2214 goto errorTreeReturn;
2217 if (IS_FUNC (LTYPE (tree)))
2219 // this ought to be ignored
2220 return (tree->left);
2223 if (IS_LITERAL(LTYPE(tree)))
2225 werror (E_ILLEGAL_ADDR, "address of literal");
2226 goto errorTreeReturn;
2231 werror (E_LVALUE_REQUIRED, "address of");
2232 goto errorTreeReturn;
2234 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2235 DCL_TYPE (p) = CPOINTER;
2236 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2237 DCL_TYPE (p) = FPOINTER;
2238 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2239 DCL_TYPE (p) = PPOINTER;
2240 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2241 DCL_TYPE (p) = IPOINTER;
2242 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2243 DCL_TYPE (p) = EEPPOINTER;
2244 else if (SPEC_OCLS(tree->left->etype))
2245 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2247 DCL_TYPE (p) = POINTER;
2249 if (IS_AST_SYM_VALUE (tree->left))
2251 AST_SYMBOL (tree->left)->addrtaken = 1;
2252 AST_SYMBOL (tree->left)->allocreq = 1;
2255 p->next = LTYPE (tree);
2257 TETYPE (tree) = getSpec (TTYPE (tree));
2262 /*------------------------------------------------------------------*/
2263 /*----------------------------*/
2265 /*----------------------------*/
2267 /* if the rewrite succeeds then don't go any furthur */
2269 ast *wtree = optimizeRRCRLC (tree);
2271 return decorateType (wtree);
2274 /*------------------------------------------------------------------*/
2275 /*----------------------------*/
2277 /*----------------------------*/
2279 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2281 werror (E_BITWISE_OP);
2282 werror (W_CONTINUE, "left & right types are ");
2283 printTypeChain (LTYPE (tree), stderr);
2284 fprintf (stderr, ",");
2285 printTypeChain (RTYPE (tree), stderr);
2286 fprintf (stderr, "\n");
2287 goto errorTreeReturn;
2290 /* if they are both literal then */
2291 /* rewrite the tree */
2292 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2294 tree->type = EX_VALUE;
2295 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2296 valFromType (RETYPE (tree)),
2298 tree->right = tree->left = NULL;
2299 TETYPE (tree) = tree->opval.val->etype;
2300 TTYPE (tree) = tree->opval.val->type;
2303 LRVAL (tree) = RRVAL (tree) = 1;
2304 TETYPE (tree) = getSpec (TTYPE (tree) =
2305 computeType (LTYPE (tree),
2308 /*------------------------------------------------------------------*/
2309 /*----------------------------*/
2311 /*----------------------------*/
2313 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2315 werror (E_INVALID_OP, "divide");
2316 goto errorTreeReturn;
2318 /* if they are both literal then */
2319 /* rewrite the tree */
2320 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2322 tree->type = EX_VALUE;
2323 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2324 valFromType (RETYPE (tree)));
2325 tree->right = tree->left = NULL;
2326 TETYPE (tree) = getSpec (TTYPE (tree) =
2327 tree->opval.val->type);
2330 LRVAL (tree) = RRVAL (tree) = 1;
2331 TETYPE (tree) = getSpec (TTYPE (tree) =
2332 computeType (LTYPE (tree),
2336 /*------------------------------------------------------------------*/
2337 /*----------------------------*/
2339 /*----------------------------*/
2341 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2343 werror (E_BITWISE_OP);
2344 werror (W_CONTINUE, "left & right types are ");
2345 printTypeChain (LTYPE (tree), stderr);
2346 fprintf (stderr, ",");
2347 printTypeChain (RTYPE (tree), stderr);
2348 fprintf (stderr, "\n");
2349 goto errorTreeReturn;
2351 /* if they are both literal then */
2352 /* rewrite the tree */
2353 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2355 tree->type = EX_VALUE;
2356 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2357 valFromType (RETYPE (tree)));
2358 tree->right = tree->left = NULL;
2359 TETYPE (tree) = getSpec (TTYPE (tree) =
2360 tree->opval.val->type);
2363 LRVAL (tree) = RRVAL (tree) = 1;
2364 TETYPE (tree) = getSpec (TTYPE (tree) =
2365 computeType (LTYPE (tree),
2369 /*------------------------------------------------------------------*/
2370 /*----------------------------*/
2371 /* address dereference */
2372 /*----------------------------*/
2373 case '*': /* can be unary : if right is null then unary operation */
2376 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2378 werror (E_PTR_REQD);
2379 goto errorTreeReturn;
2384 werror (E_LVALUE_REQUIRED, "pointer deref");
2385 goto errorTreeReturn;
2387 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2388 TETYPE (tree) = getSpec (TTYPE (tree));
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2394 /* multiplication */
2395 /*----------------------------*/
2396 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2398 werror (E_INVALID_OP, "multiplication");
2399 goto errorTreeReturn;
2402 /* if they are both literal then */
2403 /* rewrite the tree */
2404 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2406 tree->type = EX_VALUE;
2407 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2408 valFromType (RETYPE (tree)));
2409 tree->right = tree->left = NULL;
2410 TETYPE (tree) = getSpec (TTYPE (tree) =
2411 tree->opval.val->type);
2415 /* if left is a literal exchange left & right */
2416 if (IS_LITERAL (LTYPE (tree)))
2418 ast *tTree = tree->left;
2419 tree->left = tree->right;
2420 tree->right = tTree;
2423 LRVAL (tree) = RRVAL (tree) = 1;
2424 TETYPE (tree) = getSpec (TTYPE (tree) =
2425 computeType (LTYPE (tree),
2428 /* promote result to int if left & right are char
2429 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2430 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2431 SPEC_NOUN(TETYPE(tree)) = V_INT;
2436 /*------------------------------------------------------------------*/
2437 /*----------------------------*/
2438 /* unary '+' operator */
2439 /*----------------------------*/
2444 if (!IS_INTEGRAL (LTYPE (tree)))
2446 werror (E_UNARY_OP, '+');
2447 goto errorTreeReturn;
2450 /* if left is a literal then do it */
2451 if (IS_LITERAL (LTYPE (tree)))
2453 tree->type = EX_VALUE;
2454 tree->opval.val = valFromType (LETYPE (tree));
2456 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2460 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2464 /*------------------------------------------------------------------*/
2465 /*----------------------------*/
2467 /*----------------------------*/
2469 /* this is not a unary operation */
2470 /* if both pointers then problem */
2471 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2472 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2474 werror (E_PTR_PLUS_PTR);
2475 goto errorTreeReturn;
2478 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2479 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2481 werror (E_PLUS_INVALID, "+");
2482 goto errorTreeReturn;
2485 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2486 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2488 werror (E_PLUS_INVALID, "+");
2489 goto errorTreeReturn;
2491 /* if they are both literal then */
2492 /* rewrite the tree */
2493 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2495 tree->type = EX_VALUE;
2496 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2497 valFromType (RETYPE (tree)));
2498 tree->right = tree->left = NULL;
2499 TETYPE (tree) = getSpec (TTYPE (tree) =
2500 tree->opval.val->type);
2504 /* if the right is a pointer or left is a literal
2505 xchange left & right */
2506 if (IS_ARRAY (RTYPE (tree)) ||
2507 IS_PTR (RTYPE (tree)) ||
2508 IS_LITERAL (LTYPE (tree)))
2510 ast *tTree = tree->left;
2511 tree->left = tree->right;
2512 tree->right = tTree;
2515 LRVAL (tree) = RRVAL (tree) = 1;
2516 /* if the left is a pointer */
2517 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2518 TETYPE (tree) = getSpec (TTYPE (tree) =
2521 TETYPE (tree) = getSpec (TTYPE (tree) =
2522 computeType (LTYPE (tree),
2526 /*------------------------------------------------------------------*/
2527 /*----------------------------*/
2529 /*----------------------------*/
2530 case '-': /* can be unary */
2531 /* if right is null then unary */
2535 if (!IS_ARITHMETIC (LTYPE (tree)))
2537 werror (E_UNARY_OP, tree->opval.op);
2538 goto errorTreeReturn;
2541 /* if left is a literal then do it */
2542 if (IS_LITERAL (LTYPE (tree)))
2544 tree->type = EX_VALUE;
2545 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2547 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2548 SPEC_USIGN(TETYPE(tree)) = 0;
2552 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2556 /*------------------------------------------------------------------*/
2557 /*----------------------------*/
2559 /*----------------------------*/
2561 if (!(IS_PTR (LTYPE (tree)) ||
2562 IS_ARRAY (LTYPE (tree)) ||
2563 IS_ARITHMETIC (LTYPE (tree))))
2565 werror (E_PLUS_INVALID, "-");
2566 goto errorTreeReturn;
2569 if (!(IS_PTR (RTYPE (tree)) ||
2570 IS_ARRAY (RTYPE (tree)) ||
2571 IS_ARITHMETIC (RTYPE (tree))))
2573 werror (E_PLUS_INVALID, "-");
2574 goto errorTreeReturn;
2577 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2578 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2579 IS_INTEGRAL (RTYPE (tree))))
2581 werror (E_PLUS_INVALID, "-");
2582 goto errorTreeReturn;
2585 /* if they are both literal then */
2586 /* rewrite the tree */
2587 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2589 tree->type = EX_VALUE;
2590 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2591 valFromType (RETYPE (tree)));
2592 tree->right = tree->left = NULL;
2593 TETYPE (tree) = getSpec (TTYPE (tree) =
2594 tree->opval.val->type);
2598 /* if the left & right are equal then zero */
2599 if (isAstEqual (tree->left, tree->right))
2601 tree->type = EX_VALUE;
2602 tree->left = tree->right = NULL;
2603 tree->opval.val = constVal ("0");
2604 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2608 /* if both of them are pointers or arrays then */
2609 /* the result is going to be an integer */
2610 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2611 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2612 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2614 /* if only the left is a pointer */
2615 /* then result is a pointer */
2616 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2617 TETYPE (tree) = getSpec (TTYPE (tree) =
2620 TETYPE (tree) = getSpec (TTYPE (tree) =
2621 computeType (LTYPE (tree),
2623 LRVAL (tree) = RRVAL (tree) = 1;
2626 /*------------------------------------------------------------------*/
2627 /*----------------------------*/
2629 /*----------------------------*/
2631 /* can be only integral type */
2632 if (!IS_INTEGRAL (LTYPE (tree)))
2634 werror (E_UNARY_OP, tree->opval.op);
2635 goto errorTreeReturn;
2638 /* if left is a literal then do it */
2639 if (IS_LITERAL (LTYPE (tree)))
2641 tree->type = EX_VALUE;
2642 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2644 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2648 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2654 /*----------------------------*/
2656 /* can be pointer */
2657 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2658 !IS_PTR (LTYPE (tree)) &&
2659 !IS_ARRAY (LTYPE (tree)))
2661 werror (E_UNARY_OP, tree->opval.op);
2662 goto errorTreeReturn;
2665 /* if left is a literal then do it */
2666 if (IS_LITERAL (LTYPE (tree)))
2668 tree->type = EX_VALUE;
2669 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2671 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2675 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2678 /*------------------------------------------------------------------*/
2679 /*----------------------------*/
2681 /*----------------------------*/
2684 TTYPE (tree) = LTYPE (tree);
2685 TETYPE (tree) = LETYPE (tree);
2689 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2694 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2696 werror (E_SHIFT_OP_INVALID);
2697 werror (W_CONTINUE, "left & right types are ");
2698 printTypeChain (LTYPE (tree), stderr);
2699 fprintf (stderr, ",");
2700 printTypeChain (RTYPE (tree), stderr);
2701 fprintf (stderr, "\n");
2702 goto errorTreeReturn;
2705 /* if they are both literal then */
2706 /* rewrite the tree */
2707 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2709 tree->type = EX_VALUE;
2710 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2711 valFromType (RETYPE (tree)),
2712 (tree->opval.op == LEFT_OP ? 1 : 0));
2713 tree->right = tree->left = NULL;
2714 TETYPE (tree) = getSpec (TTYPE (tree) =
2715 tree->opval.val->type);
2719 /* if only the right side is a literal & we are
2720 shifting more than size of the left operand then zero */
2721 if (IS_LITERAL (RTYPE (tree)) &&
2722 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2723 (getSize (LTYPE (tree)) * 8))
2725 if (tree->opval.op==LEFT_OP ||
2726 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2727 lineno=tree->lineno;
2728 werror (W_SHIFT_CHANGED,
2729 (tree->opval.op == LEFT_OP ? "left" : "right"));
2730 tree->type = EX_VALUE;
2731 tree->left = tree->right = NULL;
2732 tree->opval.val = constVal ("0");
2733 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2737 LRVAL (tree) = RRVAL (tree) = 1;
2738 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2740 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2744 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2748 /*------------------------------------------------------------------*/
2749 /*----------------------------*/
2751 /*----------------------------*/
2752 case CAST: /* change the type */
2753 /* cannot cast to an aggregate type */
2754 if (IS_AGGREGATE (LTYPE (tree)))
2756 werror (E_CAST_ILLEGAL);
2757 goto errorTreeReturn;
2760 /* make sure the type is complete and sane */
2761 checkTypeSanity(LETYPE(tree), "(cast)");
2764 /* if the right is a literal replace the tree */
2765 if (IS_LITERAL (RETYPE (tree))) {
2766 if (!IS_PTR (LTYPE (tree))) {
2767 tree->type = EX_VALUE;
2769 valCastLiteral (LTYPE (tree),
2770 floatFromVal (valFromType (RETYPE (tree))));
2773 TTYPE (tree) = tree->opval.val->type;
2774 tree->values.literalFromCast = 1;
2775 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2776 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2777 sym_link *rest = LTYPE(tree)->next;
2778 werror(W_LITERAL_GENERIC);
2779 TTYPE(tree) = newLink(DECLARATOR);
2780 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2781 TTYPE(tree)->next = rest;
2782 tree->left->opval.lnk = TTYPE(tree);
2785 TTYPE (tree) = LTYPE (tree);
2789 TTYPE (tree) = LTYPE (tree);
2793 #if 0 // this is already checked, now this could be explicit
2794 /* if pointer to struct then check names */
2795 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2796 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2797 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2799 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2800 SPEC_STRUCT(LETYPE(tree))->tag);
2803 /* if the right is a literal replace the tree */
2804 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2805 tree->type = EX_VALUE;
2807 valCastLiteral (LTYPE (tree),
2808 floatFromVal (valFromType (RETYPE (tree))));
2811 TTYPE (tree) = tree->opval.val->type;
2812 tree->values.literalFromCast = 1;
2814 TTYPE (tree) = LTYPE (tree);
2818 TETYPE (tree) = getSpec (TTYPE (tree));
2822 /*------------------------------------------------------------------*/
2823 /*----------------------------*/
2824 /* logical &&, || */
2825 /*----------------------------*/
2828 /* each must me arithmetic type or be a pointer */
2829 if (!IS_PTR (LTYPE (tree)) &&
2830 !IS_ARRAY (LTYPE (tree)) &&
2831 !IS_INTEGRAL (LTYPE (tree)))
2833 werror (E_COMPARE_OP);
2834 goto errorTreeReturn;
2837 if (!IS_PTR (RTYPE (tree)) &&
2838 !IS_ARRAY (RTYPE (tree)) &&
2839 !IS_INTEGRAL (RTYPE (tree)))
2841 werror (E_COMPARE_OP);
2842 goto errorTreeReturn;
2844 /* if they are both literal then */
2845 /* rewrite the tree */
2846 if (IS_LITERAL (RTYPE (tree)) &&
2847 IS_LITERAL (LTYPE (tree)))
2849 tree->type = EX_VALUE;
2850 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2851 valFromType (RETYPE (tree)),
2853 tree->right = tree->left = NULL;
2854 TETYPE (tree) = getSpec (TTYPE (tree) =
2855 tree->opval.val->type);
2858 LRVAL (tree) = RRVAL (tree) = 1;
2859 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2862 /*------------------------------------------------------------------*/
2863 /*----------------------------*/
2864 /* comparison operators */
2865 /*----------------------------*/
2873 ast *lt = optimizeCompare (tree);
2879 /* if they are pointers they must be castable */
2880 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2882 if (tree->opval.op==EQ_OP &&
2883 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
2884 // we cannot cast a gptr to a !gptr: switch the leaves
2885 struct ast *s=tree->left;
2886 tree->left=tree->right;
2889 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2891 werror (E_COMPARE_OP);
2892 fprintf (stderr, "comparring type ");
2893 printTypeChain (LTYPE (tree), stderr);
2894 fprintf (stderr, "to type ");
2895 printTypeChain (RTYPE (tree), stderr);
2896 fprintf (stderr, "\n");
2897 goto errorTreeReturn;
2900 /* else they should be promotable to one another */
2903 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2904 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2906 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2908 werror (E_COMPARE_OP);
2909 fprintf (stderr, "comparing type ");
2910 printTypeChain (LTYPE (tree), stderr);
2911 fprintf (stderr, "to type ");
2912 printTypeChain (RTYPE (tree), stderr);
2913 fprintf (stderr, "\n");
2914 goto errorTreeReturn;
2917 /* if unsigned value < 0 then always false */
2918 /* if (unsigned value) > 0 then (unsigned value) */
2919 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2920 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2922 if (tree->opval.op == '<') {
2925 if (tree->opval.op == '>') {
2929 /* if they are both literal then */
2930 /* rewrite the tree */
2931 if (IS_LITERAL (RTYPE (tree)) &&
2932 IS_LITERAL (LTYPE (tree)))
2934 tree->type = EX_VALUE;
2935 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2936 valFromType (RETYPE (tree)),
2938 tree->right = tree->left = NULL;
2939 TETYPE (tree) = getSpec (TTYPE (tree) =
2940 tree->opval.val->type);
2943 LRVAL (tree) = RRVAL (tree) = 1;
2944 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2947 /*------------------------------------------------------------------*/
2948 /*----------------------------*/
2950 /*----------------------------*/
2951 case SIZEOF: /* evaluate wihout code generation */
2952 /* change the type to a integer */
2953 tree->type = EX_VALUE;
2954 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2955 tree->opval.val = constVal (buffer);
2956 tree->right = tree->left = NULL;
2957 TETYPE (tree) = getSpec (TTYPE (tree) =
2958 tree->opval.val->type);
2961 /*------------------------------------------------------------------*/
2962 /*----------------------------*/
2964 /*----------------------------*/
2966 /* return typeof enum value */
2967 tree->type = EX_VALUE;
2970 if (IS_SPEC(tree->right->ftype)) {
2971 switch (SPEC_NOUN(tree->right->ftype)) {
2973 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2974 else typeofv = TYPEOF_INT;
2977 typeofv = TYPEOF_FLOAT;
2980 typeofv = TYPEOF_CHAR;
2983 typeofv = TYPEOF_VOID;
2986 typeofv = TYPEOF_STRUCT;
2989 typeofv = TYPEOF_BITFIELD;
2992 typeofv = TYPEOF_BIT;
2995 typeofv = TYPEOF_SBIT;
3001 switch (DCL_TYPE(tree->right->ftype)) {
3003 typeofv = TYPEOF_POINTER;
3006 typeofv = TYPEOF_FPOINTER;
3009 typeofv = TYPEOF_CPOINTER;
3012 typeofv = TYPEOF_GPOINTER;
3015 typeofv = TYPEOF_PPOINTER;
3018 typeofv = TYPEOF_IPOINTER;
3021 typeofv = TYPEOF_ARRAY;
3024 typeofv = TYPEOF_FUNCTION;
3030 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3031 tree->opval.val = constVal (buffer);
3032 tree->right = tree->left = NULL;
3033 TETYPE (tree) = getSpec (TTYPE (tree) =
3034 tree->opval.val->type);
3037 /*------------------------------------------------------------------*/
3038 /*----------------------------*/
3039 /* conditional operator '?' */
3040 /*----------------------------*/
3042 /* the type is value of the colon operator (on the right) */
3043 assert(IS_COLON_OP(tree->right));
3044 /* if already known then replace the tree : optimizer will do it
3045 but faster to do it here */
3046 if (IS_LITERAL (LTYPE(tree))) {
3047 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3048 return decorateType(tree->right->left) ;
3050 return decorateType(tree->right->right) ;
3053 tree->right = decorateType(tree->right);
3054 TTYPE (tree) = RTYPE(tree);
3055 TETYPE (tree) = getSpec (TTYPE (tree));
3060 /* if they don't match we have a problem */
3061 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3063 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3064 goto errorTreeReturn;
3067 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3068 TETYPE (tree) = getSpec (TTYPE (tree));
3072 #if 0 // assignment operators are converted by the parser
3073 /*------------------------------------------------------------------*/
3074 /*----------------------------*/
3075 /* assignment operators */
3076 /*----------------------------*/
3079 /* for these it must be both must be integral */
3080 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3081 !IS_ARITHMETIC (RTYPE (tree)))
3083 werror (E_OPS_INTEGRAL);
3084 goto errorTreeReturn;
3087 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3089 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3090 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3094 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3095 goto errorTreeReturn;
3106 /* for these it must be both must be integral */
3107 if (!IS_INTEGRAL (LTYPE (tree)) ||
3108 !IS_INTEGRAL (RTYPE (tree)))
3110 werror (E_OPS_INTEGRAL);
3111 goto errorTreeReturn;
3114 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3116 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3117 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3121 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3122 goto errorTreeReturn;
3128 /*------------------------------------------------------------------*/
3129 /*----------------------------*/
3131 /*----------------------------*/
3133 if (!(IS_PTR (LTYPE (tree)) ||
3134 IS_ARITHMETIC (LTYPE (tree))))
3136 werror (E_PLUS_INVALID, "-=");
3137 goto errorTreeReturn;
3140 if (!(IS_PTR (RTYPE (tree)) ||
3141 IS_ARITHMETIC (RTYPE (tree))))
3143 werror (E_PLUS_INVALID, "-=");
3144 goto errorTreeReturn;
3147 TETYPE (tree) = getSpec (TTYPE (tree) =
3148 computeType (LTYPE (tree),
3151 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3152 werror (E_CODE_WRITE, "-=");
3156 werror (E_LVALUE_REQUIRED, "-=");
3157 goto errorTreeReturn;
3163 /*------------------------------------------------------------------*/
3164 /*----------------------------*/
3166 /*----------------------------*/
3168 /* this is not a unary operation */
3169 /* if both pointers then problem */
3170 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3172 werror (E_PTR_PLUS_PTR);
3173 goto errorTreeReturn;
3176 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3178 werror (E_PLUS_INVALID, "+=");
3179 goto errorTreeReturn;
3182 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3184 werror (E_PLUS_INVALID, "+=");
3185 goto errorTreeReturn;
3188 TETYPE (tree) = getSpec (TTYPE (tree) =
3189 computeType (LTYPE (tree),
3192 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3193 werror (E_CODE_WRITE, "+=");
3197 werror (E_LVALUE_REQUIRED, "+=");
3198 goto errorTreeReturn;
3201 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3202 tree->opval.op = '=';
3207 /*------------------------------------------------------------------*/
3208 /*----------------------------*/
3209 /* straight assignemnt */
3210 /*----------------------------*/
3212 /* cannot be an aggregate */
3213 if (IS_AGGREGATE (LTYPE (tree)))
3215 werror (E_AGGR_ASSIGN);
3216 goto errorTreeReturn;
3219 /* they should either match or be castable */
3220 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3222 werror (E_TYPE_MISMATCH, "assignment", " ");
3223 printFromToType(RTYPE(tree),LTYPE(tree));
3226 /* if the left side of the tree is of type void
3227 then report error */
3228 if (IS_VOID (LTYPE (tree)))
3230 werror (E_CAST_ZERO);
3231 printFromToType(RTYPE(tree), LTYPE(tree));
3234 TETYPE (tree) = getSpec (TTYPE (tree) =
3238 if (!tree->initMode ) {
3239 if (IS_CONSTANT(LTYPE(tree)))
3240 werror (E_CODE_WRITE, "=");
3244 werror (E_LVALUE_REQUIRED, "=");
3245 goto errorTreeReturn;
3250 /*------------------------------------------------------------------*/
3251 /*----------------------------*/
3252 /* comma operator */
3253 /*----------------------------*/
3255 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3258 /*------------------------------------------------------------------*/
3259 /*----------------------------*/
3261 /*----------------------------*/
3265 if (processParms (tree->left,
3266 FUNC_ARGS(tree->left->ftype),
3267 tree->right, &parmNumber, TRUE)) {
3268 goto errorTreeReturn;
3271 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3272 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3274 reverseParms (tree->right);
3277 if (IS_CODEPTR(LTYPE(tree))) {
3278 TTYPE(tree) = LTYPE(tree)->next->next;
3280 TTYPE(tree) = LTYPE(tree)->next;
3282 TETYPE (tree) = getSpec (TTYPE (tree));
3285 /*------------------------------------------------------------------*/
3286 /*----------------------------*/
3287 /* return statement */
3288 /*----------------------------*/
3293 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3295 werror (W_RETURN_MISMATCH);
3296 printFromToType (RTYPE(tree), currFunc->type->next);
3297 goto errorTreeReturn;
3300 if (IS_VOID (currFunc->type->next)
3302 !IS_VOID (RTYPE (tree)))
3304 werror (E_FUNC_VOID);
3305 goto errorTreeReturn;
3308 /* if there is going to be a casing required then add it */
3309 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3312 decorateType (newNode (CAST,
3313 newAst_LINK (copyLinkChain (currFunc->type->next)),
3322 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3324 werror (W_VOID_FUNC, currFunc->name);
3325 goto errorTreeReturn;
3328 TTYPE (tree) = TETYPE (tree) = NULL;
3331 /*------------------------------------------------------------------*/
3332 /*----------------------------*/
3333 /* switch statement */
3334 /*----------------------------*/
3336 /* the switch value must be an integer */
3337 if (!IS_INTEGRAL (LTYPE (tree)))
3339 werror (E_SWITCH_NON_INTEGER);
3340 goto errorTreeReturn;
3343 TTYPE (tree) = TETYPE (tree) = NULL;
3346 /*------------------------------------------------------------------*/
3347 /*----------------------------*/
3349 /*----------------------------*/
3351 tree->left = backPatchLabels (tree->left,
3354 TTYPE (tree) = TETYPE (tree) = NULL;
3357 /*------------------------------------------------------------------*/
3358 /*----------------------------*/
3360 /*----------------------------*/
3363 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3364 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3365 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3367 /* if the for loop is reversible then
3368 reverse it otherwise do what we normally
3374 if (isLoopReversible (tree, &sym, &init, &end))
3375 return reverseLoop (tree, sym, init, end);
3377 return decorateType (createFor (AST_FOR (tree, trueLabel),
3378 AST_FOR (tree, continueLabel),
3379 AST_FOR (tree, falseLabel),
3380 AST_FOR (tree, condLabel),
3381 AST_FOR (tree, initExpr),
3382 AST_FOR (tree, condExpr),
3383 AST_FOR (tree, loopExpr),
3387 TTYPE (tree) = TETYPE (tree) = NULL;
3391 /* some error found this tree will be killed */
3393 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3394 tree->opval.op = NULLOP;
3400 /*-----------------------------------------------------------------*/
3401 /* sizeofOp - processes size of operation */
3402 /*-----------------------------------------------------------------*/
3404 sizeofOp (sym_link * type)
3408 /* make sure the type is complete and sane */
3409 checkTypeSanity(type, "(sizeof)");
3411 /* get the size and convert it to character */
3412 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3414 /* now convert into value */
3415 return constVal (buff);
3419 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3420 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3421 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3422 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3423 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3424 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3425 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3427 /*-----------------------------------------------------------------*/
3428 /* backPatchLabels - change and or not operators to flow control */
3429 /*-----------------------------------------------------------------*/
3431 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3437 if (!(IS_ANDORNOT (tree)))
3440 /* if this an and */
3443 static int localLbl = 0;
3446 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3447 localLabel = newSymbol (buffer, NestLevel);
3449 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3451 /* if left is already a IFX then just change the if true label in that */
3452 if (!IS_IFX (tree->left))
3453 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3455 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3456 /* right is a IFX then just join */
3457 if (IS_IFX (tree->right))
3458 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3460 tree->right = createLabel (localLabel, tree->right);
3461 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3463 return newNode (NULLOP, tree->left, tree->right);
3466 /* if this is an or operation */
3469 static int localLbl = 0;
3472 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3473 localLabel = newSymbol (buffer, NestLevel);
3475 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3477 /* if left is already a IFX then just change the if true label in that */
3478 if (!IS_IFX (tree->left))
3479 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3481 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3482 /* right is a IFX then just join */
3483 if (IS_IFX (tree->right))
3484 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3486 tree->right = createLabel (localLabel, tree->right);
3487 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3489 return newNode (NULLOP, tree->left, tree->right);
3495 int wasnot = IS_NOT (tree->left);
3496 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3498 /* if the left is already a IFX */
3499 if (!IS_IFX (tree->left))
3500 tree->left = newNode (IFX, tree->left, NULL);
3504 tree->left->trueLabel = trueLabel;
3505 tree->left->falseLabel = falseLabel;
3509 tree->left->trueLabel = falseLabel;
3510 tree->left->falseLabel = trueLabel;
3517 tree->trueLabel = trueLabel;
3518 tree->falseLabel = falseLabel;
3525 /*-----------------------------------------------------------------*/
3526 /* createBlock - create expression tree for block */
3527 /*-----------------------------------------------------------------*/
3529 createBlock (symbol * decl, ast * body)
3533 /* if the block has nothing */
3537 ex = newNode (BLOCK, NULL, body);
3538 ex->values.sym = decl;
3540 ex->right = ex->right;
3546 /*-----------------------------------------------------------------*/
3547 /* createLabel - creates the expression tree for labels */
3548 /*-----------------------------------------------------------------*/
3550 createLabel (symbol * label, ast * stmnt)
3553 char name[SDCC_NAME_MAX + 1];
3556 /* must create fresh symbol if the symbol name */
3557 /* exists in the symbol table, since there can */
3558 /* be a variable with the same name as the labl */
3559 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3560 (csym->level == label->level))
3561 label = newSymbol (label->name, label->level);
3563 /* change the name before putting it in add _ */
3564 SNPRINTF(name, sizeof(name), "%s", label->name);
3566 /* put the label in the LabelSymbol table */
3567 /* but first check if a label of the same */
3569 if ((csym = findSym (LabelTab, NULL, name)))
3570 werror (E_DUPLICATE_LABEL, label->name);
3572 addSym (LabelTab, label, name, label->level, 0, 0);
3575 label->key = labelKey++;
3576 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3582 /*-----------------------------------------------------------------*/
3583 /* createCase - generates the parsetree for a case statement */
3584 /*-----------------------------------------------------------------*/
3586 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3588 char caseLbl[SDCC_NAME_MAX + 1];
3592 /* if the switch statement does not exist */
3593 /* then case is out of context */
3596 werror (E_CASE_CONTEXT);
3600 caseVal = decorateType (resolveSymbols (caseVal));
3601 /* if not a constant then error */
3602 if (!IS_LITERAL (caseVal->ftype))
3604 werror (E_CASE_CONSTANT);
3608 /* if not a integer than error */
3609 if (!IS_INTEGRAL (caseVal->ftype))
3611 werror (E_CASE_NON_INTEGER);
3615 /* find the end of the switch values chain */
3616 if (!(val = swStat->values.switchVals.swVals))
3617 swStat->values.switchVals.swVals = caseVal->opval.val;
3620 /* also order the cases according to value */
3622 int cVal = (int) floatFromVal (caseVal->opval.val);
3623 while (val && (int) floatFromVal (val) < cVal)
3629 /* if we reached the end then */
3632 pval->next = caseVal->opval.val;
3636 /* we found a value greater than */
3637 /* the current value we must add this */
3638 /* before the value */
3639 caseVal->opval.val->next = val;
3641 /* if this was the first in chain */
3642 if (swStat->values.switchVals.swVals == val)
3643 swStat->values.switchVals.swVals =
3646 pval->next = caseVal->opval.val;
3651 /* create the case label */
3652 SNPRINTF(caseLbl, sizeof(caseLbl),
3654 swStat->values.switchVals.swNum,
3655 (int) floatFromVal (caseVal->opval.val));
3657 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3662 /*-----------------------------------------------------------------*/
3663 /* createDefault - creates the parse tree for the default statement */
3664 /*-----------------------------------------------------------------*/
3666 createDefault (ast * swStat, ast * stmnt)
3668 char defLbl[SDCC_NAME_MAX + 1];
3670 /* if the switch statement does not exist */
3671 /* then case is out of context */
3674 werror (E_CASE_CONTEXT);
3678 /* turn on the default flag */
3679 swStat->values.switchVals.swDefault = 1;
3681 /* create the label */
3682 SNPRINTF (defLbl, sizeof(defLbl),
3683 "_default_%d", swStat->values.switchVals.swNum);
3684 return createLabel (newSymbol (defLbl, 0), stmnt);
3687 /*-----------------------------------------------------------------*/
3688 /* createIf - creates the parsetree for the if statement */
3689 /*-----------------------------------------------------------------*/
3691 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3693 static int Lblnum = 0;
3695 symbol *ifTrue, *ifFalse, *ifEnd;
3697 /* if neither exists */
3698 if (!elseBody && !ifBody) {
3699 // if there are no side effects (i++, j() etc)
3700 if (!hasSEFcalls(condAst)) {
3705 /* create the labels */
3706 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3707 ifFalse = newSymbol (buffer, NestLevel);
3708 /* if no else body then end == false */
3713 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3714 ifEnd = newSymbol (buffer, NestLevel);
3717 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3718 ifTrue = newSymbol (buffer, NestLevel);
3722 /* attach the ifTrue label to the top of it body */
3723 ifBody = createLabel (ifTrue, ifBody);
3724 /* attach a goto end to the ifBody if else is present */
3727 ifBody = newNode (NULLOP, ifBody,
3729 newAst_VALUE (symbolVal (ifEnd)),
3731 /* put the elseLabel on the else body */
3732 elseBody = createLabel (ifFalse, elseBody);
3733 /* out the end at the end of the body */
3734 elseBody = newNode (NULLOP,
3736 createLabel (ifEnd, NULL));
3740 ifBody = newNode (NULLOP, ifBody,
3741 createLabel (ifFalse, NULL));
3743 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3744 if (IS_IFX (condAst))
3747 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3749 return newNode (NULLOP, ifTree,
3750 newNode (NULLOP, ifBody, elseBody));
3754 /*-----------------------------------------------------------------*/
3755 /* createDo - creates parse tree for do */
3758 /* _docontinue_n: */
3759 /* condition_expression +-> trueLabel -> _dobody_n */
3761 /* +-> falseLabel-> _dobreak_n */
3763 /*-----------------------------------------------------------------*/
3765 createDo (symbol * trueLabel, symbol * continueLabel,
3766 symbol * falseLabel, ast * condAst, ast * doBody)
3771 /* if the body does not exist then it is simple */
3774 condAst = backPatchLabels (condAst, continueLabel, NULL);
3775 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3776 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3777 doTree->trueLabel = continueLabel;
3778 doTree->falseLabel = NULL;
3782 /* otherwise we have a body */
3783 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3785 /* attach the body label to the top */
3786 doBody = createLabel (trueLabel, doBody);
3787 /* attach the continue label to end of body */
3788 doBody = newNode (NULLOP, doBody,
3789 createLabel (continueLabel, NULL));
3791 /* now put the break label at the end */
3792 if (IS_IFX (condAst))
3795 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3797 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3799 /* putting it together */
3800 return newNode (NULLOP, doBody, doTree);
3803 /*-----------------------------------------------------------------*/
3804 /* createFor - creates parse tree for 'for' statement */
3807 /* condExpr +-> trueLabel -> _forbody_n */
3809 /* +-> falseLabel-> _forbreak_n */
3812 /* _forcontinue_n: */
3814 /* goto _forcond_n ; */
3816 /*-----------------------------------------------------------------*/
3818 createFor (symbol * trueLabel, symbol * continueLabel,
3819 symbol * falseLabel, symbol * condLabel,
3820 ast * initExpr, ast * condExpr, ast * loopExpr,
3825 /* if loopexpression not present then we can generate it */
3826 /* the same way as a while */
3828 return newNode (NULLOP, initExpr,
3829 createWhile (trueLabel, continueLabel,
3830 falseLabel, condExpr, forBody));
3831 /* vanilla for statement */
3832 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3834 if (condExpr && !IS_IFX (condExpr))
3835 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3838 /* attach condition label to condition */
3839 condExpr = createLabel (condLabel, condExpr);
3841 /* attach body label to body */
3842 forBody = createLabel (trueLabel, forBody);
3844 /* attach continue to forLoop expression & attach */
3845 /* goto the forcond @ and of loopExpression */
3846 loopExpr = createLabel (continueLabel,
3850 newAst_VALUE (symbolVal (condLabel)),
3852 /* now start putting them together */
3853 forTree = newNode (NULLOP, initExpr, condExpr);
3854 forTree = newNode (NULLOP, forTree, forBody);
3855 forTree = newNode (NULLOP, forTree, loopExpr);
3856 /* finally add the break label */
3857 forTree = newNode (NULLOP, forTree,
3858 createLabel (falseLabel, NULL));
3862 /*-----------------------------------------------------------------*/
3863 /* createWhile - creates parse tree for while statement */
3864 /* the while statement will be created as follows */
3866 /* _while_continue_n: */
3867 /* condition_expression +-> trueLabel -> _while_boby_n */
3869 /* +-> falseLabel -> _while_break_n */
3870 /* _while_body_n: */
3872 /* goto _while_continue_n */
3873 /* _while_break_n: */
3874 /*-----------------------------------------------------------------*/
3876 createWhile (symbol * trueLabel, symbol * continueLabel,
3877 symbol * falseLabel, ast * condExpr, ast * whileBody)
3881 /* put the continue label */
3882 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3883 condExpr = createLabel (continueLabel, condExpr);
3884 condExpr->lineno = 0;
3886 /* put the body label in front of the body */
3887 whileBody = createLabel (trueLabel, whileBody);
3888 whileBody->lineno = 0;
3889 /* put a jump to continue at the end of the body */
3890 /* and put break label at the end of the body */
3891 whileBody = newNode (NULLOP,
3894 newAst_VALUE (symbolVal (continueLabel)),
3895 createLabel (falseLabel, NULL)));
3897 /* put it all together */
3898 if (IS_IFX (condExpr))
3899 whileTree = condExpr;
3902 whileTree = newNode (IFX, condExpr, NULL);
3903 /* put the true & false labels in place */
3904 whileTree->trueLabel = trueLabel;
3905 whileTree->falseLabel = falseLabel;
3908 return newNode (NULLOP, whileTree, whileBody);
3911 /*-----------------------------------------------------------------*/
3912 /* optimizeGetHbit - get highest order bit of the expression */
3913 /*-----------------------------------------------------------------*/
3915 optimizeGetHbit (ast * tree)
3918 /* if this is not a bit and */
3919 if (!IS_BITAND (tree))
3922 /* will look for tree of the form
3923 ( expr >> ((sizeof expr) -1) ) & 1 */
3924 if (!IS_AST_LIT_VALUE (tree->right))
3927 if (AST_LIT_VALUE (tree->right) != 1)
3930 if (!IS_RIGHT_OP (tree->left))
3933 if (!IS_AST_LIT_VALUE (tree->left->right))
3936 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3937 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3940 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3944 /*-----------------------------------------------------------------*/
3945 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3946 /*-----------------------------------------------------------------*/
3948 optimizeRRCRLC (ast * root)
3950 /* will look for trees of the form
3951 (?expr << 1) | (?expr >> 7) or
3952 (?expr >> 7) | (?expr << 1) will make that
3953 into a RLC : operation ..
3955 (?expr >> 1) | (?expr << 7) or
3956 (?expr << 7) | (?expr >> 1) will make that
3957 into a RRC operation
3958 note : by 7 I mean (number of bits required to hold the
3960 /* if the root operations is not a | operation the not */
3961 if (!IS_BITOR (root))
3964 /* I have to think of a better way to match patterns this sucks */
3965 /* that aside let start looking for the first case : I use a the
3966 negative check a lot to improve the efficiency */
3967 /* (?expr << 1) | (?expr >> 7) */
3968 if (IS_LEFT_OP (root->left) &&
3969 IS_RIGHT_OP (root->right))
3972 if (!SPEC_USIGN (TETYPE (root->left->left)))
3975 if (!IS_AST_LIT_VALUE (root->left->right) ||
3976 !IS_AST_LIT_VALUE (root->right->right))
3979 /* make sure it is the same expression */
3980 if (!isAstEqual (root->left->left,
3984 if (AST_LIT_VALUE (root->left->right) != 1)
3987 if (AST_LIT_VALUE (root->right->right) !=
3988 (getSize (TTYPE (root->left->left)) * 8 - 1))
3991 /* whew got the first case : create the AST */
3992 return newNode (RLC, root->left->left, NULL);
3996 /* check for second case */
3997 /* (?expr >> 7) | (?expr << 1) */
3998 if (IS_LEFT_OP (root->right) &&
3999 IS_RIGHT_OP (root->left))
4002 if (!SPEC_USIGN (TETYPE (root->left->left)))
4005 if (!IS_AST_LIT_VALUE (root->left->right) ||
4006 !IS_AST_LIT_VALUE (root->right->right))
4009 /* make sure it is the same symbol */
4010 if (!isAstEqual (root->left->left,
4014 if (AST_LIT_VALUE (root->right->right) != 1)
4017 if (AST_LIT_VALUE (root->left->right) !=
4018 (getSize (TTYPE (root->left->left)) * 8 - 1))
4021 /* whew got the first case : create the AST */
4022 return newNode (RLC, root->left->left, NULL);
4027 /* third case for RRC */
4028 /* (?symbol >> 1) | (?symbol << 7) */
4029 if (IS_LEFT_OP (root->right) &&
4030 IS_RIGHT_OP (root->left))
4033 if (!SPEC_USIGN (TETYPE (root->left->left)))
4036 if (!IS_AST_LIT_VALUE (root->left->right) ||
4037 !IS_AST_LIT_VALUE (root->right->right))
4040 /* make sure it is the same symbol */
4041 if (!isAstEqual (root->left->left,
4045 if (AST_LIT_VALUE (root->left->right) != 1)
4048 if (AST_LIT_VALUE (root->right->right) !=
4049 (getSize (TTYPE (root->left->left)) * 8 - 1))
4052 /* whew got the first case : create the AST */
4053 return newNode (RRC, root->left->left, NULL);
4057 /* fourth and last case for now */
4058 /* (?symbol << 7) | (?symbol >> 1) */
4059 if (IS_RIGHT_OP (root->right) &&
4060 IS_LEFT_OP (root->left))
4063 if (!SPEC_USIGN (TETYPE (root->left->left)))
4066 if (!IS_AST_LIT_VALUE (root->left->right) ||
4067 !IS_AST_LIT_VALUE (root->right->right))
4070 /* make sure it is the same symbol */
4071 if (!isAstEqual (root->left->left,
4075 if (AST_LIT_VALUE (root->right->right) != 1)
4078 if (AST_LIT_VALUE (root->left->right) !=
4079 (getSize (TTYPE (root->left->left)) * 8 - 1))
4082 /* whew got the first case : create the AST */
4083 return newNode (RRC, root->left->left, NULL);
4087 /* not found return root */
4091 /*-----------------------------------------------------------------*/
4092 /* optimizeCompare - otimizes compares for bit variables */
4093 /*-----------------------------------------------------------------*/
4095 optimizeCompare (ast * root)
4097 ast *optExpr = NULL;
4100 unsigned int litValue;
4102 /* if nothing then return nothing */
4106 /* if not a compare op then do leaves */
4107 if (!IS_COMPARE_OP (root))
4109 root->left = optimizeCompare (root->left);
4110 root->right = optimizeCompare (root->right);
4114 /* if left & right are the same then depending
4115 of the operation do */
4116 if (isAstEqual (root->left, root->right))
4118 switch (root->opval.op)
4123 optExpr = newAst_VALUE (constVal ("0"));
4128 optExpr = newAst_VALUE (constVal ("1"));
4132 return decorateType (optExpr);
4135 vleft = (root->left->type == EX_VALUE ?
4136 root->left->opval.val : NULL);
4138 vright = (root->right->type == EX_VALUE ?
4139 root->right->opval.val : NULL);
4141 /* if left is a BITVAR in BITSPACE */
4142 /* and right is a LITERAL then opt- */
4143 /* imize else do nothing */
4144 if (vleft && vright &&
4145 IS_BITVAR (vleft->etype) &&
4146 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4147 IS_LITERAL (vright->etype))
4150 /* if right side > 1 then comparison may never succeed */
4151 if ((litValue = (int) floatFromVal (vright)) > 1)
4153 werror (W_BAD_COMPARE);
4159 switch (root->opval.op)
4161 case '>': /* bit value greater than 1 cannot be */
4162 werror (W_BAD_COMPARE);
4166 case '<': /* bit value < 1 means 0 */
4168 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4171 case LE_OP: /* bit value <= 1 means no check */
4172 optExpr = newAst_VALUE (vright);
4175 case GE_OP: /* bit value >= 1 means only check for = */
4177 optExpr = newAst_VALUE (vleft);
4182 { /* literal is zero */
4183 switch (root->opval.op)
4185 case '<': /* bit value < 0 cannot be */
4186 werror (W_BAD_COMPARE);
4190 case '>': /* bit value > 0 means 1 */
4192 optExpr = newAst_VALUE (vleft);
4195 case LE_OP: /* bit value <= 0 means no check */
4196 case GE_OP: /* bit value >= 0 means no check */
4197 werror (W_BAD_COMPARE);
4201 case EQ_OP: /* bit == 0 means ! of bit */
4202 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4206 return decorateType (resolveSymbols (optExpr));
4207 } /* end-of-if of BITVAR */
4212 /*-----------------------------------------------------------------*/
4213 /* addSymToBlock : adds the symbol to the first block we find */
4214 /*-----------------------------------------------------------------*/
4216 addSymToBlock (symbol * sym, ast * tree)
4218 /* reached end of tree or a leaf */
4219 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4223 if (IS_AST_OP (tree) &&
4224 tree->opval.op == BLOCK)
4227 symbol *lsym = copySymbol (sym);
4229 lsym->next = AST_VALUES (tree, sym);
4230 AST_VALUES (tree, sym) = lsym;
4234 addSymToBlock (sym, tree->left);
4235 addSymToBlock (sym, tree->right);
4238 /*-----------------------------------------------------------------*/
4239 /* processRegParms - do processing for register parameters */
4240 /*-----------------------------------------------------------------*/
4242 processRegParms (value * args, ast * body)
4246 if (IS_REGPARM (args->etype))
4247 addSymToBlock (args->sym, body);
4252 /*-----------------------------------------------------------------*/
4253 /* resetParmKey - resets the operandkeys for the symbols */
4254 /*-----------------------------------------------------------------*/
4255 DEFSETFUNC (resetParmKey)
4266 /*-----------------------------------------------------------------*/
4267 /* createFunction - This is the key node that calls the iCode for */
4268 /* generating the code for a function. Note code */
4269 /* is generated function by function, later when */
4270 /* add inter-procedural analysis this will change */
4271 /*-----------------------------------------------------------------*/
4273 createFunction (symbol * name, ast * body)
4279 iCode *piCode = NULL;
4281 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4282 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4284 /* if check function return 0 then some problem */
4285 if (checkFunction (name, NULL) == 0)
4288 /* create a dummy block if none exists */
4290 body = newNode (BLOCK, NULL, NULL);
4294 /* check if the function name already in the symbol table */
4295 if ((csym = findSym (SymbolTab, NULL, name->name)))
4298 /* special case for compiler defined functions
4299 we need to add the name to the publics list : this
4300 actually means we are now compiling the compiler
4304 addSet (&publics, name);
4310 allocVariables (name);
4312 name->lastLine = mylineno;
4315 /* set the stack pointer */
4316 /* PENDING: check this for the mcs51 */
4317 stackPtr = -port->stack.direction * port->stack.call_overhead;
4318 if (IFFUNC_ISISR (name->type))
4319 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4320 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4321 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4323 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4325 fetype = getSpec (name->type); /* get the specifier for the function */
4326 /* if this is a reentrant function then */
4327 if (IFFUNC_ISREENT (name->type))
4330 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4332 /* do processing for parameters that are passed in registers */
4333 processRegParms (FUNC_ARGS(name->type), body);
4335 /* set the stack pointer */
4339 /* allocate & autoinit the block variables */
4340 processBlockVars (body, &stack, ALLOCATE);
4342 /* save the stack information */
4343 if (options.useXstack)
4344 name->xstack = SPEC_STAK (fetype) = stack;
4346 name->stack = SPEC_STAK (fetype) = stack;
4348 /* name needs to be mangled */
4349 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4351 body = resolveSymbols (body); /* resolve the symbols */
4352 body = decorateType (body); /* propagateType & do semantic checks */
4354 ex = newAst_VALUE (symbolVal (name)); /* create name */
4355 ex = newNode (FUNCTION, ex, body);
4356 ex->values.args = FUNC_ARGS(name->type);
4358 if (options.dump_tree) PA(ex);
4361 werror (E_FUNC_NO_CODE, name->name);
4365 /* create the node & generate intermediate code */
4367 codeOutFile = code->oFile;
4368 piCode = iCodeFromAst (ex);
4372 werror (E_FUNC_NO_CODE, name->name);
4376 eBBlockFromiCode (piCode);
4378 /* if there are any statics then do them */
4381 GcurMemmap = statsg;
4382 codeOutFile = statsg->oFile;
4383 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4389 /* dealloc the block variables */
4390 processBlockVars (body, &stack, DEALLOCATE);
4391 outputDebugStackSymbols();
4392 /* deallocate paramaters */
4393 deallocParms (FUNC_ARGS(name->type));
4395 if (IFFUNC_ISREENT (name->type))
4398 /* we are done freeup memory & cleanup */
4400 if (port->reset_labelKey) labelKey = 1;
4402 FUNC_HASBODY(name->type) = 1;
4403 addSet (&operKeyReset, name);
4404 applyToSet (operKeyReset, resetParmKey);
4409 cleanUpLevel (LabelTab, 0);
4410 cleanUpBlock (StructTab, 1);
4411 cleanUpBlock (TypedefTab, 1);
4413 xstack->syms = NULL;
4414 istack->syms = NULL;
4419 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4420 /*-----------------------------------------------------------------*/
4421 /* ast_print : prints the ast (for debugging purposes) */
4422 /*-----------------------------------------------------------------*/
4424 void ast_print (ast * tree, FILE *outfile, int indent)
4429 /* can print only decorated trees */
4430 if (!tree->decorated) return;
4432 /* if any child is an error | this one is an error do nothing */
4433 if (tree->isError ||
4434 (tree->left && tree->left->isError) ||
4435 (tree->right && tree->right->isError)) {
4436 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4440 /* print the line */
4441 /* if not block & function */
4442 if (tree->type == EX_OP &&
4443 (tree->opval.op != FUNCTION &&
4444 tree->opval.op != BLOCK &&
4445 tree->opval.op != NULLOP)) {
4448 if (tree->opval.op == FUNCTION) {
4450 value *args=FUNC_ARGS(tree->left->opval.val->type);
4451 fprintf(outfile,"FUNCTION (%s=%p) type (",
4452 tree->left->opval.val->name, tree);
4453 printTypeChain (tree->left->opval.val->type->next,outfile);
4454 fprintf(outfile,") args (");
4457 fprintf (outfile, ", ");
4459 printTypeChain (args ? args->type : NULL, outfile);
4461 args= args ? args->next : NULL;
4463 fprintf(outfile,")\n");
4464 ast_print(tree->left,outfile,indent);
4465 ast_print(tree->right,outfile,indent);
4468 if (tree->opval.op == BLOCK) {
4469 symbol *decls = tree->values.sym;
4470 INDENT(indent,outfile);
4471 fprintf(outfile,"{\n");
4473 INDENT(indent+2,outfile);
4474 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4475 decls->name, decls);
4476 printTypeChain(decls->type,outfile);
4477 fprintf(outfile,")\n");
4479 decls = decls->next;
4481 ast_print(tree->right,outfile,indent+2);
4482 INDENT(indent,outfile);
4483 fprintf(outfile,"}\n");
4486 if (tree->opval.op == NULLOP) {
4487 ast_print(tree->left,outfile,indent);
4488 ast_print(tree->right,outfile,indent);
4491 INDENT(indent,outfile);
4493 /*------------------------------------------------------------------*/
4494 /*----------------------------*/
4495 /* leaf has been reached */
4496 /*----------------------------*/
4497 /* if this is of type value */
4498 /* just get the type */
4499 if (tree->type == EX_VALUE) {
4501 if (IS_LITERAL (tree->opval.val->etype)) {
4502 fprintf(outfile,"CONSTANT (%p) value = ", tree);
4503 if (SPEC_USIGN (tree->opval.val->etype))
4504 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
4506 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
4507 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
4508 floatFromVal(tree->opval.val));
4509 } else if (tree->opval.val->sym) {
4510 /* if the undefined flag is set then give error message */
4511 if (tree->opval.val->sym->undefined) {
4512 fprintf(outfile,"UNDEFINED SYMBOL ");
4514 fprintf(outfile,"SYMBOL ");
4516 fprintf(outfile,"(%s=%p)",
4517 tree->opval.val->sym->name,tree);
4520 fprintf(outfile," type (");
4521 printTypeChain(tree->ftype,outfile);
4522 fprintf(outfile,")\n");
4524 fprintf(outfile,"\n");
4529 /* if type link for the case of cast */
4530 if (tree->type == EX_LINK) {
4531 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4532 printTypeChain(tree->opval.lnk,outfile);
4533 fprintf(outfile,")\n");
4538 /* depending on type of operator do */
4540 switch (tree->opval.op) {
4541 /*------------------------------------------------------------------*/
4542 /*----------------------------*/
4544 /*----------------------------*/
4546 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4547 printTypeChain(tree->ftype,outfile);
4548 fprintf(outfile,")\n");
4549 ast_print(tree->left,outfile,indent+2);
4550 ast_print(tree->right,outfile,indent+2);
4553 /*------------------------------------------------------------------*/
4554 /*----------------------------*/
4556 /*----------------------------*/
4558 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4559 printTypeChain(tree->ftype,outfile);
4560 fprintf(outfile,")\n");
4561 ast_print(tree->left,outfile,indent+2);
4562 ast_print(tree->right,outfile,indent+2);
4565 /*------------------------------------------------------------------*/
4566 /*----------------------------*/
4567 /* struct/union pointer */
4568 /*----------------------------*/
4570 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4571 printTypeChain(tree->ftype,outfile);
4572 fprintf(outfile,")\n");
4573 ast_print(tree->left,outfile,indent+2);
4574 ast_print(tree->right,outfile,indent+2);
4577 /*------------------------------------------------------------------*/
4578 /*----------------------------*/
4579 /* ++/-- operation */
4580 /*----------------------------*/
4581 case INC_OP: /* incerement operator unary so left only */
4582 fprintf(outfile,"INC_OP (%p) type (",tree);
4583 printTypeChain(tree->ftype,outfile);
4584 fprintf(outfile,")\n");
4585 ast_print(tree->left,outfile,indent+2);
4589 fprintf(outfile,"DEC_OP (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->left,outfile,indent+2);
4595 /*------------------------------------------------------------------*/
4596 /*----------------------------*/
4598 /*----------------------------*/
4601 fprintf(outfile,"& (%p) type (",tree);
4602 printTypeChain(tree->ftype,outfile);
4603 fprintf(outfile,")\n");
4604 ast_print(tree->left,outfile,indent+2);
4605 ast_print(tree->right,outfile,indent+2);
4607 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4608 printTypeChain(tree->ftype,outfile);
4609 fprintf(outfile,")\n");
4610 ast_print(tree->left,outfile,indent+2);
4611 ast_print(tree->right,outfile,indent+2);
4614 /*----------------------------*/
4616 /*----------------------------*/
4618 fprintf(outfile,"OR (%p) type (",tree);
4619 printTypeChain(tree->ftype,outfile);
4620 fprintf(outfile,")\n");
4621 ast_print(tree->left,outfile,indent+2);
4622 ast_print(tree->right,outfile,indent+2);
4624 /*------------------------------------------------------------------*/
4625 /*----------------------------*/
4627 /*----------------------------*/
4629 fprintf(outfile,"XOR (%p) type (",tree);
4630 printTypeChain(tree->ftype,outfile);
4631 fprintf(outfile,")\n");
4632 ast_print(tree->left,outfile,indent+2);
4633 ast_print(tree->right,outfile,indent+2);
4636 /*------------------------------------------------------------------*/
4637 /*----------------------------*/
4639 /*----------------------------*/
4641 fprintf(outfile,"DIV (%p) type (",tree);
4642 printTypeChain(tree->ftype,outfile);
4643 fprintf(outfile,")\n");
4644 ast_print(tree->left,outfile,indent+2);
4645 ast_print(tree->right,outfile,indent+2);
4647 /*------------------------------------------------------------------*/
4648 /*----------------------------*/
4650 /*----------------------------*/
4652 fprintf(outfile,"MOD (%p) type (",tree);
4653 printTypeChain(tree->ftype,outfile);
4654 fprintf(outfile,")\n");
4655 ast_print(tree->left,outfile,indent+2);
4656 ast_print(tree->right,outfile,indent+2);
4659 /*------------------------------------------------------------------*/
4660 /*----------------------------*/
4661 /* address dereference */
4662 /*----------------------------*/
4663 case '*': /* can be unary : if right is null then unary operation */
4665 fprintf(outfile,"DEREF (%p) type (",tree);
4666 printTypeChain(tree->ftype,outfile);
4667 fprintf(outfile,")\n");
4668 ast_print(tree->left,outfile,indent+2);
4671 /*------------------------------------------------------------------*/
4672 /*----------------------------*/
4673 /* multiplication */
4674 /*----------------------------*/
4675 fprintf(outfile,"MULT (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+2);
4679 ast_print(tree->right,outfile,indent+2);
4683 /*------------------------------------------------------------------*/
4684 /*----------------------------*/
4685 /* unary '+' operator */
4686 /*----------------------------*/
4690 fprintf(outfile,"UPLUS (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+2);
4695 /*------------------------------------------------------------------*/
4696 /*----------------------------*/
4698 /*----------------------------*/
4699 fprintf(outfile,"ADD (%p) type (",tree);
4700 printTypeChain(tree->ftype,outfile);
4701 fprintf(outfile,")\n");
4702 ast_print(tree->left,outfile,indent+2);
4703 ast_print(tree->right,outfile,indent+2);
4706 /*------------------------------------------------------------------*/
4707 /*----------------------------*/
4709 /*----------------------------*/
4710 case '-': /* can be unary */
4712 fprintf(outfile,"UMINUS (%p) type (",tree);
4713 printTypeChain(tree->ftype,outfile);
4714 fprintf(outfile,")\n");
4715 ast_print(tree->left,outfile,indent+2);
4717 /*------------------------------------------------------------------*/
4718 /*----------------------------*/
4720 /*----------------------------*/
4721 fprintf(outfile,"SUB (%p) type (",tree);
4722 printTypeChain(tree->ftype,outfile);
4723 fprintf(outfile,")\n");
4724 ast_print(tree->left,outfile,indent+2);
4725 ast_print(tree->right,outfile,indent+2);
4728 /*------------------------------------------------------------------*/
4729 /*----------------------------*/
4731 /*----------------------------*/
4733 fprintf(outfile,"COMPL (%p) type (",tree);
4734 printTypeChain(tree->ftype,outfile);
4735 fprintf(outfile,")\n");
4736 ast_print(tree->left,outfile,indent+2);
4738 /*------------------------------------------------------------------*/
4739 /*----------------------------*/
4741 /*----------------------------*/
4743 fprintf(outfile,"NOT (%p) type (",tree);
4744 printTypeChain(tree->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->left,outfile,indent+2);
4748 /*------------------------------------------------------------------*/
4749 /*----------------------------*/
4751 /*----------------------------*/
4753 fprintf(outfile,"RRC (%p) type (",tree);
4754 printTypeChain(tree->ftype,outfile);
4755 fprintf(outfile,")\n");
4756 ast_print(tree->left,outfile,indent+2);
4760 fprintf(outfile,"RLC (%p) type (",tree);
4761 printTypeChain(tree->ftype,outfile);
4762 fprintf(outfile,")\n");
4763 ast_print(tree->left,outfile,indent+2);
4766 fprintf(outfile,"GETHBIT (%p) type (",tree);
4767 printTypeChain(tree->ftype,outfile);
4768 fprintf(outfile,")\n");
4769 ast_print(tree->left,outfile,indent+2);
4772 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4773 printTypeChain(tree->ftype,outfile);
4774 fprintf(outfile,")\n");
4775 ast_print(tree->left,outfile,indent+2);
4776 ast_print(tree->right,outfile,indent+2);
4779 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4780 printTypeChain(tree->ftype,outfile);
4781 fprintf(outfile,")\n");
4782 ast_print(tree->left,outfile,indent+2);
4783 ast_print(tree->right,outfile,indent+2);
4785 /*------------------------------------------------------------------*/
4786 /*----------------------------*/
4788 /*----------------------------*/
4789 case CAST: /* change the type */
4790 fprintf(outfile,"CAST (%p) from type (",tree);
4791 printTypeChain(tree->right->ftype,outfile);
4792 fprintf(outfile,") to type (");
4793 printTypeChain(tree->ftype,outfile);
4794 fprintf(outfile,")\n");
4795 ast_print(tree->right,outfile,indent+2);
4799 fprintf(outfile,"ANDAND (%p) type (",tree);
4800 printTypeChain(tree->ftype,outfile);
4801 fprintf(outfile,")\n");
4802 ast_print(tree->left,outfile,indent+2);
4803 ast_print(tree->right,outfile,indent+2);
4806 fprintf(outfile,"OROR (%p) type (",tree);
4807 printTypeChain(tree->ftype,outfile);
4808 fprintf(outfile,")\n");
4809 ast_print(tree->left,outfile,indent+2);
4810 ast_print(tree->right,outfile,indent+2);
4813 /*------------------------------------------------------------------*/
4814 /*----------------------------*/
4815 /* comparison operators */
4816 /*----------------------------*/
4818 fprintf(outfile,"GT(>) (%p) type (",tree);
4819 printTypeChain(tree->ftype,outfile);
4820 fprintf(outfile,")\n");
4821 ast_print(tree->left,outfile,indent+2);
4822 ast_print(tree->right,outfile,indent+2);
4825 fprintf(outfile,"LT(<) (%p) type (",tree);
4826 printTypeChain(tree->ftype,outfile);
4827 fprintf(outfile,")\n");
4828 ast_print(tree->left,outfile,indent+2);
4829 ast_print(tree->right,outfile,indent+2);
4832 fprintf(outfile,"LE(<=) (%p) type (",tree);
4833 printTypeChain(tree->ftype,outfile);
4834 fprintf(outfile,")\n");
4835 ast_print(tree->left,outfile,indent+2);
4836 ast_print(tree->right,outfile,indent+2);
4839 fprintf(outfile,"GE(>=) (%p) type (",tree);
4840 printTypeChain(tree->ftype,outfile);
4841 fprintf(outfile,")\n");
4842 ast_print(tree->left,outfile,indent+2);
4843 ast_print(tree->right,outfile,indent+2);
4846 fprintf(outfile,"EQ(==) (%p) type (",tree);
4847 printTypeChain(tree->ftype,outfile);
4848 fprintf(outfile,")\n");
4849 ast_print(tree->left,outfile,indent+2);
4850 ast_print(tree->right,outfile,indent+2);
4853 fprintf(outfile,"NE(!=) (%p) type (",tree);
4854 printTypeChain(tree->ftype,outfile);
4855 fprintf(outfile,")\n");
4856 ast_print(tree->left,outfile,indent+2);
4857 ast_print(tree->right,outfile,indent+2);
4858 /*------------------------------------------------------------------*/
4859 /*----------------------------*/
4861 /*----------------------------*/
4862 case SIZEOF: /* evaluate wihout code generation */
4863 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4866 /*------------------------------------------------------------------*/
4867 /*----------------------------*/
4868 /* conditional operator '?' */
4869 /*----------------------------*/
4871 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4872 printTypeChain(tree->ftype,outfile);
4873 fprintf(outfile,")\n");
4874 ast_print(tree->left,outfile,indent+2);
4875 ast_print(tree->right,outfile,indent+2);
4879 fprintf(outfile,"COLON(:) (%p) type (",tree);
4880 printTypeChain(tree->ftype,outfile);
4881 fprintf(outfile,")\n");
4882 ast_print(tree->left,outfile,indent+2);
4883 ast_print(tree->right,outfile,indent+2);
4886 /*------------------------------------------------------------------*/
4887 /*----------------------------*/
4888 /* assignment operators */
4889 /*----------------------------*/
4891 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4892 printTypeChain(tree->ftype,outfile);
4893 fprintf(outfile,")\n");
4894 ast_print(tree->left,outfile,indent+2);
4895 ast_print(tree->right,outfile,indent+2);
4898 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4899 printTypeChain(tree->ftype,outfile);
4900 fprintf(outfile,")\n");
4901 ast_print(tree->left,outfile,indent+2);
4902 ast_print(tree->right,outfile,indent+2);
4905 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4906 printTypeChain(tree->ftype,outfile);
4907 fprintf(outfile,")\n");
4908 ast_print(tree->left,outfile,indent+2);
4909 ast_print(tree->right,outfile,indent+2);
4912 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
4913 printTypeChain(tree->ftype,outfile);
4914 fprintf(outfile,")\n");
4915 ast_print(tree->left,outfile,indent+2);
4916 ast_print(tree->right,outfile,indent+2);
4919 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
4920 printTypeChain(tree->ftype,outfile);
4921 fprintf(outfile,")\n");
4922 ast_print(tree->left,outfile,indent+2);
4923 ast_print(tree->right,outfile,indent+2);
4926 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4927 printTypeChain(tree->ftype,outfile);
4928 fprintf(outfile,")\n");
4929 ast_print(tree->left,outfile,indent+2);
4930 ast_print(tree->right,outfile,indent+2);
4933 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
4934 printTypeChain(tree->ftype,outfile);
4935 fprintf(outfile,")\n");
4936 ast_print(tree->left,outfile,indent+2);
4937 ast_print(tree->right,outfile,indent+2);
4939 /*------------------------------------------------------------------*/
4940 /*----------------------------*/
4942 /*----------------------------*/
4944 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4945 printTypeChain(tree->ftype,outfile);
4946 fprintf(outfile,")\n");
4947 ast_print(tree->left,outfile,indent+2);
4948 ast_print(tree->right,outfile,indent+2);
4950 /*------------------------------------------------------------------*/
4951 /*----------------------------*/
4953 /*----------------------------*/
4955 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4956 printTypeChain(tree->ftype,outfile);
4957 fprintf(outfile,")\n");
4958 ast_print(tree->left,outfile,indent+2);
4959 ast_print(tree->right,outfile,indent+2);
4961 /*------------------------------------------------------------------*/
4962 /*----------------------------*/
4963 /* straight assignemnt */
4964 /*----------------------------*/
4966 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4967 printTypeChain(tree->ftype,outfile);
4968 fprintf(outfile,")\n");
4969 ast_print(tree->left,outfile,indent+2);
4970 ast_print(tree->right,outfile,indent+2);
4972 /*------------------------------------------------------------------*/
4973 /*----------------------------*/
4974 /* comma operator */
4975 /*----------------------------*/
4977 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4978 printTypeChain(tree->ftype,outfile);
4979 fprintf(outfile,")\n");
4980 ast_print(tree->left,outfile,indent+2);
4981 ast_print(tree->right,outfile,indent+2);
4983 /*------------------------------------------------------------------*/
4984 /*----------------------------*/
4986 /*----------------------------*/
4989 fprintf(outfile,"CALL (%p) type (",tree);
4990 printTypeChain(tree->ftype,outfile);
4991 fprintf(outfile,")\n");
4992 ast_print(tree->left,outfile,indent+2);
4993 ast_print(tree->right,outfile,indent+2);
4996 fprintf(outfile,"PARMS\n");
4997 ast_print(tree->left,outfile,indent+2);
4998 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4999 ast_print(tree->right,outfile,indent+2);
5002 /*------------------------------------------------------------------*/
5003 /*----------------------------*/
5004 /* return statement */
5005 /*----------------------------*/
5007 fprintf(outfile,"RETURN (%p) type (",tree);
5009 printTypeChain(tree->right->ftype,outfile);
5011 fprintf(outfile,")\n");
5012 ast_print(tree->right,outfile,indent+2);
5014 /*------------------------------------------------------------------*/
5015 /*----------------------------*/
5016 /* label statement */
5017 /*----------------------------*/
5019 fprintf(outfile,"LABEL (%p)\n",tree);
5020 ast_print(tree->left,outfile,indent+2);
5021 ast_print(tree->right,outfile,indent);
5023 /*------------------------------------------------------------------*/
5024 /*----------------------------*/
5025 /* switch statement */
5026 /*----------------------------*/
5030 fprintf(outfile,"SWITCH (%p) ",tree);
5031 ast_print(tree->left,outfile,0);
5032 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5033 INDENT(indent+2,outfile);
5034 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5035 (int) floatFromVal(val),
5036 tree->values.switchVals.swNum,
5037 (int) floatFromVal(val));
5039 ast_print(tree->right,outfile,indent);
5042 /*------------------------------------------------------------------*/
5043 /*----------------------------*/
5045 /*----------------------------*/
5047 fprintf(outfile,"IF (%p) \n",tree);
5048 ast_print(tree->left,outfile,indent+2);
5049 if (tree->trueLabel) {
5050 INDENT(indent+2,outfile);
5051 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5053 if (tree->falseLabel) {
5054 INDENT(indent+2,outfile);
5055 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5057 ast_print(tree->right,outfile,indent+2);
5059 /*----------------------------*/
5060 /* goto Statement */
5061 /*----------------------------*/
5063 fprintf(outfile,"GOTO (%p) \n",tree);
5064 ast_print(tree->left,outfile,indent+2);
5065 fprintf(outfile,"\n");
5067 /*------------------------------------------------------------------*/
5068 /*----------------------------*/
5070 /*----------------------------*/
5072 fprintf(outfile,"FOR (%p) \n",tree);
5073 if (AST_FOR( tree, initExpr)) {
5074 INDENT(indent+2,outfile);
5075 fprintf(outfile,"INIT EXPR ");
5076 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5078 if (AST_FOR( tree, condExpr)) {
5079 INDENT(indent+2,outfile);
5080 fprintf(outfile,"COND EXPR ");
5081 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5083 if (AST_FOR( tree, loopExpr)) {
5084 INDENT(indent+2,outfile);
5085 fprintf(outfile,"LOOP EXPR ");
5086 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5088 fprintf(outfile,"FOR LOOP BODY \n");
5089 ast_print(tree->left,outfile,indent+2);
5098 ast_print(t,stdout,0);