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 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
278 /* "*++s += 3" -> "*++s = *++s + 3" */
279 /*-----------------------------------------------------------------*/
280 ast *removePreIncDecOps (ast * tree) {
282 // traverse the tree and remove pre-inc/dec ops
287 if (tree->type == EX_OP &&
288 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
293 tree->left=removePreIncDecOps(tree->left);
294 tree->right=removePreIncDecOps(tree->right);
299 /*-----------------------------------------------------------------*/
300 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
301 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
302 /*-----------------------------------------------------------------*/
303 ast *removePostIncDecOps (ast * tree) {
305 // traverse the tree and remove pre-inc/dec ops
310 if (tree->type == EX_OP &&
311 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
316 tree->left=removePostIncDecOps(tree->left);
317 tree->right=removePostIncDecOps(tree->right);
322 /*-----------------------------------------------------------------*/
323 /* hasSEFcalls - returns TRUE if tree has a function call */
324 /*-----------------------------------------------------------------*/
326 hasSEFcalls (ast * tree)
331 if (tree->type == EX_OP &&
332 (tree->opval.op == CALL ||
333 tree->opval.op == PCALL ||
334 tree->opval.op == '=' ||
335 tree->opval.op == INC_OP ||
336 tree->opval.op == DEC_OP))
339 return (hasSEFcalls (tree->left) |
340 hasSEFcalls (tree->right));
343 /*-----------------------------------------------------------------*/
344 /* isAstEqual - compares two asts & returns 1 if they are equal */
345 /*-----------------------------------------------------------------*/
347 isAstEqual (ast * t1, ast * t2)
356 if (t1->type != t2->type)
362 if (t1->opval.op != t2->opval.op)
364 return (isAstEqual (t1->left, t2->left) &&
365 isAstEqual (t1->right, t2->right));
369 if (t1->opval.val->sym)
371 if (!t2->opval.val->sym)
374 return isSymbolEqual (t1->opval.val->sym,
379 if (t2->opval.val->sym)
382 return (floatFromVal (t1->opval.val) ==
383 floatFromVal (t2->opval.val));
387 /* only compare these two types */
395 /*-----------------------------------------------------------------*/
396 /* resolveSymbols - resolve symbols from the symbol table */
397 /*-----------------------------------------------------------------*/
399 resolveSymbols (ast * tree)
401 /* walk the entire tree and check for values */
402 /* with symbols if we find one then replace */
403 /* symbol with that from the symbol table */
410 /* if not block & function */
411 if (tree->type == EX_OP &&
412 (tree->opval.op != FUNCTION &&
413 tree->opval.op != BLOCK &&
414 tree->opval.op != NULLOP))
416 filename = tree->filename;
417 lineno = tree->lineno;
421 /* make sure we resolve the true & false labels for ifx */
422 if (tree->type == EX_OP && tree->opval.op == IFX)
428 if ((csym = findSym (LabelTab, tree->trueLabel,
429 tree->trueLabel->name)))
430 tree->trueLabel = csym;
432 werror (E_LABEL_UNDEF, tree->trueLabel->name);
435 if (tree->falseLabel)
437 if ((csym = findSym (LabelTab,
439 tree->falseLabel->name)))
440 tree->falseLabel = csym;
442 werror (E_LABEL_UNDEF, tree->falseLabel->name);
447 /* if this is a label resolve it from the labelTab */
448 if (IS_AST_VALUE (tree) &&
449 tree->opval.val->sym &&
450 tree->opval.val->sym->islbl)
453 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
454 tree->opval.val->sym->name);
457 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
459 tree->opval.val->sym = csym;
461 goto resolveChildren;
464 /* do only for leafs */
465 if (IS_AST_VALUE (tree) &&
466 tree->opval.val->sym &&
467 !tree->opval.val->sym->implicit)
470 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
472 /* if found in the symbol table & they r not the same */
473 if (csym && tree->opval.val->sym != csym)
475 tree->opval.val->sym = csym;
476 tree->opval.val->type = csym->type;
477 tree->opval.val->etype = csym->etype;
480 /* if not found in the symbol table */
481 /* mark it as undefined assume it is */
482 /* an integer in data space */
483 if (!csym && !tree->opval.val->sym->implicit)
486 /* if this is a function name then */
487 /* mark it as returning an int */
490 tree->opval.val->sym->type = newLink (DECLARATOR);
491 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
492 tree->opval.val->sym->type->next =
493 tree->opval.val->sym->etype = newIntLink ();
494 tree->opval.val->etype = tree->opval.val->etype;
495 tree->opval.val->type = tree->opval.val->sym->type;
496 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
497 allocVariables (tree->opval.val->sym);
501 tree->opval.val->sym->undefined = 1;
502 tree->opval.val->type =
503 tree->opval.val->etype = newIntLink ();
504 tree->opval.val->sym->type =
505 tree->opval.val->sym->etype = newIntLink ();
511 resolveSymbols (tree->left);
512 resolveSymbols (tree->right);
517 /*-----------------------------------------------------------------*/
518 /* setAstLineno - walks a ast tree & sets the line number */
519 /*-----------------------------------------------------------------*/
520 int setAstLineno (ast * tree, int lineno)
525 tree->lineno = lineno;
526 setAstLineno (tree->left, lineno);
527 setAstLineno (tree->right, lineno);
531 /*-----------------------------------------------------------------*/
532 /* funcOfType :- function of type with name */
533 /*-----------------------------------------------------------------*/
535 funcOfType (char *name, sym_link * type, sym_link * argType,
539 /* create the symbol */
540 sym = newSymbol (name, 0);
542 /* setup return value */
543 sym->type = newLink (DECLARATOR);
544 DCL_TYPE (sym->type) = FUNCTION;
545 sym->type->next = copyLinkChain (type);
546 sym->etype = getSpec (sym->type);
547 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
549 /* if arguments required */
553 args = FUNC_ARGS(sym->type) = newValue ();
557 args->type = copyLinkChain (argType);
558 args->etype = getSpec (args->type);
559 SPEC_EXTR(args->etype)=1;
562 args = args->next = newValue ();
569 allocVariables (sym);
574 /*-----------------------------------------------------------------*/
575 /* funcOfTypeVarg :- function of type with name and argtype */
576 /*-----------------------------------------------------------------*/
578 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
583 /* create the symbol */
584 sym = newSymbol (name, 0);
586 /* setup return value */
587 sym->type = newLink (DECLARATOR);
588 DCL_TYPE (sym->type) = FUNCTION;
589 sym->type->next = typeFromStr(rtype);
590 sym->etype = getSpec (sym->type);
592 /* if arguments required */
595 args = FUNC_ARGS(sym->type) = newValue ();
597 for ( i = 0 ; i < nArgs ; i++ ) {
598 args->type = typeFromStr(atypes[i]);
599 args->etype = getSpec (args->type);
600 SPEC_EXTR(args->etype)=1;
601 if ((i + 1) == nArgs) break;
602 args = args->next = newValue ();
609 allocVariables (sym);
614 /*-----------------------------------------------------------------*/
615 /* reverseParms - will reverse a parameter tree */
616 /*-----------------------------------------------------------------*/
618 reverseParms (ast * ptree)
624 /* top down if we find a nonParm tree then quit */
625 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
628 ptree->left = ptree->right;
629 ptree->right = ttree;
630 reverseParms (ptree->left);
631 reverseParms (ptree->right);
637 /*-----------------------------------------------------------------*/
638 /* processParms - makes sure the parameters are okay and do some */
639 /* processing with them */
640 /*-----------------------------------------------------------------*/
642 processParms (ast * func,
645 int *parmNumber, // unused, although updated
648 /* if none of them exist */
649 if (!defParm && !actParm)
653 if (getenv("DEBUG_SANITY")) {
654 fprintf (stderr, "processParms: %s ", defParm->name);
656 /* make sure the type is complete and sane */
657 checkTypeSanity(defParm->etype, defParm->name);
660 /* if the function is being called via a pointer & */
661 /* it has not been defined a reentrant then we cannot */
662 /* have parameters */
663 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
665 werror (W_NONRENT_ARGS);
669 /* if defined parameters ended but actual parameters */
670 /* exist and this is not defined as a variable arg */
671 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
673 werror (E_TOO_MANY_PARMS);
677 /* if defined parameters present but no actual parameters */
678 if (defParm && !actParm)
680 werror (E_TOO_FEW_PARMS);
684 if (IS_VOID(actParm->ftype)) {
685 werror (E_VOID_VALUE_USED);
689 /* If this is a varargs function... */
690 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
695 if (IS_CAST_OP (actParm)
696 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
698 /* Parameter was explicitly typecast; don't touch it. */
702 ftype = actParm->ftype;
704 /* If it's a small integer, upcast to int. */
705 if (IS_INTEGRAL (ftype)
706 && (getSize (ftype) < (unsigned) INTSIZE))
708 if (IS_AST_OP(actParm) &&
709 (actParm->opval.op == LEFT_OP ||
710 actParm->opval.op == '*' ||
711 actParm->opval.op == '+' ||
712 actParm->opval.op == '-') &&
714 // we should cast an operand instead of the result
715 actParm->decorated = 0;
716 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
718 actParm = decorateType(actParm);
720 newType = newAst_LINK(INTTYPE);
724 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
726 newType = newAst_LINK (copyLinkChain(ftype));
727 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
730 if (IS_AGGREGATE (ftype))
732 newType = newAst_LINK (copyLinkChain (ftype));
733 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
737 /* cast required; change this op to a cast. */
738 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
740 actParm->type = EX_OP;
741 actParm->opval.op = CAST;
742 actParm->left = newType;
743 actParm->right = parmCopy;
744 decorateType (actParm);
746 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
748 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
749 processParms (func, NULL, actParm->right, parmNumber, rightmost));
754 /* if defined parameters ended but actual has not & */
756 if (!defParm && actParm &&
757 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
760 resolveSymbols (actParm);
761 /* if this is a PARAM node then match left & right */
762 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
764 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
765 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
769 /* If we have found a value node by following only right-hand links,
770 * then we know that there are no more values after us.
772 * Therefore, if there are more defined parameters, the caller didn't
775 if (rightmost && defParm->next)
777 werror (E_TOO_FEW_PARMS);
782 /* the parameter type must be at least castable */
783 if (compareType (defParm->type, actParm->ftype) == 0) {
784 werror (E_INCOMPAT_TYPES);
785 printFromToType (actParm->ftype, defParm->type);
789 /* if the parameter is castable then add the cast */
790 if (compareType (defParm->type, actParm->ftype) < 0)
792 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
794 /* now change the current one to a cast */
795 actParm->type = EX_OP;
796 actParm->opval.op = CAST;
797 actParm->left = newAst_LINK (defParm->type);
798 actParm->right = pTree;
799 actParm->etype = defParm->etype;
800 actParm->ftype = defParm->type;
801 actParm->decorated=0; /* force typechecking */
802 decorateType (actParm);
805 /* make a copy and change the regparm type to the defined parm */
806 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
807 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
808 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
812 /*-----------------------------------------------------------------*/
813 /* createIvalType - generates ival for basic types */
814 /*-----------------------------------------------------------------*/
816 createIvalType (ast * sym, sym_link * type, initList * ilist)
820 /* if initList is deep */
821 if (ilist->type == INIT_DEEP)
822 ilist = ilist->init.deep;
824 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
825 return decorateType (newNode ('=', sym, iExpr));
828 /*-----------------------------------------------------------------*/
829 /* createIvalStruct - generates initial value for structures */
830 /*-----------------------------------------------------------------*/
832 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
839 sflds = SPEC_STRUCT (type)->fields;
840 if (ilist->type != INIT_DEEP)
842 werror (E_INIT_STRUCT, "");
846 iloop = ilist->init.deep;
848 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
850 /* if we have come to end */
854 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
855 lAst = decorateType (resolveSymbols (lAst));
856 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
860 werror (W_EXCESS_INITIALIZERS, "struct",
861 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
868 /*-----------------------------------------------------------------*/
869 /* createIvalArray - generates code for array initialization */
870 /*-----------------------------------------------------------------*/
872 createIvalArray (ast * sym, sym_link * type, initList * ilist)
876 int lcnt = 0, size = 0;
877 literalList *literalL;
879 /* take care of the special case */
880 /* array of characters can be init */
882 if (IS_CHAR (type->next))
883 if ((rast = createIvalCharPtr (sym,
885 decorateType (resolveSymbols (list2expr (ilist))))))
887 return decorateType (resolveSymbols (rast));
889 /* not the special case */
890 if (ilist->type != INIT_DEEP)
892 werror (E_INIT_STRUCT, "");
896 iloop = ilist->init.deep;
897 lcnt = DCL_ELEM (type);
899 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
903 aSym = decorateType (resolveSymbols(sym));
905 rast = newNode(ARRAYINIT, aSym, NULL);
906 rast->values.constlist = literalL;
908 // Make sure size is set to length of initializer list.
915 if (lcnt && size > lcnt)
917 // Array size was specified, and we have more initializers than needed.
918 char *name=sym->opval.val->sym->name;
919 int lineno=sym->opval.val->sym->lineDef;
921 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
930 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
931 aSym = decorateType (resolveSymbols (aSym));
932 rast = createIval (aSym, type->next, iloop, rast);
933 iloop = (iloop ? iloop->next : NULL);
939 /* no of elements given and we */
940 /* have generated for all of them */
943 // there has to be a better way
944 char *name=sym->opval.val->sym->name;
945 int lineno=sym->opval.val->sym->lineDef;
946 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
953 /* if we have not been given a size */
954 if (!DCL_ELEM (type))
956 DCL_ELEM (type) = size;
959 return decorateType (resolveSymbols (rast));
963 /*-----------------------------------------------------------------*/
964 /* createIvalCharPtr - generates initial values for char pointers */
965 /*-----------------------------------------------------------------*/
967 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
971 /* if this is a pointer & right is a literal array then */
972 /* just assignment will do */
973 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
974 SPEC_SCLS (iexpr->etype) == S_CODE)
975 && IS_ARRAY (iexpr->ftype)))
976 return newNode ('=', sym, iexpr);
978 /* left side is an array so we have to assign each */
980 if ((IS_LITERAL (iexpr->etype) ||
981 SPEC_SCLS (iexpr->etype) == S_CODE)
982 && IS_ARRAY (iexpr->ftype))
984 /* for each character generate an assignment */
985 /* to the array element */
986 char *s = SPEC_CVAL (iexpr->etype).v_char;
988 int size = getSize (iexpr->ftype);
992 rast = newNode (NULLOP,
996 newAst_VALUE (valueFromLit ((float) i))),
997 newAst_VALUE (valueFromLit (*s))));
1001 // now WE don't need iexpr's symbol anymore
1002 freeStringSymbol(AST_SYMBOL(iexpr));
1004 return decorateType (resolveSymbols (rast));
1010 /*-----------------------------------------------------------------*/
1011 /* createIvalPtr - generates initial value for pointers */
1012 /*-----------------------------------------------------------------*/
1014 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1020 if (ilist->type == INIT_DEEP)
1021 ilist = ilist->init.deep;
1023 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1025 /* if character pointer */
1026 if (IS_CHAR (type->next))
1027 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1030 return newNode ('=', sym, iexpr);
1033 /*-----------------------------------------------------------------*/
1034 /* createIval - generates code for initial value */
1035 /*-----------------------------------------------------------------*/
1037 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1044 /* if structure then */
1045 if (IS_STRUCT (type))
1046 rast = createIvalStruct (sym, type, ilist);
1048 /* if this is a pointer */
1050 rast = createIvalPtr (sym, type, ilist);
1052 /* if this is an array */
1053 if (IS_ARRAY (type))
1054 rast = createIvalArray (sym, type, ilist);
1056 /* if type is SPECIFIER */
1058 rast = createIvalType (sym, type, ilist);
1061 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1063 return decorateType (resolveSymbols (rast));
1066 /*-----------------------------------------------------------------*/
1067 /* initAggregates - initialises aggregate variables with initv */
1068 /*-----------------------------------------------------------------*/
1069 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1070 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1073 /*-----------------------------------------------------------------*/
1074 /* gatherAutoInit - creates assignment expressions for initial */
1076 /*-----------------------------------------------------------------*/
1078 gatherAutoInit (symbol * autoChain)
1085 for (sym = autoChain; sym; sym = sym->next)
1088 /* resolve the symbols in the ival */
1090 resolveIvalSym (sym->ival);
1092 /* if this is a static variable & has an */
1093 /* initial value the code needs to be lifted */
1094 /* here to the main portion since they can be */
1095 /* initialised only once at the start */
1096 if (IS_STATIC (sym->etype) && sym->ival &&
1097 SPEC_SCLS (sym->etype) != S_CODE)
1101 /* insert the symbol into the symbol table */
1102 /* with level = 0 & name = rname */
1103 newSym = copySymbol (sym);
1104 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1106 /* now lift the code to main */
1107 if (IS_AGGREGATE (sym->type)) {
1108 work = initAggregates (sym, sym->ival, NULL);
1110 if (getNelements(sym->type, sym->ival)>1) {
1111 werror (W_EXCESS_INITIALIZERS, "scalar",
1112 sym->name, sym->lineDef);
1114 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1115 list2expr (sym->ival));
1118 setAstLineno (work, sym->lineDef);
1122 staticAutos = newNode (NULLOP, staticAutos, work);
1129 /* if there is an initial value */
1130 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1132 initList *ilist=sym->ival;
1134 while (ilist->type == INIT_DEEP) {
1135 ilist = ilist->init.deep;
1138 /* update lineno for error msg */
1139 lineno=sym->lineDef;
1140 setAstLineno (ilist->init.node, lineno);
1142 if (IS_AGGREGATE (sym->type)) {
1143 work = initAggregates (sym, sym->ival, NULL);
1145 if (getNelements(sym->type, sym->ival)>1) {
1146 werror (W_EXCESS_INITIALIZERS, "scalar",
1147 sym->name, sym->lineDef);
1149 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1150 list2expr (sym->ival));
1154 setAstLineno (work, sym->lineDef);
1158 init = newNode (NULLOP, init, work);
1167 /*-----------------------------------------------------------------*/
1168 /* freeStringSymbol - delete a literal string if no more usage */
1169 /*-----------------------------------------------------------------*/
1170 void freeStringSymbol(symbol *sym) {
1171 /* make sure this is a literal string */
1172 assert (sym->isstrlit);
1173 if (--sym->isstrlit == 0) { // lower the usage count
1174 memmap *segment=SPEC_OCLS(sym->etype);
1176 deleteSetItem(&segment->syms, sym);
1181 /*-----------------------------------------------------------------*/
1182 /* stringToSymbol - creates a symbol from a literal string */
1183 /*-----------------------------------------------------------------*/
1185 stringToSymbol (value * val)
1187 char name[SDCC_NAME_MAX + 1];
1188 static int charLbl = 0;
1193 // have we heard this before?
1194 for (sp=statsg->syms; sp; sp=sp->next) {
1196 size = getSize (sym->type);
1197 if (sym->isstrlit && size == getSize (val->type) &&
1198 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1199 // yes, this is old news. Don't publish it again.
1200 sym->isstrlit++; // but raise the usage count
1201 return symbolVal(sym);
1205 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1206 sym = newSymbol (name, 0); /* make it @ level 0 */
1207 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1209 /* copy the type from the value passed */
1210 sym->type = copyLinkChain (val->type);
1211 sym->etype = getSpec (sym->type);
1212 /* change to storage class & output class */
1213 SPEC_SCLS (sym->etype) = S_CODE;
1214 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1215 SPEC_STAT (sym->etype) = 1;
1216 /* make the level & block = 0 */
1217 sym->block = sym->level = 0;
1219 /* create an ival */
1220 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1225 allocVariables (sym);
1228 return symbolVal (sym);
1232 /*-----------------------------------------------------------------*/
1233 /* processBlockVars - will go thru the ast looking for block if */
1234 /* a block is found then will allocate the syms */
1235 /* will also gather the auto inits present */
1236 /*-----------------------------------------------------------------*/
1238 processBlockVars (ast * tree, int *stack, int action)
1243 /* if this is a block */
1244 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1248 if (action == ALLOCATE)
1250 *stack += allocVariables (tree->values.sym);
1251 autoInit = gatherAutoInit (tree->values.sym);
1253 /* if there are auto inits then do them */
1255 tree->left = newNode (NULLOP, autoInit, tree->left);
1257 else /* action is deallocate */
1258 deallocLocal (tree->values.sym);
1261 processBlockVars (tree->left, stack, action);
1262 processBlockVars (tree->right, stack, action);
1267 /*-------------------------------------------------------------*/
1268 /* constExprTree - returns TRUE if this tree is a constant */
1270 /*-------------------------------------------------------------*/
1271 bool constExprTree (ast *cexpr) {
1277 cexpr = decorateType (resolveSymbols (cexpr));
1279 switch (cexpr->type)
1282 if (IS_AST_LIT_VALUE(cexpr)) {
1283 // this is a literal
1286 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1287 // a function's address will never change
1290 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1291 // an array's address will never change
1294 if (IS_AST_SYM_VALUE(cexpr) &&
1295 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1296 // a symbol in code space will never change
1297 // This is only for the 'char *s="hallo"' case and will have to leave
1298 //printf(" code space symbol");
1303 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1304 "unexpected link in expression tree\n");
1307 if (cexpr->opval.op==ARRAYINIT) {
1308 // this is a list of literals
1311 if (cexpr->opval.op=='=') {
1312 return constExprTree(cexpr->right);
1314 if (cexpr->opval.op==CAST) {
1315 // cast ignored, maybe we should throw a warning here?
1316 return constExprTree(cexpr->right);
1318 if (cexpr->opval.op=='&') {
1321 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1324 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1329 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1334 /*-----------------------------------------------------------------*/
1335 /* constExprValue - returns the value of a constant expression */
1336 /* or NULL if it is not a constant expression */
1337 /*-----------------------------------------------------------------*/
1339 constExprValue (ast * cexpr, int check)
1341 cexpr = decorateType (resolveSymbols (cexpr));
1343 /* if this is not a constant then */
1344 if (!IS_LITERAL (cexpr->ftype))
1346 /* then check if this is a literal array
1348 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1349 SPEC_CVAL (cexpr->etype).v_char &&
1350 IS_ARRAY (cexpr->ftype))
1352 value *val = valFromType (cexpr->ftype);
1353 SPEC_SCLS (val->etype) = S_LITERAL;
1354 val->sym = cexpr->opval.val->sym;
1355 val->sym->type = copyLinkChain (cexpr->ftype);
1356 val->sym->etype = getSpec (val->sym->type);
1357 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1361 /* if we are casting a literal value then */
1362 if (IS_AST_OP (cexpr) &&
1363 cexpr->opval.op == CAST &&
1364 IS_LITERAL (cexpr->right->ftype))
1366 return valCastLiteral (cexpr->ftype,
1367 floatFromVal (cexpr->right->opval.val));
1370 if (IS_AST_VALUE (cexpr))
1372 return cexpr->opval.val;
1376 werror (E_CONST_EXPECTED, "found expression");
1381 /* return the value */
1382 return cexpr->opval.val;
1386 /*-----------------------------------------------------------------*/
1387 /* isLabelInAst - will return true if a given label is found */
1388 /*-----------------------------------------------------------------*/
1390 isLabelInAst (symbol * label, ast * tree)
1392 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1395 if (IS_AST_OP (tree) &&
1396 tree->opval.op == LABEL &&
1397 isSymbolEqual (AST_SYMBOL (tree->left), label))
1400 return isLabelInAst (label, tree->right) &&
1401 isLabelInAst (label, tree->left);
1405 /*-----------------------------------------------------------------*/
1406 /* isLoopCountable - return true if the loop count can be determi- */
1407 /* -ned at compile time . */
1408 /*-----------------------------------------------------------------*/
1410 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1411 symbol ** sym, ast ** init, ast ** end)
1414 /* the loop is considered countable if the following
1415 conditions are true :-
1417 a) initExpr :- <sym> = <const>
1418 b) condExpr :- <sym> < <const1>
1419 c) loopExpr :- <sym> ++
1422 /* first check the initExpr */
1423 if (IS_AST_OP (initExpr) &&
1424 initExpr->opval.op == '=' && /* is assignment */
1425 IS_AST_SYM_VALUE (initExpr->left))
1426 { /* left is a symbol */
1428 *sym = AST_SYMBOL (initExpr->left);
1429 *init = initExpr->right;
1434 /* for now the symbol has to be of
1436 if (!IS_INTEGRAL ((*sym)->type))
1439 /* now check condExpr */
1440 if (IS_AST_OP (condExpr))
1443 switch (condExpr->opval.op)
1446 if (IS_AST_SYM_VALUE (condExpr->left) &&
1447 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1448 IS_AST_LIT_VALUE (condExpr->right))
1450 *end = condExpr->right;
1456 if (IS_AST_OP (condExpr->left) &&
1457 condExpr->left->opval.op == '>' &&
1458 IS_AST_LIT_VALUE (condExpr->left->right) &&
1459 IS_AST_SYM_VALUE (condExpr->left->left) &&
1460 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1463 *end = newNode ('+', condExpr->left->right,
1464 newAst_VALUE (constVal ("1")));
1475 /* check loop expression is of the form <sym>++ */
1476 if (!IS_AST_OP (loopExpr))
1479 /* check if <sym> ++ */
1480 if (loopExpr->opval.op == INC_OP)
1486 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1487 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1494 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1495 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1503 if (loopExpr->opval.op == ADD_ASSIGN)
1506 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1507 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1508 IS_AST_LIT_VALUE (loopExpr->right) &&
1509 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1517 /*-----------------------------------------------------------------*/
1518 /* astHasVolatile - returns true if ast contains any volatile */
1519 /*-----------------------------------------------------------------*/
1521 astHasVolatile (ast * tree)
1526 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1529 if (IS_AST_OP (tree))
1530 return astHasVolatile (tree->left) ||
1531 astHasVolatile (tree->right);
1536 /*-----------------------------------------------------------------*/
1537 /* astHasPointer - return true if the ast contains any ptr variable */
1538 /*-----------------------------------------------------------------*/
1540 astHasPointer (ast * tree)
1545 if (IS_AST_LINK (tree))
1548 /* if we hit an array expression then check
1549 only the left side */
1550 if (IS_AST_OP (tree) && tree->opval.op == '[')
1551 return astHasPointer (tree->left);
1553 if (IS_AST_VALUE (tree))
1554 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1556 return astHasPointer (tree->left) ||
1557 astHasPointer (tree->right);
1561 /*-----------------------------------------------------------------*/
1562 /* astHasSymbol - return true if the ast has the given symbol */
1563 /*-----------------------------------------------------------------*/
1565 astHasSymbol (ast * tree, symbol * sym)
1567 if (!tree || IS_AST_LINK (tree))
1570 if (IS_AST_VALUE (tree))
1572 if (IS_AST_SYM_VALUE (tree))
1573 return isSymbolEqual (AST_SYMBOL (tree), sym);
1578 return astHasSymbol (tree->left, sym) ||
1579 astHasSymbol (tree->right, sym);
1582 /*-----------------------------------------------------------------*/
1583 /* astHasDeref - return true if the ast has an indirect access */
1584 /*-----------------------------------------------------------------*/
1586 astHasDeref (ast * tree)
1588 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1591 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1593 return astHasDeref (tree->left) || astHasDeref (tree->right);
1596 /*-----------------------------------------------------------------*/
1597 /* isConformingBody - the loop body has to conform to a set of rules */
1598 /* for the loop to be considered reversible read on for rules */
1599 /*-----------------------------------------------------------------*/
1601 isConformingBody (ast * pbody, symbol * sym, ast * body)
1604 /* we are going to do a pre-order traversal of the
1605 tree && check for the following conditions. (essentially
1606 a set of very shallow tests )
1607 a) the sym passed does not participate in
1608 any arithmetic operation
1609 b) There are no function calls
1610 c) all jumps are within the body
1611 d) address of loop control variable not taken
1612 e) if an assignment has a pointer on the
1613 left hand side make sure right does not have
1614 loop control variable */
1616 /* if we reach the end or a leaf then true */
1617 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1620 /* if anything else is "volatile" */
1621 if (IS_VOLATILE (TETYPE (pbody)))
1624 /* we will walk the body in a pre-order traversal for
1626 switch (pbody->opval.op)
1628 /*------------------------------------------------------------------*/
1630 // if the loopvar is used as an index
1631 if (astHasSymbol(pbody->right, sym)) {
1634 return isConformingBody (pbody->right, sym, body);
1636 /*------------------------------------------------------------------*/
1641 /*------------------------------------------------------------------*/
1645 /* sure we are not sym is not modified */
1647 IS_AST_SYM_VALUE (pbody->left) &&
1648 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1652 IS_AST_SYM_VALUE (pbody->right) &&
1653 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1658 /*------------------------------------------------------------------*/
1660 case '*': /* can be unary : if right is null then unary operation */
1665 /* if right is NULL then unary operation */
1666 /*------------------------------------------------------------------*/
1667 /*----------------------------*/
1669 /*----------------------------*/
1672 if (IS_AST_SYM_VALUE (pbody->left) &&
1673 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1676 return isConformingBody (pbody->left, sym, body);
1680 if (astHasSymbol (pbody->left, sym) ||
1681 astHasSymbol (pbody->right, sym))
1686 /*------------------------------------------------------------------*/
1694 if (IS_AST_SYM_VALUE (pbody->left) &&
1695 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1698 if (IS_AST_SYM_VALUE (pbody->right) &&
1699 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1702 return isConformingBody (pbody->left, sym, body) &&
1703 isConformingBody (pbody->right, sym, body);
1711 if (IS_AST_SYM_VALUE (pbody->left) &&
1712 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1714 return isConformingBody (pbody->left, sym, body);
1716 /*------------------------------------------------------------------*/
1728 case SIZEOF: /* evaluate wihout code generation */
1730 if (IS_AST_SYM_VALUE (pbody->left) &&
1731 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1734 if (IS_AST_SYM_VALUE (pbody->right) &&
1735 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1738 return isConformingBody (pbody->left, sym, body) &&
1739 isConformingBody (pbody->right, sym, body);
1741 /*------------------------------------------------------------------*/
1744 /* if left has a pointer & right has loop
1745 control variable then we cannot */
1746 if (astHasPointer (pbody->left) &&
1747 astHasSymbol (pbody->right, sym))
1749 if (astHasVolatile (pbody->left))
1752 if (IS_AST_SYM_VALUE (pbody->left)) {
1753 // if the loopvar has an assignment
1754 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1756 // if the loopvar is used in another (maybe conditional) block
1757 if (astHasSymbol (pbody->right, sym) &&
1758 (pbody->level >= body->level)) {
1763 if (astHasVolatile (pbody->left))
1766 if (astHasDeref(pbody->right)) return FALSE;
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1780 assert ("Parser should not have generated this\n");
1782 /*------------------------------------------------------------------*/
1783 /*----------------------------*/
1784 /* comma operator */
1785 /*----------------------------*/
1787 return isConformingBody (pbody->left, sym, body) &&
1788 isConformingBody (pbody->right, sym, body);
1790 /*------------------------------------------------------------------*/
1791 /*----------------------------*/
1793 /*----------------------------*/
1795 /* if local & not passed as paramater then ok */
1796 if (sym->level && !astHasSymbol(pbody->right,sym))
1800 /*------------------------------------------------------------------*/
1801 /*----------------------------*/
1802 /* return statement */
1803 /*----------------------------*/
1808 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1813 if (astHasSymbol (pbody->left, sym))
1820 return isConformingBody (pbody->left, sym, body) &&
1821 isConformingBody (pbody->right, sym, body);
1827 /*-----------------------------------------------------------------*/
1828 /* isLoopReversible - takes a for loop as input && returns true */
1829 /* if the for loop is reversible. If yes will set the value of */
1830 /* the loop control var & init value & termination value */
1831 /*-----------------------------------------------------------------*/
1833 isLoopReversible (ast * loop, symbol ** loopCntrl,
1834 ast ** init, ast ** end)
1836 /* if option says don't do it then don't */
1837 if (optimize.noLoopReverse)
1839 /* there are several tests to determine this */
1841 /* for loop has to be of the form
1842 for ( <sym> = <const1> ;
1843 [<sym> < <const2>] ;
1844 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1846 if (!isLoopCountable (AST_FOR (loop, initExpr),
1847 AST_FOR (loop, condExpr),
1848 AST_FOR (loop, loopExpr),
1849 loopCntrl, init, end))
1852 /* now do some serious checking on the body of the loop
1855 return isConformingBody (loop->left, *loopCntrl, loop->left);
1859 /*-----------------------------------------------------------------*/
1860 /* replLoopSym - replace the loop sym by loop sym -1 */
1861 /*-----------------------------------------------------------------*/
1863 replLoopSym (ast * body, symbol * sym)
1866 if (!body || IS_AST_LINK (body))
1869 if (IS_AST_SYM_VALUE (body))
1872 if (isSymbolEqual (AST_SYMBOL (body), sym))
1876 body->opval.op = '-';
1877 body->left = newAst_VALUE (symbolVal (sym));
1878 body->right = newAst_VALUE (constVal ("1"));
1886 replLoopSym (body->left, sym);
1887 replLoopSym (body->right, sym);
1891 /*-----------------------------------------------------------------*/
1892 /* reverseLoop - do the actual loop reversal */
1893 /*-----------------------------------------------------------------*/
1895 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1899 /* create the following tree
1904 if (sym) goto for_continue ;
1907 /* put it together piece by piece */
1908 rloop = newNode (NULLOP,
1909 createIf (newAst_VALUE (symbolVal (sym)),
1911 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1914 newAst_VALUE (symbolVal (sym)),
1917 replLoopSym (loop->left, sym);
1918 setAstLineno (rloop, init->lineno);
1920 rloop = newNode (NULLOP,
1922 newAst_VALUE (symbolVal (sym)),
1923 newNode ('-', end, init)),
1924 createLabel (AST_FOR (loop, continueLabel),
1928 newNode (SUB_ASSIGN,
1929 newAst_VALUE (symbolVal (sym)),
1930 newAst_VALUE (constVal ("1"))),
1933 rloop->lineno=init->lineno;
1934 return decorateType (rloop);
1938 /*-----------------------------------------------------------------*/
1939 /* searchLitOp - search tree (*ops only) for an ast with literal */
1940 /*-----------------------------------------------------------------*/
1942 searchLitOp (ast *tree, ast **parent, const char *ops)
1946 if (tree && optimize.global_cse)
1948 /* is there a literal operand? */
1950 IS_AST_OP(tree->right) &&
1951 tree->right->right &&
1952 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1954 if (IS_LITERAL (RTYPE (tree->right)) ^
1955 IS_LITERAL (LTYPE (tree->right)))
1957 tree->right->decorated = 0;
1958 tree->decorated = 0;
1962 ret = searchLitOp (tree->right, parent, ops);
1967 IS_AST_OP(tree->left) &&
1968 tree->left->right &&
1969 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1971 if (IS_LITERAL (RTYPE (tree->left)) ^
1972 IS_LITERAL (LTYPE (tree->left)))
1974 tree->left->decorated = 0;
1975 tree->decorated = 0;
1979 ret = searchLitOp (tree->left, parent, ops);
1987 /*-----------------------------------------------------------------*/
1988 /* decorateType - compute type for this tree also does type checking */
1989 /* this is done bottom up, since type have to flow upwards */
1990 /* it also does constant folding, and paramater checking */
1991 /*-----------------------------------------------------------------*/
1993 decorateType (ast * tree)
2001 /* if already has type then do nothing */
2002 if (tree->decorated)
2005 tree->decorated = 1;
2008 /* print the line */
2009 /* if not block & function */
2010 if (tree->type == EX_OP &&
2011 (tree->opval.op != FUNCTION &&
2012 tree->opval.op != BLOCK &&
2013 tree->opval.op != NULLOP))
2015 filename = tree->filename;
2016 lineno = tree->lineno;
2020 /* if any child is an error | this one is an error do nothing */
2021 if (tree->isError ||
2022 (tree->left && tree->left->isError) ||
2023 (tree->right && tree->right->isError))
2026 /*------------------------------------------------------------------*/
2027 /*----------------------------*/
2028 /* leaf has been reached */
2029 /*----------------------------*/
2030 lineno=tree->lineno;
2031 /* if this is of type value */
2032 /* just get the type */
2033 if (tree->type == EX_VALUE)
2036 if (IS_LITERAL (tree->opval.val->etype))
2039 /* if this is a character array then declare it */
2040 if (IS_ARRAY (tree->opval.val->type))
2041 tree->opval.val = stringToSymbol (tree->opval.val);
2043 /* otherwise just copy the type information */
2044 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2048 if (tree->opval.val->sym)
2050 /* if the undefined flag is set then give error message */
2051 if (tree->opval.val->sym->undefined)
2053 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2055 TTYPE (tree) = TETYPE (tree) =
2056 tree->opval.val->type = tree->opval.val->sym->type =
2057 tree->opval.val->etype = tree->opval.val->sym->etype =
2058 copyLinkChain (INTTYPE);
2063 /* if impilicit i.e. struct/union member then no type */
2064 if (tree->opval.val->sym->implicit)
2065 TTYPE (tree) = TETYPE (tree) = NULL;
2070 /* else copy the type */
2071 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2073 /* and mark it as referenced */
2074 tree->opval.val->sym->isref = 1;
2082 /* if type link for the case of cast */
2083 if (tree->type == EX_LINK)
2085 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2092 dtl = decorateType (tree->left);
2093 /* delay right side for '?' operator since conditional macro expansions might
2095 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2097 /* this is to take care of situations
2098 when the tree gets rewritten */
2099 if (dtl != tree->left)
2101 if (dtr != tree->right)
2103 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2106 if (IS_AST_OP(tree) &&
2107 (tree->opval.op == CAST || tree->opval.op == '=') &&
2108 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2109 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2110 // this is a cast/assign to a bigger type
2111 if (IS_AST_OP(tree->right) &&
2112 IS_INTEGRAL(tree->right->ftype) &&
2113 (tree->right->opval.op == LEFT_OP ||
2114 tree->right->opval.op == '*' ||
2115 tree->right->opval.op == '+' ||
2116 tree->right->opval.op == '-') &&
2117 tree->right->right) {
2118 // we should cast an operand instead of the result
2119 tree->right->decorated = 0;
2120 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2122 tree->right = decorateType(tree->right);
2127 /* depending on type of operator do */
2129 switch (tree->opval.op)
2131 /*------------------------------------------------------------------*/
2132 /*----------------------------*/
2134 /*----------------------------*/
2137 /* determine which is the array & which the index */
2138 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2141 ast *tempTree = tree->left;
2142 tree->left = tree->right;
2143 tree->right = tempTree;
2146 /* first check if this is a array or a pointer */
2147 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2149 werror (E_NEED_ARRAY_PTR, "[]");
2150 goto errorTreeReturn;
2153 /* check if the type of the idx */
2154 if (!IS_INTEGRAL (RTYPE (tree)))
2156 werror (E_IDX_NOT_INT);
2157 goto errorTreeReturn;
2160 /* if the left is an rvalue then error */
2163 werror (E_LVALUE_REQUIRED, "array access");
2164 goto errorTreeReturn;
2167 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2170 /*------------------------------------------------------------------*/
2171 /*----------------------------*/
2173 /*----------------------------*/
2175 /* if this is not a structure */
2176 if (!IS_STRUCT (LTYPE (tree)))
2178 werror (E_STRUCT_UNION, ".");
2179 goto errorTreeReturn;
2181 TTYPE (tree) = structElemType (LTYPE (tree),
2182 (tree->right->type == EX_VALUE ?
2183 tree->right->opval.val : NULL));
2184 TETYPE (tree) = getSpec (TTYPE (tree));
2187 /*------------------------------------------------------------------*/
2188 /*----------------------------*/
2189 /* struct/union pointer */
2190 /*----------------------------*/
2192 /* if not pointer to a structure */
2193 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2195 werror (E_PTR_REQD);
2196 goto errorTreeReturn;
2199 if (!IS_STRUCT (LTYPE (tree)->next))
2201 werror (E_STRUCT_UNION, "->");
2202 goto errorTreeReturn;
2205 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2206 (tree->right->type == EX_VALUE ?
2207 tree->right->opval.val : NULL));
2208 TETYPE (tree) = getSpec (TTYPE (tree));
2210 /* adjust the storage class */
2211 switch (DCL_TYPE(tree->left->ftype)) {
2213 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2216 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2219 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2222 SPEC_SCLS (TETYPE (tree)) = 0;
2225 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2228 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2231 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2234 SPEC_SCLS (TETYPE (tree)) = 0;
2241 /* This breaks with extern declarations, bitfields, and perhaps other */
2242 /* cases (gcse). Let's leave this optimization disabled for now and */
2243 /* ponder if there's a safe way to do this. -- EEP */
2245 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2246 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2248 /* If defined struct type at addr var
2249 then rewrite (&struct var)->member
2251 and define membertype at (addr+offsetof(struct var,member)) temp
2254 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2255 AST_SYMBOL(tree->right));
2257 sym = newSymbol(genSymName (0), 0);
2258 sym->type = TTYPE (tree);
2259 sym->etype = getSpec(sym->type);
2260 sym->lineDef = tree->lineno;
2263 SPEC_STAT (sym->etype) = 1;
2264 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2266 SPEC_ABSA(sym->etype) = 1;
2267 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2270 AST_VALUE (tree) = symbolVal(sym);
2273 tree->type = EX_VALUE;
2281 /*------------------------------------------------------------------*/
2282 /*----------------------------*/
2283 /* ++/-- operation */
2284 /*----------------------------*/
2288 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2289 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2290 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2291 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2300 /*------------------------------------------------------------------*/
2301 /*----------------------------*/
2303 /*----------------------------*/
2304 case '&': /* can be unary */
2305 /* if right is NULL then unary operation */
2306 if (tree->right) /* not an unary operation */
2309 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2311 werror (E_BITWISE_OP);
2312 werror (W_CONTINUE, "left & right types are ");
2313 printTypeChain (LTYPE (tree), stderr);
2314 fprintf (stderr, ",");
2315 printTypeChain (RTYPE (tree), stderr);
2316 fprintf (stderr, "\n");
2317 goto errorTreeReturn;
2320 /* if they are both literal */
2321 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2323 tree->type = EX_VALUE;
2324 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2325 valFromType (RETYPE (tree)), '&');
2327 tree->right = tree->left = NULL;
2328 TETYPE (tree) = tree->opval.val->etype;
2329 TTYPE (tree) = tree->opval.val->type;
2333 /* see if this is a GETHBIT operation if yes
2336 ast *otree = optimizeGetHbit (tree);
2339 return decorateType (otree);
2343 computeType (LTYPE (tree), RTYPE (tree));
2344 TETYPE (tree) = getSpec (TTYPE (tree));
2346 /* if left is a literal exchange left & right */
2347 if (IS_LITERAL (LTYPE (tree)))
2349 ast *tTree = tree->left;
2350 tree->left = tree->right;
2351 tree->right = tTree;
2354 /* if right is a literal and */
2355 /* we can find a 2nd literal in a and-tree then */
2356 /* rearrange the tree */
2357 if (IS_LITERAL (RTYPE (tree)))
2360 ast *litTree = searchLitOp (tree, &parent, "&");
2363 ast *tTree = litTree->left;
2364 litTree->left = tree->right;
2365 tree->right = tTree;
2366 /* both operands in tTree are literal now */
2367 decorateType (parent);
2371 LRVAL (tree) = RRVAL (tree) = 1;
2375 /*------------------------------------------------------------------*/
2376 /*----------------------------*/
2378 /*----------------------------*/
2379 p = newLink (DECLARATOR);
2380 /* if bit field then error */
2381 if (IS_BITVAR (tree->left->etype))
2383 werror (E_ILLEGAL_ADDR, "address of bit variable");
2384 goto errorTreeReturn;
2387 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2389 werror (E_ILLEGAL_ADDR, "address of register variable");
2390 goto errorTreeReturn;
2393 if (IS_FUNC (LTYPE (tree)))
2395 // this ought to be ignored
2396 return (tree->left);
2399 if (IS_LITERAL(LTYPE(tree)))
2401 werror (E_ILLEGAL_ADDR, "address of literal");
2402 goto errorTreeReturn;
2407 werror (E_LVALUE_REQUIRED, "address of");
2408 goto errorTreeReturn;
2411 DCL_TYPE (p) = POINTER;
2412 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2413 DCL_TYPE (p) = CPOINTER;
2414 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2415 DCL_TYPE (p) = FPOINTER;
2416 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2417 DCL_TYPE (p) = PPOINTER;
2418 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2419 DCL_TYPE (p) = IPOINTER;
2420 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2421 DCL_TYPE (p) = EEPPOINTER;
2422 else if (SPEC_OCLS(tree->left->etype))
2423 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2425 DCL_TYPE (p) = POINTER;
2427 if (IS_AST_SYM_VALUE (tree->left))
2429 AST_SYMBOL (tree->left)->addrtaken = 1;
2430 AST_SYMBOL (tree->left)->allocreq = 1;
2433 p->next = LTYPE (tree);
2435 TETYPE (tree) = getSpec (TTYPE (tree));
2440 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2441 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2443 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2444 AST_SYMBOL(tree->left->right));
2445 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2446 valueFromLit(element->offset));
2449 tree->type = EX_VALUE;
2450 tree->values.literalFromCast = 1;
2456 /*------------------------------------------------------------------*/
2457 /*----------------------------*/
2459 /*----------------------------*/
2461 /* if the rewrite succeeds then don't go any furthur */
2463 ast *wtree = optimizeRRCRLC (tree);
2465 return decorateType (wtree);
2467 wtree = optimizeSWAP (tree);
2469 return decorateType (wtree);
2474 /* if left is a literal exchange left & right */
2475 if (IS_LITERAL (LTYPE (tree)))
2477 ast *tTree = tree->left;
2478 tree->left = tree->right;
2479 tree->right = tTree;
2482 /* if right is a literal and */
2483 /* we can find a 2nd literal in a or-tree then */
2484 /* rearrange the tree */
2485 if (IS_LITERAL (RTYPE (tree)))
2488 ast *litTree = searchLitOp (tree, &parent, "|");
2491 ast *tTree = litTree->left;
2492 litTree->left = tree->right;
2493 tree->right = tTree;
2494 /* both operands in tTree are literal now */
2495 decorateType (parent);
2498 /*------------------------------------------------------------------*/
2499 /*----------------------------*/
2501 /*----------------------------*/
2503 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2505 werror (E_BITWISE_OP);
2506 werror (W_CONTINUE, "left & right types are ");
2507 printTypeChain (LTYPE (tree), stderr);
2508 fprintf (stderr, ",");
2509 printTypeChain (RTYPE (tree), stderr);
2510 fprintf (stderr, "\n");
2511 goto errorTreeReturn;
2514 /* if they are both literal then */
2515 /* rewrite the tree */
2516 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2518 tree->type = EX_VALUE;
2519 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2520 valFromType (RETYPE (tree)),
2522 tree->right = tree->left = NULL;
2523 TETYPE (tree) = tree->opval.val->etype;
2524 TTYPE (tree) = tree->opval.val->type;
2528 /* if left is a literal exchange left & right */
2529 if (IS_LITERAL (LTYPE (tree)))
2531 ast *tTree = tree->left;
2532 tree->left = tree->right;
2533 tree->right = tTree;
2536 /* if right is a literal and */
2537 /* we can find a 2nd literal in a xor-tree then */
2538 /* rearrange the tree */
2539 if (IS_LITERAL (RTYPE (tree)))
2542 ast *litTree = searchLitOp (tree, &parent, "^");
2545 ast *tTree = litTree->left;
2546 litTree->left = tree->right;
2547 tree->right = tTree;
2548 /* both operands in litTree are literal now */
2549 decorateType (parent);
2553 LRVAL (tree) = RRVAL (tree) = 1;
2554 TETYPE (tree) = getSpec (TTYPE (tree) =
2555 computeType (LTYPE (tree),
2558 /*------------------------------------------------------------------*/
2559 /*----------------------------*/
2561 /*----------------------------*/
2563 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2565 werror (E_INVALID_OP, "divide");
2566 goto errorTreeReturn;
2568 /* if they are both literal then */
2569 /* rewrite the tree */
2570 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2572 tree->type = EX_VALUE;
2573 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2574 valFromType (RETYPE (tree)));
2575 tree->right = tree->left = NULL;
2576 TETYPE (tree) = getSpec (TTYPE (tree) =
2577 tree->opval.val->type);
2581 LRVAL (tree) = RRVAL (tree) = 1;
2582 TETYPE (tree) = getSpec (TTYPE (tree) =
2583 computeType (LTYPE (tree),
2586 /* if right is a literal and */
2587 /* left is also a division by a literal then */
2588 /* rearrange the tree */
2589 if (IS_LITERAL (RTYPE (tree))
2590 /* avoid infinite loop */
2591 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2594 ast *litTree = searchLitOp (tree, &parent, "/");
2597 if (IS_LITERAL (RTYPE (litTree)))
2600 litTree->right = newNode ('*', litTree->right, tree->right);
2601 litTree->right->lineno = tree->lineno;
2603 tree->right->opval.val = constVal ("1");
2604 decorateType (parent);
2608 /* litTree->left is literal: no gcse possible.
2609 We can't call decorateType(parent), because
2610 this would cause an infinit loop. */
2611 parent->decorated = 1;
2612 decorateType (litTree);
2619 /*------------------------------------------------------------------*/
2620 /*----------------------------*/
2622 /*----------------------------*/
2624 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2626 werror (E_BITWISE_OP);
2627 werror (W_CONTINUE, "left & right types are ");
2628 printTypeChain (LTYPE (tree), stderr);
2629 fprintf (stderr, ",");
2630 printTypeChain (RTYPE (tree), stderr);
2631 fprintf (stderr, "\n");
2632 goto errorTreeReturn;
2634 /* if they are both literal then */
2635 /* rewrite the tree */
2636 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2638 tree->type = EX_VALUE;
2639 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2640 valFromType (RETYPE (tree)));
2641 tree->right = tree->left = NULL;
2642 TETYPE (tree) = getSpec (TTYPE (tree) =
2643 tree->opval.val->type);
2646 LRVAL (tree) = RRVAL (tree) = 1;
2647 TETYPE (tree) = getSpec (TTYPE (tree) =
2648 computeType (LTYPE (tree),
2652 /*------------------------------------------------------------------*/
2653 /*----------------------------*/
2654 /* address dereference */
2655 /*----------------------------*/
2656 case '*': /* can be unary : if right is null then unary operation */
2659 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2661 werror (E_PTR_REQD);
2662 goto errorTreeReturn;
2667 werror (E_LVALUE_REQUIRED, "pointer deref");
2668 goto errorTreeReturn;
2670 if (IS_ADDRESS_OF_OP(tree->left))
2672 /* replace *&obj with obj */
2673 return tree->left->left;
2675 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2676 TETYPE (tree) = getSpec (TTYPE (tree));
2677 /* adjust the storage class */
2678 switch (DCL_TYPE(tree->left->ftype)) {
2680 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2683 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2686 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2689 SPEC_SCLS (TETYPE (tree)) = 0;
2692 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2695 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2698 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2701 SPEC_SCLS (TETYPE (tree)) = 0;
2710 /*------------------------------------------------------------------*/
2711 /*----------------------------*/
2712 /* multiplication */
2713 /*----------------------------*/
2714 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2716 werror (E_INVALID_OP, "multiplication");
2717 goto errorTreeReturn;
2720 /* if they are both literal then */
2721 /* rewrite the tree */
2722 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2724 tree->type = EX_VALUE;
2725 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2726 valFromType (RETYPE (tree)));
2727 tree->right = tree->left = NULL;
2728 TETYPE (tree) = getSpec (TTYPE (tree) =
2729 tree->opval.val->type);
2733 /* if left is a literal exchange left & right */
2734 if (IS_LITERAL (LTYPE (tree)))
2736 ast *tTree = tree->left;
2737 tree->left = tree->right;
2738 tree->right = tTree;
2741 /* if right is a literal and */
2742 /* we can find a 2nd literal in a mul-tree then */
2743 /* rearrange the tree */
2744 if (IS_LITERAL (RTYPE (tree)))
2747 ast *litTree = searchLitOp (tree, &parent, "*");
2750 ast *tTree = litTree->left;
2751 litTree->left = tree->right;
2752 tree->right = tTree;
2753 /* both operands in litTree are literal now */
2754 decorateType (parent);
2758 LRVAL (tree) = RRVAL (tree) = 1;
2759 TETYPE (tree) = getSpec (TTYPE (tree) =
2760 computeType (LTYPE (tree),
2763 /* promote result to int if left & right are char
2764 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2765 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2766 SPEC_NOUN(TETYPE(tree)) = V_INT;
2771 /*------------------------------------------------------------------*/
2772 /*----------------------------*/
2773 /* unary '+' operator */
2774 /*----------------------------*/
2779 if (!IS_INTEGRAL (LTYPE (tree)))
2781 werror (E_UNARY_OP, '+');
2782 goto errorTreeReturn;
2785 /* if left is a literal then do it */
2786 if (IS_LITERAL (LTYPE (tree)))
2788 tree->type = EX_VALUE;
2789 tree->opval.val = valFromType (LETYPE (tree));
2791 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2795 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2799 /*------------------------------------------------------------------*/
2800 /*----------------------------*/
2802 /*----------------------------*/
2804 /* this is not a unary operation */
2805 /* if both pointers then problem */
2806 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2807 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2809 werror (E_PTR_PLUS_PTR);
2810 goto errorTreeReturn;
2813 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2814 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2816 werror (E_PLUS_INVALID, "+");
2817 goto errorTreeReturn;
2820 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2821 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2823 werror (E_PLUS_INVALID, "+");
2824 goto errorTreeReturn;
2826 /* if they are both literal then */
2827 /* rewrite the tree */
2828 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2830 tree->type = EX_VALUE;
2831 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2832 valFromType (RETYPE (tree)));
2833 tree->right = tree->left = NULL;
2834 TETYPE (tree) = getSpec (TTYPE (tree) =
2835 tree->opval.val->type);
2839 /* if the right is a pointer or left is a literal
2840 xchange left & right */
2841 if (IS_ARRAY (RTYPE (tree)) ||
2842 IS_PTR (RTYPE (tree)) ||
2843 IS_LITERAL (LTYPE (tree)))
2845 ast *tTree = tree->left;
2846 tree->left = tree->right;
2847 tree->right = tTree;
2850 /* if right is a literal and */
2851 /* left is also an addition/subtraction with a literal then */
2852 /* rearrange the tree */
2853 if (IS_LITERAL (RTYPE (tree)))
2855 ast *litTree, *parent;
2856 litTree = searchLitOp (tree, &parent, "+-");
2859 if (litTree->opval.op == '+')
2862 ast *tTree = litTree->left;
2863 litTree->left = tree->right;
2864 tree->right = tree->left;
2867 else if (litTree->opval.op == '-')
2869 if (IS_LITERAL (RTYPE (litTree)))
2872 ast *tTree = litTree->left;
2873 litTree->left = tree->right;
2874 tree->right = tTree;
2879 ast *tTree = litTree->right;
2880 litTree->right = tree->right;
2881 tree->right = tTree;
2882 litTree->opval.op = '+';
2883 tree->opval.op = '-';
2886 decorateType (parent);
2890 LRVAL (tree) = RRVAL (tree) = 1;
2891 /* if the left is a pointer */
2892 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2893 TETYPE (tree) = getSpec (TTYPE (tree) =
2896 TETYPE (tree) = getSpec (TTYPE (tree) =
2897 computeType (LTYPE (tree),
2901 /*------------------------------------------------------------------*/
2902 /*----------------------------*/
2904 /*----------------------------*/
2905 case '-': /* can be unary */
2906 /* if right is null then unary */
2910 if (!IS_ARITHMETIC (LTYPE (tree)))
2912 werror (E_UNARY_OP, tree->opval.op);
2913 goto errorTreeReturn;
2916 /* if left is a literal then do it */
2917 if (IS_LITERAL (LTYPE (tree)))
2919 tree->type = EX_VALUE;
2920 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2922 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2923 SPEC_USIGN(TETYPE(tree)) = 0;
2927 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2931 /*------------------------------------------------------------------*/
2932 /*----------------------------*/
2934 /*----------------------------*/
2936 if (!(IS_PTR (LTYPE (tree)) ||
2937 IS_ARRAY (LTYPE (tree)) ||
2938 IS_ARITHMETIC (LTYPE (tree))))
2940 werror (E_PLUS_INVALID, "-");
2941 goto errorTreeReturn;
2944 if (!(IS_PTR (RTYPE (tree)) ||
2945 IS_ARRAY (RTYPE (tree)) ||
2946 IS_ARITHMETIC (RTYPE (tree))))
2948 werror (E_PLUS_INVALID, "-");
2949 goto errorTreeReturn;
2952 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2953 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2954 IS_INTEGRAL (RTYPE (tree))))
2956 werror (E_PLUS_INVALID, "-");
2957 goto errorTreeReturn;
2960 /* if they are both literal then */
2961 /* rewrite the tree */
2962 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2964 tree->type = EX_VALUE;
2965 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2966 valFromType (RETYPE (tree)));
2967 tree->right = tree->left = NULL;
2968 TETYPE (tree) = getSpec (TTYPE (tree) =
2969 tree->opval.val->type);
2973 /* if the left & right are equal then zero */
2974 if (isAstEqual (tree->left, tree->right))
2976 tree->type = EX_VALUE;
2977 tree->left = tree->right = NULL;
2978 tree->opval.val = constVal ("0");
2979 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2983 /* if both of them are pointers or arrays then */
2984 /* the result is going to be an integer */
2985 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2986 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2987 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2989 /* if only the left is a pointer */
2990 /* then result is a pointer */
2991 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2992 TETYPE (tree) = getSpec (TTYPE (tree) =
2995 TETYPE (tree) = getSpec (TTYPE (tree) =
2996 computeType (LTYPE (tree),
2999 LRVAL (tree) = RRVAL (tree) = 1;
3001 /* if right is a literal and */
3002 /* left is also an addition/subtraction with a literal then */
3003 /* rearrange the tree */
3004 if (IS_LITERAL (RTYPE (tree))
3005 /* avoid infinite loop */
3006 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3008 ast *litTree, *litParent;
3009 litTree = searchLitOp (tree, &litParent, "+-");
3012 if (litTree->opval.op == '+')
3015 litTree->right = newNode ('-', litTree->right, tree->right);
3016 litTree->right->lineno = tree->lineno;
3018 tree->right->opval.val = constVal ("0");
3020 else if (litTree->opval.op == '-')
3022 if (IS_LITERAL (RTYPE (litTree)))
3025 litTree->right = newNode ('+', tree->right, litTree->right);
3026 litTree->right->lineno = tree->lineno;
3028 tree->right->opval.val = constVal ("0");
3033 ast *tTree = litTree->right;
3034 litTree->right = tree->right;
3035 tree->right = tTree;
3038 decorateType (litParent);
3043 /*------------------------------------------------------------------*/
3044 /*----------------------------*/
3046 /*----------------------------*/
3048 /* can be only integral type */
3049 if (!IS_INTEGRAL (LTYPE (tree)))
3051 werror (E_UNARY_OP, tree->opval.op);
3052 goto errorTreeReturn;
3055 /* if left is a literal then do it */
3056 if (IS_LITERAL (LTYPE (tree)))
3058 tree->type = EX_VALUE;
3059 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3061 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3065 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3071 /*----------------------------*/
3073 /* can be pointer */
3074 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3075 !IS_PTR (LTYPE (tree)) &&
3076 !IS_ARRAY (LTYPE (tree)))
3078 werror (E_UNARY_OP, tree->opval.op);
3079 goto errorTreeReturn;
3082 /* if left is a literal then do it */
3083 if (IS_LITERAL (LTYPE (tree)))
3085 tree->type = EX_VALUE;
3086 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3088 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3092 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3095 /*------------------------------------------------------------------*/
3096 /*----------------------------*/
3098 /*----------------------------*/
3102 TTYPE (tree) = LTYPE (tree);
3103 TETYPE (tree) = LETYPE (tree);
3107 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3112 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3114 werror (E_SHIFT_OP_INVALID);
3115 werror (W_CONTINUE, "left & right types are ");
3116 printTypeChain (LTYPE (tree), stderr);
3117 fprintf (stderr, ",");
3118 printTypeChain (RTYPE (tree), stderr);
3119 fprintf (stderr, "\n");
3120 goto errorTreeReturn;
3123 /* if they are both literal then */
3124 /* rewrite the tree */
3125 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3127 tree->type = EX_VALUE;
3128 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3129 valFromType (RETYPE (tree)),
3130 (tree->opval.op == LEFT_OP ? 1 : 0));
3131 tree->right = tree->left = NULL;
3132 TETYPE (tree) = getSpec (TTYPE (tree) =
3133 tree->opval.val->type);
3137 /* if only the right side is a literal & we are
3138 shifting more than size of the left operand then zero */
3139 if (IS_LITERAL (RTYPE (tree)) &&
3140 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3141 (getSize (LTYPE (tree)) * 8))
3143 if (tree->opval.op==LEFT_OP ||
3144 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3145 lineno=tree->lineno;
3146 werror (W_SHIFT_CHANGED,
3147 (tree->opval.op == LEFT_OP ? "left" : "right"));
3148 tree->type = EX_VALUE;
3149 tree->left = tree->right = NULL;
3150 tree->opval.val = constVal ("0");
3151 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3155 LRVAL (tree) = RRVAL (tree) = 1;
3156 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3157 if (IS_LITERAL (TTYPE (tree)))
3158 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3164 /*----------------------------*/
3165 case CAST: /* change the type */
3166 /* cannot cast to an aggregate type */
3167 if (IS_AGGREGATE (LTYPE (tree)))
3169 werror (E_CAST_ILLEGAL);
3170 goto errorTreeReturn;
3173 /* make sure the type is complete and sane */
3174 checkTypeSanity(LETYPE(tree), "(cast)");
3177 /* if the right is a literal replace the tree */
3178 if (IS_LITERAL (RETYPE (tree))) {
3179 if (!IS_PTR (LTYPE (tree))) {
3180 tree->type = EX_VALUE;
3182 valCastLiteral (LTYPE (tree),
3183 floatFromVal (valFromType (RETYPE (tree))));
3186 TTYPE (tree) = tree->opval.val->type;
3187 tree->values.literalFromCast = 1;
3188 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3189 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3190 sym_link *rest = LTYPE(tree)->next;
3191 werror(W_LITERAL_GENERIC);
3192 TTYPE(tree) = newLink(DECLARATOR);
3193 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3194 TTYPE(tree)->next = rest;
3195 tree->left->opval.lnk = TTYPE(tree);
3198 TTYPE (tree) = LTYPE (tree);
3202 TTYPE (tree) = LTYPE (tree);
3206 #if 0 // this is already checked, now this could be explicit
3207 /* if pointer to struct then check names */
3208 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3209 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3210 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3212 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3213 SPEC_STRUCT(LETYPE(tree))->tag);
3216 if (IS_ADDRESS_OF_OP(tree->right)
3217 && IS_AST_SYM_VALUE (tree->right->left)
3218 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3220 tree->type = EX_VALUE;
3222 valCastLiteral (LTYPE (tree),
3223 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3224 TTYPE (tree) = tree->opval.val->type;
3225 TETYPE (tree) = getSpec (TTYPE (tree));
3228 tree->values.literalFromCast = 1;
3232 /* handle offsetof macro: */
3233 /* #define offsetof(TYPE, MEMBER) \ */
3234 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3235 if (IS_ADDRESS_OF_OP(tree->right)
3236 && IS_AST_OP (tree->right->left)
3237 && tree->right->left->opval.op == PTR_OP
3238 && IS_AST_OP (tree->right->left->left)
3239 && tree->right->left->left->opval.op == CAST
3240 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3242 symbol *element = getStructElement (
3243 SPEC_STRUCT (LETYPE(tree->right->left)),
3244 AST_SYMBOL(tree->right->left->right)
3248 tree->type = EX_VALUE;
3249 tree->opval.val = valCastLiteral (
3252 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3255 TTYPE (tree) = tree->opval.val->type;
3256 TETYPE (tree) = getSpec (TTYPE (tree));
3263 /* if the right is a literal replace the tree */
3264 if (IS_LITERAL (RETYPE (tree))) {
3265 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3266 /* rewrite (type *)litaddr
3268 and define type at litaddr temp
3269 (but only if type's storage class is not generic)
3271 ast *newTree = newNode ('&', NULL, NULL);
3274 TTYPE (newTree) = LTYPE (tree);
3275 TETYPE (newTree) = getSpec(LTYPE (tree));
3277 /* define a global symbol at the casted address*/
3278 sym = newSymbol(genSymName (0), 0);
3279 sym->type = LTYPE (tree)->next;
3281 sym->type = newLink (V_VOID);
3282 sym->etype = getSpec(sym->type);
3283 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3284 sym->lineDef = tree->lineno;
3287 SPEC_STAT (sym->etype) = 1;
3288 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3289 SPEC_ABSA(sym->etype) = 1;
3290 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3293 newTree->left = newAst_VALUE(symbolVal(sym));
3294 newTree->left->lineno = tree->lineno;
3295 LTYPE (newTree) = sym->type;
3296 LETYPE (newTree) = sym->etype;
3297 LLVAL (newTree) = 1;
3298 LRVAL (newTree) = 0;
3299 TLVAL (newTree) = 1;
3302 if (!IS_PTR (LTYPE (tree))) {
3303 tree->type = EX_VALUE;
3305 valCastLiteral (LTYPE (tree),
3306 floatFromVal (valFromType (RETYPE (tree))));
3307 TTYPE (tree) = tree->opval.val->type;
3310 tree->values.literalFromCast = 1;
3311 TETYPE (tree) = getSpec (TTYPE (tree));
3315 TTYPE (tree) = LTYPE (tree);
3319 TETYPE (tree) = getSpec (TTYPE (tree));
3323 /*------------------------------------------------------------------*/
3324 /*----------------------------*/
3325 /* logical &&, || */
3326 /*----------------------------*/
3329 /* each must me arithmetic type or be a pointer */
3330 if (!IS_PTR (LTYPE (tree)) &&
3331 !IS_ARRAY (LTYPE (tree)) &&
3332 !IS_INTEGRAL (LTYPE (tree)))
3334 werror (E_COMPARE_OP);
3335 goto errorTreeReturn;
3338 if (!IS_PTR (RTYPE (tree)) &&
3339 !IS_ARRAY (RTYPE (tree)) &&
3340 !IS_INTEGRAL (RTYPE (tree)))
3342 werror (E_COMPARE_OP);
3343 goto errorTreeReturn;
3345 /* if they are both literal then */
3346 /* rewrite the tree */
3347 if (IS_LITERAL (RTYPE (tree)) &&
3348 IS_LITERAL (LTYPE (tree)))
3350 tree->type = EX_VALUE;
3351 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3352 valFromType (RETYPE (tree)),
3354 tree->right = tree->left = NULL;
3355 TETYPE (tree) = getSpec (TTYPE (tree) =
3356 tree->opval.val->type);
3359 LRVAL (tree) = RRVAL (tree) = 1;
3360 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3363 /*------------------------------------------------------------------*/
3364 /*----------------------------*/
3365 /* comparison operators */
3366 /*----------------------------*/
3374 ast *lt = optimizeCompare (tree);
3380 /* if they are pointers they must be castable */
3381 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3383 if (tree->opval.op==EQ_OP &&
3384 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3385 // we cannot cast a gptr to a !gptr: switch the leaves
3386 struct ast *s=tree->left;
3387 tree->left=tree->right;
3390 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3392 werror (E_COMPARE_OP);
3393 fprintf (stderr, "comparring type ");
3394 printTypeChain (LTYPE (tree), stderr);
3395 fprintf (stderr, "to type ");
3396 printTypeChain (RTYPE (tree), stderr);
3397 fprintf (stderr, "\n");
3398 goto errorTreeReturn;
3401 /* else they should be promotable to one another */
3404 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3405 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3407 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3409 werror (E_COMPARE_OP);
3410 fprintf (stderr, "comparing type ");
3411 printTypeChain (LTYPE (tree), stderr);
3412 fprintf (stderr, "to type ");
3413 printTypeChain (RTYPE (tree), stderr);
3414 fprintf (stderr, "\n");
3415 goto errorTreeReturn;
3418 /* if unsigned value < 0 then always false */
3419 /* if (unsigned value) > 0 then (unsigned value) */
3420 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3421 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3423 if (tree->opval.op == '<') {
3426 if (tree->opval.op == '>') {
3430 /* if they are both literal then */
3431 /* rewrite the tree */
3432 if (IS_LITERAL (RTYPE (tree)) &&
3433 IS_LITERAL (LTYPE (tree)))
3435 tree->type = EX_VALUE;
3436 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3437 valFromType (RETYPE (tree)),
3439 tree->right = tree->left = NULL;
3440 TETYPE (tree) = getSpec (TTYPE (tree) =
3441 tree->opval.val->type);
3444 LRVAL (tree) = RRVAL (tree) = 1;
3445 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3448 /*------------------------------------------------------------------*/
3449 /*----------------------------*/
3451 /*----------------------------*/
3452 case SIZEOF: /* evaluate wihout code generation */
3453 /* change the type to a integer */
3454 tree->type = EX_VALUE;
3455 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3456 tree->opval.val = constVal (buffer);
3457 tree->right = tree->left = NULL;
3458 TETYPE (tree) = getSpec (TTYPE (tree) =
3459 tree->opval.val->type);
3462 /*------------------------------------------------------------------*/
3463 /*----------------------------*/
3465 /*----------------------------*/
3467 /* return typeof enum value */
3468 tree->type = EX_VALUE;
3471 if (IS_SPEC(tree->right->ftype)) {
3472 switch (SPEC_NOUN(tree->right->ftype)) {
3474 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3475 else typeofv = TYPEOF_INT;
3478 typeofv = TYPEOF_FLOAT;
3481 typeofv = TYPEOF_CHAR;
3484 typeofv = TYPEOF_VOID;
3487 typeofv = TYPEOF_STRUCT;
3490 typeofv = TYPEOF_BITFIELD;
3493 typeofv = TYPEOF_BIT;
3496 typeofv = TYPEOF_SBIT;
3502 switch (DCL_TYPE(tree->right->ftype)) {
3504 typeofv = TYPEOF_POINTER;
3507 typeofv = TYPEOF_FPOINTER;
3510 typeofv = TYPEOF_CPOINTER;
3513 typeofv = TYPEOF_GPOINTER;
3516 typeofv = TYPEOF_PPOINTER;
3519 typeofv = TYPEOF_IPOINTER;
3522 typeofv = TYPEOF_ARRAY;
3525 typeofv = TYPEOF_FUNCTION;
3531 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3532 tree->opval.val = constVal (buffer);
3533 tree->right = tree->left = NULL;
3534 TETYPE (tree) = getSpec (TTYPE (tree) =
3535 tree->opval.val->type);
3538 /*------------------------------------------------------------------*/
3539 /*----------------------------*/
3540 /* conditional operator '?' */
3541 /*----------------------------*/
3543 /* the type is value of the colon operator (on the right) */
3544 assert(IS_COLON_OP(tree->right));
3545 /* if already known then replace the tree : optimizer will do it
3546 but faster to do it here */
3547 if (IS_LITERAL (LTYPE(tree))) {
3548 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3549 return decorateType(tree->right->left) ;
3551 return decorateType(tree->right->right) ;
3554 tree->right = decorateType(tree->right);
3555 TTYPE (tree) = RTYPE(tree);
3556 TETYPE (tree) = getSpec (TTYPE (tree));
3561 /* if they don't match we have a problem */
3562 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3564 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3565 goto errorTreeReturn;
3568 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3569 TETYPE (tree) = getSpec (TTYPE (tree));
3573 #if 0 // assignment operators are converted by the parser
3574 /*------------------------------------------------------------------*/
3575 /*----------------------------*/
3576 /* assignment operators */
3577 /*----------------------------*/
3580 /* for these it must be both must be integral */
3581 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3582 !IS_ARITHMETIC (RTYPE (tree)))
3584 werror (E_OPS_INTEGRAL);
3585 goto errorTreeReturn;
3588 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3590 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3591 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3595 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3596 goto errorTreeReturn;
3607 /* for these it must be both must be integral */
3608 if (!IS_INTEGRAL (LTYPE (tree)) ||
3609 !IS_INTEGRAL (RTYPE (tree)))
3611 werror (E_OPS_INTEGRAL);
3612 goto errorTreeReturn;
3615 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3617 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3618 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3622 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3623 goto errorTreeReturn;
3629 /*------------------------------------------------------------------*/
3630 /*----------------------------*/
3632 /*----------------------------*/
3634 if (!(IS_PTR (LTYPE (tree)) ||
3635 IS_ARITHMETIC (LTYPE (tree))))
3637 werror (E_PLUS_INVALID, "-=");
3638 goto errorTreeReturn;
3641 if (!(IS_PTR (RTYPE (tree)) ||
3642 IS_ARITHMETIC (RTYPE (tree))))
3644 werror (E_PLUS_INVALID, "-=");
3645 goto errorTreeReturn;
3648 TETYPE (tree) = getSpec (TTYPE (tree) =
3649 computeType (LTYPE (tree),
3652 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3653 werror (E_CODE_WRITE, "-=");
3657 werror (E_LVALUE_REQUIRED, "-=");
3658 goto errorTreeReturn;
3664 /*------------------------------------------------------------------*/
3665 /*----------------------------*/
3667 /*----------------------------*/
3669 /* this is not a unary operation */
3670 /* if both pointers then problem */
3671 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3673 werror (E_PTR_PLUS_PTR);
3674 goto errorTreeReturn;
3677 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3679 werror (E_PLUS_INVALID, "+=");
3680 goto errorTreeReturn;
3683 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3685 werror (E_PLUS_INVALID, "+=");
3686 goto errorTreeReturn;
3689 TETYPE (tree) = getSpec (TTYPE (tree) =
3690 computeType (LTYPE (tree),
3693 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3694 werror (E_CODE_WRITE, "+=");
3698 werror (E_LVALUE_REQUIRED, "+=");
3699 goto errorTreeReturn;
3702 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3703 tree->opval.op = '=';
3708 /*------------------------------------------------------------------*/
3709 /*----------------------------*/
3710 /* straight assignemnt */
3711 /*----------------------------*/
3713 /* cannot be an aggregate */
3714 if (IS_AGGREGATE (LTYPE (tree)))
3716 werror (E_AGGR_ASSIGN);
3717 goto errorTreeReturn;
3720 /* they should either match or be castable */
3721 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3723 werror (E_TYPE_MISMATCH, "assignment", " ");
3724 printFromToType(RTYPE(tree),LTYPE(tree));
3727 /* if the left side of the tree is of type void
3728 then report error */
3729 if (IS_VOID (LTYPE (tree)))
3731 werror (E_CAST_ZERO);
3732 printFromToType(RTYPE(tree), LTYPE(tree));
3735 TETYPE (tree) = getSpec (TTYPE (tree) =
3739 if (!tree->initMode ) {
3740 if (IS_CONSTANT(LTYPE(tree)))
3741 werror (E_CODE_WRITE, "=");
3745 werror (E_LVALUE_REQUIRED, "=");
3746 goto errorTreeReturn;
3751 /*------------------------------------------------------------------*/
3752 /*----------------------------*/
3753 /* comma operator */
3754 /*----------------------------*/
3756 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3759 /*------------------------------------------------------------------*/
3760 /*----------------------------*/
3762 /*----------------------------*/
3766 if (processParms (tree->left,
3767 FUNC_ARGS(tree->left->ftype),
3768 tree->right, &parmNumber, TRUE)) {
3769 goto errorTreeReturn;
3772 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3773 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3775 reverseParms (tree->right);
3778 if (IS_CODEPTR(LTYPE(tree))) {
3779 TTYPE(tree) = LTYPE(tree)->next->next;
3781 TTYPE(tree) = LTYPE(tree)->next;
3783 TETYPE (tree) = getSpec (TTYPE (tree));
3786 /*------------------------------------------------------------------*/
3787 /*----------------------------*/
3788 /* return statement */
3789 /*----------------------------*/
3794 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3796 werror (W_RETURN_MISMATCH);
3797 printFromToType (RTYPE(tree), currFunc->type->next);
3798 goto errorTreeReturn;
3801 if (IS_VOID (currFunc->type->next)
3803 !IS_VOID (RTYPE (tree)))
3805 werror (E_FUNC_VOID);
3806 goto errorTreeReturn;
3809 /* if there is going to be a casing required then add it */
3810 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3813 decorateType (newNode (CAST,
3814 newAst_LINK (copyLinkChain (currFunc->type->next)),
3823 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3825 werror (W_VOID_FUNC, currFunc->name);
3826 goto errorTreeReturn;
3829 TTYPE (tree) = TETYPE (tree) = NULL;
3832 /*------------------------------------------------------------------*/
3833 /*----------------------------*/
3834 /* switch statement */
3835 /*----------------------------*/
3837 /* the switch value must be an integer */
3838 if (!IS_INTEGRAL (LTYPE (tree)))
3840 werror (E_SWITCH_NON_INTEGER);
3841 goto errorTreeReturn;
3844 TTYPE (tree) = TETYPE (tree) = NULL;
3847 /*------------------------------------------------------------------*/
3848 /*----------------------------*/
3850 /*----------------------------*/
3852 tree->left = backPatchLabels (tree->left,
3855 TTYPE (tree) = TETYPE (tree) = NULL;
3858 /*------------------------------------------------------------------*/
3859 /*----------------------------*/
3861 /*----------------------------*/
3864 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3865 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3866 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3868 /* if the for loop is reversible then
3869 reverse it otherwise do what we normally
3875 if (isLoopReversible (tree, &sym, &init, &end))
3876 return reverseLoop (tree, sym, init, end);
3878 return decorateType (createFor (AST_FOR (tree, trueLabel),
3879 AST_FOR (tree, continueLabel),
3880 AST_FOR (tree, falseLabel),
3881 AST_FOR (tree, condLabel),
3882 AST_FOR (tree, initExpr),
3883 AST_FOR (tree, condExpr),
3884 AST_FOR (tree, loopExpr),
3888 TTYPE (tree) = TETYPE (tree) = NULL;
3892 /* some error found this tree will be killed */
3894 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3895 tree->opval.op = NULLOP;
3901 /*-----------------------------------------------------------------*/
3902 /* sizeofOp - processes size of operation */
3903 /*-----------------------------------------------------------------*/
3905 sizeofOp (sym_link * type)
3909 /* make sure the type is complete and sane */
3910 checkTypeSanity(type, "(sizeof)");
3912 /* get the size and convert it to character */
3913 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3915 /* now convert into value */
3916 return constVal (buff);
3920 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3921 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3922 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3923 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3924 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3925 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3926 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3928 /*-----------------------------------------------------------------*/
3929 /* backPatchLabels - change and or not operators to flow control */
3930 /*-----------------------------------------------------------------*/
3932 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3938 if (!(IS_ANDORNOT (tree)))
3941 /* if this an and */
3944 static int localLbl = 0;
3947 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3948 localLabel = newSymbol (buffer, NestLevel);
3950 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3952 /* if left is already a IFX then just change the if true label in that */
3953 if (!IS_IFX (tree->left))
3954 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3956 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3957 /* right is a IFX then just join */
3958 if (IS_IFX (tree->right))
3959 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3961 tree->right = createLabel (localLabel, tree->right);
3962 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3964 return newNode (NULLOP, tree->left, tree->right);
3967 /* if this is an or operation */
3970 static int localLbl = 0;
3973 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3974 localLabel = newSymbol (buffer, NestLevel);
3976 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3978 /* if left is already a IFX then just change the if true label in that */
3979 if (!IS_IFX (tree->left))
3980 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3982 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3983 /* right is a IFX then just join */
3984 if (IS_IFX (tree->right))
3985 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3987 tree->right = createLabel (localLabel, tree->right);
3988 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3990 return newNode (NULLOP, tree->left, tree->right);
3996 int wasnot = IS_NOT (tree->left);
3997 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3999 /* if the left is already a IFX */
4000 if (!IS_IFX (tree->left))
4001 tree->left = newNode (IFX, tree->left, NULL);
4005 tree->left->trueLabel = trueLabel;
4006 tree->left->falseLabel = falseLabel;
4010 tree->left->trueLabel = falseLabel;
4011 tree->left->falseLabel = trueLabel;
4018 tree->trueLabel = trueLabel;
4019 tree->falseLabel = falseLabel;
4026 /*-----------------------------------------------------------------*/
4027 /* createBlock - create expression tree for block */
4028 /*-----------------------------------------------------------------*/
4030 createBlock (symbol * decl, ast * body)
4034 /* if the block has nothing */
4038 ex = newNode (BLOCK, NULL, body);
4039 ex->values.sym = decl;
4041 ex->right = ex->right;
4047 /*-----------------------------------------------------------------*/
4048 /* createLabel - creates the expression tree for labels */
4049 /*-----------------------------------------------------------------*/
4051 createLabel (symbol * label, ast * stmnt)
4054 char name[SDCC_NAME_MAX + 1];
4057 /* must create fresh symbol if the symbol name */
4058 /* exists in the symbol table, since there can */
4059 /* be a variable with the same name as the labl */
4060 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4061 (csym->level == label->level))
4062 label = newSymbol (label->name, label->level);
4064 /* change the name before putting it in add _ */
4065 SNPRINTF(name, sizeof(name), "%s", label->name);
4067 /* put the label in the LabelSymbol table */
4068 /* but first check if a label of the same */
4070 if ((csym = findSym (LabelTab, NULL, name)))
4071 werror (E_DUPLICATE_LABEL, label->name);
4073 addSym (LabelTab, label, name, label->level, 0, 0);
4076 label->key = labelKey++;
4077 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4083 /*-----------------------------------------------------------------*/
4084 /* createCase - generates the parsetree for a case statement */
4085 /*-----------------------------------------------------------------*/
4087 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4089 char caseLbl[SDCC_NAME_MAX + 1];
4093 /* if the switch statement does not exist */
4094 /* then case is out of context */
4097 werror (E_CASE_CONTEXT);
4101 caseVal = decorateType (resolveSymbols (caseVal));
4102 /* if not a constant then error */
4103 if (!IS_LITERAL (caseVal->ftype))
4105 werror (E_CASE_CONSTANT);
4109 /* if not a integer than error */
4110 if (!IS_INTEGRAL (caseVal->ftype))
4112 werror (E_CASE_NON_INTEGER);
4116 /* find the end of the switch values chain */
4117 if (!(val = swStat->values.switchVals.swVals))
4118 swStat->values.switchVals.swVals = caseVal->opval.val;
4121 /* also order the cases according to value */
4123 int cVal = (int) floatFromVal (caseVal->opval.val);
4124 while (val && (int) floatFromVal (val) < cVal)
4130 /* if we reached the end then */
4133 pval->next = caseVal->opval.val;
4137 /* we found a value greater than */
4138 /* the current value we must add this */
4139 /* before the value */
4140 caseVal->opval.val->next = val;
4142 /* if this was the first in chain */
4143 if (swStat->values.switchVals.swVals == val)
4144 swStat->values.switchVals.swVals =
4147 pval->next = caseVal->opval.val;
4152 /* create the case label */
4153 SNPRINTF(caseLbl, sizeof(caseLbl),
4155 swStat->values.switchVals.swNum,
4156 (int) floatFromVal (caseVal->opval.val));
4158 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4163 /*-----------------------------------------------------------------*/
4164 /* createDefault - creates the parse tree for the default statement */
4165 /*-----------------------------------------------------------------*/
4167 createDefault (ast * swStat, ast * stmnt)
4169 char defLbl[SDCC_NAME_MAX + 1];
4171 /* if the switch statement does not exist */
4172 /* then case is out of context */
4175 werror (E_CASE_CONTEXT);
4179 /* turn on the default flag */
4180 swStat->values.switchVals.swDefault = 1;
4182 /* create the label */
4183 SNPRINTF (defLbl, sizeof(defLbl),
4184 "_default_%d", swStat->values.switchVals.swNum);
4185 return createLabel (newSymbol (defLbl, 0), stmnt);
4188 /*-----------------------------------------------------------------*/
4189 /* createIf - creates the parsetree for the if statement */
4190 /*-----------------------------------------------------------------*/
4192 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4194 static int Lblnum = 0;
4196 symbol *ifTrue, *ifFalse, *ifEnd;
4198 /* if neither exists */
4199 if (!elseBody && !ifBody) {
4200 // if there are no side effects (i++, j() etc)
4201 if (!hasSEFcalls(condAst)) {
4206 /* create the labels */
4207 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4208 ifFalse = newSymbol (buffer, NestLevel);
4209 /* if no else body then end == false */
4214 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4215 ifEnd = newSymbol (buffer, NestLevel);
4218 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4219 ifTrue = newSymbol (buffer, NestLevel);
4223 /* attach the ifTrue label to the top of it body */
4224 ifBody = createLabel (ifTrue, ifBody);
4225 /* attach a goto end to the ifBody if else is present */
4228 ifBody = newNode (NULLOP, ifBody,
4230 newAst_VALUE (symbolVal (ifEnd)),
4232 /* put the elseLabel on the else body */
4233 elseBody = createLabel (ifFalse, elseBody);
4234 /* out the end at the end of the body */
4235 elseBody = newNode (NULLOP,
4237 createLabel (ifEnd, NULL));
4241 ifBody = newNode (NULLOP, ifBody,
4242 createLabel (ifFalse, NULL));
4244 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4245 if (IS_IFX (condAst))
4248 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4250 return newNode (NULLOP, ifTree,
4251 newNode (NULLOP, ifBody, elseBody));
4255 /*-----------------------------------------------------------------*/
4256 /* createDo - creates parse tree for do */
4259 /* _docontinue_n: */
4260 /* condition_expression +-> trueLabel -> _dobody_n */
4262 /* +-> falseLabel-> _dobreak_n */
4264 /*-----------------------------------------------------------------*/
4266 createDo (symbol * trueLabel, symbol * continueLabel,
4267 symbol * falseLabel, ast * condAst, ast * doBody)
4272 /* if the body does not exist then it is simple */
4275 condAst = backPatchLabels (condAst, continueLabel, NULL);
4276 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4277 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4278 doTree->trueLabel = continueLabel;
4279 doTree->falseLabel = NULL;
4283 /* otherwise we have a body */
4284 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4286 /* attach the body label to the top */
4287 doBody = createLabel (trueLabel, doBody);
4288 /* attach the continue label to end of body */
4289 doBody = newNode (NULLOP, doBody,
4290 createLabel (continueLabel, NULL));
4292 /* now put the break label at the end */
4293 if (IS_IFX (condAst))
4296 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4298 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4300 /* putting it together */
4301 return newNode (NULLOP, doBody, doTree);
4304 /*-----------------------------------------------------------------*/
4305 /* createFor - creates parse tree for 'for' statement */
4308 /* condExpr +-> trueLabel -> _forbody_n */
4310 /* +-> falseLabel-> _forbreak_n */
4313 /* _forcontinue_n: */
4315 /* goto _forcond_n ; */
4317 /*-----------------------------------------------------------------*/
4319 createFor (symbol * trueLabel, symbol * continueLabel,
4320 symbol * falseLabel, symbol * condLabel,
4321 ast * initExpr, ast * condExpr, ast * loopExpr,
4326 /* if loopexpression not present then we can generate it */
4327 /* the same way as a while */
4329 return newNode (NULLOP, initExpr,
4330 createWhile (trueLabel, continueLabel,
4331 falseLabel, condExpr, forBody));
4332 /* vanilla for statement */
4333 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4335 if (condExpr && !IS_IFX (condExpr))
4336 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4339 /* attach condition label to condition */
4340 condExpr = createLabel (condLabel, condExpr);
4342 /* attach body label to body */
4343 forBody = createLabel (trueLabel, forBody);
4345 /* attach continue to forLoop expression & attach */
4346 /* goto the forcond @ and of loopExpression */
4347 loopExpr = createLabel (continueLabel,
4351 newAst_VALUE (symbolVal (condLabel)),
4353 /* now start putting them together */
4354 forTree = newNode (NULLOP, initExpr, condExpr);
4355 forTree = newNode (NULLOP, forTree, forBody);
4356 forTree = newNode (NULLOP, forTree, loopExpr);
4357 /* finally add the break label */
4358 forTree = newNode (NULLOP, forTree,
4359 createLabel (falseLabel, NULL));
4363 /*-----------------------------------------------------------------*/
4364 /* createWhile - creates parse tree for while statement */
4365 /* the while statement will be created as follows */
4367 /* _while_continue_n: */
4368 /* condition_expression +-> trueLabel -> _while_boby_n */
4370 /* +-> falseLabel -> _while_break_n */
4371 /* _while_body_n: */
4373 /* goto _while_continue_n */
4374 /* _while_break_n: */
4375 /*-----------------------------------------------------------------*/
4377 createWhile (symbol * trueLabel, symbol * continueLabel,
4378 symbol * falseLabel, ast * condExpr, ast * whileBody)
4382 /* put the continue label */
4383 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4384 condExpr = createLabel (continueLabel, condExpr);
4385 condExpr->lineno = 0;
4387 /* put the body label in front of the body */
4388 whileBody = createLabel (trueLabel, whileBody);
4389 whileBody->lineno = 0;
4390 /* put a jump to continue at the end of the body */
4391 /* and put break label at the end of the body */
4392 whileBody = newNode (NULLOP,
4395 newAst_VALUE (symbolVal (continueLabel)),
4396 createLabel (falseLabel, NULL)));
4398 /* put it all together */
4399 if (IS_IFX (condExpr))
4400 whileTree = condExpr;
4403 whileTree = newNode (IFX, condExpr, NULL);
4404 /* put the true & false labels in place */
4405 whileTree->trueLabel = trueLabel;
4406 whileTree->falseLabel = falseLabel;
4409 return newNode (NULLOP, whileTree, whileBody);
4412 /*-----------------------------------------------------------------*/
4413 /* optimizeGetHbit - get highest order bit of the expression */
4414 /*-----------------------------------------------------------------*/
4416 optimizeGetHbit (ast * tree)
4419 /* if this is not a bit and */
4420 if (!IS_BITAND (tree))
4423 /* will look for tree of the form
4424 ( expr >> ((sizeof expr) -1) ) & 1 */
4425 if (!IS_AST_LIT_VALUE (tree->right))
4428 if (AST_LIT_VALUE (tree->right) != 1)
4431 if (!IS_RIGHT_OP (tree->left))
4434 if (!IS_AST_LIT_VALUE (tree->left->right))
4437 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4438 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4441 /* make sure the port supports GETHBIT */
4442 if (port->hasExtBitOp
4443 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4446 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4450 /*-----------------------------------------------------------------*/
4451 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4452 /*-----------------------------------------------------------------*/
4454 optimizeRRCRLC (ast * root)
4456 /* will look for trees of the form
4457 (?expr << 1) | (?expr >> 7) or
4458 (?expr >> 7) | (?expr << 1) will make that
4459 into a RLC : operation ..
4461 (?expr >> 1) | (?expr << 7) or
4462 (?expr << 7) | (?expr >> 1) will make that
4463 into a RRC operation
4464 note : by 7 I mean (number of bits required to hold the
4466 /* if the root operations is not a | operation the not */
4467 if (!IS_BITOR (root))
4470 /* I have to think of a better way to match patterns this sucks */
4471 /* that aside let start looking for the first case : I use a the
4472 negative check a lot to improve the efficiency */
4473 /* (?expr << 1) | (?expr >> 7) */
4474 if (IS_LEFT_OP (root->left) &&
4475 IS_RIGHT_OP (root->right))
4478 if (!SPEC_USIGN (TETYPE (root->left->left)))
4481 if (!IS_AST_LIT_VALUE (root->left->right) ||
4482 !IS_AST_LIT_VALUE (root->right->right))
4485 /* make sure it is the same expression */
4486 if (!isAstEqual (root->left->left,
4490 if (AST_LIT_VALUE (root->left->right) != 1)
4493 if (AST_LIT_VALUE (root->right->right) !=
4494 (getSize (TTYPE (root->left->left)) * 8 - 1))
4497 /* make sure the port supports RLC */
4498 if (port->hasExtBitOp
4499 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4502 /* whew got the first case : create the AST */
4503 return newNode (RLC, root->left->left, NULL);
4507 /* check for second case */
4508 /* (?expr >> 7) | (?expr << 1) */
4509 if (IS_LEFT_OP (root->right) &&
4510 IS_RIGHT_OP (root->left))
4513 if (!SPEC_USIGN (TETYPE (root->left->left)))
4516 if (!IS_AST_LIT_VALUE (root->left->right) ||
4517 !IS_AST_LIT_VALUE (root->right->right))
4520 /* make sure it is the same symbol */
4521 if (!isAstEqual (root->left->left,
4525 if (AST_LIT_VALUE (root->right->right) != 1)
4528 if (AST_LIT_VALUE (root->left->right) !=
4529 (getSize (TTYPE (root->left->left)) * 8 - 1))
4532 /* make sure the port supports RLC */
4533 if (port->hasExtBitOp
4534 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4537 /* whew got the first case : create the AST */
4538 return newNode (RLC, root->left->left, NULL);
4543 /* third case for RRC */
4544 /* (?symbol >> 1) | (?symbol << 7) */
4545 if (IS_LEFT_OP (root->right) &&
4546 IS_RIGHT_OP (root->left))
4549 if (!SPEC_USIGN (TETYPE (root->left->left)))
4552 if (!IS_AST_LIT_VALUE (root->left->right) ||
4553 !IS_AST_LIT_VALUE (root->right->right))
4556 /* make sure it is the same symbol */
4557 if (!isAstEqual (root->left->left,
4561 if (AST_LIT_VALUE (root->left->right) != 1)
4564 if (AST_LIT_VALUE (root->right->right) !=
4565 (getSize (TTYPE (root->left->left)) * 8 - 1))
4568 /* make sure the port supports RRC */
4569 if (port->hasExtBitOp
4570 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4573 /* whew got the first case : create the AST */
4574 return newNode (RRC, root->left->left, NULL);
4578 /* fourth and last case for now */
4579 /* (?symbol << 7) | (?symbol >> 1) */
4580 if (IS_RIGHT_OP (root->right) &&
4581 IS_LEFT_OP (root->left))
4584 if (!SPEC_USIGN (TETYPE (root->left->left)))
4587 if (!IS_AST_LIT_VALUE (root->left->right) ||
4588 !IS_AST_LIT_VALUE (root->right->right))
4591 /* make sure it is the same symbol */
4592 if (!isAstEqual (root->left->left,
4596 if (AST_LIT_VALUE (root->right->right) != 1)
4599 if (AST_LIT_VALUE (root->left->right) !=
4600 (getSize (TTYPE (root->left->left)) * 8 - 1))
4603 /* make sure the port supports RRC */
4604 if (port->hasExtBitOp
4605 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4608 /* whew got the first case : create the AST */
4609 return newNode (RRC, root->left->left, NULL);
4613 /* not found return root */
4617 /*-----------------------------------------------------------------*/
4618 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4619 /*-----------------------------------------------------------------*/
4621 optimizeSWAP (ast * root)
4623 /* will look for trees of the form
4624 (?expr << 4) | (?expr >> 4) or
4625 (?expr >> 4) | (?expr << 4) will make that
4626 into a SWAP : operation ..
4627 note : by 4 I mean (number of bits required to hold the
4629 /* if the root operations is not a | operation the not */
4630 if (!IS_BITOR (root))
4633 /* (?expr << 4) | (?expr >> 4) */
4634 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4635 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4638 if (!SPEC_USIGN (TETYPE (root->left->left)))
4641 if (!IS_AST_LIT_VALUE (root->left->right) ||
4642 !IS_AST_LIT_VALUE (root->right->right))
4645 /* make sure it is the same expression */
4646 if (!isAstEqual (root->left->left,
4650 if (AST_LIT_VALUE (root->left->right) !=
4651 (getSize (TTYPE (root->left->left)) * 4))
4654 if (AST_LIT_VALUE (root->right->right) !=
4655 (getSize (TTYPE (root->left->left)) * 4))
4658 /* make sure the port supports SWAP */
4659 if (port->hasExtBitOp
4660 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4663 /* found it : create the AST */
4664 return newNode (SWAP, root->left->left, NULL);
4668 /* not found return root */
4672 /*-----------------------------------------------------------------*/
4673 /* optimizeCompare - otimizes compares for bit variables */
4674 /*-----------------------------------------------------------------*/
4676 optimizeCompare (ast * root)
4678 ast *optExpr = NULL;
4681 unsigned int litValue;
4683 /* if nothing then return nothing */
4687 /* if not a compare op then do leaves */
4688 if (!IS_COMPARE_OP (root))
4690 root->left = optimizeCompare (root->left);
4691 root->right = optimizeCompare (root->right);
4695 /* if left & right are the same then depending
4696 of the operation do */
4697 if (isAstEqual (root->left, root->right))
4699 switch (root->opval.op)
4704 optExpr = newAst_VALUE (constVal ("0"));
4709 optExpr = newAst_VALUE (constVal ("1"));
4713 return decorateType (optExpr);
4716 vleft = (root->left->type == EX_VALUE ?
4717 root->left->opval.val : NULL);
4719 vright = (root->right->type == EX_VALUE ?
4720 root->right->opval.val : NULL);
4722 /* if left is a BITVAR in BITSPACE */
4723 /* and right is a LITERAL then opt- */
4724 /* imize else do nothing */
4725 if (vleft && vright &&
4726 IS_BITVAR (vleft->etype) &&
4727 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4728 IS_LITERAL (vright->etype))
4731 /* if right side > 1 then comparison may never succeed */
4732 if ((litValue = (int) floatFromVal (vright)) > 1)
4734 werror (W_BAD_COMPARE);
4740 switch (root->opval.op)
4742 case '>': /* bit value greater than 1 cannot be */
4743 werror (W_BAD_COMPARE);
4747 case '<': /* bit value < 1 means 0 */
4749 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4752 case LE_OP: /* bit value <= 1 means no check */
4753 optExpr = newAst_VALUE (vright);
4756 case GE_OP: /* bit value >= 1 means only check for = */
4758 optExpr = newAst_VALUE (vleft);
4763 { /* literal is zero */
4764 switch (root->opval.op)
4766 case '<': /* bit value < 0 cannot be */
4767 werror (W_BAD_COMPARE);
4771 case '>': /* bit value > 0 means 1 */
4773 optExpr = newAst_VALUE (vleft);
4776 case LE_OP: /* bit value <= 0 means no check */
4777 case GE_OP: /* bit value >= 0 means no check */
4778 werror (W_BAD_COMPARE);
4782 case EQ_OP: /* bit == 0 means ! of bit */
4783 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4787 return decorateType (resolveSymbols (optExpr));
4788 } /* end-of-if of BITVAR */
4793 /*-----------------------------------------------------------------*/
4794 /* addSymToBlock : adds the symbol to the first block we find */
4795 /*-----------------------------------------------------------------*/
4797 addSymToBlock (symbol * sym, ast * tree)
4799 /* reached end of tree or a leaf */
4800 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4804 if (IS_AST_OP (tree) &&
4805 tree->opval.op == BLOCK)
4808 symbol *lsym = copySymbol (sym);
4810 lsym->next = AST_VALUES (tree, sym);
4811 AST_VALUES (tree, sym) = lsym;
4815 addSymToBlock (sym, tree->left);
4816 addSymToBlock (sym, tree->right);
4819 /*-----------------------------------------------------------------*/
4820 /* processRegParms - do processing for register parameters */
4821 /*-----------------------------------------------------------------*/
4823 processRegParms (value * args, ast * body)
4827 if (IS_REGPARM (args->etype))
4828 addSymToBlock (args->sym, body);
4833 /*-----------------------------------------------------------------*/
4834 /* resetParmKey - resets the operandkeys for the symbols */
4835 /*-----------------------------------------------------------------*/
4836 DEFSETFUNC (resetParmKey)
4847 /*-----------------------------------------------------------------*/
4848 /* createFunction - This is the key node that calls the iCode for */
4849 /* generating the code for a function. Note code */
4850 /* is generated function by function, later when */
4851 /* add inter-procedural analysis this will change */
4852 /*-----------------------------------------------------------------*/
4854 createFunction (symbol * name, ast * body)
4860 iCode *piCode = NULL;
4862 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4863 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4865 /* if check function return 0 then some problem */
4866 if (checkFunction (name, NULL) == 0)
4869 /* create a dummy block if none exists */
4871 body = newNode (BLOCK, NULL, NULL);
4875 /* check if the function name already in the symbol table */
4876 if ((csym = findSym (SymbolTab, NULL, name->name)))
4879 /* special case for compiler defined functions
4880 we need to add the name to the publics list : this
4881 actually means we are now compiling the compiler
4885 addSet (&publics, name);
4891 allocVariables (name);
4893 name->lastLine = mylineno;
4896 /* set the stack pointer */
4897 /* PENDING: check this for the mcs51 */
4898 stackPtr = -port->stack.direction * port->stack.call_overhead;
4899 if (IFFUNC_ISISR (name->type))
4900 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4901 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4902 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4904 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4906 fetype = getSpec (name->type); /* get the specifier for the function */
4907 /* if this is a reentrant function then */
4908 if (IFFUNC_ISREENT (name->type))
4911 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4913 /* do processing for parameters that are passed in registers */
4914 processRegParms (FUNC_ARGS(name->type), body);
4916 /* set the stack pointer */
4920 /* allocate & autoinit the block variables */
4921 processBlockVars (body, &stack, ALLOCATE);
4923 /* save the stack information */
4924 if (options.useXstack)
4925 name->xstack = SPEC_STAK (fetype) = stack;
4927 name->stack = SPEC_STAK (fetype) = stack;
4929 /* name needs to be mangled */
4930 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4932 body = resolveSymbols (body); /* resolve the symbols */
4933 body = decorateType (body); /* propagateType & do semantic checks */
4935 ex = newAst_VALUE (symbolVal (name)); /* create name */
4936 ex = newNode (FUNCTION, ex, body);
4937 ex->values.args = FUNC_ARGS(name->type);
4939 if (options.dump_tree) PA(ex);
4942 werror (E_FUNC_NO_CODE, name->name);
4946 /* create the node & generate intermediate code */
4948 codeOutFile = code->oFile;
4949 piCode = iCodeFromAst (ex);
4953 werror (E_FUNC_NO_CODE, name->name);
4957 eBBlockFromiCode (piCode);
4959 /* if there are any statics then do them */
4962 GcurMemmap = statsg;
4963 codeOutFile = statsg->oFile;
4964 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4970 /* dealloc the block variables */
4971 processBlockVars (body, &stack, DEALLOCATE);
4972 outputDebugStackSymbols();
4973 /* deallocate paramaters */
4974 deallocParms (FUNC_ARGS(name->type));
4976 if (IFFUNC_ISREENT (name->type))
4979 /* we are done freeup memory & cleanup */
4981 if (port->reset_labelKey) labelKey = 1;
4983 FUNC_HASBODY(name->type) = 1;
4984 addSet (&operKeyReset, name);
4985 applyToSet (operKeyReset, resetParmKey);
4990 cleanUpLevel (LabelTab, 0);
4991 cleanUpBlock (StructTab, 1);
4992 cleanUpBlock (TypedefTab, 1);
4994 xstack->syms = NULL;
4995 istack->syms = NULL;
5000 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5001 /*-----------------------------------------------------------------*/
5002 /* ast_print : prints the ast (for debugging purposes) */
5003 /*-----------------------------------------------------------------*/
5005 void ast_print (ast * tree, FILE *outfile, int indent)
5010 /* can print only decorated trees */
5011 if (!tree->decorated) return;
5013 /* if any child is an error | this one is an error do nothing */
5014 if (tree->isError ||
5015 (tree->left && tree->left->isError) ||
5016 (tree->right && tree->right->isError)) {
5017 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5021 /* print the line */
5022 /* if not block & function */
5023 if (tree->type == EX_OP &&
5024 (tree->opval.op != FUNCTION &&
5025 tree->opval.op != BLOCK &&
5026 tree->opval.op != NULLOP)) {
5029 if (tree->opval.op == FUNCTION) {
5031 value *args=FUNC_ARGS(tree->left->opval.val->type);
5032 fprintf(outfile,"FUNCTION (%s=%p) type (",
5033 tree->left->opval.val->name, tree);
5034 printTypeChain (tree->left->opval.val->type->next,outfile);
5035 fprintf(outfile,") args (");
5038 fprintf (outfile, ", ");
5040 printTypeChain (args ? args->type : NULL, outfile);
5042 args= args ? args->next : NULL;
5044 fprintf(outfile,")\n");
5045 ast_print(tree->left,outfile,indent);
5046 ast_print(tree->right,outfile,indent);
5049 if (tree->opval.op == BLOCK) {
5050 symbol *decls = tree->values.sym;
5051 INDENT(indent,outfile);
5052 fprintf(outfile,"{\n");
5054 INDENT(indent+2,outfile);
5055 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5056 decls->name, decls);
5057 printTypeChain(decls->type,outfile);
5058 fprintf(outfile,")\n");
5060 decls = decls->next;
5062 ast_print(tree->right,outfile,indent+2);
5063 INDENT(indent,outfile);
5064 fprintf(outfile,"}\n");
5067 if (tree->opval.op == NULLOP) {
5068 ast_print(tree->left,outfile,indent);
5069 ast_print(tree->right,outfile,indent);
5072 INDENT(indent,outfile);
5074 /*------------------------------------------------------------------*/
5075 /*----------------------------*/
5076 /* leaf has been reached */
5077 /*----------------------------*/
5078 /* if this is of type value */
5079 /* just get the type */
5080 if (tree->type == EX_VALUE) {
5082 if (IS_LITERAL (tree->opval.val->etype)) {
5083 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5084 if (SPEC_USIGN (tree->opval.val->etype))
5085 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5087 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5088 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5089 floatFromVal(tree->opval.val));
5090 } else if (tree->opval.val->sym) {
5091 /* if the undefined flag is set then give error message */
5092 if (tree->opval.val->sym->undefined) {
5093 fprintf(outfile,"UNDEFINED SYMBOL ");
5095 fprintf(outfile,"SYMBOL ");
5097 fprintf(outfile,"(%s=%p)",
5098 tree->opval.val->sym->name,tree);
5101 fprintf(outfile," type (");
5102 printTypeChain(tree->ftype,outfile);
5103 fprintf(outfile,")\n");
5105 fprintf(outfile,"\n");
5110 /* if type link for the case of cast */
5111 if (tree->type == EX_LINK) {
5112 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5113 printTypeChain(tree->opval.lnk,outfile);
5114 fprintf(outfile,")\n");
5119 /* depending on type of operator do */
5121 switch (tree->opval.op) {
5122 /*------------------------------------------------------------------*/
5123 /*----------------------------*/
5125 /*----------------------------*/
5127 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5128 printTypeChain(tree->ftype,outfile);
5129 fprintf(outfile,")\n");
5130 ast_print(tree->left,outfile,indent+2);
5131 ast_print(tree->right,outfile,indent+2);
5134 /*------------------------------------------------------------------*/
5135 /*----------------------------*/
5137 /*----------------------------*/
5139 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5140 printTypeChain(tree->ftype,outfile);
5141 fprintf(outfile,")\n");
5142 ast_print(tree->left,outfile,indent+2);
5143 ast_print(tree->right,outfile,indent+2);
5146 /*------------------------------------------------------------------*/
5147 /*----------------------------*/
5148 /* struct/union pointer */
5149 /*----------------------------*/
5151 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5152 printTypeChain(tree->ftype,outfile);
5153 fprintf(outfile,")\n");
5154 ast_print(tree->left,outfile,indent+2);
5155 ast_print(tree->right,outfile,indent+2);
5158 /*------------------------------------------------------------------*/
5159 /*----------------------------*/
5160 /* ++/-- operation */
5161 /*----------------------------*/
5164 fprintf(outfile,"post-");
5166 fprintf(outfile,"pre-");
5167 fprintf(outfile,"INC_OP (%p) type (",tree);
5168 printTypeChain(tree->ftype,outfile);
5169 fprintf(outfile,")\n");
5170 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5171 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5176 fprintf(outfile,"post-");
5178 fprintf(outfile,"pre-");
5179 fprintf(outfile,"DEC_OP (%p) type (",tree);
5180 printTypeChain(tree->ftype,outfile);
5181 fprintf(outfile,")\n");
5182 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5183 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5186 /*------------------------------------------------------------------*/
5187 /*----------------------------*/
5189 /*----------------------------*/
5192 fprintf(outfile,"& (%p) type (",tree);
5193 printTypeChain(tree->ftype,outfile);
5194 fprintf(outfile,")\n");
5195 ast_print(tree->left,outfile,indent+2);
5196 ast_print(tree->right,outfile,indent+2);
5198 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5199 printTypeChain(tree->ftype,outfile);
5200 fprintf(outfile,")\n");
5201 ast_print(tree->left,outfile,indent+2);
5202 ast_print(tree->right,outfile,indent+2);
5205 /*----------------------------*/
5207 /*----------------------------*/
5209 fprintf(outfile,"OR (%p) type (",tree);
5210 printTypeChain(tree->ftype,outfile);
5211 fprintf(outfile,")\n");
5212 ast_print(tree->left,outfile,indent+2);
5213 ast_print(tree->right,outfile,indent+2);
5215 /*------------------------------------------------------------------*/
5216 /*----------------------------*/
5218 /*----------------------------*/
5220 fprintf(outfile,"XOR (%p) type (",tree);
5221 printTypeChain(tree->ftype,outfile);
5222 fprintf(outfile,")\n");
5223 ast_print(tree->left,outfile,indent+2);
5224 ast_print(tree->right,outfile,indent+2);
5227 /*------------------------------------------------------------------*/
5228 /*----------------------------*/
5230 /*----------------------------*/
5232 fprintf(outfile,"DIV (%p) type (",tree);
5233 printTypeChain(tree->ftype,outfile);
5234 fprintf(outfile,")\n");
5235 ast_print(tree->left,outfile,indent+2);
5236 ast_print(tree->right,outfile,indent+2);
5238 /*------------------------------------------------------------------*/
5239 /*----------------------------*/
5241 /*----------------------------*/
5243 fprintf(outfile,"MOD (%p) type (",tree);
5244 printTypeChain(tree->ftype,outfile);
5245 fprintf(outfile,")\n");
5246 ast_print(tree->left,outfile,indent+2);
5247 ast_print(tree->right,outfile,indent+2);
5250 /*------------------------------------------------------------------*/
5251 /*----------------------------*/
5252 /* address dereference */
5253 /*----------------------------*/
5254 case '*': /* can be unary : if right is null then unary operation */
5256 fprintf(outfile,"DEREF (%p) type (",tree);
5257 printTypeChain(tree->ftype,outfile);
5258 fprintf(outfile,")\n");
5259 ast_print(tree->left,outfile,indent+2);
5262 /*------------------------------------------------------------------*/
5263 /*----------------------------*/
5264 /* multiplication */
5265 /*----------------------------*/
5266 fprintf(outfile,"MULT (%p) type (",tree);
5267 printTypeChain(tree->ftype,outfile);
5268 fprintf(outfile,")\n");
5269 ast_print(tree->left,outfile,indent+2);
5270 ast_print(tree->right,outfile,indent+2);
5274 /*------------------------------------------------------------------*/
5275 /*----------------------------*/
5276 /* unary '+' operator */
5277 /*----------------------------*/
5281 fprintf(outfile,"UPLUS (%p) type (",tree);
5282 printTypeChain(tree->ftype,outfile);
5283 fprintf(outfile,")\n");
5284 ast_print(tree->left,outfile,indent+2);
5286 /*------------------------------------------------------------------*/
5287 /*----------------------------*/
5289 /*----------------------------*/
5290 fprintf(outfile,"ADD (%p) type (",tree);
5291 printTypeChain(tree->ftype,outfile);
5292 fprintf(outfile,")\n");
5293 ast_print(tree->left,outfile,indent+2);
5294 ast_print(tree->right,outfile,indent+2);
5297 /*------------------------------------------------------------------*/
5298 /*----------------------------*/
5300 /*----------------------------*/
5301 case '-': /* can be unary */
5303 fprintf(outfile,"UMINUS (%p) type (",tree);
5304 printTypeChain(tree->ftype,outfile);
5305 fprintf(outfile,")\n");
5306 ast_print(tree->left,outfile,indent+2);
5308 /*------------------------------------------------------------------*/
5309 /*----------------------------*/
5311 /*----------------------------*/
5312 fprintf(outfile,"SUB (%p) type (",tree);
5313 printTypeChain(tree->ftype,outfile);
5314 fprintf(outfile,")\n");
5315 ast_print(tree->left,outfile,indent+2);
5316 ast_print(tree->right,outfile,indent+2);
5319 /*------------------------------------------------------------------*/
5320 /*----------------------------*/
5322 /*----------------------------*/
5324 fprintf(outfile,"COMPL (%p) type (",tree);
5325 printTypeChain(tree->ftype,outfile);
5326 fprintf(outfile,")\n");
5327 ast_print(tree->left,outfile,indent+2);
5329 /*------------------------------------------------------------------*/
5330 /*----------------------------*/
5332 /*----------------------------*/
5334 fprintf(outfile,"NOT (%p) type (",tree);
5335 printTypeChain(tree->ftype,outfile);
5336 fprintf(outfile,")\n");
5337 ast_print(tree->left,outfile,indent+2);
5339 /*------------------------------------------------------------------*/
5340 /*----------------------------*/
5342 /*----------------------------*/
5344 fprintf(outfile,"RRC (%p) type (",tree);
5345 printTypeChain(tree->ftype,outfile);
5346 fprintf(outfile,")\n");
5347 ast_print(tree->left,outfile,indent+2);
5351 fprintf(outfile,"RLC (%p) type (",tree);
5352 printTypeChain(tree->ftype,outfile);
5353 fprintf(outfile,")\n");
5354 ast_print(tree->left,outfile,indent+2);
5357 fprintf(outfile,"SWAP (%p) type (",tree);
5358 printTypeChain(tree->ftype,outfile);
5359 fprintf(outfile,")\n");
5360 ast_print(tree->left,outfile,indent+2);
5363 fprintf(outfile,"GETHBIT (%p) type (",tree);
5364 printTypeChain(tree->ftype,outfile);
5365 fprintf(outfile,")\n");
5366 ast_print(tree->left,outfile,indent+2);
5369 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5370 printTypeChain(tree->ftype,outfile);
5371 fprintf(outfile,")\n");
5372 ast_print(tree->left,outfile,indent+2);
5373 ast_print(tree->right,outfile,indent+2);
5376 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5377 printTypeChain(tree->ftype,outfile);
5378 fprintf(outfile,")\n");
5379 ast_print(tree->left,outfile,indent+2);
5380 ast_print(tree->right,outfile,indent+2);
5382 /*------------------------------------------------------------------*/
5383 /*----------------------------*/
5385 /*----------------------------*/
5386 case CAST: /* change the type */
5387 fprintf(outfile,"CAST (%p) from type (",tree);
5388 printTypeChain(tree->right->ftype,outfile);
5389 fprintf(outfile,") to type (");
5390 printTypeChain(tree->ftype,outfile);
5391 fprintf(outfile,")\n");
5392 ast_print(tree->right,outfile,indent+2);
5396 fprintf(outfile,"ANDAND (%p) type (",tree);
5397 printTypeChain(tree->ftype,outfile);
5398 fprintf(outfile,")\n");
5399 ast_print(tree->left,outfile,indent+2);
5400 ast_print(tree->right,outfile,indent+2);
5403 fprintf(outfile,"OROR (%p) type (",tree);
5404 printTypeChain(tree->ftype,outfile);
5405 fprintf(outfile,")\n");
5406 ast_print(tree->left,outfile,indent+2);
5407 ast_print(tree->right,outfile,indent+2);
5410 /*------------------------------------------------------------------*/
5411 /*----------------------------*/
5412 /* comparison operators */
5413 /*----------------------------*/
5415 fprintf(outfile,"GT(>) (%p) type (",tree);
5416 printTypeChain(tree->ftype,outfile);
5417 fprintf(outfile,")\n");
5418 ast_print(tree->left,outfile,indent+2);
5419 ast_print(tree->right,outfile,indent+2);
5422 fprintf(outfile,"LT(<) (%p) type (",tree);
5423 printTypeChain(tree->ftype,outfile);
5424 fprintf(outfile,")\n");
5425 ast_print(tree->left,outfile,indent+2);
5426 ast_print(tree->right,outfile,indent+2);
5429 fprintf(outfile,"LE(<=) (%p) type (",tree);
5430 printTypeChain(tree->ftype,outfile);
5431 fprintf(outfile,")\n");
5432 ast_print(tree->left,outfile,indent+2);
5433 ast_print(tree->right,outfile,indent+2);
5436 fprintf(outfile,"GE(>=) (%p) type (",tree);
5437 printTypeChain(tree->ftype,outfile);
5438 fprintf(outfile,")\n");
5439 ast_print(tree->left,outfile,indent+2);
5440 ast_print(tree->right,outfile,indent+2);
5443 fprintf(outfile,"EQ(==) (%p) type (",tree);
5444 printTypeChain(tree->ftype,outfile);
5445 fprintf(outfile,")\n");
5446 ast_print(tree->left,outfile,indent+2);
5447 ast_print(tree->right,outfile,indent+2);
5450 fprintf(outfile,"NE(!=) (%p) type (",tree);
5451 printTypeChain(tree->ftype,outfile);
5452 fprintf(outfile,")\n");
5453 ast_print(tree->left,outfile,indent+2);
5454 ast_print(tree->right,outfile,indent+2);
5455 /*------------------------------------------------------------------*/
5456 /*----------------------------*/
5458 /*----------------------------*/
5459 case SIZEOF: /* evaluate wihout code generation */
5460 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5463 /*------------------------------------------------------------------*/
5464 /*----------------------------*/
5465 /* conditional operator '?' */
5466 /*----------------------------*/
5468 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5469 printTypeChain(tree->ftype,outfile);
5470 fprintf(outfile,")\n");
5471 ast_print(tree->left,outfile,indent+2);
5472 ast_print(tree->right,outfile,indent+2);
5476 fprintf(outfile,"COLON(:) (%p) type (",tree);
5477 printTypeChain(tree->ftype,outfile);
5478 fprintf(outfile,")\n");
5479 ast_print(tree->left,outfile,indent+2);
5480 ast_print(tree->right,outfile,indent+2);
5483 /*------------------------------------------------------------------*/
5484 /*----------------------------*/
5485 /* assignment operators */
5486 /*----------------------------*/
5488 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5489 printTypeChain(tree->ftype,outfile);
5490 fprintf(outfile,")\n");
5491 ast_print(tree->left,outfile,indent+2);
5492 ast_print(tree->right,outfile,indent+2);
5495 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5496 printTypeChain(tree->ftype,outfile);
5497 fprintf(outfile,")\n");
5498 ast_print(tree->left,outfile,indent+2);
5499 ast_print(tree->right,outfile,indent+2);
5502 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5503 printTypeChain(tree->ftype,outfile);
5504 fprintf(outfile,")\n");
5505 ast_print(tree->left,outfile,indent+2);
5506 ast_print(tree->right,outfile,indent+2);
5509 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5510 printTypeChain(tree->ftype,outfile);
5511 fprintf(outfile,")\n");
5512 ast_print(tree->left,outfile,indent+2);
5513 ast_print(tree->right,outfile,indent+2);
5516 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5517 printTypeChain(tree->ftype,outfile);
5518 fprintf(outfile,")\n");
5519 ast_print(tree->left,outfile,indent+2);
5520 ast_print(tree->right,outfile,indent+2);
5523 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5524 printTypeChain(tree->ftype,outfile);
5525 fprintf(outfile,")\n");
5526 ast_print(tree->left,outfile,indent+2);
5527 ast_print(tree->right,outfile,indent+2);
5530 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5531 printTypeChain(tree->ftype,outfile);
5532 fprintf(outfile,")\n");
5533 ast_print(tree->left,outfile,indent+2);
5534 ast_print(tree->right,outfile,indent+2);
5536 /*------------------------------------------------------------------*/
5537 /*----------------------------*/
5539 /*----------------------------*/
5541 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5542 printTypeChain(tree->ftype,outfile);
5543 fprintf(outfile,")\n");
5544 ast_print(tree->left,outfile,indent+2);
5545 ast_print(tree->right,outfile,indent+2);
5547 /*------------------------------------------------------------------*/
5548 /*----------------------------*/
5550 /*----------------------------*/
5552 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5553 printTypeChain(tree->ftype,outfile);
5554 fprintf(outfile,")\n");
5555 ast_print(tree->left,outfile,indent+2);
5556 ast_print(tree->right,outfile,indent+2);
5558 /*------------------------------------------------------------------*/
5559 /*----------------------------*/
5560 /* straight assignemnt */
5561 /*----------------------------*/
5563 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5564 printTypeChain(tree->ftype,outfile);
5565 fprintf(outfile,")\n");
5566 ast_print(tree->left,outfile,indent+2);
5567 ast_print(tree->right,outfile,indent+2);
5569 /*------------------------------------------------------------------*/
5570 /*----------------------------*/
5571 /* comma operator */
5572 /*----------------------------*/
5574 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5575 printTypeChain(tree->ftype,outfile);
5576 fprintf(outfile,")\n");
5577 ast_print(tree->left,outfile,indent+2);
5578 ast_print(tree->right,outfile,indent+2);
5580 /*------------------------------------------------------------------*/
5581 /*----------------------------*/
5583 /*----------------------------*/
5586 fprintf(outfile,"CALL (%p) type (",tree);
5587 printTypeChain(tree->ftype,outfile);
5588 fprintf(outfile,")\n");
5589 ast_print(tree->left,outfile,indent+2);
5590 ast_print(tree->right,outfile,indent+2);
5593 fprintf(outfile,"PARMS\n");
5594 ast_print(tree->left,outfile,indent+2);
5595 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5596 ast_print(tree->right,outfile,indent+2);
5599 /*------------------------------------------------------------------*/
5600 /*----------------------------*/
5601 /* return statement */
5602 /*----------------------------*/
5604 fprintf(outfile,"RETURN (%p) type (",tree);
5606 printTypeChain(tree->right->ftype,outfile);
5608 fprintf(outfile,")\n");
5609 ast_print(tree->right,outfile,indent+2);
5611 /*------------------------------------------------------------------*/
5612 /*----------------------------*/
5613 /* label statement */
5614 /*----------------------------*/
5616 fprintf(outfile,"LABEL (%p)\n",tree);
5617 ast_print(tree->left,outfile,indent+2);
5618 ast_print(tree->right,outfile,indent);
5620 /*------------------------------------------------------------------*/
5621 /*----------------------------*/
5622 /* switch statement */
5623 /*----------------------------*/
5627 fprintf(outfile,"SWITCH (%p) ",tree);
5628 ast_print(tree->left,outfile,0);
5629 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5630 INDENT(indent+2,outfile);
5631 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5632 (int) floatFromVal(val),
5633 tree->values.switchVals.swNum,
5634 (int) floatFromVal(val));
5636 ast_print(tree->right,outfile,indent);
5639 /*------------------------------------------------------------------*/
5640 /*----------------------------*/
5642 /*----------------------------*/
5644 fprintf(outfile,"IF (%p) \n",tree);
5645 ast_print(tree->left,outfile,indent+2);
5646 if (tree->trueLabel) {
5647 INDENT(indent+2,outfile);
5648 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5650 if (tree->falseLabel) {
5651 INDENT(indent+2,outfile);
5652 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5654 ast_print(tree->right,outfile,indent+2);
5656 /*----------------------------*/
5657 /* goto Statement */
5658 /*----------------------------*/
5660 fprintf(outfile,"GOTO (%p) \n",tree);
5661 ast_print(tree->left,outfile,indent+2);
5662 fprintf(outfile,"\n");
5664 /*------------------------------------------------------------------*/
5665 /*----------------------------*/
5667 /*----------------------------*/
5669 fprintf(outfile,"FOR (%p) \n",tree);
5670 if (AST_FOR( tree, initExpr)) {
5671 INDENT(indent+2,outfile);
5672 fprintf(outfile,"INIT EXPR ");
5673 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5675 if (AST_FOR( tree, condExpr)) {
5676 INDENT(indent+2,outfile);
5677 fprintf(outfile,"COND EXPR ");
5678 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5680 if (AST_FOR( tree, loopExpr)) {
5681 INDENT(indent+2,outfile);
5682 fprintf(outfile,"LOOP EXPR ");
5683 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5685 fprintf(outfile,"FOR LOOP BODY \n");
5686 ast_print(tree->left,outfile,indent+2);
5689 fprintf(outfile,"CRITICAL (%p) \n",tree);
5690 ast_print(tree->left,outfile,indent+2);
5698 ast_print(t,stdout,0);
5703 /*-----------------------------------------------------------------*/
5704 /* astErrors : returns non-zero if errors present in tree */
5705 /*-----------------------------------------------------------------*/
5706 int astErrors(ast *t)
5715 if (t->type == EX_VALUE
5716 && t->opval.val->sym
5717 && t->opval.val->sym->undefined)
5720 errors += astErrors(t->left);
5721 errors += astErrors(t->right);