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), FALSE);
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);
2514 /* if left is a literal exchange left & right */
2515 if (IS_LITERAL (LTYPE (tree)))
2517 ast *tTree = tree->left;
2518 tree->left = tree->right;
2519 tree->right = tTree;
2522 /* if right is a literal and */
2523 /* we can find a 2nd literal in a or-tree then */
2524 /* rearrange the tree */
2525 if (IS_LITERAL (RTYPE (tree)))
2528 ast *litTree = searchLitOp (tree, &parent, "|");
2531 ast *tTree = litTree->left;
2532 litTree->left = tree->right;
2533 tree->right = tTree;
2534 /* both operands in tTree are literal now */
2535 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)) &&
2582 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2585 ast *litTree = searchLitOp (tree, &parent, "^");
2588 ast *tTree = litTree->left;
2589 litTree->left = tree->right;
2590 tree->right = tTree;
2591 /* both operands in litTree are literal now */
2592 decorateType (parent);
2596 LRVAL (tree) = RRVAL (tree) = 1;
2597 TETYPE (tree) = getSpec (TTYPE (tree) =
2598 computeType (LTYPE (tree),
2604 /*------------------------------------------------------------------*/
2605 /*----------------------------*/
2607 /*----------------------------*/
2609 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2611 werror (E_INVALID_OP, "divide");
2612 goto errorTreeReturn;
2614 /* if they are both literal then */
2615 /* rewrite the tree */
2616 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2618 tree->type = EX_VALUE;
2619 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2620 valFromType (RETYPE (tree)));
2621 tree->right = tree->left = NULL;
2622 TETYPE (tree) = getSpec (TTYPE (tree) =
2623 tree->opval.val->type);
2627 LRVAL (tree) = RRVAL (tree) = 1;
2628 TETYPE (tree) = getSpec (TTYPE (tree) =
2629 computeType (LTYPE (tree),
2633 /* if right is a literal and */
2634 /* left is also a division by a literal then */
2635 /* rearrange the tree */
2636 if (IS_LITERAL (RTYPE (tree))
2637 /* avoid infinite loop */
2638 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2641 ast *litTree = searchLitOp (tree, &parent, "/");
2644 if (IS_LITERAL (RTYPE (litTree)))
2647 litTree->right = newNode ('*', litTree->right, tree->right);
2648 litTree->right->lineno = tree->lineno;
2650 tree->right->opval.val = constVal ("1");
2651 decorateType (parent);
2655 /* litTree->left is literal: no gcse possible.
2656 We can't call decorateType(parent), because
2657 this would cause an infinit loop. */
2658 parent->decorated = 1;
2659 decorateType (litTree);
2666 /*------------------------------------------------------------------*/
2667 /*----------------------------*/
2669 /*----------------------------*/
2671 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2673 werror (E_BITWISE_OP);
2674 werror (W_CONTINUE, "left & right types are ");
2675 printTypeChain (LTYPE (tree), stderr);
2676 fprintf (stderr, ",");
2677 printTypeChain (RTYPE (tree), stderr);
2678 fprintf (stderr, "\n");
2679 goto errorTreeReturn;
2681 /* if they are both literal then */
2682 /* rewrite the tree */
2683 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2685 tree->type = EX_VALUE;
2686 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2687 valFromType (RETYPE (tree)));
2688 tree->right = tree->left = NULL;
2689 TETYPE (tree) = getSpec (TTYPE (tree) =
2690 tree->opval.val->type);
2693 LRVAL (tree) = RRVAL (tree) = 1;
2694 TETYPE (tree) = getSpec (TTYPE (tree) =
2695 computeType (LTYPE (tree),
2700 /*------------------------------------------------------------------*/
2701 /*----------------------------*/
2702 /* address dereference */
2703 /*----------------------------*/
2704 case '*': /* can be unary : if right is null then unary operation */
2707 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2709 werror (E_PTR_REQD);
2710 goto errorTreeReturn;
2715 werror (E_LVALUE_REQUIRED, "pointer deref");
2716 goto errorTreeReturn;
2718 if (IS_ADDRESS_OF_OP(tree->left))
2720 /* replace *&obj with obj */
2721 return tree->left->left;
2723 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2724 TETYPE (tree) = getSpec (TTYPE (tree));
2725 /* adjust the storage class */
2726 switch (DCL_TYPE(tree->left->ftype)) {
2728 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2731 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2734 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2737 SPEC_SCLS (TETYPE (tree)) = 0;
2740 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2743 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2746 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2749 SPEC_SCLS (TETYPE (tree)) = 0;
2758 /*------------------------------------------------------------------*/
2759 /*----------------------------*/
2760 /* multiplication */
2761 /*----------------------------*/
2762 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2764 werror (E_INVALID_OP, "multiplication");
2765 goto errorTreeReturn;
2768 /* if they are both literal then */
2769 /* rewrite the tree */
2770 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2772 tree->type = EX_VALUE;
2773 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2774 valFromType (RETYPE (tree)));
2775 tree->right = tree->left = NULL;
2776 TETYPE (tree) = getSpec (TTYPE (tree) =
2777 tree->opval.val->type);
2781 /* if left is a literal exchange left & right */
2782 if (IS_LITERAL (LTYPE (tree)))
2784 ast *tTree = tree->left;
2785 tree->left = tree->right;
2786 tree->right = tTree;
2789 /* if right is a literal and */
2790 /* we can find a 2nd literal in a mul-tree then */
2791 /* rearrange the tree */
2792 if (IS_LITERAL (RTYPE (tree)))
2795 ast *litTree = searchLitOp (tree, &parent, "*");
2798 ast *tTree = litTree->left;
2799 litTree->left = tree->right;
2800 tree->right = tTree;
2801 /* both operands in litTree are literal now */
2802 decorateType (parent);
2806 LRVAL (tree) = RRVAL (tree) = 1;
2807 TETYPE (tree) = getSpec (TTYPE (tree) =
2808 computeType (LTYPE (tree),
2814 /*------------------------------------------------------------------*/
2815 /*----------------------------*/
2816 /* unary '+' operator */
2817 /*----------------------------*/
2822 if (!IS_ARITHMETIC (LTYPE (tree)))
2824 werror (E_UNARY_OP, '+');
2825 goto errorTreeReturn;
2828 /* if left is a literal then do it */
2829 if (IS_LITERAL (LTYPE (tree)))
2831 tree->type = EX_VALUE;
2832 tree->opval.val = valFromType (LETYPE (tree));
2834 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2838 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2842 /*------------------------------------------------------------------*/
2843 /*----------------------------*/
2845 /*----------------------------*/
2847 /* this is not a unary operation */
2848 /* if both pointers then problem */
2849 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2850 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2852 werror (E_PTR_PLUS_PTR);
2853 goto errorTreeReturn;
2856 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2857 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2859 werror (E_PLUS_INVALID, "+");
2860 goto errorTreeReturn;
2863 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2864 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2866 werror (E_PLUS_INVALID, "+");
2867 goto errorTreeReturn;
2869 /* if they are both literal then */
2870 /* rewrite the tree */
2871 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2873 tree->type = EX_VALUE;
2874 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2875 valFromType (RETYPE (tree)));
2876 tree->right = tree->left = NULL;
2877 TETYPE (tree) = getSpec (TTYPE (tree) =
2878 tree->opval.val->type);
2882 /* if the right is a pointer or left is a literal
2883 xchange left & right */
2884 if (IS_ARRAY (RTYPE (tree)) ||
2885 IS_PTR (RTYPE (tree)) ||
2886 IS_LITERAL (LTYPE (tree)))
2888 ast *tTree = tree->left;
2889 tree->left = tree->right;
2890 tree->right = tTree;
2893 /* if right is a literal and */
2894 /* left is also an addition/subtraction with a literal then */
2895 /* rearrange the tree */
2896 if (IS_LITERAL (RTYPE (tree)))
2898 ast *litTree, *parent;
2899 litTree = searchLitOp (tree, &parent, "+-");
2902 if (litTree->opval.op == '+')
2905 ast *tTree = litTree->left;
2906 litTree->left = tree->right;
2907 tree->right = tree->left;
2910 else if (litTree->opval.op == '-')
2912 if (IS_LITERAL (RTYPE (litTree)))
2915 ast *tTree = litTree->left;
2916 litTree->left = tree->right;
2917 tree->right = tTree;
2922 ast *tTree = litTree->right;
2923 litTree->right = tree->right;
2924 tree->right = tTree;
2925 litTree->opval.op = '+';
2926 tree->opval.op = '-';
2929 decorateType (parent);
2933 LRVAL (tree) = RRVAL (tree) = 1;
2934 /* if the left is a pointer */
2935 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2936 TETYPE (tree) = getSpec (TTYPE (tree) =
2939 TETYPE (tree) = getSpec (TTYPE (tree) =
2940 computeType (LTYPE (tree),
2945 /*------------------------------------------------------------------*/
2946 /*----------------------------*/
2948 /*----------------------------*/
2949 case '-': /* can be unary */
2950 /* if right is null then unary */
2954 if (!IS_ARITHMETIC (LTYPE (tree)))
2956 werror (E_UNARY_OP, tree->opval.op);
2957 goto errorTreeReturn;
2960 /* if left is a literal then do it */
2961 if (IS_LITERAL (LTYPE (tree)))
2963 tree->type = EX_VALUE;
2964 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2966 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2967 SPEC_USIGN(TETYPE(tree)) = 0;
2971 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2975 /*------------------------------------------------------------------*/
2976 /*----------------------------*/
2978 /*----------------------------*/
2980 if (!(IS_PTR (LTYPE (tree)) ||
2981 IS_ARRAY (LTYPE (tree)) ||
2982 IS_ARITHMETIC (LTYPE (tree))))
2984 werror (E_PLUS_INVALID, "-");
2985 goto errorTreeReturn;
2988 if (!(IS_PTR (RTYPE (tree)) ||
2989 IS_ARRAY (RTYPE (tree)) ||
2990 IS_ARITHMETIC (RTYPE (tree))))
2992 werror (E_PLUS_INVALID, "-");
2993 goto errorTreeReturn;
2996 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2997 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2998 IS_INTEGRAL (RTYPE (tree))))
3000 werror (E_PLUS_INVALID, "-");
3001 goto errorTreeReturn;
3004 /* if they are both literal then */
3005 /* rewrite the tree */
3006 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3008 tree->type = EX_VALUE;
3009 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3010 valFromType (RETYPE (tree)));
3011 tree->right = tree->left = NULL;
3012 TETYPE (tree) = getSpec (TTYPE (tree) =
3013 tree->opval.val->type);
3017 /* if the left & right are equal then zero */
3018 if (isAstEqual (tree->left, tree->right))
3020 tree->type = EX_VALUE;
3021 tree->left = tree->right = NULL;
3022 tree->opval.val = constVal ("0");
3023 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3027 /* if both of them are pointers or arrays then */
3028 /* the result is going to be an integer */
3029 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3030 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3031 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3033 /* if only the left is a pointer */
3034 /* then result is a pointer */
3035 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3036 TETYPE (tree) = getSpec (TTYPE (tree) =
3039 TETYPE (tree) = getSpec (TTYPE (tree) =
3040 computeType (LTYPE (tree),
3044 LRVAL (tree) = RRVAL (tree) = 1;
3046 /* if right is a literal and */
3047 /* left is also an addition/subtraction with a literal then */
3048 /* rearrange the tree */
3049 if (IS_LITERAL (RTYPE (tree))
3050 /* avoid infinite loop */
3051 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3053 ast *litTree, *litParent;
3054 litTree = searchLitOp (tree, &litParent, "+-");
3057 if (litTree->opval.op == '+')
3060 litTree->right = newNode ('-', litTree->right, tree->right);
3061 litTree->right->lineno = tree->lineno;
3063 tree->right->opval.val = constVal ("0");
3065 else if (litTree->opval.op == '-')
3067 if (IS_LITERAL (RTYPE (litTree)))
3070 litTree->right = newNode ('+', tree->right, litTree->right);
3071 litTree->right->lineno = tree->lineno;
3073 tree->right->opval.val = constVal ("0");
3078 ast *tTree = litTree->right;
3079 litTree->right = tree->right;
3080 tree->right = tTree;
3083 decorateType (litParent);
3088 /*------------------------------------------------------------------*/
3089 /*----------------------------*/
3091 /*----------------------------*/
3093 /* can be only integral type */
3094 if (!IS_INTEGRAL (LTYPE (tree)))
3096 werror (E_UNARY_OP, tree->opval.op);
3097 goto errorTreeReturn;
3100 /* if left is a literal then do it */
3101 if (IS_LITERAL (LTYPE (tree)))
3103 tree->type = EX_VALUE;
3104 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3106 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3110 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3113 /*------------------------------------------------------------------*/
3114 /*----------------------------*/
3116 /*----------------------------*/
3118 /* can be pointer */
3119 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3120 !IS_PTR (LTYPE (tree)) &&
3121 !IS_ARRAY (LTYPE (tree)))
3123 werror (E_UNARY_OP, tree->opval.op);
3124 goto errorTreeReturn;
3127 /* if left is a literal then do it */
3128 if (IS_LITERAL (LTYPE (tree)))
3130 tree->type = EX_VALUE;
3131 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3133 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3137 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3140 /*------------------------------------------------------------------*/
3141 /*----------------------------*/
3143 /*----------------------------*/
3147 TTYPE (tree) = LTYPE (tree);
3148 TETYPE (tree) = LETYPE (tree);
3152 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3157 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3159 werror (E_SHIFT_OP_INVALID);
3160 werror (W_CONTINUE, "left & right types are ");
3161 printTypeChain (LTYPE (tree), stderr);
3162 fprintf (stderr, ",");
3163 printTypeChain (RTYPE (tree), stderr);
3164 fprintf (stderr, "\n");
3165 goto errorTreeReturn;
3168 /* if they are both literal then */
3169 /* rewrite the tree */
3170 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3172 tree->type = EX_VALUE;
3173 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3174 valFromType (RETYPE (tree)),
3175 (tree->opval.op == LEFT_OP ? 1 : 0));
3176 tree->right = tree->left = NULL;
3177 TETYPE (tree) = getSpec (TTYPE (tree) =
3178 tree->opval.val->type);
3182 LRVAL (tree) = RRVAL (tree) = 1;
3183 if (tree->opval.op == LEFT_OP)
3185 /* promote char to int */
3186 TETYPE (tree) = getSpec (TTYPE (tree) =
3187 computeType (LTYPE (tree),
3188 LTYPE (tree), /* no, not RTYPE! */
3193 /* no promotion necessary */
3194 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3195 if (IS_LITERAL (TTYPE (tree)))
3196 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3199 /* if only the right side is a literal & we are
3200 shifting more than size of the left operand then zero */
3201 if (IS_LITERAL (RTYPE (tree)) &&
3202 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3203 (getSize (TETYPE (tree)) * 8))
3205 if (tree->opval.op==LEFT_OP ||
3206 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3208 lineno=tree->lineno;
3209 werror (W_SHIFT_CHANGED,
3210 (tree->opval.op == LEFT_OP ? "left" : "right"));
3211 tree->type = EX_VALUE;
3212 tree->left = tree->right = NULL;
3213 tree->opval.val = constVal ("0");
3214 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3221 /*------------------------------------------------------------------*/
3222 /*----------------------------*/
3224 /*----------------------------*/
3225 case CAST: /* change the type */
3226 /* cannot cast to an aggregate type */
3227 if (IS_AGGREGATE (LTYPE (tree)))
3229 werror (E_CAST_ILLEGAL);
3230 goto errorTreeReturn;
3233 /* make sure the type is complete and sane */
3234 checkTypeSanity(LETYPE(tree), "(cast)");
3236 /* If code memory is read only, then pointers to code memory */
3237 /* implicitly point to constants -- make this explicit */
3239 sym_link *t = LTYPE(tree);
3240 while (t && t->next)
3242 if (IS_CODEPTR(t) && port->mem.code_ro)
3244 if (IS_SPEC(t->next))
3245 SPEC_CONST (t->next) = 1;
3247 DCL_PTR_CONST (t->next) = 1;
3254 /* if the right is a literal replace the tree */
3255 if (IS_LITERAL (RETYPE (tree))) {
3256 if (!IS_PTR (LTYPE (tree))) {
3257 tree->type = EX_VALUE;
3259 valCastLiteral (LTYPE (tree),
3260 floatFromVal (valFromType (RETYPE (tree))));
3263 TTYPE (tree) = tree->opval.val->type;
3264 tree->values.literalFromCast = 1;
3265 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3266 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3267 sym_link *rest = LTYPE(tree)->next;
3268 werror(W_LITERAL_GENERIC);
3269 TTYPE(tree) = newLink(DECLARATOR);
3270 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3271 TTYPE(tree)->next = rest;
3272 tree->left->opval.lnk = TTYPE(tree);
3275 TTYPE (tree) = LTYPE (tree);
3279 TTYPE (tree) = LTYPE (tree);
3283 #if 0 // this is already checked, now this could be explicit
3284 /* if pointer to struct then check names */
3285 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3286 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3287 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3289 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3290 SPEC_STRUCT(LETYPE(tree))->tag);
3293 if (IS_ADDRESS_OF_OP(tree->right)
3294 && IS_AST_SYM_VALUE (tree->right->left)
3295 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3297 tree->type = EX_VALUE;
3299 valCastLiteral (LTYPE (tree),
3300 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3301 TTYPE (tree) = tree->opval.val->type;
3302 TETYPE (tree) = getSpec (TTYPE (tree));
3305 tree->values.literalFromCast = 1;
3309 /* handle offsetof macro: */
3310 /* #define offsetof(TYPE, MEMBER) \ */
3311 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3312 if (IS_ADDRESS_OF_OP(tree->right)
3313 && IS_AST_OP (tree->right->left)
3314 && tree->right->left->opval.op == PTR_OP
3315 && IS_AST_OP (tree->right->left->left)
3316 && tree->right->left->left->opval.op == CAST
3317 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3319 symbol *element = getStructElement (
3320 SPEC_STRUCT (LETYPE(tree->right->left)),
3321 AST_SYMBOL(tree->right->left->right)
3325 tree->type = EX_VALUE;
3326 tree->opval.val = valCastLiteral (
3329 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3332 TTYPE (tree) = tree->opval.val->type;
3333 TETYPE (tree) = getSpec (TTYPE (tree));
3340 /* if the right is a literal replace the tree */
3341 if (IS_LITERAL (RETYPE (tree))) {
3343 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3344 /* rewrite (type *)litaddr
3346 and define type at litaddr temp
3347 (but only if type's storage class is not generic)
3349 ast *newTree = newNode ('&', NULL, NULL);
3352 TTYPE (newTree) = LTYPE (tree);
3353 TETYPE (newTree) = getSpec(LTYPE (tree));
3355 /* define a global symbol at the casted address*/
3356 sym = newSymbol(genSymName (0), 0);
3357 sym->type = LTYPE (tree)->next;
3359 sym->type = newLink (V_VOID);
3360 sym->etype = getSpec(sym->type);
3361 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3362 sym->lineDef = tree->lineno;
3365 SPEC_STAT (sym->etype) = 1;
3366 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3367 SPEC_ABSA(sym->etype) = 1;
3368 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3371 newTree->left = newAst_VALUE(symbolVal(sym));
3372 newTree->left->lineno = tree->lineno;
3373 LTYPE (newTree) = sym->type;
3374 LETYPE (newTree) = sym->etype;
3375 LLVAL (newTree) = 1;
3376 LRVAL (newTree) = 0;
3377 TLVAL (newTree) = 1;
3381 if (!IS_PTR (LTYPE (tree))) {
3382 tree->type = EX_VALUE;
3384 valCastLiteral (LTYPE (tree),
3385 floatFromVal (valFromType (RTYPE (tree))));
3386 TTYPE (tree) = tree->opval.val->type;
3389 tree->values.literalFromCast = 1;
3390 TETYPE (tree) = getSpec (TTYPE (tree));
3394 TTYPE (tree) = LTYPE (tree);
3398 TETYPE (tree) = getSpec (TTYPE (tree));
3402 /*------------------------------------------------------------------*/
3403 /*----------------------------*/
3404 /* logical &&, || */
3405 /*----------------------------*/
3408 /* each must me arithmetic type or be a pointer */
3409 if (!IS_PTR (LTYPE (tree)) &&
3410 !IS_ARRAY (LTYPE (tree)) &&
3411 !IS_INTEGRAL (LTYPE (tree)))
3413 werror (E_COMPARE_OP);
3414 goto errorTreeReturn;
3417 if (!IS_PTR (RTYPE (tree)) &&
3418 !IS_ARRAY (RTYPE (tree)) &&
3419 !IS_INTEGRAL (RTYPE (tree)))
3421 werror (E_COMPARE_OP);
3422 goto errorTreeReturn;
3424 /* if they are both literal then */
3425 /* rewrite the tree */
3426 if (IS_LITERAL (RTYPE (tree)) &&
3427 IS_LITERAL (LTYPE (tree)))
3429 tree->type = EX_VALUE;
3430 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3431 valFromType (RTYPE (tree)),
3433 tree->right = tree->left = NULL;
3434 TETYPE (tree) = getSpec (TTYPE (tree) =
3435 tree->opval.val->type);
3438 LRVAL (tree) = RRVAL (tree) = 1;
3439 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3442 /*------------------------------------------------------------------*/
3443 /*----------------------------*/
3444 /* comparison operators */
3445 /*----------------------------*/
3453 ast *lt = optimizeCompare (tree);
3459 /* if they are pointers they must be castable */
3460 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3462 if (tree->opval.op==EQ_OP &&
3463 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3464 // we cannot cast a gptr to a !gptr: switch the leaves
3465 struct ast *s=tree->left;
3466 tree->left=tree->right;
3469 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3471 werror (E_COMPARE_OP);
3472 fprintf (stderr, "comparing type ");
3473 printTypeChain (LTYPE (tree), stderr);
3474 fprintf (stderr, "to type ");
3475 printTypeChain (RTYPE (tree), stderr);
3476 fprintf (stderr, "\n");
3477 goto errorTreeReturn;
3480 /* else they should be promotable to one another */
3483 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3484 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3486 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3488 werror (E_COMPARE_OP);
3489 fprintf (stderr, "comparing type ");
3490 printTypeChain (LTYPE (tree), stderr);
3491 fprintf (stderr, "to type ");
3492 printTypeChain (RTYPE (tree), stderr);
3493 fprintf (stderr, "\n");
3494 goto errorTreeReturn;
3497 /* if unsigned value < 0 then always false */
3498 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3499 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
3500 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3502 if (tree->opval.op == '<')
3506 if (tree->opval.op == '>')
3508 /* if the parent is an ifx, then we could do */
3509 /* return tree->left; */
3510 tree->opval.op = '?';
3511 tree->right = newNode (':',
3512 newAst_VALUE (constVal ("1")),
3513 tree->right); /* val 0 */
3514 tree->right->lineno = tree->lineno;
3515 tree->right->left->lineno = tree->lineno;
3516 decorateType (tree->right);
3519 /* if they are both literal then */
3520 /* rewrite the tree */
3521 if (IS_LITERAL (RTYPE (tree)) &&
3522 IS_LITERAL (LTYPE (tree)))
3524 tree->type = EX_VALUE;
3525 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3526 valFromType (RETYPE (tree)),
3528 tree->right = tree->left = NULL;
3529 TETYPE (tree) = getSpec (TTYPE (tree) =
3530 tree->opval.val->type);
3533 LRVAL (tree) = RRVAL (tree) = 1;
3534 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3537 /*------------------------------------------------------------------*/
3538 /*----------------------------*/
3540 /*----------------------------*/
3541 case SIZEOF: /* evaluate wihout code generation */
3542 /* change the type to a integer */
3543 tree->type = EX_VALUE;
3544 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3545 tree->opval.val = constVal (buffer);
3546 tree->right = tree->left = NULL;
3547 TETYPE (tree) = getSpec (TTYPE (tree) =
3548 tree->opval.val->type);
3551 /*------------------------------------------------------------------*/
3552 /*----------------------------*/
3554 /*----------------------------*/
3556 /* return typeof enum value */
3557 tree->type = EX_VALUE;
3560 if (IS_SPEC(tree->right->ftype)) {
3561 switch (SPEC_NOUN(tree->right->ftype)) {
3563 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3564 else typeofv = TYPEOF_INT;
3567 typeofv = TYPEOF_FLOAT;
3570 typeofv = TYPEOF_CHAR;
3573 typeofv = TYPEOF_VOID;
3576 typeofv = TYPEOF_STRUCT;
3579 typeofv = TYPEOF_BITFIELD;
3582 typeofv = TYPEOF_BIT;
3585 typeofv = TYPEOF_SBIT;
3591 switch (DCL_TYPE(tree->right->ftype)) {
3593 typeofv = TYPEOF_POINTER;
3596 typeofv = TYPEOF_FPOINTER;
3599 typeofv = TYPEOF_CPOINTER;
3602 typeofv = TYPEOF_GPOINTER;
3605 typeofv = TYPEOF_PPOINTER;
3608 typeofv = TYPEOF_IPOINTER;
3611 typeofv = TYPEOF_ARRAY;
3614 typeofv = TYPEOF_FUNCTION;
3620 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3621 tree->opval.val = constVal (buffer);
3622 tree->right = tree->left = NULL;
3623 TETYPE (tree) = getSpec (TTYPE (tree) =
3624 tree->opval.val->type);
3627 /*------------------------------------------------------------------*/
3628 /*----------------------------*/
3629 /* conditional operator '?' */
3630 /*----------------------------*/
3632 /* the type is value of the colon operator (on the right) */
3633 assert(IS_COLON_OP(tree->right));
3634 /* if already known then replace the tree : optimizer will do it
3635 but faster to do it here */
3636 if (IS_LITERAL (LTYPE(tree))) {
3637 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3638 return decorateType(tree->right->left) ;
3640 return decorateType(tree->right->right) ;
3643 tree->right = decorateType(tree->right);
3644 TTYPE (tree) = RTYPE(tree);
3645 TETYPE (tree) = getSpec (TTYPE (tree));
3650 /* if they don't match we have a problem */
3651 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3653 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3654 goto errorTreeReturn;
3657 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3658 TETYPE (tree) = getSpec (TTYPE (tree));
3662 #if 0 // assignment operators are converted by the parser
3663 /*------------------------------------------------------------------*/
3664 /*----------------------------*/
3665 /* assignment operators */
3666 /*----------------------------*/
3669 /* for these it must be both must be integral */
3670 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3671 !IS_ARITHMETIC (RTYPE (tree)))
3673 werror (E_OPS_INTEGRAL);
3674 goto errorTreeReturn;
3677 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3679 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3680 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3684 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3685 goto errorTreeReturn;
3696 /* for these it must be both must be integral */
3697 if (!IS_INTEGRAL (LTYPE (tree)) ||
3698 !IS_INTEGRAL (RTYPE (tree)))
3700 werror (E_OPS_INTEGRAL);
3701 goto errorTreeReturn;
3704 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3706 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3707 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3711 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3712 goto errorTreeReturn;
3718 /*------------------------------------------------------------------*/
3719 /*----------------------------*/
3721 /*----------------------------*/
3723 if (!(IS_PTR (LTYPE (tree)) ||
3724 IS_ARITHMETIC (LTYPE (tree))))
3726 werror (E_PLUS_INVALID, "-=");
3727 goto errorTreeReturn;
3730 if (!(IS_PTR (RTYPE (tree)) ||
3731 IS_ARITHMETIC (RTYPE (tree))))
3733 werror (E_PLUS_INVALID, "-=");
3734 goto errorTreeReturn;
3737 TETYPE (tree) = getSpec (TTYPE (tree) =
3738 computeType (LTYPE (tree),
3742 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3743 werror (E_CODE_WRITE, "-=");
3747 werror (E_LVALUE_REQUIRED, "-=");
3748 goto errorTreeReturn;
3754 /*------------------------------------------------------------------*/
3755 /*----------------------------*/
3757 /*----------------------------*/
3759 /* this is not a unary operation */
3760 /* if both pointers then problem */
3761 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3763 werror (E_PTR_PLUS_PTR);
3764 goto errorTreeReturn;
3767 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3769 werror (E_PLUS_INVALID, "+=");
3770 goto errorTreeReturn;
3773 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3775 werror (E_PLUS_INVALID, "+=");
3776 goto errorTreeReturn;
3779 TETYPE (tree) = getSpec (TTYPE (tree) =
3780 computeType (LTYPE (tree),
3784 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3785 werror (E_CODE_WRITE, "+=");
3789 werror (E_LVALUE_REQUIRED, "+=");
3790 goto errorTreeReturn;
3793 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3794 tree->opval.op = '=';
3799 /*------------------------------------------------------------------*/
3800 /*----------------------------*/
3801 /* straight assignemnt */
3802 /*----------------------------*/
3804 /* cannot be an aggregate */
3805 if (IS_AGGREGATE (LTYPE (tree)))
3807 werror (E_AGGR_ASSIGN);
3808 goto errorTreeReturn;
3811 /* they should either match or be castable */
3812 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3814 werror (E_TYPE_MISMATCH, "assignment", " ");
3815 printFromToType(RTYPE(tree),LTYPE(tree));
3818 /* if the left side of the tree is of type void
3819 then report error */
3820 if (IS_VOID (LTYPE (tree)))
3822 werror (E_CAST_ZERO);
3823 printFromToType(RTYPE(tree), LTYPE(tree));
3826 TETYPE (tree) = getSpec (TTYPE (tree) =
3830 if (!tree->initMode ) {
3831 if (IS_CONSTANT(LTYPE(tree)))
3832 werror (E_CODE_WRITE, "=");
3836 werror (E_LVALUE_REQUIRED, "=");
3837 goto errorTreeReturn;
3842 /*------------------------------------------------------------------*/
3843 /*----------------------------*/
3844 /* comma operator */
3845 /*----------------------------*/
3847 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3850 /*------------------------------------------------------------------*/
3851 /*----------------------------*/
3853 /*----------------------------*/
3857 if (processParms (tree->left,
3858 FUNC_ARGS(tree->left->ftype),
3859 tree->right, &parmNumber, TRUE)) {
3860 goto errorTreeReturn;
3863 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3864 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3866 reverseParms (tree->right);
3869 if (IS_CODEPTR(LTYPE(tree))) {
3870 TTYPE(tree) = LTYPE(tree)->next->next;
3872 TTYPE(tree) = LTYPE(tree)->next;
3874 TETYPE (tree) = getSpec (TTYPE (tree));
3877 /*------------------------------------------------------------------*/
3878 /*----------------------------*/
3879 /* return statement */
3880 /*----------------------------*/
3885 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3887 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
3888 printFromToType (RTYPE(tree), currFunc->type->next);
3889 goto errorTreeReturn;
3892 if (IS_VOID (currFunc->type->next)
3894 !IS_VOID (RTYPE (tree)))
3896 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
3897 goto errorTreeReturn;
3900 /* if there is going to be a casing required then add it */
3901 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3904 decorateType (newNode (CAST,
3905 newAst_LINK (copyLinkChain (currFunc->type->next)),
3914 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3916 werror (W_VOID_FUNC, currFunc->name);
3917 goto errorTreeReturn;
3920 TTYPE (tree) = TETYPE (tree) = NULL;
3923 /*------------------------------------------------------------------*/
3924 /*----------------------------*/
3925 /* switch statement */
3926 /*----------------------------*/
3928 /* the switch value must be an integer */
3929 if (!IS_INTEGRAL (LTYPE (tree)))
3931 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
3932 goto errorTreeReturn;
3935 TTYPE (tree) = TETYPE (tree) = NULL;
3938 /*------------------------------------------------------------------*/
3939 /*----------------------------*/
3941 /*----------------------------*/
3943 tree->left = backPatchLabels (tree->left,
3946 TTYPE (tree) = TETYPE (tree) = NULL;
3949 /*------------------------------------------------------------------*/
3950 /*----------------------------*/
3952 /*----------------------------*/
3955 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3956 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3957 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3959 /* if the for loop is reversible then
3960 reverse it otherwise do what we normally
3966 if (isLoopReversible (tree, &sym, &init, &end))
3967 return reverseLoop (tree, sym, init, end);
3969 return decorateType (createFor (AST_FOR (tree, trueLabel),
3970 AST_FOR (tree, continueLabel),
3971 AST_FOR (tree, falseLabel),
3972 AST_FOR (tree, condLabel),
3973 AST_FOR (tree, initExpr),
3974 AST_FOR (tree, condExpr),
3975 AST_FOR (tree, loopExpr),
3979 TTYPE (tree) = TETYPE (tree) = NULL;
3983 /* some error found this tree will be killed */
3985 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3986 tree->opval.op = NULLOP;
3992 /*-----------------------------------------------------------------*/
3993 /* sizeofOp - processes size of operation */
3994 /*-----------------------------------------------------------------*/
3996 sizeofOp (sym_link * type)
4000 /* make sure the type is complete and sane */
4001 checkTypeSanity(type, "(sizeof)");
4003 /* get the size and convert it to character */
4004 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4006 /* now convert into value */
4007 return constVal (buff);
4011 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4012 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4013 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4014 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4015 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4016 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4017 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4019 /*-----------------------------------------------------------------*/
4020 /* backPatchLabels - change and or not operators to flow control */
4021 /*-----------------------------------------------------------------*/
4023 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4029 if (!(IS_ANDORNOT (tree)))
4032 /* if this an and */
4035 static int localLbl = 0;
4038 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4039 localLabel = newSymbol (buffer, NestLevel);
4041 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4043 /* if left is already a IFX then just change the if true label in that */
4044 if (!IS_IFX (tree->left))
4045 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4047 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4048 /* right is a IFX then just join */
4049 if (IS_IFX (tree->right))
4050 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4052 tree->right = createLabel (localLabel, tree->right);
4053 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4055 return newNode (NULLOP, tree->left, tree->right);
4058 /* if this is an or operation */
4061 static int localLbl = 0;
4064 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4065 localLabel = newSymbol (buffer, NestLevel);
4067 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4069 /* if left is already a IFX then just change the if true label in that */
4070 if (!IS_IFX (tree->left))
4071 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4073 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4074 /* right is a IFX then just join */
4075 if (IS_IFX (tree->right))
4076 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4078 tree->right = createLabel (localLabel, tree->right);
4079 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4081 return newNode (NULLOP, tree->left, tree->right);
4087 int wasnot = IS_NOT (tree->left);
4088 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4090 /* if the left is already a IFX */
4091 if (!IS_IFX (tree->left))
4092 tree->left = newNode (IFX, tree->left, NULL);
4096 tree->left->trueLabel = trueLabel;
4097 tree->left->falseLabel = falseLabel;
4101 tree->left->trueLabel = falseLabel;
4102 tree->left->falseLabel = trueLabel;
4109 tree->trueLabel = trueLabel;
4110 tree->falseLabel = falseLabel;
4117 /*-----------------------------------------------------------------*/
4118 /* createBlock - create expression tree for block */
4119 /*-----------------------------------------------------------------*/
4121 createBlock (symbol * decl, ast * body)
4125 /* if the block has nothing */
4129 ex = newNode (BLOCK, NULL, body);
4130 ex->values.sym = decl;
4132 ex->right = ex->right;
4138 /*-----------------------------------------------------------------*/
4139 /* createLabel - creates the expression tree for labels */
4140 /*-----------------------------------------------------------------*/
4142 createLabel (symbol * label, ast * stmnt)
4145 char name[SDCC_NAME_MAX + 1];
4148 /* must create fresh symbol if the symbol name */
4149 /* exists in the symbol table, since there can */
4150 /* be a variable with the same name as the labl */
4151 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4152 (csym->level == label->level))
4153 label = newSymbol (label->name, label->level);
4155 /* change the name before putting it in add _ */
4156 SNPRINTF(name, sizeof(name), "%s", label->name);
4158 /* put the label in the LabelSymbol table */
4159 /* but first check if a label of the same */
4161 if ((csym = findSym (LabelTab, NULL, name)))
4162 werror (E_DUPLICATE_LABEL, label->name);
4164 addSym (LabelTab, label, name, label->level, 0, 0);
4167 label->key = labelKey++;
4168 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4174 /*-----------------------------------------------------------------*/
4175 /* createCase - generates the parsetree for a case statement */
4176 /*-----------------------------------------------------------------*/
4178 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4180 char caseLbl[SDCC_NAME_MAX + 1];
4184 /* if the switch statement does not exist */
4185 /* then case is out of context */
4188 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4192 caseVal = decorateType (resolveSymbols (caseVal));
4193 /* if not a constant then error */
4194 if (!IS_LITERAL (caseVal->ftype))
4196 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4200 /* if not a integer than error */
4201 if (!IS_INTEGRAL (caseVal->ftype))
4203 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4207 /* find the end of the switch values chain */
4208 if (!(val = swStat->values.switchVals.swVals))
4209 swStat->values.switchVals.swVals = caseVal->opval.val;
4212 /* also order the cases according to value */
4214 int cVal = (int) floatFromVal (caseVal->opval.val);
4215 while (val && (int) floatFromVal (val) < cVal)
4221 /* if we reached the end then */
4224 pval->next = caseVal->opval.val;
4226 else if ((int) floatFromVal (val) == cVal)
4228 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4234 /* we found a value greater than */
4235 /* the current value we must add this */
4236 /* before the value */
4237 caseVal->opval.val->next = val;
4239 /* if this was the first in chain */
4240 if (swStat->values.switchVals.swVals == val)
4241 swStat->values.switchVals.swVals =
4244 pval->next = caseVal->opval.val;
4249 /* create the case label */
4250 SNPRINTF(caseLbl, sizeof(caseLbl),
4252 swStat->values.switchVals.swNum,
4253 (int) floatFromVal (caseVal->opval.val));
4255 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4260 /*-----------------------------------------------------------------*/
4261 /* createDefault - creates the parse tree for the default statement */
4262 /*-----------------------------------------------------------------*/
4264 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4266 char defLbl[SDCC_NAME_MAX + 1];
4268 /* if the switch statement does not exist */
4269 /* then case is out of context */
4272 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4276 if (swStat->values.switchVals.swDefault)
4278 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4283 /* turn on the default flag */
4284 swStat->values.switchVals.swDefault = 1;
4286 /* create the label */
4287 SNPRINTF (defLbl, sizeof(defLbl),
4288 "_default_%d", swStat->values.switchVals.swNum);
4289 return createLabel (newSymbol (defLbl, 0), stmnt);
4292 /*-----------------------------------------------------------------*/
4293 /* createIf - creates the parsetree for the if statement */
4294 /*-----------------------------------------------------------------*/
4296 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4298 static int Lblnum = 0;
4300 symbol *ifTrue, *ifFalse, *ifEnd;
4302 /* if neither exists */
4303 if (!elseBody && !ifBody) {
4304 // if there are no side effects (i++, j() etc)
4305 if (!hasSEFcalls(condAst)) {
4310 /* create the labels */
4311 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4312 ifFalse = newSymbol (buffer, NestLevel);
4313 /* if no else body then end == false */
4318 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4319 ifEnd = newSymbol (buffer, NestLevel);
4322 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4323 ifTrue = newSymbol (buffer, NestLevel);
4327 /* attach the ifTrue label to the top of it body */
4328 ifBody = createLabel (ifTrue, ifBody);
4329 /* attach a goto end to the ifBody if else is present */
4332 ifBody = newNode (NULLOP, ifBody,
4334 newAst_VALUE (symbolVal (ifEnd)),
4336 /* put the elseLabel on the else body */
4337 elseBody = createLabel (ifFalse, elseBody);
4338 /* out the end at the end of the body */
4339 elseBody = newNode (NULLOP,
4341 createLabel (ifEnd, NULL));
4345 ifBody = newNode (NULLOP, ifBody,
4346 createLabel (ifFalse, NULL));
4348 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4349 if (IS_IFX (condAst))
4352 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4354 return newNode (NULLOP, ifTree,
4355 newNode (NULLOP, ifBody, elseBody));
4359 /*-----------------------------------------------------------------*/
4360 /* createDo - creates parse tree for do */
4363 /* _docontinue_n: */
4364 /* condition_expression +-> trueLabel -> _dobody_n */
4366 /* +-> falseLabel-> _dobreak_n */
4368 /*-----------------------------------------------------------------*/
4370 createDo (symbol * trueLabel, symbol * continueLabel,
4371 symbol * falseLabel, ast * condAst, ast * doBody)
4376 /* if the body does not exist then it is simple */
4379 condAst = backPatchLabels (condAst, continueLabel, NULL);
4380 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4381 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4382 doTree->trueLabel = continueLabel;
4383 doTree->falseLabel = NULL;
4387 /* otherwise we have a body */
4388 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4390 /* attach the body label to the top */
4391 doBody = createLabel (trueLabel, doBody);
4392 /* attach the continue label to end of body */
4393 doBody = newNode (NULLOP, doBody,
4394 createLabel (continueLabel, NULL));
4396 /* now put the break label at the end */
4397 if (IS_IFX (condAst))
4400 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4402 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4404 /* putting it together */
4405 return newNode (NULLOP, doBody, doTree);
4408 /*-----------------------------------------------------------------*/
4409 /* createFor - creates parse tree for 'for' statement */
4412 /* condExpr +-> trueLabel -> _forbody_n */
4414 /* +-> falseLabel-> _forbreak_n */
4417 /* _forcontinue_n: */
4419 /* goto _forcond_n ; */
4421 /*-----------------------------------------------------------------*/
4423 createFor (symbol * trueLabel, symbol * continueLabel,
4424 symbol * falseLabel, symbol * condLabel,
4425 ast * initExpr, ast * condExpr, ast * loopExpr,
4430 /* if loopexpression not present then we can generate it */
4431 /* the same way as a while */
4433 return newNode (NULLOP, initExpr,
4434 createWhile (trueLabel, continueLabel,
4435 falseLabel, condExpr, forBody));
4436 /* vanilla for statement */
4437 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4439 if (condExpr && !IS_IFX (condExpr))
4440 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4443 /* attach condition label to condition */
4444 condExpr = createLabel (condLabel, condExpr);
4446 /* attach body label to body */
4447 forBody = createLabel (trueLabel, forBody);
4449 /* attach continue to forLoop expression & attach */
4450 /* goto the forcond @ and of loopExpression */
4451 loopExpr = createLabel (continueLabel,
4455 newAst_VALUE (symbolVal (condLabel)),
4457 /* now start putting them together */
4458 forTree = newNode (NULLOP, initExpr, condExpr);
4459 forTree = newNode (NULLOP, forTree, forBody);
4460 forTree = newNode (NULLOP, forTree, loopExpr);
4461 /* finally add the break label */
4462 forTree = newNode (NULLOP, forTree,
4463 createLabel (falseLabel, NULL));
4467 /*-----------------------------------------------------------------*/
4468 /* createWhile - creates parse tree for while statement */
4469 /* the while statement will be created as follows */
4471 /* _while_continue_n: */
4472 /* condition_expression +-> trueLabel -> _while_boby_n */
4474 /* +-> falseLabel -> _while_break_n */
4475 /* _while_body_n: */
4477 /* goto _while_continue_n */
4478 /* _while_break_n: */
4479 /*-----------------------------------------------------------------*/
4481 createWhile (symbol * trueLabel, symbol * continueLabel,
4482 symbol * falseLabel, ast * condExpr, ast * whileBody)
4486 /* put the continue label */
4487 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4488 condExpr = createLabel (continueLabel, condExpr);
4489 condExpr->lineno = 0;
4491 /* put the body label in front of the body */
4492 whileBody = createLabel (trueLabel, whileBody);
4493 whileBody->lineno = 0;
4494 /* put a jump to continue at the end of the body */
4495 /* and put break label at the end of the body */
4496 whileBody = newNode (NULLOP,
4499 newAst_VALUE (symbolVal (continueLabel)),
4500 createLabel (falseLabel, NULL)));
4502 /* put it all together */
4503 if (IS_IFX (condExpr))
4504 whileTree = condExpr;
4507 whileTree = newNode (IFX, condExpr, NULL);
4508 /* put the true & false labels in place */
4509 whileTree->trueLabel = trueLabel;
4510 whileTree->falseLabel = falseLabel;
4513 return newNode (NULLOP, whileTree, whileBody);
4516 /*-----------------------------------------------------------------*/
4517 /* optimizeGetHbit - get highest order bit of the expression */
4518 /*-----------------------------------------------------------------*/
4520 optimizeGetHbit (ast * tree)
4523 /* if this is not a bit and */
4524 if (!IS_BITAND (tree))
4527 /* will look for tree of the form
4528 ( expr >> ((sizeof expr) -1) ) & 1 */
4529 if (!IS_AST_LIT_VALUE (tree->right))
4532 if (AST_LIT_VALUE (tree->right) != 1)
4535 if (!IS_RIGHT_OP (tree->left))
4538 if (!IS_AST_LIT_VALUE (tree->left->right))
4541 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4542 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4545 /* make sure the port supports GETHBIT */
4546 if (port->hasExtBitOp
4547 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4550 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4554 /*-----------------------------------------------------------------*/
4555 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4556 /*-----------------------------------------------------------------*/
4558 optimizeRRCRLC (ast * root)
4560 /* will look for trees of the form
4561 (?expr << 1) | (?expr >> 7) or
4562 (?expr >> 7) | (?expr << 1) will make that
4563 into a RLC : operation ..
4565 (?expr >> 1) | (?expr << 7) or
4566 (?expr << 7) | (?expr >> 1) will make that
4567 into a RRC operation
4568 note : by 7 I mean (number of bits required to hold the
4570 /* if the root operations is not a | operation the not */
4571 if (!IS_BITOR (root))
4574 /* I have to think of a better way to match patterns this sucks */
4575 /* that aside let start looking for the first case : I use a the
4576 negative check a lot to improve the efficiency */
4577 /* (?expr << 1) | (?expr >> 7) */
4578 if (IS_LEFT_OP (root->left) &&
4579 IS_RIGHT_OP (root->right))
4582 if (!SPEC_USIGN (TETYPE (root->left->left)))
4585 if (!IS_AST_LIT_VALUE (root->left->right) ||
4586 !IS_AST_LIT_VALUE (root->right->right))
4589 /* make sure it is the same expression */
4590 if (!isAstEqual (root->left->left,
4594 if (AST_LIT_VALUE (root->left->right) != 1)
4597 if (AST_LIT_VALUE (root->right->right) !=
4598 (getSize (TTYPE (root->left->left)) * 8 - 1))
4601 /* make sure the port supports RLC */
4602 if (port->hasExtBitOp
4603 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4606 /* whew got the first case : create the AST */
4607 return newNode (RLC, root->left->left, NULL);
4611 /* check for second case */
4612 /* (?expr >> 7) | (?expr << 1) */
4613 if (IS_LEFT_OP (root->right) &&
4614 IS_RIGHT_OP (root->left))
4617 if (!SPEC_USIGN (TETYPE (root->left->left)))
4620 if (!IS_AST_LIT_VALUE (root->left->right) ||
4621 !IS_AST_LIT_VALUE (root->right->right))
4624 /* make sure it is the same symbol */
4625 if (!isAstEqual (root->left->left,
4629 if (AST_LIT_VALUE (root->right->right) != 1)
4632 if (AST_LIT_VALUE (root->left->right) !=
4633 (getSize (TTYPE (root->left->left)) * 8 - 1))
4636 /* make sure the port supports RLC */
4637 if (port->hasExtBitOp
4638 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4641 /* whew got the first case : create the AST */
4642 return newNode (RLC, root->left->left, NULL);
4647 /* third case for RRC */
4648 /* (?symbol >> 1) | (?symbol << 7) */
4649 if (IS_LEFT_OP (root->right) &&
4650 IS_RIGHT_OP (root->left))
4653 if (!SPEC_USIGN (TETYPE (root->left->left)))
4656 if (!IS_AST_LIT_VALUE (root->left->right) ||
4657 !IS_AST_LIT_VALUE (root->right->right))
4660 /* make sure it is the same symbol */
4661 if (!isAstEqual (root->left->left,
4665 if (AST_LIT_VALUE (root->left->right) != 1)
4668 if (AST_LIT_VALUE (root->right->right) !=
4669 (getSize (TTYPE (root->left->left)) * 8 - 1))
4672 /* make sure the port supports RRC */
4673 if (port->hasExtBitOp
4674 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4677 /* whew got the first case : create the AST */
4678 return newNode (RRC, root->left->left, NULL);
4682 /* fourth and last case for now */
4683 /* (?symbol << 7) | (?symbol >> 1) */
4684 if (IS_RIGHT_OP (root->right) &&
4685 IS_LEFT_OP (root->left))
4688 if (!SPEC_USIGN (TETYPE (root->left->left)))
4691 if (!IS_AST_LIT_VALUE (root->left->right) ||
4692 !IS_AST_LIT_VALUE (root->right->right))
4695 /* make sure it is the same symbol */
4696 if (!isAstEqual (root->left->left,
4700 if (AST_LIT_VALUE (root->right->right) != 1)
4703 if (AST_LIT_VALUE (root->left->right) !=
4704 (getSize (TTYPE (root->left->left)) * 8 - 1))
4707 /* make sure the port supports RRC */
4708 if (port->hasExtBitOp
4709 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4712 /* whew got the first case : create the AST */
4713 return newNode (RRC, root->left->left, NULL);
4717 /* not found return root */
4721 /*-----------------------------------------------------------------*/
4722 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4723 /*-----------------------------------------------------------------*/
4725 optimizeSWAP (ast * root)
4727 /* will look for trees of the form
4728 (?expr << 4) | (?expr >> 4) or
4729 (?expr >> 4) | (?expr << 4) will make that
4730 into a SWAP : operation ..
4731 note : by 4 I mean (number of bits required to hold the
4733 /* if the root operations is not a | operation the not */
4734 if (!IS_BITOR (root))
4737 /* (?expr << 4) | (?expr >> 4) */
4738 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4739 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4742 if (!SPEC_USIGN (TETYPE (root->left->left)))
4745 if (!IS_AST_LIT_VALUE (root->left->right) ||
4746 !IS_AST_LIT_VALUE (root->right->right))
4749 /* make sure it is the same expression */
4750 if (!isAstEqual (root->left->left,
4754 if (AST_LIT_VALUE (root->left->right) !=
4755 (getSize (TTYPE (root->left->left)) * 4))
4758 if (AST_LIT_VALUE (root->right->right) !=
4759 (getSize (TTYPE (root->left->left)) * 4))
4762 /* make sure the port supports SWAP */
4763 if (port->hasExtBitOp
4764 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4767 /* found it : create the AST */
4768 return newNode (SWAP, root->left->left, NULL);
4772 /* not found return root */
4776 /*-----------------------------------------------------------------*/
4777 /* optimizeCompare - otimizes compares for bit variables */
4778 /*-----------------------------------------------------------------*/
4780 optimizeCompare (ast * root)
4782 ast *optExpr = NULL;
4785 unsigned int litValue;
4787 /* if nothing then return nothing */
4791 /* if not a compare op then do leaves */
4792 if (!IS_COMPARE_OP (root))
4794 root->left = optimizeCompare (root->left);
4795 root->right = optimizeCompare (root->right);
4799 /* if left & right are the same then depending
4800 of the operation do */
4801 if (isAstEqual (root->left, root->right))
4803 switch (root->opval.op)
4808 optExpr = newAst_VALUE (constVal ("0"));
4813 optExpr = newAst_VALUE (constVal ("1"));
4817 return decorateType (optExpr);
4820 vleft = (root->left->type == EX_VALUE ?
4821 root->left->opval.val : NULL);
4823 vright = (root->right->type == EX_VALUE ?
4824 root->right->opval.val : NULL);
4826 /* if left is a BITVAR in BITSPACE */
4827 /* and right is a LITERAL then opt- */
4828 /* imize else do nothing */
4829 if (vleft && vright &&
4830 IS_BITVAR (vleft->etype) &&
4831 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4832 IS_LITERAL (vright->etype))
4835 /* if right side > 1 then comparison may never succeed */
4836 if ((litValue = (int) floatFromVal (vright)) > 1)
4838 werror (W_BAD_COMPARE);
4844 switch (root->opval.op)
4846 case '>': /* bit value greater than 1 cannot be */
4847 werror (W_BAD_COMPARE);
4851 case '<': /* bit value < 1 means 0 */
4853 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4856 case LE_OP: /* bit value <= 1 means no check */
4857 optExpr = newAst_VALUE (vright);
4860 case GE_OP: /* bit value >= 1 means only check for = */
4862 optExpr = newAst_VALUE (vleft);
4867 { /* literal is zero */
4868 switch (root->opval.op)
4870 case '<': /* bit value < 0 cannot be */
4871 werror (W_BAD_COMPARE);
4875 case '>': /* bit value > 0 means 1 */
4877 optExpr = newAst_VALUE (vleft);
4880 case LE_OP: /* bit value <= 0 means no check */
4881 case GE_OP: /* bit value >= 0 means no check */
4882 werror (W_BAD_COMPARE);
4886 case EQ_OP: /* bit == 0 means ! of bit */
4887 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4891 return decorateType (resolveSymbols (optExpr));
4892 } /* end-of-if of BITVAR */
4897 /*-----------------------------------------------------------------*/
4898 /* addSymToBlock : adds the symbol to the first block we find */
4899 /*-----------------------------------------------------------------*/
4901 addSymToBlock (symbol * sym, ast * tree)
4903 /* reached end of tree or a leaf */
4904 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4908 if (IS_AST_OP (tree) &&
4909 tree->opval.op == BLOCK)
4912 symbol *lsym = copySymbol (sym);
4914 lsym->next = AST_VALUES (tree, sym);
4915 AST_VALUES (tree, sym) = lsym;
4919 addSymToBlock (sym, tree->left);
4920 addSymToBlock (sym, tree->right);
4923 /*-----------------------------------------------------------------*/
4924 /* processRegParms - do processing for register parameters */
4925 /*-----------------------------------------------------------------*/
4927 processRegParms (value * args, ast * body)
4931 if (IS_REGPARM (args->etype))
4932 addSymToBlock (args->sym, body);
4937 /*-----------------------------------------------------------------*/
4938 /* resetParmKey - resets the operandkeys for the symbols */
4939 /*-----------------------------------------------------------------*/
4940 DEFSETFUNC (resetParmKey)
4951 /*-----------------------------------------------------------------*/
4952 /* createFunction - This is the key node that calls the iCode for */
4953 /* generating the code for a function. Note code */
4954 /* is generated function by function, later when */
4955 /* add inter-procedural analysis this will change */
4956 /*-----------------------------------------------------------------*/
4958 createFunction (symbol * name, ast * body)
4964 iCode *piCode = NULL;
4966 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4967 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4969 /* if check function return 0 then some problem */
4970 if (checkFunction (name, NULL) == 0)
4973 /* create a dummy block if none exists */
4975 body = newNode (BLOCK, NULL, NULL);
4979 /* check if the function name already in the symbol table */
4980 if ((csym = findSym (SymbolTab, NULL, name->name)))
4983 /* special case for compiler defined functions
4984 we need to add the name to the publics list : this
4985 actually means we are now compiling the compiler
4989 addSet (&publics, name);
4995 allocVariables (name);
4997 name->lastLine = mylineno;
5000 /* set the stack pointer */
5001 /* PENDING: check this for the mcs51 */
5002 stackPtr = -port->stack.direction * port->stack.call_overhead;
5003 if (IFFUNC_ISISR (name->type))
5004 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5005 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5006 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5008 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5010 fetype = getSpec (name->type); /* get the specifier for the function */
5011 /* if this is a reentrant function then */
5012 if (IFFUNC_ISREENT (name->type))
5015 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5017 /* do processing for parameters that are passed in registers */
5018 processRegParms (FUNC_ARGS(name->type), body);
5020 /* set the stack pointer */
5024 /* allocate & autoinit the block variables */
5025 processBlockVars (body, &stack, ALLOCATE);
5027 /* save the stack information */
5028 if (options.useXstack)
5029 name->xstack = SPEC_STAK (fetype) = stack;
5031 name->stack = SPEC_STAK (fetype) = stack;
5033 /* name needs to be mangled */
5034 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5036 body = resolveSymbols (body); /* resolve the symbols */
5037 body = decorateType (body); /* propagateType & do semantic checks */
5039 ex = newAst_VALUE (symbolVal (name)); /* create name */
5040 ex = newNode (FUNCTION, ex, body);
5041 ex->values.args = FUNC_ARGS(name->type);
5043 if (options.dump_tree) PA(ex);
5046 werror (E_FUNC_NO_CODE, name->name);
5050 /* create the node & generate intermediate code */
5052 codeOutFile = code->oFile;
5053 piCode = iCodeFromAst (ex);
5057 werror (E_FUNC_NO_CODE, name->name);
5061 eBBlockFromiCode (piCode);
5063 /* if there are any statics then do them */
5066 GcurMemmap = statsg;
5067 codeOutFile = statsg->oFile;
5068 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
5074 /* dealloc the block variables */
5075 processBlockVars (body, &stack, DEALLOCATE);
5076 outputDebugStackSymbols();
5077 /* deallocate paramaters */
5078 deallocParms (FUNC_ARGS(name->type));
5080 if (IFFUNC_ISREENT (name->type))
5083 /* we are done freeup memory & cleanup */
5085 if (port->reset_labelKey) labelKey = 1;
5087 FUNC_HASBODY(name->type) = 1;
5088 addSet (&operKeyReset, name);
5089 applyToSet (operKeyReset, resetParmKey);
5094 cleanUpLevel (LabelTab, 0);
5095 cleanUpBlock (StructTab, 1);
5096 cleanUpBlock (TypedefTab, 1);
5098 xstack->syms = NULL;
5099 istack->syms = NULL;
5104 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5105 /*-----------------------------------------------------------------*/
5106 /* ast_print : prints the ast (for debugging purposes) */
5107 /*-----------------------------------------------------------------*/
5109 void ast_print (ast * tree, FILE *outfile, int indent)
5114 /* can print only decorated trees */
5115 if (!tree->decorated) return;
5117 /* if any child is an error | this one is an error do nothing */
5118 if (tree->isError ||
5119 (tree->left && tree->left->isError) ||
5120 (tree->right && tree->right->isError)) {
5121 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5125 /* print the line */
5126 /* if not block & function */
5127 if (tree->type == EX_OP &&
5128 (tree->opval.op != FUNCTION &&
5129 tree->opval.op != BLOCK &&
5130 tree->opval.op != NULLOP)) {
5133 if (tree->opval.op == FUNCTION) {
5135 value *args=FUNC_ARGS(tree->left->opval.val->type);
5136 fprintf(outfile,"FUNCTION (%s=%p) type (",
5137 tree->left->opval.val->name, tree);
5138 printTypeChain (tree->left->opval.val->type->next,outfile);
5139 fprintf(outfile,") args (");
5142 fprintf (outfile, ", ");
5144 printTypeChain (args ? args->type : NULL, outfile);
5146 args= args ? args->next : NULL;
5148 fprintf(outfile,")\n");
5149 ast_print(tree->left,outfile,indent);
5150 ast_print(tree->right,outfile,indent);
5153 if (tree->opval.op == BLOCK) {
5154 symbol *decls = tree->values.sym;
5155 INDENT(indent,outfile);
5156 fprintf(outfile,"{\n");
5158 INDENT(indent+2,outfile);
5159 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5160 decls->name, decls);
5161 printTypeChain(decls->type,outfile);
5162 fprintf(outfile,")\n");
5164 decls = decls->next;
5166 ast_print(tree->right,outfile,indent+2);
5167 INDENT(indent,outfile);
5168 fprintf(outfile,"}\n");
5171 if (tree->opval.op == NULLOP) {
5172 ast_print(tree->left,outfile,indent);
5173 ast_print(tree->right,outfile,indent);
5176 INDENT(indent,outfile);
5178 /*------------------------------------------------------------------*/
5179 /*----------------------------*/
5180 /* leaf has been reached */
5181 /*----------------------------*/
5182 /* if this is of type value */
5183 /* just get the type */
5184 if (tree->type == EX_VALUE) {
5186 if (IS_LITERAL (tree->opval.val->etype)) {
5187 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5188 if (SPEC_USIGN (tree->opval.val->etype))
5189 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5191 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5192 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5193 floatFromVal(tree->opval.val));
5194 } else if (tree->opval.val->sym) {
5195 /* if the undefined flag is set then give error message */
5196 if (tree->opval.val->sym->undefined) {
5197 fprintf(outfile,"UNDEFINED SYMBOL ");
5199 fprintf(outfile,"SYMBOL ");
5201 fprintf(outfile,"(%s=%p)",
5202 tree->opval.val->sym->name,tree);
5205 fprintf(outfile," type (");
5206 printTypeChain(tree->ftype,outfile);
5207 fprintf(outfile,")\n");
5209 fprintf(outfile,"\n");
5214 /* if type link for the case of cast */
5215 if (tree->type == EX_LINK) {
5216 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5217 printTypeChain(tree->opval.lnk,outfile);
5218 fprintf(outfile,")\n");
5223 /* depending on type of operator do */
5225 switch (tree->opval.op) {
5226 /*------------------------------------------------------------------*/
5227 /*----------------------------*/
5229 /*----------------------------*/
5231 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5232 printTypeChain(tree->ftype,outfile);
5233 fprintf(outfile,")\n");
5234 ast_print(tree->left,outfile,indent+2);
5235 ast_print(tree->right,outfile,indent+2);
5238 /*------------------------------------------------------------------*/
5239 /*----------------------------*/
5241 /*----------------------------*/
5243 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5244 printTypeChain(tree->ftype,outfile);
5245 fprintf(outfile,")\n");
5246 ast_print(tree->left,outfile,indent+2);
5247 ast_print(tree->right,outfile,indent+2);
5250 /*------------------------------------------------------------------*/
5251 /*----------------------------*/
5252 /* struct/union pointer */
5253 /*----------------------------*/
5255 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5256 printTypeChain(tree->ftype,outfile);
5257 fprintf(outfile,")\n");
5258 ast_print(tree->left,outfile,indent+2);
5259 ast_print(tree->right,outfile,indent+2);
5262 /*------------------------------------------------------------------*/
5263 /*----------------------------*/
5264 /* ++/-- operation */
5265 /*----------------------------*/
5268 fprintf(outfile,"post-");
5270 fprintf(outfile,"pre-");
5271 fprintf(outfile,"INC_OP (%p) type (",tree);
5272 printTypeChain(tree->ftype,outfile);
5273 fprintf(outfile,")\n");
5274 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5275 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5280 fprintf(outfile,"post-");
5282 fprintf(outfile,"pre-");
5283 fprintf(outfile,"DEC_OP (%p) type (",tree);
5284 printTypeChain(tree->ftype,outfile);
5285 fprintf(outfile,")\n");
5286 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5287 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5290 /*------------------------------------------------------------------*/
5291 /*----------------------------*/
5293 /*----------------------------*/
5296 fprintf(outfile,"& (%p) type (",tree);
5297 printTypeChain(tree->ftype,outfile);
5298 fprintf(outfile,")\n");
5299 ast_print(tree->left,outfile,indent+2);
5300 ast_print(tree->right,outfile,indent+2);
5302 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5303 printTypeChain(tree->ftype,outfile);
5304 fprintf(outfile,")\n");
5305 ast_print(tree->left,outfile,indent+2);
5306 ast_print(tree->right,outfile,indent+2);
5309 /*----------------------------*/
5311 /*----------------------------*/
5313 fprintf(outfile,"OR (%p) type (",tree);
5314 printTypeChain(tree->ftype,outfile);
5315 fprintf(outfile,")\n");
5316 ast_print(tree->left,outfile,indent+2);
5317 ast_print(tree->right,outfile,indent+2);
5319 /*------------------------------------------------------------------*/
5320 /*----------------------------*/
5322 /*----------------------------*/
5324 fprintf(outfile,"XOR (%p) type (",tree);
5325 printTypeChain(tree->ftype,outfile);
5326 fprintf(outfile,")\n");
5327 ast_print(tree->left,outfile,indent+2);
5328 ast_print(tree->right,outfile,indent+2);
5331 /*------------------------------------------------------------------*/
5332 /*----------------------------*/
5334 /*----------------------------*/
5336 fprintf(outfile,"DIV (%p) type (",tree);
5337 printTypeChain(tree->ftype,outfile);
5338 fprintf(outfile,")\n");
5339 ast_print(tree->left,outfile,indent+2);
5340 ast_print(tree->right,outfile,indent+2);
5342 /*------------------------------------------------------------------*/
5343 /*----------------------------*/
5345 /*----------------------------*/
5347 fprintf(outfile,"MOD (%p) type (",tree);
5348 printTypeChain(tree->ftype,outfile);
5349 fprintf(outfile,")\n");
5350 ast_print(tree->left,outfile,indent+2);
5351 ast_print(tree->right,outfile,indent+2);
5354 /*------------------------------------------------------------------*/
5355 /*----------------------------*/
5356 /* address dereference */
5357 /*----------------------------*/
5358 case '*': /* can be unary : if right is null then unary operation */
5360 fprintf(outfile,"DEREF (%p) type (",tree);
5361 printTypeChain(tree->ftype,outfile);
5362 fprintf(outfile,")\n");
5363 ast_print(tree->left,outfile,indent+2);
5366 /*------------------------------------------------------------------*/
5367 /*----------------------------*/
5368 /* multiplication */
5369 /*----------------------------*/
5370 fprintf(outfile,"MULT (%p) type (",tree);
5371 printTypeChain(tree->ftype,outfile);
5372 fprintf(outfile,")\n");
5373 ast_print(tree->left,outfile,indent+2);
5374 ast_print(tree->right,outfile,indent+2);
5378 /*------------------------------------------------------------------*/
5379 /*----------------------------*/
5380 /* unary '+' operator */
5381 /*----------------------------*/
5385 fprintf(outfile,"UPLUS (%p) type (",tree);
5386 printTypeChain(tree->ftype,outfile);
5387 fprintf(outfile,")\n");
5388 ast_print(tree->left,outfile,indent+2);
5390 /*------------------------------------------------------------------*/
5391 /*----------------------------*/
5393 /*----------------------------*/
5394 fprintf(outfile,"ADD (%p) type (",tree);
5395 printTypeChain(tree->ftype,outfile);
5396 fprintf(outfile,")\n");
5397 ast_print(tree->left,outfile,indent+2);
5398 ast_print(tree->right,outfile,indent+2);
5401 /*------------------------------------------------------------------*/
5402 /*----------------------------*/
5404 /*----------------------------*/
5405 case '-': /* can be unary */
5407 fprintf(outfile,"UMINUS (%p) type (",tree);
5408 printTypeChain(tree->ftype,outfile);
5409 fprintf(outfile,")\n");
5410 ast_print(tree->left,outfile,indent+2);
5412 /*------------------------------------------------------------------*/
5413 /*----------------------------*/
5415 /*----------------------------*/
5416 fprintf(outfile,"SUB (%p) type (",tree);
5417 printTypeChain(tree->ftype,outfile);
5418 fprintf(outfile,")\n");
5419 ast_print(tree->left,outfile,indent+2);
5420 ast_print(tree->right,outfile,indent+2);
5423 /*------------------------------------------------------------------*/
5424 /*----------------------------*/
5426 /*----------------------------*/
5428 fprintf(outfile,"COMPL (%p) type (",tree);
5429 printTypeChain(tree->ftype,outfile);
5430 fprintf(outfile,")\n");
5431 ast_print(tree->left,outfile,indent+2);
5433 /*------------------------------------------------------------------*/
5434 /*----------------------------*/
5436 /*----------------------------*/
5438 fprintf(outfile,"NOT (%p) type (",tree);
5439 printTypeChain(tree->ftype,outfile);
5440 fprintf(outfile,")\n");
5441 ast_print(tree->left,outfile,indent+2);
5443 /*------------------------------------------------------------------*/
5444 /*----------------------------*/
5446 /*----------------------------*/
5448 fprintf(outfile,"RRC (%p) type (",tree);
5449 printTypeChain(tree->ftype,outfile);
5450 fprintf(outfile,")\n");
5451 ast_print(tree->left,outfile,indent+2);
5455 fprintf(outfile,"RLC (%p) type (",tree);
5456 printTypeChain(tree->ftype,outfile);
5457 fprintf(outfile,")\n");
5458 ast_print(tree->left,outfile,indent+2);
5461 fprintf(outfile,"SWAP (%p) type (",tree);
5462 printTypeChain(tree->ftype,outfile);
5463 fprintf(outfile,")\n");
5464 ast_print(tree->left,outfile,indent+2);
5467 fprintf(outfile,"GETHBIT (%p) type (",tree);
5468 printTypeChain(tree->ftype,outfile);
5469 fprintf(outfile,")\n");
5470 ast_print(tree->left,outfile,indent+2);
5473 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5474 printTypeChain(tree->ftype,outfile);
5475 fprintf(outfile,")\n");
5476 ast_print(tree->left,outfile,indent+2);
5477 ast_print(tree->right,outfile,indent+2);
5480 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5481 printTypeChain(tree->ftype,outfile);
5482 fprintf(outfile,")\n");
5483 ast_print(tree->left,outfile,indent+2);
5484 ast_print(tree->right,outfile,indent+2);
5486 /*------------------------------------------------------------------*/
5487 /*----------------------------*/
5489 /*----------------------------*/
5490 case CAST: /* change the type */
5491 fprintf(outfile,"CAST (%p) from type (",tree);
5492 printTypeChain(tree->right->ftype,outfile);
5493 fprintf(outfile,") to type (");
5494 printTypeChain(tree->ftype,outfile);
5495 fprintf(outfile,")\n");
5496 ast_print(tree->right,outfile,indent+2);
5500 fprintf(outfile,"ANDAND (%p) type (",tree);
5501 printTypeChain(tree->ftype,outfile);
5502 fprintf(outfile,")\n");
5503 ast_print(tree->left,outfile,indent+2);
5504 ast_print(tree->right,outfile,indent+2);
5507 fprintf(outfile,"OROR (%p) type (",tree);
5508 printTypeChain(tree->ftype,outfile);
5509 fprintf(outfile,")\n");
5510 ast_print(tree->left,outfile,indent+2);
5511 ast_print(tree->right,outfile,indent+2);
5514 /*------------------------------------------------------------------*/
5515 /*----------------------------*/
5516 /* comparison operators */
5517 /*----------------------------*/
5519 fprintf(outfile,"GT(>) (%p) type (",tree);
5520 printTypeChain(tree->ftype,outfile);
5521 fprintf(outfile,")\n");
5522 ast_print(tree->left,outfile,indent+2);
5523 ast_print(tree->right,outfile,indent+2);
5526 fprintf(outfile,"LT(<) (%p) type (",tree);
5527 printTypeChain(tree->ftype,outfile);
5528 fprintf(outfile,")\n");
5529 ast_print(tree->left,outfile,indent+2);
5530 ast_print(tree->right,outfile,indent+2);
5533 fprintf(outfile,"LE(<=) (%p) type (",tree);
5534 printTypeChain(tree->ftype,outfile);
5535 fprintf(outfile,")\n");
5536 ast_print(tree->left,outfile,indent+2);
5537 ast_print(tree->right,outfile,indent+2);
5540 fprintf(outfile,"GE(>=) (%p) type (",tree);
5541 printTypeChain(tree->ftype,outfile);
5542 fprintf(outfile,")\n");
5543 ast_print(tree->left,outfile,indent+2);
5544 ast_print(tree->right,outfile,indent+2);
5547 fprintf(outfile,"EQ(==) (%p) type (",tree);
5548 printTypeChain(tree->ftype,outfile);
5549 fprintf(outfile,")\n");
5550 ast_print(tree->left,outfile,indent+2);
5551 ast_print(tree->right,outfile,indent+2);
5554 fprintf(outfile,"NE(!=) (%p) type (",tree);
5555 printTypeChain(tree->ftype,outfile);
5556 fprintf(outfile,")\n");
5557 ast_print(tree->left,outfile,indent+2);
5558 ast_print(tree->right,outfile,indent+2);
5559 /*------------------------------------------------------------------*/
5560 /*----------------------------*/
5562 /*----------------------------*/
5563 case SIZEOF: /* evaluate wihout code generation */
5564 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5567 /*------------------------------------------------------------------*/
5568 /*----------------------------*/
5569 /* conditional operator '?' */
5570 /*----------------------------*/
5572 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5573 printTypeChain(tree->ftype,outfile);
5574 fprintf(outfile,")\n");
5575 ast_print(tree->left,outfile,indent+2);
5576 ast_print(tree->right,outfile,indent+2);
5580 fprintf(outfile,"COLON(:) (%p) type (",tree);
5581 printTypeChain(tree->ftype,outfile);
5582 fprintf(outfile,")\n");
5583 ast_print(tree->left,outfile,indent+2);
5584 ast_print(tree->right,outfile,indent+2);
5587 /*------------------------------------------------------------------*/
5588 /*----------------------------*/
5589 /* assignment operators */
5590 /*----------------------------*/
5592 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5593 printTypeChain(tree->ftype,outfile);
5594 fprintf(outfile,")\n");
5595 ast_print(tree->left,outfile,indent+2);
5596 ast_print(tree->right,outfile,indent+2);
5599 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5600 printTypeChain(tree->ftype,outfile);
5601 fprintf(outfile,")\n");
5602 ast_print(tree->left,outfile,indent+2);
5603 ast_print(tree->right,outfile,indent+2);
5606 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5607 printTypeChain(tree->ftype,outfile);
5608 fprintf(outfile,")\n");
5609 ast_print(tree->left,outfile,indent+2);
5610 ast_print(tree->right,outfile,indent+2);
5613 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5614 printTypeChain(tree->ftype,outfile);
5615 fprintf(outfile,")\n");
5616 ast_print(tree->left,outfile,indent+2);
5617 ast_print(tree->right,outfile,indent+2);
5620 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5621 printTypeChain(tree->ftype,outfile);
5622 fprintf(outfile,")\n");
5623 ast_print(tree->left,outfile,indent+2);
5624 ast_print(tree->right,outfile,indent+2);
5627 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5628 printTypeChain(tree->ftype,outfile);
5629 fprintf(outfile,")\n");
5630 ast_print(tree->left,outfile,indent+2);
5631 ast_print(tree->right,outfile,indent+2);
5634 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5635 printTypeChain(tree->ftype,outfile);
5636 fprintf(outfile,")\n");
5637 ast_print(tree->left,outfile,indent+2);
5638 ast_print(tree->right,outfile,indent+2);
5640 /*------------------------------------------------------------------*/
5641 /*----------------------------*/
5643 /*----------------------------*/
5645 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5646 printTypeChain(tree->ftype,outfile);
5647 fprintf(outfile,")\n");
5648 ast_print(tree->left,outfile,indent+2);
5649 ast_print(tree->right,outfile,indent+2);
5651 /*------------------------------------------------------------------*/
5652 /*----------------------------*/
5654 /*----------------------------*/
5656 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5657 printTypeChain(tree->ftype,outfile);
5658 fprintf(outfile,")\n");
5659 ast_print(tree->left,outfile,indent+2);
5660 ast_print(tree->right,outfile,indent+2);
5662 /*------------------------------------------------------------------*/
5663 /*----------------------------*/
5664 /* straight assignemnt */
5665 /*----------------------------*/
5667 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5668 printTypeChain(tree->ftype,outfile);
5669 fprintf(outfile,")\n");
5670 ast_print(tree->left,outfile,indent+2);
5671 ast_print(tree->right,outfile,indent+2);
5673 /*------------------------------------------------------------------*/
5674 /*----------------------------*/
5675 /* comma operator */
5676 /*----------------------------*/
5678 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5679 printTypeChain(tree->ftype,outfile);
5680 fprintf(outfile,")\n");
5681 ast_print(tree->left,outfile,indent+2);
5682 ast_print(tree->right,outfile,indent+2);
5684 /*------------------------------------------------------------------*/
5685 /*----------------------------*/
5687 /*----------------------------*/
5690 fprintf(outfile,"CALL (%p) type (",tree);
5691 printTypeChain(tree->ftype,outfile);
5692 fprintf(outfile,")\n");
5693 ast_print(tree->left,outfile,indent+2);
5694 ast_print(tree->right,outfile,indent+2);
5697 fprintf(outfile,"PARMS\n");
5698 ast_print(tree->left,outfile,indent+2);
5699 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5700 ast_print(tree->right,outfile,indent+2);
5703 /*------------------------------------------------------------------*/
5704 /*----------------------------*/
5705 /* return statement */
5706 /*----------------------------*/
5708 fprintf(outfile,"RETURN (%p) type (",tree);
5710 printTypeChain(tree->right->ftype,outfile);
5712 fprintf(outfile,")\n");
5713 ast_print(tree->right,outfile,indent+2);
5715 /*------------------------------------------------------------------*/
5716 /*----------------------------*/
5717 /* label statement */
5718 /*----------------------------*/
5720 fprintf(outfile,"LABEL (%p)\n",tree);
5721 ast_print(tree->left,outfile,indent+2);
5722 ast_print(tree->right,outfile,indent);
5724 /*------------------------------------------------------------------*/
5725 /*----------------------------*/
5726 /* switch statement */
5727 /*----------------------------*/
5731 fprintf(outfile,"SWITCH (%p) ",tree);
5732 ast_print(tree->left,outfile,0);
5733 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5734 INDENT(indent+2,outfile);
5735 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5736 (int) floatFromVal(val),
5737 tree->values.switchVals.swNum,
5738 (int) floatFromVal(val));
5740 ast_print(tree->right,outfile,indent);
5743 /*------------------------------------------------------------------*/
5744 /*----------------------------*/
5746 /*----------------------------*/
5748 fprintf(outfile,"IF (%p) \n",tree);
5749 ast_print(tree->left,outfile,indent+2);
5750 if (tree->trueLabel) {
5751 INDENT(indent+2,outfile);
5752 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5754 if (tree->falseLabel) {
5755 INDENT(indent+2,outfile);
5756 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5758 ast_print(tree->right,outfile,indent+2);
5760 /*----------------------------*/
5761 /* goto Statement */
5762 /*----------------------------*/
5764 fprintf(outfile,"GOTO (%p) \n",tree);
5765 ast_print(tree->left,outfile,indent+2);
5766 fprintf(outfile,"\n");
5768 /*------------------------------------------------------------------*/
5769 /*----------------------------*/
5771 /*----------------------------*/
5773 fprintf(outfile,"FOR (%p) \n",tree);
5774 if (AST_FOR( tree, initExpr)) {
5775 INDENT(indent+2,outfile);
5776 fprintf(outfile,"INIT EXPR ");
5777 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5779 if (AST_FOR( tree, condExpr)) {
5780 INDENT(indent+2,outfile);
5781 fprintf(outfile,"COND EXPR ");
5782 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5784 if (AST_FOR( tree, loopExpr)) {
5785 INDENT(indent+2,outfile);
5786 fprintf(outfile,"LOOP EXPR ");
5787 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5789 fprintf(outfile,"FOR LOOP BODY \n");
5790 ast_print(tree->left,outfile,indent+2);
5793 fprintf(outfile,"CRITICAL (%p) \n",tree);
5794 ast_print(tree->left,outfile,indent+2);
5802 ast_print(t,stdout,0);
5807 /*-----------------------------------------------------------------*/
5808 /* astErrors : returns non-zero if errors present in tree */
5809 /*-----------------------------------------------------------------*/
5810 int astErrors(ast *t)
5819 if (t->type == EX_VALUE
5820 && t->opval.val->sym
5821 && t->opval.val->sym->undefined)
5824 errors += astErrors(t->left);
5825 errors += astErrors(t->right);