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;
991 rast = newNode (NULLOP,
995 newAst_VALUE (valueFromLit ((float) i))),
996 newAst_VALUE (valueFromLit (*s))));
1000 rast = newNode (NULLOP,
1004 newAst_VALUE (valueFromLit ((float) i))),
1005 newAst_VALUE (valueFromLit (*s))));
1007 // now WE don't need iexpr's symbol anymore
1008 freeStringSymbol(AST_SYMBOL(iexpr));
1010 return decorateType (resolveSymbols (rast));
1016 /*-----------------------------------------------------------------*/
1017 /* createIvalPtr - generates initial value for pointers */
1018 /*-----------------------------------------------------------------*/
1020 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1026 if (ilist->type == INIT_DEEP)
1027 ilist = ilist->init.deep;
1029 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1031 /* if character pointer */
1032 if (IS_CHAR (type->next))
1033 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1036 return newNode ('=', sym, iexpr);
1039 /*-----------------------------------------------------------------*/
1040 /* createIval - generates code for initial value */
1041 /*-----------------------------------------------------------------*/
1043 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1050 /* if structure then */
1051 if (IS_STRUCT (type))
1052 rast = createIvalStruct (sym, type, ilist);
1054 /* if this is a pointer */
1056 rast = createIvalPtr (sym, type, ilist);
1058 /* if this is an array */
1059 if (IS_ARRAY (type))
1060 rast = createIvalArray (sym, type, ilist);
1062 /* if type is SPECIFIER */
1064 rast = createIvalType (sym, type, ilist);
1067 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1069 return decorateType (resolveSymbols (rast));
1072 /*-----------------------------------------------------------------*/
1073 /* initAggregates - initialises aggregate variables with initv */
1074 /*-----------------------------------------------------------------*/
1075 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1076 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1079 /*-----------------------------------------------------------------*/
1080 /* gatherAutoInit - creates assignment expressions for initial */
1082 /*-----------------------------------------------------------------*/
1084 gatherAutoInit (symbol * autoChain)
1091 for (sym = autoChain; sym; sym = sym->next)
1094 /* resolve the symbols in the ival */
1096 resolveIvalSym (sym->ival);
1098 /* if this is a static variable & has an */
1099 /* initial value the code needs to be lifted */
1100 /* here to the main portion since they can be */
1101 /* initialised only once at the start */
1102 if (IS_STATIC (sym->etype) && sym->ival &&
1103 SPEC_SCLS (sym->etype) != S_CODE)
1107 /* insert the symbol into the symbol table */
1108 /* with level = 0 & name = rname */
1109 newSym = copySymbol (sym);
1110 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1112 /* now lift the code to main */
1113 if (IS_AGGREGATE (sym->type)) {
1114 work = initAggregates (sym, sym->ival, NULL);
1116 if (getNelements(sym->type, sym->ival)>1) {
1117 werror (W_EXCESS_INITIALIZERS, "scalar",
1118 sym->name, sym->lineDef);
1120 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1121 list2expr (sym->ival));
1124 setAstLineno (work, sym->lineDef);
1128 staticAutos = newNode (NULLOP, staticAutos, work);
1135 /* if there is an initial value */
1136 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1138 initList *ilist=sym->ival;
1140 while (ilist->type == INIT_DEEP) {
1141 ilist = ilist->init.deep;
1144 /* update lineno for error msg */
1145 lineno=sym->lineDef;
1146 setAstLineno (ilist->init.node, lineno);
1148 if (IS_AGGREGATE (sym->type)) {
1149 work = initAggregates (sym, sym->ival, NULL);
1151 if (getNelements(sym->type, sym->ival)>1) {
1152 werror (W_EXCESS_INITIALIZERS, "scalar",
1153 sym->name, sym->lineDef);
1155 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1156 list2expr (sym->ival));
1160 setAstLineno (work, sym->lineDef);
1164 init = newNode (NULLOP, init, work);
1173 /*-----------------------------------------------------------------*/
1174 /* freeStringSymbol - delete a literal string if no more usage */
1175 /*-----------------------------------------------------------------*/
1176 void freeStringSymbol(symbol *sym) {
1177 /* make sure this is a literal string */
1178 assert (sym->isstrlit);
1179 if (--sym->isstrlit == 0) { // lower the usage count
1180 memmap *segment=SPEC_OCLS(sym->etype);
1182 deleteSetItem(&segment->syms, sym);
1187 /*-----------------------------------------------------------------*/
1188 /* stringToSymbol - creates a symbol from a literal string */
1189 /*-----------------------------------------------------------------*/
1191 stringToSymbol (value * val)
1193 char name[SDCC_NAME_MAX + 1];
1194 static int charLbl = 0;
1198 // have we heard this before?
1199 for (sp=statsg->syms; sp; sp=sp->next) {
1201 if (sym->isstrlit &&
1202 !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
1203 // yes, this is old news. Don't publish it again.
1204 sym->isstrlit++; // but raise the usage count
1205 return symbolVal(sym);
1209 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1210 sym = newSymbol (name, 0); /* make it @ level 0 */
1211 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1213 /* copy the type from the value passed */
1214 sym->type = copyLinkChain (val->type);
1215 sym->etype = getSpec (sym->type);
1216 /* change to storage class & output class */
1217 SPEC_SCLS (sym->etype) = S_CODE;
1218 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1219 SPEC_STAT (sym->etype) = 1;
1220 /* make the level & block = 0 */
1221 sym->block = sym->level = 0;
1223 /* create an ival */
1224 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1229 allocVariables (sym);
1232 return symbolVal (sym);
1236 /*-----------------------------------------------------------------*/
1237 /* processBlockVars - will go thru the ast looking for block if */
1238 /* a block is found then will allocate the syms */
1239 /* will also gather the auto inits present */
1240 /*-----------------------------------------------------------------*/
1242 processBlockVars (ast * tree, int *stack, int action)
1247 /* if this is a block */
1248 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1252 if (action == ALLOCATE)
1254 *stack += allocVariables (tree->values.sym);
1255 autoInit = gatherAutoInit (tree->values.sym);
1257 /* if there are auto inits then do them */
1259 tree->left = newNode (NULLOP, autoInit, tree->left);
1261 else /* action is deallocate */
1262 deallocLocal (tree->values.sym);
1265 processBlockVars (tree->left, stack, action);
1266 processBlockVars (tree->right, stack, action);
1271 /*-------------------------------------------------------------*/
1272 /* constExprTree - returns TRUE if this tree is a constant */
1274 /*-------------------------------------------------------------*/
1275 bool constExprTree (ast *cexpr) {
1281 cexpr = decorateType (resolveSymbols (cexpr));
1283 switch (cexpr->type)
1286 if (IS_AST_LIT_VALUE(cexpr)) {
1287 // this is a literal
1290 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1291 // a function's address will never change
1294 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1295 // an array's address will never change
1298 if (IS_AST_SYM_VALUE(cexpr) &&
1299 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1300 // a symbol in code space will never change
1301 // This is only for the 'char *s="hallo"' case and will have to leave
1302 //printf(" code space symbol");
1307 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1308 "unexpected link in expression tree\n");
1311 if (cexpr->opval.op==ARRAYINIT) {
1312 // this is a list of literals
1315 if (cexpr->opval.op=='=') {
1316 return constExprTree(cexpr->right);
1318 if (cexpr->opval.op==CAST) {
1319 // cast ignored, maybe we should throw a warning here?
1320 return constExprTree(cexpr->right);
1322 if (cexpr->opval.op=='&') {
1325 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1328 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1333 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1338 /*-----------------------------------------------------------------*/
1339 /* constExprValue - returns the value of a constant expression */
1340 /* or NULL if it is not a constant expression */
1341 /*-----------------------------------------------------------------*/
1343 constExprValue (ast * cexpr, int check)
1345 cexpr = decorateType (resolveSymbols (cexpr));
1347 /* if this is not a constant then */
1348 if (!IS_LITERAL (cexpr->ftype))
1350 /* then check if this is a literal array
1352 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1353 SPEC_CVAL (cexpr->etype).v_char &&
1354 IS_ARRAY (cexpr->ftype))
1356 value *val = valFromType (cexpr->ftype);
1357 SPEC_SCLS (val->etype) = S_LITERAL;
1358 val->sym = cexpr->opval.val->sym;
1359 val->sym->type = copyLinkChain (cexpr->ftype);
1360 val->sym->etype = getSpec (val->sym->type);
1361 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1365 /* if we are casting a literal value then */
1366 if (IS_AST_OP (cexpr) &&
1367 cexpr->opval.op == CAST &&
1368 IS_LITERAL (cexpr->right->ftype))
1370 return valCastLiteral (cexpr->ftype,
1371 floatFromVal (cexpr->right->opval.val));
1374 if (IS_AST_VALUE (cexpr))
1376 return cexpr->opval.val;
1380 werror (E_CONST_EXPECTED, "found expression");
1385 /* return the value */
1386 return cexpr->opval.val;
1390 /*-----------------------------------------------------------------*/
1391 /* isLabelInAst - will return true if a given label is found */
1392 /*-----------------------------------------------------------------*/
1394 isLabelInAst (symbol * label, ast * tree)
1396 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1399 if (IS_AST_OP (tree) &&
1400 tree->opval.op == LABEL &&
1401 isSymbolEqual (AST_SYMBOL (tree->left), label))
1404 return isLabelInAst (label, tree->right) &&
1405 isLabelInAst (label, tree->left);
1409 /*-----------------------------------------------------------------*/
1410 /* isLoopCountable - return true if the loop count can be determi- */
1411 /* -ned at compile time . */
1412 /*-----------------------------------------------------------------*/
1414 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1415 symbol ** sym, ast ** init, ast ** end)
1418 /* the loop is considered countable if the following
1419 conditions are true :-
1421 a) initExpr :- <sym> = <const>
1422 b) condExpr :- <sym> < <const1>
1423 c) loopExpr :- <sym> ++
1426 /* first check the initExpr */
1427 if (IS_AST_OP (initExpr) &&
1428 initExpr->opval.op == '=' && /* is assignment */
1429 IS_AST_SYM_VALUE (initExpr->left))
1430 { /* left is a symbol */
1432 *sym = AST_SYMBOL (initExpr->left);
1433 *init = initExpr->right;
1438 /* for now the symbol has to be of
1440 if (!IS_INTEGRAL ((*sym)->type))
1443 /* now check condExpr */
1444 if (IS_AST_OP (condExpr))
1447 switch (condExpr->opval.op)
1450 if (IS_AST_SYM_VALUE (condExpr->left) &&
1451 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1452 IS_AST_LIT_VALUE (condExpr->right))
1454 *end = condExpr->right;
1460 if (IS_AST_OP (condExpr->left) &&
1461 condExpr->left->opval.op == '>' &&
1462 IS_AST_LIT_VALUE (condExpr->left->right) &&
1463 IS_AST_SYM_VALUE (condExpr->left->left) &&
1464 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1467 *end = newNode ('+', condExpr->left->right,
1468 newAst_VALUE (constVal ("1")));
1479 /* check loop expression is of the form <sym>++ */
1480 if (!IS_AST_OP (loopExpr))
1483 /* check if <sym> ++ */
1484 if (loopExpr->opval.op == INC_OP)
1490 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1491 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1498 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1499 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1507 if (loopExpr->opval.op == ADD_ASSIGN)
1510 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1511 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1512 IS_AST_LIT_VALUE (loopExpr->right) &&
1513 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1521 /*-----------------------------------------------------------------*/
1522 /* astHasVolatile - returns true if ast contains any volatile */
1523 /*-----------------------------------------------------------------*/
1525 astHasVolatile (ast * tree)
1530 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1533 if (IS_AST_OP (tree))
1534 return astHasVolatile (tree->left) ||
1535 astHasVolatile (tree->right);
1540 /*-----------------------------------------------------------------*/
1541 /* astHasPointer - return true if the ast contains any ptr variable */
1542 /*-----------------------------------------------------------------*/
1544 astHasPointer (ast * tree)
1549 if (IS_AST_LINK (tree))
1552 /* if we hit an array expression then check
1553 only the left side */
1554 if (IS_AST_OP (tree) && tree->opval.op == '[')
1555 return astHasPointer (tree->left);
1557 if (IS_AST_VALUE (tree))
1558 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1560 return astHasPointer (tree->left) ||
1561 astHasPointer (tree->right);
1565 /*-----------------------------------------------------------------*/
1566 /* astHasSymbol - return true if the ast has the given symbol */
1567 /*-----------------------------------------------------------------*/
1569 astHasSymbol (ast * tree, symbol * sym)
1571 if (!tree || IS_AST_LINK (tree))
1574 if (IS_AST_VALUE (tree))
1576 if (IS_AST_SYM_VALUE (tree))
1577 return isSymbolEqual (AST_SYMBOL (tree), sym);
1582 return astHasSymbol (tree->left, sym) ||
1583 astHasSymbol (tree->right, sym);
1586 /*-----------------------------------------------------------------*/
1587 /* astHasDeref - return true if the ast has an indirect access */
1588 /*-----------------------------------------------------------------*/
1590 astHasDeref (ast * tree)
1592 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1595 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1597 return astHasDeref (tree->left) || astHasDeref (tree->right);
1600 /*-----------------------------------------------------------------*/
1601 /* isConformingBody - the loop body has to conform to a set of rules */
1602 /* for the loop to be considered reversible read on for rules */
1603 /*-----------------------------------------------------------------*/
1605 isConformingBody (ast * pbody, symbol * sym, ast * body)
1608 /* we are going to do a pre-order traversal of the
1609 tree && check for the following conditions. (essentially
1610 a set of very shallow tests )
1611 a) the sym passed does not participate in
1612 any arithmetic operation
1613 b) There are no function calls
1614 c) all jumps are within the body
1615 d) address of loop control variable not taken
1616 e) if an assignment has a pointer on the
1617 left hand side make sure right does not have
1618 loop control variable */
1620 /* if we reach the end or a leaf then true */
1621 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1624 /* if anything else is "volatile" */
1625 if (IS_VOLATILE (TETYPE (pbody)))
1628 /* we will walk the body in a pre-order traversal for
1630 switch (pbody->opval.op)
1632 /*------------------------------------------------------------------*/
1634 // if the loopvar is used as an index
1635 if (astHasSymbol(pbody->right, sym)) {
1638 return isConformingBody (pbody->right, sym, body);
1640 /*------------------------------------------------------------------*/
1645 /*------------------------------------------------------------------*/
1649 /* sure we are not sym is not modified */
1651 IS_AST_SYM_VALUE (pbody->left) &&
1652 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1656 IS_AST_SYM_VALUE (pbody->right) &&
1657 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1662 /*------------------------------------------------------------------*/
1664 case '*': /* can be unary : if right is null then unary operation */
1669 /* if right is NULL then unary operation */
1670 /*------------------------------------------------------------------*/
1671 /*----------------------------*/
1673 /*----------------------------*/
1676 if (IS_AST_SYM_VALUE (pbody->left) &&
1677 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1680 return isConformingBody (pbody->left, sym, body);
1684 if (astHasSymbol (pbody->left, sym) ||
1685 astHasSymbol (pbody->right, sym))
1690 /*------------------------------------------------------------------*/
1698 if (IS_AST_SYM_VALUE (pbody->left) &&
1699 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1702 if (IS_AST_SYM_VALUE (pbody->right) &&
1703 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1706 return isConformingBody (pbody->left, sym, body) &&
1707 isConformingBody (pbody->right, sym, body);
1715 if (IS_AST_SYM_VALUE (pbody->left) &&
1716 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1718 return isConformingBody (pbody->left, sym, body);
1720 /*------------------------------------------------------------------*/
1732 case SIZEOF: /* evaluate wihout code generation */
1734 if (IS_AST_SYM_VALUE (pbody->left) &&
1735 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1738 if (IS_AST_SYM_VALUE (pbody->right) &&
1739 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1742 return isConformingBody (pbody->left, sym, body) &&
1743 isConformingBody (pbody->right, sym, body);
1745 /*------------------------------------------------------------------*/
1748 /* if left has a pointer & right has loop
1749 control variable then we cannot */
1750 if (astHasPointer (pbody->left) &&
1751 astHasSymbol (pbody->right, sym))
1753 if (astHasVolatile (pbody->left))
1756 if (IS_AST_SYM_VALUE (pbody->left)) {
1757 // if the loopvar has an assignment
1758 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1760 // if the loopvar is used in another (maybe conditional) block
1761 if (astHasSymbol (pbody->right, sym) &&
1762 (pbody->level >= body->level)) {
1767 if (astHasVolatile (pbody->left))
1770 if (astHasDeref(pbody->right)) return FALSE;
1772 return isConformingBody (pbody->left, sym, body) &&
1773 isConformingBody (pbody->right, sym, body);
1784 assert ("Parser should not have generated this\n");
1786 /*------------------------------------------------------------------*/
1787 /*----------------------------*/
1788 /* comma operator */
1789 /*----------------------------*/
1791 return isConformingBody (pbody->left, sym, body) &&
1792 isConformingBody (pbody->right, sym, body);
1794 /*------------------------------------------------------------------*/
1795 /*----------------------------*/
1797 /*----------------------------*/
1799 /* if local & not passed as paramater then ok */
1800 if (sym->level && !astHasSymbol(pbody->right,sym))
1804 /*------------------------------------------------------------------*/
1805 /*----------------------------*/
1806 /* return statement */
1807 /*----------------------------*/
1812 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1817 if (astHasSymbol (pbody->left, sym))
1824 return isConformingBody (pbody->left, sym, body) &&
1825 isConformingBody (pbody->right, sym, body);
1831 /*-----------------------------------------------------------------*/
1832 /* isLoopReversible - takes a for loop as input && returns true */
1833 /* if the for loop is reversible. If yes will set the value of */
1834 /* the loop control var & init value & termination value */
1835 /*-----------------------------------------------------------------*/
1837 isLoopReversible (ast * loop, symbol ** loopCntrl,
1838 ast ** init, ast ** end)
1840 /* if option says don't do it then don't */
1841 if (optimize.noLoopReverse)
1843 /* there are several tests to determine this */
1845 /* for loop has to be of the form
1846 for ( <sym> = <const1> ;
1847 [<sym> < <const2>] ;
1848 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1850 if (!isLoopCountable (AST_FOR (loop, initExpr),
1851 AST_FOR (loop, condExpr),
1852 AST_FOR (loop, loopExpr),
1853 loopCntrl, init, end))
1856 /* now do some serious checking on the body of the loop
1859 return isConformingBody (loop->left, *loopCntrl, loop->left);
1863 /*-----------------------------------------------------------------*/
1864 /* replLoopSym - replace the loop sym by loop sym -1 */
1865 /*-----------------------------------------------------------------*/
1867 replLoopSym (ast * body, symbol * sym)
1870 if (!body || IS_AST_LINK (body))
1873 if (IS_AST_SYM_VALUE (body))
1876 if (isSymbolEqual (AST_SYMBOL (body), sym))
1880 body->opval.op = '-';
1881 body->left = newAst_VALUE (symbolVal (sym));
1882 body->right = newAst_VALUE (constVal ("1"));
1890 replLoopSym (body->left, sym);
1891 replLoopSym (body->right, sym);
1895 /*-----------------------------------------------------------------*/
1896 /* reverseLoop - do the actual loop reversal */
1897 /*-----------------------------------------------------------------*/
1899 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1903 /* create the following tree
1908 if (sym) goto for_continue ;
1911 /* put it together piece by piece */
1912 rloop = newNode (NULLOP,
1913 createIf (newAst_VALUE (symbolVal (sym)),
1915 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1918 newAst_VALUE (symbolVal (sym)),
1921 replLoopSym (loop->left, sym);
1922 setAstLineno (rloop, init->lineno);
1924 rloop = newNode (NULLOP,
1926 newAst_VALUE (symbolVal (sym)),
1927 newNode ('-', end, init)),
1928 createLabel (AST_FOR (loop, continueLabel),
1932 newNode (SUB_ASSIGN,
1933 newAst_VALUE (symbolVal (sym)),
1934 newAst_VALUE (constVal ("1"))),
1937 rloop->lineno=init->lineno;
1938 return decorateType (rloop);
1942 /*-----------------------------------------------------------------*/
1943 /* searchLitOp - search tree (*ops only) for an ast with literal */
1944 /*-----------------------------------------------------------------*/
1946 searchLitOp (ast *tree, ast **parent, const char *ops)
1950 if (tree && optimize.global_cse)
1952 /* is there a literal operand? */
1954 IS_AST_OP(tree->right) &&
1955 tree->right->right &&
1956 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1958 if (IS_LITERAL (RTYPE (tree->right)) ^
1959 IS_LITERAL (LTYPE (tree->right)))
1961 tree->right->decorated = 0;
1962 tree->decorated = 0;
1966 ret = searchLitOp (tree->right, parent, ops);
1971 IS_AST_OP(tree->left) &&
1972 tree->left->right &&
1973 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1975 if (IS_LITERAL (RTYPE (tree->left)) ^
1976 IS_LITERAL (LTYPE (tree->left)))
1978 tree->left->decorated = 0;
1979 tree->decorated = 0;
1983 ret = searchLitOp (tree->left, parent, ops);
1991 /*-----------------------------------------------------------------*/
1992 /* decorateType - compute type for this tree also does type checking */
1993 /* this is done bottom up, since type have to flow upwards */
1994 /* it also does constant folding, and paramater checking */
1995 /*-----------------------------------------------------------------*/
1997 decorateType (ast * tree)
2005 /* if already has type then do nothing */
2006 if (tree->decorated)
2009 tree->decorated = 1;
2012 /* print the line */
2013 /* if not block & function */
2014 if (tree->type == EX_OP &&
2015 (tree->opval.op != FUNCTION &&
2016 tree->opval.op != BLOCK &&
2017 tree->opval.op != NULLOP))
2019 filename = tree->filename;
2020 lineno = tree->lineno;
2024 /* if any child is an error | this one is an error do nothing */
2025 if (tree->isError ||
2026 (tree->left && tree->left->isError) ||
2027 (tree->right && tree->right->isError))
2030 /*------------------------------------------------------------------*/
2031 /*----------------------------*/
2032 /* leaf has been reached */
2033 /*----------------------------*/
2034 lineno=tree->lineno;
2035 /* if this is of type value */
2036 /* just get the type */
2037 if (tree->type == EX_VALUE)
2040 if (IS_LITERAL (tree->opval.val->etype))
2043 /* if this is a character array then declare it */
2044 if (IS_ARRAY (tree->opval.val->type))
2045 tree->opval.val = stringToSymbol (tree->opval.val);
2047 /* otherwise just copy the type information */
2048 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2052 if (tree->opval.val->sym)
2054 /* if the undefined flag is set then give error message */
2055 if (tree->opval.val->sym->undefined)
2057 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2059 TTYPE (tree) = TETYPE (tree) =
2060 tree->opval.val->type = tree->opval.val->sym->type =
2061 tree->opval.val->etype = tree->opval.val->sym->etype =
2062 copyLinkChain (INTTYPE);
2067 /* if impilicit i.e. struct/union member then no type */
2068 if (tree->opval.val->sym->implicit)
2069 TTYPE (tree) = TETYPE (tree) = NULL;
2074 /* else copy the type */
2075 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2077 /* and mark it as referenced */
2078 tree->opval.val->sym->isref = 1;
2086 /* if type link for the case of cast */
2087 if (tree->type == EX_LINK)
2089 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2096 dtl = decorateType (tree->left);
2097 /* delay right side for '?' operator since conditional macro expansions might
2099 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2101 /* this is to take care of situations
2102 when the tree gets rewritten */
2103 if (dtl != tree->left)
2105 if (dtr != tree->right)
2107 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2110 if (IS_AST_OP(tree) &&
2111 (tree->opval.op == CAST || tree->opval.op == '=') &&
2112 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2113 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2114 // this is a cast/assign to a bigger type
2115 if (IS_AST_OP(tree->right) &&
2116 IS_INTEGRAL(tree->right->ftype) &&
2117 (tree->right->opval.op == LEFT_OP ||
2118 tree->right->opval.op == '*' ||
2119 tree->right->opval.op == '+' ||
2120 tree->right->opval.op == '-') &&
2121 tree->right->right) {
2122 // we should cast an operand instead of the result
2123 tree->right->decorated = 0;
2124 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2126 tree->right = decorateType(tree->right);
2131 /* depending on type of operator do */
2133 switch (tree->opval.op)
2135 /*------------------------------------------------------------------*/
2136 /*----------------------------*/
2138 /*----------------------------*/
2141 /* determine which is the array & which the index */
2142 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2145 ast *tempTree = tree->left;
2146 tree->left = tree->right;
2147 tree->right = tempTree;
2150 /* first check if this is a array or a pointer */
2151 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2153 werror (E_NEED_ARRAY_PTR, "[]");
2154 goto errorTreeReturn;
2157 /* check if the type of the idx */
2158 if (!IS_INTEGRAL (RTYPE (tree)))
2160 werror (E_IDX_NOT_INT);
2161 goto errorTreeReturn;
2164 /* if the left is an rvalue then error */
2167 werror (E_LVALUE_REQUIRED, "array access");
2168 goto errorTreeReturn;
2171 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2174 /*------------------------------------------------------------------*/
2175 /*----------------------------*/
2177 /*----------------------------*/
2179 /* if this is not a structure */
2180 if (!IS_STRUCT (LTYPE (tree)))
2182 werror (E_STRUCT_UNION, ".");
2183 goto errorTreeReturn;
2185 TTYPE (tree) = structElemType (LTYPE (tree),
2186 (tree->right->type == EX_VALUE ?
2187 tree->right->opval.val : NULL));
2188 TETYPE (tree) = getSpec (TTYPE (tree));
2191 /*------------------------------------------------------------------*/
2192 /*----------------------------*/
2193 /* struct/union pointer */
2194 /*----------------------------*/
2196 /* if not pointer to a structure */
2197 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2199 werror (E_PTR_REQD);
2200 goto errorTreeReturn;
2203 if (!IS_STRUCT (LTYPE (tree)->next))
2205 werror (E_STRUCT_UNION, "->");
2206 goto errorTreeReturn;
2209 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2210 (tree->right->type == EX_VALUE ?
2211 tree->right->opval.val : NULL));
2212 TETYPE (tree) = getSpec (TTYPE (tree));
2214 /* adjust the storage class */
2215 switch (DCL_TYPE(tree->left->ftype)) {
2217 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2220 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2223 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2226 SPEC_SCLS (TETYPE (tree)) = 0;
2229 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2232 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2235 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2238 SPEC_SCLS (TETYPE (tree)) = 0;
2245 /* This breaks with extern declarations, bitfields, and perhaps other */
2246 /* cases (gcse). Let's leave this optimization disabled for now and */
2247 /* ponder if there's a safe way to do this. -- EEP */
2249 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2250 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2252 /* If defined struct type at addr var
2253 then rewrite (&struct var)->member
2255 and define membertype at (addr+offsetof(struct var,member)) temp
2258 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2259 AST_SYMBOL(tree->right));
2261 sym = newSymbol(genSymName (0), 0);
2262 sym->type = TTYPE (tree);
2263 sym->etype = getSpec(sym->type);
2264 sym->lineDef = tree->lineno;
2267 SPEC_STAT (sym->etype) = 1;
2268 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2270 SPEC_ABSA(sym->etype) = 1;
2271 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2274 AST_VALUE (tree) = symbolVal(sym);
2277 tree->type = EX_VALUE;
2285 /*------------------------------------------------------------------*/
2286 /*----------------------------*/
2287 /* ++/-- operation */
2288 /*----------------------------*/
2292 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2293 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2294 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2295 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2304 /*------------------------------------------------------------------*/
2305 /*----------------------------*/
2307 /*----------------------------*/
2308 case '&': /* can be unary */
2309 /* if right is NULL then unary operation */
2310 if (tree->right) /* not an unary operation */
2313 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2315 werror (E_BITWISE_OP);
2316 werror (W_CONTINUE, "left & right types are ");
2317 printTypeChain (LTYPE (tree), stderr);
2318 fprintf (stderr, ",");
2319 printTypeChain (RTYPE (tree), stderr);
2320 fprintf (stderr, "\n");
2321 goto errorTreeReturn;
2324 /* if they are both literal */
2325 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2327 tree->type = EX_VALUE;
2328 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2329 valFromType (RETYPE (tree)), '&');
2331 tree->right = tree->left = NULL;
2332 TETYPE (tree) = tree->opval.val->etype;
2333 TTYPE (tree) = tree->opval.val->type;
2337 /* see if this is a GETHBIT operation if yes
2340 ast *otree = optimizeGetHbit (tree);
2343 return decorateType (otree);
2347 computeType (LTYPE (tree), RTYPE (tree));
2348 TETYPE (tree) = getSpec (TTYPE (tree));
2350 /* if left is a literal exchange left & right */
2351 if (IS_LITERAL (LTYPE (tree)))
2353 ast *tTree = tree->left;
2354 tree->left = tree->right;
2355 tree->right = tTree;
2358 /* if right is a literal and */
2359 /* we can find a 2nd literal in a and-tree then */
2360 /* rearrange the tree */
2361 if (IS_LITERAL (RTYPE (tree)))
2364 ast *litTree = searchLitOp (tree, &parent, "&");
2367 ast *tTree = litTree->left;
2368 litTree->left = tree->right;
2369 tree->right = tTree;
2370 /* both operands in tTree are literal now */
2371 decorateType (parent);
2375 LRVAL (tree) = RRVAL (tree) = 1;
2379 /*------------------------------------------------------------------*/
2380 /*----------------------------*/
2382 /*----------------------------*/
2383 p = newLink (DECLARATOR);
2384 /* if bit field then error */
2385 if (IS_BITVAR (tree->left->etype))
2387 werror (E_ILLEGAL_ADDR, "address of bit variable");
2388 goto errorTreeReturn;
2391 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2393 werror (E_ILLEGAL_ADDR, "address of register variable");
2394 goto errorTreeReturn;
2397 if (IS_FUNC (LTYPE (tree)))
2399 // this ought to be ignored
2400 return (tree->left);
2403 if (IS_LITERAL(LTYPE(tree)))
2405 werror (E_ILLEGAL_ADDR, "address of literal");
2406 goto errorTreeReturn;
2411 werror (E_LVALUE_REQUIRED, "address of");
2412 goto errorTreeReturn;
2415 DCL_TYPE (p) = POINTER;
2416 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2417 DCL_TYPE (p) = CPOINTER;
2418 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2419 DCL_TYPE (p) = FPOINTER;
2420 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2421 DCL_TYPE (p) = PPOINTER;
2422 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2423 DCL_TYPE (p) = IPOINTER;
2424 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2425 DCL_TYPE (p) = EEPPOINTER;
2426 else if (SPEC_OCLS(tree->left->etype))
2427 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2429 DCL_TYPE (p) = POINTER;
2431 if (IS_AST_SYM_VALUE (tree->left))
2433 AST_SYMBOL (tree->left)->addrtaken = 1;
2434 AST_SYMBOL (tree->left)->allocreq = 1;
2437 p->next = LTYPE (tree);
2439 TETYPE (tree) = getSpec (TTYPE (tree));
2444 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2445 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2447 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2448 AST_SYMBOL(tree->left->right));
2449 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2450 valueFromLit(element->offset));
2453 tree->type = EX_VALUE;
2454 tree->values.literalFromCast = 1;
2460 /*------------------------------------------------------------------*/
2461 /*----------------------------*/
2463 /*----------------------------*/
2465 /* if the rewrite succeeds then don't go any furthur */
2467 ast *wtree = optimizeRRCRLC (tree);
2469 return decorateType (wtree);
2471 wtree = optimizeSWAP (tree);
2473 return decorateType (wtree);
2478 /* if left is a literal exchange left & right */
2479 if (IS_LITERAL (LTYPE (tree)))
2481 ast *tTree = tree->left;
2482 tree->left = tree->right;
2483 tree->right = tTree;
2486 /* if right is a literal and */
2487 /* we can find a 2nd literal in a or-tree then */
2488 /* rearrange the tree */
2489 if (IS_LITERAL (RTYPE (tree)))
2492 ast *litTree = searchLitOp (tree, &parent, "|");
2495 ast *tTree = litTree->left;
2496 litTree->left = tree->right;
2497 tree->right = tTree;
2498 /* both operands in tTree are literal now */
2499 decorateType (parent);
2502 /*------------------------------------------------------------------*/
2503 /*----------------------------*/
2505 /*----------------------------*/
2507 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2509 werror (E_BITWISE_OP);
2510 werror (W_CONTINUE, "left & right types are ");
2511 printTypeChain (LTYPE (tree), stderr);
2512 fprintf (stderr, ",");
2513 printTypeChain (RTYPE (tree), stderr);
2514 fprintf (stderr, "\n");
2515 goto errorTreeReturn;
2518 /* if they are both literal then */
2519 /* rewrite the tree */
2520 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2522 tree->type = EX_VALUE;
2523 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2524 valFromType (RETYPE (tree)),
2526 tree->right = tree->left = NULL;
2527 TETYPE (tree) = tree->opval.val->etype;
2528 TTYPE (tree) = tree->opval.val->type;
2532 /* if left is a literal exchange left & right */
2533 if (IS_LITERAL (LTYPE (tree)))
2535 ast *tTree = tree->left;
2536 tree->left = tree->right;
2537 tree->right = tTree;
2540 /* if right is a literal and */
2541 /* we can find a 2nd literal in a xor-tree then */
2542 /* rearrange the tree */
2543 if (IS_LITERAL (RTYPE (tree)))
2546 ast *litTree = searchLitOp (tree, &parent, "^");
2549 ast *tTree = litTree->left;
2550 litTree->left = tree->right;
2551 tree->right = tTree;
2552 /* both operands in litTree are literal now */
2553 decorateType (parent);
2557 LRVAL (tree) = RRVAL (tree) = 1;
2558 TETYPE (tree) = getSpec (TTYPE (tree) =
2559 computeType (LTYPE (tree),
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2565 /*----------------------------*/
2567 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2569 werror (E_INVALID_OP, "divide");
2570 goto errorTreeReturn;
2572 /* if they are both literal then */
2573 /* rewrite the tree */
2574 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2576 tree->type = EX_VALUE;
2577 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2578 valFromType (RETYPE (tree)));
2579 tree->right = tree->left = NULL;
2580 TETYPE (tree) = getSpec (TTYPE (tree) =
2581 tree->opval.val->type);
2585 LRVAL (tree) = RRVAL (tree) = 1;
2586 TETYPE (tree) = getSpec (TTYPE (tree) =
2587 computeType (LTYPE (tree),
2590 /* if right is a literal and */
2591 /* left is also a division by a literal then */
2592 /* rearrange the tree */
2593 if (IS_LITERAL (RTYPE (tree))
2594 /* avoid infinite loop */
2595 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2598 ast *litTree = searchLitOp (tree, &parent, "/");
2601 if (IS_LITERAL (RTYPE (litTree)))
2604 litTree->right = newNode ('*', litTree->right, tree->right);
2605 litTree->right->lineno = tree->lineno;
2607 tree->right->opval.val = constVal ("1");
2608 decorateType (parent);
2612 /* litTree->left is literal: no gcse possible.
2613 We can't call decorateType(parent), because
2614 this would cause an infinit loop. */
2615 parent->decorated = 1;
2616 decorateType (litTree);
2623 /*------------------------------------------------------------------*/
2624 /*----------------------------*/
2626 /*----------------------------*/
2628 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2630 werror (E_BITWISE_OP);
2631 werror (W_CONTINUE, "left & right types are ");
2632 printTypeChain (LTYPE (tree), stderr);
2633 fprintf (stderr, ",");
2634 printTypeChain (RTYPE (tree), stderr);
2635 fprintf (stderr, "\n");
2636 goto errorTreeReturn;
2638 /* if they are both literal then */
2639 /* rewrite the tree */
2640 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2642 tree->type = EX_VALUE;
2643 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2644 valFromType (RETYPE (tree)));
2645 tree->right = tree->left = NULL;
2646 TETYPE (tree) = getSpec (TTYPE (tree) =
2647 tree->opval.val->type);
2650 LRVAL (tree) = RRVAL (tree) = 1;
2651 TETYPE (tree) = getSpec (TTYPE (tree) =
2652 computeType (LTYPE (tree),
2656 /*------------------------------------------------------------------*/
2657 /*----------------------------*/
2658 /* address dereference */
2659 /*----------------------------*/
2660 case '*': /* can be unary : if right is null then unary operation */
2663 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2665 werror (E_PTR_REQD);
2666 goto errorTreeReturn;
2671 werror (E_LVALUE_REQUIRED, "pointer deref");
2672 goto errorTreeReturn;
2674 if (IS_ADDRESS_OF_OP(tree->left))
2676 /* replace *&obj with obj */
2677 return tree->left->left;
2679 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2680 TETYPE (tree) = getSpec (TTYPE (tree));
2681 /* adjust the storage class */
2682 switch (DCL_TYPE(tree->left->ftype)) {
2684 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2687 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2690 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2693 SPEC_SCLS (TETYPE (tree)) = 0;
2696 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2699 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2702 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2705 SPEC_SCLS (TETYPE (tree)) = 0;
2714 /*------------------------------------------------------------------*/
2715 /*----------------------------*/
2716 /* multiplication */
2717 /*----------------------------*/
2718 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2720 werror (E_INVALID_OP, "multiplication");
2721 goto errorTreeReturn;
2724 /* if they are both literal then */
2725 /* rewrite the tree */
2726 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2728 tree->type = EX_VALUE;
2729 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2730 valFromType (RETYPE (tree)));
2731 tree->right = tree->left = NULL;
2732 TETYPE (tree) = getSpec (TTYPE (tree) =
2733 tree->opval.val->type);
2737 /* if left is a literal exchange left & right */
2738 if (IS_LITERAL (LTYPE (tree)))
2740 ast *tTree = tree->left;
2741 tree->left = tree->right;
2742 tree->right = tTree;
2745 /* if right is a literal and */
2746 /* we can find a 2nd literal in a mul-tree then */
2747 /* rearrange the tree */
2748 if (IS_LITERAL (RTYPE (tree)))
2751 ast *litTree = searchLitOp (tree, &parent, "*");
2754 ast *tTree = litTree->left;
2755 litTree->left = tree->right;
2756 tree->right = tTree;
2757 /* both operands in litTree are literal now */
2758 decorateType (parent);
2762 LRVAL (tree) = RRVAL (tree) = 1;
2763 TETYPE (tree) = getSpec (TTYPE (tree) =
2764 computeType (LTYPE (tree),
2767 /* promote result to int if left & right are char
2768 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2769 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2770 SPEC_NOUN(TETYPE(tree)) = V_INT;
2775 /*------------------------------------------------------------------*/
2776 /*----------------------------*/
2777 /* unary '+' operator */
2778 /*----------------------------*/
2783 if (!IS_INTEGRAL (LTYPE (tree)))
2785 werror (E_UNARY_OP, '+');
2786 goto errorTreeReturn;
2789 /* if left is a literal then do it */
2790 if (IS_LITERAL (LTYPE (tree)))
2792 tree->type = EX_VALUE;
2793 tree->opval.val = valFromType (LETYPE (tree));
2795 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2799 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2803 /*------------------------------------------------------------------*/
2804 /*----------------------------*/
2806 /*----------------------------*/
2808 /* this is not a unary operation */
2809 /* if both pointers then problem */
2810 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2811 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2813 werror (E_PTR_PLUS_PTR);
2814 goto errorTreeReturn;
2817 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2818 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2820 werror (E_PLUS_INVALID, "+");
2821 goto errorTreeReturn;
2824 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2825 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2827 werror (E_PLUS_INVALID, "+");
2828 goto errorTreeReturn;
2830 /* if they are both literal then */
2831 /* rewrite the tree */
2832 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2834 tree->type = EX_VALUE;
2835 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2836 valFromType (RETYPE (tree)));
2837 tree->right = tree->left = NULL;
2838 TETYPE (tree) = getSpec (TTYPE (tree) =
2839 tree->opval.val->type);
2843 /* if the right is a pointer or left is a literal
2844 xchange left & right */
2845 if (IS_ARRAY (RTYPE (tree)) ||
2846 IS_PTR (RTYPE (tree)) ||
2847 IS_LITERAL (LTYPE (tree)))
2849 ast *tTree = tree->left;
2850 tree->left = tree->right;
2851 tree->right = tTree;
2854 /* if right is a literal and */
2855 /* left is also an addition/subtraction with a literal then */
2856 /* rearrange the tree */
2857 if (IS_LITERAL (RTYPE (tree)))
2859 ast *litTree, *parent;
2860 litTree = searchLitOp (tree, &parent, "+-");
2863 if (litTree->opval.op == '+')
2866 ast *tTree = litTree->left;
2867 litTree->left = tree->right;
2868 tree->right = tree->left;
2871 else if (litTree->opval.op == '-')
2873 if (IS_LITERAL (RTYPE (litTree)))
2876 ast *tTree = litTree->left;
2877 litTree->left = tree->right;
2878 tree->right = tTree;
2883 ast *tTree = litTree->right;
2884 litTree->right = tree->right;
2885 tree->right = tTree;
2886 litTree->opval.op = '+';
2887 tree->opval.op = '-';
2890 decorateType (parent);
2894 LRVAL (tree) = RRVAL (tree) = 1;
2895 /* if the left is a pointer */
2896 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2897 TETYPE (tree) = getSpec (TTYPE (tree) =
2900 TETYPE (tree) = getSpec (TTYPE (tree) =
2901 computeType (LTYPE (tree),
2905 /*------------------------------------------------------------------*/
2906 /*----------------------------*/
2908 /*----------------------------*/
2909 case '-': /* can be unary */
2910 /* if right is null then unary */
2914 if (!IS_ARITHMETIC (LTYPE (tree)))
2916 werror (E_UNARY_OP, tree->opval.op);
2917 goto errorTreeReturn;
2920 /* if left is a literal then do it */
2921 if (IS_LITERAL (LTYPE (tree)))
2923 tree->type = EX_VALUE;
2924 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2926 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2927 SPEC_USIGN(TETYPE(tree)) = 0;
2931 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2935 /*------------------------------------------------------------------*/
2936 /*----------------------------*/
2938 /*----------------------------*/
2940 if (!(IS_PTR (LTYPE (tree)) ||
2941 IS_ARRAY (LTYPE (tree)) ||
2942 IS_ARITHMETIC (LTYPE (tree))))
2944 werror (E_PLUS_INVALID, "-");
2945 goto errorTreeReturn;
2948 if (!(IS_PTR (RTYPE (tree)) ||
2949 IS_ARRAY (RTYPE (tree)) ||
2950 IS_ARITHMETIC (RTYPE (tree))))
2952 werror (E_PLUS_INVALID, "-");
2953 goto errorTreeReturn;
2956 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2957 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2958 IS_INTEGRAL (RTYPE (tree))))
2960 werror (E_PLUS_INVALID, "-");
2961 goto errorTreeReturn;
2964 /* if they are both literal then */
2965 /* rewrite the tree */
2966 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2968 tree->type = EX_VALUE;
2969 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2970 valFromType (RETYPE (tree)));
2971 tree->right = tree->left = NULL;
2972 TETYPE (tree) = getSpec (TTYPE (tree) =
2973 tree->opval.val->type);
2977 /* if the left & right are equal then zero */
2978 if (isAstEqual (tree->left, tree->right))
2980 tree->type = EX_VALUE;
2981 tree->left = tree->right = NULL;
2982 tree->opval.val = constVal ("0");
2983 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2987 /* if both of them are pointers or arrays then */
2988 /* the result is going to be an integer */
2989 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2990 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2991 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2993 /* if only the left is a pointer */
2994 /* then result is a pointer */
2995 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2996 TETYPE (tree) = getSpec (TTYPE (tree) =
2999 TETYPE (tree) = getSpec (TTYPE (tree) =
3000 computeType (LTYPE (tree),
3003 LRVAL (tree) = RRVAL (tree) = 1;
3005 /* if right is a literal and */
3006 /* left is also an addition/subtraction with a literal then */
3007 /* rearrange the tree */
3008 if (IS_LITERAL (RTYPE (tree))
3009 /* avoid infinite loop */
3010 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3012 ast *litTree, *litParent;
3013 litTree = searchLitOp (tree, &litParent, "+-");
3016 if (litTree->opval.op == '+')
3019 litTree->right = newNode ('-', litTree->right, tree->right);
3020 litTree->right->lineno = tree->lineno;
3022 tree->right->opval.val = constVal ("0");
3024 else if (litTree->opval.op == '-')
3026 if (IS_LITERAL (RTYPE (litTree)))
3029 litTree->right = newNode ('+', tree->right, litTree->right);
3030 litTree->right->lineno = tree->lineno;
3032 tree->right->opval.val = constVal ("0");
3037 ast *tTree = litTree->right;
3038 litTree->right = tree->right;
3039 tree->right = tTree;
3042 decorateType (litParent);
3047 /*------------------------------------------------------------------*/
3048 /*----------------------------*/
3050 /*----------------------------*/
3052 /* can be only integral type */
3053 if (!IS_INTEGRAL (LTYPE (tree)))
3055 werror (E_UNARY_OP, tree->opval.op);
3056 goto errorTreeReturn;
3059 /* if left is a literal then do it */
3060 if (IS_LITERAL (LTYPE (tree)))
3062 tree->type = EX_VALUE;
3063 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3065 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3069 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3072 /*------------------------------------------------------------------*/
3073 /*----------------------------*/
3075 /*----------------------------*/
3077 /* can be pointer */
3078 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3079 !IS_PTR (LTYPE (tree)) &&
3080 !IS_ARRAY (LTYPE (tree)))
3082 werror (E_UNARY_OP, tree->opval.op);
3083 goto errorTreeReturn;
3086 /* if left is a literal then do it */
3087 if (IS_LITERAL (LTYPE (tree)))
3089 tree->type = EX_VALUE;
3090 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3092 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3096 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3099 /*------------------------------------------------------------------*/
3100 /*----------------------------*/
3102 /*----------------------------*/
3106 TTYPE (tree) = LTYPE (tree);
3107 TETYPE (tree) = LETYPE (tree);
3111 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3116 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3118 werror (E_SHIFT_OP_INVALID);
3119 werror (W_CONTINUE, "left & right types are ");
3120 printTypeChain (LTYPE (tree), stderr);
3121 fprintf (stderr, ",");
3122 printTypeChain (RTYPE (tree), stderr);
3123 fprintf (stderr, "\n");
3124 goto errorTreeReturn;
3127 /* if they are both literal then */
3128 /* rewrite the tree */
3129 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3131 tree->type = EX_VALUE;
3132 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3133 valFromType (RETYPE (tree)),
3134 (tree->opval.op == LEFT_OP ? 1 : 0));
3135 tree->right = tree->left = NULL;
3136 TETYPE (tree) = getSpec (TTYPE (tree) =
3137 tree->opval.val->type);
3141 /* if only the right side is a literal & we are
3142 shifting more than size of the left operand then zero */
3143 if (IS_LITERAL (RTYPE (tree)) &&
3144 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3145 (getSize (LTYPE (tree)) * 8))
3147 if (tree->opval.op==LEFT_OP ||
3148 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3149 lineno=tree->lineno;
3150 werror (W_SHIFT_CHANGED,
3151 (tree->opval.op == LEFT_OP ? "left" : "right"));
3152 tree->type = EX_VALUE;
3153 tree->left = tree->right = NULL;
3154 tree->opval.val = constVal ("0");
3155 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3159 LRVAL (tree) = RRVAL (tree) = 1;
3160 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3161 if (IS_LITERAL (TTYPE (tree)))
3162 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3165 /*------------------------------------------------------------------*/
3166 /*----------------------------*/
3168 /*----------------------------*/
3169 case CAST: /* change the type */
3170 /* cannot cast to an aggregate type */
3171 if (IS_AGGREGATE (LTYPE (tree)))
3173 werror (E_CAST_ILLEGAL);
3174 goto errorTreeReturn;
3177 /* make sure the type is complete and sane */
3178 checkTypeSanity(LETYPE(tree), "(cast)");
3181 /* if the right is a literal replace the tree */
3182 if (IS_LITERAL (RETYPE (tree))) {
3183 if (!IS_PTR (LTYPE (tree))) {
3184 tree->type = EX_VALUE;
3186 valCastLiteral (LTYPE (tree),
3187 floatFromVal (valFromType (RETYPE (tree))));
3190 TTYPE (tree) = tree->opval.val->type;
3191 tree->values.literalFromCast = 1;
3192 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3193 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3194 sym_link *rest = LTYPE(tree)->next;
3195 werror(W_LITERAL_GENERIC);
3196 TTYPE(tree) = newLink(DECLARATOR);
3197 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3198 TTYPE(tree)->next = rest;
3199 tree->left->opval.lnk = TTYPE(tree);
3202 TTYPE (tree) = LTYPE (tree);
3206 TTYPE (tree) = LTYPE (tree);
3210 #if 0 // this is already checked, now this could be explicit
3211 /* if pointer to struct then check names */
3212 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3213 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3214 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3216 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3217 SPEC_STRUCT(LETYPE(tree))->tag);
3220 if (IS_ADDRESS_OF_OP(tree->right)
3221 && IS_AST_SYM_VALUE (tree->right->left)
3222 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3224 tree->type = EX_VALUE;
3226 valCastLiteral (LTYPE (tree),
3227 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3228 TTYPE (tree) = tree->opval.val->type;
3229 TETYPE (tree) = getSpec (TTYPE (tree));
3232 tree->values.literalFromCast = 1;
3236 /* handle offsetof macro: */
3237 /* #define offsetof(TYPE, MEMBER) \ */
3238 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3239 if (IS_ADDRESS_OF_OP(tree->right)
3240 && IS_AST_OP (tree->right->left)
3241 && tree->right->left->opval.op == PTR_OP
3242 && IS_AST_OP (tree->right->left->left)
3243 && tree->right->left->left->opval.op == CAST
3244 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3246 symbol *element = getStructElement (
3247 SPEC_STRUCT (LETYPE(tree->right->left)),
3248 AST_SYMBOL(tree->right->left->right)
3252 tree->type = EX_VALUE;
3253 tree->opval.val = valCastLiteral (
3256 + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
3259 TTYPE (tree) = tree->opval.val->type;
3260 TETYPE (tree) = getSpec (TTYPE (tree));
3267 /* if the right is a literal replace the tree */
3268 if (IS_LITERAL (RETYPE (tree))) {
3269 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3270 /* rewrite (type *)litaddr
3272 and define type at litaddr temp
3273 (but only if type's storage class is not generic)
3275 ast *newTree = newNode ('&', NULL, NULL);
3278 TTYPE (newTree) = LTYPE (tree);
3279 TETYPE (newTree) = getSpec(LTYPE (tree));
3281 /* define a global symbol at the casted address*/
3282 sym = newSymbol(genSymName (0), 0);
3283 sym->type = LTYPE (tree)->next;
3285 sym->type = newLink (V_VOID);
3286 sym->etype = getSpec(sym->type);
3287 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3288 sym->lineDef = tree->lineno;
3291 SPEC_STAT (sym->etype) = 1;
3292 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
3293 SPEC_ABSA(sym->etype) = 1;
3294 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3297 newTree->left = newAst_VALUE(symbolVal(sym));
3298 newTree->left->lineno = tree->lineno;
3299 LTYPE (newTree) = sym->type;
3300 LETYPE (newTree) = sym->etype;
3301 LLVAL (newTree) = 1;
3302 LRVAL (newTree) = 0;
3303 TLVAL (newTree) = 1;
3306 if (!IS_PTR (LTYPE (tree))) {
3307 tree->type = EX_VALUE;
3309 valCastLiteral (LTYPE (tree),
3310 floatFromVal (valFromType (RETYPE (tree))));
3311 TTYPE (tree) = tree->opval.val->type;
3314 tree->values.literalFromCast = 1;
3315 TETYPE (tree) = getSpec (TTYPE (tree));
3319 TTYPE (tree) = LTYPE (tree);
3323 TETYPE (tree) = getSpec (TTYPE (tree));
3327 /*------------------------------------------------------------------*/
3328 /*----------------------------*/
3329 /* logical &&, || */
3330 /*----------------------------*/
3333 /* each must me arithmetic type or be a pointer */
3334 if (!IS_PTR (LTYPE (tree)) &&
3335 !IS_ARRAY (LTYPE (tree)) &&
3336 !IS_INTEGRAL (LTYPE (tree)))
3338 werror (E_COMPARE_OP);
3339 goto errorTreeReturn;
3342 if (!IS_PTR (RTYPE (tree)) &&
3343 !IS_ARRAY (RTYPE (tree)) &&
3344 !IS_INTEGRAL (RTYPE (tree)))
3346 werror (E_COMPARE_OP);
3347 goto errorTreeReturn;
3349 /* if they are both literal then */
3350 /* rewrite the tree */
3351 if (IS_LITERAL (RTYPE (tree)) &&
3352 IS_LITERAL (LTYPE (tree)))
3354 tree->type = EX_VALUE;
3355 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
3356 valFromType (RETYPE (tree)),
3358 tree->right = tree->left = NULL;
3359 TETYPE (tree) = getSpec (TTYPE (tree) =
3360 tree->opval.val->type);
3363 LRVAL (tree) = RRVAL (tree) = 1;
3364 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3367 /*------------------------------------------------------------------*/
3368 /*----------------------------*/
3369 /* comparison operators */
3370 /*----------------------------*/
3378 ast *lt = optimizeCompare (tree);
3384 /* if they are pointers they must be castable */
3385 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3387 if (tree->opval.op==EQ_OP &&
3388 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3389 // we cannot cast a gptr to a !gptr: switch the leaves
3390 struct ast *s=tree->left;
3391 tree->left=tree->right;
3394 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3396 werror (E_COMPARE_OP);
3397 fprintf (stderr, "comparring type ");
3398 printTypeChain (LTYPE (tree), stderr);
3399 fprintf (stderr, "to type ");
3400 printTypeChain (RTYPE (tree), stderr);
3401 fprintf (stderr, "\n");
3402 goto errorTreeReturn;
3405 /* else they should be promotable to one another */
3408 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3409 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3411 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3413 werror (E_COMPARE_OP);
3414 fprintf (stderr, "comparing type ");
3415 printTypeChain (LTYPE (tree), stderr);
3416 fprintf (stderr, "to type ");
3417 printTypeChain (RTYPE (tree), stderr);
3418 fprintf (stderr, "\n");
3419 goto errorTreeReturn;
3422 /* if unsigned value < 0 then always false */
3423 /* if (unsigned value) > 0 then (unsigned value) */
3424 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3425 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3427 if (tree->opval.op == '<') {
3430 if (tree->opval.op == '>') {
3434 /* if they are both literal then */
3435 /* rewrite the tree */
3436 if (IS_LITERAL (RTYPE (tree)) &&
3437 IS_LITERAL (LTYPE (tree)))
3439 tree->type = EX_VALUE;
3440 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3441 valFromType (RETYPE (tree)),
3443 tree->right = tree->left = NULL;
3444 TETYPE (tree) = getSpec (TTYPE (tree) =
3445 tree->opval.val->type);
3448 LRVAL (tree) = RRVAL (tree) = 1;
3449 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3452 /*------------------------------------------------------------------*/
3453 /*----------------------------*/
3455 /*----------------------------*/
3456 case SIZEOF: /* evaluate wihout code generation */
3457 /* change the type to a integer */
3458 tree->type = EX_VALUE;
3459 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3460 tree->opval.val = constVal (buffer);
3461 tree->right = tree->left = NULL;
3462 TETYPE (tree) = getSpec (TTYPE (tree) =
3463 tree->opval.val->type);
3466 /*------------------------------------------------------------------*/
3467 /*----------------------------*/
3469 /*----------------------------*/
3471 /* return typeof enum value */
3472 tree->type = EX_VALUE;
3475 if (IS_SPEC(tree->right->ftype)) {
3476 switch (SPEC_NOUN(tree->right->ftype)) {
3478 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3479 else typeofv = TYPEOF_INT;
3482 typeofv = TYPEOF_FLOAT;
3485 typeofv = TYPEOF_CHAR;
3488 typeofv = TYPEOF_VOID;
3491 typeofv = TYPEOF_STRUCT;
3494 typeofv = TYPEOF_BITFIELD;
3497 typeofv = TYPEOF_BIT;
3500 typeofv = TYPEOF_SBIT;
3506 switch (DCL_TYPE(tree->right->ftype)) {
3508 typeofv = TYPEOF_POINTER;
3511 typeofv = TYPEOF_FPOINTER;
3514 typeofv = TYPEOF_CPOINTER;
3517 typeofv = TYPEOF_GPOINTER;
3520 typeofv = TYPEOF_PPOINTER;
3523 typeofv = TYPEOF_IPOINTER;
3526 typeofv = TYPEOF_ARRAY;
3529 typeofv = TYPEOF_FUNCTION;
3535 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3536 tree->opval.val = constVal (buffer);
3537 tree->right = tree->left = NULL;
3538 TETYPE (tree) = getSpec (TTYPE (tree) =
3539 tree->opval.val->type);
3542 /*------------------------------------------------------------------*/
3543 /*----------------------------*/
3544 /* conditional operator '?' */
3545 /*----------------------------*/
3547 /* the type is value of the colon operator (on the right) */
3548 assert(IS_COLON_OP(tree->right));
3549 /* if already known then replace the tree : optimizer will do it
3550 but faster to do it here */
3551 if (IS_LITERAL (LTYPE(tree))) {
3552 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3553 return decorateType(tree->right->left) ;
3555 return decorateType(tree->right->right) ;
3558 tree->right = decorateType(tree->right);
3559 TTYPE (tree) = RTYPE(tree);
3560 TETYPE (tree) = getSpec (TTYPE (tree));
3565 /* if they don't match we have a problem */
3566 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3568 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3569 goto errorTreeReturn;
3572 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3573 TETYPE (tree) = getSpec (TTYPE (tree));
3577 #if 0 // assignment operators are converted by the parser
3578 /*------------------------------------------------------------------*/
3579 /*----------------------------*/
3580 /* assignment operators */
3581 /*----------------------------*/
3584 /* for these it must be both must be integral */
3585 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3586 !IS_ARITHMETIC (RTYPE (tree)))
3588 werror (E_OPS_INTEGRAL);
3589 goto errorTreeReturn;
3592 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3594 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3595 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3599 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3600 goto errorTreeReturn;
3611 /* for these it must be both must be integral */
3612 if (!IS_INTEGRAL (LTYPE (tree)) ||
3613 !IS_INTEGRAL (RTYPE (tree)))
3615 werror (E_OPS_INTEGRAL);
3616 goto errorTreeReturn;
3619 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3621 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3622 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3626 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3627 goto errorTreeReturn;
3633 /*------------------------------------------------------------------*/
3634 /*----------------------------*/
3636 /*----------------------------*/
3638 if (!(IS_PTR (LTYPE (tree)) ||
3639 IS_ARITHMETIC (LTYPE (tree))))
3641 werror (E_PLUS_INVALID, "-=");
3642 goto errorTreeReturn;
3645 if (!(IS_PTR (RTYPE (tree)) ||
3646 IS_ARITHMETIC (RTYPE (tree))))
3648 werror (E_PLUS_INVALID, "-=");
3649 goto errorTreeReturn;
3652 TETYPE (tree) = getSpec (TTYPE (tree) =
3653 computeType (LTYPE (tree),
3656 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3657 werror (E_CODE_WRITE, "-=");
3661 werror (E_LVALUE_REQUIRED, "-=");
3662 goto errorTreeReturn;
3668 /*------------------------------------------------------------------*/
3669 /*----------------------------*/
3671 /*----------------------------*/
3673 /* this is not a unary operation */
3674 /* if both pointers then problem */
3675 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3677 werror (E_PTR_PLUS_PTR);
3678 goto errorTreeReturn;
3681 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3683 werror (E_PLUS_INVALID, "+=");
3684 goto errorTreeReturn;
3687 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3689 werror (E_PLUS_INVALID, "+=");
3690 goto errorTreeReturn;
3693 TETYPE (tree) = getSpec (TTYPE (tree) =
3694 computeType (LTYPE (tree),
3697 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3698 werror (E_CODE_WRITE, "+=");
3702 werror (E_LVALUE_REQUIRED, "+=");
3703 goto errorTreeReturn;
3706 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3707 tree->opval.op = '=';
3712 /*------------------------------------------------------------------*/
3713 /*----------------------------*/
3714 /* straight assignemnt */
3715 /*----------------------------*/
3717 /* cannot be an aggregate */
3718 if (IS_AGGREGATE (LTYPE (tree)))
3720 werror (E_AGGR_ASSIGN);
3721 goto errorTreeReturn;
3724 /* they should either match or be castable */
3725 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3727 werror (E_TYPE_MISMATCH, "assignment", " ");
3728 printFromToType(RTYPE(tree),LTYPE(tree));
3731 /* if the left side of the tree is of type void
3732 then report error */
3733 if (IS_VOID (LTYPE (tree)))
3735 werror (E_CAST_ZERO);
3736 printFromToType(RTYPE(tree), LTYPE(tree));
3739 TETYPE (tree) = getSpec (TTYPE (tree) =
3743 if (!tree->initMode ) {
3744 if (IS_CONSTANT(LTYPE(tree)))
3745 werror (E_CODE_WRITE, "=");
3749 werror (E_LVALUE_REQUIRED, "=");
3750 goto errorTreeReturn;
3755 /*------------------------------------------------------------------*/
3756 /*----------------------------*/
3757 /* comma operator */
3758 /*----------------------------*/
3760 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3763 /*------------------------------------------------------------------*/
3764 /*----------------------------*/
3766 /*----------------------------*/
3770 if (processParms (tree->left,
3771 FUNC_ARGS(tree->left->ftype),
3772 tree->right, &parmNumber, TRUE)) {
3773 goto errorTreeReturn;
3776 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3777 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3779 reverseParms (tree->right);
3782 if (IS_CODEPTR(LTYPE(tree))) {
3783 TTYPE(tree) = LTYPE(tree)->next->next;
3785 TTYPE(tree) = LTYPE(tree)->next;
3787 TETYPE (tree) = getSpec (TTYPE (tree));
3790 /*------------------------------------------------------------------*/
3791 /*----------------------------*/
3792 /* return statement */
3793 /*----------------------------*/
3798 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3800 werror (W_RETURN_MISMATCH);
3801 printFromToType (RTYPE(tree), currFunc->type->next);
3802 goto errorTreeReturn;
3805 if (IS_VOID (currFunc->type->next)
3807 !IS_VOID (RTYPE (tree)))
3809 werror (E_FUNC_VOID);
3810 goto errorTreeReturn;
3813 /* if there is going to be a casing required then add it */
3814 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3817 decorateType (newNode (CAST,
3818 newAst_LINK (copyLinkChain (currFunc->type->next)),
3827 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3829 werror (W_VOID_FUNC, currFunc->name);
3830 goto errorTreeReturn;
3833 TTYPE (tree) = TETYPE (tree) = NULL;
3836 /*------------------------------------------------------------------*/
3837 /*----------------------------*/
3838 /* switch statement */
3839 /*----------------------------*/
3841 /* the switch value must be an integer */
3842 if (!IS_INTEGRAL (LTYPE (tree)))
3844 werror (E_SWITCH_NON_INTEGER);
3845 goto errorTreeReturn;
3848 TTYPE (tree) = TETYPE (tree) = NULL;
3851 /*------------------------------------------------------------------*/
3852 /*----------------------------*/
3854 /*----------------------------*/
3856 tree->left = backPatchLabels (tree->left,
3859 TTYPE (tree) = TETYPE (tree) = NULL;
3862 /*------------------------------------------------------------------*/
3863 /*----------------------------*/
3865 /*----------------------------*/
3868 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3869 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3870 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3872 /* if the for loop is reversible then
3873 reverse it otherwise do what we normally
3879 if (isLoopReversible (tree, &sym, &init, &end))
3880 return reverseLoop (tree, sym, init, end);
3882 return decorateType (createFor (AST_FOR (tree, trueLabel),
3883 AST_FOR (tree, continueLabel),
3884 AST_FOR (tree, falseLabel),
3885 AST_FOR (tree, condLabel),
3886 AST_FOR (tree, initExpr),
3887 AST_FOR (tree, condExpr),
3888 AST_FOR (tree, loopExpr),
3892 TTYPE (tree) = TETYPE (tree) = NULL;
3896 /* some error found this tree will be killed */
3898 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3899 tree->opval.op = NULLOP;
3905 /*-----------------------------------------------------------------*/
3906 /* sizeofOp - processes size of operation */
3907 /*-----------------------------------------------------------------*/
3909 sizeofOp (sym_link * type)
3913 /* make sure the type is complete and sane */
3914 checkTypeSanity(type, "(sizeof)");
3916 /* get the size and convert it to character */
3917 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3919 /* now convert into value */
3920 return constVal (buff);
3924 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3925 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3926 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3927 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3928 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3929 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3930 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3932 /*-----------------------------------------------------------------*/
3933 /* backPatchLabels - change and or not operators to flow control */
3934 /*-----------------------------------------------------------------*/
3936 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3942 if (!(IS_ANDORNOT (tree)))
3945 /* if this an and */
3948 static int localLbl = 0;
3951 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3952 localLabel = newSymbol (buffer, NestLevel);
3954 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3956 /* if left is already a IFX then just change the if true label in that */
3957 if (!IS_IFX (tree->left))
3958 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3960 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3961 /* right is a IFX then just join */
3962 if (IS_IFX (tree->right))
3963 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3965 tree->right = createLabel (localLabel, tree->right);
3966 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3968 return newNode (NULLOP, tree->left, tree->right);
3971 /* if this is an or operation */
3974 static int localLbl = 0;
3977 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3978 localLabel = newSymbol (buffer, NestLevel);
3980 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3982 /* if left is already a IFX then just change the if true label in that */
3983 if (!IS_IFX (tree->left))
3984 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3986 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3987 /* right is a IFX then just join */
3988 if (IS_IFX (tree->right))
3989 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3991 tree->right = createLabel (localLabel, tree->right);
3992 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3994 return newNode (NULLOP, tree->left, tree->right);
4000 int wasnot = IS_NOT (tree->left);
4001 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4003 /* if the left is already a IFX */
4004 if (!IS_IFX (tree->left))
4005 tree->left = newNode (IFX, tree->left, NULL);
4009 tree->left->trueLabel = trueLabel;
4010 tree->left->falseLabel = falseLabel;
4014 tree->left->trueLabel = falseLabel;
4015 tree->left->falseLabel = trueLabel;
4022 tree->trueLabel = trueLabel;
4023 tree->falseLabel = falseLabel;
4030 /*-----------------------------------------------------------------*/
4031 /* createBlock - create expression tree for block */
4032 /*-----------------------------------------------------------------*/
4034 createBlock (symbol * decl, ast * body)
4038 /* if the block has nothing */
4042 ex = newNode (BLOCK, NULL, body);
4043 ex->values.sym = decl;
4045 ex->right = ex->right;
4051 /*-----------------------------------------------------------------*/
4052 /* createLabel - creates the expression tree for labels */
4053 /*-----------------------------------------------------------------*/
4055 createLabel (symbol * label, ast * stmnt)
4058 char name[SDCC_NAME_MAX + 1];
4061 /* must create fresh symbol if the symbol name */
4062 /* exists in the symbol table, since there can */
4063 /* be a variable with the same name as the labl */
4064 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4065 (csym->level == label->level))
4066 label = newSymbol (label->name, label->level);
4068 /* change the name before putting it in add _ */
4069 SNPRINTF(name, sizeof(name), "%s", label->name);
4071 /* put the label in the LabelSymbol table */
4072 /* but first check if a label of the same */
4074 if ((csym = findSym (LabelTab, NULL, name)))
4075 werror (E_DUPLICATE_LABEL, label->name);
4077 addSym (LabelTab, label, name, label->level, 0, 0);
4080 label->key = labelKey++;
4081 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4087 /*-----------------------------------------------------------------*/
4088 /* createCase - generates the parsetree for a case statement */
4089 /*-----------------------------------------------------------------*/
4091 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4093 char caseLbl[SDCC_NAME_MAX + 1];
4097 /* if the switch statement does not exist */
4098 /* then case is out of context */
4101 werror (E_CASE_CONTEXT);
4105 caseVal = decorateType (resolveSymbols (caseVal));
4106 /* if not a constant then error */
4107 if (!IS_LITERAL (caseVal->ftype))
4109 werror (E_CASE_CONSTANT);
4113 /* if not a integer than error */
4114 if (!IS_INTEGRAL (caseVal->ftype))
4116 werror (E_CASE_NON_INTEGER);
4120 /* find the end of the switch values chain */
4121 if (!(val = swStat->values.switchVals.swVals))
4122 swStat->values.switchVals.swVals = caseVal->opval.val;
4125 /* also order the cases according to value */
4127 int cVal = (int) floatFromVal (caseVal->opval.val);
4128 while (val && (int) floatFromVal (val) < cVal)
4134 /* if we reached the end then */
4137 pval->next = caseVal->opval.val;
4141 /* we found a value greater than */
4142 /* the current value we must add this */
4143 /* before the value */
4144 caseVal->opval.val->next = val;
4146 /* if this was the first in chain */
4147 if (swStat->values.switchVals.swVals == val)
4148 swStat->values.switchVals.swVals =
4151 pval->next = caseVal->opval.val;
4156 /* create the case label */
4157 SNPRINTF(caseLbl, sizeof(caseLbl),
4159 swStat->values.switchVals.swNum,
4160 (int) floatFromVal (caseVal->opval.val));
4162 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4167 /*-----------------------------------------------------------------*/
4168 /* createDefault - creates the parse tree for the default statement */
4169 /*-----------------------------------------------------------------*/
4171 createDefault (ast * swStat, ast * stmnt)
4173 char defLbl[SDCC_NAME_MAX + 1];
4175 /* if the switch statement does not exist */
4176 /* then case is out of context */
4179 werror (E_CASE_CONTEXT);
4183 /* turn on the default flag */
4184 swStat->values.switchVals.swDefault = 1;
4186 /* create the label */
4187 SNPRINTF (defLbl, sizeof(defLbl),
4188 "_default_%d", swStat->values.switchVals.swNum);
4189 return createLabel (newSymbol (defLbl, 0), stmnt);
4192 /*-----------------------------------------------------------------*/
4193 /* createIf - creates the parsetree for the if statement */
4194 /*-----------------------------------------------------------------*/
4196 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4198 static int Lblnum = 0;
4200 symbol *ifTrue, *ifFalse, *ifEnd;
4202 /* if neither exists */
4203 if (!elseBody && !ifBody) {
4204 // if there are no side effects (i++, j() etc)
4205 if (!hasSEFcalls(condAst)) {
4210 /* create the labels */
4211 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4212 ifFalse = newSymbol (buffer, NestLevel);
4213 /* if no else body then end == false */
4218 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4219 ifEnd = newSymbol (buffer, NestLevel);
4222 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4223 ifTrue = newSymbol (buffer, NestLevel);
4227 /* attach the ifTrue label to the top of it body */
4228 ifBody = createLabel (ifTrue, ifBody);
4229 /* attach a goto end to the ifBody if else is present */
4232 ifBody = newNode (NULLOP, ifBody,
4234 newAst_VALUE (symbolVal (ifEnd)),
4236 /* put the elseLabel on the else body */
4237 elseBody = createLabel (ifFalse, elseBody);
4238 /* out the end at the end of the body */
4239 elseBody = newNode (NULLOP,
4241 createLabel (ifEnd, NULL));
4245 ifBody = newNode (NULLOP, ifBody,
4246 createLabel (ifFalse, NULL));
4248 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4249 if (IS_IFX (condAst))
4252 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4254 return newNode (NULLOP, ifTree,
4255 newNode (NULLOP, ifBody, elseBody));
4259 /*-----------------------------------------------------------------*/
4260 /* createDo - creates parse tree for do */
4263 /* _docontinue_n: */
4264 /* condition_expression +-> trueLabel -> _dobody_n */
4266 /* +-> falseLabel-> _dobreak_n */
4268 /*-----------------------------------------------------------------*/
4270 createDo (symbol * trueLabel, symbol * continueLabel,
4271 symbol * falseLabel, ast * condAst, ast * doBody)
4276 /* if the body does not exist then it is simple */
4279 condAst = backPatchLabels (condAst, continueLabel, NULL);
4280 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4281 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4282 doTree->trueLabel = continueLabel;
4283 doTree->falseLabel = NULL;
4287 /* otherwise we have a body */
4288 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4290 /* attach the body label to the top */
4291 doBody = createLabel (trueLabel, doBody);
4292 /* attach the continue label to end of body */
4293 doBody = newNode (NULLOP, doBody,
4294 createLabel (continueLabel, NULL));
4296 /* now put the break label at the end */
4297 if (IS_IFX (condAst))
4300 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4302 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4304 /* putting it together */
4305 return newNode (NULLOP, doBody, doTree);
4308 /*-----------------------------------------------------------------*/
4309 /* createFor - creates parse tree for 'for' statement */
4312 /* condExpr +-> trueLabel -> _forbody_n */
4314 /* +-> falseLabel-> _forbreak_n */
4317 /* _forcontinue_n: */
4319 /* goto _forcond_n ; */
4321 /*-----------------------------------------------------------------*/
4323 createFor (symbol * trueLabel, symbol * continueLabel,
4324 symbol * falseLabel, symbol * condLabel,
4325 ast * initExpr, ast * condExpr, ast * loopExpr,
4330 /* if loopexpression not present then we can generate it */
4331 /* the same way as a while */
4333 return newNode (NULLOP, initExpr,
4334 createWhile (trueLabel, continueLabel,
4335 falseLabel, condExpr, forBody));
4336 /* vanilla for statement */
4337 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4339 if (condExpr && !IS_IFX (condExpr))
4340 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4343 /* attach condition label to condition */
4344 condExpr = createLabel (condLabel, condExpr);
4346 /* attach body label to body */
4347 forBody = createLabel (trueLabel, forBody);
4349 /* attach continue to forLoop expression & attach */
4350 /* goto the forcond @ and of loopExpression */
4351 loopExpr = createLabel (continueLabel,
4355 newAst_VALUE (symbolVal (condLabel)),
4357 /* now start putting them together */
4358 forTree = newNode (NULLOP, initExpr, condExpr);
4359 forTree = newNode (NULLOP, forTree, forBody);
4360 forTree = newNode (NULLOP, forTree, loopExpr);
4361 /* finally add the break label */
4362 forTree = newNode (NULLOP, forTree,
4363 createLabel (falseLabel, NULL));
4367 /*-----------------------------------------------------------------*/
4368 /* createWhile - creates parse tree for while statement */
4369 /* the while statement will be created as follows */
4371 /* _while_continue_n: */
4372 /* condition_expression +-> trueLabel -> _while_boby_n */
4374 /* +-> falseLabel -> _while_break_n */
4375 /* _while_body_n: */
4377 /* goto _while_continue_n */
4378 /* _while_break_n: */
4379 /*-----------------------------------------------------------------*/
4381 createWhile (symbol * trueLabel, symbol * continueLabel,
4382 symbol * falseLabel, ast * condExpr, ast * whileBody)
4386 /* put the continue label */
4387 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4388 condExpr = createLabel (continueLabel, condExpr);
4389 condExpr->lineno = 0;
4391 /* put the body label in front of the body */
4392 whileBody = createLabel (trueLabel, whileBody);
4393 whileBody->lineno = 0;
4394 /* put a jump to continue at the end of the body */
4395 /* and put break label at the end of the body */
4396 whileBody = newNode (NULLOP,
4399 newAst_VALUE (symbolVal (continueLabel)),
4400 createLabel (falseLabel, NULL)));
4402 /* put it all together */
4403 if (IS_IFX (condExpr))
4404 whileTree = condExpr;
4407 whileTree = newNode (IFX, condExpr, NULL);
4408 /* put the true & false labels in place */
4409 whileTree->trueLabel = trueLabel;
4410 whileTree->falseLabel = falseLabel;
4413 return newNode (NULLOP, whileTree, whileBody);
4416 /*-----------------------------------------------------------------*/
4417 /* optimizeGetHbit - get highest order bit of the expression */
4418 /*-----------------------------------------------------------------*/
4420 optimizeGetHbit (ast * tree)
4423 /* if this is not a bit and */
4424 if (!IS_BITAND (tree))
4427 /* will look for tree of the form
4428 ( expr >> ((sizeof expr) -1) ) & 1 */
4429 if (!IS_AST_LIT_VALUE (tree->right))
4432 if (AST_LIT_VALUE (tree->right) != 1)
4435 if (!IS_RIGHT_OP (tree->left))
4438 if (!IS_AST_LIT_VALUE (tree->left->right))
4441 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4442 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4445 /* make sure the port supports GETHBIT */
4446 if (port->hasExtBitOp
4447 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4450 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4454 /*-----------------------------------------------------------------*/
4455 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4456 /*-----------------------------------------------------------------*/
4458 optimizeRRCRLC (ast * root)
4460 /* will look for trees of the form
4461 (?expr << 1) | (?expr >> 7) or
4462 (?expr >> 7) | (?expr << 1) will make that
4463 into a RLC : operation ..
4465 (?expr >> 1) | (?expr << 7) or
4466 (?expr << 7) | (?expr >> 1) will make that
4467 into a RRC operation
4468 note : by 7 I mean (number of bits required to hold the
4470 /* if the root operations is not a | operation the not */
4471 if (!IS_BITOR (root))
4474 /* I have to think of a better way to match patterns this sucks */
4475 /* that aside let start looking for the first case : I use a the
4476 negative check a lot to improve the efficiency */
4477 /* (?expr << 1) | (?expr >> 7) */
4478 if (IS_LEFT_OP (root->left) &&
4479 IS_RIGHT_OP (root->right))
4482 if (!SPEC_USIGN (TETYPE (root->left->left)))
4485 if (!IS_AST_LIT_VALUE (root->left->right) ||
4486 !IS_AST_LIT_VALUE (root->right->right))
4489 /* make sure it is the same expression */
4490 if (!isAstEqual (root->left->left,
4494 if (AST_LIT_VALUE (root->left->right) != 1)
4497 if (AST_LIT_VALUE (root->right->right) !=
4498 (getSize (TTYPE (root->left->left)) * 8 - 1))
4501 /* make sure the port supports RLC */
4502 if (port->hasExtBitOp
4503 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4506 /* whew got the first case : create the AST */
4507 return newNode (RLC, root->left->left, NULL);
4511 /* check for second case */
4512 /* (?expr >> 7) | (?expr << 1) */
4513 if (IS_LEFT_OP (root->right) &&
4514 IS_RIGHT_OP (root->left))
4517 if (!SPEC_USIGN (TETYPE (root->left->left)))
4520 if (!IS_AST_LIT_VALUE (root->left->right) ||
4521 !IS_AST_LIT_VALUE (root->right->right))
4524 /* make sure it is the same symbol */
4525 if (!isAstEqual (root->left->left,
4529 if (AST_LIT_VALUE (root->right->right) != 1)
4532 if (AST_LIT_VALUE (root->left->right) !=
4533 (getSize (TTYPE (root->left->left)) * 8 - 1))
4536 /* make sure the port supports RLC */
4537 if (port->hasExtBitOp
4538 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4541 /* whew got the first case : create the AST */
4542 return newNode (RLC, root->left->left, NULL);
4547 /* third case for RRC */
4548 /* (?symbol >> 1) | (?symbol << 7) */
4549 if (IS_LEFT_OP (root->right) &&
4550 IS_RIGHT_OP (root->left))
4553 if (!SPEC_USIGN (TETYPE (root->left->left)))
4556 if (!IS_AST_LIT_VALUE (root->left->right) ||
4557 !IS_AST_LIT_VALUE (root->right->right))
4560 /* make sure it is the same symbol */
4561 if (!isAstEqual (root->left->left,
4565 if (AST_LIT_VALUE (root->left->right) != 1)
4568 if (AST_LIT_VALUE (root->right->right) !=
4569 (getSize (TTYPE (root->left->left)) * 8 - 1))
4572 /* make sure the port supports RRC */
4573 if (port->hasExtBitOp
4574 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4577 /* whew got the first case : create the AST */
4578 return newNode (RRC, root->left->left, NULL);
4582 /* fourth and last case for now */
4583 /* (?symbol << 7) | (?symbol >> 1) */
4584 if (IS_RIGHT_OP (root->right) &&
4585 IS_LEFT_OP (root->left))
4588 if (!SPEC_USIGN (TETYPE (root->left->left)))
4591 if (!IS_AST_LIT_VALUE (root->left->right) ||
4592 !IS_AST_LIT_VALUE (root->right->right))
4595 /* make sure it is the same symbol */
4596 if (!isAstEqual (root->left->left,
4600 if (AST_LIT_VALUE (root->right->right) != 1)
4603 if (AST_LIT_VALUE (root->left->right) !=
4604 (getSize (TTYPE (root->left->left)) * 8 - 1))
4607 /* make sure the port supports RRC */
4608 if (port->hasExtBitOp
4609 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4612 /* whew got the first case : create the AST */
4613 return newNode (RRC, root->left->left, NULL);
4617 /* not found return root */
4621 /*-----------------------------------------------------------------*/
4622 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4623 /*-----------------------------------------------------------------*/
4625 optimizeSWAP (ast * root)
4627 /* will look for trees of the form
4628 (?expr << 4) | (?expr >> 4) or
4629 (?expr >> 4) | (?expr << 4) will make that
4630 into a SWAP : operation ..
4631 note : by 4 I mean (number of bits required to hold the
4633 /* if the root operations is not a | operation the not */
4634 if (!IS_BITOR (root))
4637 /* (?expr << 4) | (?expr >> 4) */
4638 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4639 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4642 if (!SPEC_USIGN (TETYPE (root->left->left)))
4645 if (!IS_AST_LIT_VALUE (root->left->right) ||
4646 !IS_AST_LIT_VALUE (root->right->right))
4649 /* make sure it is the same expression */
4650 if (!isAstEqual (root->left->left,
4654 if (AST_LIT_VALUE (root->left->right) !=
4655 (getSize (TTYPE (root->left->left)) * 4))
4658 if (AST_LIT_VALUE (root->right->right) !=
4659 (getSize (TTYPE (root->left->left)) * 4))
4662 /* make sure the port supports SWAP */
4663 if (port->hasExtBitOp
4664 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4667 /* found it : create the AST */
4668 return newNode (SWAP, root->left->left, NULL);
4672 /* not found return root */
4676 /*-----------------------------------------------------------------*/
4677 /* optimizeCompare - otimizes compares for bit variables */
4678 /*-----------------------------------------------------------------*/
4680 optimizeCompare (ast * root)
4682 ast *optExpr = NULL;
4685 unsigned int litValue;
4687 /* if nothing then return nothing */
4691 /* if not a compare op then do leaves */
4692 if (!IS_COMPARE_OP (root))
4694 root->left = optimizeCompare (root->left);
4695 root->right = optimizeCompare (root->right);
4699 /* if left & right are the same then depending
4700 of the operation do */
4701 if (isAstEqual (root->left, root->right))
4703 switch (root->opval.op)
4708 optExpr = newAst_VALUE (constVal ("0"));
4713 optExpr = newAst_VALUE (constVal ("1"));
4717 return decorateType (optExpr);
4720 vleft = (root->left->type == EX_VALUE ?
4721 root->left->opval.val : NULL);
4723 vright = (root->right->type == EX_VALUE ?
4724 root->right->opval.val : NULL);
4726 /* if left is a BITVAR in BITSPACE */
4727 /* and right is a LITERAL then opt- */
4728 /* imize else do nothing */
4729 if (vleft && vright &&
4730 IS_BITVAR (vleft->etype) &&
4731 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4732 IS_LITERAL (vright->etype))
4735 /* if right side > 1 then comparison may never succeed */
4736 if ((litValue = (int) floatFromVal (vright)) > 1)
4738 werror (W_BAD_COMPARE);
4744 switch (root->opval.op)
4746 case '>': /* bit value greater than 1 cannot be */
4747 werror (W_BAD_COMPARE);
4751 case '<': /* bit value < 1 means 0 */
4753 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4756 case LE_OP: /* bit value <= 1 means no check */
4757 optExpr = newAst_VALUE (vright);
4760 case GE_OP: /* bit value >= 1 means only check for = */
4762 optExpr = newAst_VALUE (vleft);
4767 { /* literal is zero */
4768 switch (root->opval.op)
4770 case '<': /* bit value < 0 cannot be */
4771 werror (W_BAD_COMPARE);
4775 case '>': /* bit value > 0 means 1 */
4777 optExpr = newAst_VALUE (vleft);
4780 case LE_OP: /* bit value <= 0 means no check */
4781 case GE_OP: /* bit value >= 0 means no check */
4782 werror (W_BAD_COMPARE);
4786 case EQ_OP: /* bit == 0 means ! of bit */
4787 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4791 return decorateType (resolveSymbols (optExpr));
4792 } /* end-of-if of BITVAR */
4797 /*-----------------------------------------------------------------*/
4798 /* addSymToBlock : adds the symbol to the first block we find */
4799 /*-----------------------------------------------------------------*/
4801 addSymToBlock (symbol * sym, ast * tree)
4803 /* reached end of tree or a leaf */
4804 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4808 if (IS_AST_OP (tree) &&
4809 tree->opval.op == BLOCK)
4812 symbol *lsym = copySymbol (sym);
4814 lsym->next = AST_VALUES (tree, sym);
4815 AST_VALUES (tree, sym) = lsym;
4819 addSymToBlock (sym, tree->left);
4820 addSymToBlock (sym, tree->right);
4823 /*-----------------------------------------------------------------*/
4824 /* processRegParms - do processing for register parameters */
4825 /*-----------------------------------------------------------------*/
4827 processRegParms (value * args, ast * body)
4831 if (IS_REGPARM (args->etype))
4832 addSymToBlock (args->sym, body);
4837 /*-----------------------------------------------------------------*/
4838 /* resetParmKey - resets the operandkeys for the symbols */
4839 /*-----------------------------------------------------------------*/
4840 DEFSETFUNC (resetParmKey)
4851 /*-----------------------------------------------------------------*/
4852 /* createFunction - This is the key node that calls the iCode for */
4853 /* generating the code for a function. Note code */
4854 /* is generated function by function, later when */
4855 /* add inter-procedural analysis this will change */
4856 /*-----------------------------------------------------------------*/
4858 createFunction (symbol * name, ast * body)
4864 iCode *piCode = NULL;
4866 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4867 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4869 /* if check function return 0 then some problem */
4870 if (checkFunction (name, NULL) == 0)
4873 /* create a dummy block if none exists */
4875 body = newNode (BLOCK, NULL, NULL);
4879 /* check if the function name already in the symbol table */
4880 if ((csym = findSym (SymbolTab, NULL, name->name)))
4883 /* special case for compiler defined functions
4884 we need to add the name to the publics list : this
4885 actually means we are now compiling the compiler
4889 addSet (&publics, name);
4895 allocVariables (name);
4897 name->lastLine = mylineno;
4900 /* set the stack pointer */
4901 /* PENDING: check this for the mcs51 */
4902 stackPtr = -port->stack.direction * port->stack.call_overhead;
4903 if (IFFUNC_ISISR (name->type))
4904 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4905 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4906 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4908 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4910 fetype = getSpec (name->type); /* get the specifier for the function */
4911 /* if this is a reentrant function then */
4912 if (IFFUNC_ISREENT (name->type))
4915 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4917 /* do processing for parameters that are passed in registers */
4918 processRegParms (FUNC_ARGS(name->type), body);
4920 /* set the stack pointer */
4924 /* allocate & autoinit the block variables */
4925 processBlockVars (body, &stack, ALLOCATE);
4927 /* save the stack information */
4928 if (options.useXstack)
4929 name->xstack = SPEC_STAK (fetype) = stack;
4931 name->stack = SPEC_STAK (fetype) = stack;
4933 /* name needs to be mangled */
4934 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4936 body = resolveSymbols (body); /* resolve the symbols */
4937 body = decorateType (body); /* propagateType & do semantic checks */
4939 ex = newAst_VALUE (symbolVal (name)); /* create name */
4940 ex = newNode (FUNCTION, ex, body);
4941 ex->values.args = FUNC_ARGS(name->type);
4943 if (options.dump_tree) PA(ex);
4946 werror (E_FUNC_NO_CODE, name->name);
4950 /* create the node & generate intermediate code */
4952 codeOutFile = code->oFile;
4953 piCode = iCodeFromAst (ex);
4957 werror (E_FUNC_NO_CODE, name->name);
4961 eBBlockFromiCode (piCode);
4963 /* if there are any statics then do them */
4966 GcurMemmap = statsg;
4967 codeOutFile = statsg->oFile;
4968 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4974 /* dealloc the block variables */
4975 processBlockVars (body, &stack, DEALLOCATE);
4976 outputDebugStackSymbols();
4977 /* deallocate paramaters */
4978 deallocParms (FUNC_ARGS(name->type));
4980 if (IFFUNC_ISREENT (name->type))
4983 /* we are done freeup memory & cleanup */
4985 if (port->reset_labelKey) labelKey = 1;
4987 FUNC_HASBODY(name->type) = 1;
4988 addSet (&operKeyReset, name);
4989 applyToSet (operKeyReset, resetParmKey);
4994 cleanUpLevel (LabelTab, 0);
4995 cleanUpBlock (StructTab, 1);
4996 cleanUpBlock (TypedefTab, 1);
4998 xstack->syms = NULL;
4999 istack->syms = NULL;
5004 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5005 /*-----------------------------------------------------------------*/
5006 /* ast_print : prints the ast (for debugging purposes) */
5007 /*-----------------------------------------------------------------*/
5009 void ast_print (ast * tree, FILE *outfile, int indent)
5014 /* can print only decorated trees */
5015 if (!tree->decorated) return;
5017 /* if any child is an error | this one is an error do nothing */
5018 if (tree->isError ||
5019 (tree->left && tree->left->isError) ||
5020 (tree->right && tree->right->isError)) {
5021 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5025 /* print the line */
5026 /* if not block & function */
5027 if (tree->type == EX_OP &&
5028 (tree->opval.op != FUNCTION &&
5029 tree->opval.op != BLOCK &&
5030 tree->opval.op != NULLOP)) {
5033 if (tree->opval.op == FUNCTION) {
5035 value *args=FUNC_ARGS(tree->left->opval.val->type);
5036 fprintf(outfile,"FUNCTION (%s=%p) type (",
5037 tree->left->opval.val->name, tree);
5038 printTypeChain (tree->left->opval.val->type->next,outfile);
5039 fprintf(outfile,") args (");
5042 fprintf (outfile, ", ");
5044 printTypeChain (args ? args->type : NULL, outfile);
5046 args= args ? args->next : NULL;
5048 fprintf(outfile,")\n");
5049 ast_print(tree->left,outfile,indent);
5050 ast_print(tree->right,outfile,indent);
5053 if (tree->opval.op == BLOCK) {
5054 symbol *decls = tree->values.sym;
5055 INDENT(indent,outfile);
5056 fprintf(outfile,"{\n");
5058 INDENT(indent+2,outfile);
5059 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5060 decls->name, decls);
5061 printTypeChain(decls->type,outfile);
5062 fprintf(outfile,")\n");
5064 decls = decls->next;
5066 ast_print(tree->right,outfile,indent+2);
5067 INDENT(indent,outfile);
5068 fprintf(outfile,"}\n");
5071 if (tree->opval.op == NULLOP) {
5072 ast_print(tree->left,outfile,indent);
5073 ast_print(tree->right,outfile,indent);
5076 INDENT(indent,outfile);
5078 /*------------------------------------------------------------------*/
5079 /*----------------------------*/
5080 /* leaf has been reached */
5081 /*----------------------------*/
5082 /* if this is of type value */
5083 /* just get the type */
5084 if (tree->type == EX_VALUE) {
5086 if (IS_LITERAL (tree->opval.val->etype)) {
5087 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5088 if (SPEC_USIGN (tree->opval.val->etype))
5089 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5091 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5092 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5093 floatFromVal(tree->opval.val));
5094 } else if (tree->opval.val->sym) {
5095 /* if the undefined flag is set then give error message */
5096 if (tree->opval.val->sym->undefined) {
5097 fprintf(outfile,"UNDEFINED SYMBOL ");
5099 fprintf(outfile,"SYMBOL ");
5101 fprintf(outfile,"(%s=%p)",
5102 tree->opval.val->sym->name,tree);
5105 fprintf(outfile," type (");
5106 printTypeChain(tree->ftype,outfile);
5107 fprintf(outfile,")\n");
5109 fprintf(outfile,"\n");
5114 /* if type link for the case of cast */
5115 if (tree->type == EX_LINK) {
5116 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5117 printTypeChain(tree->opval.lnk,outfile);
5118 fprintf(outfile,")\n");
5123 /* depending on type of operator do */
5125 switch (tree->opval.op) {
5126 /*------------------------------------------------------------------*/
5127 /*----------------------------*/
5129 /*----------------------------*/
5131 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5132 printTypeChain(tree->ftype,outfile);
5133 fprintf(outfile,")\n");
5134 ast_print(tree->left,outfile,indent+2);
5135 ast_print(tree->right,outfile,indent+2);
5138 /*------------------------------------------------------------------*/
5139 /*----------------------------*/
5141 /*----------------------------*/
5143 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5144 printTypeChain(tree->ftype,outfile);
5145 fprintf(outfile,")\n");
5146 ast_print(tree->left,outfile,indent+2);
5147 ast_print(tree->right,outfile,indent+2);
5150 /*------------------------------------------------------------------*/
5151 /*----------------------------*/
5152 /* struct/union pointer */
5153 /*----------------------------*/
5155 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5156 printTypeChain(tree->ftype,outfile);
5157 fprintf(outfile,")\n");
5158 ast_print(tree->left,outfile,indent+2);
5159 ast_print(tree->right,outfile,indent+2);
5162 /*------------------------------------------------------------------*/
5163 /*----------------------------*/
5164 /* ++/-- operation */
5165 /*----------------------------*/
5168 fprintf(outfile,"post-");
5170 fprintf(outfile,"pre-");
5171 fprintf(outfile,"INC_OP (%p) type (",tree);
5172 printTypeChain(tree->ftype,outfile);
5173 fprintf(outfile,")\n");
5174 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5175 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5180 fprintf(outfile,"post-");
5182 fprintf(outfile,"pre-");
5183 fprintf(outfile,"DEC_OP (%p) type (",tree);
5184 printTypeChain(tree->ftype,outfile);
5185 fprintf(outfile,")\n");
5186 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5187 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5190 /*------------------------------------------------------------------*/
5191 /*----------------------------*/
5193 /*----------------------------*/
5196 fprintf(outfile,"& (%p) type (",tree);
5197 printTypeChain(tree->ftype,outfile);
5198 fprintf(outfile,")\n");
5199 ast_print(tree->left,outfile,indent+2);
5200 ast_print(tree->right,outfile,indent+2);
5202 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5203 printTypeChain(tree->ftype,outfile);
5204 fprintf(outfile,")\n");
5205 ast_print(tree->left,outfile,indent+2);
5206 ast_print(tree->right,outfile,indent+2);
5209 /*----------------------------*/
5211 /*----------------------------*/
5213 fprintf(outfile,"OR (%p) type (",tree);
5214 printTypeChain(tree->ftype,outfile);
5215 fprintf(outfile,")\n");
5216 ast_print(tree->left,outfile,indent+2);
5217 ast_print(tree->right,outfile,indent+2);
5219 /*------------------------------------------------------------------*/
5220 /*----------------------------*/
5222 /*----------------------------*/
5224 fprintf(outfile,"XOR (%p) type (",tree);
5225 printTypeChain(tree->ftype,outfile);
5226 fprintf(outfile,")\n");
5227 ast_print(tree->left,outfile,indent+2);
5228 ast_print(tree->right,outfile,indent+2);
5231 /*------------------------------------------------------------------*/
5232 /*----------------------------*/
5234 /*----------------------------*/
5236 fprintf(outfile,"DIV (%p) type (",tree);
5237 printTypeChain(tree->ftype,outfile);
5238 fprintf(outfile,")\n");
5239 ast_print(tree->left,outfile,indent+2);
5240 ast_print(tree->right,outfile,indent+2);
5242 /*------------------------------------------------------------------*/
5243 /*----------------------------*/
5245 /*----------------------------*/
5247 fprintf(outfile,"MOD (%p) type (",tree);
5248 printTypeChain(tree->ftype,outfile);
5249 fprintf(outfile,")\n");
5250 ast_print(tree->left,outfile,indent+2);
5251 ast_print(tree->right,outfile,indent+2);
5254 /*------------------------------------------------------------------*/
5255 /*----------------------------*/
5256 /* address dereference */
5257 /*----------------------------*/
5258 case '*': /* can be unary : if right is null then unary operation */
5260 fprintf(outfile,"DEREF (%p) type (",tree);
5261 printTypeChain(tree->ftype,outfile);
5262 fprintf(outfile,")\n");
5263 ast_print(tree->left,outfile,indent+2);
5266 /*------------------------------------------------------------------*/
5267 /*----------------------------*/
5268 /* multiplication */
5269 /*----------------------------*/
5270 fprintf(outfile,"MULT (%p) type (",tree);
5271 printTypeChain(tree->ftype,outfile);
5272 fprintf(outfile,")\n");
5273 ast_print(tree->left,outfile,indent+2);
5274 ast_print(tree->right,outfile,indent+2);
5278 /*------------------------------------------------------------------*/
5279 /*----------------------------*/
5280 /* unary '+' operator */
5281 /*----------------------------*/
5285 fprintf(outfile,"UPLUS (%p) type (",tree);
5286 printTypeChain(tree->ftype,outfile);
5287 fprintf(outfile,")\n");
5288 ast_print(tree->left,outfile,indent+2);
5290 /*------------------------------------------------------------------*/
5291 /*----------------------------*/
5293 /*----------------------------*/
5294 fprintf(outfile,"ADD (%p) type (",tree);
5295 printTypeChain(tree->ftype,outfile);
5296 fprintf(outfile,")\n");
5297 ast_print(tree->left,outfile,indent+2);
5298 ast_print(tree->right,outfile,indent+2);
5301 /*------------------------------------------------------------------*/
5302 /*----------------------------*/
5304 /*----------------------------*/
5305 case '-': /* can be unary */
5307 fprintf(outfile,"UMINUS (%p) type (",tree);
5308 printTypeChain(tree->ftype,outfile);
5309 fprintf(outfile,")\n");
5310 ast_print(tree->left,outfile,indent+2);
5312 /*------------------------------------------------------------------*/
5313 /*----------------------------*/
5315 /*----------------------------*/
5316 fprintf(outfile,"SUB (%p) type (",tree);
5317 printTypeChain(tree->ftype,outfile);
5318 fprintf(outfile,")\n");
5319 ast_print(tree->left,outfile,indent+2);
5320 ast_print(tree->right,outfile,indent+2);
5323 /*------------------------------------------------------------------*/
5324 /*----------------------------*/
5326 /*----------------------------*/
5328 fprintf(outfile,"COMPL (%p) type (",tree);
5329 printTypeChain(tree->ftype,outfile);
5330 fprintf(outfile,")\n");
5331 ast_print(tree->left,outfile,indent+2);
5333 /*------------------------------------------------------------------*/
5334 /*----------------------------*/
5336 /*----------------------------*/
5338 fprintf(outfile,"NOT (%p) type (",tree);
5339 printTypeChain(tree->ftype,outfile);
5340 fprintf(outfile,")\n");
5341 ast_print(tree->left,outfile,indent+2);
5343 /*------------------------------------------------------------------*/
5344 /*----------------------------*/
5346 /*----------------------------*/
5348 fprintf(outfile,"RRC (%p) type (",tree);
5349 printTypeChain(tree->ftype,outfile);
5350 fprintf(outfile,")\n");
5351 ast_print(tree->left,outfile,indent+2);
5355 fprintf(outfile,"RLC (%p) type (",tree);
5356 printTypeChain(tree->ftype,outfile);
5357 fprintf(outfile,")\n");
5358 ast_print(tree->left,outfile,indent+2);
5361 fprintf(outfile,"SWAP (%p) type (",tree);
5362 printTypeChain(tree->ftype,outfile);
5363 fprintf(outfile,")\n");
5364 ast_print(tree->left,outfile,indent+2);
5367 fprintf(outfile,"GETHBIT (%p) type (",tree);
5368 printTypeChain(tree->ftype,outfile);
5369 fprintf(outfile,")\n");
5370 ast_print(tree->left,outfile,indent+2);
5373 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5374 printTypeChain(tree->ftype,outfile);
5375 fprintf(outfile,")\n");
5376 ast_print(tree->left,outfile,indent+2);
5377 ast_print(tree->right,outfile,indent+2);
5380 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5381 printTypeChain(tree->ftype,outfile);
5382 fprintf(outfile,")\n");
5383 ast_print(tree->left,outfile,indent+2);
5384 ast_print(tree->right,outfile,indent+2);
5386 /*------------------------------------------------------------------*/
5387 /*----------------------------*/
5389 /*----------------------------*/
5390 case CAST: /* change the type */
5391 fprintf(outfile,"CAST (%p) from type (",tree);
5392 printTypeChain(tree->right->ftype,outfile);
5393 fprintf(outfile,") to type (");
5394 printTypeChain(tree->ftype,outfile);
5395 fprintf(outfile,")\n");
5396 ast_print(tree->right,outfile,indent+2);
5400 fprintf(outfile,"ANDAND (%p) type (",tree);
5401 printTypeChain(tree->ftype,outfile);
5402 fprintf(outfile,")\n");
5403 ast_print(tree->left,outfile,indent+2);
5404 ast_print(tree->right,outfile,indent+2);
5407 fprintf(outfile,"OROR (%p) type (",tree);
5408 printTypeChain(tree->ftype,outfile);
5409 fprintf(outfile,")\n");
5410 ast_print(tree->left,outfile,indent+2);
5411 ast_print(tree->right,outfile,indent+2);
5414 /*------------------------------------------------------------------*/
5415 /*----------------------------*/
5416 /* comparison operators */
5417 /*----------------------------*/
5419 fprintf(outfile,"GT(>) (%p) type (",tree);
5420 printTypeChain(tree->ftype,outfile);
5421 fprintf(outfile,")\n");
5422 ast_print(tree->left,outfile,indent+2);
5423 ast_print(tree->right,outfile,indent+2);
5426 fprintf(outfile,"LT(<) (%p) type (",tree);
5427 printTypeChain(tree->ftype,outfile);
5428 fprintf(outfile,")\n");
5429 ast_print(tree->left,outfile,indent+2);
5430 ast_print(tree->right,outfile,indent+2);
5433 fprintf(outfile,"LE(<=) (%p) type (",tree);
5434 printTypeChain(tree->ftype,outfile);
5435 fprintf(outfile,")\n");
5436 ast_print(tree->left,outfile,indent+2);
5437 ast_print(tree->right,outfile,indent+2);
5440 fprintf(outfile,"GE(>=) (%p) type (",tree);
5441 printTypeChain(tree->ftype,outfile);
5442 fprintf(outfile,")\n");
5443 ast_print(tree->left,outfile,indent+2);
5444 ast_print(tree->right,outfile,indent+2);
5447 fprintf(outfile,"EQ(==) (%p) type (",tree);
5448 printTypeChain(tree->ftype,outfile);
5449 fprintf(outfile,")\n");
5450 ast_print(tree->left,outfile,indent+2);
5451 ast_print(tree->right,outfile,indent+2);
5454 fprintf(outfile,"NE(!=) (%p) type (",tree);
5455 printTypeChain(tree->ftype,outfile);
5456 fprintf(outfile,")\n");
5457 ast_print(tree->left,outfile,indent+2);
5458 ast_print(tree->right,outfile,indent+2);
5459 /*------------------------------------------------------------------*/
5460 /*----------------------------*/
5462 /*----------------------------*/
5463 case SIZEOF: /* evaluate wihout code generation */
5464 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5467 /*------------------------------------------------------------------*/
5468 /*----------------------------*/
5469 /* conditional operator '?' */
5470 /*----------------------------*/
5472 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5473 printTypeChain(tree->ftype,outfile);
5474 fprintf(outfile,")\n");
5475 ast_print(tree->left,outfile,indent+2);
5476 ast_print(tree->right,outfile,indent+2);
5480 fprintf(outfile,"COLON(:) (%p) type (",tree);
5481 printTypeChain(tree->ftype,outfile);
5482 fprintf(outfile,")\n");
5483 ast_print(tree->left,outfile,indent+2);
5484 ast_print(tree->right,outfile,indent+2);
5487 /*------------------------------------------------------------------*/
5488 /*----------------------------*/
5489 /* assignment operators */
5490 /*----------------------------*/
5492 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5493 printTypeChain(tree->ftype,outfile);
5494 fprintf(outfile,")\n");
5495 ast_print(tree->left,outfile,indent+2);
5496 ast_print(tree->right,outfile,indent+2);
5499 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5500 printTypeChain(tree->ftype,outfile);
5501 fprintf(outfile,")\n");
5502 ast_print(tree->left,outfile,indent+2);
5503 ast_print(tree->right,outfile,indent+2);
5506 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5507 printTypeChain(tree->ftype,outfile);
5508 fprintf(outfile,")\n");
5509 ast_print(tree->left,outfile,indent+2);
5510 ast_print(tree->right,outfile,indent+2);
5513 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5514 printTypeChain(tree->ftype,outfile);
5515 fprintf(outfile,")\n");
5516 ast_print(tree->left,outfile,indent+2);
5517 ast_print(tree->right,outfile,indent+2);
5520 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5521 printTypeChain(tree->ftype,outfile);
5522 fprintf(outfile,")\n");
5523 ast_print(tree->left,outfile,indent+2);
5524 ast_print(tree->right,outfile,indent+2);
5527 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5528 printTypeChain(tree->ftype,outfile);
5529 fprintf(outfile,")\n");
5530 ast_print(tree->left,outfile,indent+2);
5531 ast_print(tree->right,outfile,indent+2);
5534 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5535 printTypeChain(tree->ftype,outfile);
5536 fprintf(outfile,")\n");
5537 ast_print(tree->left,outfile,indent+2);
5538 ast_print(tree->right,outfile,indent+2);
5540 /*------------------------------------------------------------------*/
5541 /*----------------------------*/
5543 /*----------------------------*/
5545 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5546 printTypeChain(tree->ftype,outfile);
5547 fprintf(outfile,")\n");
5548 ast_print(tree->left,outfile,indent+2);
5549 ast_print(tree->right,outfile,indent+2);
5551 /*------------------------------------------------------------------*/
5552 /*----------------------------*/
5554 /*----------------------------*/
5556 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5557 printTypeChain(tree->ftype,outfile);
5558 fprintf(outfile,")\n");
5559 ast_print(tree->left,outfile,indent+2);
5560 ast_print(tree->right,outfile,indent+2);
5562 /*------------------------------------------------------------------*/
5563 /*----------------------------*/
5564 /* straight assignemnt */
5565 /*----------------------------*/
5567 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5568 printTypeChain(tree->ftype,outfile);
5569 fprintf(outfile,")\n");
5570 ast_print(tree->left,outfile,indent+2);
5571 ast_print(tree->right,outfile,indent+2);
5573 /*------------------------------------------------------------------*/
5574 /*----------------------------*/
5575 /* comma operator */
5576 /*----------------------------*/
5578 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5579 printTypeChain(tree->ftype,outfile);
5580 fprintf(outfile,")\n");
5581 ast_print(tree->left,outfile,indent+2);
5582 ast_print(tree->right,outfile,indent+2);
5584 /*------------------------------------------------------------------*/
5585 /*----------------------------*/
5587 /*----------------------------*/
5590 fprintf(outfile,"CALL (%p) type (",tree);
5591 printTypeChain(tree->ftype,outfile);
5592 fprintf(outfile,")\n");
5593 ast_print(tree->left,outfile,indent+2);
5594 ast_print(tree->right,outfile,indent+2);
5597 fprintf(outfile,"PARMS\n");
5598 ast_print(tree->left,outfile,indent+2);
5599 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5600 ast_print(tree->right,outfile,indent+2);
5603 /*------------------------------------------------------------------*/
5604 /*----------------------------*/
5605 /* return statement */
5606 /*----------------------------*/
5608 fprintf(outfile,"RETURN (%p) type (",tree);
5610 printTypeChain(tree->right->ftype,outfile);
5612 fprintf(outfile,")\n");
5613 ast_print(tree->right,outfile,indent+2);
5615 /*------------------------------------------------------------------*/
5616 /*----------------------------*/
5617 /* label statement */
5618 /*----------------------------*/
5620 fprintf(outfile,"LABEL (%p)\n",tree);
5621 ast_print(tree->left,outfile,indent+2);
5622 ast_print(tree->right,outfile,indent);
5624 /*------------------------------------------------------------------*/
5625 /*----------------------------*/
5626 /* switch statement */
5627 /*----------------------------*/
5631 fprintf(outfile,"SWITCH (%p) ",tree);
5632 ast_print(tree->left,outfile,0);
5633 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5634 INDENT(indent+2,outfile);
5635 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5636 (int) floatFromVal(val),
5637 tree->values.switchVals.swNum,
5638 (int) floatFromVal(val));
5640 ast_print(tree->right,outfile,indent);
5643 /*------------------------------------------------------------------*/
5644 /*----------------------------*/
5646 /*----------------------------*/
5648 fprintf(outfile,"IF (%p) \n",tree);
5649 ast_print(tree->left,outfile,indent+2);
5650 if (tree->trueLabel) {
5651 INDENT(indent+2,outfile);
5652 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5654 if (tree->falseLabel) {
5655 INDENT(indent+2,outfile);
5656 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5658 ast_print(tree->right,outfile,indent+2);
5660 /*----------------------------*/
5661 /* goto Statement */
5662 /*----------------------------*/
5664 fprintf(outfile,"GOTO (%p) \n",tree);
5665 ast_print(tree->left,outfile,indent+2);
5666 fprintf(outfile,"\n");
5668 /*------------------------------------------------------------------*/
5669 /*----------------------------*/
5671 /*----------------------------*/
5673 fprintf(outfile,"FOR (%p) \n",tree);
5674 if (AST_FOR( tree, initExpr)) {
5675 INDENT(indent+2,outfile);
5676 fprintf(outfile,"INIT EXPR ");
5677 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5679 if (AST_FOR( tree, condExpr)) {
5680 INDENT(indent+2,outfile);
5681 fprintf(outfile,"COND EXPR ");
5682 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5684 if (AST_FOR( tree, loopExpr)) {
5685 INDENT(indent+2,outfile);
5686 fprintf(outfile,"LOOP EXPR ");
5687 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5689 fprintf(outfile,"FOR LOOP BODY \n");
5690 ast_print(tree->left,outfile,indent+2);
5693 fprintf(outfile,"CRITICAL (%p) \n",tree);
5694 ast_print(tree->left,outfile,indent+2);
5702 ast_print(t,stdout,0);
5707 /*-----------------------------------------------------------------*/
5708 /* astErrors : returns non-zero if errors present in tree */
5709 /*-----------------------------------------------------------------*/
5710 int astErrors(ast *t)
5719 if (t->type == EX_VALUE
5720 && t->opval.val->sym
5721 && t->opval.val->sym->undefined)
5724 errors += astErrors(t->left);
5725 errors += astErrors(t->right);