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 *optimizeSWAP (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
60 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
65 printTypeChain (tree->ftype, stdout);
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree */
72 /*-----------------------------------------------------------------*/
74 newAst_ (unsigned type)
77 static int oldLineno = 0;
79 ex = Safe_alloc ( sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : mylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
91 newAst_VALUE (value * val)
93 ast *ex = newAst_ (EX_VALUE);
99 newAst_OP (unsigned op)
101 ast *ex = newAst_ (EX_OP);
107 newAst_LINK (sym_link * val)
109 ast *ex = newAst_ (EX_LINK);
114 /*-----------------------------------------------------------------*/
115 /* newNode - creates a new node */
116 /*-----------------------------------------------------------------*/
118 newNode (long op, ast * left, ast * right)
129 /*-----------------------------------------------------------------*/
130 /* newIfxNode - creates a new Ifx Node */
131 /*-----------------------------------------------------------------*/
133 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
137 /* if this is a literal then we already know the result */
138 if (condAst->etype && IS_LITERAL (condAst->etype))
140 /* then depending on the expression value */
141 if (floatFromVal (condAst->opval.val))
142 ifxNode = newNode (GOTO,
143 newAst_VALUE (symbolVal (trueLabel)),
146 ifxNode = newNode (GOTO,
147 newAst_VALUE (symbolVal (falseLabel)),
152 ifxNode = newNode (IFX, condAst, NULL);
153 ifxNode->trueLabel = trueLabel;
154 ifxNode->falseLabel = falseLabel;
160 /*-----------------------------------------------------------------*/
161 /* copyAstValues - copies value portion of ast if needed */
162 /*-----------------------------------------------------------------*/
164 copyAstValues (ast * dest, ast * src)
166 switch (src->opval.op)
169 dest->values.sym = copySymbolChain (src->values.sym);
173 dest->values.switchVals.swVals =
174 copyValue (src->values.switchVals.swVals);
175 dest->values.switchVals.swDefault =
176 src->values.switchVals.swDefault;
177 dest->values.switchVals.swNum =
178 src->values.switchVals.swNum;
182 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
186 dest->values.constlist = copyLiteralList(src->values.constlist);
190 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
191 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
192 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
193 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
194 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
195 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
196 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
201 /*-----------------------------------------------------------------*/
202 /* copyAst - makes a copy of a given astession */
203 /*-----------------------------------------------------------------*/
212 dest = Safe_alloc ( sizeof (ast));
214 dest->type = src->type;
215 dest->lineno = src->lineno;
216 dest->level = src->level;
217 dest->funcName = src->funcName;
220 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
222 /* if this is a leaf */
224 if (src->type == EX_VALUE)
226 dest->opval.val = copyValue (src->opval.val);
231 if (src->type == EX_LINK)
233 dest->opval.lnk = copyLinkChain (src->opval.lnk);
237 dest->opval.op = src->opval.op;
239 /* if this is a node that has special values */
240 copyAstValues (dest, src);
242 dest->trueLabel = copySymbol (src->trueLabel);
243 dest->falseLabel = copySymbol (src->falseLabel);
244 dest->left = copyAst (src->left);
245 dest->right = copyAst (src->right);
251 /*-----------------------------------------------------------------*/
252 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
253 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
254 /*-----------------------------------------------------------------*/
255 ast *removeIncDecOps (ast * tree) {
257 // traverse the tree and remove inc/dec ops
262 if (tree->type == EX_OP &&
263 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
270 tree->left=removeIncDecOps(tree->left);
271 tree->right=removeIncDecOps(tree->right);
276 /*-----------------------------------------------------------------*/
277 /* hasSEFcalls - returns TRUE if tree has a function call */
278 /*-----------------------------------------------------------------*/
280 hasSEFcalls (ast * tree)
285 if (tree->type == EX_OP &&
286 (tree->opval.op == CALL ||
287 tree->opval.op == PCALL ||
288 tree->opval.op == '=' ||
289 tree->opval.op == INC_OP ||
290 tree->opval.op == DEC_OP))
293 return (hasSEFcalls (tree->left) |
294 hasSEFcalls (tree->right));
297 /*-----------------------------------------------------------------*/
298 /* isAstEqual - compares two asts & returns 1 if they are equal */
299 /*-----------------------------------------------------------------*/
301 isAstEqual (ast * t1, ast * t2)
310 if (t1->type != t2->type)
316 if (t1->opval.op != t2->opval.op)
318 return (isAstEqual (t1->left, t2->left) &&
319 isAstEqual (t1->right, t2->right));
323 if (t1->opval.val->sym)
325 if (!t2->opval.val->sym)
328 return isSymbolEqual (t1->opval.val->sym,
333 if (t2->opval.val->sym)
336 return (floatFromVal (t1->opval.val) ==
337 floatFromVal (t2->opval.val));
341 /* only compare these two types */
349 /*-----------------------------------------------------------------*/
350 /* resolveSymbols - resolve symbols from the symbol table */
351 /*-----------------------------------------------------------------*/
353 resolveSymbols (ast * tree)
355 /* walk the entire tree and check for values */
356 /* with symbols if we find one then replace */
357 /* symbol with that from the symbol table */
364 /* if not block & function */
365 if (tree->type == EX_OP &&
366 (tree->opval.op != FUNCTION &&
367 tree->opval.op != BLOCK &&
368 tree->opval.op != NULLOP))
370 filename = tree->filename;
371 lineno = tree->lineno;
375 /* make sure we resolve the true & false labels for ifx */
376 if (tree->type == EX_OP && tree->opval.op == IFX)
382 if ((csym = findSym (LabelTab, tree->trueLabel,
383 tree->trueLabel->name)))
384 tree->trueLabel = csym;
386 werror (E_LABEL_UNDEF, tree->trueLabel->name);
389 if (tree->falseLabel)
391 if ((csym = findSym (LabelTab,
393 tree->falseLabel->name)))
394 tree->falseLabel = csym;
396 werror (E_LABEL_UNDEF, tree->falseLabel->name);
401 /* if this is a label resolve it from the labelTab */
402 if (IS_AST_VALUE (tree) &&
403 tree->opval.val->sym &&
404 tree->opval.val->sym->islbl)
407 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
408 tree->opval.val->sym->name);
411 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
413 tree->opval.val->sym = csym;
415 goto resolveChildren;
418 /* do only for leafs */
419 if (IS_AST_VALUE (tree) &&
420 tree->opval.val->sym &&
421 !tree->opval.val->sym->implicit)
424 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
426 /* if found in the symbol table & they r not the same */
427 if (csym && tree->opval.val->sym != csym)
429 tree->opval.val->sym = csym;
430 tree->opval.val->type = csym->type;
431 tree->opval.val->etype = csym->etype;
434 /* if not found in the symbol table */
435 /* mark it as undefined assume it is */
436 /* an integer in data space */
437 if (!csym && !tree->opval.val->sym->implicit)
440 /* if this is a function name then */
441 /* mark it as returning an int */
444 tree->opval.val->sym->type = newLink (DECLARATOR);
445 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
446 tree->opval.val->sym->type->next =
447 tree->opval.val->sym->etype = newIntLink ();
448 tree->opval.val->etype = tree->opval.val->etype;
449 tree->opval.val->type = tree->opval.val->sym->type;
450 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
451 allocVariables (tree->opval.val->sym);
455 tree->opval.val->sym->undefined = 1;
456 tree->opval.val->type =
457 tree->opval.val->etype = newIntLink ();
458 tree->opval.val->sym->type =
459 tree->opval.val->sym->etype = newIntLink ();
465 resolveSymbols (tree->left);
466 resolveSymbols (tree->right);
471 /*-----------------------------------------------------------------*/
472 /* setAstLineno - walks a ast tree & sets the line number */
473 /*-----------------------------------------------------------------*/
474 int setAstLineno (ast * tree, int lineno)
479 tree->lineno = lineno;
480 setAstLineno (tree->left, lineno);
481 setAstLineno (tree->right, lineno);
485 /*-----------------------------------------------------------------*/
486 /* funcOfType :- function of type with name */
487 /*-----------------------------------------------------------------*/
489 funcOfType (char *name, sym_link * type, sym_link * argType,
493 /* create the symbol */
494 sym = newSymbol (name, 0);
496 /* setup return value */
497 sym->type = newLink (DECLARATOR);
498 DCL_TYPE (sym->type) = FUNCTION;
499 sym->type->next = copyLinkChain (type);
500 sym->etype = getSpec (sym->type);
501 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
503 /* if arguments required */
507 args = FUNC_ARGS(sym->type) = newValue ();
511 args->type = copyLinkChain (argType);
512 args->etype = getSpec (args->type);
513 SPEC_EXTR(args->etype)=1;
516 args = args->next = newValue ();
523 allocVariables (sym);
528 /*-----------------------------------------------------------------*/
529 /* funcOfTypeVarg :- function of type with name and argtype */
530 /*-----------------------------------------------------------------*/
532 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
537 /* create the symbol */
538 sym = newSymbol (name, 0);
540 /* setup return value */
541 sym->type = newLink (DECLARATOR);
542 DCL_TYPE (sym->type) = FUNCTION;
543 sym->type->next = typeFromStr(rtype);
544 sym->etype = getSpec (sym->type);
546 /* if arguments required */
549 args = FUNC_ARGS(sym->type) = newValue ();
551 for ( i = 0 ; i < nArgs ; i++ ) {
552 args->type = typeFromStr(atypes[i]);
553 args->etype = getSpec (args->type);
554 SPEC_EXTR(args->etype)=1;
555 if ((i + 1) == nArgs) break;
556 args = args->next = newValue ();
563 allocVariables (sym);
568 /*-----------------------------------------------------------------*/
569 /* reverseParms - will reverse a parameter tree */
570 /*-----------------------------------------------------------------*/
572 reverseParms (ast * ptree)
578 /* top down if we find a nonParm tree then quit */
579 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
582 ptree->left = ptree->right;
583 ptree->right = ttree;
584 reverseParms (ptree->left);
585 reverseParms (ptree->right);
591 /*-----------------------------------------------------------------*/
592 /* processParms - makes sure the parameters are okay and do some */
593 /* processing with them */
594 /*-----------------------------------------------------------------*/
596 processParms (ast * func,
599 int *parmNumber, // unused, although updated
602 /* if none of them exist */
603 if (!defParm && !actParm)
607 if (getenv("DEBUG_SANITY")) {
608 fprintf (stderr, "processParms: %s ", defParm->name);
610 /* make sure the type is complete and sane */
611 checkTypeSanity(defParm->etype, defParm->name);
614 /* if the function is being called via a pointer & */
615 /* it has not been defined a reentrant then we cannot */
616 /* have parameters */
617 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
619 werror (W_NONRENT_ARGS);
623 /* if defined parameters ended but actual parameters */
624 /* exist and this is not defined as a variable arg */
625 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
627 werror (E_TOO_MANY_PARMS);
631 /* if defined parameters present but no actual parameters */
632 if (defParm && !actParm)
634 werror (E_TOO_FEW_PARMS);
638 if (IS_VOID(actParm->ftype)) {
639 werror (E_VOID_VALUE_USED);
643 /* If this is a varargs function... */
644 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
649 if (IS_CAST_OP (actParm)
650 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
652 /* Parameter was explicitly typecast; don't touch it. */
656 ftype = actParm->ftype;
658 /* If it's a small integer, upcast to int. */
659 if (IS_INTEGRAL (ftype)
660 && (getSize (ftype) < (unsigned) INTSIZE))
662 if (IS_AST_OP(actParm) &&
663 (actParm->opval.op == LEFT_OP ||
664 actParm->opval.op == '*' ||
665 actParm->opval.op == '+' ||
666 actParm->opval.op == '-') &&
668 // we should cast an operand instead of the result
669 actParm->decorated = 0;
670 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
672 actParm = decorateType(actParm);
674 newType = newAst_LINK(INTTYPE);
678 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
680 newType = newAst_LINK (copyLinkChain(ftype));
681 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
684 if (IS_AGGREGATE (ftype))
686 newType = newAst_LINK (copyLinkChain (ftype));
687 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
691 /* cast required; change this op to a cast. */
692 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
694 actParm->type = EX_OP;
695 actParm->opval.op = CAST;
696 actParm->left = newType;
697 actParm->right = parmCopy;
698 decorateType (actParm);
700 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
702 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
703 processParms (func, NULL, actParm->right, parmNumber, rightmost));
708 /* if defined parameters ended but actual has not & */
710 if (!defParm && actParm &&
711 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
714 resolveSymbols (actParm);
715 /* if this is a PARAM node then match left & right */
716 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
718 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
719 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
723 /* If we have found a value node by following only right-hand links,
724 * then we know that there are no more values after us.
726 * Therefore, if there are more defined parameters, the caller didn't
729 if (rightmost && defParm->next)
731 werror (E_TOO_FEW_PARMS);
736 /* the parameter type must be at least castable */
737 if (compareType (defParm->type, actParm->ftype) == 0) {
738 werror (E_INCOMPAT_TYPES);
739 printFromToType (actParm->ftype, defParm->type);
743 /* if the parameter is castable then add the cast */
744 if (compareType (defParm->type, actParm->ftype) < 0)
746 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
748 /* now change the current one to a cast */
749 actParm->type = EX_OP;
750 actParm->opval.op = CAST;
751 actParm->left = newAst_LINK (defParm->type);
752 actParm->right = pTree;
753 actParm->etype = defParm->etype;
754 actParm->ftype = defParm->type;
755 actParm->decorated=0; /* force typechecking */
756 decorateType (actParm);
759 /* make a copy and change the regparm type to the defined parm */
760 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
761 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
762 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
766 /*-----------------------------------------------------------------*/
767 /* createIvalType - generates ival for basic types */
768 /*-----------------------------------------------------------------*/
770 createIvalType (ast * sym, sym_link * type, initList * ilist)
774 /* if initList is deep */
775 if (ilist->type == INIT_DEEP)
776 ilist = ilist->init.deep;
778 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
779 return decorateType (newNode ('=', sym, iExpr));
782 /*-----------------------------------------------------------------*/
783 /* createIvalStruct - generates initial value for structures */
784 /*-----------------------------------------------------------------*/
786 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
793 sflds = SPEC_STRUCT (type)->fields;
794 if (ilist->type != INIT_DEEP)
796 werror (E_INIT_STRUCT, "");
800 iloop = ilist->init.deep;
802 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
804 /* if we have come to end */
808 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
809 lAst = decorateType (resolveSymbols (lAst));
810 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
814 werror (W_EXCESS_INITIALIZERS, "struct",
815 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
822 /*-----------------------------------------------------------------*/
823 /* createIvalArray - generates code for array initialization */
824 /*-----------------------------------------------------------------*/
826 createIvalArray (ast * sym, sym_link * type, initList * ilist)
830 int lcnt = 0, size = 0;
831 literalList *literalL;
833 /* take care of the special case */
834 /* array of characters can be init */
836 if (IS_CHAR (type->next))
837 if ((rast = createIvalCharPtr (sym,
839 decorateType (resolveSymbols (list2expr (ilist))))))
841 return decorateType (resolveSymbols (rast));
843 /* not the special case */
844 if (ilist->type != INIT_DEEP)
846 werror (E_INIT_STRUCT, "");
850 iloop = ilist->init.deep;
851 lcnt = DCL_ELEM (type);
853 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
857 aSym = decorateType (resolveSymbols(sym));
859 rast = newNode(ARRAYINIT, aSym, NULL);
860 rast->values.constlist = literalL;
862 // Make sure size is set to length of initializer list.
869 if (lcnt && size > lcnt)
871 // Array size was specified, and we have more initializers than needed.
872 char *name=sym->opval.val->sym->name;
873 int lineno=sym->opval.val->sym->lineDef;
875 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
884 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
885 aSym = decorateType (resolveSymbols (aSym));
886 rast = createIval (aSym, type->next, iloop, rast);
887 iloop = (iloop ? iloop->next : NULL);
893 /* no of elements given and we */
894 /* have generated for all of them */
897 // there has to be a better way
898 char *name=sym->opval.val->sym->name;
899 int lineno=sym->opval.val->sym->lineDef;
900 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
907 /* if we have not been given a size */
908 if (!DCL_ELEM (type))
910 DCL_ELEM (type) = size;
913 return decorateType (resolveSymbols (rast));
917 /*-----------------------------------------------------------------*/
918 /* createIvalCharPtr - generates initial values for char pointers */
919 /*-----------------------------------------------------------------*/
921 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
925 /* if this is a pointer & right is a literal array then */
926 /* just assignment will do */
927 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
928 SPEC_SCLS (iexpr->etype) == S_CODE)
929 && IS_ARRAY (iexpr->ftype)))
930 return newNode ('=', sym, iexpr);
932 /* left side is an array so we have to assign each */
934 if ((IS_LITERAL (iexpr->etype) ||
935 SPEC_SCLS (iexpr->etype) == S_CODE)
936 && IS_ARRAY (iexpr->ftype))
938 /* for each character generate an assignment */
939 /* to the array element */
940 char *s = SPEC_CVAL (iexpr->etype).v_char;
945 rast = newNode (NULLOP,
949 newAst_VALUE (valueFromLit ((float) i))),
950 newAst_VALUE (valueFromLit (*s))));
954 rast = newNode (NULLOP,
958 newAst_VALUE (valueFromLit ((float) i))),
959 newAst_VALUE (valueFromLit (*s))));
961 // now WE don't need iexpr's symbol anymore
962 freeStringSymbol(AST_SYMBOL(iexpr));
964 return decorateType (resolveSymbols (rast));
970 /*-----------------------------------------------------------------*/
971 /* createIvalPtr - generates initial value for pointers */
972 /*-----------------------------------------------------------------*/
974 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
980 if (ilist->type == INIT_DEEP)
981 ilist = ilist->init.deep;
983 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
985 /* if character pointer */
986 if (IS_CHAR (type->next))
987 if ((rast = createIvalCharPtr (sym, type, iexpr)))
990 return newNode ('=', sym, iexpr);
993 /*-----------------------------------------------------------------*/
994 /* createIval - generates code for initial value */
995 /*-----------------------------------------------------------------*/
997 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1004 /* if structure then */
1005 if (IS_STRUCT (type))
1006 rast = createIvalStruct (sym, type, ilist);
1008 /* if this is a pointer */
1010 rast = createIvalPtr (sym, type, ilist);
1012 /* if this is an array */
1013 if (IS_ARRAY (type))
1014 rast = createIvalArray (sym, type, ilist);
1016 /* if type is SPECIFIER */
1018 rast = createIvalType (sym, type, ilist);
1021 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1023 return decorateType (resolveSymbols (rast));
1026 /*-----------------------------------------------------------------*/
1027 /* initAggregates - initialises aggregate variables with initv */
1028 /*-----------------------------------------------------------------*/
1029 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1030 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1033 /*-----------------------------------------------------------------*/
1034 /* gatherAutoInit - creates assignment expressions for initial */
1036 /*-----------------------------------------------------------------*/
1038 gatherAutoInit (symbol * autoChain)
1045 for (sym = autoChain; sym; sym = sym->next)
1048 /* resolve the symbols in the ival */
1050 resolveIvalSym (sym->ival);
1052 /* if this is a static variable & has an */
1053 /* initial value the code needs to be lifted */
1054 /* here to the main portion since they can be */
1055 /* initialised only once at the start */
1056 if (IS_STATIC (sym->etype) && sym->ival &&
1057 SPEC_SCLS (sym->etype) != S_CODE)
1061 /* insert the symbol into the symbol table */
1062 /* with level = 0 & name = rname */
1063 newSym = copySymbol (sym);
1064 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1066 /* now lift the code to main */
1067 if (IS_AGGREGATE (sym->type)) {
1068 work = initAggregates (sym, sym->ival, NULL);
1070 if (getNelements(sym->type, sym->ival)>1) {
1071 werror (W_EXCESS_INITIALIZERS, "scalar",
1072 sym->name, sym->lineDef);
1074 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1075 list2expr (sym->ival));
1078 setAstLineno (work, sym->lineDef);
1082 staticAutos = newNode (NULLOP, staticAutos, work);
1089 /* if there is an initial value */
1090 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1092 initList *ilist=sym->ival;
1094 while (ilist->type == INIT_DEEP) {
1095 ilist = ilist->init.deep;
1098 /* update lineno for error msg */
1099 lineno=sym->lineDef;
1100 setAstLineno (ilist->init.node, lineno);
1102 if (IS_AGGREGATE (sym->type)) {
1103 work = initAggregates (sym, sym->ival, NULL);
1105 if (getNelements(sym->type, sym->ival)>1) {
1106 werror (W_EXCESS_INITIALIZERS, "scalar",
1107 sym->name, sym->lineDef);
1109 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1110 list2expr (sym->ival));
1114 setAstLineno (work, sym->lineDef);
1118 init = newNode (NULLOP, init, work);
1127 /*-----------------------------------------------------------------*/
1128 /* freeStringSymbol - delete a literal string if no more usage */
1129 /*-----------------------------------------------------------------*/
1130 void freeStringSymbol(symbol *sym) {
1131 /* make sure this is a literal string */
1132 assert (sym->isstrlit);
1133 if (--sym->isstrlit == 0) { // lower the usage count
1134 memmap *segment=SPEC_OCLS(sym->etype);
1136 deleteSetItem(&segment->syms, sym);
1141 /*-----------------------------------------------------------------*/
1142 /* stringToSymbol - creates a symbol from a literal string */
1143 /*-----------------------------------------------------------------*/
1145 stringToSymbol (value * val)
1147 char name[SDCC_NAME_MAX + 1];
1148 static int charLbl = 0;
1152 // have we heard this before?
1153 for (sp=statsg->syms; sp; sp=sp->next) {
1155 if (sym->isstrlit &&
1156 !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
1157 // yes, this is old news. Don't publish it again.
1158 sym->isstrlit++; // but raise the usage count
1159 return symbolVal(sym);
1163 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1164 sym = newSymbol (name, 0); /* make it @ level 0 */
1165 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1167 /* copy the type from the value passed */
1168 sym->type = copyLinkChain (val->type);
1169 sym->etype = getSpec (sym->type);
1170 /* change to storage class & output class */
1171 SPEC_SCLS (sym->etype) = S_CODE;
1172 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1173 SPEC_STAT (sym->etype) = 1;
1174 /* make the level & block = 0 */
1175 sym->block = sym->level = 0;
1177 /* create an ival */
1178 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1183 allocVariables (sym);
1186 return symbolVal (sym);
1190 /*-----------------------------------------------------------------*/
1191 /* processBlockVars - will go thru the ast looking for block if */
1192 /* a block is found then will allocate the syms */
1193 /* will also gather the auto inits present */
1194 /*-----------------------------------------------------------------*/
1196 processBlockVars (ast * tree, int *stack, int action)
1201 /* if this is a block */
1202 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1206 if (action == ALLOCATE)
1208 *stack += allocVariables (tree->values.sym);
1209 autoInit = gatherAutoInit (tree->values.sym);
1211 /* if there are auto inits then do them */
1213 tree->left = newNode (NULLOP, autoInit, tree->left);
1215 else /* action is deallocate */
1216 deallocLocal (tree->values.sym);
1219 processBlockVars (tree->left, stack, action);
1220 processBlockVars (tree->right, stack, action);
1225 /*-------------------------------------------------------------*/
1226 /* constExprTree - returns TRUE if this tree is a constant */
1228 /*-------------------------------------------------------------*/
1229 bool constExprTree (ast *cexpr) {
1235 cexpr = decorateType (resolveSymbols (cexpr));
1237 switch (cexpr->type)
1240 if (IS_AST_LIT_VALUE(cexpr)) {
1241 // this is a literal
1244 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1245 // a function's address will never change
1248 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1249 // an array's address will never change
1252 if (IS_AST_SYM_VALUE(cexpr) &&
1253 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1254 // a symbol in code space will never change
1255 // This is only for the 'char *s="hallo"' case and will have to leave
1256 //printf(" code space symbol");
1261 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1262 "unexpected link in expression tree\n");
1265 if (cexpr->opval.op==ARRAYINIT) {
1266 // this is a list of literals
1269 if (cexpr->opval.op=='=') {
1270 return constExprTree(cexpr->right);
1272 if (cexpr->opval.op==CAST) {
1273 // cast ignored, maybe we should throw a warning here?
1274 return constExprTree(cexpr->right);
1276 if (cexpr->opval.op=='&') {
1279 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1282 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1287 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1292 /*-----------------------------------------------------------------*/
1293 /* constExprValue - returns the value of a constant expression */
1294 /* or NULL if it is not a constant expression */
1295 /*-----------------------------------------------------------------*/
1297 constExprValue (ast * cexpr, int check)
1299 cexpr = decorateType (resolveSymbols (cexpr));
1301 /* if this is not a constant then */
1302 if (!IS_LITERAL (cexpr->ftype))
1304 /* then check if this is a literal array
1306 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1307 SPEC_CVAL (cexpr->etype).v_char &&
1308 IS_ARRAY (cexpr->ftype))
1310 value *val = valFromType (cexpr->ftype);
1311 SPEC_SCLS (val->etype) = S_LITERAL;
1312 val->sym = cexpr->opval.val->sym;
1313 val->sym->type = copyLinkChain (cexpr->ftype);
1314 val->sym->etype = getSpec (val->sym->type);
1315 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1319 /* if we are casting a literal value then */
1320 if (IS_AST_OP (cexpr) &&
1321 cexpr->opval.op == CAST &&
1322 IS_LITERAL (cexpr->right->ftype))
1324 return valCastLiteral (cexpr->ftype,
1325 floatFromVal (cexpr->right->opval.val));
1328 if (IS_AST_VALUE (cexpr))
1330 return cexpr->opval.val;
1334 werror (E_CONST_EXPECTED, "found expression");
1339 /* return the value */
1340 return cexpr->opval.val;
1344 /*-----------------------------------------------------------------*/
1345 /* isLabelInAst - will return true if a given label is found */
1346 /*-----------------------------------------------------------------*/
1348 isLabelInAst (symbol * label, ast * tree)
1350 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1353 if (IS_AST_OP (tree) &&
1354 tree->opval.op == LABEL &&
1355 isSymbolEqual (AST_SYMBOL (tree->left), label))
1358 return isLabelInAst (label, tree->right) &&
1359 isLabelInAst (label, tree->left);
1363 /*-----------------------------------------------------------------*/
1364 /* isLoopCountable - return true if the loop count can be determi- */
1365 /* -ned at compile time . */
1366 /*-----------------------------------------------------------------*/
1368 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1369 symbol ** sym, ast ** init, ast ** end)
1372 /* the loop is considered countable if the following
1373 conditions are true :-
1375 a) initExpr :- <sym> = <const>
1376 b) condExpr :- <sym> < <const1>
1377 c) loopExpr :- <sym> ++
1380 /* first check the initExpr */
1381 if (IS_AST_OP (initExpr) &&
1382 initExpr->opval.op == '=' && /* is assignment */
1383 IS_AST_SYM_VALUE (initExpr->left))
1384 { /* left is a symbol */
1386 *sym = AST_SYMBOL (initExpr->left);
1387 *init = initExpr->right;
1392 /* for now the symbol has to be of
1394 if (!IS_INTEGRAL ((*sym)->type))
1397 /* now check condExpr */
1398 if (IS_AST_OP (condExpr))
1401 switch (condExpr->opval.op)
1404 if (IS_AST_SYM_VALUE (condExpr->left) &&
1405 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1406 IS_AST_LIT_VALUE (condExpr->right))
1408 *end = condExpr->right;
1414 if (IS_AST_OP (condExpr->left) &&
1415 condExpr->left->opval.op == '>' &&
1416 IS_AST_LIT_VALUE (condExpr->left->right) &&
1417 IS_AST_SYM_VALUE (condExpr->left->left) &&
1418 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1421 *end = newNode ('+', condExpr->left->right,
1422 newAst_VALUE (constVal ("1")));
1433 /* check loop expression is of the form <sym>++ */
1434 if (!IS_AST_OP (loopExpr))
1437 /* check if <sym> ++ */
1438 if (loopExpr->opval.op == INC_OP)
1444 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1445 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1452 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1453 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1461 if (loopExpr->opval.op == ADD_ASSIGN)
1464 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1465 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1466 IS_AST_LIT_VALUE (loopExpr->right) &&
1467 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1475 /*-----------------------------------------------------------------*/
1476 /* astHasVolatile - returns true if ast contains any volatile */
1477 /*-----------------------------------------------------------------*/
1479 astHasVolatile (ast * tree)
1484 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1487 if (IS_AST_OP (tree))
1488 return astHasVolatile (tree->left) ||
1489 astHasVolatile (tree->right);
1494 /*-----------------------------------------------------------------*/
1495 /* astHasPointer - return true if the ast contains any ptr variable */
1496 /*-----------------------------------------------------------------*/
1498 astHasPointer (ast * tree)
1503 if (IS_AST_LINK (tree))
1506 /* if we hit an array expression then check
1507 only the left side */
1508 if (IS_AST_OP (tree) && tree->opval.op == '[')
1509 return astHasPointer (tree->left);
1511 if (IS_AST_VALUE (tree))
1512 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1514 return astHasPointer (tree->left) ||
1515 astHasPointer (tree->right);
1519 /*-----------------------------------------------------------------*/
1520 /* astHasSymbol - return true if the ast has the given symbol */
1521 /*-----------------------------------------------------------------*/
1523 astHasSymbol (ast * tree, symbol * sym)
1525 if (!tree || IS_AST_LINK (tree))
1528 if (IS_AST_VALUE (tree))
1530 if (IS_AST_SYM_VALUE (tree))
1531 return isSymbolEqual (AST_SYMBOL (tree), sym);
1536 return astHasSymbol (tree->left, sym) ||
1537 astHasSymbol (tree->right, sym);
1540 /*-----------------------------------------------------------------*/
1541 /* astHasDeref - return true if the ast has an indirect access */
1542 /*-----------------------------------------------------------------*/
1544 astHasDeref (ast * tree)
1546 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1549 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1551 return astHasDeref (tree->left) || astHasDeref (tree->right);
1554 /*-----------------------------------------------------------------*/
1555 /* isConformingBody - the loop body has to conform to a set of rules */
1556 /* for the loop to be considered reversible read on for rules */
1557 /*-----------------------------------------------------------------*/
1559 isConformingBody (ast * pbody, symbol * sym, ast * body)
1562 /* we are going to do a pre-order traversal of the
1563 tree && check for the following conditions. (essentially
1564 a set of very shallow tests )
1565 a) the sym passed does not participate in
1566 any arithmetic operation
1567 b) There are no function calls
1568 c) all jumps are within the body
1569 d) address of loop control variable not taken
1570 e) if an assignment has a pointer on the
1571 left hand side make sure right does not have
1572 loop control variable */
1574 /* if we reach the end or a leaf then true */
1575 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1578 /* if anything else is "volatile" */
1579 if (IS_VOLATILE (TETYPE (pbody)))
1582 /* we will walk the body in a pre-order traversal for
1584 switch (pbody->opval.op)
1586 /*------------------------------------------------------------------*/
1588 // if the loopvar is used as an index
1589 if (astHasSymbol(pbody->right, sym)) {
1592 return isConformingBody (pbody->right, sym, body);
1594 /*------------------------------------------------------------------*/
1599 /*------------------------------------------------------------------*/
1603 /* sure we are not sym is not modified */
1605 IS_AST_SYM_VALUE (pbody->left) &&
1606 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1610 IS_AST_SYM_VALUE (pbody->right) &&
1611 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1616 /*------------------------------------------------------------------*/
1618 case '*': /* can be unary : if right is null then unary operation */
1623 /* if right is NULL then unary operation */
1624 /*------------------------------------------------------------------*/
1625 /*----------------------------*/
1627 /*----------------------------*/
1630 if (IS_AST_SYM_VALUE (pbody->left) &&
1631 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1634 return isConformingBody (pbody->left, sym, body);
1638 if (astHasSymbol (pbody->left, sym) ||
1639 astHasSymbol (pbody->right, sym))
1644 /*------------------------------------------------------------------*/
1652 if (IS_AST_SYM_VALUE (pbody->left) &&
1653 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1656 if (IS_AST_SYM_VALUE (pbody->right) &&
1657 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1660 return isConformingBody (pbody->left, sym, body) &&
1661 isConformingBody (pbody->right, sym, body);
1669 if (IS_AST_SYM_VALUE (pbody->left) &&
1670 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1672 return isConformingBody (pbody->left, sym, body);
1674 /*------------------------------------------------------------------*/
1686 case SIZEOF: /* evaluate wihout code generation */
1688 if (IS_AST_SYM_VALUE (pbody->left) &&
1689 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1692 if (IS_AST_SYM_VALUE (pbody->right) &&
1693 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1696 return isConformingBody (pbody->left, sym, body) &&
1697 isConformingBody (pbody->right, sym, body);
1699 /*------------------------------------------------------------------*/
1702 /* if left has a pointer & right has loop
1703 control variable then we cannot */
1704 if (astHasPointer (pbody->left) &&
1705 astHasSymbol (pbody->right, sym))
1707 if (astHasVolatile (pbody->left))
1710 if (IS_AST_SYM_VALUE (pbody->left)) {
1711 // if the loopvar has an assignment
1712 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1714 // if the loopvar is used in another (maybe conditional) block
1715 if (astHasSymbol (pbody->right, sym) &&
1716 (pbody->level >= body->level)) {
1721 if (astHasVolatile (pbody->left))
1724 if (astHasDeref(pbody->right)) return FALSE;
1726 return isConformingBody (pbody->left, sym, body) &&
1727 isConformingBody (pbody->right, sym, body);
1738 assert ("Parser should not have generated this\n");
1740 /*------------------------------------------------------------------*/
1741 /*----------------------------*/
1742 /* comma operator */
1743 /*----------------------------*/
1745 return isConformingBody (pbody->left, sym, body) &&
1746 isConformingBody (pbody->right, sym, body);
1748 /*------------------------------------------------------------------*/
1749 /*----------------------------*/
1751 /*----------------------------*/
1753 /* if local & not passed as paramater then ok */
1754 if (sym->level && !astHasSymbol(pbody->right,sym))
1758 /*------------------------------------------------------------------*/
1759 /*----------------------------*/
1760 /* return statement */
1761 /*----------------------------*/
1766 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1771 if (astHasSymbol (pbody->left, sym))
1778 return isConformingBody (pbody->left, sym, body) &&
1779 isConformingBody (pbody->right, sym, body);
1785 /*-----------------------------------------------------------------*/
1786 /* isLoopReversible - takes a for loop as input && returns true */
1787 /* if the for loop is reversible. If yes will set the value of */
1788 /* the loop control var & init value & termination value */
1789 /*-----------------------------------------------------------------*/
1791 isLoopReversible (ast * loop, symbol ** loopCntrl,
1792 ast ** init, ast ** end)
1794 /* if option says don't do it then don't */
1795 if (optimize.noLoopReverse)
1797 /* there are several tests to determine this */
1799 /* for loop has to be of the form
1800 for ( <sym> = <const1> ;
1801 [<sym> < <const2>] ;
1802 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1804 if (!isLoopCountable (AST_FOR (loop, initExpr),
1805 AST_FOR (loop, condExpr),
1806 AST_FOR (loop, loopExpr),
1807 loopCntrl, init, end))
1810 /* now do some serious checking on the body of the loop
1813 return isConformingBody (loop->left, *loopCntrl, loop->left);
1817 /*-----------------------------------------------------------------*/
1818 /* replLoopSym - replace the loop sym by loop sym -1 */
1819 /*-----------------------------------------------------------------*/
1821 replLoopSym (ast * body, symbol * sym)
1824 if (!body || IS_AST_LINK (body))
1827 if (IS_AST_SYM_VALUE (body))
1830 if (isSymbolEqual (AST_SYMBOL (body), sym))
1834 body->opval.op = '-';
1835 body->left = newAst_VALUE (symbolVal (sym));
1836 body->right = newAst_VALUE (constVal ("1"));
1844 replLoopSym (body->left, sym);
1845 replLoopSym (body->right, sym);
1849 /*-----------------------------------------------------------------*/
1850 /* reverseLoop - do the actual loop reversal */
1851 /*-----------------------------------------------------------------*/
1853 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1857 /* create the following tree
1862 if (sym) goto for_continue ;
1865 /* put it together piece by piece */
1866 rloop = newNode (NULLOP,
1867 createIf (newAst_VALUE (symbolVal (sym)),
1869 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1872 newAst_VALUE (symbolVal (sym)),
1875 replLoopSym (loop->left, sym);
1876 setAstLineno (rloop, init->lineno);
1878 rloop = newNode (NULLOP,
1880 newAst_VALUE (symbolVal (sym)),
1881 newNode ('-', end, init)),
1882 createLabel (AST_FOR (loop, continueLabel),
1886 newNode (SUB_ASSIGN,
1887 newAst_VALUE (symbolVal (sym)),
1888 newAst_VALUE (constVal ("1"))),
1891 rloop->lineno=init->lineno;
1892 return decorateType (rloop);
1896 /*-----------------------------------------------------------------*/
1897 /* searchLitOp - search tree (*ops only) for an ast with literal */
1898 /*-----------------------------------------------------------------*/
1900 searchLitOp (ast *tree, ast **parent, const char *ops)
1904 if (tree && optimize.global_cse)
1906 /* is there a literal operand? */
1908 IS_AST_OP(tree->right) &&
1909 tree->right->right &&
1910 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1912 if (IS_LITERAL (RTYPE (tree->right)) ^
1913 IS_LITERAL (LTYPE (tree->right)))
1915 tree->right->decorated = 0;
1916 tree->decorated = 0;
1920 ret = searchLitOp (tree->right, parent, ops);
1925 IS_AST_OP(tree->left) &&
1926 tree->left->right &&
1927 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1929 if (IS_LITERAL (RTYPE (tree->left)) ^
1930 IS_LITERAL (LTYPE (tree->left)))
1932 tree->left->decorated = 0;
1933 tree->decorated = 0;
1937 ret = searchLitOp (tree->left, parent, ops);
1945 /*-----------------------------------------------------------------*/
1946 /* decorateType - compute type for this tree also does type checking */
1947 /* this is done bottom up, since type have to flow upwards */
1948 /* it also does constant folding, and paramater checking */
1949 /*-----------------------------------------------------------------*/
1951 decorateType (ast * tree)
1959 /* if already has type then do nothing */
1960 if (tree->decorated)
1963 tree->decorated = 1;
1966 /* print the line */
1967 /* if not block & function */
1968 if (tree->type == EX_OP &&
1969 (tree->opval.op != FUNCTION &&
1970 tree->opval.op != BLOCK &&
1971 tree->opval.op != NULLOP))
1973 filename = tree->filename;
1974 lineno = tree->lineno;
1978 /* if any child is an error | this one is an error do nothing */
1979 if (tree->isError ||
1980 (tree->left && tree->left->isError) ||
1981 (tree->right && tree->right->isError))
1984 /*------------------------------------------------------------------*/
1985 /*----------------------------*/
1986 /* leaf has been reached */
1987 /*----------------------------*/
1988 lineno=tree->lineno;
1989 /* if this is of type value */
1990 /* just get the type */
1991 if (tree->type == EX_VALUE)
1994 if (IS_LITERAL (tree->opval.val->etype))
1997 /* if this is a character array then declare it */
1998 if (IS_ARRAY (tree->opval.val->type))
1999 tree->opval.val = stringToSymbol (tree->opval.val);
2001 /* otherwise just copy the type information */
2002 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2006 if (tree->opval.val->sym)
2008 /* if the undefined flag is set then give error message */
2009 if (tree->opval.val->sym->undefined)
2011 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2013 TTYPE (tree) = TETYPE (tree) =
2014 tree->opval.val->type = tree->opval.val->sym->type =
2015 tree->opval.val->etype = tree->opval.val->sym->etype =
2016 copyLinkChain (INTTYPE);
2021 /* if impilicit i.e. struct/union member then no type */
2022 if (tree->opval.val->sym->implicit)
2023 TTYPE (tree) = TETYPE (tree) = NULL;
2028 /* else copy the type */
2029 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2031 /* and mark it as referenced */
2032 tree->opval.val->sym->isref = 1;
2040 /* if type link for the case of cast */
2041 if (tree->type == EX_LINK)
2043 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2050 dtl = decorateType (tree->left);
2051 /* delay right side for '?' operator since conditional macro expansions might
2053 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2055 /* this is to take care of situations
2056 when the tree gets rewritten */
2057 if (dtl != tree->left)
2059 if (dtr != tree->right)
2061 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2064 if (IS_AST_OP(tree) &&
2065 (tree->opval.op == CAST || tree->opval.op == '=') &&
2066 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2067 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2068 // this is a cast/assign to a bigger type
2069 if (IS_AST_OP(tree->right) &&
2070 IS_INTEGRAL(tree->right->ftype) &&
2071 (tree->right->opval.op == LEFT_OP ||
2072 tree->right->opval.op == '*' ||
2073 tree->right->opval.op == '+' ||
2074 tree->right->opval.op == '-') &&
2075 tree->right->right) {
2076 // we should cast an operand instead of the result
2077 tree->right->decorated = 0;
2078 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2080 tree->right = decorateType(tree->right);
2085 /* depending on type of operator do */
2087 switch (tree->opval.op)
2089 /*------------------------------------------------------------------*/
2090 /*----------------------------*/
2092 /*----------------------------*/
2095 /* determine which is the array & which the index */
2096 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2099 ast *tempTree = tree->left;
2100 tree->left = tree->right;
2101 tree->right = tempTree;
2104 /* first check if this is a array or a pointer */
2105 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2107 werror (E_NEED_ARRAY_PTR, "[]");
2108 goto errorTreeReturn;
2111 /* check if the type of the idx */
2112 if (!IS_INTEGRAL (RTYPE (tree)))
2114 werror (E_IDX_NOT_INT);
2115 goto errorTreeReturn;
2118 /* if the left is an rvalue then error */
2121 werror (E_LVALUE_REQUIRED, "array access");
2122 goto errorTreeReturn;
2125 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2128 /*------------------------------------------------------------------*/
2129 /*----------------------------*/
2131 /*----------------------------*/
2133 /* if this is not a structure */
2134 if (!IS_STRUCT (LTYPE (tree)))
2136 werror (E_STRUCT_UNION, ".");
2137 goto errorTreeReturn;
2139 TTYPE (tree) = structElemType (LTYPE (tree),
2140 (tree->right->type == EX_VALUE ?
2141 tree->right->opval.val : NULL));
2142 TETYPE (tree) = getSpec (TTYPE (tree));
2145 /*------------------------------------------------------------------*/
2146 /*----------------------------*/
2147 /* struct/union pointer */
2148 /*----------------------------*/
2150 /* if not pointer to a structure */
2151 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2153 werror (E_PTR_REQD);
2154 goto errorTreeReturn;
2157 if (!IS_STRUCT (LTYPE (tree)->next))
2159 werror (E_STRUCT_UNION, "->");
2160 goto errorTreeReturn;
2163 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2164 (tree->right->type == EX_VALUE ?
2165 tree->right->opval.val : NULL));
2166 TETYPE (tree) = getSpec (TTYPE (tree));
2168 /* adjust the storage class */
2169 switch (DCL_TYPE(tree->left->ftype)) {
2173 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2176 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2181 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2184 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2187 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2195 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2196 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2198 /* If defined struct type at addr var
2199 then rewrite (&struct var)->member
2201 and define membertype at (addr+offsetof(struct var,member)) temp
2204 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2205 AST_SYMBOL(tree->right));
2207 sym = newSymbol(genSymName (0), 0);
2208 sym->type = TTYPE (tree);
2209 sym->etype = getSpec(sym->type);
2210 sym->lineDef = tree->lineno;
2213 SPEC_STAT (sym->etype) = 1;
2214 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2216 SPEC_ABSA(sym->etype) = 1;
2217 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2220 AST_VALUE (tree) = symbolVal(sym);
2223 tree->type = EX_VALUE;
2230 /*------------------------------------------------------------------*/
2231 /*----------------------------*/
2232 /* ++/-- operation */
2233 /*----------------------------*/
2237 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2238 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2239 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2240 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2249 /*------------------------------------------------------------------*/
2250 /*----------------------------*/
2252 /*----------------------------*/
2253 case '&': /* can be unary */
2254 /* if right is NULL then unary operation */
2255 if (tree->right) /* not an unary operation */
2258 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2260 werror (E_BITWISE_OP);
2261 werror (W_CONTINUE, "left & right types are ");
2262 printTypeChain (LTYPE (tree), stderr);
2263 fprintf (stderr, ",");
2264 printTypeChain (RTYPE (tree), stderr);
2265 fprintf (stderr, "\n");
2266 goto errorTreeReturn;
2269 /* if they are both literal */
2270 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2272 tree->type = EX_VALUE;
2273 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2274 valFromType (RETYPE (tree)), '&');
2276 tree->right = tree->left = NULL;
2277 TETYPE (tree) = tree->opval.val->etype;
2278 TTYPE (tree) = tree->opval.val->type;
2282 /* see if this is a GETHBIT operation if yes
2285 ast *otree = optimizeGetHbit (tree);
2288 return decorateType (otree);
2292 computeType (LTYPE (tree), RTYPE (tree));
2293 TETYPE (tree) = getSpec (TTYPE (tree));
2295 /* if left is a literal exchange left & right */
2296 if (IS_LITERAL (LTYPE (tree)))
2298 ast *tTree = tree->left;
2299 tree->left = tree->right;
2300 tree->right = tTree;
2303 /* if right is a literal and */
2304 /* we can find a 2nd literal in a and-tree then */
2305 /* rearrange the tree */
2306 if (IS_LITERAL (RTYPE (tree)))
2309 ast *litTree = searchLitOp (tree, &parent, "&");
2312 ast *tTree = litTree->left;
2313 litTree->left = tree->right;
2314 tree->right = tTree;
2315 /* both operands in tTree are literal now */
2316 decorateType (parent);
2320 LRVAL (tree) = RRVAL (tree) = 1;
2324 /*------------------------------------------------------------------*/
2325 /*----------------------------*/
2327 /*----------------------------*/
2328 p = newLink (DECLARATOR);
2329 /* if bit field then error */
2330 if (IS_BITVAR (tree->left->etype))
2332 werror (E_ILLEGAL_ADDR, "address of bit variable");
2333 goto errorTreeReturn;
2336 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2338 werror (E_ILLEGAL_ADDR, "address of register variable");
2339 goto errorTreeReturn;
2342 if (IS_FUNC (LTYPE (tree)))
2344 // this ought to be ignored
2345 return (tree->left);
2348 if (IS_LITERAL(LTYPE(tree)))
2350 werror (E_ILLEGAL_ADDR, "address of literal");
2351 goto errorTreeReturn;
2356 werror (E_LVALUE_REQUIRED, "address of");
2357 goto errorTreeReturn;
2359 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2360 DCL_TYPE (p) = CPOINTER;
2361 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2362 DCL_TYPE (p) = FPOINTER;
2363 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2364 DCL_TYPE (p) = PPOINTER;
2365 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2366 DCL_TYPE (p) = IPOINTER;
2367 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2368 DCL_TYPE (p) = EEPPOINTER;
2369 else if (SPEC_OCLS(tree->left->etype))
2370 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2372 DCL_TYPE (p) = POINTER;
2374 if (IS_AST_SYM_VALUE (tree->left))
2376 AST_SYMBOL (tree->left)->addrtaken = 1;
2377 AST_SYMBOL (tree->left)->allocreq = 1;
2380 p->next = LTYPE (tree);
2382 TETYPE (tree) = getSpec (TTYPE (tree));
2387 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2388 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2390 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2391 AST_SYMBOL(tree->left->right));
2392 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2393 valueFromLit(element->offset));
2396 tree->type = EX_VALUE;
2397 tree->values.literalFromCast = 1;
2403 /*------------------------------------------------------------------*/
2404 /*----------------------------*/
2406 /*----------------------------*/
2408 /* if the rewrite succeeds then don't go any furthur */
2410 ast *wtree = optimizeRRCRLC (tree);
2412 return decorateType (wtree);
2414 wtree = optimizeSWAP (tree);
2416 return decorateType (wtree);
2421 /* if left is a literal exchange left & right */
2422 if (IS_LITERAL (LTYPE (tree)))
2424 ast *tTree = tree->left;
2425 tree->left = tree->right;
2426 tree->right = tTree;
2429 /* if right is a literal and */
2430 /* we can find a 2nd literal in a or-tree then */
2431 /* rearrange the tree */
2432 if (IS_LITERAL (RTYPE (tree)))
2435 ast *litTree = searchLitOp (tree, &parent, "|");
2438 ast *tTree = litTree->left;
2439 litTree->left = tree->right;
2440 tree->right = tTree;
2441 /* both operands in tTree are literal now */
2442 decorateType (parent);
2445 /*------------------------------------------------------------------*/
2446 /*----------------------------*/
2448 /*----------------------------*/
2450 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2452 werror (E_BITWISE_OP);
2453 werror (W_CONTINUE, "left & right types are ");
2454 printTypeChain (LTYPE (tree), stderr);
2455 fprintf (stderr, ",");
2456 printTypeChain (RTYPE (tree), stderr);
2457 fprintf (stderr, "\n");
2458 goto errorTreeReturn;
2461 /* if they are both literal then */
2462 /* rewrite the tree */
2463 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2465 tree->type = EX_VALUE;
2466 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2467 valFromType (RETYPE (tree)),
2469 tree->right = tree->left = NULL;
2470 TETYPE (tree) = tree->opval.val->etype;
2471 TTYPE (tree) = tree->opval.val->type;
2475 /* if left is a literal exchange left & right */
2476 if (IS_LITERAL (LTYPE (tree)))
2478 ast *tTree = tree->left;
2479 tree->left = tree->right;
2480 tree->right = tTree;
2483 /* if right is a literal and */
2484 /* we can find a 2nd literal in a xor-tree then */
2485 /* rearrange the tree */
2486 if (IS_LITERAL (RTYPE (tree)))
2489 ast *litTree = searchLitOp (tree, &parent, "^");
2492 ast *tTree = litTree->left;
2493 litTree->left = tree->right;
2494 tree->right = tTree;
2495 /* both operands in litTree are literal now */
2496 decorateType (parent);
2500 LRVAL (tree) = RRVAL (tree) = 1;
2501 TETYPE (tree) = getSpec (TTYPE (tree) =
2502 computeType (LTYPE (tree),
2505 /*------------------------------------------------------------------*/
2506 /*----------------------------*/
2508 /*----------------------------*/
2510 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2512 werror (E_INVALID_OP, "divide");
2513 goto errorTreeReturn;
2515 /* if they are both literal then */
2516 /* rewrite the tree */
2517 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2519 tree->type = EX_VALUE;
2520 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2521 valFromType (RETYPE (tree)));
2522 tree->right = tree->left = NULL;
2523 TETYPE (tree) = getSpec (TTYPE (tree) =
2524 tree->opval.val->type);
2528 LRVAL (tree) = RRVAL (tree) = 1;
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 computeType (LTYPE (tree),
2533 /* if right is a literal and */
2534 /* left is also a division by a literal then */
2535 /* rearrange the tree */
2536 if (IS_LITERAL (RTYPE (tree))
2537 /* avoid infinite loop */
2538 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2541 ast *litTree = searchLitOp (tree, &parent, "/");
2544 if (IS_LITERAL (RTYPE (litTree)))
2547 litTree->right = newNode ('*', litTree->right, tree->right);
2548 litTree->right->lineno = tree->lineno;
2550 tree->right->opval.val = constVal ("1");
2551 decorateType (parent);
2555 /* litTree->left is literal: no gcse possible.
2556 We can't call decorateType(parent), because
2557 this would cause an infinit loop. */
2558 parent->decorated = 1;
2559 decorateType (litTree);
2566 /*------------------------------------------------------------------*/
2567 /*----------------------------*/
2569 /*----------------------------*/
2571 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2573 werror (E_BITWISE_OP);
2574 werror (W_CONTINUE, "left & right types are ");
2575 printTypeChain (LTYPE (tree), stderr);
2576 fprintf (stderr, ",");
2577 printTypeChain (RTYPE (tree), stderr);
2578 fprintf (stderr, "\n");
2579 goto errorTreeReturn;
2581 /* if they are both literal then */
2582 /* rewrite the tree */
2583 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2585 tree->type = EX_VALUE;
2586 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2587 valFromType (RETYPE (tree)));
2588 tree->right = tree->left = NULL;
2589 TETYPE (tree) = getSpec (TTYPE (tree) =
2590 tree->opval.val->type);
2593 LRVAL (tree) = RRVAL (tree) = 1;
2594 TETYPE (tree) = getSpec (TTYPE (tree) =
2595 computeType (LTYPE (tree),
2599 /*------------------------------------------------------------------*/
2600 /*----------------------------*/
2601 /* address dereference */
2602 /*----------------------------*/
2603 case '*': /* can be unary : if right is null then unary operation */
2606 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2608 werror (E_PTR_REQD);
2609 goto errorTreeReturn;
2614 werror (E_LVALUE_REQUIRED, "pointer deref");
2615 goto errorTreeReturn;
2617 if (IS_ADDRESS_OF_OP(tree->left))
2619 /* replace *&obj with obj */
2620 return tree->left->left;
2622 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2623 TETYPE (tree) = getSpec (TTYPE (tree));
2627 /*------------------------------------------------------------------*/
2628 /*----------------------------*/
2629 /* multiplication */
2630 /*----------------------------*/
2631 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2633 werror (E_INVALID_OP, "multiplication");
2634 goto errorTreeReturn;
2637 /* if they are both literal then */
2638 /* rewrite the tree */
2639 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2641 tree->type = EX_VALUE;
2642 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2643 valFromType (RETYPE (tree)));
2644 tree->right = tree->left = NULL;
2645 TETYPE (tree) = getSpec (TTYPE (tree) =
2646 tree->opval.val->type);
2650 /* if left is a literal exchange left & right */
2651 if (IS_LITERAL (LTYPE (tree)))
2653 ast *tTree = tree->left;
2654 tree->left = tree->right;
2655 tree->right = tTree;
2658 /* if right is a literal and */
2659 /* we can find a 2nd literal in a mul-tree then */
2660 /* rearrange the tree */
2661 if (IS_LITERAL (RTYPE (tree)))
2664 ast *litTree = searchLitOp (tree, &parent, "*");
2667 ast *tTree = litTree->left;
2668 litTree->left = tree->right;
2669 tree->right = tTree;
2670 /* both operands in litTree are literal now */
2671 decorateType (parent);
2675 LRVAL (tree) = RRVAL (tree) = 1;
2676 TETYPE (tree) = getSpec (TTYPE (tree) =
2677 computeType (LTYPE (tree),
2680 /* promote result to int if left & right are char
2681 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2682 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2683 SPEC_NOUN(TETYPE(tree)) = V_INT;
2688 /*------------------------------------------------------------------*/
2689 /*----------------------------*/
2690 /* unary '+' operator */
2691 /*----------------------------*/
2696 if (!IS_INTEGRAL (LTYPE (tree)))
2698 werror (E_UNARY_OP, '+');
2699 goto errorTreeReturn;
2702 /* if left is a literal then do it */
2703 if (IS_LITERAL (LTYPE (tree)))
2705 tree->type = EX_VALUE;
2706 tree->opval.val = valFromType (LETYPE (tree));
2708 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2712 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2716 /*------------------------------------------------------------------*/
2717 /*----------------------------*/
2719 /*----------------------------*/
2721 /* this is not a unary operation */
2722 /* if both pointers then problem */
2723 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2724 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2726 werror (E_PTR_PLUS_PTR);
2727 goto errorTreeReturn;
2730 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2731 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2733 werror (E_PLUS_INVALID, "+");
2734 goto errorTreeReturn;
2737 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2738 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2740 werror (E_PLUS_INVALID, "+");
2741 goto errorTreeReturn;
2743 /* if they are both literal then */
2744 /* rewrite the tree */
2745 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2747 tree->type = EX_VALUE;
2748 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2749 valFromType (RETYPE (tree)));
2750 tree->right = tree->left = NULL;
2751 TETYPE (tree) = getSpec (TTYPE (tree) =
2752 tree->opval.val->type);
2756 /* if the right is a pointer or left is a literal
2757 xchange left & right */
2758 if (IS_ARRAY (RTYPE (tree)) ||
2759 IS_PTR (RTYPE (tree)) ||
2760 IS_LITERAL (LTYPE (tree)))
2762 ast *tTree = tree->left;
2763 tree->left = tree->right;
2764 tree->right = tTree;
2767 /* if right is a literal and */
2768 /* left is also an addition/subtraction with a literal then */
2769 /* rearrange the tree */
2770 if (IS_LITERAL (RTYPE (tree)))
2772 ast *litTree, *parent;
2773 litTree = searchLitOp (tree, &parent, "+-");
2776 if (litTree->opval.op == '+')
2779 ast *tTree = litTree->left;
2780 litTree->left = tree->right;
2781 tree->right = tree->left;
2784 else if (litTree->opval.op == '-')
2786 if (IS_LITERAL (RTYPE (litTree)))
2789 ast *tTree = litTree->left;
2790 litTree->left = tree->right;
2791 tree->right = tTree;
2796 ast *tTree = litTree->right;
2797 litTree->right = tree->right;
2798 tree->right = tTree;
2799 litTree->opval.op = '+';
2800 tree->opval.op = '-';
2803 decorateType (parent);
2807 LRVAL (tree) = RRVAL (tree) = 1;
2808 /* if the left is a pointer */
2809 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2810 TETYPE (tree) = getSpec (TTYPE (tree) =
2813 TETYPE (tree) = getSpec (TTYPE (tree) =
2814 computeType (LTYPE (tree),
2818 /*------------------------------------------------------------------*/
2819 /*----------------------------*/
2821 /*----------------------------*/
2822 case '-': /* can be unary */
2823 /* if right is null then unary */
2827 if (!IS_ARITHMETIC (LTYPE (tree)))
2829 werror (E_UNARY_OP, tree->opval.op);
2830 goto errorTreeReturn;
2833 /* if left is a literal then do it */
2834 if (IS_LITERAL (LTYPE (tree)))
2836 tree->type = EX_VALUE;
2837 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2839 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2840 SPEC_USIGN(TETYPE(tree)) = 0;
2844 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2848 /*------------------------------------------------------------------*/
2849 /*----------------------------*/
2851 /*----------------------------*/
2853 if (!(IS_PTR (LTYPE (tree)) ||
2854 IS_ARRAY (LTYPE (tree)) ||
2855 IS_ARITHMETIC (LTYPE (tree))))
2857 werror (E_PLUS_INVALID, "-");
2858 goto errorTreeReturn;
2861 if (!(IS_PTR (RTYPE (tree)) ||
2862 IS_ARRAY (RTYPE (tree)) ||
2863 IS_ARITHMETIC (RTYPE (tree))))
2865 werror (E_PLUS_INVALID, "-");
2866 goto errorTreeReturn;
2869 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2870 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2871 IS_INTEGRAL (RTYPE (tree))))
2873 werror (E_PLUS_INVALID, "-");
2874 goto errorTreeReturn;
2877 /* if they are both literal then */
2878 /* rewrite the tree */
2879 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2881 tree->type = EX_VALUE;
2882 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2883 valFromType (RETYPE (tree)));
2884 tree->right = tree->left = NULL;
2885 TETYPE (tree) = getSpec (TTYPE (tree) =
2886 tree->opval.val->type);
2890 /* if the left & right are equal then zero */
2891 if (isAstEqual (tree->left, tree->right))
2893 tree->type = EX_VALUE;
2894 tree->left = tree->right = NULL;
2895 tree->opval.val = constVal ("0");
2896 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2900 /* if both of them are pointers or arrays then */
2901 /* the result is going to be an integer */
2902 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2903 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2904 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2906 /* if only the left is a pointer */
2907 /* then result is a pointer */
2908 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2909 TETYPE (tree) = getSpec (TTYPE (tree) =
2912 TETYPE (tree) = getSpec (TTYPE (tree) =
2913 computeType (LTYPE (tree),
2916 LRVAL (tree) = RRVAL (tree) = 1;
2918 /* if right is a literal and */
2919 /* left is also an addition/subtraction with a literal then */
2920 /* rearrange the tree */
2921 if (IS_LITERAL (RTYPE (tree))
2922 /* avoid infinite loop */
2923 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
2925 ast *litTree, *litParent;
2926 litTree = searchLitOp (tree, &litParent, "+-");
2929 if (litTree->opval.op == '+')
2932 litTree->right = newNode ('-', litTree->right, tree->right);
2933 litTree->right->lineno = tree->lineno;
2935 tree->right->opval.val = constVal ("0");
2937 else if (litTree->opval.op == '-')
2939 if (IS_LITERAL (RTYPE (litTree)))
2942 litTree->right = newNode ('+', tree->right, litTree->right);
2943 litTree->right->lineno = tree->lineno;
2945 tree->right->opval.val = constVal ("0");
2950 ast *tTree = litTree->right;
2951 litTree->right = tree->right;
2952 tree->right = tTree;
2955 decorateType (litParent);
2960 /*------------------------------------------------------------------*/
2961 /*----------------------------*/
2963 /*----------------------------*/
2965 /* can be only integral type */
2966 if (!IS_INTEGRAL (LTYPE (tree)))
2968 werror (E_UNARY_OP, tree->opval.op);
2969 goto errorTreeReturn;
2972 /* if left is a literal then do it */
2973 if (IS_LITERAL (LTYPE (tree)))
2975 tree->type = EX_VALUE;
2976 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2978 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2982 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2985 /*------------------------------------------------------------------*/
2986 /*----------------------------*/
2988 /*----------------------------*/
2990 /* can be pointer */
2991 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2992 !IS_PTR (LTYPE (tree)) &&
2993 !IS_ARRAY (LTYPE (tree)))
2995 werror (E_UNARY_OP, tree->opval.op);
2996 goto errorTreeReturn;
2999 /* if left is a literal then do it */
3000 if (IS_LITERAL (LTYPE (tree)))
3002 tree->type = EX_VALUE;
3003 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3005 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3009 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3012 /*------------------------------------------------------------------*/
3013 /*----------------------------*/
3015 /*----------------------------*/
3019 TTYPE (tree) = LTYPE (tree);
3020 TETYPE (tree) = LETYPE (tree);
3024 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3029 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3031 werror (E_SHIFT_OP_INVALID);
3032 werror (W_CONTINUE, "left & right types are ");
3033 printTypeChain (LTYPE (tree), stderr);
3034 fprintf (stderr, ",");
3035 printTypeChain (RTYPE (tree), stderr);
3036 fprintf (stderr, "\n");
3037 goto errorTreeReturn;
3040 /* if they are both literal then */
3041 /* rewrite the tree */
3042 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3044 tree->type = EX_VALUE;
3045 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3046 valFromType (RETYPE (tree)),
3047 (tree->opval.op == LEFT_OP ? 1 : 0));
3048 tree->right = tree->left = NULL;
3049 TETYPE (tree) = getSpec (TTYPE (tree) =
3050 tree->opval.val->type);
3054 /* if only the right side is a literal & we are
3055 shifting more than size of the left operand then zero */
3056 if (IS_LITERAL (RTYPE (tree)) &&
3057 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3058 (getSize (LTYPE (tree)) * 8))
3060 if (tree->opval.op==LEFT_OP ||
3061 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3062 lineno=tree->lineno;
3063 werror (W_SHIFT_CHANGED,
3064 (tree->opval.op == LEFT_OP ? "left" : "right"));
3065 tree->type = EX_VALUE;
3066 tree->left = tree->right = NULL;
3067 tree->opval.val = constVal ("0");
3068 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3072 LRVAL (tree) = RRVAL (tree) = 1;
3073 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3074 if (IS_LITERAL (TTYPE (tree)))
3075 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3078 /*------------------------------------------------------------------*/
3079 /*----------------------------*/
3081 /*----------------------------*/
3082 case CAST: /* change the type */
3083 /* cannot cast to an aggregate type */
3084 if (IS_AGGREGATE (LTYPE (tree)))
3086 werror (E_CAST_ILLEGAL);
3087 goto errorTreeReturn;
3090 /* make sure the type is complete and sane */
3091 checkTypeSanity(LETYPE(tree), "(cast)");
3094 /* if the right is a literal replace the tree */
3095 if (IS_LITERAL (RETYPE (tree))) {
3096 if (!IS_PTR (LTYPE (tree))) {
3097 tree->type = EX_VALUE;
3099 valCastLiteral (LTYPE (tree),
3100 floatFromVal (valFromType (RETYPE (tree))));
3103 TTYPE (tree) = tree->opval.val->type;
3104 tree->values.literalFromCast = 1;
3105 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3106 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3107 sym_link *rest = LTYPE(tree)->next;
3108 werror(W_LITERAL_GENERIC);
3109 TTYPE(tree) = newLink(DECLARATOR);
3110 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3111 TTYPE(tree)->next = rest;
3112 tree->left->opval.lnk = TTYPE(tree);
3115 TTYPE (tree) = LTYPE (tree);
3119 TTYPE (tree) = LTYPE (tree);
3123 #if 0 // this is already checked, now this could be explicit
3124 /* if pointer to struct then check names */
3125 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3126 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3127 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3129 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3130 SPEC_STRUCT(LETYPE(tree))->tag);
3133 if (IS_ADDRESS_OF_OP(tree->right)
3134 && IS_AST_SYM_VALUE (tree->right->left)
3135 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3137 tree->type = EX_VALUE;
3139 valCastLiteral (LTYPE (tree),
3140 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3141 TTYPE (tree) = tree->opval.val->type;
3142 TETYPE (tree) = getSpec (TTYPE (tree));
3145 tree->values.literalFromCast = 1;
3149 /* handle offsetof macro: */
3150 /* #define offsetof(TYPE, MEMBER) \ */
3151 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3152 if (IS_ADDRESS_OF_OP(tree->right)
3153 && IS_AST_OP (tree->right->left)
3154 && tree->right->left->opval.op == PTR_OP
3155 && IS_AST_OP (tree->right->left->left)
3156 && tree->right->left->left->opval.op == CAST
3157 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3159 symbol *element = getStructElement (
3160 SPEC_STRUCT (LETYPE(tree->right->left)),
3161 AST_SYMBOL(tree->right->left->right)
3165 tree->type = EX_VALUE;
3166 tree->opval.val = valCastLiteral (
3169 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3172 TTYPE (tree) = tree->opval.val->type;
3173 TETYPE (tree) = getSpec (TTYPE (tree));
3180 /* if the right is a literal replace the tree */
3181 if (IS_LITERAL (RETYPE (tree))) {
3182 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3183 /* rewrite (type *)litaddr
3185 and define type at litaddr temp
3186 (but only if type's storage class is not generic)
3188 ast *newTree = newNode ('&', NULL, NULL);
3191 TTYPE (newTree) = LTYPE (tree);
3192 TETYPE (newTree) = getSpec(LTYPE (tree));
3194 /* define a global symbol at the casted address*/
3195 sym = newSymbol(genSymName (0), 0);
3196 sym->type = LTYPE (tree)->next;
3198 sym->type = newLink (V_VOID);
3199 sym->etype = getSpec(sym->type);
3200 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3201 sym->lineDef = tree->lineno;
3204 SPEC_STAT (sym->etype) = 1;
3205 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3206 SPEC_ABSA(sym->etype) = 1;
3207 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3210 newTree->left = newAst_VALUE(symbolVal(sym));
3211 newTree->left->lineno = tree->lineno;
3212 LTYPE (newTree) = sym->type;
3213 LETYPE (newTree) = sym->etype;
3214 LLVAL (newTree) = 1;
3215 LRVAL (newTree) = 0;
3216 TLVAL (newTree) = 1;
3219 if (!IS_PTR (LTYPE (tree))) {
3220 tree->type = EX_VALUE;
3222 valCastLiteral (LTYPE (tree),
3223 floatFromVal (valFromType (RETYPE (tree))));
3224 TTYPE (tree) = tree->opval.val->type;
3227 tree->values.literalFromCast = 1;
3228 TETYPE (tree) = getSpec (TTYPE (tree));
3232 TTYPE (tree) = LTYPE (tree);
3236 TETYPE (tree) = getSpec (TTYPE (tree));
3240 /*------------------------------------------------------------------*/
3241 /*----------------------------*/
3242 /* logical &&, || */
3243 /*----------------------------*/
3246 /* each must me arithmetic type or be a pointer */
3247 if (!IS_PTR (LTYPE (tree)) &&
3248 !IS_ARRAY (LTYPE (tree)) &&
3249 !IS_INTEGRAL (LTYPE (tree)))
3251 werror (E_COMPARE_OP);
3252 goto errorTreeReturn;
3255 if (!IS_PTR (RTYPE (tree)) &&
3256 !IS_ARRAY (RTYPE (tree)) &&
3257 !IS_INTEGRAL (RTYPE (tree)))
3259 werror (E_COMPARE_OP);
3260 goto errorTreeReturn;
3262 /* if they are both literal then */
3263 /* rewrite the tree */
3264 if (IS_LITERAL (RTYPE (tree)) &&
3265 IS_LITERAL (LTYPE (tree)))
3267 tree->type = EX_VALUE;
3268 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3269 valFromType (RETYPE (tree)),
3271 tree->right = tree->left = NULL;
3272 TETYPE (tree) = getSpec (TTYPE (tree) =
3273 tree->opval.val->type);
3276 LRVAL (tree) = RRVAL (tree) = 1;
3277 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3280 /*------------------------------------------------------------------*/
3281 /*----------------------------*/
3282 /* comparison operators */
3283 /*----------------------------*/
3291 ast *lt = optimizeCompare (tree);
3297 /* if they are pointers they must be castable */
3298 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3300 if (tree->opval.op==EQ_OP &&
3301 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3302 // we cannot cast a gptr to a !gptr: switch the leaves
3303 struct ast *s=tree->left;
3304 tree->left=tree->right;
3307 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3309 werror (E_COMPARE_OP);
3310 fprintf (stderr, "comparring type ");
3311 printTypeChain (LTYPE (tree), stderr);
3312 fprintf (stderr, "to type ");
3313 printTypeChain (RTYPE (tree), stderr);
3314 fprintf (stderr, "\n");
3315 goto errorTreeReturn;
3318 /* else they should be promotable to one another */
3321 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3322 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3324 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3326 werror (E_COMPARE_OP);
3327 fprintf (stderr, "comparing type ");
3328 printTypeChain (LTYPE (tree), stderr);
3329 fprintf (stderr, "to type ");
3330 printTypeChain (RTYPE (tree), stderr);
3331 fprintf (stderr, "\n");
3332 goto errorTreeReturn;
3335 /* if unsigned value < 0 then always false */
3336 /* if (unsigned value) > 0 then (unsigned value) */
3337 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3338 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3340 if (tree->opval.op == '<') {
3343 if (tree->opval.op == '>') {
3347 /* if they are both literal then */
3348 /* rewrite the tree */
3349 if (IS_LITERAL (RTYPE (tree)) &&
3350 IS_LITERAL (LTYPE (tree)))
3352 tree->type = EX_VALUE;
3353 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3354 valFromType (RETYPE (tree)),
3356 tree->right = tree->left = NULL;
3357 TETYPE (tree) = getSpec (TTYPE (tree) =
3358 tree->opval.val->type);
3361 LRVAL (tree) = RRVAL (tree) = 1;
3362 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3365 /*------------------------------------------------------------------*/
3366 /*----------------------------*/
3368 /*----------------------------*/
3369 case SIZEOF: /* evaluate wihout code generation */
3370 /* change the type to a integer */
3371 tree->type = EX_VALUE;
3372 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3373 tree->opval.val = constVal (buffer);
3374 tree->right = tree->left = NULL;
3375 TETYPE (tree) = getSpec (TTYPE (tree) =
3376 tree->opval.val->type);
3379 /*------------------------------------------------------------------*/
3380 /*----------------------------*/
3382 /*----------------------------*/
3384 /* return typeof enum value */
3385 tree->type = EX_VALUE;
3388 if (IS_SPEC(tree->right->ftype)) {
3389 switch (SPEC_NOUN(tree->right->ftype)) {
3391 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3392 else typeofv = TYPEOF_INT;
3395 typeofv = TYPEOF_FLOAT;
3398 typeofv = TYPEOF_CHAR;
3401 typeofv = TYPEOF_VOID;
3404 typeofv = TYPEOF_STRUCT;
3407 typeofv = TYPEOF_BITFIELD;
3410 typeofv = TYPEOF_BIT;
3413 typeofv = TYPEOF_SBIT;
3419 switch (DCL_TYPE(tree->right->ftype)) {
3421 typeofv = TYPEOF_POINTER;
3424 typeofv = TYPEOF_FPOINTER;
3427 typeofv = TYPEOF_CPOINTER;
3430 typeofv = TYPEOF_GPOINTER;
3433 typeofv = TYPEOF_PPOINTER;
3436 typeofv = TYPEOF_IPOINTER;
3439 typeofv = TYPEOF_ARRAY;
3442 typeofv = TYPEOF_FUNCTION;
3448 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3449 tree->opval.val = constVal (buffer);
3450 tree->right = tree->left = NULL;
3451 TETYPE (tree) = getSpec (TTYPE (tree) =
3452 tree->opval.val->type);
3455 /*------------------------------------------------------------------*/
3456 /*----------------------------*/
3457 /* conditional operator '?' */
3458 /*----------------------------*/
3460 /* the type is value of the colon operator (on the right) */
3461 assert(IS_COLON_OP(tree->right));
3462 /* if already known then replace the tree : optimizer will do it
3463 but faster to do it here */
3464 if (IS_LITERAL (LTYPE(tree))) {
3465 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3466 return decorateType(tree->right->left) ;
3468 return decorateType(tree->right->right) ;
3471 tree->right = decorateType(tree->right);
3472 TTYPE (tree) = RTYPE(tree);
3473 TETYPE (tree) = getSpec (TTYPE (tree));
3478 /* if they don't match we have a problem */
3479 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3481 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3482 goto errorTreeReturn;
3485 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3486 TETYPE (tree) = getSpec (TTYPE (tree));
3490 #if 0 // assignment operators are converted by the parser
3491 /*------------------------------------------------------------------*/
3492 /*----------------------------*/
3493 /* assignment operators */
3494 /*----------------------------*/
3497 /* for these it must be both must be integral */
3498 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3499 !IS_ARITHMETIC (RTYPE (tree)))
3501 werror (E_OPS_INTEGRAL);
3502 goto errorTreeReturn;
3505 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3507 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3508 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3512 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3513 goto errorTreeReturn;
3524 /* for these it must be both must be integral */
3525 if (!IS_INTEGRAL (LTYPE (tree)) ||
3526 !IS_INTEGRAL (RTYPE (tree)))
3528 werror (E_OPS_INTEGRAL);
3529 goto errorTreeReturn;
3532 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3534 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3535 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3539 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3540 goto errorTreeReturn;
3546 /*------------------------------------------------------------------*/
3547 /*----------------------------*/
3549 /*----------------------------*/
3551 if (!(IS_PTR (LTYPE (tree)) ||
3552 IS_ARITHMETIC (LTYPE (tree))))
3554 werror (E_PLUS_INVALID, "-=");
3555 goto errorTreeReturn;
3558 if (!(IS_PTR (RTYPE (tree)) ||
3559 IS_ARITHMETIC (RTYPE (tree))))
3561 werror (E_PLUS_INVALID, "-=");
3562 goto errorTreeReturn;
3565 TETYPE (tree) = getSpec (TTYPE (tree) =
3566 computeType (LTYPE (tree),
3569 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3570 werror (E_CODE_WRITE, "-=");
3574 werror (E_LVALUE_REQUIRED, "-=");
3575 goto errorTreeReturn;
3581 /*------------------------------------------------------------------*/
3582 /*----------------------------*/
3584 /*----------------------------*/
3586 /* this is not a unary operation */
3587 /* if both pointers then problem */
3588 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3590 werror (E_PTR_PLUS_PTR);
3591 goto errorTreeReturn;
3594 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3596 werror (E_PLUS_INVALID, "+=");
3597 goto errorTreeReturn;
3600 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3602 werror (E_PLUS_INVALID, "+=");
3603 goto errorTreeReturn;
3606 TETYPE (tree) = getSpec (TTYPE (tree) =
3607 computeType (LTYPE (tree),
3610 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3611 werror (E_CODE_WRITE, "+=");
3615 werror (E_LVALUE_REQUIRED, "+=");
3616 goto errorTreeReturn;
3619 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3620 tree->opval.op = '=';
3625 /*------------------------------------------------------------------*/
3626 /*----------------------------*/
3627 /* straight assignemnt */
3628 /*----------------------------*/
3630 /* cannot be an aggregate */
3631 if (IS_AGGREGATE (LTYPE (tree)))
3633 werror (E_AGGR_ASSIGN);
3634 goto errorTreeReturn;
3637 /* they should either match or be castable */
3638 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3640 werror (E_TYPE_MISMATCH, "assignment", " ");
3641 printFromToType(RTYPE(tree),LTYPE(tree));
3644 /* if the left side of the tree is of type void
3645 then report error */
3646 if (IS_VOID (LTYPE (tree)))
3648 werror (E_CAST_ZERO);
3649 printFromToType(RTYPE(tree), LTYPE(tree));
3652 TETYPE (tree) = getSpec (TTYPE (tree) =
3656 if (!tree->initMode ) {
3657 if (IS_CONSTANT(LTYPE(tree)))
3658 werror (E_CODE_WRITE, "=");
3662 werror (E_LVALUE_REQUIRED, "=");
3663 goto errorTreeReturn;
3668 /*------------------------------------------------------------------*/
3669 /*----------------------------*/
3670 /* comma operator */
3671 /*----------------------------*/
3673 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3676 /*------------------------------------------------------------------*/
3677 /*----------------------------*/
3679 /*----------------------------*/
3683 if (processParms (tree->left,
3684 FUNC_ARGS(tree->left->ftype),
3685 tree->right, &parmNumber, TRUE)) {
3686 goto errorTreeReturn;
3689 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3690 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3692 reverseParms (tree->right);
3695 if (IS_CODEPTR(LTYPE(tree))) {
3696 TTYPE(tree) = LTYPE(tree)->next->next;
3698 TTYPE(tree) = LTYPE(tree)->next;
3700 TETYPE (tree) = getSpec (TTYPE (tree));
3703 /*------------------------------------------------------------------*/
3704 /*----------------------------*/
3705 /* return statement */
3706 /*----------------------------*/
3711 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3713 werror (W_RETURN_MISMATCH);
3714 printFromToType (RTYPE(tree), currFunc->type->next);
3715 goto errorTreeReturn;
3718 if (IS_VOID (currFunc->type->next)
3720 !IS_VOID (RTYPE (tree)))
3722 werror (E_FUNC_VOID);
3723 goto errorTreeReturn;
3726 /* if there is going to be a casing required then add it */
3727 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3730 decorateType (newNode (CAST,
3731 newAst_LINK (copyLinkChain (currFunc->type->next)),
3740 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3742 werror (W_VOID_FUNC, currFunc->name);
3743 goto errorTreeReturn;
3746 TTYPE (tree) = TETYPE (tree) = NULL;
3749 /*------------------------------------------------------------------*/
3750 /*----------------------------*/
3751 /* switch statement */
3752 /*----------------------------*/
3754 /* the switch value must be an integer */
3755 if (!IS_INTEGRAL (LTYPE (tree)))
3757 werror (E_SWITCH_NON_INTEGER);
3758 goto errorTreeReturn;
3761 TTYPE (tree) = TETYPE (tree) = NULL;
3764 /*------------------------------------------------------------------*/
3765 /*----------------------------*/
3767 /*----------------------------*/
3769 tree->left = backPatchLabels (tree->left,
3772 TTYPE (tree) = TETYPE (tree) = NULL;
3775 /*------------------------------------------------------------------*/
3776 /*----------------------------*/
3778 /*----------------------------*/
3781 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3782 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3783 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3785 /* if the for loop is reversible then
3786 reverse it otherwise do what we normally
3792 if (isLoopReversible (tree, &sym, &init, &end))
3793 return reverseLoop (tree, sym, init, end);
3795 return decorateType (createFor (AST_FOR (tree, trueLabel),
3796 AST_FOR (tree, continueLabel),
3797 AST_FOR (tree, falseLabel),
3798 AST_FOR (tree, condLabel),
3799 AST_FOR (tree, initExpr),
3800 AST_FOR (tree, condExpr),
3801 AST_FOR (tree, loopExpr),
3805 TTYPE (tree) = TETYPE (tree) = NULL;
3809 /* some error found this tree will be killed */
3811 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3812 tree->opval.op = NULLOP;
3818 /*-----------------------------------------------------------------*/
3819 /* sizeofOp - processes size of operation */
3820 /*-----------------------------------------------------------------*/
3822 sizeofOp (sym_link * type)
3826 /* make sure the type is complete and sane */
3827 checkTypeSanity(type, "(sizeof)");
3829 /* get the size and convert it to character */
3830 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3832 /* now convert into value */
3833 return constVal (buff);
3837 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3838 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3839 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3840 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3841 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3842 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3843 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3845 /*-----------------------------------------------------------------*/
3846 /* backPatchLabels - change and or not operators to flow control */
3847 /*-----------------------------------------------------------------*/
3849 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3855 if (!(IS_ANDORNOT (tree)))
3858 /* if this an and */
3861 static int localLbl = 0;
3864 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3865 localLabel = newSymbol (buffer, NestLevel);
3867 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3869 /* if left is already a IFX then just change the if true label in that */
3870 if (!IS_IFX (tree->left))
3871 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3873 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3874 /* right is a IFX then just join */
3875 if (IS_IFX (tree->right))
3876 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3878 tree->right = createLabel (localLabel, tree->right);
3879 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3881 return newNode (NULLOP, tree->left, tree->right);
3884 /* if this is an or operation */
3887 static int localLbl = 0;
3890 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3891 localLabel = newSymbol (buffer, NestLevel);
3893 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3895 /* if left is already a IFX then just change the if true label in that */
3896 if (!IS_IFX (tree->left))
3897 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3899 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3900 /* right is a IFX then just join */
3901 if (IS_IFX (tree->right))
3902 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3904 tree->right = createLabel (localLabel, tree->right);
3905 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3907 return newNode (NULLOP, tree->left, tree->right);
3913 int wasnot = IS_NOT (tree->left);
3914 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3916 /* if the left is already a IFX */
3917 if (!IS_IFX (tree->left))
3918 tree->left = newNode (IFX, tree->left, NULL);
3922 tree->left->trueLabel = trueLabel;
3923 tree->left->falseLabel = falseLabel;
3927 tree->left->trueLabel = falseLabel;
3928 tree->left->falseLabel = trueLabel;
3935 tree->trueLabel = trueLabel;
3936 tree->falseLabel = falseLabel;
3943 /*-----------------------------------------------------------------*/
3944 /* createBlock - create expression tree for block */
3945 /*-----------------------------------------------------------------*/
3947 createBlock (symbol * decl, ast * body)
3951 /* if the block has nothing */
3955 ex = newNode (BLOCK, NULL, body);
3956 ex->values.sym = decl;
3958 ex->right = ex->right;
3964 /*-----------------------------------------------------------------*/
3965 /* createLabel - creates the expression tree for labels */
3966 /*-----------------------------------------------------------------*/
3968 createLabel (symbol * label, ast * stmnt)
3971 char name[SDCC_NAME_MAX + 1];
3974 /* must create fresh symbol if the symbol name */
3975 /* exists in the symbol table, since there can */
3976 /* be a variable with the same name as the labl */
3977 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3978 (csym->level == label->level))
3979 label = newSymbol (label->name, label->level);
3981 /* change the name before putting it in add _ */
3982 SNPRINTF(name, sizeof(name), "%s", label->name);
3984 /* put the label in the LabelSymbol table */
3985 /* but first check if a label of the same */
3987 if ((csym = findSym (LabelTab, NULL, name)))
3988 werror (E_DUPLICATE_LABEL, label->name);
3990 addSym (LabelTab, label, name, label->level, 0, 0);
3993 label->key = labelKey++;
3994 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4000 /*-----------------------------------------------------------------*/
4001 /* createCase - generates the parsetree for a case statement */
4002 /*-----------------------------------------------------------------*/
4004 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4006 char caseLbl[SDCC_NAME_MAX + 1];
4010 /* if the switch statement does not exist */
4011 /* then case is out of context */
4014 werror (E_CASE_CONTEXT);
4018 caseVal = decorateType (resolveSymbols (caseVal));
4019 /* if not a constant then error */
4020 if (!IS_LITERAL (caseVal->ftype))
4022 werror (E_CASE_CONSTANT);
4026 /* if not a integer than error */
4027 if (!IS_INTEGRAL (caseVal->ftype))
4029 werror (E_CASE_NON_INTEGER);
4033 /* find the end of the switch values chain */
4034 if (!(val = swStat->values.switchVals.swVals))
4035 swStat->values.switchVals.swVals = caseVal->opval.val;
4038 /* also order the cases according to value */
4040 int cVal = (int) floatFromVal (caseVal->opval.val);
4041 while (val && (int) floatFromVal (val) < cVal)
4047 /* if we reached the end then */
4050 pval->next = caseVal->opval.val;
4054 /* we found a value greater than */
4055 /* the current value we must add this */
4056 /* before the value */
4057 caseVal->opval.val->next = val;
4059 /* if this was the first in chain */
4060 if (swStat->values.switchVals.swVals == val)
4061 swStat->values.switchVals.swVals =
4064 pval->next = caseVal->opval.val;
4069 /* create the case label */
4070 SNPRINTF(caseLbl, sizeof(caseLbl),
4072 swStat->values.switchVals.swNum,
4073 (int) floatFromVal (caseVal->opval.val));
4075 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4080 /*-----------------------------------------------------------------*/
4081 /* createDefault - creates the parse tree for the default statement */
4082 /*-----------------------------------------------------------------*/
4084 createDefault (ast * swStat, ast * stmnt)
4086 char defLbl[SDCC_NAME_MAX + 1];
4088 /* if the switch statement does not exist */
4089 /* then case is out of context */
4092 werror (E_CASE_CONTEXT);
4096 /* turn on the default flag */
4097 swStat->values.switchVals.swDefault = 1;
4099 /* create the label */
4100 SNPRINTF (defLbl, sizeof(defLbl),
4101 "_default_%d", swStat->values.switchVals.swNum);
4102 return createLabel (newSymbol (defLbl, 0), stmnt);
4105 /*-----------------------------------------------------------------*/
4106 /* createIf - creates the parsetree for the if statement */
4107 /*-----------------------------------------------------------------*/
4109 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4111 static int Lblnum = 0;
4113 symbol *ifTrue, *ifFalse, *ifEnd;
4115 /* if neither exists */
4116 if (!elseBody && !ifBody) {
4117 // if there are no side effects (i++, j() etc)
4118 if (!hasSEFcalls(condAst)) {
4123 /* create the labels */
4124 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4125 ifFalse = newSymbol (buffer, NestLevel);
4126 /* if no else body then end == false */
4131 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4132 ifEnd = newSymbol (buffer, NestLevel);
4135 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4136 ifTrue = newSymbol (buffer, NestLevel);
4140 /* attach the ifTrue label to the top of it body */
4141 ifBody = createLabel (ifTrue, ifBody);
4142 /* attach a goto end to the ifBody if else is present */
4145 ifBody = newNode (NULLOP, ifBody,
4147 newAst_VALUE (symbolVal (ifEnd)),
4149 /* put the elseLabel on the else body */
4150 elseBody = createLabel (ifFalse, elseBody);
4151 /* out the end at the end of the body */
4152 elseBody = newNode (NULLOP,
4154 createLabel (ifEnd, NULL));
4158 ifBody = newNode (NULLOP, ifBody,
4159 createLabel (ifFalse, NULL));
4161 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4162 if (IS_IFX (condAst))
4165 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4167 return newNode (NULLOP, ifTree,
4168 newNode (NULLOP, ifBody, elseBody));
4172 /*-----------------------------------------------------------------*/
4173 /* createDo - creates parse tree for do */
4176 /* _docontinue_n: */
4177 /* condition_expression +-> trueLabel -> _dobody_n */
4179 /* +-> falseLabel-> _dobreak_n */
4181 /*-----------------------------------------------------------------*/
4183 createDo (symbol * trueLabel, symbol * continueLabel,
4184 symbol * falseLabel, ast * condAst, ast * doBody)
4189 /* if the body does not exist then it is simple */
4192 condAst = backPatchLabels (condAst, continueLabel, NULL);
4193 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4194 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4195 doTree->trueLabel = continueLabel;
4196 doTree->falseLabel = NULL;
4200 /* otherwise we have a body */
4201 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4203 /* attach the body label to the top */
4204 doBody = createLabel (trueLabel, doBody);
4205 /* attach the continue label to end of body */
4206 doBody = newNode (NULLOP, doBody,
4207 createLabel (continueLabel, NULL));
4209 /* now put the break label at the end */
4210 if (IS_IFX (condAst))
4213 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4215 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4217 /* putting it together */
4218 return newNode (NULLOP, doBody, doTree);
4221 /*-----------------------------------------------------------------*/
4222 /* createFor - creates parse tree for 'for' statement */
4225 /* condExpr +-> trueLabel -> _forbody_n */
4227 /* +-> falseLabel-> _forbreak_n */
4230 /* _forcontinue_n: */
4232 /* goto _forcond_n ; */
4234 /*-----------------------------------------------------------------*/
4236 createFor (symbol * trueLabel, symbol * continueLabel,
4237 symbol * falseLabel, symbol * condLabel,
4238 ast * initExpr, ast * condExpr, ast * loopExpr,
4243 /* if loopexpression not present then we can generate it */
4244 /* the same way as a while */
4246 return newNode (NULLOP, initExpr,
4247 createWhile (trueLabel, continueLabel,
4248 falseLabel, condExpr, forBody));
4249 /* vanilla for statement */
4250 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4252 if (condExpr && !IS_IFX (condExpr))
4253 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4256 /* attach condition label to condition */
4257 condExpr = createLabel (condLabel, condExpr);
4259 /* attach body label to body */
4260 forBody = createLabel (trueLabel, forBody);
4262 /* attach continue to forLoop expression & attach */
4263 /* goto the forcond @ and of loopExpression */
4264 loopExpr = createLabel (continueLabel,
4268 newAst_VALUE (symbolVal (condLabel)),
4270 /* now start putting them together */
4271 forTree = newNode (NULLOP, initExpr, condExpr);
4272 forTree = newNode (NULLOP, forTree, forBody);
4273 forTree = newNode (NULLOP, forTree, loopExpr);
4274 /* finally add the break label */
4275 forTree = newNode (NULLOP, forTree,
4276 createLabel (falseLabel, NULL));
4280 /*-----------------------------------------------------------------*/
4281 /* createWhile - creates parse tree for while statement */
4282 /* the while statement will be created as follows */
4284 /* _while_continue_n: */
4285 /* condition_expression +-> trueLabel -> _while_boby_n */
4287 /* +-> falseLabel -> _while_break_n */
4288 /* _while_body_n: */
4290 /* goto _while_continue_n */
4291 /* _while_break_n: */
4292 /*-----------------------------------------------------------------*/
4294 createWhile (symbol * trueLabel, symbol * continueLabel,
4295 symbol * falseLabel, ast * condExpr, ast * whileBody)
4299 /* put the continue label */
4300 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4301 condExpr = createLabel (continueLabel, condExpr);
4302 condExpr->lineno = 0;
4304 /* put the body label in front of the body */
4305 whileBody = createLabel (trueLabel, whileBody);
4306 whileBody->lineno = 0;
4307 /* put a jump to continue at the end of the body */
4308 /* and put break label at the end of the body */
4309 whileBody = newNode (NULLOP,
4312 newAst_VALUE (symbolVal (continueLabel)),
4313 createLabel (falseLabel, NULL)));
4315 /* put it all together */
4316 if (IS_IFX (condExpr))
4317 whileTree = condExpr;
4320 whileTree = newNode (IFX, condExpr, NULL);
4321 /* put the true & false labels in place */
4322 whileTree->trueLabel = trueLabel;
4323 whileTree->falseLabel = falseLabel;
4326 return newNode (NULLOP, whileTree, whileBody);
4329 /*-----------------------------------------------------------------*/
4330 /* optimizeGetHbit - get highest order bit of the expression */
4331 /*-----------------------------------------------------------------*/
4333 optimizeGetHbit (ast * tree)
4336 /* if this is not a bit and */
4337 if (!IS_BITAND (tree))
4340 /* will look for tree of the form
4341 ( expr >> ((sizeof expr) -1) ) & 1 */
4342 if (!IS_AST_LIT_VALUE (tree->right))
4345 if (AST_LIT_VALUE (tree->right) != 1)
4348 if (!IS_RIGHT_OP (tree->left))
4351 if (!IS_AST_LIT_VALUE (tree->left->right))
4354 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4355 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4358 /* make sure the port supports GETHBIT */
4359 if (port->hasExtBitOp
4360 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4363 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4367 /*-----------------------------------------------------------------*/
4368 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4369 /*-----------------------------------------------------------------*/
4371 optimizeRRCRLC (ast * root)
4373 /* will look for trees of the form
4374 (?expr << 1) | (?expr >> 7) or
4375 (?expr >> 7) | (?expr << 1) will make that
4376 into a RLC : operation ..
4378 (?expr >> 1) | (?expr << 7) or
4379 (?expr << 7) | (?expr >> 1) will make that
4380 into a RRC operation
4381 note : by 7 I mean (number of bits required to hold the
4383 /* if the root operations is not a | operation the not */
4384 if (!IS_BITOR (root))
4387 /* I have to think of a better way to match patterns this sucks */
4388 /* that aside let start looking for the first case : I use a the
4389 negative check a lot to improve the efficiency */
4390 /* (?expr << 1) | (?expr >> 7) */
4391 if (IS_LEFT_OP (root->left) &&
4392 IS_RIGHT_OP (root->right))
4395 if (!SPEC_USIGN (TETYPE (root->left->left)))
4398 if (!IS_AST_LIT_VALUE (root->left->right) ||
4399 !IS_AST_LIT_VALUE (root->right->right))
4402 /* make sure it is the same expression */
4403 if (!isAstEqual (root->left->left,
4407 if (AST_LIT_VALUE (root->left->right) != 1)
4410 if (AST_LIT_VALUE (root->right->right) !=
4411 (getSize (TTYPE (root->left->left)) * 8 - 1))
4414 /* make sure the port supports RLC */
4415 if (port->hasExtBitOp
4416 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4419 /* whew got the first case : create the AST */
4420 return newNode (RLC, root->left->left, NULL);
4424 /* check for second case */
4425 /* (?expr >> 7) | (?expr << 1) */
4426 if (IS_LEFT_OP (root->right) &&
4427 IS_RIGHT_OP (root->left))
4430 if (!SPEC_USIGN (TETYPE (root->left->left)))
4433 if (!IS_AST_LIT_VALUE (root->left->right) ||
4434 !IS_AST_LIT_VALUE (root->right->right))
4437 /* make sure it is the same symbol */
4438 if (!isAstEqual (root->left->left,
4442 if (AST_LIT_VALUE (root->right->right) != 1)
4445 if (AST_LIT_VALUE (root->left->right) !=
4446 (getSize (TTYPE (root->left->left)) * 8 - 1))
4449 /* make sure the port supports RLC */
4450 if (port->hasExtBitOp
4451 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4454 /* whew got the first case : create the AST */
4455 return newNode (RLC, root->left->left, NULL);
4460 /* third case for RRC */
4461 /* (?symbol >> 1) | (?symbol << 7) */
4462 if (IS_LEFT_OP (root->right) &&
4463 IS_RIGHT_OP (root->left))
4466 if (!SPEC_USIGN (TETYPE (root->left->left)))
4469 if (!IS_AST_LIT_VALUE (root->left->right) ||
4470 !IS_AST_LIT_VALUE (root->right->right))
4473 /* make sure it is the same symbol */
4474 if (!isAstEqual (root->left->left,
4478 if (AST_LIT_VALUE (root->left->right) != 1)
4481 if (AST_LIT_VALUE (root->right->right) !=
4482 (getSize (TTYPE (root->left->left)) * 8 - 1))
4485 /* make sure the port supports RRC */
4486 if (port->hasExtBitOp
4487 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4490 /* whew got the first case : create the AST */
4491 return newNode (RRC, root->left->left, NULL);
4495 /* fourth and last case for now */
4496 /* (?symbol << 7) | (?symbol >> 1) */
4497 if (IS_RIGHT_OP (root->right) &&
4498 IS_LEFT_OP (root->left))
4501 if (!SPEC_USIGN (TETYPE (root->left->left)))
4504 if (!IS_AST_LIT_VALUE (root->left->right) ||
4505 !IS_AST_LIT_VALUE (root->right->right))
4508 /* make sure it is the same symbol */
4509 if (!isAstEqual (root->left->left,
4513 if (AST_LIT_VALUE (root->right->right) != 1)
4516 if (AST_LIT_VALUE (root->left->right) !=
4517 (getSize (TTYPE (root->left->left)) * 8 - 1))
4520 /* make sure the port supports RRC */
4521 if (port->hasExtBitOp
4522 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4525 /* whew got the first case : create the AST */
4526 return newNode (RRC, root->left->left, NULL);
4530 /* not found return root */
4534 /*-----------------------------------------------------------------*/
4535 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4536 /*-----------------------------------------------------------------*/
4538 optimizeSWAP (ast * root)
4540 /* will look for trees of the form
4541 (?expr << 4) | (?expr >> 4) or
4542 (?expr >> 4) | (?expr << 4) will make that
4543 into a SWAP : operation ..
4544 note : by 4 I mean (number of bits required to hold the
4546 /* if the root operations is not a | operation the not */
4547 if (!IS_BITOR (root))
4550 /* (?expr << 4) | (?expr >> 4) */
4551 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4552 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4555 if (!SPEC_USIGN (TETYPE (root->left->left)))
4558 if (!IS_AST_LIT_VALUE (root->left->right) ||
4559 !IS_AST_LIT_VALUE (root->right->right))
4562 /* make sure it is the same expression */
4563 if (!isAstEqual (root->left->left,
4567 if (AST_LIT_VALUE (root->left->right) !=
4568 (getSize (TTYPE (root->left->left)) * 4))
4571 if (AST_LIT_VALUE (root->right->right) !=
4572 (getSize (TTYPE (root->left->left)) * 4))
4575 /* make sure the port supports SWAP */
4576 if (port->hasExtBitOp
4577 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4580 /* found it : create the AST */
4581 return newNode (SWAP, root->left->left, NULL);
4585 /* not found return root */
4589 /*-----------------------------------------------------------------*/
4590 /* optimizeCompare - otimizes compares for bit variables */
4591 /*-----------------------------------------------------------------*/
4593 optimizeCompare (ast * root)
4595 ast *optExpr = NULL;
4598 unsigned int litValue;
4600 /* if nothing then return nothing */
4604 /* if not a compare op then do leaves */
4605 if (!IS_COMPARE_OP (root))
4607 root->left = optimizeCompare (root->left);
4608 root->right = optimizeCompare (root->right);
4612 /* if left & right are the same then depending
4613 of the operation do */
4614 if (isAstEqual (root->left, root->right))
4616 switch (root->opval.op)
4621 optExpr = newAst_VALUE (constVal ("0"));
4626 optExpr = newAst_VALUE (constVal ("1"));
4630 return decorateType (optExpr);
4633 vleft = (root->left->type == EX_VALUE ?
4634 root->left->opval.val : NULL);
4636 vright = (root->right->type == EX_VALUE ?
4637 root->right->opval.val : NULL);
4639 /* if left is a BITVAR in BITSPACE */
4640 /* and right is a LITERAL then opt- */
4641 /* imize else do nothing */
4642 if (vleft && vright &&
4643 IS_BITVAR (vleft->etype) &&
4644 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4645 IS_LITERAL (vright->etype))
4648 /* if right side > 1 then comparison may never succeed */
4649 if ((litValue = (int) floatFromVal (vright)) > 1)
4651 werror (W_BAD_COMPARE);
4657 switch (root->opval.op)
4659 case '>': /* bit value greater than 1 cannot be */
4660 werror (W_BAD_COMPARE);
4664 case '<': /* bit value < 1 means 0 */
4666 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4669 case LE_OP: /* bit value <= 1 means no check */
4670 optExpr = newAst_VALUE (vright);
4673 case GE_OP: /* bit value >= 1 means only check for = */
4675 optExpr = newAst_VALUE (vleft);
4680 { /* literal is zero */
4681 switch (root->opval.op)
4683 case '<': /* bit value < 0 cannot be */
4684 werror (W_BAD_COMPARE);
4688 case '>': /* bit value > 0 means 1 */
4690 optExpr = newAst_VALUE (vleft);
4693 case LE_OP: /* bit value <= 0 means no check */
4694 case GE_OP: /* bit value >= 0 means no check */
4695 werror (W_BAD_COMPARE);
4699 case EQ_OP: /* bit == 0 means ! of bit */
4700 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4704 return decorateType (resolveSymbols (optExpr));
4705 } /* end-of-if of BITVAR */
4710 /*-----------------------------------------------------------------*/
4711 /* addSymToBlock : adds the symbol to the first block we find */
4712 /*-----------------------------------------------------------------*/
4714 addSymToBlock (symbol * sym, ast * tree)
4716 /* reached end of tree or a leaf */
4717 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4721 if (IS_AST_OP (tree) &&
4722 tree->opval.op == BLOCK)
4725 symbol *lsym = copySymbol (sym);
4727 lsym->next = AST_VALUES (tree, sym);
4728 AST_VALUES (tree, sym) = lsym;
4732 addSymToBlock (sym, tree->left);
4733 addSymToBlock (sym, tree->right);
4736 /*-----------------------------------------------------------------*/
4737 /* processRegParms - do processing for register parameters */
4738 /*-----------------------------------------------------------------*/
4740 processRegParms (value * args, ast * body)
4744 if (IS_REGPARM (args->etype))
4745 addSymToBlock (args->sym, body);
4750 /*-----------------------------------------------------------------*/
4751 /* resetParmKey - resets the operandkeys for the symbols */
4752 /*-----------------------------------------------------------------*/
4753 DEFSETFUNC (resetParmKey)
4764 /*-----------------------------------------------------------------*/
4765 /* createFunction - This is the key node that calls the iCode for */
4766 /* generating the code for a function. Note code */
4767 /* is generated function by function, later when */
4768 /* add inter-procedural analysis this will change */
4769 /*-----------------------------------------------------------------*/
4771 createFunction (symbol * name, ast * body)
4777 iCode *piCode = NULL;
4779 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4780 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4782 /* if check function return 0 then some problem */
4783 if (checkFunction (name, NULL) == 0)
4786 /* create a dummy block if none exists */
4788 body = newNode (BLOCK, NULL, NULL);
4792 /* check if the function name already in the symbol table */
4793 if ((csym = findSym (SymbolTab, NULL, name->name)))
4796 /* special case for compiler defined functions
4797 we need to add the name to the publics list : this
4798 actually means we are now compiling the compiler
4802 addSet (&publics, name);
4808 allocVariables (name);
4810 name->lastLine = mylineno;
4813 /* set the stack pointer */
4814 /* PENDING: check this for the mcs51 */
4815 stackPtr = -port->stack.direction * port->stack.call_overhead;
4816 if (IFFUNC_ISISR (name->type))
4817 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4818 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4819 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4821 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4823 fetype = getSpec (name->type); /* get the specifier for the function */
4824 /* if this is a reentrant function then */
4825 if (IFFUNC_ISREENT (name->type))
4828 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4830 /* do processing for parameters that are passed in registers */
4831 processRegParms (FUNC_ARGS(name->type), body);
4833 /* set the stack pointer */
4837 /* allocate & autoinit the block variables */
4838 processBlockVars (body, &stack, ALLOCATE);
4840 /* save the stack information */
4841 if (options.useXstack)
4842 name->xstack = SPEC_STAK (fetype) = stack;
4844 name->stack = SPEC_STAK (fetype) = stack;
4846 /* name needs to be mangled */
4847 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4849 body = resolveSymbols (body); /* resolve the symbols */
4850 body = decorateType (body); /* propagateType & do semantic checks */
4852 ex = newAst_VALUE (symbolVal (name)); /* create name */
4853 ex = newNode (FUNCTION, ex, body);
4854 ex->values.args = FUNC_ARGS(name->type);
4856 if (options.dump_tree) PA(ex);
4859 werror (E_FUNC_NO_CODE, name->name);
4863 /* create the node & generate intermediate code */
4865 codeOutFile = code->oFile;
4866 piCode = iCodeFromAst (ex);
4870 werror (E_FUNC_NO_CODE, name->name);
4874 eBBlockFromiCode (piCode);
4876 /* if there are any statics then do them */
4879 GcurMemmap = statsg;
4880 codeOutFile = statsg->oFile;
4881 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4887 /* dealloc the block variables */
4888 processBlockVars (body, &stack, DEALLOCATE);
4889 outputDebugStackSymbols();
4890 /* deallocate paramaters */
4891 deallocParms (FUNC_ARGS(name->type));
4893 if (IFFUNC_ISREENT (name->type))
4896 /* we are done freeup memory & cleanup */
4898 if (port->reset_labelKey) labelKey = 1;
4900 FUNC_HASBODY(name->type) = 1;
4901 addSet (&operKeyReset, name);
4902 applyToSet (operKeyReset, resetParmKey);
4907 cleanUpLevel (LabelTab, 0);
4908 cleanUpBlock (StructTab, 1);
4909 cleanUpBlock (TypedefTab, 1);
4911 xstack->syms = NULL;
4912 istack->syms = NULL;
4917 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4918 /*-----------------------------------------------------------------*/
4919 /* ast_print : prints the ast (for debugging purposes) */
4920 /*-----------------------------------------------------------------*/
4922 void ast_print (ast * tree, FILE *outfile, int indent)
4927 /* can print only decorated trees */
4928 if (!tree->decorated) return;
4930 /* if any child is an error | this one is an error do nothing */
4931 if (tree->isError ||
4932 (tree->left && tree->left->isError) ||
4933 (tree->right && tree->right->isError)) {
4934 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4938 /* print the line */
4939 /* if not block & function */
4940 if (tree->type == EX_OP &&
4941 (tree->opval.op != FUNCTION &&
4942 tree->opval.op != BLOCK &&
4943 tree->opval.op != NULLOP)) {
4946 if (tree->opval.op == FUNCTION) {
4948 value *args=FUNC_ARGS(tree->left->opval.val->type);
4949 fprintf(outfile,"FUNCTION (%s=%p) type (",
4950 tree->left->opval.val->name, tree);
4951 printTypeChain (tree->left->opval.val->type->next,outfile);
4952 fprintf(outfile,") args (");
4955 fprintf (outfile, ", ");
4957 printTypeChain (args ? args->type : NULL, outfile);
4959 args= args ? args->next : NULL;
4961 fprintf(outfile,")\n");
4962 ast_print(tree->left,outfile,indent);
4963 ast_print(tree->right,outfile,indent);
4966 if (tree->opval.op == BLOCK) {
4967 symbol *decls = tree->values.sym;
4968 INDENT(indent,outfile);
4969 fprintf(outfile,"{\n");
4971 INDENT(indent+2,outfile);
4972 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4973 decls->name, decls);
4974 printTypeChain(decls->type,outfile);
4975 fprintf(outfile,")\n");
4977 decls = decls->next;
4979 ast_print(tree->right,outfile,indent+2);
4980 INDENT(indent,outfile);
4981 fprintf(outfile,"}\n");
4984 if (tree->opval.op == NULLOP) {
4985 ast_print(tree->left,outfile,indent);
4986 ast_print(tree->right,outfile,indent);
4989 INDENT(indent,outfile);
4991 /*------------------------------------------------------------------*/
4992 /*----------------------------*/
4993 /* leaf has been reached */
4994 /*----------------------------*/
4995 /* if this is of type value */
4996 /* just get the type */
4997 if (tree->type == EX_VALUE) {
4999 if (IS_LITERAL (tree->opval.val->etype)) {
5000 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5001 if (SPEC_USIGN (tree->opval.val->etype))
5002 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5004 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5005 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5006 floatFromVal(tree->opval.val));
5007 } else if (tree->opval.val->sym) {
5008 /* if the undefined flag is set then give error message */
5009 if (tree->opval.val->sym->undefined) {
5010 fprintf(outfile,"UNDEFINED SYMBOL ");
5012 fprintf(outfile,"SYMBOL ");
5014 fprintf(outfile,"(%s=%p)",
5015 tree->opval.val->sym->name,tree);
5018 fprintf(outfile," type (");
5019 printTypeChain(tree->ftype,outfile);
5020 fprintf(outfile,")\n");
5022 fprintf(outfile,"\n");
5027 /* if type link for the case of cast */
5028 if (tree->type == EX_LINK) {
5029 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5030 printTypeChain(tree->opval.lnk,outfile);
5031 fprintf(outfile,")\n");
5036 /* depending on type of operator do */
5038 switch (tree->opval.op) {
5039 /*------------------------------------------------------------------*/
5040 /*----------------------------*/
5042 /*----------------------------*/
5044 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5045 printTypeChain(tree->ftype,outfile);
5046 fprintf(outfile,")\n");
5047 ast_print(tree->left,outfile,indent+2);
5048 ast_print(tree->right,outfile,indent+2);
5051 /*------------------------------------------------------------------*/
5052 /*----------------------------*/
5054 /*----------------------------*/
5056 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5057 printTypeChain(tree->ftype,outfile);
5058 fprintf(outfile,")\n");
5059 ast_print(tree->left,outfile,indent+2);
5060 ast_print(tree->right,outfile,indent+2);
5063 /*------------------------------------------------------------------*/
5064 /*----------------------------*/
5065 /* struct/union pointer */
5066 /*----------------------------*/
5068 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5069 printTypeChain(tree->ftype,outfile);
5070 fprintf(outfile,")\n");
5071 ast_print(tree->left,outfile,indent+2);
5072 ast_print(tree->right,outfile,indent+2);
5075 /*------------------------------------------------------------------*/
5076 /*----------------------------*/
5077 /* ++/-- operation */
5078 /*----------------------------*/
5081 fprintf(outfile,"post-");
5083 fprintf(outfile,"pre-");
5084 fprintf(outfile,"INC_OP (%p) type (",tree);
5085 printTypeChain(tree->ftype,outfile);
5086 fprintf(outfile,")\n");
5087 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5088 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5093 fprintf(outfile,"post-");
5095 fprintf(outfile,"pre-");
5096 fprintf(outfile,"DEC_OP (%p) type (",tree);
5097 printTypeChain(tree->ftype,outfile);
5098 fprintf(outfile,")\n");
5099 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5100 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5103 /*------------------------------------------------------------------*/
5104 /*----------------------------*/
5106 /*----------------------------*/
5109 fprintf(outfile,"& (%p) type (",tree);
5110 printTypeChain(tree->ftype,outfile);
5111 fprintf(outfile,")\n");
5112 ast_print(tree->left,outfile,indent+2);
5113 ast_print(tree->right,outfile,indent+2);
5115 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5116 printTypeChain(tree->ftype,outfile);
5117 fprintf(outfile,")\n");
5118 ast_print(tree->left,outfile,indent+2);
5119 ast_print(tree->right,outfile,indent+2);
5122 /*----------------------------*/
5124 /*----------------------------*/
5126 fprintf(outfile,"OR (%p) type (",tree);
5127 printTypeChain(tree->ftype,outfile);
5128 fprintf(outfile,")\n");
5129 ast_print(tree->left,outfile,indent+2);
5130 ast_print(tree->right,outfile,indent+2);
5132 /*------------------------------------------------------------------*/
5133 /*----------------------------*/
5135 /*----------------------------*/
5137 fprintf(outfile,"XOR (%p) type (",tree);
5138 printTypeChain(tree->ftype,outfile);
5139 fprintf(outfile,")\n");
5140 ast_print(tree->left,outfile,indent+2);
5141 ast_print(tree->right,outfile,indent+2);
5144 /*------------------------------------------------------------------*/
5145 /*----------------------------*/
5147 /*----------------------------*/
5149 fprintf(outfile,"DIV (%p) type (",tree);
5150 printTypeChain(tree->ftype,outfile);
5151 fprintf(outfile,")\n");
5152 ast_print(tree->left,outfile,indent+2);
5153 ast_print(tree->right,outfile,indent+2);
5155 /*------------------------------------------------------------------*/
5156 /*----------------------------*/
5158 /*----------------------------*/
5160 fprintf(outfile,"MOD (%p) type (",tree);
5161 printTypeChain(tree->ftype,outfile);
5162 fprintf(outfile,")\n");
5163 ast_print(tree->left,outfile,indent+2);
5164 ast_print(tree->right,outfile,indent+2);
5167 /*------------------------------------------------------------------*/
5168 /*----------------------------*/
5169 /* address dereference */
5170 /*----------------------------*/
5171 case '*': /* can be unary : if right is null then unary operation */
5173 fprintf(outfile,"DEREF (%p) type (",tree);
5174 printTypeChain(tree->ftype,outfile);
5175 fprintf(outfile,")\n");
5176 ast_print(tree->left,outfile,indent+2);
5179 /*------------------------------------------------------------------*/
5180 /*----------------------------*/
5181 /* multiplication */
5182 /*----------------------------*/
5183 fprintf(outfile,"MULT (%p) type (",tree);
5184 printTypeChain(tree->ftype,outfile);
5185 fprintf(outfile,")\n");
5186 ast_print(tree->left,outfile,indent+2);
5187 ast_print(tree->right,outfile,indent+2);
5191 /*------------------------------------------------------------------*/
5192 /*----------------------------*/
5193 /* unary '+' operator */
5194 /*----------------------------*/
5198 fprintf(outfile,"UPLUS (%p) type (",tree);
5199 printTypeChain(tree->ftype,outfile);
5200 fprintf(outfile,")\n");
5201 ast_print(tree->left,outfile,indent+2);
5203 /*------------------------------------------------------------------*/
5204 /*----------------------------*/
5206 /*----------------------------*/
5207 fprintf(outfile,"ADD (%p) type (",tree);
5208 printTypeChain(tree->ftype,outfile);
5209 fprintf(outfile,")\n");
5210 ast_print(tree->left,outfile,indent+2);
5211 ast_print(tree->right,outfile,indent+2);
5214 /*------------------------------------------------------------------*/
5215 /*----------------------------*/
5217 /*----------------------------*/
5218 case '-': /* can be unary */
5220 fprintf(outfile,"UMINUS (%p) type (",tree);
5221 printTypeChain(tree->ftype,outfile);
5222 fprintf(outfile,")\n");
5223 ast_print(tree->left,outfile,indent+2);
5225 /*------------------------------------------------------------------*/
5226 /*----------------------------*/
5228 /*----------------------------*/
5229 fprintf(outfile,"SUB (%p) type (",tree);
5230 printTypeChain(tree->ftype,outfile);
5231 fprintf(outfile,")\n");
5232 ast_print(tree->left,outfile,indent+2);
5233 ast_print(tree->right,outfile,indent+2);
5236 /*------------------------------------------------------------------*/
5237 /*----------------------------*/
5239 /*----------------------------*/
5241 fprintf(outfile,"COMPL (%p) type (",tree);
5242 printTypeChain(tree->ftype,outfile);
5243 fprintf(outfile,")\n");
5244 ast_print(tree->left,outfile,indent+2);
5246 /*------------------------------------------------------------------*/
5247 /*----------------------------*/
5249 /*----------------------------*/
5251 fprintf(outfile,"NOT (%p) type (",tree);
5252 printTypeChain(tree->ftype,outfile);
5253 fprintf(outfile,")\n");
5254 ast_print(tree->left,outfile,indent+2);
5256 /*------------------------------------------------------------------*/
5257 /*----------------------------*/
5259 /*----------------------------*/
5261 fprintf(outfile,"RRC (%p) type (",tree);
5262 printTypeChain(tree->ftype,outfile);
5263 fprintf(outfile,")\n");
5264 ast_print(tree->left,outfile,indent+2);
5268 fprintf(outfile,"RLC (%p) type (",tree);
5269 printTypeChain(tree->ftype,outfile);
5270 fprintf(outfile,")\n");
5271 ast_print(tree->left,outfile,indent+2);
5274 fprintf(outfile,"SWAP (%p) type (",tree);
5275 printTypeChain(tree->ftype,outfile);
5276 fprintf(outfile,")\n");
5277 ast_print(tree->left,outfile,indent+2);
5280 fprintf(outfile,"GETHBIT (%p) type (",tree);
5281 printTypeChain(tree->ftype,outfile);
5282 fprintf(outfile,")\n");
5283 ast_print(tree->left,outfile,indent+2);
5286 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5287 printTypeChain(tree->ftype,outfile);
5288 fprintf(outfile,")\n");
5289 ast_print(tree->left,outfile,indent+2);
5290 ast_print(tree->right,outfile,indent+2);
5293 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5294 printTypeChain(tree->ftype,outfile);
5295 fprintf(outfile,")\n");
5296 ast_print(tree->left,outfile,indent+2);
5297 ast_print(tree->right,outfile,indent+2);
5299 /*------------------------------------------------------------------*/
5300 /*----------------------------*/
5302 /*----------------------------*/
5303 case CAST: /* change the type */
5304 fprintf(outfile,"CAST (%p) from type (",tree);
5305 printTypeChain(tree->right->ftype,outfile);
5306 fprintf(outfile,") to type (");
5307 printTypeChain(tree->ftype,outfile);
5308 fprintf(outfile,")\n");
5309 ast_print(tree->right,outfile,indent+2);
5313 fprintf(outfile,"ANDAND (%p) type (",tree);
5314 printTypeChain(tree->ftype,outfile);
5315 fprintf(outfile,")\n");
5316 ast_print(tree->left,outfile,indent+2);
5317 ast_print(tree->right,outfile,indent+2);
5320 fprintf(outfile,"OROR (%p) type (",tree);
5321 printTypeChain(tree->ftype,outfile);
5322 fprintf(outfile,")\n");
5323 ast_print(tree->left,outfile,indent+2);
5324 ast_print(tree->right,outfile,indent+2);
5327 /*------------------------------------------------------------------*/
5328 /*----------------------------*/
5329 /* comparison operators */
5330 /*----------------------------*/
5332 fprintf(outfile,"GT(>) (%p) type (",tree);
5333 printTypeChain(tree->ftype,outfile);
5334 fprintf(outfile,")\n");
5335 ast_print(tree->left,outfile,indent+2);
5336 ast_print(tree->right,outfile,indent+2);
5339 fprintf(outfile,"LT(<) (%p) type (",tree);
5340 printTypeChain(tree->ftype,outfile);
5341 fprintf(outfile,")\n");
5342 ast_print(tree->left,outfile,indent+2);
5343 ast_print(tree->right,outfile,indent+2);
5346 fprintf(outfile,"LE(<=) (%p) type (",tree);
5347 printTypeChain(tree->ftype,outfile);
5348 fprintf(outfile,")\n");
5349 ast_print(tree->left,outfile,indent+2);
5350 ast_print(tree->right,outfile,indent+2);
5353 fprintf(outfile,"GE(>=) (%p) type (",tree);
5354 printTypeChain(tree->ftype,outfile);
5355 fprintf(outfile,")\n");
5356 ast_print(tree->left,outfile,indent+2);
5357 ast_print(tree->right,outfile,indent+2);
5360 fprintf(outfile,"EQ(==) (%p) type (",tree);
5361 printTypeChain(tree->ftype,outfile);
5362 fprintf(outfile,")\n");
5363 ast_print(tree->left,outfile,indent+2);
5364 ast_print(tree->right,outfile,indent+2);
5367 fprintf(outfile,"NE(!=) (%p) type (",tree);
5368 printTypeChain(tree->ftype,outfile);
5369 fprintf(outfile,")\n");
5370 ast_print(tree->left,outfile,indent+2);
5371 ast_print(tree->right,outfile,indent+2);
5372 /*------------------------------------------------------------------*/
5373 /*----------------------------*/
5375 /*----------------------------*/
5376 case SIZEOF: /* evaluate wihout code generation */
5377 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5380 /*------------------------------------------------------------------*/
5381 /*----------------------------*/
5382 /* conditional operator '?' */
5383 /*----------------------------*/
5385 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5386 printTypeChain(tree->ftype,outfile);
5387 fprintf(outfile,")\n");
5388 ast_print(tree->left,outfile,indent+2);
5389 ast_print(tree->right,outfile,indent+2);
5393 fprintf(outfile,"COLON(:) (%p) type (",tree);
5394 printTypeChain(tree->ftype,outfile);
5395 fprintf(outfile,")\n");
5396 ast_print(tree->left,outfile,indent+2);
5397 ast_print(tree->right,outfile,indent+2);
5400 /*------------------------------------------------------------------*/
5401 /*----------------------------*/
5402 /* assignment operators */
5403 /*----------------------------*/
5405 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5406 printTypeChain(tree->ftype,outfile);
5407 fprintf(outfile,")\n");
5408 ast_print(tree->left,outfile,indent+2);
5409 ast_print(tree->right,outfile,indent+2);
5412 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5413 printTypeChain(tree->ftype,outfile);
5414 fprintf(outfile,")\n");
5415 ast_print(tree->left,outfile,indent+2);
5416 ast_print(tree->right,outfile,indent+2);
5419 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5420 printTypeChain(tree->ftype,outfile);
5421 fprintf(outfile,")\n");
5422 ast_print(tree->left,outfile,indent+2);
5423 ast_print(tree->right,outfile,indent+2);
5426 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5427 printTypeChain(tree->ftype,outfile);
5428 fprintf(outfile,")\n");
5429 ast_print(tree->left,outfile,indent+2);
5430 ast_print(tree->right,outfile,indent+2);
5433 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5434 printTypeChain(tree->ftype,outfile);
5435 fprintf(outfile,")\n");
5436 ast_print(tree->left,outfile,indent+2);
5437 ast_print(tree->right,outfile,indent+2);
5440 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5441 printTypeChain(tree->ftype,outfile);
5442 fprintf(outfile,")\n");
5443 ast_print(tree->left,outfile,indent+2);
5444 ast_print(tree->right,outfile,indent+2);
5447 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5448 printTypeChain(tree->ftype,outfile);
5449 fprintf(outfile,")\n");
5450 ast_print(tree->left,outfile,indent+2);
5451 ast_print(tree->right,outfile,indent+2);
5453 /*------------------------------------------------------------------*/
5454 /*----------------------------*/
5456 /*----------------------------*/
5458 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5459 printTypeChain(tree->ftype,outfile);
5460 fprintf(outfile,")\n");
5461 ast_print(tree->left,outfile,indent+2);
5462 ast_print(tree->right,outfile,indent+2);
5464 /*------------------------------------------------------------------*/
5465 /*----------------------------*/
5467 /*----------------------------*/
5469 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5470 printTypeChain(tree->ftype,outfile);
5471 fprintf(outfile,")\n");
5472 ast_print(tree->left,outfile,indent+2);
5473 ast_print(tree->right,outfile,indent+2);
5475 /*------------------------------------------------------------------*/
5476 /*----------------------------*/
5477 /* straight assignemnt */
5478 /*----------------------------*/
5480 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5481 printTypeChain(tree->ftype,outfile);
5482 fprintf(outfile,")\n");
5483 ast_print(tree->left,outfile,indent+2);
5484 ast_print(tree->right,outfile,indent+2);
5486 /*------------------------------------------------------------------*/
5487 /*----------------------------*/
5488 /* comma operator */
5489 /*----------------------------*/
5491 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5492 printTypeChain(tree->ftype,outfile);
5493 fprintf(outfile,")\n");
5494 ast_print(tree->left,outfile,indent+2);
5495 ast_print(tree->right,outfile,indent+2);
5497 /*------------------------------------------------------------------*/
5498 /*----------------------------*/
5500 /*----------------------------*/
5503 fprintf(outfile,"CALL (%p) type (",tree);
5504 printTypeChain(tree->ftype,outfile);
5505 fprintf(outfile,")\n");
5506 ast_print(tree->left,outfile,indent+2);
5507 ast_print(tree->right,outfile,indent+2);
5510 fprintf(outfile,"PARMS\n");
5511 ast_print(tree->left,outfile,indent+2);
5512 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5513 ast_print(tree->right,outfile,indent+2);
5516 /*------------------------------------------------------------------*/
5517 /*----------------------------*/
5518 /* return statement */
5519 /*----------------------------*/
5521 fprintf(outfile,"RETURN (%p) type (",tree);
5523 printTypeChain(tree->right->ftype,outfile);
5525 fprintf(outfile,")\n");
5526 ast_print(tree->right,outfile,indent+2);
5528 /*------------------------------------------------------------------*/
5529 /*----------------------------*/
5530 /* label statement */
5531 /*----------------------------*/
5533 fprintf(outfile,"LABEL (%p)\n",tree);
5534 ast_print(tree->left,outfile,indent+2);
5535 ast_print(tree->right,outfile,indent);
5537 /*------------------------------------------------------------------*/
5538 /*----------------------------*/
5539 /* switch statement */
5540 /*----------------------------*/
5544 fprintf(outfile,"SWITCH (%p) ",tree);
5545 ast_print(tree->left,outfile,0);
5546 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5547 INDENT(indent+2,outfile);
5548 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5549 (int) floatFromVal(val),
5550 tree->values.switchVals.swNum,
5551 (int) floatFromVal(val));
5553 ast_print(tree->right,outfile,indent);
5556 /*------------------------------------------------------------------*/
5557 /*----------------------------*/
5559 /*----------------------------*/
5561 fprintf(outfile,"IF (%p) \n",tree);
5562 ast_print(tree->left,outfile,indent+2);
5563 if (tree->trueLabel) {
5564 INDENT(indent+2,outfile);
5565 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5567 if (tree->falseLabel) {
5568 INDENT(indent+2,outfile);
5569 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5571 ast_print(tree->right,outfile,indent+2);
5573 /*----------------------------*/
5574 /* goto Statement */
5575 /*----------------------------*/
5577 fprintf(outfile,"GOTO (%p) \n",tree);
5578 ast_print(tree->left,outfile,indent+2);
5579 fprintf(outfile,"\n");
5581 /*------------------------------------------------------------------*/
5582 /*----------------------------*/
5584 /*----------------------------*/
5586 fprintf(outfile,"FOR (%p) \n",tree);
5587 if (AST_FOR( tree, initExpr)) {
5588 INDENT(indent+2,outfile);
5589 fprintf(outfile,"INIT EXPR ");
5590 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5592 if (AST_FOR( tree, condExpr)) {
5593 INDENT(indent+2,outfile);
5594 fprintf(outfile,"COND EXPR ");
5595 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5597 if (AST_FOR( tree, loopExpr)) {
5598 INDENT(indent+2,outfile);
5599 fprintf(outfile,"LOOP EXPR ");
5600 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5602 fprintf(outfile,"FOR LOOP BODY \n");
5603 ast_print(tree->left,outfile,indent+2);
5606 fprintf(outfile,"CRITICAL (%p) \n",tree);
5607 ast_print(tree->left,outfile,indent+2);
5615 ast_print(t,stdout,0);