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)) {
2171 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2174 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2177 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2180 SPEC_SCLS (TETYPE (tree)) = 0;
2183 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2186 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2189 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2192 SPEC_SCLS (TETYPE (tree)) = 0;
2199 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2200 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2202 /* If defined struct type at addr var
2203 then rewrite (&struct var)->member
2205 and define membertype at (addr+offsetof(struct var,member)) temp
2208 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2209 AST_SYMBOL(tree->right));
2211 sym = newSymbol(genSymName (0), 0);
2212 sym->type = TTYPE (tree);
2213 sym->etype = getSpec(sym->type);
2214 sym->lineDef = tree->lineno;
2217 SPEC_STAT (sym->etype) = 1;
2218 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2220 SPEC_ABSA(sym->etype) = 1;
2221 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2224 AST_VALUE (tree) = symbolVal(sym);
2227 tree->type = EX_VALUE;
2234 /*------------------------------------------------------------------*/
2235 /*----------------------------*/
2236 /* ++/-- operation */
2237 /*----------------------------*/
2241 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2242 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2243 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2244 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2253 /*------------------------------------------------------------------*/
2254 /*----------------------------*/
2256 /*----------------------------*/
2257 case '&': /* can be unary */
2258 /* if right is NULL then unary operation */
2259 if (tree->right) /* not an unary operation */
2262 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2264 werror (E_BITWISE_OP);
2265 werror (W_CONTINUE, "left & right types are ");
2266 printTypeChain (LTYPE (tree), stderr);
2267 fprintf (stderr, ",");
2268 printTypeChain (RTYPE (tree), stderr);
2269 fprintf (stderr, "\n");
2270 goto errorTreeReturn;
2273 /* if they are both literal */
2274 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2276 tree->type = EX_VALUE;
2277 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2278 valFromType (RETYPE (tree)), '&');
2280 tree->right = tree->left = NULL;
2281 TETYPE (tree) = tree->opval.val->etype;
2282 TTYPE (tree) = tree->opval.val->type;
2286 /* see if this is a GETHBIT operation if yes
2289 ast *otree = optimizeGetHbit (tree);
2292 return decorateType (otree);
2296 computeType (LTYPE (tree), RTYPE (tree));
2297 TETYPE (tree) = getSpec (TTYPE (tree));
2299 /* if left is a literal exchange left & right */
2300 if (IS_LITERAL (LTYPE (tree)))
2302 ast *tTree = tree->left;
2303 tree->left = tree->right;
2304 tree->right = tTree;
2307 /* if right is a literal and */
2308 /* we can find a 2nd literal in a and-tree then */
2309 /* rearrange the tree */
2310 if (IS_LITERAL (RTYPE (tree)))
2313 ast *litTree = searchLitOp (tree, &parent, "&");
2316 ast *tTree = litTree->left;
2317 litTree->left = tree->right;
2318 tree->right = tTree;
2319 /* both operands in tTree are literal now */
2320 decorateType (parent);
2324 LRVAL (tree) = RRVAL (tree) = 1;
2328 /*------------------------------------------------------------------*/
2329 /*----------------------------*/
2331 /*----------------------------*/
2332 p = newLink (DECLARATOR);
2333 /* if bit field then error */
2334 if (IS_BITVAR (tree->left->etype))
2336 werror (E_ILLEGAL_ADDR, "address of bit variable");
2337 goto errorTreeReturn;
2340 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2342 werror (E_ILLEGAL_ADDR, "address of register variable");
2343 goto errorTreeReturn;
2346 if (IS_FUNC (LTYPE (tree)))
2348 // this ought to be ignored
2349 return (tree->left);
2352 if (IS_LITERAL(LTYPE(tree)))
2354 werror (E_ILLEGAL_ADDR, "address of literal");
2355 goto errorTreeReturn;
2360 werror (E_LVALUE_REQUIRED, "address of");
2361 goto errorTreeReturn;
2363 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2364 DCL_TYPE (p) = CPOINTER;
2365 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2366 DCL_TYPE (p) = FPOINTER;
2367 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2368 DCL_TYPE (p) = PPOINTER;
2369 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2370 DCL_TYPE (p) = IPOINTER;
2371 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2372 DCL_TYPE (p) = EEPPOINTER;
2373 else if (SPEC_OCLS(tree->left->etype))
2374 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2376 DCL_TYPE (p) = POINTER;
2378 if (IS_AST_SYM_VALUE (tree->left))
2380 AST_SYMBOL (tree->left)->addrtaken = 1;
2381 AST_SYMBOL (tree->left)->allocreq = 1;
2384 p->next = LTYPE (tree);
2386 TETYPE (tree) = getSpec (TTYPE (tree));
2391 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2392 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2394 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2395 AST_SYMBOL(tree->left->right));
2396 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2397 valueFromLit(element->offset));
2400 tree->type = EX_VALUE;
2401 tree->values.literalFromCast = 1;
2407 /*------------------------------------------------------------------*/
2408 /*----------------------------*/
2410 /*----------------------------*/
2412 /* if the rewrite succeeds then don't go any furthur */
2414 ast *wtree = optimizeRRCRLC (tree);
2416 return decorateType (wtree);
2418 wtree = optimizeSWAP (tree);
2420 return decorateType (wtree);
2425 /* if left is a literal exchange left & right */
2426 if (IS_LITERAL (LTYPE (tree)))
2428 ast *tTree = tree->left;
2429 tree->left = tree->right;
2430 tree->right = tTree;
2433 /* if right is a literal and */
2434 /* we can find a 2nd literal in a or-tree then */
2435 /* rearrange the tree */
2436 if (IS_LITERAL (RTYPE (tree)))
2439 ast *litTree = searchLitOp (tree, &parent, "|");
2442 ast *tTree = litTree->left;
2443 litTree->left = tree->right;
2444 tree->right = tTree;
2445 /* both operands in tTree are literal now */
2446 decorateType (parent);
2449 /*------------------------------------------------------------------*/
2450 /*----------------------------*/
2452 /*----------------------------*/
2454 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2456 werror (E_BITWISE_OP);
2457 werror (W_CONTINUE, "left & right types are ");
2458 printTypeChain (LTYPE (tree), stderr);
2459 fprintf (stderr, ",");
2460 printTypeChain (RTYPE (tree), stderr);
2461 fprintf (stderr, "\n");
2462 goto errorTreeReturn;
2465 /* if they are both literal then */
2466 /* rewrite the tree */
2467 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2469 tree->type = EX_VALUE;
2470 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2471 valFromType (RETYPE (tree)),
2473 tree->right = tree->left = NULL;
2474 TETYPE (tree) = tree->opval.val->etype;
2475 TTYPE (tree) = tree->opval.val->type;
2479 /* if left is a literal exchange left & right */
2480 if (IS_LITERAL (LTYPE (tree)))
2482 ast *tTree = tree->left;
2483 tree->left = tree->right;
2484 tree->right = tTree;
2487 /* if right is a literal and */
2488 /* we can find a 2nd literal in a xor-tree then */
2489 /* rearrange the tree */
2490 if (IS_LITERAL (RTYPE (tree)))
2493 ast *litTree = searchLitOp (tree, &parent, "^");
2496 ast *tTree = litTree->left;
2497 litTree->left = tree->right;
2498 tree->right = tTree;
2499 /* both operands in litTree are literal now */
2500 decorateType (parent);
2504 LRVAL (tree) = RRVAL (tree) = 1;
2505 TETYPE (tree) = getSpec (TTYPE (tree) =
2506 computeType (LTYPE (tree),
2509 /*------------------------------------------------------------------*/
2510 /*----------------------------*/
2512 /*----------------------------*/
2514 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2516 werror (E_INVALID_OP, "divide");
2517 goto errorTreeReturn;
2519 /* if they are both literal then */
2520 /* rewrite the tree */
2521 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2523 tree->type = EX_VALUE;
2524 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2525 valFromType (RETYPE (tree)));
2526 tree->right = tree->left = NULL;
2527 TETYPE (tree) = getSpec (TTYPE (tree) =
2528 tree->opval.val->type);
2532 LRVAL (tree) = RRVAL (tree) = 1;
2533 TETYPE (tree) = getSpec (TTYPE (tree) =
2534 computeType (LTYPE (tree),
2537 /* if right is a literal and */
2538 /* left is also a division by a literal then */
2539 /* rearrange the tree */
2540 if (IS_LITERAL (RTYPE (tree))
2541 /* avoid infinite loop */
2542 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2545 ast *litTree = searchLitOp (tree, &parent, "/");
2548 if (IS_LITERAL (RTYPE (litTree)))
2551 litTree->right = newNode ('*', litTree->right, tree->right);
2552 litTree->right->lineno = tree->lineno;
2554 tree->right->opval.val = constVal ("1");
2555 decorateType (parent);
2559 /* litTree->left is literal: no gcse possible.
2560 We can't call decorateType(parent), because
2561 this would cause an infinit loop. */
2562 parent->decorated = 1;
2563 decorateType (litTree);
2570 /*------------------------------------------------------------------*/
2571 /*----------------------------*/
2573 /*----------------------------*/
2575 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2577 werror (E_BITWISE_OP);
2578 werror (W_CONTINUE, "left & right types are ");
2579 printTypeChain (LTYPE (tree), stderr);
2580 fprintf (stderr, ",");
2581 printTypeChain (RTYPE (tree), stderr);
2582 fprintf (stderr, "\n");
2583 goto errorTreeReturn;
2585 /* if they are both literal then */
2586 /* rewrite the tree */
2587 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2589 tree->type = EX_VALUE;
2590 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2591 valFromType (RETYPE (tree)));
2592 tree->right = tree->left = NULL;
2593 TETYPE (tree) = getSpec (TTYPE (tree) =
2594 tree->opval.val->type);
2597 LRVAL (tree) = RRVAL (tree) = 1;
2598 TETYPE (tree) = getSpec (TTYPE (tree) =
2599 computeType (LTYPE (tree),
2603 /*------------------------------------------------------------------*/
2604 /*----------------------------*/
2605 /* address dereference */
2606 /*----------------------------*/
2607 case '*': /* can be unary : if right is null then unary operation */
2610 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2612 werror (E_PTR_REQD);
2613 goto errorTreeReturn;
2618 werror (E_LVALUE_REQUIRED, "pointer deref");
2619 goto errorTreeReturn;
2621 if (IS_ADDRESS_OF_OP(tree->left))
2623 /* replace *&obj with obj */
2624 return tree->left->left;
2626 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2627 TETYPE (tree) = getSpec (TTYPE (tree));
2628 /* adjust the storage class */
2629 switch (DCL_TYPE(tree->left->ftype)) {
2631 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2634 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2637 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2640 SPEC_SCLS (TETYPE (tree)) = 0;
2643 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2646 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2649 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2652 SPEC_SCLS (TETYPE (tree)) = 0;
2661 /*------------------------------------------------------------------*/
2662 /*----------------------------*/
2663 /* multiplication */
2664 /*----------------------------*/
2665 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2667 werror (E_INVALID_OP, "multiplication");
2668 goto errorTreeReturn;
2671 /* if they are both literal then */
2672 /* rewrite the tree */
2673 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2675 tree->type = EX_VALUE;
2676 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2677 valFromType (RETYPE (tree)));
2678 tree->right = tree->left = NULL;
2679 TETYPE (tree) = getSpec (TTYPE (tree) =
2680 tree->opval.val->type);
2684 /* if left is a literal exchange left & right */
2685 if (IS_LITERAL (LTYPE (tree)))
2687 ast *tTree = tree->left;
2688 tree->left = tree->right;
2689 tree->right = tTree;
2692 /* if right is a literal and */
2693 /* we can find a 2nd literal in a mul-tree then */
2694 /* rearrange the tree */
2695 if (IS_LITERAL (RTYPE (tree)))
2698 ast *litTree = searchLitOp (tree, &parent, "*");
2701 ast *tTree = litTree->left;
2702 litTree->left = tree->right;
2703 tree->right = tTree;
2704 /* both operands in litTree are literal now */
2705 decorateType (parent);
2709 LRVAL (tree) = RRVAL (tree) = 1;
2710 TETYPE (tree) = getSpec (TTYPE (tree) =
2711 computeType (LTYPE (tree),
2714 /* promote result to int if left & right are char
2715 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2716 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2717 SPEC_NOUN(TETYPE(tree)) = V_INT;
2722 /*------------------------------------------------------------------*/
2723 /*----------------------------*/
2724 /* unary '+' operator */
2725 /*----------------------------*/
2730 if (!IS_INTEGRAL (LTYPE (tree)))
2732 werror (E_UNARY_OP, '+');
2733 goto errorTreeReturn;
2736 /* if left is a literal then do it */
2737 if (IS_LITERAL (LTYPE (tree)))
2739 tree->type = EX_VALUE;
2740 tree->opval.val = valFromType (LETYPE (tree));
2742 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2746 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2750 /*------------------------------------------------------------------*/
2751 /*----------------------------*/
2753 /*----------------------------*/
2755 /* this is not a unary operation */
2756 /* if both pointers then problem */
2757 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2758 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2760 werror (E_PTR_PLUS_PTR);
2761 goto errorTreeReturn;
2764 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2765 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2767 werror (E_PLUS_INVALID, "+");
2768 goto errorTreeReturn;
2771 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2772 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2774 werror (E_PLUS_INVALID, "+");
2775 goto errorTreeReturn;
2777 /* if they are both literal then */
2778 /* rewrite the tree */
2779 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2781 tree->type = EX_VALUE;
2782 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2783 valFromType (RETYPE (tree)));
2784 tree->right = tree->left = NULL;
2785 TETYPE (tree) = getSpec (TTYPE (tree) =
2786 tree->opval.val->type);
2790 /* if the right is a pointer or left is a literal
2791 xchange left & right */
2792 if (IS_ARRAY (RTYPE (tree)) ||
2793 IS_PTR (RTYPE (tree)) ||
2794 IS_LITERAL (LTYPE (tree)))
2796 ast *tTree = tree->left;
2797 tree->left = tree->right;
2798 tree->right = tTree;
2801 /* if right is a literal and */
2802 /* left is also an addition/subtraction with a literal then */
2803 /* rearrange the tree */
2804 if (IS_LITERAL (RTYPE (tree)))
2806 ast *litTree, *parent;
2807 litTree = searchLitOp (tree, &parent, "+-");
2810 if (litTree->opval.op == '+')
2813 ast *tTree = litTree->left;
2814 litTree->left = tree->right;
2815 tree->right = tree->left;
2818 else if (litTree->opval.op == '-')
2820 if (IS_LITERAL (RTYPE (litTree)))
2823 ast *tTree = litTree->left;
2824 litTree->left = tree->right;
2825 tree->right = tTree;
2830 ast *tTree = litTree->right;
2831 litTree->right = tree->right;
2832 tree->right = tTree;
2833 litTree->opval.op = '+';
2834 tree->opval.op = '-';
2837 decorateType (parent);
2841 LRVAL (tree) = RRVAL (tree) = 1;
2842 /* if the left is a pointer */
2843 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2844 TETYPE (tree) = getSpec (TTYPE (tree) =
2847 TETYPE (tree) = getSpec (TTYPE (tree) =
2848 computeType (LTYPE (tree),
2852 /*------------------------------------------------------------------*/
2853 /*----------------------------*/
2855 /*----------------------------*/
2856 case '-': /* can be unary */
2857 /* if right is null then unary */
2861 if (!IS_ARITHMETIC (LTYPE (tree)))
2863 werror (E_UNARY_OP, tree->opval.op);
2864 goto errorTreeReturn;
2867 /* if left is a literal then do it */
2868 if (IS_LITERAL (LTYPE (tree)))
2870 tree->type = EX_VALUE;
2871 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2873 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2874 SPEC_USIGN(TETYPE(tree)) = 0;
2878 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2882 /*------------------------------------------------------------------*/
2883 /*----------------------------*/
2885 /*----------------------------*/
2887 if (!(IS_PTR (LTYPE (tree)) ||
2888 IS_ARRAY (LTYPE (tree)) ||
2889 IS_ARITHMETIC (LTYPE (tree))))
2891 werror (E_PLUS_INVALID, "-");
2892 goto errorTreeReturn;
2895 if (!(IS_PTR (RTYPE (tree)) ||
2896 IS_ARRAY (RTYPE (tree)) ||
2897 IS_ARITHMETIC (RTYPE (tree))))
2899 werror (E_PLUS_INVALID, "-");
2900 goto errorTreeReturn;
2903 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2904 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2905 IS_INTEGRAL (RTYPE (tree))))
2907 werror (E_PLUS_INVALID, "-");
2908 goto errorTreeReturn;
2911 /* if they are both literal then */
2912 /* rewrite the tree */
2913 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2915 tree->type = EX_VALUE;
2916 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2917 valFromType (RETYPE (tree)));
2918 tree->right = tree->left = NULL;
2919 TETYPE (tree) = getSpec (TTYPE (tree) =
2920 tree->opval.val->type);
2924 /* if the left & right are equal then zero */
2925 if (isAstEqual (tree->left, tree->right))
2927 tree->type = EX_VALUE;
2928 tree->left = tree->right = NULL;
2929 tree->opval.val = constVal ("0");
2930 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2934 /* if both of them are pointers or arrays then */
2935 /* the result is going to be an integer */
2936 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2937 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2938 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2940 /* if only the left is a pointer */
2941 /* then result is a pointer */
2942 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2943 TETYPE (tree) = getSpec (TTYPE (tree) =
2946 TETYPE (tree) = getSpec (TTYPE (tree) =
2947 computeType (LTYPE (tree),
2950 LRVAL (tree) = RRVAL (tree) = 1;
2952 /* if right is a literal and */
2953 /* left is also an addition/subtraction with a literal then */
2954 /* rearrange the tree */
2955 if (IS_LITERAL (RTYPE (tree))
2956 /* avoid infinite loop */
2957 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
2959 ast *litTree, *litParent;
2960 litTree = searchLitOp (tree, &litParent, "+-");
2963 if (litTree->opval.op == '+')
2966 litTree->right = newNode ('-', litTree->right, tree->right);
2967 litTree->right->lineno = tree->lineno;
2969 tree->right->opval.val = constVal ("0");
2971 else if (litTree->opval.op == '-')
2973 if (IS_LITERAL (RTYPE (litTree)))
2976 litTree->right = newNode ('+', tree->right, litTree->right);
2977 litTree->right->lineno = tree->lineno;
2979 tree->right->opval.val = constVal ("0");
2984 ast *tTree = litTree->right;
2985 litTree->right = tree->right;
2986 tree->right = tTree;
2989 decorateType (litParent);
2994 /*------------------------------------------------------------------*/
2995 /*----------------------------*/
2997 /*----------------------------*/
2999 /* can be only integral type */
3000 if (!IS_INTEGRAL (LTYPE (tree)))
3002 werror (E_UNARY_OP, tree->opval.op);
3003 goto errorTreeReturn;
3006 /* if left is a literal then do it */
3007 if (IS_LITERAL (LTYPE (tree)))
3009 tree->type = EX_VALUE;
3010 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3012 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3016 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3019 /*------------------------------------------------------------------*/
3020 /*----------------------------*/
3022 /*----------------------------*/
3024 /* can be pointer */
3025 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3026 !IS_PTR (LTYPE (tree)) &&
3027 !IS_ARRAY (LTYPE (tree)))
3029 werror (E_UNARY_OP, tree->opval.op);
3030 goto errorTreeReturn;
3033 /* if left is a literal then do it */
3034 if (IS_LITERAL (LTYPE (tree)))
3036 tree->type = EX_VALUE;
3037 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3039 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3043 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3046 /*------------------------------------------------------------------*/
3047 /*----------------------------*/
3049 /*----------------------------*/
3053 TTYPE (tree) = LTYPE (tree);
3054 TETYPE (tree) = LETYPE (tree);
3058 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3063 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3065 werror (E_SHIFT_OP_INVALID);
3066 werror (W_CONTINUE, "left & right types are ");
3067 printTypeChain (LTYPE (tree), stderr);
3068 fprintf (stderr, ",");
3069 printTypeChain (RTYPE (tree), stderr);
3070 fprintf (stderr, "\n");
3071 goto errorTreeReturn;
3074 /* if they are both literal then */
3075 /* rewrite the tree */
3076 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3078 tree->type = EX_VALUE;
3079 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3080 valFromType (RETYPE (tree)),
3081 (tree->opval.op == LEFT_OP ? 1 : 0));
3082 tree->right = tree->left = NULL;
3083 TETYPE (tree) = getSpec (TTYPE (tree) =
3084 tree->opval.val->type);
3088 /* if only the right side is a literal & we are
3089 shifting more than size of the left operand then zero */
3090 if (IS_LITERAL (RTYPE (tree)) &&
3091 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3092 (getSize (LTYPE (tree)) * 8))
3094 if (tree->opval.op==LEFT_OP ||
3095 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3096 lineno=tree->lineno;
3097 werror (W_SHIFT_CHANGED,
3098 (tree->opval.op == LEFT_OP ? "left" : "right"));
3099 tree->type = EX_VALUE;
3100 tree->left = tree->right = NULL;
3101 tree->opval.val = constVal ("0");
3102 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3106 LRVAL (tree) = RRVAL (tree) = 1;
3107 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3108 if (IS_LITERAL (TTYPE (tree)))
3109 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3112 /*------------------------------------------------------------------*/
3113 /*----------------------------*/
3115 /*----------------------------*/
3116 case CAST: /* change the type */
3117 /* cannot cast to an aggregate type */
3118 if (IS_AGGREGATE (LTYPE (tree)))
3120 werror (E_CAST_ILLEGAL);
3121 goto errorTreeReturn;
3124 /* make sure the type is complete and sane */
3125 checkTypeSanity(LETYPE(tree), "(cast)");
3128 /* if the right is a literal replace the tree */
3129 if (IS_LITERAL (RETYPE (tree))) {
3130 if (!IS_PTR (LTYPE (tree))) {
3131 tree->type = EX_VALUE;
3133 valCastLiteral (LTYPE (tree),
3134 floatFromVal (valFromType (RETYPE (tree))));
3137 TTYPE (tree) = tree->opval.val->type;
3138 tree->values.literalFromCast = 1;
3139 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3140 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3141 sym_link *rest = LTYPE(tree)->next;
3142 werror(W_LITERAL_GENERIC);
3143 TTYPE(tree) = newLink(DECLARATOR);
3144 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3145 TTYPE(tree)->next = rest;
3146 tree->left->opval.lnk = TTYPE(tree);
3149 TTYPE (tree) = LTYPE (tree);
3153 TTYPE (tree) = LTYPE (tree);
3157 #if 0 // this is already checked, now this could be explicit
3158 /* if pointer to struct then check names */
3159 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3160 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3161 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3163 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3164 SPEC_STRUCT(LETYPE(tree))->tag);
3167 if (IS_ADDRESS_OF_OP(tree->right)
3168 && IS_AST_SYM_VALUE (tree->right->left)
3169 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3171 tree->type = EX_VALUE;
3173 valCastLiteral (LTYPE (tree),
3174 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3175 TTYPE (tree) = tree->opval.val->type;
3176 TETYPE (tree) = getSpec (TTYPE (tree));
3179 tree->values.literalFromCast = 1;
3183 /* handle offsetof macro: */
3184 /* #define offsetof(TYPE, MEMBER) \ */
3185 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3186 if (IS_ADDRESS_OF_OP(tree->right)
3187 && IS_AST_OP (tree->right->left)
3188 && tree->right->left->opval.op == PTR_OP
3189 && IS_AST_OP (tree->right->left->left)
3190 && tree->right->left->left->opval.op == CAST
3191 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3193 symbol *element = getStructElement (
3194 SPEC_STRUCT (LETYPE(tree->right->left)),
3195 AST_SYMBOL(tree->right->left->right)
3199 tree->type = EX_VALUE;
3200 tree->opval.val = valCastLiteral (
3203 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3206 TTYPE (tree) = tree->opval.val->type;
3207 TETYPE (tree) = getSpec (TTYPE (tree));
3214 /* if the right is a literal replace the tree */
3215 if (IS_LITERAL (RETYPE (tree))) {
3216 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3217 /* rewrite (type *)litaddr
3219 and define type at litaddr temp
3220 (but only if type's storage class is not generic)
3222 ast *newTree = newNode ('&', NULL, NULL);
3225 TTYPE (newTree) = LTYPE (tree);
3226 TETYPE (newTree) = getSpec(LTYPE (tree));
3228 /* define a global symbol at the casted address*/
3229 sym = newSymbol(genSymName (0), 0);
3230 sym->type = LTYPE (tree)->next;
3232 sym->type = newLink (V_VOID);
3233 sym->etype = getSpec(sym->type);
3234 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3235 sym->lineDef = tree->lineno;
3238 SPEC_STAT (sym->etype) = 1;
3239 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3240 SPEC_ABSA(sym->etype) = 1;
3241 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3244 newTree->left = newAst_VALUE(symbolVal(sym));
3245 newTree->left->lineno = tree->lineno;
3246 LTYPE (newTree) = sym->type;
3247 LETYPE (newTree) = sym->etype;
3248 LLVAL (newTree) = 1;
3249 LRVAL (newTree) = 0;
3250 TLVAL (newTree) = 1;
3253 if (!IS_PTR (LTYPE (tree))) {
3254 tree->type = EX_VALUE;
3256 valCastLiteral (LTYPE (tree),
3257 floatFromVal (valFromType (RETYPE (tree))));
3258 TTYPE (tree) = tree->opval.val->type;
3261 tree->values.literalFromCast = 1;
3262 TETYPE (tree) = getSpec (TTYPE (tree));
3266 TTYPE (tree) = LTYPE (tree);
3270 TETYPE (tree) = getSpec (TTYPE (tree));
3274 /*------------------------------------------------------------------*/
3275 /*----------------------------*/
3276 /* logical &&, || */
3277 /*----------------------------*/
3280 /* each must me arithmetic type or be a pointer */
3281 if (!IS_PTR (LTYPE (tree)) &&
3282 !IS_ARRAY (LTYPE (tree)) &&
3283 !IS_INTEGRAL (LTYPE (tree)))
3285 werror (E_COMPARE_OP);
3286 goto errorTreeReturn;
3289 if (!IS_PTR (RTYPE (tree)) &&
3290 !IS_ARRAY (RTYPE (tree)) &&
3291 !IS_INTEGRAL (RTYPE (tree)))
3293 werror (E_COMPARE_OP);
3294 goto errorTreeReturn;
3296 /* if they are both literal then */
3297 /* rewrite the tree */
3298 if (IS_LITERAL (RTYPE (tree)) &&
3299 IS_LITERAL (LTYPE (tree)))
3301 tree->type = EX_VALUE;
3302 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3303 valFromType (RETYPE (tree)),
3305 tree->right = tree->left = NULL;
3306 TETYPE (tree) = getSpec (TTYPE (tree) =
3307 tree->opval.val->type);
3310 LRVAL (tree) = RRVAL (tree) = 1;
3311 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3314 /*------------------------------------------------------------------*/
3315 /*----------------------------*/
3316 /* comparison operators */
3317 /*----------------------------*/
3325 ast *lt = optimizeCompare (tree);
3331 /* if they are pointers they must be castable */
3332 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3334 if (tree->opval.op==EQ_OP &&
3335 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3336 // we cannot cast a gptr to a !gptr: switch the leaves
3337 struct ast *s=tree->left;
3338 tree->left=tree->right;
3341 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3343 werror (E_COMPARE_OP);
3344 fprintf (stderr, "comparring type ");
3345 printTypeChain (LTYPE (tree), stderr);
3346 fprintf (stderr, "to type ");
3347 printTypeChain (RTYPE (tree), stderr);
3348 fprintf (stderr, "\n");
3349 goto errorTreeReturn;
3352 /* else they should be promotable to one another */
3355 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3356 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3358 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3360 werror (E_COMPARE_OP);
3361 fprintf (stderr, "comparing type ");
3362 printTypeChain (LTYPE (tree), stderr);
3363 fprintf (stderr, "to type ");
3364 printTypeChain (RTYPE (tree), stderr);
3365 fprintf (stderr, "\n");
3366 goto errorTreeReturn;
3369 /* if unsigned value < 0 then always false */
3370 /* if (unsigned value) > 0 then (unsigned value) */
3371 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3372 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3374 if (tree->opval.op == '<') {
3377 if (tree->opval.op == '>') {
3381 /* if they are both literal then */
3382 /* rewrite the tree */
3383 if (IS_LITERAL (RTYPE (tree)) &&
3384 IS_LITERAL (LTYPE (tree)))
3386 tree->type = EX_VALUE;
3387 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3388 valFromType (RETYPE (tree)),
3390 tree->right = tree->left = NULL;
3391 TETYPE (tree) = getSpec (TTYPE (tree) =
3392 tree->opval.val->type);
3395 LRVAL (tree) = RRVAL (tree) = 1;
3396 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3399 /*------------------------------------------------------------------*/
3400 /*----------------------------*/
3402 /*----------------------------*/
3403 case SIZEOF: /* evaluate wihout code generation */
3404 /* change the type to a integer */
3405 tree->type = EX_VALUE;
3406 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3407 tree->opval.val = constVal (buffer);
3408 tree->right = tree->left = NULL;
3409 TETYPE (tree) = getSpec (TTYPE (tree) =
3410 tree->opval.val->type);
3413 /*------------------------------------------------------------------*/
3414 /*----------------------------*/
3416 /*----------------------------*/
3418 /* return typeof enum value */
3419 tree->type = EX_VALUE;
3422 if (IS_SPEC(tree->right->ftype)) {
3423 switch (SPEC_NOUN(tree->right->ftype)) {
3425 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3426 else typeofv = TYPEOF_INT;
3429 typeofv = TYPEOF_FLOAT;
3432 typeofv = TYPEOF_CHAR;
3435 typeofv = TYPEOF_VOID;
3438 typeofv = TYPEOF_STRUCT;
3441 typeofv = TYPEOF_BITFIELD;
3444 typeofv = TYPEOF_BIT;
3447 typeofv = TYPEOF_SBIT;
3453 switch (DCL_TYPE(tree->right->ftype)) {
3455 typeofv = TYPEOF_POINTER;
3458 typeofv = TYPEOF_FPOINTER;
3461 typeofv = TYPEOF_CPOINTER;
3464 typeofv = TYPEOF_GPOINTER;
3467 typeofv = TYPEOF_PPOINTER;
3470 typeofv = TYPEOF_IPOINTER;
3473 typeofv = TYPEOF_ARRAY;
3476 typeofv = TYPEOF_FUNCTION;
3482 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3483 tree->opval.val = constVal (buffer);
3484 tree->right = tree->left = NULL;
3485 TETYPE (tree) = getSpec (TTYPE (tree) =
3486 tree->opval.val->type);
3489 /*------------------------------------------------------------------*/
3490 /*----------------------------*/
3491 /* conditional operator '?' */
3492 /*----------------------------*/
3494 /* the type is value of the colon operator (on the right) */
3495 assert(IS_COLON_OP(tree->right));
3496 /* if already known then replace the tree : optimizer will do it
3497 but faster to do it here */
3498 if (IS_LITERAL (LTYPE(tree))) {
3499 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3500 return decorateType(tree->right->left) ;
3502 return decorateType(tree->right->right) ;
3505 tree->right = decorateType(tree->right);
3506 TTYPE (tree) = RTYPE(tree);
3507 TETYPE (tree) = getSpec (TTYPE (tree));
3512 /* if they don't match we have a problem */
3513 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3515 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3516 goto errorTreeReturn;
3519 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3520 TETYPE (tree) = getSpec (TTYPE (tree));
3524 #if 0 // assignment operators are converted by the parser
3525 /*------------------------------------------------------------------*/
3526 /*----------------------------*/
3527 /* assignment operators */
3528 /*----------------------------*/
3531 /* for these it must be both must be integral */
3532 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3533 !IS_ARITHMETIC (RTYPE (tree)))
3535 werror (E_OPS_INTEGRAL);
3536 goto errorTreeReturn;
3539 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3541 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3542 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3546 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3547 goto errorTreeReturn;
3558 /* for these it must be both must be integral */
3559 if (!IS_INTEGRAL (LTYPE (tree)) ||
3560 !IS_INTEGRAL (RTYPE (tree)))
3562 werror (E_OPS_INTEGRAL);
3563 goto errorTreeReturn;
3566 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3568 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3569 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3573 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3574 goto errorTreeReturn;
3580 /*------------------------------------------------------------------*/
3581 /*----------------------------*/
3583 /*----------------------------*/
3585 if (!(IS_PTR (LTYPE (tree)) ||
3586 IS_ARITHMETIC (LTYPE (tree))))
3588 werror (E_PLUS_INVALID, "-=");
3589 goto errorTreeReturn;
3592 if (!(IS_PTR (RTYPE (tree)) ||
3593 IS_ARITHMETIC (RTYPE (tree))))
3595 werror (E_PLUS_INVALID, "-=");
3596 goto errorTreeReturn;
3599 TETYPE (tree) = getSpec (TTYPE (tree) =
3600 computeType (LTYPE (tree),
3603 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3604 werror (E_CODE_WRITE, "-=");
3608 werror (E_LVALUE_REQUIRED, "-=");
3609 goto errorTreeReturn;
3615 /*------------------------------------------------------------------*/
3616 /*----------------------------*/
3618 /*----------------------------*/
3620 /* this is not a unary operation */
3621 /* if both pointers then problem */
3622 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3624 werror (E_PTR_PLUS_PTR);
3625 goto errorTreeReturn;
3628 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3630 werror (E_PLUS_INVALID, "+=");
3631 goto errorTreeReturn;
3634 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3636 werror (E_PLUS_INVALID, "+=");
3637 goto errorTreeReturn;
3640 TETYPE (tree) = getSpec (TTYPE (tree) =
3641 computeType (LTYPE (tree),
3644 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3645 werror (E_CODE_WRITE, "+=");
3649 werror (E_LVALUE_REQUIRED, "+=");
3650 goto errorTreeReturn;
3653 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3654 tree->opval.op = '=';
3659 /*------------------------------------------------------------------*/
3660 /*----------------------------*/
3661 /* straight assignemnt */
3662 /*----------------------------*/
3664 /* cannot be an aggregate */
3665 if (IS_AGGREGATE (LTYPE (tree)))
3667 werror (E_AGGR_ASSIGN);
3668 goto errorTreeReturn;
3671 /* they should either match or be castable */
3672 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3674 werror (E_TYPE_MISMATCH, "assignment", " ");
3675 printFromToType(RTYPE(tree),LTYPE(tree));
3678 /* if the left side of the tree is of type void
3679 then report error */
3680 if (IS_VOID (LTYPE (tree)))
3682 werror (E_CAST_ZERO);
3683 printFromToType(RTYPE(tree), LTYPE(tree));
3686 TETYPE (tree) = getSpec (TTYPE (tree) =
3690 if (!tree->initMode ) {
3691 if (IS_CONSTANT(LTYPE(tree)))
3692 werror (E_CODE_WRITE, "=");
3696 werror (E_LVALUE_REQUIRED, "=");
3697 goto errorTreeReturn;
3702 /*------------------------------------------------------------------*/
3703 /*----------------------------*/
3704 /* comma operator */
3705 /*----------------------------*/
3707 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3710 /*------------------------------------------------------------------*/
3711 /*----------------------------*/
3713 /*----------------------------*/
3717 if (processParms (tree->left,
3718 FUNC_ARGS(tree->left->ftype),
3719 tree->right, &parmNumber, TRUE)) {
3720 goto errorTreeReturn;
3723 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3724 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3726 reverseParms (tree->right);
3729 if (IS_CODEPTR(LTYPE(tree))) {
3730 TTYPE(tree) = LTYPE(tree)->next->next;
3732 TTYPE(tree) = LTYPE(tree)->next;
3734 TETYPE (tree) = getSpec (TTYPE (tree));
3737 /*------------------------------------------------------------------*/
3738 /*----------------------------*/
3739 /* return statement */
3740 /*----------------------------*/
3745 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3747 werror (W_RETURN_MISMATCH);
3748 printFromToType (RTYPE(tree), currFunc->type->next);
3749 goto errorTreeReturn;
3752 if (IS_VOID (currFunc->type->next)
3754 !IS_VOID (RTYPE (tree)))
3756 werror (E_FUNC_VOID);
3757 goto errorTreeReturn;
3760 /* if there is going to be a casing required then add it */
3761 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3764 decorateType (newNode (CAST,
3765 newAst_LINK (copyLinkChain (currFunc->type->next)),
3774 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3776 werror (W_VOID_FUNC, currFunc->name);
3777 goto errorTreeReturn;
3780 TTYPE (tree) = TETYPE (tree) = NULL;
3783 /*------------------------------------------------------------------*/
3784 /*----------------------------*/
3785 /* switch statement */
3786 /*----------------------------*/
3788 /* the switch value must be an integer */
3789 if (!IS_INTEGRAL (LTYPE (tree)))
3791 werror (E_SWITCH_NON_INTEGER);
3792 goto errorTreeReturn;
3795 TTYPE (tree) = TETYPE (tree) = NULL;
3798 /*------------------------------------------------------------------*/
3799 /*----------------------------*/
3801 /*----------------------------*/
3803 tree->left = backPatchLabels (tree->left,
3806 TTYPE (tree) = TETYPE (tree) = NULL;
3809 /*------------------------------------------------------------------*/
3810 /*----------------------------*/
3812 /*----------------------------*/
3815 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3816 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3817 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3819 /* if the for loop is reversible then
3820 reverse it otherwise do what we normally
3826 if (isLoopReversible (tree, &sym, &init, &end))
3827 return reverseLoop (tree, sym, init, end);
3829 return decorateType (createFor (AST_FOR (tree, trueLabel),
3830 AST_FOR (tree, continueLabel),
3831 AST_FOR (tree, falseLabel),
3832 AST_FOR (tree, condLabel),
3833 AST_FOR (tree, initExpr),
3834 AST_FOR (tree, condExpr),
3835 AST_FOR (tree, loopExpr),
3839 TTYPE (tree) = TETYPE (tree) = NULL;
3843 /* some error found this tree will be killed */
3845 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3846 tree->opval.op = NULLOP;
3852 /*-----------------------------------------------------------------*/
3853 /* sizeofOp - processes size of operation */
3854 /*-----------------------------------------------------------------*/
3856 sizeofOp (sym_link * type)
3860 /* make sure the type is complete and sane */
3861 checkTypeSanity(type, "(sizeof)");
3863 /* get the size and convert it to character */
3864 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3866 /* now convert into value */
3867 return constVal (buff);
3871 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3872 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3873 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3874 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3875 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3876 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3877 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3879 /*-----------------------------------------------------------------*/
3880 /* backPatchLabels - change and or not operators to flow control */
3881 /*-----------------------------------------------------------------*/
3883 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3889 if (!(IS_ANDORNOT (tree)))
3892 /* if this an and */
3895 static int localLbl = 0;
3898 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3899 localLabel = newSymbol (buffer, NestLevel);
3901 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3903 /* if left is already a IFX then just change the if true label in that */
3904 if (!IS_IFX (tree->left))
3905 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3907 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3908 /* right is a IFX then just join */
3909 if (IS_IFX (tree->right))
3910 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3912 tree->right = createLabel (localLabel, tree->right);
3913 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3915 return newNode (NULLOP, tree->left, tree->right);
3918 /* if this is an or operation */
3921 static int localLbl = 0;
3924 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3925 localLabel = newSymbol (buffer, NestLevel);
3927 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3929 /* if left is already a IFX then just change the if true label in that */
3930 if (!IS_IFX (tree->left))
3931 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3933 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3934 /* right is a IFX then just join */
3935 if (IS_IFX (tree->right))
3936 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3938 tree->right = createLabel (localLabel, tree->right);
3939 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3941 return newNode (NULLOP, tree->left, tree->right);
3947 int wasnot = IS_NOT (tree->left);
3948 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3950 /* if the left is already a IFX */
3951 if (!IS_IFX (tree->left))
3952 tree->left = newNode (IFX, tree->left, NULL);
3956 tree->left->trueLabel = trueLabel;
3957 tree->left->falseLabel = falseLabel;
3961 tree->left->trueLabel = falseLabel;
3962 tree->left->falseLabel = trueLabel;
3969 tree->trueLabel = trueLabel;
3970 tree->falseLabel = falseLabel;
3977 /*-----------------------------------------------------------------*/
3978 /* createBlock - create expression tree for block */
3979 /*-----------------------------------------------------------------*/
3981 createBlock (symbol * decl, ast * body)
3985 /* if the block has nothing */
3989 ex = newNode (BLOCK, NULL, body);
3990 ex->values.sym = decl;
3992 ex->right = ex->right;
3998 /*-----------------------------------------------------------------*/
3999 /* createLabel - creates the expression tree for labels */
4000 /*-----------------------------------------------------------------*/
4002 createLabel (symbol * label, ast * stmnt)
4005 char name[SDCC_NAME_MAX + 1];
4008 /* must create fresh symbol if the symbol name */
4009 /* exists in the symbol table, since there can */
4010 /* be a variable with the same name as the labl */
4011 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4012 (csym->level == label->level))
4013 label = newSymbol (label->name, label->level);
4015 /* change the name before putting it in add _ */
4016 SNPRINTF(name, sizeof(name), "%s", label->name);
4018 /* put the label in the LabelSymbol table */
4019 /* but first check if a label of the same */
4021 if ((csym = findSym (LabelTab, NULL, name)))
4022 werror (E_DUPLICATE_LABEL, label->name);
4024 addSym (LabelTab, label, name, label->level, 0, 0);
4027 label->key = labelKey++;
4028 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4034 /*-----------------------------------------------------------------*/
4035 /* createCase - generates the parsetree for a case statement */
4036 /*-----------------------------------------------------------------*/
4038 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4040 char caseLbl[SDCC_NAME_MAX + 1];
4044 /* if the switch statement does not exist */
4045 /* then case is out of context */
4048 werror (E_CASE_CONTEXT);
4052 caseVal = decorateType (resolveSymbols (caseVal));
4053 /* if not a constant then error */
4054 if (!IS_LITERAL (caseVal->ftype))
4056 werror (E_CASE_CONSTANT);
4060 /* if not a integer than error */
4061 if (!IS_INTEGRAL (caseVal->ftype))
4063 werror (E_CASE_NON_INTEGER);
4067 /* find the end of the switch values chain */
4068 if (!(val = swStat->values.switchVals.swVals))
4069 swStat->values.switchVals.swVals = caseVal->opval.val;
4072 /* also order the cases according to value */
4074 int cVal = (int) floatFromVal (caseVal->opval.val);
4075 while (val && (int) floatFromVal (val) < cVal)
4081 /* if we reached the end then */
4084 pval->next = caseVal->opval.val;
4088 /* we found a value greater than */
4089 /* the current value we must add this */
4090 /* before the value */
4091 caseVal->opval.val->next = val;
4093 /* if this was the first in chain */
4094 if (swStat->values.switchVals.swVals == val)
4095 swStat->values.switchVals.swVals =
4098 pval->next = caseVal->opval.val;
4103 /* create the case label */
4104 SNPRINTF(caseLbl, sizeof(caseLbl),
4106 swStat->values.switchVals.swNum,
4107 (int) floatFromVal (caseVal->opval.val));
4109 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4114 /*-----------------------------------------------------------------*/
4115 /* createDefault - creates the parse tree for the default statement */
4116 /*-----------------------------------------------------------------*/
4118 createDefault (ast * swStat, ast * stmnt)
4120 char defLbl[SDCC_NAME_MAX + 1];
4122 /* if the switch statement does not exist */
4123 /* then case is out of context */
4126 werror (E_CASE_CONTEXT);
4130 /* turn on the default flag */
4131 swStat->values.switchVals.swDefault = 1;
4133 /* create the label */
4134 SNPRINTF (defLbl, sizeof(defLbl),
4135 "_default_%d", swStat->values.switchVals.swNum);
4136 return createLabel (newSymbol (defLbl, 0), stmnt);
4139 /*-----------------------------------------------------------------*/
4140 /* createIf - creates the parsetree for the if statement */
4141 /*-----------------------------------------------------------------*/
4143 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4145 static int Lblnum = 0;
4147 symbol *ifTrue, *ifFalse, *ifEnd;
4149 /* if neither exists */
4150 if (!elseBody && !ifBody) {
4151 // if there are no side effects (i++, j() etc)
4152 if (!hasSEFcalls(condAst)) {
4157 /* create the labels */
4158 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4159 ifFalse = newSymbol (buffer, NestLevel);
4160 /* if no else body then end == false */
4165 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4166 ifEnd = newSymbol (buffer, NestLevel);
4169 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4170 ifTrue = newSymbol (buffer, NestLevel);
4174 /* attach the ifTrue label to the top of it body */
4175 ifBody = createLabel (ifTrue, ifBody);
4176 /* attach a goto end to the ifBody if else is present */
4179 ifBody = newNode (NULLOP, ifBody,
4181 newAst_VALUE (symbolVal (ifEnd)),
4183 /* put the elseLabel on the else body */
4184 elseBody = createLabel (ifFalse, elseBody);
4185 /* out the end at the end of the body */
4186 elseBody = newNode (NULLOP,
4188 createLabel (ifEnd, NULL));
4192 ifBody = newNode (NULLOP, ifBody,
4193 createLabel (ifFalse, NULL));
4195 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4196 if (IS_IFX (condAst))
4199 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4201 return newNode (NULLOP, ifTree,
4202 newNode (NULLOP, ifBody, elseBody));
4206 /*-----------------------------------------------------------------*/
4207 /* createDo - creates parse tree for do */
4210 /* _docontinue_n: */
4211 /* condition_expression +-> trueLabel -> _dobody_n */
4213 /* +-> falseLabel-> _dobreak_n */
4215 /*-----------------------------------------------------------------*/
4217 createDo (symbol * trueLabel, symbol * continueLabel,
4218 symbol * falseLabel, ast * condAst, ast * doBody)
4223 /* if the body does not exist then it is simple */
4226 condAst = backPatchLabels (condAst, continueLabel, NULL);
4227 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4228 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4229 doTree->trueLabel = continueLabel;
4230 doTree->falseLabel = NULL;
4234 /* otherwise we have a body */
4235 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4237 /* attach the body label to the top */
4238 doBody = createLabel (trueLabel, doBody);
4239 /* attach the continue label to end of body */
4240 doBody = newNode (NULLOP, doBody,
4241 createLabel (continueLabel, NULL));
4243 /* now put the break label at the end */
4244 if (IS_IFX (condAst))
4247 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4249 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4251 /* putting it together */
4252 return newNode (NULLOP, doBody, doTree);
4255 /*-----------------------------------------------------------------*/
4256 /* createFor - creates parse tree for 'for' statement */
4259 /* condExpr +-> trueLabel -> _forbody_n */
4261 /* +-> falseLabel-> _forbreak_n */
4264 /* _forcontinue_n: */
4266 /* goto _forcond_n ; */
4268 /*-----------------------------------------------------------------*/
4270 createFor (symbol * trueLabel, symbol * continueLabel,
4271 symbol * falseLabel, symbol * condLabel,
4272 ast * initExpr, ast * condExpr, ast * loopExpr,
4277 /* if loopexpression not present then we can generate it */
4278 /* the same way as a while */
4280 return newNode (NULLOP, initExpr,
4281 createWhile (trueLabel, continueLabel,
4282 falseLabel, condExpr, forBody));
4283 /* vanilla for statement */
4284 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4286 if (condExpr && !IS_IFX (condExpr))
4287 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4290 /* attach condition label to condition */
4291 condExpr = createLabel (condLabel, condExpr);
4293 /* attach body label to body */
4294 forBody = createLabel (trueLabel, forBody);
4296 /* attach continue to forLoop expression & attach */
4297 /* goto the forcond @ and of loopExpression */
4298 loopExpr = createLabel (continueLabel,
4302 newAst_VALUE (symbolVal (condLabel)),
4304 /* now start putting them together */
4305 forTree = newNode (NULLOP, initExpr, condExpr);
4306 forTree = newNode (NULLOP, forTree, forBody);
4307 forTree = newNode (NULLOP, forTree, loopExpr);
4308 /* finally add the break label */
4309 forTree = newNode (NULLOP, forTree,
4310 createLabel (falseLabel, NULL));
4314 /*-----------------------------------------------------------------*/
4315 /* createWhile - creates parse tree for while statement */
4316 /* the while statement will be created as follows */
4318 /* _while_continue_n: */
4319 /* condition_expression +-> trueLabel -> _while_boby_n */
4321 /* +-> falseLabel -> _while_break_n */
4322 /* _while_body_n: */
4324 /* goto _while_continue_n */
4325 /* _while_break_n: */
4326 /*-----------------------------------------------------------------*/
4328 createWhile (symbol * trueLabel, symbol * continueLabel,
4329 symbol * falseLabel, ast * condExpr, ast * whileBody)
4333 /* put the continue label */
4334 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4335 condExpr = createLabel (continueLabel, condExpr);
4336 condExpr->lineno = 0;
4338 /* put the body label in front of the body */
4339 whileBody = createLabel (trueLabel, whileBody);
4340 whileBody->lineno = 0;
4341 /* put a jump to continue at the end of the body */
4342 /* and put break label at the end of the body */
4343 whileBody = newNode (NULLOP,
4346 newAst_VALUE (symbolVal (continueLabel)),
4347 createLabel (falseLabel, NULL)));
4349 /* put it all together */
4350 if (IS_IFX (condExpr))
4351 whileTree = condExpr;
4354 whileTree = newNode (IFX, condExpr, NULL);
4355 /* put the true & false labels in place */
4356 whileTree->trueLabel = trueLabel;
4357 whileTree->falseLabel = falseLabel;
4360 return newNode (NULLOP, whileTree, whileBody);
4363 /*-----------------------------------------------------------------*/
4364 /* optimizeGetHbit - get highest order bit of the expression */
4365 /*-----------------------------------------------------------------*/
4367 optimizeGetHbit (ast * tree)
4370 /* if this is not a bit and */
4371 if (!IS_BITAND (tree))
4374 /* will look for tree of the form
4375 ( expr >> ((sizeof expr) -1) ) & 1 */
4376 if (!IS_AST_LIT_VALUE (tree->right))
4379 if (AST_LIT_VALUE (tree->right) != 1)
4382 if (!IS_RIGHT_OP (tree->left))
4385 if (!IS_AST_LIT_VALUE (tree->left->right))
4388 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4389 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4392 /* make sure the port supports GETHBIT */
4393 if (port->hasExtBitOp
4394 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4397 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4401 /*-----------------------------------------------------------------*/
4402 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4403 /*-----------------------------------------------------------------*/
4405 optimizeRRCRLC (ast * root)
4407 /* will look for trees of the form
4408 (?expr << 1) | (?expr >> 7) or
4409 (?expr >> 7) | (?expr << 1) will make that
4410 into a RLC : operation ..
4412 (?expr >> 1) | (?expr << 7) or
4413 (?expr << 7) | (?expr >> 1) will make that
4414 into a RRC operation
4415 note : by 7 I mean (number of bits required to hold the
4417 /* if the root operations is not a | operation the not */
4418 if (!IS_BITOR (root))
4421 /* I have to think of a better way to match patterns this sucks */
4422 /* that aside let start looking for the first case : I use a the
4423 negative check a lot to improve the efficiency */
4424 /* (?expr << 1) | (?expr >> 7) */
4425 if (IS_LEFT_OP (root->left) &&
4426 IS_RIGHT_OP (root->right))
4429 if (!SPEC_USIGN (TETYPE (root->left->left)))
4432 if (!IS_AST_LIT_VALUE (root->left->right) ||
4433 !IS_AST_LIT_VALUE (root->right->right))
4436 /* make sure it is the same expression */
4437 if (!isAstEqual (root->left->left,
4441 if (AST_LIT_VALUE (root->left->right) != 1)
4444 if (AST_LIT_VALUE (root->right->right) !=
4445 (getSize (TTYPE (root->left->left)) * 8 - 1))
4448 /* make sure the port supports RLC */
4449 if (port->hasExtBitOp
4450 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4453 /* whew got the first case : create the AST */
4454 return newNode (RLC, root->left->left, NULL);
4458 /* check for second case */
4459 /* (?expr >> 7) | (?expr << 1) */
4460 if (IS_LEFT_OP (root->right) &&
4461 IS_RIGHT_OP (root->left))
4464 if (!SPEC_USIGN (TETYPE (root->left->left)))
4467 if (!IS_AST_LIT_VALUE (root->left->right) ||
4468 !IS_AST_LIT_VALUE (root->right->right))
4471 /* make sure it is the same symbol */
4472 if (!isAstEqual (root->left->left,
4476 if (AST_LIT_VALUE (root->right->right) != 1)
4479 if (AST_LIT_VALUE (root->left->right) !=
4480 (getSize (TTYPE (root->left->left)) * 8 - 1))
4483 /* make sure the port supports RLC */
4484 if (port->hasExtBitOp
4485 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4488 /* whew got the first case : create the AST */
4489 return newNode (RLC, root->left->left, NULL);
4494 /* third case for RRC */
4495 /* (?symbol >> 1) | (?symbol << 7) */
4496 if (IS_LEFT_OP (root->right) &&
4497 IS_RIGHT_OP (root->left))
4500 if (!SPEC_USIGN (TETYPE (root->left->left)))
4503 if (!IS_AST_LIT_VALUE (root->left->right) ||
4504 !IS_AST_LIT_VALUE (root->right->right))
4507 /* make sure it is the same symbol */
4508 if (!isAstEqual (root->left->left,
4512 if (AST_LIT_VALUE (root->left->right) != 1)
4515 if (AST_LIT_VALUE (root->right->right) !=
4516 (getSize (TTYPE (root->left->left)) * 8 - 1))
4519 /* make sure the port supports RRC */
4520 if (port->hasExtBitOp
4521 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4524 /* whew got the first case : create the AST */
4525 return newNode (RRC, root->left->left, NULL);
4529 /* fourth and last case for now */
4530 /* (?symbol << 7) | (?symbol >> 1) */
4531 if (IS_RIGHT_OP (root->right) &&
4532 IS_LEFT_OP (root->left))
4535 if (!SPEC_USIGN (TETYPE (root->left->left)))
4538 if (!IS_AST_LIT_VALUE (root->left->right) ||
4539 !IS_AST_LIT_VALUE (root->right->right))
4542 /* make sure it is the same symbol */
4543 if (!isAstEqual (root->left->left,
4547 if (AST_LIT_VALUE (root->right->right) != 1)
4550 if (AST_LIT_VALUE (root->left->right) !=
4551 (getSize (TTYPE (root->left->left)) * 8 - 1))
4554 /* make sure the port supports RRC */
4555 if (port->hasExtBitOp
4556 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4559 /* whew got the first case : create the AST */
4560 return newNode (RRC, root->left->left, NULL);
4564 /* not found return root */
4568 /*-----------------------------------------------------------------*/
4569 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4570 /*-----------------------------------------------------------------*/
4572 optimizeSWAP (ast * root)
4574 /* will look for trees of the form
4575 (?expr << 4) | (?expr >> 4) or
4576 (?expr >> 4) | (?expr << 4) will make that
4577 into a SWAP : operation ..
4578 note : by 4 I mean (number of bits required to hold the
4580 /* if the root operations is not a | operation the not */
4581 if (!IS_BITOR (root))
4584 /* (?expr << 4) | (?expr >> 4) */
4585 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4586 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4589 if (!SPEC_USIGN (TETYPE (root->left->left)))
4592 if (!IS_AST_LIT_VALUE (root->left->right) ||
4593 !IS_AST_LIT_VALUE (root->right->right))
4596 /* make sure it is the same expression */
4597 if (!isAstEqual (root->left->left,
4601 if (AST_LIT_VALUE (root->left->right) !=
4602 (getSize (TTYPE (root->left->left)) * 4))
4605 if (AST_LIT_VALUE (root->right->right) !=
4606 (getSize (TTYPE (root->left->left)) * 4))
4609 /* make sure the port supports SWAP */
4610 if (port->hasExtBitOp
4611 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4614 /* found it : create the AST */
4615 return newNode (SWAP, root->left->left, NULL);
4619 /* not found return root */
4623 /*-----------------------------------------------------------------*/
4624 /* optimizeCompare - otimizes compares for bit variables */
4625 /*-----------------------------------------------------------------*/
4627 optimizeCompare (ast * root)
4629 ast *optExpr = NULL;
4632 unsigned int litValue;
4634 /* if nothing then return nothing */
4638 /* if not a compare op then do leaves */
4639 if (!IS_COMPARE_OP (root))
4641 root->left = optimizeCompare (root->left);
4642 root->right = optimizeCompare (root->right);
4646 /* if left & right are the same then depending
4647 of the operation do */
4648 if (isAstEqual (root->left, root->right))
4650 switch (root->opval.op)
4655 optExpr = newAst_VALUE (constVal ("0"));
4660 optExpr = newAst_VALUE (constVal ("1"));
4664 return decorateType (optExpr);
4667 vleft = (root->left->type == EX_VALUE ?
4668 root->left->opval.val : NULL);
4670 vright = (root->right->type == EX_VALUE ?
4671 root->right->opval.val : NULL);
4673 /* if left is a BITVAR in BITSPACE */
4674 /* and right is a LITERAL then opt- */
4675 /* imize else do nothing */
4676 if (vleft && vright &&
4677 IS_BITVAR (vleft->etype) &&
4678 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4679 IS_LITERAL (vright->etype))
4682 /* if right side > 1 then comparison may never succeed */
4683 if ((litValue = (int) floatFromVal (vright)) > 1)
4685 werror (W_BAD_COMPARE);
4691 switch (root->opval.op)
4693 case '>': /* bit value greater than 1 cannot be */
4694 werror (W_BAD_COMPARE);
4698 case '<': /* bit value < 1 means 0 */
4700 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4703 case LE_OP: /* bit value <= 1 means no check */
4704 optExpr = newAst_VALUE (vright);
4707 case GE_OP: /* bit value >= 1 means only check for = */
4709 optExpr = newAst_VALUE (vleft);
4714 { /* literal is zero */
4715 switch (root->opval.op)
4717 case '<': /* bit value < 0 cannot be */
4718 werror (W_BAD_COMPARE);
4722 case '>': /* bit value > 0 means 1 */
4724 optExpr = newAst_VALUE (vleft);
4727 case LE_OP: /* bit value <= 0 means no check */
4728 case GE_OP: /* bit value >= 0 means no check */
4729 werror (W_BAD_COMPARE);
4733 case EQ_OP: /* bit == 0 means ! of bit */
4734 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4738 return decorateType (resolveSymbols (optExpr));
4739 } /* end-of-if of BITVAR */
4744 /*-----------------------------------------------------------------*/
4745 /* addSymToBlock : adds the symbol to the first block we find */
4746 /*-----------------------------------------------------------------*/
4748 addSymToBlock (symbol * sym, ast * tree)
4750 /* reached end of tree or a leaf */
4751 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4755 if (IS_AST_OP (tree) &&
4756 tree->opval.op == BLOCK)
4759 symbol *lsym = copySymbol (sym);
4761 lsym->next = AST_VALUES (tree, sym);
4762 AST_VALUES (tree, sym) = lsym;
4766 addSymToBlock (sym, tree->left);
4767 addSymToBlock (sym, tree->right);
4770 /*-----------------------------------------------------------------*/
4771 /* processRegParms - do processing for register parameters */
4772 /*-----------------------------------------------------------------*/
4774 processRegParms (value * args, ast * body)
4778 if (IS_REGPARM (args->etype))
4779 addSymToBlock (args->sym, body);
4784 /*-----------------------------------------------------------------*/
4785 /* resetParmKey - resets the operandkeys for the symbols */
4786 /*-----------------------------------------------------------------*/
4787 DEFSETFUNC (resetParmKey)
4798 /*-----------------------------------------------------------------*/
4799 /* createFunction - This is the key node that calls the iCode for */
4800 /* generating the code for a function. Note code */
4801 /* is generated function by function, later when */
4802 /* add inter-procedural analysis this will change */
4803 /*-----------------------------------------------------------------*/
4805 createFunction (symbol * name, ast * body)
4811 iCode *piCode = NULL;
4813 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4814 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4816 /* if check function return 0 then some problem */
4817 if (checkFunction (name, NULL) == 0)
4820 /* create a dummy block if none exists */
4822 body = newNode (BLOCK, NULL, NULL);
4826 /* check if the function name already in the symbol table */
4827 if ((csym = findSym (SymbolTab, NULL, name->name)))
4830 /* special case for compiler defined functions
4831 we need to add the name to the publics list : this
4832 actually means we are now compiling the compiler
4836 addSet (&publics, name);
4842 allocVariables (name);
4844 name->lastLine = mylineno;
4847 /* set the stack pointer */
4848 /* PENDING: check this for the mcs51 */
4849 stackPtr = -port->stack.direction * port->stack.call_overhead;
4850 if (IFFUNC_ISISR (name->type))
4851 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4852 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4853 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4855 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4857 fetype = getSpec (name->type); /* get the specifier for the function */
4858 /* if this is a reentrant function then */
4859 if (IFFUNC_ISREENT (name->type))
4862 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4864 /* do processing for parameters that are passed in registers */
4865 processRegParms (FUNC_ARGS(name->type), body);
4867 /* set the stack pointer */
4871 /* allocate & autoinit the block variables */
4872 processBlockVars (body, &stack, ALLOCATE);
4874 /* save the stack information */
4875 if (options.useXstack)
4876 name->xstack = SPEC_STAK (fetype) = stack;
4878 name->stack = SPEC_STAK (fetype) = stack;
4880 /* name needs to be mangled */
4881 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4883 body = resolveSymbols (body); /* resolve the symbols */
4884 body = decorateType (body); /* propagateType & do semantic checks */
4886 ex = newAst_VALUE (symbolVal (name)); /* create name */
4887 ex = newNode (FUNCTION, ex, body);
4888 ex->values.args = FUNC_ARGS(name->type);
4890 if (options.dump_tree) PA(ex);
4893 werror (E_FUNC_NO_CODE, name->name);
4897 /* create the node & generate intermediate code */
4899 codeOutFile = code->oFile;
4900 piCode = iCodeFromAst (ex);
4904 werror (E_FUNC_NO_CODE, name->name);
4908 eBBlockFromiCode (piCode);
4910 /* if there are any statics then do them */
4913 GcurMemmap = statsg;
4914 codeOutFile = statsg->oFile;
4915 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4921 /* dealloc the block variables */
4922 processBlockVars (body, &stack, DEALLOCATE);
4923 outputDebugStackSymbols();
4924 /* deallocate paramaters */
4925 deallocParms (FUNC_ARGS(name->type));
4927 if (IFFUNC_ISREENT (name->type))
4930 /* we are done freeup memory & cleanup */
4932 if (port->reset_labelKey) labelKey = 1;
4934 FUNC_HASBODY(name->type) = 1;
4935 addSet (&operKeyReset, name);
4936 applyToSet (operKeyReset, resetParmKey);
4941 cleanUpLevel (LabelTab, 0);
4942 cleanUpBlock (StructTab, 1);
4943 cleanUpBlock (TypedefTab, 1);
4945 xstack->syms = NULL;
4946 istack->syms = NULL;
4951 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4952 /*-----------------------------------------------------------------*/
4953 /* ast_print : prints the ast (for debugging purposes) */
4954 /*-----------------------------------------------------------------*/
4956 void ast_print (ast * tree, FILE *outfile, int indent)
4961 /* can print only decorated trees */
4962 if (!tree->decorated) return;
4964 /* if any child is an error | this one is an error do nothing */
4965 if (tree->isError ||
4966 (tree->left && tree->left->isError) ||
4967 (tree->right && tree->right->isError)) {
4968 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4972 /* print the line */
4973 /* if not block & function */
4974 if (tree->type == EX_OP &&
4975 (tree->opval.op != FUNCTION &&
4976 tree->opval.op != BLOCK &&
4977 tree->opval.op != NULLOP)) {
4980 if (tree->opval.op == FUNCTION) {
4982 value *args=FUNC_ARGS(tree->left->opval.val->type);
4983 fprintf(outfile,"FUNCTION (%s=%p) type (",
4984 tree->left->opval.val->name, tree);
4985 printTypeChain (tree->left->opval.val->type->next,outfile);
4986 fprintf(outfile,") args (");
4989 fprintf (outfile, ", ");
4991 printTypeChain (args ? args->type : NULL, outfile);
4993 args= args ? args->next : NULL;
4995 fprintf(outfile,")\n");
4996 ast_print(tree->left,outfile,indent);
4997 ast_print(tree->right,outfile,indent);
5000 if (tree->opval.op == BLOCK) {
5001 symbol *decls = tree->values.sym;
5002 INDENT(indent,outfile);
5003 fprintf(outfile,"{\n");
5005 INDENT(indent+2,outfile);
5006 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5007 decls->name, decls);
5008 printTypeChain(decls->type,outfile);
5009 fprintf(outfile,")\n");
5011 decls = decls->next;
5013 ast_print(tree->right,outfile,indent+2);
5014 INDENT(indent,outfile);
5015 fprintf(outfile,"}\n");
5018 if (tree->opval.op == NULLOP) {
5019 ast_print(tree->left,outfile,indent);
5020 ast_print(tree->right,outfile,indent);
5023 INDENT(indent,outfile);
5025 /*------------------------------------------------------------------*/
5026 /*----------------------------*/
5027 /* leaf has been reached */
5028 /*----------------------------*/
5029 /* if this is of type value */
5030 /* just get the type */
5031 if (tree->type == EX_VALUE) {
5033 if (IS_LITERAL (tree->opval.val->etype)) {
5034 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5035 if (SPEC_USIGN (tree->opval.val->etype))
5036 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5038 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5039 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5040 floatFromVal(tree->opval.val));
5041 } else if (tree->opval.val->sym) {
5042 /* if the undefined flag is set then give error message */
5043 if (tree->opval.val->sym->undefined) {
5044 fprintf(outfile,"UNDEFINED SYMBOL ");
5046 fprintf(outfile,"SYMBOL ");
5048 fprintf(outfile,"(%s=%p)",
5049 tree->opval.val->sym->name,tree);
5052 fprintf(outfile," type (");
5053 printTypeChain(tree->ftype,outfile);
5054 fprintf(outfile,")\n");
5056 fprintf(outfile,"\n");
5061 /* if type link for the case of cast */
5062 if (tree->type == EX_LINK) {
5063 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5064 printTypeChain(tree->opval.lnk,outfile);
5065 fprintf(outfile,")\n");
5070 /* depending on type of operator do */
5072 switch (tree->opval.op) {
5073 /*------------------------------------------------------------------*/
5074 /*----------------------------*/
5076 /*----------------------------*/
5078 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5079 printTypeChain(tree->ftype,outfile);
5080 fprintf(outfile,")\n");
5081 ast_print(tree->left,outfile,indent+2);
5082 ast_print(tree->right,outfile,indent+2);
5085 /*------------------------------------------------------------------*/
5086 /*----------------------------*/
5088 /*----------------------------*/
5090 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5091 printTypeChain(tree->ftype,outfile);
5092 fprintf(outfile,")\n");
5093 ast_print(tree->left,outfile,indent+2);
5094 ast_print(tree->right,outfile,indent+2);
5097 /*------------------------------------------------------------------*/
5098 /*----------------------------*/
5099 /* struct/union pointer */
5100 /*----------------------------*/
5102 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5103 printTypeChain(tree->ftype,outfile);
5104 fprintf(outfile,")\n");
5105 ast_print(tree->left,outfile,indent+2);
5106 ast_print(tree->right,outfile,indent+2);
5109 /*------------------------------------------------------------------*/
5110 /*----------------------------*/
5111 /* ++/-- operation */
5112 /*----------------------------*/
5115 fprintf(outfile,"post-");
5117 fprintf(outfile,"pre-");
5118 fprintf(outfile,"INC_OP (%p) type (",tree);
5119 printTypeChain(tree->ftype,outfile);
5120 fprintf(outfile,")\n");
5121 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5122 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5127 fprintf(outfile,"post-");
5129 fprintf(outfile,"pre-");
5130 fprintf(outfile,"DEC_OP (%p) type (",tree);
5131 printTypeChain(tree->ftype,outfile);
5132 fprintf(outfile,")\n");
5133 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5134 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5137 /*------------------------------------------------------------------*/
5138 /*----------------------------*/
5140 /*----------------------------*/
5143 fprintf(outfile,"& (%p) type (",tree);
5144 printTypeChain(tree->ftype,outfile);
5145 fprintf(outfile,")\n");
5146 ast_print(tree->left,outfile,indent+2);
5147 ast_print(tree->right,outfile,indent+2);
5149 fprintf(outfile,"ADDRESS_OF (%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);
5156 /*----------------------------*/
5158 /*----------------------------*/
5160 fprintf(outfile,"OR (%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);
5166 /*------------------------------------------------------------------*/
5167 /*----------------------------*/
5169 /*----------------------------*/
5171 fprintf(outfile,"XOR (%p) type (",tree);
5172 printTypeChain(tree->ftype,outfile);
5173 fprintf(outfile,")\n");
5174 ast_print(tree->left,outfile,indent+2);
5175 ast_print(tree->right,outfile,indent+2);
5178 /*------------------------------------------------------------------*/
5179 /*----------------------------*/
5181 /*----------------------------*/
5183 fprintf(outfile,"DIV (%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);
5189 /*------------------------------------------------------------------*/
5190 /*----------------------------*/
5192 /*----------------------------*/
5194 fprintf(outfile,"MOD (%p) type (",tree);
5195 printTypeChain(tree->ftype,outfile);
5196 fprintf(outfile,")\n");
5197 ast_print(tree->left,outfile,indent+2);
5198 ast_print(tree->right,outfile,indent+2);
5201 /*------------------------------------------------------------------*/
5202 /*----------------------------*/
5203 /* address dereference */
5204 /*----------------------------*/
5205 case '*': /* can be unary : if right is null then unary operation */
5207 fprintf(outfile,"DEREF (%p) type (",tree);
5208 printTypeChain(tree->ftype,outfile);
5209 fprintf(outfile,")\n");
5210 ast_print(tree->left,outfile,indent+2);
5213 /*------------------------------------------------------------------*/
5214 /*----------------------------*/
5215 /* multiplication */
5216 /*----------------------------*/
5217 fprintf(outfile,"MULT (%p) type (",tree);
5218 printTypeChain(tree->ftype,outfile);
5219 fprintf(outfile,")\n");
5220 ast_print(tree->left,outfile,indent+2);
5221 ast_print(tree->right,outfile,indent+2);
5225 /*------------------------------------------------------------------*/
5226 /*----------------------------*/
5227 /* unary '+' operator */
5228 /*----------------------------*/
5232 fprintf(outfile,"UPLUS (%p) type (",tree);
5233 printTypeChain(tree->ftype,outfile);
5234 fprintf(outfile,")\n");
5235 ast_print(tree->left,outfile,indent+2);
5237 /*------------------------------------------------------------------*/
5238 /*----------------------------*/
5240 /*----------------------------*/
5241 fprintf(outfile,"ADD (%p) type (",tree);
5242 printTypeChain(tree->ftype,outfile);
5243 fprintf(outfile,")\n");
5244 ast_print(tree->left,outfile,indent+2);
5245 ast_print(tree->right,outfile,indent+2);
5248 /*------------------------------------------------------------------*/
5249 /*----------------------------*/
5251 /*----------------------------*/
5252 case '-': /* can be unary */
5254 fprintf(outfile,"UMINUS (%p) type (",tree);
5255 printTypeChain(tree->ftype,outfile);
5256 fprintf(outfile,")\n");
5257 ast_print(tree->left,outfile,indent+2);
5259 /*------------------------------------------------------------------*/
5260 /*----------------------------*/
5262 /*----------------------------*/
5263 fprintf(outfile,"SUB (%p) type (",tree);
5264 printTypeChain(tree->ftype,outfile);
5265 fprintf(outfile,")\n");
5266 ast_print(tree->left,outfile,indent+2);
5267 ast_print(tree->right,outfile,indent+2);
5270 /*------------------------------------------------------------------*/
5271 /*----------------------------*/
5273 /*----------------------------*/
5275 fprintf(outfile,"COMPL (%p) type (",tree);
5276 printTypeChain(tree->ftype,outfile);
5277 fprintf(outfile,")\n");
5278 ast_print(tree->left,outfile,indent+2);
5280 /*------------------------------------------------------------------*/
5281 /*----------------------------*/
5283 /*----------------------------*/
5285 fprintf(outfile,"NOT (%p) type (",tree);
5286 printTypeChain(tree->ftype,outfile);
5287 fprintf(outfile,")\n");
5288 ast_print(tree->left,outfile,indent+2);
5290 /*------------------------------------------------------------------*/
5291 /*----------------------------*/
5293 /*----------------------------*/
5295 fprintf(outfile,"RRC (%p) type (",tree);
5296 printTypeChain(tree->ftype,outfile);
5297 fprintf(outfile,")\n");
5298 ast_print(tree->left,outfile,indent+2);
5302 fprintf(outfile,"RLC (%p) type (",tree);
5303 printTypeChain(tree->ftype,outfile);
5304 fprintf(outfile,")\n");
5305 ast_print(tree->left,outfile,indent+2);
5308 fprintf(outfile,"SWAP (%p) type (",tree);
5309 printTypeChain(tree->ftype,outfile);
5310 fprintf(outfile,")\n");
5311 ast_print(tree->left,outfile,indent+2);
5314 fprintf(outfile,"GETHBIT (%p) type (",tree);
5315 printTypeChain(tree->ftype,outfile);
5316 fprintf(outfile,")\n");
5317 ast_print(tree->left,outfile,indent+2);
5320 fprintf(outfile,"LEFT_SHIFT (%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 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5328 printTypeChain(tree->ftype,outfile);
5329 fprintf(outfile,")\n");
5330 ast_print(tree->left,outfile,indent+2);
5331 ast_print(tree->right,outfile,indent+2);
5333 /*------------------------------------------------------------------*/
5334 /*----------------------------*/
5336 /*----------------------------*/
5337 case CAST: /* change the type */
5338 fprintf(outfile,"CAST (%p) from type (",tree);
5339 printTypeChain(tree->right->ftype,outfile);
5340 fprintf(outfile,") to type (");
5341 printTypeChain(tree->ftype,outfile);
5342 fprintf(outfile,")\n");
5343 ast_print(tree->right,outfile,indent+2);
5347 fprintf(outfile,"ANDAND (%p) type (",tree);
5348 printTypeChain(tree->ftype,outfile);
5349 fprintf(outfile,")\n");
5350 ast_print(tree->left,outfile,indent+2);
5351 ast_print(tree->right,outfile,indent+2);
5354 fprintf(outfile,"OROR (%p) type (",tree);
5355 printTypeChain(tree->ftype,outfile);
5356 fprintf(outfile,")\n");
5357 ast_print(tree->left,outfile,indent+2);
5358 ast_print(tree->right,outfile,indent+2);
5361 /*------------------------------------------------------------------*/
5362 /*----------------------------*/
5363 /* comparison operators */
5364 /*----------------------------*/
5366 fprintf(outfile,"GT(>) (%p) type (",tree);
5367 printTypeChain(tree->ftype,outfile);
5368 fprintf(outfile,")\n");
5369 ast_print(tree->left,outfile,indent+2);
5370 ast_print(tree->right,outfile,indent+2);
5373 fprintf(outfile,"LT(<) (%p) type (",tree);
5374 printTypeChain(tree->ftype,outfile);
5375 fprintf(outfile,")\n");
5376 ast_print(tree->left,outfile,indent+2);
5377 ast_print(tree->right,outfile,indent+2);
5380 fprintf(outfile,"LE(<=) (%p) type (",tree);
5381 printTypeChain(tree->ftype,outfile);
5382 fprintf(outfile,")\n");
5383 ast_print(tree->left,outfile,indent+2);
5384 ast_print(tree->right,outfile,indent+2);
5387 fprintf(outfile,"GE(>=) (%p) type (",tree);
5388 printTypeChain(tree->ftype,outfile);
5389 fprintf(outfile,")\n");
5390 ast_print(tree->left,outfile,indent+2);
5391 ast_print(tree->right,outfile,indent+2);
5394 fprintf(outfile,"EQ(==) (%p) type (",tree);
5395 printTypeChain(tree->ftype,outfile);
5396 fprintf(outfile,")\n");
5397 ast_print(tree->left,outfile,indent+2);
5398 ast_print(tree->right,outfile,indent+2);
5401 fprintf(outfile,"NE(!=) (%p) type (",tree);
5402 printTypeChain(tree->ftype,outfile);
5403 fprintf(outfile,")\n");
5404 ast_print(tree->left,outfile,indent+2);
5405 ast_print(tree->right,outfile,indent+2);
5406 /*------------------------------------------------------------------*/
5407 /*----------------------------*/
5409 /*----------------------------*/
5410 case SIZEOF: /* evaluate wihout code generation */
5411 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5414 /*------------------------------------------------------------------*/
5415 /*----------------------------*/
5416 /* conditional operator '?' */
5417 /*----------------------------*/
5419 fprintf(outfile,"QUEST(?) (%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);
5427 fprintf(outfile,"COLON(:) (%p) type (",tree);
5428 printTypeChain(tree->ftype,outfile);
5429 fprintf(outfile,")\n");
5430 ast_print(tree->left,outfile,indent+2);
5431 ast_print(tree->right,outfile,indent+2);
5434 /*------------------------------------------------------------------*/
5435 /*----------------------------*/
5436 /* assignment operators */
5437 /*----------------------------*/
5439 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5440 printTypeChain(tree->ftype,outfile);
5441 fprintf(outfile,")\n");
5442 ast_print(tree->left,outfile,indent+2);
5443 ast_print(tree->right,outfile,indent+2);
5446 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5447 printTypeChain(tree->ftype,outfile);
5448 fprintf(outfile,")\n");
5449 ast_print(tree->left,outfile,indent+2);
5450 ast_print(tree->right,outfile,indent+2);
5453 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5454 printTypeChain(tree->ftype,outfile);
5455 fprintf(outfile,")\n");
5456 ast_print(tree->left,outfile,indent+2);
5457 ast_print(tree->right,outfile,indent+2);
5460 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5461 printTypeChain(tree->ftype,outfile);
5462 fprintf(outfile,")\n");
5463 ast_print(tree->left,outfile,indent+2);
5464 ast_print(tree->right,outfile,indent+2);
5467 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5468 printTypeChain(tree->ftype,outfile);
5469 fprintf(outfile,")\n");
5470 ast_print(tree->left,outfile,indent+2);
5471 ast_print(tree->right,outfile,indent+2);
5474 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5475 printTypeChain(tree->ftype,outfile);
5476 fprintf(outfile,")\n");
5477 ast_print(tree->left,outfile,indent+2);
5478 ast_print(tree->right,outfile,indent+2);
5481 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5482 printTypeChain(tree->ftype,outfile);
5483 fprintf(outfile,")\n");
5484 ast_print(tree->left,outfile,indent+2);
5485 ast_print(tree->right,outfile,indent+2);
5487 /*------------------------------------------------------------------*/
5488 /*----------------------------*/
5490 /*----------------------------*/
5492 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5493 printTypeChain(tree->ftype,outfile);
5494 fprintf(outfile,")\n");
5495 ast_print(tree->left,outfile,indent+2);
5496 ast_print(tree->right,outfile,indent+2);
5498 /*------------------------------------------------------------------*/
5499 /*----------------------------*/
5501 /*----------------------------*/
5503 fprintf(outfile,"ADDASS(+=) (%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);
5509 /*------------------------------------------------------------------*/
5510 /*----------------------------*/
5511 /* straight assignemnt */
5512 /*----------------------------*/
5514 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5515 printTypeChain(tree->ftype,outfile);
5516 fprintf(outfile,")\n");
5517 ast_print(tree->left,outfile,indent+2);
5518 ast_print(tree->right,outfile,indent+2);
5520 /*------------------------------------------------------------------*/
5521 /*----------------------------*/
5522 /* comma operator */
5523 /*----------------------------*/
5525 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5526 printTypeChain(tree->ftype,outfile);
5527 fprintf(outfile,")\n");
5528 ast_print(tree->left,outfile,indent+2);
5529 ast_print(tree->right,outfile,indent+2);
5531 /*------------------------------------------------------------------*/
5532 /*----------------------------*/
5534 /*----------------------------*/
5537 fprintf(outfile,"CALL (%p) type (",tree);
5538 printTypeChain(tree->ftype,outfile);
5539 fprintf(outfile,")\n");
5540 ast_print(tree->left,outfile,indent+2);
5541 ast_print(tree->right,outfile,indent+2);
5544 fprintf(outfile,"PARMS\n");
5545 ast_print(tree->left,outfile,indent+2);
5546 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5547 ast_print(tree->right,outfile,indent+2);
5550 /*------------------------------------------------------------------*/
5551 /*----------------------------*/
5552 /* return statement */
5553 /*----------------------------*/
5555 fprintf(outfile,"RETURN (%p) type (",tree);
5557 printTypeChain(tree->right->ftype,outfile);
5559 fprintf(outfile,")\n");
5560 ast_print(tree->right,outfile,indent+2);
5562 /*------------------------------------------------------------------*/
5563 /*----------------------------*/
5564 /* label statement */
5565 /*----------------------------*/
5567 fprintf(outfile,"LABEL (%p)\n",tree);
5568 ast_print(tree->left,outfile,indent+2);
5569 ast_print(tree->right,outfile,indent);
5571 /*------------------------------------------------------------------*/
5572 /*----------------------------*/
5573 /* switch statement */
5574 /*----------------------------*/
5578 fprintf(outfile,"SWITCH (%p) ",tree);
5579 ast_print(tree->left,outfile,0);
5580 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5581 INDENT(indent+2,outfile);
5582 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5583 (int) floatFromVal(val),
5584 tree->values.switchVals.swNum,
5585 (int) floatFromVal(val));
5587 ast_print(tree->right,outfile,indent);
5590 /*------------------------------------------------------------------*/
5591 /*----------------------------*/
5593 /*----------------------------*/
5595 fprintf(outfile,"IF (%p) \n",tree);
5596 ast_print(tree->left,outfile,indent+2);
5597 if (tree->trueLabel) {
5598 INDENT(indent+2,outfile);
5599 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5601 if (tree->falseLabel) {
5602 INDENT(indent+2,outfile);
5603 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5605 ast_print(tree->right,outfile,indent+2);
5607 /*----------------------------*/
5608 /* goto Statement */
5609 /*----------------------------*/
5611 fprintf(outfile,"GOTO (%p) \n",tree);
5612 ast_print(tree->left,outfile,indent+2);
5613 fprintf(outfile,"\n");
5615 /*------------------------------------------------------------------*/
5616 /*----------------------------*/
5618 /*----------------------------*/
5620 fprintf(outfile,"FOR (%p) \n",tree);
5621 if (AST_FOR( tree, initExpr)) {
5622 INDENT(indent+2,outfile);
5623 fprintf(outfile,"INIT EXPR ");
5624 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5626 if (AST_FOR( tree, condExpr)) {
5627 INDENT(indent+2,outfile);
5628 fprintf(outfile,"COND EXPR ");
5629 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5631 if (AST_FOR( tree, loopExpr)) {
5632 INDENT(indent+2,outfile);
5633 fprintf(outfile,"LOOP EXPR ");
5634 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5636 fprintf(outfile,"FOR LOOP BODY \n");
5637 ast_print(tree->left,outfile,indent+2);
5640 fprintf(outfile,"CRITICAL (%p) \n",tree);
5641 ast_print(tree->left,outfile,indent+2);
5649 ast_print(t,stdout,0);