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;
87 ex->seqPoint = seqPointNo;
92 newAst_VALUE (value * val)
94 ast *ex = newAst_ (EX_VALUE);
100 newAst_OP (unsigned op)
102 ast *ex = newAst_ (EX_OP);
108 newAst_LINK (sym_link * val)
110 ast *ex = newAst_ (EX_LINK);
115 /*-----------------------------------------------------------------*/
116 /* newNode - creates a new node */
117 /*-----------------------------------------------------------------*/
119 newNode (long op, ast * left, ast * right)
130 /*-----------------------------------------------------------------*/
131 /* newIfxNode - creates a new Ifx Node */
132 /*-----------------------------------------------------------------*/
134 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
138 /* if this is a literal then we already know the result */
139 if (condAst->etype && IS_LITERAL (condAst->etype))
141 /* then depending on the expression value */
142 if (floatFromVal (condAst->opval.val))
143 ifxNode = newNode (GOTO,
144 newAst_VALUE (symbolVal (trueLabel)),
147 ifxNode = newNode (GOTO,
148 newAst_VALUE (symbolVal (falseLabel)),
153 ifxNode = newNode (IFX, condAst, NULL);
154 ifxNode->trueLabel = trueLabel;
155 ifxNode->falseLabel = falseLabel;
161 /*-----------------------------------------------------------------*/
162 /* copyAstValues - copies value portion of ast if needed */
163 /*-----------------------------------------------------------------*/
165 copyAstValues (ast * dest, ast * src)
167 switch (src->opval.op)
170 dest->values.sym = copySymbolChain (src->values.sym);
174 dest->values.switchVals.swVals =
175 copyValue (src->values.switchVals.swVals);
176 dest->values.switchVals.swDefault =
177 src->values.switchVals.swDefault;
178 dest->values.switchVals.swNum =
179 src->values.switchVals.swNum;
183 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
187 dest->values.constlist = copyLiteralList(src->values.constlist);
191 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
192 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
193 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
194 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
195 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
196 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
197 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
202 /*-----------------------------------------------------------------*/
203 /* copyAst - makes a copy of a given astession */
204 /*-----------------------------------------------------------------*/
213 dest = Safe_alloc ( sizeof (ast));
215 dest->type = src->type;
216 dest->lineno = src->lineno;
217 dest->level = src->level;
218 dest->funcName = src->funcName;
221 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
223 /* if this is a leaf */
225 if (src->type == EX_VALUE)
227 dest->opval.val = copyValue (src->opval.val);
232 if (src->type == EX_LINK)
234 dest->opval.lnk = copyLinkChain (src->opval.lnk);
238 dest->opval.op = src->opval.op;
240 /* if this is a node that has special values */
241 copyAstValues (dest, src);
243 dest->trueLabel = copySymbol (src->trueLabel);
244 dest->falseLabel = copySymbol (src->falseLabel);
245 dest->left = copyAst (src->left);
246 dest->right = copyAst (src->right);
252 /*-----------------------------------------------------------------*/
253 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
254 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
255 /*-----------------------------------------------------------------*/
256 ast *removeIncDecOps (ast * tree) {
258 // traverse the tree and remove inc/dec ops
263 if (tree->type == EX_OP &&
264 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
271 tree->left=removeIncDecOps(tree->left);
272 tree->right=removeIncDecOps(tree->right);
277 /*-----------------------------------------------------------------*/
278 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
279 /* "*++s += 3" -> "*++s = *++s + 3" */
280 /*-----------------------------------------------------------------*/
281 ast *removePreIncDecOps (ast * tree) {
283 // traverse the tree and remove pre-inc/dec ops
288 if (tree->type == EX_OP &&
289 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
294 tree->left=removePreIncDecOps(tree->left);
295 tree->right=removePreIncDecOps(tree->right);
300 /*-----------------------------------------------------------------*/
301 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
302 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
303 /*-----------------------------------------------------------------*/
304 ast *removePostIncDecOps (ast * tree) {
306 // traverse the tree and remove pre-inc/dec ops
311 if (tree->type == EX_OP &&
312 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
317 tree->left=removePostIncDecOps(tree->left);
318 tree->right=removePostIncDecOps(tree->right);
323 /*-----------------------------------------------------------------*/
324 /* hasSEFcalls - returns TRUE if tree has a function call */
325 /*-----------------------------------------------------------------*/
327 hasSEFcalls (ast * tree)
332 if (tree->type == EX_OP &&
333 (tree->opval.op == CALL ||
334 tree->opval.op == PCALL ||
335 tree->opval.op == '=' ||
336 tree->opval.op == INC_OP ||
337 tree->opval.op == DEC_OP))
340 return (hasSEFcalls (tree->left) |
341 hasSEFcalls (tree->right));
344 /*-----------------------------------------------------------------*/
345 /* isAstEqual - compares two asts & returns 1 if they are equal */
346 /*-----------------------------------------------------------------*/
348 isAstEqual (ast * t1, ast * t2)
357 if (t1->type != t2->type)
363 if (t1->opval.op != t2->opval.op)
365 return (isAstEqual (t1->left, t2->left) &&
366 isAstEqual (t1->right, t2->right));
370 if (t1->opval.val->sym)
372 if (!t2->opval.val->sym)
375 return isSymbolEqual (t1->opval.val->sym,
380 if (t2->opval.val->sym)
383 return (floatFromVal (t1->opval.val) ==
384 floatFromVal (t2->opval.val));
388 /* only compare these two types */
396 /*-----------------------------------------------------------------*/
397 /* resolveSymbols - resolve symbols from the symbol table */
398 /*-----------------------------------------------------------------*/
400 resolveSymbols (ast * tree)
402 /* walk the entire tree and check for values */
403 /* with symbols if we find one then replace */
404 /* symbol with that from the symbol table */
411 /* if not block & function */
412 if (tree->type == EX_OP &&
413 (tree->opval.op != FUNCTION &&
414 tree->opval.op != BLOCK &&
415 tree->opval.op != NULLOP))
417 filename = tree->filename;
418 lineno = tree->lineno;
422 /* make sure we resolve the true & false labels for ifx */
423 if (tree->type == EX_OP && tree->opval.op == IFX)
429 if ((csym = findSym (LabelTab, tree->trueLabel,
430 tree->trueLabel->name)))
431 tree->trueLabel = csym;
433 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
434 tree->trueLabel->name);
437 if (tree->falseLabel)
439 if ((csym = findSym (LabelTab,
441 tree->falseLabel->name)))
442 tree->falseLabel = csym;
444 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
445 tree->falseLabel->name);
450 /* if this is a label resolve it from the labelTab */
451 if (IS_AST_VALUE (tree) &&
452 tree->opval.val->sym &&
453 tree->opval.val->sym->islbl)
456 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
457 tree->opval.val->sym->name);
460 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
461 tree->opval.val->sym->name);
463 tree->opval.val->sym = csym;
465 goto resolveChildren;
468 /* do only for leafs */
469 if (IS_AST_VALUE (tree) &&
470 tree->opval.val->sym &&
471 !tree->opval.val->sym->implicit)
474 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
476 /* if found in the symbol table & they r not the same */
477 if (csym && tree->opval.val->sym != csym)
479 tree->opval.val->sym = csym;
480 tree->opval.val->type = csym->type;
481 tree->opval.val->etype = csym->etype;
484 /* if not found in the symbol table */
485 /* mark it as undefined assume it is */
486 /* an integer in data space */
487 if (!csym && !tree->opval.val->sym->implicit)
490 /* if this is a function name then */
491 /* mark it as returning an int */
494 tree->opval.val->sym->type = newLink (DECLARATOR);
495 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
496 tree->opval.val->sym->type->next =
497 tree->opval.val->sym->etype = newIntLink ();
498 tree->opval.val->etype = tree->opval.val->etype;
499 tree->opval.val->type = tree->opval.val->sym->type;
500 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
501 tree->opval.val->sym->name);
502 //tree->opval.val->sym->undefined = 1;
503 allocVariables (tree->opval.val->sym);
507 tree->opval.val->sym->undefined = 1;
508 tree->opval.val->type =
509 tree->opval.val->etype = newIntLink ();
510 tree->opval.val->sym->type =
511 tree->opval.val->sym->etype = newIntLink ();
517 resolveSymbols (tree->left);
518 resolveSymbols (tree->right);
523 /*-----------------------------------------------------------------*/
524 /* setAstLineno - walks a ast tree & sets the line number */
525 /*-----------------------------------------------------------------*/
526 int setAstLineno (ast * tree, int lineno)
531 tree->lineno = lineno;
532 setAstLineno (tree->left, lineno);
533 setAstLineno (tree->right, lineno);
537 /*-----------------------------------------------------------------*/
538 /* funcOfType :- function of type with name */
539 /*-----------------------------------------------------------------*/
541 funcOfType (char *name, sym_link * type, sym_link * argType,
545 /* create the symbol */
546 sym = newSymbol (name, 0);
548 /* setup return value */
549 sym->type = newLink (DECLARATOR);
550 DCL_TYPE (sym->type) = FUNCTION;
551 sym->type->next = copyLinkChain (type);
552 sym->etype = getSpec (sym->type);
553 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
555 /* if arguments required */
559 args = FUNC_ARGS(sym->type) = newValue ();
563 args->type = copyLinkChain (argType);
564 args->etype = getSpec (args->type);
565 SPEC_EXTR(args->etype)=1;
568 args = args->next = newValue ();
575 allocVariables (sym);
580 /*-----------------------------------------------------------------*/
581 /* funcOfTypeVarg :- function of type with name and argtype */
582 /*-----------------------------------------------------------------*/
584 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
589 /* create the symbol */
590 sym = newSymbol (name, 0);
592 /* setup return value */
593 sym->type = newLink (DECLARATOR);
594 DCL_TYPE (sym->type) = FUNCTION;
595 sym->type->next = typeFromStr(rtype);
596 sym->etype = getSpec (sym->type);
598 /* if arguments required */
601 args = FUNC_ARGS(sym->type) = newValue ();
603 for ( i = 0 ; i < nArgs ; i++ ) {
604 args->type = typeFromStr(atypes[i]);
605 args->etype = getSpec (args->type);
606 SPEC_EXTR(args->etype)=1;
607 if ((i + 1) == nArgs) break;
608 args = args->next = newValue ();
615 allocVariables (sym);
620 /*-----------------------------------------------------------------*/
621 /* reverseParms - will reverse a parameter tree */
622 /*-----------------------------------------------------------------*/
624 reverseParms (ast * ptree)
630 /* top down if we find a nonParm tree then quit */
631 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
634 ptree->left = ptree->right;
635 ptree->right = ttree;
636 reverseParms (ptree->left);
637 reverseParms (ptree->right);
643 /*-----------------------------------------------------------------*/
644 /* processParms - makes sure the parameters are okay and do some */
645 /* processing with them */
646 /*-----------------------------------------------------------------*/
648 processParms (ast * func,
651 int *parmNumber, // unused, although updated
654 /* if none of them exist */
655 if (!defParm && !actParm)
659 if (getenv("DEBUG_SANITY")) {
660 fprintf (stderr, "processParms: %s ", defParm->name);
662 /* make sure the type is complete and sane */
663 checkTypeSanity(defParm->etype, defParm->name);
666 /* if the function is being called via a pointer & */
667 /* it has not been defined a reentrant then we cannot */
668 /* have parameters */
669 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
671 werror (W_NONRENT_ARGS);
675 /* if defined parameters ended but actual parameters */
676 /* exist and this is not defined as a variable arg */
677 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
679 //if (func->type==EX_VALUE && func->opval.val->sym->undefined)
680 // return 1; /* Already gave them an undefined function error */
681 werror (E_TOO_MANY_PARMS);
685 /* if defined parameters present but no actual parameters */
686 if (defParm && !actParm)
688 werror (E_TOO_FEW_PARMS);
692 if (IS_VOID(actParm->ftype)) {
693 werror (E_VOID_VALUE_USED);
697 /* If this is a varargs function... */
698 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
703 if (IS_CAST_OP (actParm)
704 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
706 /* Parameter was explicitly typecast; don't touch it. */
710 ftype = actParm->ftype;
712 /* If it's a small integer, upcast to int. */
713 if (IS_INTEGRAL (ftype)
714 && (getSize (ftype) < (unsigned) INTSIZE))
716 if (IS_AST_OP(actParm) &&
717 (actParm->opval.op == LEFT_OP ||
718 actParm->opval.op == '*' ||
719 actParm->opval.op == '+' ||
720 actParm->opval.op == '-') &&
722 // we should cast an operand instead of the result
723 actParm->decorated = 0;
724 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
726 actParm = decorateType(actParm);
728 newType = newAst_LINK(INTTYPE);
732 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
734 newType = newAst_LINK (copyLinkChain(ftype));
735 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
738 if (IS_AGGREGATE (ftype))
740 newType = newAst_LINK (copyLinkChain (ftype));
741 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
745 /* cast required; change this op to a cast. */
746 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
748 actParm->type = EX_OP;
749 actParm->opval.op = CAST;
750 actParm->left = newType;
751 actParm->right = parmCopy;
752 decorateType (actParm);
754 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
756 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
757 processParms (func, NULL, actParm->right, parmNumber, rightmost));
762 /* if defined parameters ended but actual has not & */
764 if (!defParm && actParm &&
765 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
768 resolveSymbols (actParm);
769 /* if this is a PARAM node then match left & right */
770 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
772 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
773 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
777 /* If we have found a value node by following only right-hand links,
778 * then we know that there are no more values after us.
780 * Therefore, if there are more defined parameters, the caller didn't
783 if (rightmost && defParm->next)
785 werror (E_TOO_FEW_PARMS);
790 /* the parameter type must be at least castable */
791 if (compareType (defParm->type, actParm->ftype) == 0) {
792 werror (E_INCOMPAT_TYPES);
793 printFromToType (actParm->ftype, defParm->type);
797 /* if the parameter is castable then add the cast */
798 if (compareType (defParm->type, actParm->ftype) < 0)
800 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
802 /* now change the current one to a cast */
803 actParm->type = EX_OP;
804 actParm->opval.op = CAST;
805 actParm->left = newAst_LINK (defParm->type);
806 actParm->right = pTree;
807 actParm->etype = defParm->etype;
808 actParm->ftype = defParm->type;
809 actParm->decorated=0; /* force typechecking */
810 decorateType (actParm);
813 /* make a copy and change the regparm type to the defined parm */
814 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
815 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
816 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
820 /*-----------------------------------------------------------------*/
821 /* createIvalType - generates ival for basic types */
822 /*-----------------------------------------------------------------*/
824 createIvalType (ast * sym, sym_link * type, initList * ilist)
828 /* if initList is deep */
829 if (ilist->type == INIT_DEEP)
830 ilist = ilist->init.deep;
832 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
833 return decorateType (newNode ('=', sym, iExpr));
836 /*-----------------------------------------------------------------*/
837 /* createIvalStruct - generates initial value for structures */
838 /*-----------------------------------------------------------------*/
840 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
847 sflds = SPEC_STRUCT (type)->fields;
848 if (ilist->type != INIT_DEEP)
850 werror (E_INIT_STRUCT, "");
854 iloop = ilist->init.deep;
856 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
858 /* if we have come to end */
862 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
863 lAst = decorateType (resolveSymbols (lAst));
864 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
868 werrorfl (filename, sym->opval.val->sym->lineDef,
869 W_EXCESS_INITIALIZERS, "struct",
870 sym->opval.val->sym->name);
877 /*-----------------------------------------------------------------*/
878 /* createIvalArray - generates code for array initialization */
879 /*-----------------------------------------------------------------*/
881 createIvalArray (ast * sym, sym_link * type, initList * ilist)
885 int lcnt = 0, size = 0;
886 literalList *literalL;
888 /* take care of the special case */
889 /* array of characters can be init */
891 if (IS_CHAR (type->next))
892 if ((rast = createIvalCharPtr (sym,
894 decorateType (resolveSymbols (list2expr (ilist))))))
896 return decorateType (resolveSymbols (rast));
898 /* not the special case */
899 if (ilist->type != INIT_DEEP)
901 werror (E_INIT_STRUCT, "");
905 iloop = ilist->init.deep;
906 lcnt = DCL_ELEM (type);
908 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
912 aSym = decorateType (resolveSymbols(sym));
914 rast = newNode(ARRAYINIT, aSym, NULL);
915 rast->values.constlist = literalL;
917 // Make sure size is set to length of initializer list.
924 if (lcnt && size > lcnt)
926 // Array size was specified, and we have more initializers than needed.
927 char *name=sym->opval.val->sym->name;
928 int lineno=sym->opval.val->sym->lineDef;
930 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
939 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
940 aSym = decorateType (resolveSymbols (aSym));
941 rast = createIval (aSym, type->next, iloop, rast);
942 iloop = (iloop ? iloop->next : NULL);
948 /* no of elements given and we */
949 /* have generated for all of them */
952 // there has to be a better way
953 char *name=sym->opval.val->sym->name;
954 int lineno=sym->opval.val->sym->lineDef;
955 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
962 /* if we have not been given a size */
963 if (!DCL_ELEM (type))
965 DCL_ELEM (type) = size;
968 return decorateType (resolveSymbols (rast));
972 /*-----------------------------------------------------------------*/
973 /* createIvalCharPtr - generates initial values for char pointers */
974 /*-----------------------------------------------------------------*/
976 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
980 /* if this is a pointer & right is a literal array then */
981 /* just assignment will do */
982 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
983 SPEC_SCLS (iexpr->etype) == S_CODE)
984 && IS_ARRAY (iexpr->ftype)))
985 return newNode ('=', sym, iexpr);
987 /* left side is an array so we have to assign each */
989 if ((IS_LITERAL (iexpr->etype) ||
990 SPEC_SCLS (iexpr->etype) == S_CODE)
991 && IS_ARRAY (iexpr->ftype))
993 /* for each character generate an assignment */
994 /* to the array element */
995 char *s = SPEC_CVAL (iexpr->etype).v_char;
997 int size = getSize (iexpr->ftype);
998 int symsize = getSize (type);
1002 if (size>(symsize+1))
1003 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1004 "string", sym->opval.val->sym->name);
1008 for (i=0;i<size;i++)
1010 rast = newNode (NULLOP,
1014 newAst_VALUE (valueFromLit ((float) i))),
1015 newAst_VALUE (valueFromLit (*s))));
1019 // now WE don't need iexpr's symbol anymore
1020 freeStringSymbol(AST_SYMBOL(iexpr));
1022 return decorateType (resolveSymbols (rast));
1028 /*-----------------------------------------------------------------*/
1029 /* createIvalPtr - generates initial value for pointers */
1030 /*-----------------------------------------------------------------*/
1032 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1038 if (ilist->type == INIT_DEEP)
1039 ilist = ilist->init.deep;
1041 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1043 /* if character pointer */
1044 if (IS_CHAR (type->next))
1045 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1048 return newNode ('=', sym, iexpr);
1051 /*-----------------------------------------------------------------*/
1052 /* createIval - generates code for initial value */
1053 /*-----------------------------------------------------------------*/
1055 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1062 /* if structure then */
1063 if (IS_STRUCT (type))
1064 rast = createIvalStruct (sym, type, ilist);
1066 /* if this is a pointer */
1068 rast = createIvalPtr (sym, type, ilist);
1070 /* if this is an array */
1071 if (IS_ARRAY (type))
1072 rast = createIvalArray (sym, type, ilist);
1074 /* if type is SPECIFIER */
1076 rast = createIvalType (sym, type, ilist);
1079 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1081 return decorateType (resolveSymbols (rast));
1084 /*-----------------------------------------------------------------*/
1085 /* initAggregates - initialises aggregate variables with initv */
1086 /*-----------------------------------------------------------------*/
1087 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1088 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1091 /*-----------------------------------------------------------------*/
1092 /* gatherAutoInit - creates assignment expressions for initial */
1094 /*-----------------------------------------------------------------*/
1096 gatherAutoInit (symbol * autoChain)
1103 for (sym = autoChain; sym; sym = sym->next)
1106 /* resolve the symbols in the ival */
1108 resolveIvalSym (sym->ival);
1110 /* if this is a static variable & has an */
1111 /* initial value the code needs to be lifted */
1112 /* here to the main portion since they can be */
1113 /* initialised only once at the start */
1114 if (IS_STATIC (sym->etype) && sym->ival &&
1115 SPEC_SCLS (sym->etype) != S_CODE)
1119 /* insert the symbol into the symbol table */
1120 /* with level = 0 & name = rname */
1121 newSym = copySymbol (sym);
1122 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1124 /* now lift the code to main */
1125 if (IS_AGGREGATE (sym->type)) {
1126 work = initAggregates (sym, sym->ival, NULL);
1128 if (getNelements(sym->type, sym->ival)>1) {
1129 werrorfl (filename, sym->lineDef,
1130 W_EXCESS_INITIALIZERS, "scalar",
1133 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1134 list2expr (sym->ival));
1137 setAstLineno (work, sym->lineDef);
1141 staticAutos = newNode (NULLOP, staticAutos, work);
1148 /* if there is an initial value */
1149 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1151 initList *ilist=sym->ival;
1153 while (ilist->type == INIT_DEEP) {
1154 ilist = ilist->init.deep;
1157 /* update lineno for error msg */
1158 lineno=sym->lineDef;
1159 setAstLineno (ilist->init.node, lineno);
1161 if (IS_AGGREGATE (sym->type)) {
1162 work = initAggregates (sym, sym->ival, NULL);
1164 if (getNelements(sym->type, sym->ival)>1) {
1165 werrorfl (filename, sym->lineDef,
1166 W_EXCESS_INITIALIZERS, "scalar",
1169 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1170 list2expr (sym->ival));
1174 setAstLineno (work, sym->lineDef);
1178 init = newNode (NULLOP, init, work);
1187 /*-----------------------------------------------------------------*/
1188 /* freeStringSymbol - delete a literal string if no more usage */
1189 /*-----------------------------------------------------------------*/
1190 void freeStringSymbol(symbol *sym) {
1191 /* make sure this is a literal string */
1192 assert (sym->isstrlit);
1193 if (--sym->isstrlit == 0) { // lower the usage count
1194 memmap *segment=SPEC_OCLS(sym->etype);
1196 deleteSetItem(&segment->syms, sym);
1201 /*-----------------------------------------------------------------*/
1202 /* stringToSymbol - creates a symbol from a literal string */
1203 /*-----------------------------------------------------------------*/
1205 stringToSymbol (value * val)
1207 char name[SDCC_NAME_MAX + 1];
1208 static int charLbl = 0;
1213 // have we heard this before?
1214 for (sp=statsg->syms; sp; sp=sp->next) {
1216 size = getSize (sym->type);
1217 if (sym->isstrlit && size == getSize (val->type) &&
1218 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1219 // yes, this is old news. Don't publish it again.
1220 sym->isstrlit++; // but raise the usage count
1221 return symbolVal(sym);
1225 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1226 sym = newSymbol (name, 0); /* make it @ level 0 */
1227 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1229 /* copy the type from the value passed */
1230 sym->type = copyLinkChain (val->type);
1231 sym->etype = getSpec (sym->type);
1232 /* change to storage class & output class */
1233 SPEC_SCLS (sym->etype) = S_CODE;
1234 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1235 SPEC_STAT (sym->etype) = 1;
1236 /* make the level & block = 0 */
1237 sym->block = sym->level = 0;
1239 /* create an ival */
1240 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1245 allocVariables (sym);
1248 return symbolVal (sym);
1252 /*-----------------------------------------------------------------*/
1253 /* processBlockVars - will go thru the ast looking for block if */
1254 /* a block is found then will allocate the syms */
1255 /* will also gather the auto inits present */
1256 /*-----------------------------------------------------------------*/
1258 processBlockVars (ast * tree, int *stack, int action)
1263 /* if this is a block */
1264 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1268 if (action == ALLOCATE)
1270 *stack += allocVariables (tree->values.sym);
1271 autoInit = gatherAutoInit (tree->values.sym);
1273 /* if there are auto inits then do them */
1275 tree->left = newNode (NULLOP, autoInit, tree->left);
1277 else /* action is deallocate */
1278 deallocLocal (tree->values.sym);
1281 processBlockVars (tree->left, stack, action);
1282 processBlockVars (tree->right, stack, action);
1287 /*-------------------------------------------------------------*/
1288 /* constExprTree - returns TRUE if this tree is a constant */
1290 /*-------------------------------------------------------------*/
1291 bool constExprTree (ast *cexpr) {
1297 cexpr = decorateType (resolveSymbols (cexpr));
1299 switch (cexpr->type)
1302 if (IS_AST_LIT_VALUE(cexpr)) {
1303 // this is a literal
1306 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1307 // a function's address will never change
1310 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1311 // an array's address will never change
1314 if (IS_AST_SYM_VALUE(cexpr) &&
1315 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1316 // a symbol in code space will never change
1317 // This is only for the 'char *s="hallo"' case and will have to leave
1318 //printf(" code space symbol");
1323 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1324 "unexpected link in expression tree\n");
1327 if (cexpr->opval.op==ARRAYINIT) {
1328 // this is a list of literals
1331 if (cexpr->opval.op=='=') {
1332 return constExprTree(cexpr->right);
1334 if (cexpr->opval.op==CAST) {
1335 // cast ignored, maybe we should throw a warning here?
1336 return constExprTree(cexpr->right);
1338 if (cexpr->opval.op=='&') {
1341 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1344 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1349 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1354 /*-----------------------------------------------------------------*/
1355 /* constExprValue - returns the value of a constant expression */
1356 /* or NULL if it is not a constant expression */
1357 /*-----------------------------------------------------------------*/
1359 constExprValue (ast * cexpr, int check)
1361 cexpr = decorateType (resolveSymbols (cexpr));
1363 /* if this is not a constant then */
1364 if (!IS_LITERAL (cexpr->ftype))
1366 /* then check if this is a literal array
1368 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1369 SPEC_CVAL (cexpr->etype).v_char &&
1370 IS_ARRAY (cexpr->ftype))
1372 value *val = valFromType (cexpr->ftype);
1373 SPEC_SCLS (val->etype) = S_LITERAL;
1374 val->sym = cexpr->opval.val->sym;
1375 val->sym->type = copyLinkChain (cexpr->ftype);
1376 val->sym->etype = getSpec (val->sym->type);
1377 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1381 /* if we are casting a literal value then */
1382 if (IS_AST_OP (cexpr) &&
1383 cexpr->opval.op == CAST &&
1384 IS_LITERAL (cexpr->right->ftype))
1386 return valCastLiteral (cexpr->ftype,
1387 floatFromVal (cexpr->right->opval.val));
1390 if (IS_AST_VALUE (cexpr))
1392 return cexpr->opval.val;
1396 werror (E_CONST_EXPECTED, "found expression");
1401 /* return the value */
1402 return cexpr->opval.val;
1406 /*-----------------------------------------------------------------*/
1407 /* isLabelInAst - will return true if a given label is found */
1408 /*-----------------------------------------------------------------*/
1410 isLabelInAst (symbol * label, ast * tree)
1412 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1415 if (IS_AST_OP (tree) &&
1416 tree->opval.op == LABEL &&
1417 isSymbolEqual (AST_SYMBOL (tree->left), label))
1420 return isLabelInAst (label, tree->right) &&
1421 isLabelInAst (label, tree->left);
1425 /*-----------------------------------------------------------------*/
1426 /* isLoopCountable - return true if the loop count can be determi- */
1427 /* -ned at compile time . */
1428 /*-----------------------------------------------------------------*/
1430 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1431 symbol ** sym, ast ** init, ast ** end)
1434 /* the loop is considered countable if the following
1435 conditions are true :-
1437 a) initExpr :- <sym> = <const>
1438 b) condExpr :- <sym> < <const1>
1439 c) loopExpr :- <sym> ++
1442 /* first check the initExpr */
1443 if (IS_AST_OP (initExpr) &&
1444 initExpr->opval.op == '=' && /* is assignment */
1445 IS_AST_SYM_VALUE (initExpr->left))
1446 { /* left is a symbol */
1448 *sym = AST_SYMBOL (initExpr->left);
1449 *init = initExpr->right;
1454 /* for now the symbol has to be of
1456 if (!IS_INTEGRAL ((*sym)->type))
1459 /* now check condExpr */
1460 if (IS_AST_OP (condExpr))
1463 switch (condExpr->opval.op)
1466 if (IS_AST_SYM_VALUE (condExpr->left) &&
1467 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1468 IS_AST_LIT_VALUE (condExpr->right))
1470 *end = condExpr->right;
1476 if (IS_AST_OP (condExpr->left) &&
1477 condExpr->left->opval.op == '>' &&
1478 IS_AST_LIT_VALUE (condExpr->left->right) &&
1479 IS_AST_SYM_VALUE (condExpr->left->left) &&
1480 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1483 *end = newNode ('+', condExpr->left->right,
1484 newAst_VALUE (constVal ("1")));
1495 /* check loop expression is of the form <sym>++ */
1496 if (!IS_AST_OP (loopExpr))
1499 /* check if <sym> ++ */
1500 if (loopExpr->opval.op == INC_OP)
1506 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1507 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1514 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1515 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1523 if (loopExpr->opval.op == ADD_ASSIGN)
1526 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1527 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1528 IS_AST_LIT_VALUE (loopExpr->right) &&
1529 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1537 /*-----------------------------------------------------------------*/
1538 /* astHasVolatile - returns true if ast contains any volatile */
1539 /*-----------------------------------------------------------------*/
1541 astHasVolatile (ast * tree)
1546 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1549 if (IS_AST_OP (tree))
1550 return astHasVolatile (tree->left) ||
1551 astHasVolatile (tree->right);
1556 /*-----------------------------------------------------------------*/
1557 /* astHasPointer - return true if the ast contains any ptr variable */
1558 /*-----------------------------------------------------------------*/
1560 astHasPointer (ast * tree)
1565 if (IS_AST_LINK (tree))
1568 /* if we hit an array expression then check
1569 only the left side */
1570 if (IS_AST_OP (tree) && tree->opval.op == '[')
1571 return astHasPointer (tree->left);
1573 if (IS_AST_VALUE (tree))
1574 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1576 return astHasPointer (tree->left) ||
1577 astHasPointer (tree->right);
1581 /*-----------------------------------------------------------------*/
1582 /* astHasSymbol - return true if the ast has the given symbol */
1583 /*-----------------------------------------------------------------*/
1585 astHasSymbol (ast * tree, symbol * sym)
1587 if (!tree || IS_AST_LINK (tree))
1590 if (IS_AST_VALUE (tree))
1592 if (IS_AST_SYM_VALUE (tree))
1593 return isSymbolEqual (AST_SYMBOL (tree), sym);
1598 return astHasSymbol (tree->left, sym) ||
1599 astHasSymbol (tree->right, sym);
1602 /*-----------------------------------------------------------------*/
1603 /* astHasDeref - return true if the ast has an indirect access */
1604 /*-----------------------------------------------------------------*/
1606 astHasDeref (ast * tree)
1608 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1611 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1613 return astHasDeref (tree->left) || astHasDeref (tree->right);
1616 /*-----------------------------------------------------------------*/
1617 /* isConformingBody - the loop body has to conform to a set of rules */
1618 /* for the loop to be considered reversible read on for rules */
1619 /*-----------------------------------------------------------------*/
1621 isConformingBody (ast * pbody, symbol * sym, ast * body)
1624 /* we are going to do a pre-order traversal of the
1625 tree && check for the following conditions. (essentially
1626 a set of very shallow tests )
1627 a) the sym passed does not participate in
1628 any arithmetic operation
1629 b) There are no function calls
1630 c) all jumps are within the body
1631 d) address of loop control variable not taken
1632 e) if an assignment has a pointer on the
1633 left hand side make sure right does not have
1634 loop control variable */
1636 /* if we reach the end or a leaf then true */
1637 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1640 /* if anything else is "volatile" */
1641 if (IS_VOLATILE (TETYPE (pbody)))
1644 /* we will walk the body in a pre-order traversal for
1646 switch (pbody->opval.op)
1648 /*------------------------------------------------------------------*/
1650 // if the loopvar is used as an index
1651 if (astHasSymbol(pbody->right, sym)) {
1654 return isConformingBody (pbody->right, sym, body);
1656 /*------------------------------------------------------------------*/
1661 /*------------------------------------------------------------------*/
1665 /* sure we are not sym is not modified */
1667 IS_AST_SYM_VALUE (pbody->left) &&
1668 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1672 IS_AST_SYM_VALUE (pbody->right) &&
1673 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1678 /*------------------------------------------------------------------*/
1680 case '*': /* can be unary : if right is null then unary operation */
1685 /* if right is NULL then unary operation */
1686 /*------------------------------------------------------------------*/
1687 /*----------------------------*/
1689 /*----------------------------*/
1692 if (IS_AST_SYM_VALUE (pbody->left) &&
1693 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1696 return isConformingBody (pbody->left, sym, body);
1700 if (astHasSymbol (pbody->left, sym) ||
1701 astHasSymbol (pbody->right, sym))
1706 /*------------------------------------------------------------------*/
1714 if (IS_AST_SYM_VALUE (pbody->left) &&
1715 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1718 if (IS_AST_SYM_VALUE (pbody->right) &&
1719 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1722 return isConformingBody (pbody->left, sym, body) &&
1723 isConformingBody (pbody->right, sym, body);
1731 if (IS_AST_SYM_VALUE (pbody->left) &&
1732 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1734 return isConformingBody (pbody->left, sym, body);
1736 /*------------------------------------------------------------------*/
1748 case SIZEOF: /* evaluate wihout code generation */
1750 if (IS_AST_SYM_VALUE (pbody->left) &&
1751 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1754 if (IS_AST_SYM_VALUE (pbody->right) &&
1755 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1758 return isConformingBody (pbody->left, sym, body) &&
1759 isConformingBody (pbody->right, sym, body);
1761 /*------------------------------------------------------------------*/
1764 /* if left has a pointer & right has loop
1765 control variable then we cannot */
1766 if (astHasPointer (pbody->left) &&
1767 astHasSymbol (pbody->right, sym))
1769 if (astHasVolatile (pbody->left))
1772 if (IS_AST_SYM_VALUE (pbody->left)) {
1773 // if the loopvar has an assignment
1774 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1776 // if the loopvar is used in another (maybe conditional) block
1777 if (astHasSymbol (pbody->right, sym) &&
1778 (pbody->level >= body->level)) {
1783 if (astHasVolatile (pbody->left))
1786 if (astHasDeref(pbody->right)) return FALSE;
1788 return isConformingBody (pbody->left, sym, body) &&
1789 isConformingBody (pbody->right, sym, body);
1800 assert ("Parser should not have generated this\n");
1802 /*------------------------------------------------------------------*/
1803 /*----------------------------*/
1804 /* comma operator */
1805 /*----------------------------*/
1807 return isConformingBody (pbody->left, sym, body) &&
1808 isConformingBody (pbody->right, sym, body);
1810 /*------------------------------------------------------------------*/
1811 /*----------------------------*/
1813 /*----------------------------*/
1815 /* if local & not passed as paramater then ok */
1816 if (sym->level && !astHasSymbol(pbody->right,sym))
1820 /*------------------------------------------------------------------*/
1821 /*----------------------------*/
1822 /* return statement */
1823 /*----------------------------*/
1828 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1833 if (astHasSymbol (pbody->left, sym))
1840 return isConformingBody (pbody->left, sym, body) &&
1841 isConformingBody (pbody->right, sym, body);
1847 /*-----------------------------------------------------------------*/
1848 /* isLoopReversible - takes a for loop as input && returns true */
1849 /* if the for loop is reversible. If yes will set the value of */
1850 /* the loop control var & init value & termination value */
1851 /*-----------------------------------------------------------------*/
1853 isLoopReversible (ast * loop, symbol ** loopCntrl,
1854 ast ** init, ast ** end)
1856 /* if option says don't do it then don't */
1857 if (optimize.noLoopReverse)
1859 /* there are several tests to determine this */
1861 /* for loop has to be of the form
1862 for ( <sym> = <const1> ;
1863 [<sym> < <const2>] ;
1864 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1866 if (!isLoopCountable (AST_FOR (loop, initExpr),
1867 AST_FOR (loop, condExpr),
1868 AST_FOR (loop, loopExpr),
1869 loopCntrl, init, end))
1872 /* now do some serious checking on the body of the loop
1875 return isConformingBody (loop->left, *loopCntrl, loop->left);
1879 /*-----------------------------------------------------------------*/
1880 /* replLoopSym - replace the loop sym by loop sym -1 */
1881 /*-----------------------------------------------------------------*/
1883 replLoopSym (ast * body, symbol * sym)
1886 if (!body || IS_AST_LINK (body))
1889 if (IS_AST_SYM_VALUE (body))
1892 if (isSymbolEqual (AST_SYMBOL (body), sym))
1896 body->opval.op = '-';
1897 body->left = newAst_VALUE (symbolVal (sym));
1898 body->right = newAst_VALUE (constVal ("1"));
1906 replLoopSym (body->left, sym);
1907 replLoopSym (body->right, sym);
1911 /*-----------------------------------------------------------------*/
1912 /* reverseLoop - do the actual loop reversal */
1913 /*-----------------------------------------------------------------*/
1915 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1919 /* create the following tree
1924 if (sym) goto for_continue ;
1927 /* put it together piece by piece */
1928 rloop = newNode (NULLOP,
1929 createIf (newAst_VALUE (symbolVal (sym)),
1931 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1934 newAst_VALUE (symbolVal (sym)),
1937 replLoopSym (loop->left, sym);
1938 setAstLineno (rloop, init->lineno);
1940 rloop = newNode (NULLOP,
1942 newAst_VALUE (symbolVal (sym)),
1943 newNode ('-', end, init)),
1944 createLabel (AST_FOR (loop, continueLabel),
1948 newNode (SUB_ASSIGN,
1949 newAst_VALUE (symbolVal (sym)),
1950 newAst_VALUE (constVal ("1"))),
1953 rloop->lineno=init->lineno;
1954 return decorateType (rloop);
1958 /*-----------------------------------------------------------------*/
1959 /* searchLitOp - search tree (*ops only) for an ast with literal */
1960 /*-----------------------------------------------------------------*/
1962 searchLitOp (ast *tree, ast **parent, const char *ops)
1966 if (tree && optimize.global_cse)
1968 /* is there a literal operand? */
1970 IS_AST_OP(tree->right) &&
1971 tree->right->right &&
1972 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1974 if (IS_LITERAL (RTYPE (tree->right)) ^
1975 IS_LITERAL (LTYPE (tree->right)))
1977 tree->right->decorated = 0;
1978 tree->decorated = 0;
1982 ret = searchLitOp (tree->right, parent, ops);
1987 IS_AST_OP(tree->left) &&
1988 tree->left->right &&
1989 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1991 if (IS_LITERAL (RTYPE (tree->left)) ^
1992 IS_LITERAL (LTYPE (tree->left)))
1994 tree->left->decorated = 0;
1995 tree->decorated = 0;
1999 ret = searchLitOp (tree->left, parent, ops);
2007 /*-----------------------------------------------------------------*/
2008 /* decorateType - compute type for this tree also does type checking */
2009 /* this is done bottom up, since type have to flow upwards */
2010 /* it also does constant folding, and paramater checking */
2011 /*-----------------------------------------------------------------*/
2013 decorateType (ast * tree)
2021 /* if already has type then do nothing */
2022 if (tree->decorated)
2025 tree->decorated = 1;
2028 /* print the line */
2029 /* if not block & function */
2030 if (tree->type == EX_OP &&
2031 (tree->opval.op != FUNCTION &&
2032 tree->opval.op != BLOCK &&
2033 tree->opval.op != NULLOP))
2035 filename = tree->filename;
2036 lineno = tree->lineno;
2040 /* if any child is an error | this one is an error do nothing */
2041 if (tree->isError ||
2042 (tree->left && tree->left->isError) ||
2043 (tree->right && tree->right->isError))
2046 /*------------------------------------------------------------------*/
2047 /*----------------------------*/
2048 /* leaf has been reached */
2049 /*----------------------------*/
2050 lineno=tree->lineno;
2051 /* if this is of type value */
2052 /* just get the type */
2053 if (tree->type == EX_VALUE)
2056 if (IS_LITERAL (tree->opval.val->etype))
2059 /* if this is a character array then declare it */
2060 if (IS_ARRAY (tree->opval.val->type))
2061 tree->opval.val = stringToSymbol (tree->opval.val);
2063 /* otherwise just copy the type information */
2064 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2068 if (tree->opval.val->sym)
2070 /* if the undefined flag is set then give error message */
2071 if (tree->opval.val->sym->undefined)
2073 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2075 TTYPE (tree) = TETYPE (tree) =
2076 tree->opval.val->type = tree->opval.val->sym->type =
2077 tree->opval.val->etype = tree->opval.val->sym->etype =
2078 copyLinkChain (INTTYPE);
2083 /* if impilicit i.e. struct/union member then no type */
2084 if (tree->opval.val->sym->implicit)
2085 TTYPE (tree) = TETYPE (tree) = NULL;
2090 /* else copy the type */
2091 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2093 /* and mark it as referenced */
2094 tree->opval.val->sym->isref = 1;
2102 /* if type link for the case of cast */
2103 if (tree->type == EX_LINK)
2105 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2113 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2115 if (tree->left && tree->left->type == EX_OPERAND
2116 && (tree->left->opval.op == INC_OP
2117 || tree->left->opval.op == DEC_OP)
2118 && tree->left->left)
2120 tree->left->right = tree->left->left;
2121 tree->left->left = NULL;
2123 if (tree->right && tree->right->type == EX_OPERAND
2124 && (tree->right->opval.op == INC_OP
2125 || tree->right->opval.op == DEC_OP)
2126 && tree->right->left)
2128 tree->right->right = tree->right->left;
2129 tree->right->left = NULL;
2134 dtl = decorateType (tree->left);
2135 /* delay right side for '?' operator since conditional macro expansions might
2137 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2139 /* this is to take care of situations
2140 when the tree gets rewritten */
2141 if (dtl != tree->left)
2143 if (dtr != tree->right)
2145 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2148 if (IS_AST_OP(tree) &&
2149 (tree->opval.op == CAST || tree->opval.op == '=') &&
2150 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2151 (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2152 // this is a cast/assign to a bigger type
2153 if (IS_AST_OP(tree->right) &&
2154 IS_INTEGRAL(tree->right->ftype) &&
2155 (tree->right->opval.op == LEFT_OP ||
2156 tree->right->opval.op == '*' ||
2157 tree->right->opval.op == '+' ||
2158 tree->right->opval.op == '-') &&
2159 tree->right->right) {
2160 // we should cast an operand instead of the result
2161 tree->right->decorated = 0;
2162 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2164 tree->right = decorateType(tree->right);
2169 /* depending on type of operator do */
2171 switch (tree->opval.op)
2173 /*------------------------------------------------------------------*/
2174 /*----------------------------*/
2176 /*----------------------------*/
2179 /* determine which is the array & which the index */
2180 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2183 ast *tempTree = tree->left;
2184 tree->left = tree->right;
2185 tree->right = tempTree;
2188 /* first check if this is a array or a pointer */
2189 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2191 werror (E_NEED_ARRAY_PTR, "[]");
2192 goto errorTreeReturn;
2195 /* check if the type of the idx */
2196 if (!IS_INTEGRAL (RTYPE (tree)))
2198 werror (E_IDX_NOT_INT);
2199 goto errorTreeReturn;
2202 /* if the left is an rvalue then error */
2205 werror (E_LVALUE_REQUIRED, "array access");
2206 goto errorTreeReturn;
2209 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2212 /*------------------------------------------------------------------*/
2213 /*----------------------------*/
2215 /*----------------------------*/
2217 /* if this is not a structure */
2218 if (!IS_STRUCT (LTYPE (tree)))
2220 werror (E_STRUCT_UNION, ".");
2221 goto errorTreeReturn;
2223 TTYPE (tree) = structElemType (LTYPE (tree),
2224 (tree->right->type == EX_VALUE ?
2225 tree->right->opval.val : NULL));
2226 TETYPE (tree) = getSpec (TTYPE (tree));
2229 /*------------------------------------------------------------------*/
2230 /*----------------------------*/
2231 /* struct/union pointer */
2232 /*----------------------------*/
2234 /* if not pointer to a structure */
2235 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2237 werror (E_PTR_REQD);
2238 goto errorTreeReturn;
2241 if (!IS_STRUCT (LTYPE (tree)->next))
2243 werror (E_STRUCT_UNION, "->");
2244 goto errorTreeReturn;
2247 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2248 (tree->right->type == EX_VALUE ?
2249 tree->right->opval.val : NULL));
2250 TETYPE (tree) = getSpec (TTYPE (tree));
2252 /* adjust the storage class */
2253 switch (DCL_TYPE(tree->left->ftype)) {
2255 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2258 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2261 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2264 SPEC_SCLS (TETYPE (tree)) = 0;
2267 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2270 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2273 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2276 SPEC_SCLS (TETYPE (tree)) = 0;
2283 /* This breaks with extern declarations, bitfields, and perhaps other */
2284 /* cases (gcse). Let's leave this optimization disabled for now and */
2285 /* ponder if there's a safe way to do this. -- EEP */
2287 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2288 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2290 /* If defined struct type at addr var
2291 then rewrite (&struct var)->member
2293 and define membertype at (addr+offsetof(struct var,member)) temp
2296 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2297 AST_SYMBOL(tree->right));
2299 sym = newSymbol(genSymName (0), 0);
2300 sym->type = TTYPE (tree);
2301 sym->etype = getSpec(sym->type);
2302 sym->lineDef = tree->lineno;
2305 SPEC_STAT (sym->etype) = 1;
2306 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2308 SPEC_ABSA(sym->etype) = 1;
2309 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2312 AST_VALUE (tree) = symbolVal(sym);
2315 tree->type = EX_VALUE;
2323 /*------------------------------------------------------------------*/
2324 /*----------------------------*/
2325 /* ++/-- operation */
2326 /*----------------------------*/
2330 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2331 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2332 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2333 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2342 /*------------------------------------------------------------------*/
2343 /*----------------------------*/
2345 /*----------------------------*/
2346 case '&': /* can be unary */
2347 /* if right is NULL then unary operation */
2348 if (tree->right) /* not an unary operation */
2351 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2353 werror (E_BITWISE_OP);
2354 werror (W_CONTINUE, "left & right types are ");
2355 printTypeChain (LTYPE (tree), stderr);
2356 fprintf (stderr, ",");
2357 printTypeChain (RTYPE (tree), stderr);
2358 fprintf (stderr, "\n");
2359 goto errorTreeReturn;
2362 /* if they are both literal */
2363 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2365 tree->type = EX_VALUE;
2366 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2367 valFromType (RETYPE (tree)), '&');
2369 tree->right = tree->left = NULL;
2370 TETYPE (tree) = tree->opval.val->etype;
2371 TTYPE (tree) = tree->opval.val->type;
2375 /* see if this is a GETHBIT operation if yes
2378 ast *otree = optimizeGetHbit (tree);
2381 return decorateType (otree);
2385 computeType (LTYPE (tree), RTYPE (tree));
2386 TETYPE (tree) = getSpec (TTYPE (tree));
2388 /* if left is a literal exchange left & right */
2389 if (IS_LITERAL (LTYPE (tree)))
2391 ast *tTree = tree->left;
2392 tree->left = tree->right;
2393 tree->right = tTree;
2396 /* if right is a literal and */
2397 /* we can find a 2nd literal in a and-tree then */
2398 /* rearrange the tree */
2399 if (IS_LITERAL (RTYPE (tree)))
2402 ast *litTree = searchLitOp (tree, &parent, "&");
2405 ast *tTree = litTree->left;
2406 litTree->left = tree->right;
2407 tree->right = tTree;
2408 /* both operands in tTree are literal now */
2409 decorateType (parent);
2413 LRVAL (tree) = RRVAL (tree) = 1;
2417 /*------------------------------------------------------------------*/
2418 /*----------------------------*/
2420 /*----------------------------*/
2421 p = newLink (DECLARATOR);
2422 /* if bit field then error */
2423 if (IS_BITVAR (tree->left->etype))
2425 werror (E_ILLEGAL_ADDR, "address of bit variable");
2426 goto errorTreeReturn;
2429 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2431 werror (E_ILLEGAL_ADDR, "address of register variable");
2432 goto errorTreeReturn;
2435 if (IS_FUNC (LTYPE (tree)))
2437 // this ought to be ignored
2438 return (tree->left);
2441 if (IS_LITERAL(LTYPE(tree)))
2443 werror (E_ILLEGAL_ADDR, "address of literal");
2444 goto errorTreeReturn;
2449 werror (E_LVALUE_REQUIRED, "address of");
2450 goto errorTreeReturn;
2453 DCL_TYPE (p) = POINTER;
2454 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2455 DCL_TYPE (p) = CPOINTER;
2456 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2457 DCL_TYPE (p) = FPOINTER;
2458 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2459 DCL_TYPE (p) = PPOINTER;
2460 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2461 DCL_TYPE (p) = IPOINTER;
2462 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2463 DCL_TYPE (p) = EEPPOINTER;
2464 else if (SPEC_OCLS(tree->left->etype))
2465 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2467 DCL_TYPE (p) = POINTER;
2469 if (IS_AST_SYM_VALUE (tree->left))
2471 AST_SYMBOL (tree->left)->addrtaken = 1;
2472 AST_SYMBOL (tree->left)->allocreq = 1;
2475 p->next = LTYPE (tree);
2477 TETYPE (tree) = getSpec (TTYPE (tree));
2482 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2483 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2485 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2486 AST_SYMBOL(tree->left->right));
2487 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2488 valueFromLit(element->offset));
2491 tree->type = EX_VALUE;
2492 tree->values.literalFromCast = 1;
2498 /*------------------------------------------------------------------*/
2499 /*----------------------------*/
2501 /*----------------------------*/
2503 /* if the rewrite succeeds then don't go any furthur */
2505 ast *wtree = optimizeRRCRLC (tree);
2507 return decorateType (wtree);
2509 wtree = optimizeSWAP (tree);
2511 return decorateType (wtree);
2516 /* if left is a literal exchange left & right */
2517 if (IS_LITERAL (LTYPE (tree)))
2519 ast *tTree = tree->left;
2520 tree->left = tree->right;
2521 tree->right = tTree;
2524 /* if right is a literal and */
2525 /* we can find a 2nd literal in a or-tree then */
2526 /* rearrange the tree */
2527 if (IS_LITERAL (RTYPE (tree)))
2530 ast *litTree = searchLitOp (tree, &parent, "|");
2533 ast *tTree = litTree->left;
2534 litTree->left = tree->right;
2535 tree->right = tTree;
2536 /* both operands in tTree are literal now */
2537 decorateType (parent);
2540 /*------------------------------------------------------------------*/
2541 /*----------------------------*/
2543 /*----------------------------*/
2545 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2547 werror (E_BITWISE_OP);
2548 werror (W_CONTINUE, "left & right types are ");
2549 printTypeChain (LTYPE (tree), stderr);
2550 fprintf (stderr, ",");
2551 printTypeChain (RTYPE (tree), stderr);
2552 fprintf (stderr, "\n");
2553 goto errorTreeReturn;
2556 /* if they are both literal then */
2557 /* rewrite the tree */
2558 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2560 tree->type = EX_VALUE;
2561 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2562 valFromType (RETYPE (tree)),
2564 tree->right = tree->left = NULL;
2565 TETYPE (tree) = tree->opval.val->etype;
2566 TTYPE (tree) = tree->opval.val->type;
2570 /* if left is a literal exchange left & right */
2571 if (IS_LITERAL (LTYPE (tree)))
2573 ast *tTree = tree->left;
2574 tree->left = tree->right;
2575 tree->right = tTree;
2578 /* if right is a literal and */
2579 /* we can find a 2nd literal in a xor-tree then */
2580 /* rearrange the tree */
2581 if (IS_LITERAL (RTYPE (tree)))
2584 ast *litTree = searchLitOp (tree, &parent, "^");
2587 ast *tTree = litTree->left;
2588 litTree->left = tree->right;
2589 tree->right = tTree;
2590 /* both operands in litTree are literal now */
2591 decorateType (parent);
2595 LRVAL (tree) = RRVAL (tree) = 1;
2596 TETYPE (tree) = getSpec (TTYPE (tree) =
2597 computeType (LTYPE (tree),
2600 /*------------------------------------------------------------------*/
2601 /*----------------------------*/
2603 /*----------------------------*/
2605 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2607 werror (E_INVALID_OP, "divide");
2608 goto errorTreeReturn;
2610 /* if they are both literal then */
2611 /* rewrite the tree */
2612 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2614 tree->type = EX_VALUE;
2615 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2616 valFromType (RETYPE (tree)));
2617 tree->right = tree->left = NULL;
2618 TETYPE (tree) = getSpec (TTYPE (tree) =
2619 tree->opval.val->type);
2623 LRVAL (tree) = RRVAL (tree) = 1;
2624 TETYPE (tree) = getSpec (TTYPE (tree) =
2625 computeType (LTYPE (tree),
2628 /* if right is a literal and */
2629 /* left is also a division by a literal then */
2630 /* rearrange the tree */
2631 if (IS_LITERAL (RTYPE (tree))
2632 /* avoid infinite loop */
2633 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2636 ast *litTree = searchLitOp (tree, &parent, "/");
2639 if (IS_LITERAL (RTYPE (litTree)))
2642 litTree->right = newNode ('*', litTree->right, tree->right);
2643 litTree->right->lineno = tree->lineno;
2645 tree->right->opval.val = constVal ("1");
2646 decorateType (parent);
2650 /* litTree->left is literal: no gcse possible.
2651 We can't call decorateType(parent), because
2652 this would cause an infinit loop. */
2653 parent->decorated = 1;
2654 decorateType (litTree);
2661 /*------------------------------------------------------------------*/
2662 /*----------------------------*/
2664 /*----------------------------*/
2666 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2668 werror (E_BITWISE_OP);
2669 werror (W_CONTINUE, "left & right types are ");
2670 printTypeChain (LTYPE (tree), stderr);
2671 fprintf (stderr, ",");
2672 printTypeChain (RTYPE (tree), stderr);
2673 fprintf (stderr, "\n");
2674 goto errorTreeReturn;
2676 /* if they are both literal then */
2677 /* rewrite the tree */
2678 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2680 tree->type = EX_VALUE;
2681 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2682 valFromType (RETYPE (tree)));
2683 tree->right = tree->left = NULL;
2684 TETYPE (tree) = getSpec (TTYPE (tree) =
2685 tree->opval.val->type);
2688 LRVAL (tree) = RRVAL (tree) = 1;
2689 TETYPE (tree) = getSpec (TTYPE (tree) =
2690 computeType (LTYPE (tree),
2694 /*------------------------------------------------------------------*/
2695 /*----------------------------*/
2696 /* address dereference */
2697 /*----------------------------*/
2698 case '*': /* can be unary : if right is null then unary operation */
2701 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2703 werror (E_PTR_REQD);
2704 goto errorTreeReturn;
2709 werror (E_LVALUE_REQUIRED, "pointer deref");
2710 goto errorTreeReturn;
2712 if (IS_ADDRESS_OF_OP(tree->left))
2714 /* replace *&obj with obj */
2715 return tree->left->left;
2717 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2718 TETYPE (tree) = getSpec (TTYPE (tree));
2719 /* adjust the storage class */
2720 switch (DCL_TYPE(tree->left->ftype)) {
2722 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2725 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2728 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2731 SPEC_SCLS (TETYPE (tree)) = 0;
2734 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2737 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2740 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2743 SPEC_SCLS (TETYPE (tree)) = 0;
2752 /*------------------------------------------------------------------*/
2753 /*----------------------------*/
2754 /* multiplication */
2755 /*----------------------------*/
2756 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2758 werror (E_INVALID_OP, "multiplication");
2759 goto errorTreeReturn;
2762 /* if they are both literal then */
2763 /* rewrite the tree */
2764 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2766 tree->type = EX_VALUE;
2767 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2768 valFromType (RETYPE (tree)));
2769 tree->right = tree->left = NULL;
2770 TETYPE (tree) = getSpec (TTYPE (tree) =
2771 tree->opval.val->type);
2775 /* if left is a literal exchange left & right */
2776 if (IS_LITERAL (LTYPE (tree)))
2778 ast *tTree = tree->left;
2779 tree->left = tree->right;
2780 tree->right = tTree;
2783 /* if right is a literal and */
2784 /* we can find a 2nd literal in a mul-tree then */
2785 /* rearrange the tree */
2786 if (IS_LITERAL (RTYPE (tree)))
2789 ast *litTree = searchLitOp (tree, &parent, "*");
2792 ast *tTree = litTree->left;
2793 litTree->left = tree->right;
2794 tree->right = tTree;
2795 /* both operands in litTree are literal now */
2796 decorateType (parent);
2800 LRVAL (tree) = RRVAL (tree) = 1;
2801 TETYPE (tree) = getSpec (TTYPE (tree) =
2802 computeType (LTYPE (tree),
2805 /* promote result to int if left & right are char
2806 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2807 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2808 SPEC_NOUN(TETYPE(tree)) = V_INT;
2813 /*------------------------------------------------------------------*/
2814 /*----------------------------*/
2815 /* unary '+' operator */
2816 /*----------------------------*/
2821 if (!IS_ARITHMETIC (LTYPE (tree)))
2823 werror (E_UNARY_OP, '+');
2824 goto errorTreeReturn;
2827 /* if left is a literal then do it */
2828 if (IS_LITERAL (LTYPE (tree)))
2830 tree->type = EX_VALUE;
2831 tree->opval.val = valFromType (LETYPE (tree));
2833 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2837 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2841 /*------------------------------------------------------------------*/
2842 /*----------------------------*/
2844 /*----------------------------*/
2846 /* this is not a unary operation */
2847 /* if both pointers then problem */
2848 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2849 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2851 werror (E_PTR_PLUS_PTR);
2852 goto errorTreeReturn;
2855 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2856 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2858 werror (E_PLUS_INVALID, "+");
2859 goto errorTreeReturn;
2862 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2863 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2865 werror (E_PLUS_INVALID, "+");
2866 goto errorTreeReturn;
2868 /* if they are both literal then */
2869 /* rewrite the tree */
2870 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2872 tree->type = EX_VALUE;
2873 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2874 valFromType (RETYPE (tree)));
2875 tree->right = tree->left = NULL;
2876 TETYPE (tree) = getSpec (TTYPE (tree) =
2877 tree->opval.val->type);
2881 /* if the right is a pointer or left is a literal
2882 xchange left & right */
2883 if (IS_ARRAY (RTYPE (tree)) ||
2884 IS_PTR (RTYPE (tree)) ||
2885 IS_LITERAL (LTYPE (tree)))
2887 ast *tTree = tree->left;
2888 tree->left = tree->right;
2889 tree->right = tTree;
2892 /* if right is a literal and */
2893 /* left is also an addition/subtraction with a literal then */
2894 /* rearrange the tree */
2895 if (IS_LITERAL (RTYPE (tree)))
2897 ast *litTree, *parent;
2898 litTree = searchLitOp (tree, &parent, "+-");
2901 if (litTree->opval.op == '+')
2904 ast *tTree = litTree->left;
2905 litTree->left = tree->right;
2906 tree->right = tree->left;
2909 else if (litTree->opval.op == '-')
2911 if (IS_LITERAL (RTYPE (litTree)))
2914 ast *tTree = litTree->left;
2915 litTree->left = tree->right;
2916 tree->right = tTree;
2921 ast *tTree = litTree->right;
2922 litTree->right = tree->right;
2923 tree->right = tTree;
2924 litTree->opval.op = '+';
2925 tree->opval.op = '-';
2928 decorateType (parent);
2932 LRVAL (tree) = RRVAL (tree) = 1;
2933 /* if the left is a pointer */
2934 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2935 TETYPE (tree) = getSpec (TTYPE (tree) =
2938 TETYPE (tree) = getSpec (TTYPE (tree) =
2939 computeType (LTYPE (tree),
2943 /*------------------------------------------------------------------*/
2944 /*----------------------------*/
2946 /*----------------------------*/
2947 case '-': /* can be unary */
2948 /* if right is null then unary */
2952 if (!IS_ARITHMETIC (LTYPE (tree)))
2954 werror (E_UNARY_OP, tree->opval.op);
2955 goto errorTreeReturn;
2958 /* if left is a literal then do it */
2959 if (IS_LITERAL (LTYPE (tree)))
2961 tree->type = EX_VALUE;
2962 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2964 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2965 SPEC_USIGN(TETYPE(tree)) = 0;
2969 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2973 /*------------------------------------------------------------------*/
2974 /*----------------------------*/
2976 /*----------------------------*/
2978 if (!(IS_PTR (LTYPE (tree)) ||
2979 IS_ARRAY (LTYPE (tree)) ||
2980 IS_ARITHMETIC (LTYPE (tree))))
2982 werror (E_PLUS_INVALID, "-");
2983 goto errorTreeReturn;
2986 if (!(IS_PTR (RTYPE (tree)) ||
2987 IS_ARRAY (RTYPE (tree)) ||
2988 IS_ARITHMETIC (RTYPE (tree))))
2990 werror (E_PLUS_INVALID, "-");
2991 goto errorTreeReturn;
2994 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2995 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2996 IS_INTEGRAL (RTYPE (tree))))
2998 werror (E_PLUS_INVALID, "-");
2999 goto errorTreeReturn;
3002 /* if they are both literal then */
3003 /* rewrite the tree */
3004 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3006 tree->type = EX_VALUE;
3007 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3008 valFromType (RETYPE (tree)));
3009 tree->right = tree->left = NULL;
3010 TETYPE (tree) = getSpec (TTYPE (tree) =
3011 tree->opval.val->type);
3015 /* if the left & right are equal then zero */
3016 if (isAstEqual (tree->left, tree->right))
3018 tree->type = EX_VALUE;
3019 tree->left = tree->right = NULL;
3020 tree->opval.val = constVal ("0");
3021 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3025 /* if both of them are pointers or arrays then */
3026 /* the result is going to be an integer */
3027 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3028 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3029 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3031 /* if only the left is a pointer */
3032 /* then result is a pointer */
3033 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3034 TETYPE (tree) = getSpec (TTYPE (tree) =
3037 TETYPE (tree) = getSpec (TTYPE (tree) =
3038 computeType (LTYPE (tree),
3041 LRVAL (tree) = RRVAL (tree) = 1;
3043 /* if right is a literal and */
3044 /* left is also an addition/subtraction with a literal then */
3045 /* rearrange the tree */
3046 if (IS_LITERAL (RTYPE (tree))
3047 /* avoid infinite loop */
3048 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3050 ast *litTree, *litParent;
3051 litTree = searchLitOp (tree, &litParent, "+-");
3054 if (litTree->opval.op == '+')
3057 litTree->right = newNode ('-', litTree->right, tree->right);
3058 litTree->right->lineno = tree->lineno;
3060 tree->right->opval.val = constVal ("0");
3062 else if (litTree->opval.op == '-')
3064 if (IS_LITERAL (RTYPE (litTree)))
3067 litTree->right = newNode ('+', tree->right, litTree->right);
3068 litTree->right->lineno = tree->lineno;
3070 tree->right->opval.val = constVal ("0");
3075 ast *tTree = litTree->right;
3076 litTree->right = tree->right;
3077 tree->right = tTree;
3080 decorateType (litParent);
3085 /*------------------------------------------------------------------*/
3086 /*----------------------------*/
3088 /*----------------------------*/
3090 /* can be only integral type */
3091 if (!IS_INTEGRAL (LTYPE (tree)))
3093 werror (E_UNARY_OP, tree->opval.op);
3094 goto errorTreeReturn;
3097 /* if left is a literal then do it */
3098 if (IS_LITERAL (LTYPE (tree)))
3100 tree->type = EX_VALUE;
3101 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3103 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3107 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3110 /*------------------------------------------------------------------*/
3111 /*----------------------------*/
3113 /*----------------------------*/
3115 /* can be pointer */
3116 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3117 !IS_PTR (LTYPE (tree)) &&
3118 !IS_ARRAY (LTYPE (tree)))
3120 werror (E_UNARY_OP, tree->opval.op);
3121 goto errorTreeReturn;
3124 /* if left is a literal then do it */
3125 if (IS_LITERAL (LTYPE (tree)))
3127 tree->type = EX_VALUE;
3128 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3130 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3134 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3137 /*------------------------------------------------------------------*/
3138 /*----------------------------*/
3140 /*----------------------------*/
3144 TTYPE (tree) = LTYPE (tree);
3145 TETYPE (tree) = LETYPE (tree);
3149 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3154 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3156 werror (E_SHIFT_OP_INVALID);
3157 werror (W_CONTINUE, "left & right types are ");
3158 printTypeChain (LTYPE (tree), stderr);
3159 fprintf (stderr, ",");
3160 printTypeChain (RTYPE (tree), stderr);
3161 fprintf (stderr, "\n");
3162 goto errorTreeReturn;
3165 /* if they are both literal then */
3166 /* rewrite the tree */
3167 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3169 tree->type = EX_VALUE;
3170 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3171 valFromType (RETYPE (tree)),
3172 (tree->opval.op == LEFT_OP ? 1 : 0));
3173 tree->right = tree->left = NULL;
3174 TETYPE (tree) = getSpec (TTYPE (tree) =
3175 tree->opval.val->type);
3179 /* if only the right side is a literal & we are
3180 shifting more than size of the left operand then zero */
3181 if (IS_LITERAL (RTYPE (tree)) &&
3182 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
3183 (getSize (LTYPE (tree)) * 8))
3185 if (tree->opval.op==LEFT_OP ||
3186 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
3187 lineno=tree->lineno;
3188 werror (W_SHIFT_CHANGED,
3189 (tree->opval.op == LEFT_OP ? "left" : "right"));
3190 tree->type = EX_VALUE;
3191 tree->left = tree->right = NULL;
3192 tree->opval.val = constVal ("0");
3193 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3197 LRVAL (tree) = RRVAL (tree) = 1;
3198 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3199 if (IS_LITERAL (TTYPE (tree)))
3200 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3203 /*------------------------------------------------------------------*/
3204 /*----------------------------*/
3206 /*----------------------------*/
3207 case CAST: /* change the type */
3208 /* cannot cast to an aggregate type */
3209 if (IS_AGGREGATE (LTYPE (tree)))
3211 werror (E_CAST_ILLEGAL);
3212 goto errorTreeReturn;
3215 /* make sure the type is complete and sane */
3216 checkTypeSanity(LETYPE(tree), "(cast)");
3219 /* if the right is a literal replace the tree */
3220 if (IS_LITERAL (RETYPE (tree))) {
3221 if (!IS_PTR (LTYPE (tree))) {
3222 tree->type = EX_VALUE;
3224 valCastLiteral (LTYPE (tree),
3225 floatFromVal (valFromType (RETYPE (tree))));
3228 TTYPE (tree) = tree->opval.val->type;
3229 tree->values.literalFromCast = 1;
3230 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3231 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3232 sym_link *rest = LTYPE(tree)->next;
3233 werror(W_LITERAL_GENERIC);
3234 TTYPE(tree) = newLink(DECLARATOR);
3235 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3236 TTYPE(tree)->next = rest;
3237 tree->left->opval.lnk = TTYPE(tree);
3240 TTYPE (tree) = LTYPE (tree);
3244 TTYPE (tree) = LTYPE (tree);
3248 #if 0 // this is already checked, now this could be explicit
3249 /* if pointer to struct then check names */
3250 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3251 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3252 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3254 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3255 SPEC_STRUCT(LETYPE(tree))->tag);
3258 if (IS_ADDRESS_OF_OP(tree->right)
3259 && IS_AST_SYM_VALUE (tree->right->left)
3260 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3262 tree->type = EX_VALUE;
3264 valCastLiteral (LTYPE (tree),
3265 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3266 TTYPE (tree) = tree->opval.val->type;
3267 TETYPE (tree) = getSpec (TTYPE (tree));
3270 tree->values.literalFromCast = 1;
3274 /* handle offsetof macro: */
3275 /* #define offsetof(TYPE, MEMBER) \ */
3276 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3277 if (IS_ADDRESS_OF_OP(tree->right)
3278 && IS_AST_OP (tree->right->left)
3279 && tree->right->left->opval.op == PTR_OP
3280 && IS_AST_OP (tree->right->left->left)
3281 && tree->right->left->left->opval.op == CAST
3282 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3284 symbol *element = getStructElement (
3285 SPEC_STRUCT (LETYPE(tree->right->left)),
3286 AST_SYMBOL(tree->right->left->right)
3290 tree->type = EX_VALUE;
3291 tree->opval.val = valCastLiteral (
3294 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3297 TTYPE (tree) = tree->opval.val->type;
3298 TETYPE (tree) = getSpec (TTYPE (tree));
3305 /* if the right is a literal replace the tree */
3306 if (IS_LITERAL (RETYPE (tree))) {
3307 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3308 /* rewrite (type *)litaddr
3310 and define type at litaddr temp
3311 (but only if type's storage class is not generic)
3313 ast *newTree = newNode ('&', NULL, NULL);
3316 TTYPE (newTree) = LTYPE (tree);
3317 TETYPE (newTree) = getSpec(LTYPE (tree));
3319 /* define a global symbol at the casted address*/
3320 sym = newSymbol(genSymName (0), 0);
3321 sym->type = LTYPE (tree)->next;
3323 sym->type = newLink (V_VOID);
3324 sym->etype = getSpec(sym->type);
3325 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3326 sym->lineDef = tree->lineno;
3329 SPEC_STAT (sym->etype) = 1;
3330 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3331 SPEC_ABSA(sym->etype) = 1;
3332 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3335 newTree->left = newAst_VALUE(symbolVal(sym));
3336 newTree->left->lineno = tree->lineno;
3337 LTYPE (newTree) = sym->type;
3338 LETYPE (newTree) = sym->etype;
3339 LLVAL (newTree) = 1;
3340 LRVAL (newTree) = 0;
3341 TLVAL (newTree) = 1;
3344 if (!IS_PTR (LTYPE (tree))) {
3345 tree->type = EX_VALUE;
3347 valCastLiteral (LTYPE (tree),
3348 floatFromVal (valFromType (RTYPE (tree))));
3349 TTYPE (tree) = tree->opval.val->type;
3352 tree->values.literalFromCast = 1;
3353 TETYPE (tree) = getSpec (TTYPE (tree));
3357 TTYPE (tree) = LTYPE (tree);
3361 TETYPE (tree) = getSpec (TTYPE (tree));
3365 /*------------------------------------------------------------------*/
3366 /*----------------------------*/
3367 /* logical &&, || */
3368 /*----------------------------*/
3371 /* each must me arithmetic type or be a pointer */
3372 if (!IS_PTR (LTYPE (tree)) &&
3373 !IS_ARRAY (LTYPE (tree)) &&
3374 !IS_INTEGRAL (LTYPE (tree)))
3376 werror (E_COMPARE_OP);
3377 goto errorTreeReturn;
3380 if (!IS_PTR (RTYPE (tree)) &&
3381 !IS_ARRAY (RTYPE (tree)) &&
3382 !IS_INTEGRAL (RTYPE (tree)))
3384 werror (E_COMPARE_OP);
3385 goto errorTreeReturn;
3387 /* if they are both literal then */
3388 /* rewrite the tree */
3389 if (IS_LITERAL (RTYPE (tree)) &&
3390 IS_LITERAL (LTYPE (tree)))
3392 tree->type = EX_VALUE;
3393 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3394 valFromType (RTYPE (tree)),
3396 tree->right = tree->left = NULL;
3397 TETYPE (tree) = getSpec (TTYPE (tree) =
3398 tree->opval.val->type);
3401 LRVAL (tree) = RRVAL (tree) = 1;
3402 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3405 /*------------------------------------------------------------------*/
3406 /*----------------------------*/
3407 /* comparison operators */
3408 /*----------------------------*/
3416 ast *lt = optimizeCompare (tree);
3422 /* if they are pointers they must be castable */
3423 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3425 if (tree->opval.op==EQ_OP &&
3426 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3427 // we cannot cast a gptr to a !gptr: switch the leaves
3428 struct ast *s=tree->left;
3429 tree->left=tree->right;
3432 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3434 werror (E_COMPARE_OP);
3435 fprintf (stderr, "comparing type ");
3436 printTypeChain (LTYPE (tree), stderr);
3437 fprintf (stderr, "to type ");
3438 printTypeChain (RTYPE (tree), stderr);
3439 fprintf (stderr, "\n");
3440 goto errorTreeReturn;
3443 /* else they should be promotable to one another */
3446 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3447 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3449 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3451 werror (E_COMPARE_OP);
3452 fprintf (stderr, "comparing type ");
3453 printTypeChain (LTYPE (tree), stderr);
3454 fprintf (stderr, "to type ");
3455 printTypeChain (RTYPE (tree), stderr);
3456 fprintf (stderr, "\n");
3457 goto errorTreeReturn;
3460 /* if unsigned value < 0 then always false */
3461 /* if (unsigned value) > 0 then (unsigned value) */
3462 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3463 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
3465 if (tree->opval.op == '<') {
3468 if (tree->opval.op == '>') {
3472 /* if they are both literal then */
3473 /* rewrite the tree */
3474 if (IS_LITERAL (RTYPE (tree)) &&
3475 IS_LITERAL (LTYPE (tree)))
3477 tree->type = EX_VALUE;
3478 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3479 valFromType (RETYPE (tree)),
3481 tree->right = tree->left = NULL;
3482 TETYPE (tree) = getSpec (TTYPE (tree) =
3483 tree->opval.val->type);
3486 LRVAL (tree) = RRVAL (tree) = 1;
3487 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3490 /*------------------------------------------------------------------*/
3491 /*----------------------------*/
3493 /*----------------------------*/
3494 case SIZEOF: /* evaluate wihout code generation */
3495 /* change the type to a integer */
3496 tree->type = EX_VALUE;
3497 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3498 tree->opval.val = constVal (buffer);
3499 tree->right = tree->left = NULL;
3500 TETYPE (tree) = getSpec (TTYPE (tree) =
3501 tree->opval.val->type);
3504 /*------------------------------------------------------------------*/
3505 /*----------------------------*/
3507 /*----------------------------*/
3509 /* return typeof enum value */
3510 tree->type = EX_VALUE;
3513 if (IS_SPEC(tree->right->ftype)) {
3514 switch (SPEC_NOUN(tree->right->ftype)) {
3516 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3517 else typeofv = TYPEOF_INT;
3520 typeofv = TYPEOF_FLOAT;
3523 typeofv = TYPEOF_CHAR;
3526 typeofv = TYPEOF_VOID;
3529 typeofv = TYPEOF_STRUCT;
3532 typeofv = TYPEOF_BITFIELD;
3535 typeofv = TYPEOF_BIT;
3538 typeofv = TYPEOF_SBIT;
3544 switch (DCL_TYPE(tree->right->ftype)) {
3546 typeofv = TYPEOF_POINTER;
3549 typeofv = TYPEOF_FPOINTER;
3552 typeofv = TYPEOF_CPOINTER;
3555 typeofv = TYPEOF_GPOINTER;
3558 typeofv = TYPEOF_PPOINTER;
3561 typeofv = TYPEOF_IPOINTER;
3564 typeofv = TYPEOF_ARRAY;
3567 typeofv = TYPEOF_FUNCTION;
3573 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3574 tree->opval.val = constVal (buffer);
3575 tree->right = tree->left = NULL;
3576 TETYPE (tree) = getSpec (TTYPE (tree) =
3577 tree->opval.val->type);
3580 /*------------------------------------------------------------------*/
3581 /*----------------------------*/
3582 /* conditional operator '?' */
3583 /*----------------------------*/
3585 /* the type is value of the colon operator (on the right) */
3586 assert(IS_COLON_OP(tree->right));
3587 /* if already known then replace the tree : optimizer will do it
3588 but faster to do it here */
3589 if (IS_LITERAL (LTYPE(tree))) {
3590 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3591 return decorateType(tree->right->left) ;
3593 return decorateType(tree->right->right) ;
3596 tree->right = decorateType(tree->right);
3597 TTYPE (tree) = RTYPE(tree);
3598 TETYPE (tree) = getSpec (TTYPE (tree));
3603 /* if they don't match we have a problem */
3604 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3606 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3607 goto errorTreeReturn;
3610 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3611 TETYPE (tree) = getSpec (TTYPE (tree));
3615 #if 0 // assignment operators are converted by the parser
3616 /*------------------------------------------------------------------*/
3617 /*----------------------------*/
3618 /* assignment operators */
3619 /*----------------------------*/
3622 /* for these it must be both must be integral */
3623 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3624 !IS_ARITHMETIC (RTYPE (tree)))
3626 werror (E_OPS_INTEGRAL);
3627 goto errorTreeReturn;
3630 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3632 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3633 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3637 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3638 goto errorTreeReturn;
3649 /* for these it must be both must be integral */
3650 if (!IS_INTEGRAL (LTYPE (tree)) ||
3651 !IS_INTEGRAL (RTYPE (tree)))
3653 werror (E_OPS_INTEGRAL);
3654 goto errorTreeReturn;
3657 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3659 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3660 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3664 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3665 goto errorTreeReturn;
3671 /*------------------------------------------------------------------*/
3672 /*----------------------------*/
3674 /*----------------------------*/
3676 if (!(IS_PTR (LTYPE (tree)) ||
3677 IS_ARITHMETIC (LTYPE (tree))))
3679 werror (E_PLUS_INVALID, "-=");
3680 goto errorTreeReturn;
3683 if (!(IS_PTR (RTYPE (tree)) ||
3684 IS_ARITHMETIC (RTYPE (tree))))
3686 werror (E_PLUS_INVALID, "-=");
3687 goto errorTreeReturn;
3690 TETYPE (tree) = getSpec (TTYPE (tree) =
3691 computeType (LTYPE (tree),
3694 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3695 werror (E_CODE_WRITE, "-=");
3699 werror (E_LVALUE_REQUIRED, "-=");
3700 goto errorTreeReturn;
3706 /*------------------------------------------------------------------*/
3707 /*----------------------------*/
3709 /*----------------------------*/
3711 /* this is not a unary operation */
3712 /* if both pointers then problem */
3713 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3715 werror (E_PTR_PLUS_PTR);
3716 goto errorTreeReturn;
3719 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3721 werror (E_PLUS_INVALID, "+=");
3722 goto errorTreeReturn;
3725 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3727 werror (E_PLUS_INVALID, "+=");
3728 goto errorTreeReturn;
3731 TETYPE (tree) = getSpec (TTYPE (tree) =
3732 computeType (LTYPE (tree),
3735 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3736 werror (E_CODE_WRITE, "+=");
3740 werror (E_LVALUE_REQUIRED, "+=");
3741 goto errorTreeReturn;
3744 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3745 tree->opval.op = '=';
3750 /*------------------------------------------------------------------*/
3751 /*----------------------------*/
3752 /* straight assignemnt */
3753 /*----------------------------*/
3755 /* cannot be an aggregate */
3756 if (IS_AGGREGATE (LTYPE (tree)))
3758 werror (E_AGGR_ASSIGN);
3759 goto errorTreeReturn;
3762 /* they should either match or be castable */
3763 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3765 werror (E_TYPE_MISMATCH, "assignment", " ");
3766 printFromToType(RTYPE(tree),LTYPE(tree));
3769 /* if the left side of the tree is of type void
3770 then report error */
3771 if (IS_VOID (LTYPE (tree)))
3773 werror (E_CAST_ZERO);
3774 printFromToType(RTYPE(tree), LTYPE(tree));
3777 TETYPE (tree) = getSpec (TTYPE (tree) =
3781 if (!tree->initMode ) {
3782 if (IS_CONSTANT(LTYPE(tree)))
3783 werror (E_CODE_WRITE, "=");
3787 werror (E_LVALUE_REQUIRED, "=");
3788 goto errorTreeReturn;
3793 /*------------------------------------------------------------------*/
3794 /*----------------------------*/
3795 /* comma operator */
3796 /*----------------------------*/
3798 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3801 /*------------------------------------------------------------------*/
3802 /*----------------------------*/
3804 /*----------------------------*/
3808 if (processParms (tree->left,
3809 FUNC_ARGS(tree->left->ftype),
3810 tree->right, &parmNumber, TRUE)) {
3811 goto errorTreeReturn;
3814 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3815 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3817 reverseParms (tree->right);
3820 if (IS_CODEPTR(LTYPE(tree))) {
3821 TTYPE(tree) = LTYPE(tree)->next->next;
3823 TTYPE(tree) = LTYPE(tree)->next;
3825 TETYPE (tree) = getSpec (TTYPE (tree));
3828 /*------------------------------------------------------------------*/
3829 /*----------------------------*/
3830 /* return statement */
3831 /*----------------------------*/
3836 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3838 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
3839 printFromToType (RTYPE(tree), currFunc->type->next);
3840 goto errorTreeReturn;
3843 if (IS_VOID (currFunc->type->next)
3845 !IS_VOID (RTYPE (tree)))
3847 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
3848 goto errorTreeReturn;
3851 /* if there is going to be a casing required then add it */
3852 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3855 decorateType (newNode (CAST,
3856 newAst_LINK (copyLinkChain (currFunc->type->next)),
3865 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3867 werror (W_VOID_FUNC, currFunc->name);
3868 goto errorTreeReturn;
3871 TTYPE (tree) = TETYPE (tree) = NULL;
3874 /*------------------------------------------------------------------*/
3875 /*----------------------------*/
3876 /* switch statement */
3877 /*----------------------------*/
3879 /* the switch value must be an integer */
3880 if (!IS_INTEGRAL (LTYPE (tree)))
3882 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
3883 goto errorTreeReturn;
3886 TTYPE (tree) = TETYPE (tree) = NULL;
3889 /*------------------------------------------------------------------*/
3890 /*----------------------------*/
3892 /*----------------------------*/
3894 tree->left = backPatchLabels (tree->left,
3897 TTYPE (tree) = TETYPE (tree) = NULL;
3900 /*------------------------------------------------------------------*/
3901 /*----------------------------*/
3903 /*----------------------------*/
3906 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3907 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3908 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3910 /* if the for loop is reversible then
3911 reverse it otherwise do what we normally
3917 if (isLoopReversible (tree, &sym, &init, &end))
3918 return reverseLoop (tree, sym, init, end);
3920 return decorateType (createFor (AST_FOR (tree, trueLabel),
3921 AST_FOR (tree, continueLabel),
3922 AST_FOR (tree, falseLabel),
3923 AST_FOR (tree, condLabel),
3924 AST_FOR (tree, initExpr),
3925 AST_FOR (tree, condExpr),
3926 AST_FOR (tree, loopExpr),
3930 TTYPE (tree) = TETYPE (tree) = NULL;
3934 /* some error found this tree will be killed */
3936 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3937 tree->opval.op = NULLOP;
3943 /*-----------------------------------------------------------------*/
3944 /* sizeofOp - processes size of operation */
3945 /*-----------------------------------------------------------------*/
3947 sizeofOp (sym_link * type)
3951 /* make sure the type is complete and sane */
3952 checkTypeSanity(type, "(sizeof)");
3954 /* get the size and convert it to character */
3955 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3957 /* now convert into value */
3958 return constVal (buff);
3962 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3963 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3964 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3965 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3966 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3967 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3968 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3970 /*-----------------------------------------------------------------*/
3971 /* backPatchLabels - change and or not operators to flow control */
3972 /*-----------------------------------------------------------------*/
3974 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3980 if (!(IS_ANDORNOT (tree)))
3983 /* if this an and */
3986 static int localLbl = 0;
3989 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3990 localLabel = newSymbol (buffer, NestLevel);
3992 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3994 /* if left is already a IFX then just change the if true label in that */
3995 if (!IS_IFX (tree->left))
3996 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3998 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3999 /* right is a IFX then just join */
4000 if (IS_IFX (tree->right))
4001 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4003 tree->right = createLabel (localLabel, tree->right);
4004 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4006 return newNode (NULLOP, tree->left, tree->right);
4009 /* if this is an or operation */
4012 static int localLbl = 0;
4015 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4016 localLabel = newSymbol (buffer, NestLevel);
4018 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4020 /* if left is already a IFX then just change the if true label in that */
4021 if (!IS_IFX (tree->left))
4022 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4024 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4025 /* right is a IFX then just join */
4026 if (IS_IFX (tree->right))
4027 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4029 tree->right = createLabel (localLabel, tree->right);
4030 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4032 return newNode (NULLOP, tree->left, tree->right);
4038 int wasnot = IS_NOT (tree->left);
4039 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4041 /* if the left is already a IFX */
4042 if (!IS_IFX (tree->left))
4043 tree->left = newNode (IFX, tree->left, NULL);
4047 tree->left->trueLabel = trueLabel;
4048 tree->left->falseLabel = falseLabel;
4052 tree->left->trueLabel = falseLabel;
4053 tree->left->falseLabel = trueLabel;
4060 tree->trueLabel = trueLabel;
4061 tree->falseLabel = falseLabel;
4068 /*-----------------------------------------------------------------*/
4069 /* createBlock - create expression tree for block */
4070 /*-----------------------------------------------------------------*/
4072 createBlock (symbol * decl, ast * body)
4076 /* if the block has nothing */
4080 ex = newNode (BLOCK, NULL, body);
4081 ex->values.sym = decl;
4083 ex->right = ex->right;
4089 /*-----------------------------------------------------------------*/
4090 /* createLabel - creates the expression tree for labels */
4091 /*-----------------------------------------------------------------*/
4093 createLabel (symbol * label, ast * stmnt)
4096 char name[SDCC_NAME_MAX + 1];
4099 /* must create fresh symbol if the symbol name */
4100 /* exists in the symbol table, since there can */
4101 /* be a variable with the same name as the labl */
4102 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4103 (csym->level == label->level))
4104 label = newSymbol (label->name, label->level);
4106 /* change the name before putting it in add _ */
4107 SNPRINTF(name, sizeof(name), "%s", label->name);
4109 /* put the label in the LabelSymbol table */
4110 /* but first check if a label of the same */
4112 if ((csym = findSym (LabelTab, NULL, name)))
4113 werror (E_DUPLICATE_LABEL, label->name);
4115 addSym (LabelTab, label, name, label->level, 0, 0);
4118 label->key = labelKey++;
4119 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4125 /*-----------------------------------------------------------------*/
4126 /* createCase - generates the parsetree for a case statement */
4127 /*-----------------------------------------------------------------*/
4129 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4131 char caseLbl[SDCC_NAME_MAX + 1];
4135 /* if the switch statement does not exist */
4136 /* then case is out of context */
4139 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4143 caseVal = decorateType (resolveSymbols (caseVal));
4144 /* if not a constant then error */
4145 if (!IS_LITERAL (caseVal->ftype))
4147 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4151 /* if not a integer than error */
4152 if (!IS_INTEGRAL (caseVal->ftype))
4154 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4158 /* find the end of the switch values chain */
4159 if (!(val = swStat->values.switchVals.swVals))
4160 swStat->values.switchVals.swVals = caseVal->opval.val;
4163 /* also order the cases according to value */
4165 int cVal = (int) floatFromVal (caseVal->opval.val);
4166 while (val && (int) floatFromVal (val) < cVal)
4172 /* if we reached the end then */
4175 pval->next = caseVal->opval.val;
4177 else if ((int) floatFromVal (val) == cVal)
4179 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4185 /* we found a value greater than */
4186 /* the current value we must add this */
4187 /* before the value */
4188 caseVal->opval.val->next = val;
4190 /* if this was the first in chain */
4191 if (swStat->values.switchVals.swVals == val)
4192 swStat->values.switchVals.swVals =
4195 pval->next = caseVal->opval.val;
4200 /* create the case label */
4201 SNPRINTF(caseLbl, sizeof(caseLbl),
4203 swStat->values.switchVals.swNum,
4204 (int) floatFromVal (caseVal->opval.val));
4206 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4211 /*-----------------------------------------------------------------*/
4212 /* createDefault - creates the parse tree for the default statement */
4213 /*-----------------------------------------------------------------*/
4215 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4217 char defLbl[SDCC_NAME_MAX + 1];
4219 /* if the switch statement does not exist */
4220 /* then case is out of context */
4223 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4227 if (swStat->values.switchVals.swDefault)
4229 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4234 /* turn on the default flag */
4235 swStat->values.switchVals.swDefault = 1;
4237 /* create the label */
4238 SNPRINTF (defLbl, sizeof(defLbl),
4239 "_default_%d", swStat->values.switchVals.swNum);
4240 return createLabel (newSymbol (defLbl, 0), stmnt);
4243 /*-----------------------------------------------------------------*/
4244 /* createIf - creates the parsetree for the if statement */
4245 /*-----------------------------------------------------------------*/
4247 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4249 static int Lblnum = 0;
4251 symbol *ifTrue, *ifFalse, *ifEnd;
4253 /* if neither exists */
4254 if (!elseBody && !ifBody) {
4255 // if there are no side effects (i++, j() etc)
4256 if (!hasSEFcalls(condAst)) {
4261 /* create the labels */
4262 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4263 ifFalse = newSymbol (buffer, NestLevel);
4264 /* if no else body then end == false */
4269 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4270 ifEnd = newSymbol (buffer, NestLevel);
4273 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4274 ifTrue = newSymbol (buffer, NestLevel);
4278 /* attach the ifTrue label to the top of it body */
4279 ifBody = createLabel (ifTrue, ifBody);
4280 /* attach a goto end to the ifBody if else is present */
4283 ifBody = newNode (NULLOP, ifBody,
4285 newAst_VALUE (symbolVal (ifEnd)),
4287 /* put the elseLabel on the else body */
4288 elseBody = createLabel (ifFalse, elseBody);
4289 /* out the end at the end of the body */
4290 elseBody = newNode (NULLOP,
4292 createLabel (ifEnd, NULL));
4296 ifBody = newNode (NULLOP, ifBody,
4297 createLabel (ifFalse, NULL));
4299 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4300 if (IS_IFX (condAst))
4303 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4305 return newNode (NULLOP, ifTree,
4306 newNode (NULLOP, ifBody, elseBody));
4310 /*-----------------------------------------------------------------*/
4311 /* createDo - creates parse tree for do */
4314 /* _docontinue_n: */
4315 /* condition_expression +-> trueLabel -> _dobody_n */
4317 /* +-> falseLabel-> _dobreak_n */
4319 /*-----------------------------------------------------------------*/
4321 createDo (symbol * trueLabel, symbol * continueLabel,
4322 symbol * falseLabel, ast * condAst, ast * doBody)
4327 /* if the body does not exist then it is simple */
4330 condAst = backPatchLabels (condAst, continueLabel, NULL);
4331 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4332 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4333 doTree->trueLabel = continueLabel;
4334 doTree->falseLabel = NULL;
4338 /* otherwise we have a body */
4339 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4341 /* attach the body label to the top */
4342 doBody = createLabel (trueLabel, doBody);
4343 /* attach the continue label to end of body */
4344 doBody = newNode (NULLOP, doBody,
4345 createLabel (continueLabel, NULL));
4347 /* now put the break label at the end */
4348 if (IS_IFX (condAst))
4351 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4353 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4355 /* putting it together */
4356 return newNode (NULLOP, doBody, doTree);
4359 /*-----------------------------------------------------------------*/
4360 /* createFor - creates parse tree for 'for' statement */
4363 /* condExpr +-> trueLabel -> _forbody_n */
4365 /* +-> falseLabel-> _forbreak_n */
4368 /* _forcontinue_n: */
4370 /* goto _forcond_n ; */
4372 /*-----------------------------------------------------------------*/
4374 createFor (symbol * trueLabel, symbol * continueLabel,
4375 symbol * falseLabel, symbol * condLabel,
4376 ast * initExpr, ast * condExpr, ast * loopExpr,
4381 /* if loopexpression not present then we can generate it */
4382 /* the same way as a while */
4384 return newNode (NULLOP, initExpr,
4385 createWhile (trueLabel, continueLabel,
4386 falseLabel, condExpr, forBody));
4387 /* vanilla for statement */
4388 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4390 if (condExpr && !IS_IFX (condExpr))
4391 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4394 /* attach condition label to condition */
4395 condExpr = createLabel (condLabel, condExpr);
4397 /* attach body label to body */
4398 forBody = createLabel (trueLabel, forBody);
4400 /* attach continue to forLoop expression & attach */
4401 /* goto the forcond @ and of loopExpression */
4402 loopExpr = createLabel (continueLabel,
4406 newAst_VALUE (symbolVal (condLabel)),
4408 /* now start putting them together */
4409 forTree = newNode (NULLOP, initExpr, condExpr);
4410 forTree = newNode (NULLOP, forTree, forBody);
4411 forTree = newNode (NULLOP, forTree, loopExpr);
4412 /* finally add the break label */
4413 forTree = newNode (NULLOP, forTree,
4414 createLabel (falseLabel, NULL));
4418 /*-----------------------------------------------------------------*/
4419 /* createWhile - creates parse tree for while statement */
4420 /* the while statement will be created as follows */
4422 /* _while_continue_n: */
4423 /* condition_expression +-> trueLabel -> _while_boby_n */
4425 /* +-> falseLabel -> _while_break_n */
4426 /* _while_body_n: */
4428 /* goto _while_continue_n */
4429 /* _while_break_n: */
4430 /*-----------------------------------------------------------------*/
4432 createWhile (symbol * trueLabel, symbol * continueLabel,
4433 symbol * falseLabel, ast * condExpr, ast * whileBody)
4437 /* put the continue label */
4438 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4439 condExpr = createLabel (continueLabel, condExpr);
4440 condExpr->lineno = 0;
4442 /* put the body label in front of the body */
4443 whileBody = createLabel (trueLabel, whileBody);
4444 whileBody->lineno = 0;
4445 /* put a jump to continue at the end of the body */
4446 /* and put break label at the end of the body */
4447 whileBody = newNode (NULLOP,
4450 newAst_VALUE (symbolVal (continueLabel)),
4451 createLabel (falseLabel, NULL)));
4453 /* put it all together */
4454 if (IS_IFX (condExpr))
4455 whileTree = condExpr;
4458 whileTree = newNode (IFX, condExpr, NULL);
4459 /* put the true & false labels in place */
4460 whileTree->trueLabel = trueLabel;
4461 whileTree->falseLabel = falseLabel;
4464 return newNode (NULLOP, whileTree, whileBody);
4467 /*-----------------------------------------------------------------*/
4468 /* optimizeGetHbit - get highest order bit of the expression */
4469 /*-----------------------------------------------------------------*/
4471 optimizeGetHbit (ast * tree)
4474 /* if this is not a bit and */
4475 if (!IS_BITAND (tree))
4478 /* will look for tree of the form
4479 ( expr >> ((sizeof expr) -1) ) & 1 */
4480 if (!IS_AST_LIT_VALUE (tree->right))
4483 if (AST_LIT_VALUE (tree->right) != 1)
4486 if (!IS_RIGHT_OP (tree->left))
4489 if (!IS_AST_LIT_VALUE (tree->left->right))
4492 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4493 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4496 /* make sure the port supports GETHBIT */
4497 if (port->hasExtBitOp
4498 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4501 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4505 /*-----------------------------------------------------------------*/
4506 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4507 /*-----------------------------------------------------------------*/
4509 optimizeRRCRLC (ast * root)
4511 /* will look for trees of the form
4512 (?expr << 1) | (?expr >> 7) or
4513 (?expr >> 7) | (?expr << 1) will make that
4514 into a RLC : operation ..
4516 (?expr >> 1) | (?expr << 7) or
4517 (?expr << 7) | (?expr >> 1) will make that
4518 into a RRC operation
4519 note : by 7 I mean (number of bits required to hold the
4521 /* if the root operations is not a | operation the not */
4522 if (!IS_BITOR (root))
4525 /* I have to think of a better way to match patterns this sucks */
4526 /* that aside let start looking for the first case : I use a the
4527 negative check a lot to improve the efficiency */
4528 /* (?expr << 1) | (?expr >> 7) */
4529 if (IS_LEFT_OP (root->left) &&
4530 IS_RIGHT_OP (root->right))
4533 if (!SPEC_USIGN (TETYPE (root->left->left)))
4536 if (!IS_AST_LIT_VALUE (root->left->right) ||
4537 !IS_AST_LIT_VALUE (root->right->right))
4540 /* make sure it is the same expression */
4541 if (!isAstEqual (root->left->left,
4545 if (AST_LIT_VALUE (root->left->right) != 1)
4548 if (AST_LIT_VALUE (root->right->right) !=
4549 (getSize (TTYPE (root->left->left)) * 8 - 1))
4552 /* make sure the port supports RLC */
4553 if (port->hasExtBitOp
4554 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4557 /* whew got the first case : create the AST */
4558 return newNode (RLC, root->left->left, NULL);
4562 /* check for second case */
4563 /* (?expr >> 7) | (?expr << 1) */
4564 if (IS_LEFT_OP (root->right) &&
4565 IS_RIGHT_OP (root->left))
4568 if (!SPEC_USIGN (TETYPE (root->left->left)))
4571 if (!IS_AST_LIT_VALUE (root->left->right) ||
4572 !IS_AST_LIT_VALUE (root->right->right))
4575 /* make sure it is the same symbol */
4576 if (!isAstEqual (root->left->left,
4580 if (AST_LIT_VALUE (root->right->right) != 1)
4583 if (AST_LIT_VALUE (root->left->right) !=
4584 (getSize (TTYPE (root->left->left)) * 8 - 1))
4587 /* make sure the port supports RLC */
4588 if (port->hasExtBitOp
4589 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4592 /* whew got the first case : create the AST */
4593 return newNode (RLC, root->left->left, NULL);
4598 /* third case for RRC */
4599 /* (?symbol >> 1) | (?symbol << 7) */
4600 if (IS_LEFT_OP (root->right) &&
4601 IS_RIGHT_OP (root->left))
4604 if (!SPEC_USIGN (TETYPE (root->left->left)))
4607 if (!IS_AST_LIT_VALUE (root->left->right) ||
4608 !IS_AST_LIT_VALUE (root->right->right))
4611 /* make sure it is the same symbol */
4612 if (!isAstEqual (root->left->left,
4616 if (AST_LIT_VALUE (root->left->right) != 1)
4619 if (AST_LIT_VALUE (root->right->right) !=
4620 (getSize (TTYPE (root->left->left)) * 8 - 1))
4623 /* make sure the port supports RRC */
4624 if (port->hasExtBitOp
4625 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4628 /* whew got the first case : create the AST */
4629 return newNode (RRC, root->left->left, NULL);
4633 /* fourth and last case for now */
4634 /* (?symbol << 7) | (?symbol >> 1) */
4635 if (IS_RIGHT_OP (root->right) &&
4636 IS_LEFT_OP (root->left))
4639 if (!SPEC_USIGN (TETYPE (root->left->left)))
4642 if (!IS_AST_LIT_VALUE (root->left->right) ||
4643 !IS_AST_LIT_VALUE (root->right->right))
4646 /* make sure it is the same symbol */
4647 if (!isAstEqual (root->left->left,
4651 if (AST_LIT_VALUE (root->right->right) != 1)
4654 if (AST_LIT_VALUE (root->left->right) !=
4655 (getSize (TTYPE (root->left->left)) * 8 - 1))
4658 /* make sure the port supports RRC */
4659 if (port->hasExtBitOp
4660 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4663 /* whew got the first case : create the AST */
4664 return newNode (RRC, root->left->left, NULL);
4668 /* not found return root */
4672 /*-----------------------------------------------------------------*/
4673 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4674 /*-----------------------------------------------------------------*/
4676 optimizeSWAP (ast * root)
4678 /* will look for trees of the form
4679 (?expr << 4) | (?expr >> 4) or
4680 (?expr >> 4) | (?expr << 4) will make that
4681 into a SWAP : operation ..
4682 note : by 4 I mean (number of bits required to hold the
4684 /* if the root operations is not a | operation the not */
4685 if (!IS_BITOR (root))
4688 /* (?expr << 4) | (?expr >> 4) */
4689 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4690 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4693 if (!SPEC_USIGN (TETYPE (root->left->left)))
4696 if (!IS_AST_LIT_VALUE (root->left->right) ||
4697 !IS_AST_LIT_VALUE (root->right->right))
4700 /* make sure it is the same expression */
4701 if (!isAstEqual (root->left->left,
4705 if (AST_LIT_VALUE (root->left->right) !=
4706 (getSize (TTYPE (root->left->left)) * 4))
4709 if (AST_LIT_VALUE (root->right->right) !=
4710 (getSize (TTYPE (root->left->left)) * 4))
4713 /* make sure the port supports SWAP */
4714 if (port->hasExtBitOp
4715 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4718 /* found it : create the AST */
4719 return newNode (SWAP, root->left->left, NULL);
4723 /* not found return root */
4727 /*-----------------------------------------------------------------*/
4728 /* optimizeCompare - otimizes compares for bit variables */
4729 /*-----------------------------------------------------------------*/
4731 optimizeCompare (ast * root)
4733 ast *optExpr = NULL;
4736 unsigned int litValue;
4738 /* if nothing then return nothing */
4742 /* if not a compare op then do leaves */
4743 if (!IS_COMPARE_OP (root))
4745 root->left = optimizeCompare (root->left);
4746 root->right = optimizeCompare (root->right);
4750 /* if left & right are the same then depending
4751 of the operation do */
4752 if (isAstEqual (root->left, root->right))
4754 switch (root->opval.op)
4759 optExpr = newAst_VALUE (constVal ("0"));
4764 optExpr = newAst_VALUE (constVal ("1"));
4768 return decorateType (optExpr);
4771 vleft = (root->left->type == EX_VALUE ?
4772 root->left->opval.val : NULL);
4774 vright = (root->right->type == EX_VALUE ?
4775 root->right->opval.val : NULL);
4777 /* if left is a BITVAR in BITSPACE */
4778 /* and right is a LITERAL then opt- */
4779 /* imize else do nothing */
4780 if (vleft && vright &&
4781 IS_BITVAR (vleft->etype) &&
4782 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4783 IS_LITERAL (vright->etype))
4786 /* if right side > 1 then comparison may never succeed */
4787 if ((litValue = (int) floatFromVal (vright)) > 1)
4789 werror (W_BAD_COMPARE);
4795 switch (root->opval.op)
4797 case '>': /* bit value greater than 1 cannot be */
4798 werror (W_BAD_COMPARE);
4802 case '<': /* bit value < 1 means 0 */
4804 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4807 case LE_OP: /* bit value <= 1 means no check */
4808 optExpr = newAst_VALUE (vright);
4811 case GE_OP: /* bit value >= 1 means only check for = */
4813 optExpr = newAst_VALUE (vleft);
4818 { /* literal is zero */
4819 switch (root->opval.op)
4821 case '<': /* bit value < 0 cannot be */
4822 werror (W_BAD_COMPARE);
4826 case '>': /* bit value > 0 means 1 */
4828 optExpr = newAst_VALUE (vleft);
4831 case LE_OP: /* bit value <= 0 means no check */
4832 case GE_OP: /* bit value >= 0 means no check */
4833 werror (W_BAD_COMPARE);
4837 case EQ_OP: /* bit == 0 means ! of bit */
4838 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4842 return decorateType (resolveSymbols (optExpr));
4843 } /* end-of-if of BITVAR */
4848 /*-----------------------------------------------------------------*/
4849 /* addSymToBlock : adds the symbol to the first block we find */
4850 /*-----------------------------------------------------------------*/
4852 addSymToBlock (symbol * sym, ast * tree)
4854 /* reached end of tree or a leaf */
4855 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4859 if (IS_AST_OP (tree) &&
4860 tree->opval.op == BLOCK)
4863 symbol *lsym = copySymbol (sym);
4865 lsym->next = AST_VALUES (tree, sym);
4866 AST_VALUES (tree, sym) = lsym;
4870 addSymToBlock (sym, tree->left);
4871 addSymToBlock (sym, tree->right);
4874 /*-----------------------------------------------------------------*/
4875 /* processRegParms - do processing for register parameters */
4876 /*-----------------------------------------------------------------*/
4878 processRegParms (value * args, ast * body)
4882 if (IS_REGPARM (args->etype))
4883 addSymToBlock (args->sym, body);
4888 /*-----------------------------------------------------------------*/
4889 /* resetParmKey - resets the operandkeys for the symbols */
4890 /*-----------------------------------------------------------------*/
4891 DEFSETFUNC (resetParmKey)
4902 /*-----------------------------------------------------------------*/
4903 /* createFunction - This is the key node that calls the iCode for */
4904 /* generating the code for a function. Note code */
4905 /* is generated function by function, later when */
4906 /* add inter-procedural analysis this will change */
4907 /*-----------------------------------------------------------------*/
4909 createFunction (symbol * name, ast * body)
4915 iCode *piCode = NULL;
4917 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4918 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4920 /* if check function return 0 then some problem */
4921 if (checkFunction (name, NULL) == 0)
4924 /* create a dummy block if none exists */
4926 body = newNode (BLOCK, NULL, NULL);
4930 /* check if the function name already in the symbol table */
4931 if ((csym = findSym (SymbolTab, NULL, name->name)))
4934 /* special case for compiler defined functions
4935 we need to add the name to the publics list : this
4936 actually means we are now compiling the compiler
4940 addSet (&publics, name);
4946 allocVariables (name);
4948 name->lastLine = mylineno;
4951 /* set the stack pointer */
4952 /* PENDING: check this for the mcs51 */
4953 stackPtr = -port->stack.direction * port->stack.call_overhead;
4954 if (IFFUNC_ISISR (name->type))
4955 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4956 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4957 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4959 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4961 fetype = getSpec (name->type); /* get the specifier for the function */
4962 /* if this is a reentrant function then */
4963 if (IFFUNC_ISREENT (name->type))
4966 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4968 /* do processing for parameters that are passed in registers */
4969 processRegParms (FUNC_ARGS(name->type), body);
4971 /* set the stack pointer */
4975 /* allocate & autoinit the block variables */
4976 processBlockVars (body, &stack, ALLOCATE);
4978 /* save the stack information */
4979 if (options.useXstack)
4980 name->xstack = SPEC_STAK (fetype) = stack;
4982 name->stack = SPEC_STAK (fetype) = stack;
4984 /* name needs to be mangled */
4985 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4987 body = resolveSymbols (body); /* resolve the symbols */
4988 body = decorateType (body); /* propagateType & do semantic checks */
4990 ex = newAst_VALUE (symbolVal (name)); /* create name */
4991 ex = newNode (FUNCTION, ex, body);
4992 ex->values.args = FUNC_ARGS(name->type);
4994 if (options.dump_tree) PA(ex);
4997 werror (E_FUNC_NO_CODE, name->name);
5001 /* create the node & generate intermediate code */
5003 codeOutFile = code->oFile;
5004 piCode = iCodeFromAst (ex);
5008 werror (E_FUNC_NO_CODE, name->name);
5012 eBBlockFromiCode (piCode);
5014 /* if there are any statics then do them */
5017 GcurMemmap = statsg;
5018 codeOutFile = statsg->oFile;
5019 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
5025 /* dealloc the block variables */
5026 processBlockVars (body, &stack, DEALLOCATE);
5027 outputDebugStackSymbols();
5028 /* deallocate paramaters */
5029 deallocParms (FUNC_ARGS(name->type));
5031 if (IFFUNC_ISREENT (name->type))
5034 /* we are done freeup memory & cleanup */
5036 if (port->reset_labelKey) labelKey = 1;
5038 FUNC_HASBODY(name->type) = 1;
5039 addSet (&operKeyReset, name);
5040 applyToSet (operKeyReset, resetParmKey);
5045 cleanUpLevel (LabelTab, 0);
5046 cleanUpBlock (StructTab, 1);
5047 cleanUpBlock (TypedefTab, 1);
5049 xstack->syms = NULL;
5050 istack->syms = NULL;
5055 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5056 /*-----------------------------------------------------------------*/
5057 /* ast_print : prints the ast (for debugging purposes) */
5058 /*-----------------------------------------------------------------*/
5060 void ast_print (ast * tree, FILE *outfile, int indent)
5065 /* can print only decorated trees */
5066 if (!tree->decorated) return;
5068 /* if any child is an error | this one is an error do nothing */
5069 if (tree->isError ||
5070 (tree->left && tree->left->isError) ||
5071 (tree->right && tree->right->isError)) {
5072 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5076 /* print the line */
5077 /* if not block & function */
5078 if (tree->type == EX_OP &&
5079 (tree->opval.op != FUNCTION &&
5080 tree->opval.op != BLOCK &&
5081 tree->opval.op != NULLOP)) {
5084 if (tree->opval.op == FUNCTION) {
5086 value *args=FUNC_ARGS(tree->left->opval.val->type);
5087 fprintf(outfile,"FUNCTION (%s=%p) type (",
5088 tree->left->opval.val->name, tree);
5089 printTypeChain (tree->left->opval.val->type->next,outfile);
5090 fprintf(outfile,") args (");
5093 fprintf (outfile, ", ");
5095 printTypeChain (args ? args->type : NULL, outfile);
5097 args= args ? args->next : NULL;
5099 fprintf(outfile,")\n");
5100 ast_print(tree->left,outfile,indent);
5101 ast_print(tree->right,outfile,indent);
5104 if (tree->opval.op == BLOCK) {
5105 symbol *decls = tree->values.sym;
5106 INDENT(indent,outfile);
5107 fprintf(outfile,"{\n");
5109 INDENT(indent+2,outfile);
5110 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5111 decls->name, decls);
5112 printTypeChain(decls->type,outfile);
5113 fprintf(outfile,")\n");
5115 decls = decls->next;
5117 ast_print(tree->right,outfile,indent+2);
5118 INDENT(indent,outfile);
5119 fprintf(outfile,"}\n");
5122 if (tree->opval.op == NULLOP) {
5123 ast_print(tree->left,outfile,indent);
5124 ast_print(tree->right,outfile,indent);
5127 INDENT(indent,outfile);
5129 /*------------------------------------------------------------------*/
5130 /*----------------------------*/
5131 /* leaf has been reached */
5132 /*----------------------------*/
5133 /* if this is of type value */
5134 /* just get the type */
5135 if (tree->type == EX_VALUE) {
5137 if (IS_LITERAL (tree->opval.val->etype)) {
5138 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5139 if (SPEC_USIGN (tree->opval.val->etype))
5140 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5142 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5143 fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5144 floatFromVal(tree->opval.val));
5145 } else if (tree->opval.val->sym) {
5146 /* if the undefined flag is set then give error message */
5147 if (tree->opval.val->sym->undefined) {
5148 fprintf(outfile,"UNDEFINED SYMBOL ");
5150 fprintf(outfile,"SYMBOL ");
5152 fprintf(outfile,"(%s=%p)",
5153 tree->opval.val->sym->name,tree);
5156 fprintf(outfile," type (");
5157 printTypeChain(tree->ftype,outfile);
5158 fprintf(outfile,")\n");
5160 fprintf(outfile,"\n");
5165 /* if type link for the case of cast */
5166 if (tree->type == EX_LINK) {
5167 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5168 printTypeChain(tree->opval.lnk,outfile);
5169 fprintf(outfile,")\n");
5174 /* depending on type of operator do */
5176 switch (tree->opval.op) {
5177 /*------------------------------------------------------------------*/
5178 /*----------------------------*/
5180 /*----------------------------*/
5182 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5183 printTypeChain(tree->ftype,outfile);
5184 fprintf(outfile,")\n");
5185 ast_print(tree->left,outfile,indent+2);
5186 ast_print(tree->right,outfile,indent+2);
5189 /*------------------------------------------------------------------*/
5190 /*----------------------------*/
5192 /*----------------------------*/
5194 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5195 printTypeChain(tree->ftype,outfile);
5196 fprintf(outfile,")\n");
5197 ast_print(tree->left,outfile,indent+2);
5198 ast_print(tree->right,outfile,indent+2);
5201 /*------------------------------------------------------------------*/
5202 /*----------------------------*/
5203 /* struct/union pointer */
5204 /*----------------------------*/
5206 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5207 printTypeChain(tree->ftype,outfile);
5208 fprintf(outfile,")\n");
5209 ast_print(tree->left,outfile,indent+2);
5210 ast_print(tree->right,outfile,indent+2);
5213 /*------------------------------------------------------------------*/
5214 /*----------------------------*/
5215 /* ++/-- operation */
5216 /*----------------------------*/
5219 fprintf(outfile,"post-");
5221 fprintf(outfile,"pre-");
5222 fprintf(outfile,"INC_OP (%p) type (",tree);
5223 printTypeChain(tree->ftype,outfile);
5224 fprintf(outfile,")\n");
5225 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5226 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5231 fprintf(outfile,"post-");
5233 fprintf(outfile,"pre-");
5234 fprintf(outfile,"DEC_OP (%p) type (",tree);
5235 printTypeChain(tree->ftype,outfile);
5236 fprintf(outfile,")\n");
5237 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5238 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5241 /*------------------------------------------------------------------*/
5242 /*----------------------------*/
5244 /*----------------------------*/
5247 fprintf(outfile,"& (%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);
5253 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5254 printTypeChain(tree->ftype,outfile);
5255 fprintf(outfile,")\n");
5256 ast_print(tree->left,outfile,indent+2);
5257 ast_print(tree->right,outfile,indent+2);
5260 /*----------------------------*/
5262 /*----------------------------*/
5264 fprintf(outfile,"OR (%p) type (",tree);
5265 printTypeChain(tree->ftype,outfile);
5266 fprintf(outfile,")\n");
5267 ast_print(tree->left,outfile,indent+2);
5268 ast_print(tree->right,outfile,indent+2);
5270 /*------------------------------------------------------------------*/
5271 /*----------------------------*/
5273 /*----------------------------*/
5275 fprintf(outfile,"XOR (%p) type (",tree);
5276 printTypeChain(tree->ftype,outfile);
5277 fprintf(outfile,")\n");
5278 ast_print(tree->left,outfile,indent+2);
5279 ast_print(tree->right,outfile,indent+2);
5282 /*------------------------------------------------------------------*/
5283 /*----------------------------*/
5285 /*----------------------------*/
5287 fprintf(outfile,"DIV (%p) type (",tree);
5288 printTypeChain(tree->ftype,outfile);
5289 fprintf(outfile,")\n");
5290 ast_print(tree->left,outfile,indent+2);
5291 ast_print(tree->right,outfile,indent+2);
5293 /*------------------------------------------------------------------*/
5294 /*----------------------------*/
5296 /*----------------------------*/
5298 fprintf(outfile,"MOD (%p) type (",tree);
5299 printTypeChain(tree->ftype,outfile);
5300 fprintf(outfile,")\n");
5301 ast_print(tree->left,outfile,indent+2);
5302 ast_print(tree->right,outfile,indent+2);
5305 /*------------------------------------------------------------------*/
5306 /*----------------------------*/
5307 /* address dereference */
5308 /*----------------------------*/
5309 case '*': /* can be unary : if right is null then unary operation */
5311 fprintf(outfile,"DEREF (%p) type (",tree);
5312 printTypeChain(tree->ftype,outfile);
5313 fprintf(outfile,")\n");
5314 ast_print(tree->left,outfile,indent+2);
5317 /*------------------------------------------------------------------*/
5318 /*----------------------------*/
5319 /* multiplication */
5320 /*----------------------------*/
5321 fprintf(outfile,"MULT (%p) type (",tree);
5322 printTypeChain(tree->ftype,outfile);
5323 fprintf(outfile,")\n");
5324 ast_print(tree->left,outfile,indent+2);
5325 ast_print(tree->right,outfile,indent+2);
5329 /*------------------------------------------------------------------*/
5330 /*----------------------------*/
5331 /* unary '+' operator */
5332 /*----------------------------*/
5336 fprintf(outfile,"UPLUS (%p) type (",tree);
5337 printTypeChain(tree->ftype,outfile);
5338 fprintf(outfile,")\n");
5339 ast_print(tree->left,outfile,indent+2);
5341 /*------------------------------------------------------------------*/
5342 /*----------------------------*/
5344 /*----------------------------*/
5345 fprintf(outfile,"ADD (%p) type (",tree);
5346 printTypeChain(tree->ftype,outfile);
5347 fprintf(outfile,")\n");
5348 ast_print(tree->left,outfile,indent+2);
5349 ast_print(tree->right,outfile,indent+2);
5352 /*------------------------------------------------------------------*/
5353 /*----------------------------*/
5355 /*----------------------------*/
5356 case '-': /* can be unary */
5358 fprintf(outfile,"UMINUS (%p) type (",tree);
5359 printTypeChain(tree->ftype,outfile);
5360 fprintf(outfile,")\n");
5361 ast_print(tree->left,outfile,indent+2);
5363 /*------------------------------------------------------------------*/
5364 /*----------------------------*/
5366 /*----------------------------*/
5367 fprintf(outfile,"SUB (%p) type (",tree);
5368 printTypeChain(tree->ftype,outfile);
5369 fprintf(outfile,")\n");
5370 ast_print(tree->left,outfile,indent+2);
5371 ast_print(tree->right,outfile,indent+2);
5374 /*------------------------------------------------------------------*/
5375 /*----------------------------*/
5377 /*----------------------------*/
5379 fprintf(outfile,"COMPL (%p) type (",tree);
5380 printTypeChain(tree->ftype,outfile);
5381 fprintf(outfile,")\n");
5382 ast_print(tree->left,outfile,indent+2);
5384 /*------------------------------------------------------------------*/
5385 /*----------------------------*/
5387 /*----------------------------*/
5389 fprintf(outfile,"NOT (%p) type (",tree);
5390 printTypeChain(tree->ftype,outfile);
5391 fprintf(outfile,")\n");
5392 ast_print(tree->left,outfile,indent+2);
5394 /*------------------------------------------------------------------*/
5395 /*----------------------------*/
5397 /*----------------------------*/
5399 fprintf(outfile,"RRC (%p) type (",tree);
5400 printTypeChain(tree->ftype,outfile);
5401 fprintf(outfile,")\n");
5402 ast_print(tree->left,outfile,indent+2);
5406 fprintf(outfile,"RLC (%p) type (",tree);
5407 printTypeChain(tree->ftype,outfile);
5408 fprintf(outfile,")\n");
5409 ast_print(tree->left,outfile,indent+2);
5412 fprintf(outfile,"SWAP (%p) type (",tree);
5413 printTypeChain(tree->ftype,outfile);
5414 fprintf(outfile,")\n");
5415 ast_print(tree->left,outfile,indent+2);
5418 fprintf(outfile,"GETHBIT (%p) type (",tree);
5419 printTypeChain(tree->ftype,outfile);
5420 fprintf(outfile,")\n");
5421 ast_print(tree->left,outfile,indent+2);
5424 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5425 printTypeChain(tree->ftype,outfile);
5426 fprintf(outfile,")\n");
5427 ast_print(tree->left,outfile,indent+2);
5428 ast_print(tree->right,outfile,indent+2);
5431 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5432 printTypeChain(tree->ftype,outfile);
5433 fprintf(outfile,")\n");
5434 ast_print(tree->left,outfile,indent+2);
5435 ast_print(tree->right,outfile,indent+2);
5437 /*------------------------------------------------------------------*/
5438 /*----------------------------*/
5440 /*----------------------------*/
5441 case CAST: /* change the type */
5442 fprintf(outfile,"CAST (%p) from type (",tree);
5443 printTypeChain(tree->right->ftype,outfile);
5444 fprintf(outfile,") to type (");
5445 printTypeChain(tree->ftype,outfile);
5446 fprintf(outfile,")\n");
5447 ast_print(tree->right,outfile,indent+2);
5451 fprintf(outfile,"ANDAND (%p) type (",tree);
5452 printTypeChain(tree->ftype,outfile);
5453 fprintf(outfile,")\n");
5454 ast_print(tree->left,outfile,indent+2);
5455 ast_print(tree->right,outfile,indent+2);
5458 fprintf(outfile,"OROR (%p) type (",tree);
5459 printTypeChain(tree->ftype,outfile);
5460 fprintf(outfile,")\n");
5461 ast_print(tree->left,outfile,indent+2);
5462 ast_print(tree->right,outfile,indent+2);
5465 /*------------------------------------------------------------------*/
5466 /*----------------------------*/
5467 /* comparison operators */
5468 /*----------------------------*/
5470 fprintf(outfile,"GT(>) (%p) type (",tree);
5471 printTypeChain(tree->ftype,outfile);
5472 fprintf(outfile,")\n");
5473 ast_print(tree->left,outfile,indent+2);
5474 ast_print(tree->right,outfile,indent+2);
5477 fprintf(outfile,"LT(<) (%p) type (",tree);
5478 printTypeChain(tree->ftype,outfile);
5479 fprintf(outfile,")\n");
5480 ast_print(tree->left,outfile,indent+2);
5481 ast_print(tree->right,outfile,indent+2);
5484 fprintf(outfile,"LE(<=) (%p) type (",tree);
5485 printTypeChain(tree->ftype,outfile);
5486 fprintf(outfile,")\n");
5487 ast_print(tree->left,outfile,indent+2);
5488 ast_print(tree->right,outfile,indent+2);
5491 fprintf(outfile,"GE(>=) (%p) type (",tree);
5492 printTypeChain(tree->ftype,outfile);
5493 fprintf(outfile,")\n");
5494 ast_print(tree->left,outfile,indent+2);
5495 ast_print(tree->right,outfile,indent+2);
5498 fprintf(outfile,"EQ(==) (%p) type (",tree);
5499 printTypeChain(tree->ftype,outfile);
5500 fprintf(outfile,")\n");
5501 ast_print(tree->left,outfile,indent+2);
5502 ast_print(tree->right,outfile,indent+2);
5505 fprintf(outfile,"NE(!=) (%p) type (",tree);
5506 printTypeChain(tree->ftype,outfile);
5507 fprintf(outfile,")\n");
5508 ast_print(tree->left,outfile,indent+2);
5509 ast_print(tree->right,outfile,indent+2);
5510 /*------------------------------------------------------------------*/
5511 /*----------------------------*/
5513 /*----------------------------*/
5514 case SIZEOF: /* evaluate wihout code generation */
5515 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5518 /*------------------------------------------------------------------*/
5519 /*----------------------------*/
5520 /* conditional operator '?' */
5521 /*----------------------------*/
5523 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5524 printTypeChain(tree->ftype,outfile);
5525 fprintf(outfile,")\n");
5526 ast_print(tree->left,outfile,indent+2);
5527 ast_print(tree->right,outfile,indent+2);
5531 fprintf(outfile,"COLON(:) (%p) type (",tree);
5532 printTypeChain(tree->ftype,outfile);
5533 fprintf(outfile,")\n");
5534 ast_print(tree->left,outfile,indent+2);
5535 ast_print(tree->right,outfile,indent+2);
5538 /*------------------------------------------------------------------*/
5539 /*----------------------------*/
5540 /* assignment operators */
5541 /*----------------------------*/
5543 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5544 printTypeChain(tree->ftype,outfile);
5545 fprintf(outfile,")\n");
5546 ast_print(tree->left,outfile,indent+2);
5547 ast_print(tree->right,outfile,indent+2);
5550 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5551 printTypeChain(tree->ftype,outfile);
5552 fprintf(outfile,")\n");
5553 ast_print(tree->left,outfile,indent+2);
5554 ast_print(tree->right,outfile,indent+2);
5557 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5558 printTypeChain(tree->ftype,outfile);
5559 fprintf(outfile,")\n");
5560 ast_print(tree->left,outfile,indent+2);
5561 ast_print(tree->right,outfile,indent+2);
5564 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5565 printTypeChain(tree->ftype,outfile);
5566 fprintf(outfile,")\n");
5567 ast_print(tree->left,outfile,indent+2);
5568 ast_print(tree->right,outfile,indent+2);
5571 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5572 printTypeChain(tree->ftype,outfile);
5573 fprintf(outfile,")\n");
5574 ast_print(tree->left,outfile,indent+2);
5575 ast_print(tree->right,outfile,indent+2);
5578 fprintf(outfile,"RSHFTASS(>>=) (%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);
5585 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5586 printTypeChain(tree->ftype,outfile);
5587 fprintf(outfile,")\n");
5588 ast_print(tree->left,outfile,indent+2);
5589 ast_print(tree->right,outfile,indent+2);
5591 /*------------------------------------------------------------------*/
5592 /*----------------------------*/
5594 /*----------------------------*/
5596 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5597 printTypeChain(tree->ftype,outfile);
5598 fprintf(outfile,")\n");
5599 ast_print(tree->left,outfile,indent+2);
5600 ast_print(tree->right,outfile,indent+2);
5602 /*------------------------------------------------------------------*/
5603 /*----------------------------*/
5605 /*----------------------------*/
5607 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5608 printTypeChain(tree->ftype,outfile);
5609 fprintf(outfile,")\n");
5610 ast_print(tree->left,outfile,indent+2);
5611 ast_print(tree->right,outfile,indent+2);
5613 /*------------------------------------------------------------------*/
5614 /*----------------------------*/
5615 /* straight assignemnt */
5616 /*----------------------------*/
5618 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5619 printTypeChain(tree->ftype,outfile);
5620 fprintf(outfile,")\n");
5621 ast_print(tree->left,outfile,indent+2);
5622 ast_print(tree->right,outfile,indent+2);
5624 /*------------------------------------------------------------------*/
5625 /*----------------------------*/
5626 /* comma operator */
5627 /*----------------------------*/
5629 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5630 printTypeChain(tree->ftype,outfile);
5631 fprintf(outfile,")\n");
5632 ast_print(tree->left,outfile,indent+2);
5633 ast_print(tree->right,outfile,indent+2);
5635 /*------------------------------------------------------------------*/
5636 /*----------------------------*/
5638 /*----------------------------*/
5641 fprintf(outfile,"CALL (%p) type (",tree);
5642 printTypeChain(tree->ftype,outfile);
5643 fprintf(outfile,")\n");
5644 ast_print(tree->left,outfile,indent+2);
5645 ast_print(tree->right,outfile,indent+2);
5648 fprintf(outfile,"PARMS\n");
5649 ast_print(tree->left,outfile,indent+2);
5650 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5651 ast_print(tree->right,outfile,indent+2);
5654 /*------------------------------------------------------------------*/
5655 /*----------------------------*/
5656 /* return statement */
5657 /*----------------------------*/
5659 fprintf(outfile,"RETURN (%p) type (",tree);
5661 printTypeChain(tree->right->ftype,outfile);
5663 fprintf(outfile,")\n");
5664 ast_print(tree->right,outfile,indent+2);
5666 /*------------------------------------------------------------------*/
5667 /*----------------------------*/
5668 /* label statement */
5669 /*----------------------------*/
5671 fprintf(outfile,"LABEL (%p)\n",tree);
5672 ast_print(tree->left,outfile,indent+2);
5673 ast_print(tree->right,outfile,indent);
5675 /*------------------------------------------------------------------*/
5676 /*----------------------------*/
5677 /* switch statement */
5678 /*----------------------------*/
5682 fprintf(outfile,"SWITCH (%p) ",tree);
5683 ast_print(tree->left,outfile,0);
5684 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5685 INDENT(indent+2,outfile);
5686 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5687 (int) floatFromVal(val),
5688 tree->values.switchVals.swNum,
5689 (int) floatFromVal(val));
5691 ast_print(tree->right,outfile,indent);
5694 /*------------------------------------------------------------------*/
5695 /*----------------------------*/
5697 /*----------------------------*/
5699 fprintf(outfile,"IF (%p) \n",tree);
5700 ast_print(tree->left,outfile,indent+2);
5701 if (tree->trueLabel) {
5702 INDENT(indent+2,outfile);
5703 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5705 if (tree->falseLabel) {
5706 INDENT(indent+2,outfile);
5707 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5709 ast_print(tree->right,outfile,indent+2);
5711 /*----------------------------*/
5712 /* goto Statement */
5713 /*----------------------------*/
5715 fprintf(outfile,"GOTO (%p) \n",tree);
5716 ast_print(tree->left,outfile,indent+2);
5717 fprintf(outfile,"\n");
5719 /*------------------------------------------------------------------*/
5720 /*----------------------------*/
5722 /*----------------------------*/
5724 fprintf(outfile,"FOR (%p) \n",tree);
5725 if (AST_FOR( tree, initExpr)) {
5726 INDENT(indent+2,outfile);
5727 fprintf(outfile,"INIT EXPR ");
5728 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5730 if (AST_FOR( tree, condExpr)) {
5731 INDENT(indent+2,outfile);
5732 fprintf(outfile,"COND EXPR ");
5733 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5735 if (AST_FOR( tree, loopExpr)) {
5736 INDENT(indent+2,outfile);
5737 fprintf(outfile,"LOOP EXPR ");
5738 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5740 fprintf(outfile,"FOR LOOP BODY \n");
5741 ast_print(tree->left,outfile,indent+2);
5744 fprintf(outfile,"CRITICAL (%p) \n",tree);
5745 ast_print(tree->left,outfile,indent+2);
5753 ast_print(t,stdout,0);
5758 /*-----------------------------------------------------------------*/
5759 /* astErrors : returns non-zero if errors present in tree */
5760 /*-----------------------------------------------------------------*/
5761 int astErrors(ast *t)
5770 if (t->type == EX_VALUE
5771 && t->opval.val->sym
5772 && t->opval.val->sym->undefined)
5775 errors += astErrors(t->left);
5776 errors += astErrors(t->right);