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 RESULT_TYPE resultType;
657 /* if none of them exist */
658 if (!defParm && !actParm)
663 if (getenv("DEBUG_SANITY"))
665 fprintf (stderr, "processParms: %s ", defParm->name);
667 /* make sure the type is complete and sane */
668 checkTypeSanity(defParm->etype, defParm->name);
671 if (IS_CODEPTR (func->ftype))
672 functype = func->ftype->next;
674 functype = func->ftype;
676 /* if the function is being called via a pointer & */
677 /* it has not been defined a reentrant then we cannot */
678 /* have parameters */
679 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
681 werror (W_NONRENT_ARGS);
686 /* if defined parameters ended but actual parameters */
687 /* exist and this is not defined as a variable arg */
688 if (!defParm && actParm && !IFFUNC_HASVARARGS(functype))
690 werror (E_TOO_MANY_PARMS);
694 /* if defined parameters present but no actual parameters */
695 if (defParm && !actParm)
697 werror (E_TOO_FEW_PARMS);
701 /* if this is a PARAM node then match left & right */
702 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
704 actParm->decorated = 1;
705 return (processParms (func, defParm,
706 actParm->left, parmNumber, FALSE) ||
707 processParms (func, defParm ? defParm->next : NULL,
708 actParm->right, parmNumber, rightmost));
710 else if (defParm) /* not vararg */
712 /* If we have found a value node by following only right-hand links,
713 * then we know that there are no more values after us.
715 * Therefore, if there are more defined parameters, the caller didn't
718 if (rightmost && defParm->next)
720 werror (E_TOO_FEW_PARMS);
725 /* decorate parameter */
726 resultType = defParm ? getResultTypeFromType (defParm->etype) :
728 actParm = decorateType (actParm, resultType);
730 if (IS_VOID(actParm->ftype))
732 werror (E_VOID_VALUE_USED);
736 /* If this is a varargs function... */
737 if (!defParm && actParm && IFFUNC_HASVARARGS(functype))
742 if (IS_CAST_OP (actParm)
743 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
745 /* Parameter was explicitly typecast; don't touch it. */
749 ftype = actParm->ftype;
751 /* If it's a char, upcast to int. */
752 if (IS_INTEGRAL (ftype)
753 && (getSize (ftype) < (unsigned) INTSIZE))
755 newType = newAst_LINK(INTTYPE);
758 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
760 newType = newAst_LINK (copyLinkChain(ftype));
761 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
764 if (IS_AGGREGATE (ftype))
766 newType = newAst_LINK (copyLinkChain (ftype));
767 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
772 /* cast required; change this op to a cast. */
773 ast *parmCopy = resolveSymbols (copyAst (actParm));
775 actParm->type = EX_OP;
776 actParm->opval.op = CAST;
777 actParm->left = newType;
778 actParm->right = parmCopy;
779 actParm->decorated = 0; /* force typechecking */
780 decorateType (actParm, RESULT_TYPE_NONE);
785 /* if defined parameters ended but actual has not & */
787 if (!defParm && actParm &&
788 (options.stackAuto || IFFUNC_ISREENT (functype)))
791 resolveSymbols (actParm);
793 /* the parameter type must be at least castable */
794 if (compareType (defParm->type, actParm->ftype) == 0)
796 werror (E_INCOMPAT_TYPES);
797 printFromToType (actParm->ftype, defParm->type);
801 /* if the parameter is castable then add the cast */
802 if (compareType (defParm->type, actParm->ftype) < 0)
806 resultType = getResultTypeFromType (defParm->etype);
807 pTree = resolveSymbols (copyAst (actParm));
809 /* now change the current one to a cast */
810 actParm->type = EX_OP;
811 actParm->opval.op = CAST;
812 actParm->left = newAst_LINK (defParm->type);
813 actParm->right = pTree;
814 actParm->decorated = 0; /* force typechecking */
815 decorateType (actParm, resultType);
818 /* make a copy and change the regparm type to the defined parm */
819 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
820 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
821 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
826 /*-----------------------------------------------------------------*/
827 /* createIvalType - generates ival for basic types */
828 /*-----------------------------------------------------------------*/
830 createIvalType (ast * sym, sym_link * type, initList * ilist)
834 /* if initList is deep */
835 if (ilist->type == INIT_DEEP)
836 ilist = ilist->init.deep;
838 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
839 return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
842 /*-----------------------------------------------------------------*/
843 /* createIvalStruct - generates initial value for structures */
844 /*-----------------------------------------------------------------*/
846 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
853 sflds = SPEC_STRUCT (type)->fields;
854 if (ilist->type != INIT_DEEP)
856 werror (E_INIT_STRUCT, "");
860 iloop = ilist->init.deep;
862 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
864 /* if we have come to end */
868 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
869 lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
870 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
874 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
875 W_EXCESS_INITIALIZERS, "struct",
876 sym->opval.val->sym->name);
883 /*-----------------------------------------------------------------*/
884 /* createIvalArray - generates code for array initialization */
885 /*-----------------------------------------------------------------*/
887 createIvalArray (ast * sym, sym_link * type, initList * ilist)
891 int lcnt = 0, size = 0;
892 literalList *literalL;
894 /* take care of the special case */
895 /* array of characters can be init */
897 if (IS_CHAR (type->next))
898 if ((rast = createIvalCharPtr (sym,
900 decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
902 return decorateType (resolveSymbols (rast), RESULT_CHECK);
904 /* not the special case */
905 if (ilist->type != INIT_DEEP)
907 werror (E_INIT_STRUCT, "");
911 iloop = ilist->init.deep;
912 lcnt = DCL_ELEM (type);
914 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
918 aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
920 rast = newNode(ARRAYINIT, aSym, NULL);
921 rast->values.constlist = literalL;
923 // Make sure size is set to length of initializer list.
930 if (lcnt && size > lcnt)
932 // Array size was specified, and we have more initializers than needed.
933 char *name=sym->opval.val->sym->name;
934 int lineno=sym->opval.val->sym->lineDef;
935 char *filename=sym->opval.val->sym->fileDef;
937 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
946 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
947 aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
948 rast = createIval (aSym, type->next, iloop, rast);
949 iloop = (iloop ? iloop->next : NULL);
955 /* no of elements given and we */
956 /* have generated for all of them */
959 // there has to be a better way
960 char *name=sym->opval.val->sym->name;
961 int lineno=sym->opval.val->sym->lineDef;
962 char *filename=sym->opval.val->sym->fileDef;
963 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
970 /* if we have not been given a size */
971 if (!DCL_ELEM (type))
973 DCL_ELEM (type) = size;
976 return decorateType (resolveSymbols (rast), RESULT_CHECK);
980 /*-----------------------------------------------------------------*/
981 /* createIvalCharPtr - generates initial values for char pointers */
982 /*-----------------------------------------------------------------*/
984 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
988 /* if this is a pointer & right is a literal array then */
989 /* just assignment will do */
990 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
991 SPEC_SCLS (iexpr->etype) == S_CODE)
992 && IS_ARRAY (iexpr->ftype)))
993 return newNode ('=', sym, iexpr);
995 /* left side is an array so we have to assign each */
997 if ((IS_LITERAL (iexpr->etype) ||
998 SPEC_SCLS (iexpr->etype) == S_CODE)
999 && IS_ARRAY (iexpr->ftype))
1001 /* for each character generate an assignment */
1002 /* to the array element */
1003 char *s = SPEC_CVAL (iexpr->etype).v_char;
1005 int size = getSize (iexpr->ftype);
1006 int symsize = getSize (type);
1010 if (size>(symsize+1))
1011 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1012 "string", sym->opval.val->sym->name);
1016 for (i=0;i<size;i++)
1018 rast = newNode (NULLOP,
1022 newAst_VALUE (valueFromLit ((float) i))),
1023 newAst_VALUE (valueFromLit (*s))));
1027 // now WE don't need iexpr's symbol anymore
1028 freeStringSymbol(AST_SYMBOL(iexpr));
1030 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1036 /*-----------------------------------------------------------------*/
1037 /* createIvalPtr - generates initial value for pointers */
1038 /*-----------------------------------------------------------------*/
1040 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1046 if (ilist->type == INIT_DEEP)
1047 ilist = ilist->init.deep;
1049 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1051 /* if character pointer */
1052 if (IS_CHAR (type->next))
1053 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1056 return newNode ('=', sym, iexpr);
1059 /*-----------------------------------------------------------------*/
1060 /* createIval - generates code for initial value */
1061 /*-----------------------------------------------------------------*/
1063 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1070 /* if structure then */
1071 if (IS_STRUCT (type))
1072 rast = createIvalStruct (sym, type, ilist);
1074 /* if this is a pointer */
1076 rast = createIvalPtr (sym, type, ilist);
1078 /* if this is an array */
1079 if (IS_ARRAY (type))
1080 rast = createIvalArray (sym, type, ilist);
1082 /* if type is SPECIFIER */
1084 rast = createIvalType (sym, type, ilist);
1087 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1089 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1092 /*-----------------------------------------------------------------*/
1093 /* initAggregates - initialises aggregate variables with initv */
1094 /*-----------------------------------------------------------------*/
1095 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1096 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1099 /*-----------------------------------------------------------------*/
1100 /* gatherAutoInit - creates assignment expressions for initial */
1102 /*-----------------------------------------------------------------*/
1104 gatherAutoInit (symbol * autoChain)
1111 for (sym = autoChain; sym; sym = sym->next)
1114 /* resolve the symbols in the ival */
1116 resolveIvalSym (sym->ival, sym->type);
1118 /* if this is a static variable & has an */
1119 /* initial value the code needs to be lifted */
1120 /* here to the main portion since they can be */
1121 /* initialised only once at the start */
1122 if (IS_STATIC (sym->etype) && sym->ival &&
1123 SPEC_SCLS (sym->etype) != S_CODE)
1127 /* insert the symbol into the symbol table */
1128 /* with level = 0 & name = rname */
1129 newSym = copySymbol (sym);
1130 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1132 /* now lift the code to main */
1133 if (IS_AGGREGATE (sym->type)) {
1134 work = initAggregates (sym, sym->ival, NULL);
1136 if (getNelements(sym->type, sym->ival)>1) {
1137 werrorfl (sym->fileDef, sym->lineDef,
1138 W_EXCESS_INITIALIZERS, "scalar",
1141 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1142 list2expr (sym->ival));
1145 setAstLineno (work, sym->lineDef);
1149 staticAutos = newNode (NULLOP, staticAutos, work);
1156 /* if there is an initial value */
1157 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1159 initList *ilist=sym->ival;
1161 while (ilist->type == INIT_DEEP) {
1162 ilist = ilist->init.deep;
1165 /* update lineno for error msg */
1166 lineno=sym->lineDef;
1167 setAstLineno (ilist->init.node, lineno);
1169 if (IS_AGGREGATE (sym->type)) {
1170 work = initAggregates (sym, sym->ival, NULL);
1172 if (getNelements(sym->type, sym->ival)>1) {
1173 werrorfl (sym->fileDef, sym->lineDef,
1174 W_EXCESS_INITIALIZERS, "scalar",
1177 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1178 list2expr (sym->ival));
1182 setAstLineno (work, sym->lineDef);
1186 init = newNode (NULLOP, init, work);
1195 /*-----------------------------------------------------------------*/
1196 /* freeStringSymbol - delete a literal string if no more usage */
1197 /*-----------------------------------------------------------------*/
1198 void freeStringSymbol(symbol *sym) {
1199 /* make sure this is a literal string */
1200 assert (sym->isstrlit);
1201 if (--sym->isstrlit == 0) { // lower the usage count
1202 memmap *segment=SPEC_OCLS(sym->etype);
1204 deleteSetItem(&segment->syms, sym);
1209 /*-----------------------------------------------------------------*/
1210 /* stringToSymbol - creates a symbol from a literal string */
1211 /*-----------------------------------------------------------------*/
1213 stringToSymbol (value * val)
1215 char name[SDCC_NAME_MAX + 1];
1216 static int charLbl = 0;
1221 // have we heard this before?
1222 for (sp=statsg->syms; sp; sp=sp->next) {
1224 size = getSize (sym->type);
1225 if (sym->isstrlit && size == getSize (val->type) &&
1226 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1227 // yes, this is old news. Don't publish it again.
1228 sym->isstrlit++; // but raise the usage count
1229 return symbolVal(sym);
1233 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1234 sym = newSymbol (name, 0); /* make it @ level 0 */
1235 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1237 /* copy the type from the value passed */
1238 sym->type = copyLinkChain (val->type);
1239 sym->etype = getSpec (sym->type);
1240 /* change to storage class & output class */
1241 SPEC_SCLS (sym->etype) = S_CODE;
1242 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1243 SPEC_STAT (sym->etype) = 1;
1244 /* make the level & block = 0 */
1245 sym->block = sym->level = 0;
1247 /* create an ival */
1248 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1253 allocVariables (sym);
1256 return symbolVal (sym);
1260 /*-----------------------------------------------------------------*/
1261 /* processBlockVars - will go thru the ast looking for block if */
1262 /* a block is found then will allocate the syms */
1263 /* will also gather the auto inits present */
1264 /*-----------------------------------------------------------------*/
1266 processBlockVars (ast * tree, int *stack, int action)
1271 /* if this is a block */
1272 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1276 if (action == ALLOCATE)
1278 *stack += allocVariables (tree->values.sym);
1279 autoInit = gatherAutoInit (tree->values.sym);
1281 /* if there are auto inits then do them */
1283 tree->left = newNode (NULLOP, autoInit, tree->left);
1285 else /* action is deallocate */
1286 deallocLocal (tree->values.sym);
1289 processBlockVars (tree->left, stack, action);
1290 processBlockVars (tree->right, stack, action);
1295 /*-------------------------------------------------------------*/
1296 /* constExprTree - returns TRUE if this tree is a constant */
1298 /*-------------------------------------------------------------*/
1299 bool constExprTree (ast *cexpr) {
1305 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1307 switch (cexpr->type)
1310 if (IS_AST_LIT_VALUE(cexpr)) {
1311 // this is a literal
1314 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1315 // a function's address will never change
1318 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1319 // an array's address will never change
1322 if (IS_AST_SYM_VALUE(cexpr) &&
1323 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1324 // a symbol in code space will never change
1325 // This is only for the 'char *s="hallo"' case and will have to leave
1326 //printf(" code space symbol");
1331 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1332 "unexpected link in expression tree\n");
1335 if (cexpr->opval.op==ARRAYINIT) {
1336 // this is a list of literals
1339 if (cexpr->opval.op=='=') {
1340 return constExprTree(cexpr->right);
1342 if (cexpr->opval.op==CAST) {
1343 // cast ignored, maybe we should throw a warning here?
1344 return constExprTree(cexpr->right);
1346 if (cexpr->opval.op=='&') {
1349 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1352 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1357 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1362 /*-----------------------------------------------------------------*/
1363 /* constExprValue - returns the value of a constant expression */
1364 /* or NULL if it is not a constant expression */
1365 /*-----------------------------------------------------------------*/
1367 constExprValue (ast * cexpr, int check)
1369 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1371 /* if this is not a constant then */
1372 if (!IS_LITERAL (cexpr->ftype))
1374 /* then check if this is a literal array
1376 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1377 SPEC_CVAL (cexpr->etype).v_char &&
1378 IS_ARRAY (cexpr->ftype))
1380 value *val = valFromType (cexpr->ftype);
1381 SPEC_SCLS (val->etype) = S_LITERAL;
1382 val->sym = cexpr->opval.val->sym;
1383 val->sym->type = copyLinkChain (cexpr->ftype);
1384 val->sym->etype = getSpec (val->sym->type);
1385 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1389 /* if we are casting a literal value then */
1390 if (IS_AST_OP (cexpr) &&
1391 cexpr->opval.op == CAST &&
1392 IS_LITERAL (cexpr->right->ftype))
1394 return valCastLiteral (cexpr->ftype,
1395 floatFromVal (cexpr->right->opval.val));
1398 if (IS_AST_VALUE (cexpr))
1400 return cexpr->opval.val;
1404 werror (E_CONST_EXPECTED, "found expression");
1409 /* return the value */
1410 return cexpr->opval.val;
1414 /*-----------------------------------------------------------------*/
1415 /* isLabelInAst - will return true if a given label is found */
1416 /*-----------------------------------------------------------------*/
1418 isLabelInAst (symbol * label, ast * tree)
1420 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1423 if (IS_AST_OP (tree) &&
1424 tree->opval.op == LABEL &&
1425 isSymbolEqual (AST_SYMBOL (tree->left), label))
1428 return isLabelInAst (label, tree->right) &&
1429 isLabelInAst (label, tree->left);
1433 /*-----------------------------------------------------------------*/
1434 /* isLoopCountable - return true if the loop count can be determi- */
1435 /* -ned at compile time . */
1436 /*-----------------------------------------------------------------*/
1438 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1439 symbol ** sym, ast ** init, ast ** end)
1442 /* the loop is considered countable if the following
1443 conditions are true :-
1445 a) initExpr :- <sym> = <const>
1446 b) condExpr :- <sym> < <const1>
1447 c) loopExpr :- <sym> ++
1450 /* first check the initExpr */
1451 if (IS_AST_OP (initExpr) &&
1452 initExpr->opval.op == '=' && /* is assignment */
1453 IS_AST_SYM_VALUE (initExpr->left))
1454 { /* left is a symbol */
1456 *sym = AST_SYMBOL (initExpr->left);
1457 *init = initExpr->right;
1462 /* for now the symbol has to be of
1464 if (!IS_INTEGRAL ((*sym)->type))
1467 /* now check condExpr */
1468 if (IS_AST_OP (condExpr))
1471 switch (condExpr->opval.op)
1474 if (IS_AST_SYM_VALUE (condExpr->left) &&
1475 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1476 IS_AST_LIT_VALUE (condExpr->right))
1478 *end = condExpr->right;
1484 if (IS_AST_OP (condExpr->left) &&
1485 condExpr->left->opval.op == '>' &&
1486 IS_AST_LIT_VALUE (condExpr->left->right) &&
1487 IS_AST_SYM_VALUE (condExpr->left->left) &&
1488 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1491 *end = newNode ('+', condExpr->left->right,
1492 newAst_VALUE (constVal ("1")));
1503 /* check loop expression is of the form <sym>++ */
1504 if (!IS_AST_OP (loopExpr))
1507 /* check if <sym> ++ */
1508 if (loopExpr->opval.op == INC_OP)
1514 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1515 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1522 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1523 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1531 if (loopExpr->opval.op == ADD_ASSIGN)
1534 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1535 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1536 IS_AST_LIT_VALUE (loopExpr->right) &&
1537 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1545 /*-----------------------------------------------------------------*/
1546 /* astHasVolatile - returns true if ast contains any volatile */
1547 /*-----------------------------------------------------------------*/
1549 astHasVolatile (ast * tree)
1554 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1557 if (IS_AST_OP (tree))
1558 return astHasVolatile (tree->left) ||
1559 astHasVolatile (tree->right);
1564 /*-----------------------------------------------------------------*/
1565 /* astHasPointer - return true if the ast contains any ptr variable */
1566 /*-----------------------------------------------------------------*/
1568 astHasPointer (ast * tree)
1573 if (IS_AST_LINK (tree))
1576 /* if we hit an array expression then check
1577 only the left side */
1578 if (IS_AST_OP (tree) && tree->opval.op == '[')
1579 return astHasPointer (tree->left);
1581 if (IS_AST_VALUE (tree))
1582 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1584 return astHasPointer (tree->left) ||
1585 astHasPointer (tree->right);
1589 /*-----------------------------------------------------------------*/
1590 /* astHasSymbol - return true if the ast has the given symbol */
1591 /*-----------------------------------------------------------------*/
1593 astHasSymbol (ast * tree, symbol * sym)
1595 if (!tree || IS_AST_LINK (tree))
1598 if (IS_AST_VALUE (tree))
1600 if (IS_AST_SYM_VALUE (tree))
1601 return isSymbolEqual (AST_SYMBOL (tree), sym);
1606 return astHasSymbol (tree->left, sym) ||
1607 astHasSymbol (tree->right, sym);
1610 /*-----------------------------------------------------------------*/
1611 /* astHasDeref - return true if the ast has an indirect access */
1612 /*-----------------------------------------------------------------*/
1614 astHasDeref (ast * tree)
1616 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1619 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1621 return astHasDeref (tree->left) || astHasDeref (tree->right);
1624 /*-----------------------------------------------------------------*/
1625 /* isConformingBody - the loop body has to conform to a set of rules */
1626 /* for the loop to be considered reversible read on for rules */
1627 /*-----------------------------------------------------------------*/
1629 isConformingBody (ast * pbody, symbol * sym, ast * body)
1632 /* we are going to do a pre-order traversal of the
1633 tree && check for the following conditions. (essentially
1634 a set of very shallow tests )
1635 a) the sym passed does not participate in
1636 any arithmetic operation
1637 b) There are no function calls
1638 c) all jumps are within the body
1639 d) address of loop control variable not taken
1640 e) if an assignment has a pointer on the
1641 left hand side make sure right does not have
1642 loop control variable */
1644 /* if we reach the end or a leaf then true */
1645 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1648 /* if anything else is "volatile" */
1649 if (IS_VOLATILE (TETYPE (pbody)))
1652 /* we will walk the body in a pre-order traversal for
1654 switch (pbody->opval.op)
1656 /*------------------------------------------------------------------*/
1658 // if the loopvar is used as an index
1659 if (astHasSymbol(pbody->right, sym)) {
1662 return isConformingBody (pbody->right, sym, body);
1664 /*------------------------------------------------------------------*/
1669 /*------------------------------------------------------------------*/
1673 /* sure we are not sym is not modified */
1675 IS_AST_SYM_VALUE (pbody->left) &&
1676 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1680 IS_AST_SYM_VALUE (pbody->right) &&
1681 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1686 /*------------------------------------------------------------------*/
1688 case '*': /* can be unary : if right is null then unary operation */
1693 /* if right is NULL then unary operation */
1694 /*------------------------------------------------------------------*/
1695 /*----------------------------*/
1697 /*----------------------------*/
1700 if (IS_AST_SYM_VALUE (pbody->left) &&
1701 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1704 return isConformingBody (pbody->left, sym, body);
1708 if (astHasSymbol (pbody->left, sym) ||
1709 astHasSymbol (pbody->right, sym))
1714 /*------------------------------------------------------------------*/
1722 if (IS_AST_SYM_VALUE (pbody->left) &&
1723 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1726 if (IS_AST_SYM_VALUE (pbody->right) &&
1727 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1730 return isConformingBody (pbody->left, sym, body) &&
1731 isConformingBody (pbody->right, sym, body);
1739 if (IS_AST_SYM_VALUE (pbody->left) &&
1740 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1742 return isConformingBody (pbody->left, sym, body);
1744 /*------------------------------------------------------------------*/
1756 case SIZEOF: /* evaluate wihout code generation */
1758 if (IS_AST_SYM_VALUE (pbody->left) &&
1759 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1762 if (IS_AST_SYM_VALUE (pbody->right) &&
1763 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1766 return isConformingBody (pbody->left, sym, body) &&
1767 isConformingBody (pbody->right, sym, body);
1769 /*------------------------------------------------------------------*/
1772 /* if left has a pointer & right has loop
1773 control variable then we cannot */
1774 if (astHasPointer (pbody->left) &&
1775 astHasSymbol (pbody->right, sym))
1777 if (astHasVolatile (pbody->left))
1780 if (IS_AST_SYM_VALUE (pbody->left)) {
1781 // if the loopvar has an assignment
1782 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1784 // if the loopvar is used in another (maybe conditional) block
1785 if (astHasSymbol (pbody->right, sym) &&
1786 (pbody->level >= body->level)) {
1791 if (astHasVolatile (pbody->left))
1794 if (astHasDeref(pbody->right)) return FALSE;
1796 return isConformingBody (pbody->left, sym, body) &&
1797 isConformingBody (pbody->right, sym, body);
1808 assert ("Parser should not have generated this\n");
1810 /*------------------------------------------------------------------*/
1811 /*----------------------------*/
1812 /* comma operator */
1813 /*----------------------------*/
1815 return isConformingBody (pbody->left, sym, body) &&
1816 isConformingBody (pbody->right, sym, body);
1818 /*------------------------------------------------------------------*/
1819 /*----------------------------*/
1821 /*----------------------------*/
1823 /* if local & not passed as paramater then ok */
1824 if (sym->level && !astHasSymbol(pbody->right,sym))
1828 /*------------------------------------------------------------------*/
1829 /*----------------------------*/
1830 /* return statement */
1831 /*----------------------------*/
1836 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1841 if (astHasSymbol (pbody->left, sym))
1848 return isConformingBody (pbody->left, sym, body) &&
1849 isConformingBody (pbody->right, sym, body);
1855 /*-----------------------------------------------------------------*/
1856 /* isLoopReversible - takes a for loop as input && returns true */
1857 /* if the for loop is reversible. If yes will set the value of */
1858 /* the loop control var & init value & termination value */
1859 /*-----------------------------------------------------------------*/
1861 isLoopReversible (ast * loop, symbol ** loopCntrl,
1862 ast ** init, ast ** end)
1864 /* if option says don't do it then don't */
1865 if (optimize.noLoopReverse)
1867 /* there are several tests to determine this */
1869 /* for loop has to be of the form
1870 for ( <sym> = <const1> ;
1871 [<sym> < <const2>] ;
1872 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1874 if (!isLoopCountable (AST_FOR (loop, initExpr),
1875 AST_FOR (loop, condExpr),
1876 AST_FOR (loop, loopExpr),
1877 loopCntrl, init, end))
1880 /* now do some serious checking on the body of the loop
1883 return isConformingBody (loop->left, *loopCntrl, loop->left);
1887 /*-----------------------------------------------------------------*/
1888 /* replLoopSym - replace the loop sym by loop sym -1 */
1889 /*-----------------------------------------------------------------*/
1891 replLoopSym (ast * body, symbol * sym)
1894 if (!body || IS_AST_LINK (body))
1897 if (IS_AST_SYM_VALUE (body))
1900 if (isSymbolEqual (AST_SYMBOL (body), sym))
1904 body->opval.op = '-';
1905 body->left = newAst_VALUE (symbolVal (sym));
1906 body->right = newAst_VALUE (constVal ("1"));
1914 replLoopSym (body->left, sym);
1915 replLoopSym (body->right, sym);
1919 /*-----------------------------------------------------------------*/
1920 /* reverseLoop - do the actual loop reversal */
1921 /*-----------------------------------------------------------------*/
1923 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1927 /* create the following tree
1932 if (sym) goto for_continue ;
1935 /* put it together piece by piece */
1936 rloop = newNode (NULLOP,
1937 createIf (newAst_VALUE (symbolVal (sym)),
1939 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1942 newAst_VALUE (symbolVal (sym)),
1945 replLoopSym (loop->left, sym);
1946 setAstLineno (rloop, init->lineno);
1948 rloop = newNode (NULLOP,
1950 newAst_VALUE (symbolVal (sym)),
1951 newNode ('-', end, init)),
1952 createLabel (AST_FOR (loop, continueLabel),
1956 newNode (SUB_ASSIGN,
1957 newAst_VALUE (symbolVal (sym)),
1958 newAst_VALUE (constVal ("1"))),
1961 rloop->lineno=init->lineno;
1962 return decorateType (rloop, RESULT_CHECK);
1966 /*-----------------------------------------------------------------*/
1967 /* searchLitOp - search tree (*ops only) for an ast with literal */
1968 /*-----------------------------------------------------------------*/
1970 searchLitOp (ast *tree, ast **parent, const char *ops)
1974 if (tree && optimize.global_cse)
1976 /* is there a literal operand? */
1978 IS_AST_OP(tree->right) &&
1979 tree->right->right &&
1980 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1982 if (IS_LITERAL (RTYPE (tree->right)) ^
1983 IS_LITERAL (LTYPE (tree->right)))
1985 tree->right->decorated = 0;
1986 tree->decorated = 0;
1990 ret = searchLitOp (tree->right, parent, ops);
1995 IS_AST_OP(tree->left) &&
1996 tree->left->right &&
1997 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1999 if (IS_LITERAL (RTYPE (tree->left)) ^
2000 IS_LITERAL (LTYPE (tree->left)))
2002 tree->left->decorated = 0;
2003 tree->decorated = 0;
2007 ret = searchLitOp (tree->left, parent, ops);
2015 /*-----------------------------------------------------------------*/
2016 /* getResultFromType */
2017 /*-----------------------------------------------------------------*/
2019 getResultTypeFromType (sym_link *type)
2021 /* type = getSpec (type); */
2022 if (IS_BITVAR (type))
2023 return RESULT_TYPE_BIT;
2024 if (IS_BITFIELD (type))
2025 return RESULT_TYPE_CHAR;
2027 return RESULT_TYPE_CHAR;
2030 return RESULT_TYPE_INT;
2031 return RESULT_TYPE_OTHER;
2034 /*-----------------------------------------------------------------*/
2035 /* addCast - adds casts to a type specified by RESULT_TYPE */
2036 /*-----------------------------------------------------------------*/
2038 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2041 bool upCasted = FALSE;
2045 case RESULT_TYPE_NONE:
2046 /* char: promote to int */
2048 getSize (tree->etype) >= INTSIZE)
2050 newLink = newIntLink();
2053 case RESULT_TYPE_CHAR:
2054 if (getSize (tree->etype) <= 1)
2056 newLink = newCharLink();
2058 case RESULT_TYPE_INT:
2060 if (getSize (tree->etype) > INTSIZE)
2062 /* warn ("Loosing significant digits"); */
2066 /* char: promote to int */
2068 getSize (tree->etype) >= INTSIZE)
2070 newLink = newIntLink();
2073 case RESULT_TYPE_OTHER:
2076 /* return type is long, float: promote char to int */
2077 if (getSize (tree->etype) >= INTSIZE)
2079 newLink = newIntLink();
2085 tree->decorated = 0;
2086 tree = newNode (CAST, newAst_LINK (newLink), tree);
2087 tree->lineno = tree->right->lineno;
2088 /* keep unsigned type during cast to smaller type,
2089 but not when promoting from char to int */
2091 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2092 return decorateType (tree, resultType);
2095 /*-----------------------------------------------------------------*/
2096 /* resultTypePropagate - decides if resultType can be propagated */
2097 /*-----------------------------------------------------------------*/
2099 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2101 switch (tree->opval.op)
2116 return RESULT_TYPE_NONE;
2120 return RESULT_TYPE_IFX;
2122 return RESULT_TYPE_NONE;
2126 /*-----------------------------------------------------------------*/
2127 /* getLeftResultType - gets type from left branch for propagation */
2128 /*-----------------------------------------------------------------*/
2130 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2132 switch (tree->opval.op)
2136 if (IS_PTR (LTYPE (tree)))
2137 return RESULT_TYPE_NONE;
2139 return getResultTypeFromType (LETYPE (tree));
2141 if (IS_PTR (currFunc->type->next))
2142 return RESULT_TYPE_NONE;
2144 return getResultTypeFromType (currFunc->type->next);
2146 if (!IS_ARRAY (LTYPE (tree)))
2148 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2149 return RESULT_TYPE_CHAR;
2156 /*--------------------------------------------------------------------*/
2157 /* decorateType - compute type for this tree, also does type checking.*/
2158 /* This is done bottom up, since type has to flow upwards. */
2159 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2160 /* result is a char and the operand(s) are int's. */
2161 /* It also does constant folding, and parameter checking. */
2162 /*--------------------------------------------------------------------*/
2164 decorateType (ast * tree, RESULT_TYPE resultType)
2168 RESULT_TYPE resultTypeProp;
2173 /* if already has type then do nothing */
2174 if (tree->decorated)
2177 tree->decorated = 1;
2180 /* print the line */
2181 /* if not block & function */
2182 if (tree->type == EX_OP &&
2183 (tree->opval.op != FUNCTION &&
2184 tree->opval.op != BLOCK &&
2185 tree->opval.op != NULLOP))
2187 filename = tree->filename;
2188 lineno = tree->lineno;
2192 /* if any child is an error | this one is an error do nothing */
2193 if (tree->isError ||
2194 (tree->left && tree->left->isError) ||
2195 (tree->right && tree->right->isError))
2198 /*------------------------------------------------------------------*/
2199 /*----------------------------*/
2200 /* leaf has been reached */
2201 /*----------------------------*/
2202 lineno=tree->lineno;
2203 /* if this is of type value */
2204 /* just get the type */
2205 if (tree->type == EX_VALUE)
2208 if (IS_LITERAL (tree->opval.val->etype))
2211 /* if this is a character array then declare it */
2212 if (IS_ARRAY (tree->opval.val->type))
2213 tree->opval.val = stringToSymbol (tree->opval.val);
2215 /* otherwise just copy the type information */
2216 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2220 if (tree->opval.val->sym)
2222 /* if the undefined flag is set then give error message */
2223 if (tree->opval.val->sym->undefined)
2225 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2227 TTYPE (tree) = TETYPE (tree) =
2228 tree->opval.val->type = tree->opval.val->sym->type =
2229 tree->opval.val->etype = tree->opval.val->sym->etype =
2230 copyLinkChain (INTTYPE);
2235 /* if impilicit i.e. struct/union member then no type */
2236 if (tree->opval.val->sym->implicit)
2237 TTYPE (tree) = TETYPE (tree) = NULL;
2242 /* else copy the type */
2243 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2245 /* and mark it as referenced */
2246 tree->opval.val->sym->isref = 1;
2254 /* if type link for the case of cast */
2255 if (tree->type == EX_LINK)
2257 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2265 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2267 if (tree->left && tree->left->type == EX_OPERAND
2268 && (tree->left->opval.op == INC_OP
2269 || tree->left->opval.op == DEC_OP)
2270 && tree->left->left)
2272 tree->left->right = tree->left->left;
2273 tree->left->left = NULL;
2275 if (tree->right && tree->right->type == EX_OPERAND
2276 && (tree->right->opval.op == INC_OP
2277 || tree->right->opval.op == DEC_OP)
2278 && tree->right->left)
2280 tree->right->right = tree->right->left;
2281 tree->right->left = NULL;
2286 /* Before decorating the left branch we've to decide in dependence
2287 upon tree->opval.op, if resultType can be propagated */
2288 resultTypeProp = resultTypePropagate (tree, resultType);
2290 dtl = decorateType (tree->left, resultTypeProp);
2292 /* if an array node, we may need to swap branches */
2293 if (tree->opval.op == '[')
2295 /* determine which is the array & which the index */
2296 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2297 IS_INTEGRAL (LTYPE (tree)))
2299 ast *tempTree = tree->left;
2300 tree->left = tree->right;
2301 tree->right = tempTree;
2305 /* After decorating the left branch there's type information available
2306 in tree->left->?type. If the op is e.g. '=' we extract the type
2307 information from there and propagate it to the right branch. */
2308 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2310 switch (tree->opval.op)
2313 /* delay right side for '?' operator since conditional macro
2314 expansions might rely on this */
2318 /* decorate right side for CALL (parameter list) in processParms();
2319 there is resultType available */
2323 dtr = decorateType (tree->right, resultTypeProp);
2327 /* this is to take care of situations
2328 when the tree gets rewritten */
2329 if (dtl != tree->left)
2331 if (dtr != tree->right)
2333 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2337 /* depending on type of operator do */
2339 switch (tree->opval.op)
2341 /*------------------------------------------------------------------*/
2342 /*----------------------------*/
2344 /*----------------------------*/
2347 /* first check if this is a array or a pointer */
2348 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2350 werror (E_NEED_ARRAY_PTR, "[]");
2351 goto errorTreeReturn;
2354 /* check if the type of the idx */
2355 if (!IS_INTEGRAL (RTYPE (tree)))
2357 werror (E_IDX_NOT_INT);
2358 goto errorTreeReturn;
2361 /* if the left is an rvalue then error */
2364 werror (E_LVALUE_REQUIRED, "array access");
2365 goto errorTreeReturn;
2368 if (IS_LITERAL (RTYPE (tree)))
2370 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2371 int arraySize = DCL_ELEM (LTYPE (tree));
2372 if (arraySize && arrayIndex >= arraySize)
2374 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2379 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2382 /*------------------------------------------------------------------*/
2383 /*----------------------------*/
2385 /*----------------------------*/
2387 /* if this is not a structure */
2388 if (!IS_STRUCT (LTYPE (tree)))
2390 werror (E_STRUCT_UNION, ".");
2391 goto errorTreeReturn;
2393 TTYPE (tree) = structElemType (LTYPE (tree),
2394 (tree->right->type == EX_VALUE ?
2395 tree->right->opval.val : NULL));
2396 TETYPE (tree) = getSpec (TTYPE (tree));
2399 /*------------------------------------------------------------------*/
2400 /*----------------------------*/
2401 /* struct/union pointer */
2402 /*----------------------------*/
2404 /* if not pointer to a structure */
2405 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2407 werror (E_PTR_REQD);
2408 goto errorTreeReturn;
2411 if (!IS_STRUCT (LTYPE (tree)->next))
2413 werror (E_STRUCT_UNION, "->");
2414 goto errorTreeReturn;
2417 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2418 (tree->right->type == EX_VALUE ?
2419 tree->right->opval.val : NULL));
2420 TETYPE (tree) = getSpec (TTYPE (tree));
2422 /* adjust the storage class */
2423 switch (DCL_TYPE(tree->left->ftype)) {
2425 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2428 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2431 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2434 SPEC_SCLS (TETYPE (tree)) = 0;
2437 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2440 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2443 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2446 SPEC_SCLS (TETYPE (tree)) = 0;
2453 /* This breaks with extern declarations, bitfields, and perhaps other */
2454 /* cases (gcse). Let's leave this optimization disabled for now and */
2455 /* ponder if there's a safe way to do this. -- EEP */
2457 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2458 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2460 /* If defined struct type at addr var
2461 then rewrite (&struct var)->member
2463 and define membertype at (addr+offsetof(struct var,member)) temp
2466 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2467 AST_SYMBOL(tree->right));
2469 sym = newSymbol(genSymName (0), 0);
2470 sym->type = TTYPE (tree);
2471 sym->etype = getSpec(sym->type);
2472 sym->lineDef = tree->lineno;
2475 SPEC_STAT (sym->etype) = 1;
2476 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2478 SPEC_ABSA(sym->etype) = 1;
2479 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2482 AST_VALUE (tree) = symbolVal(sym);
2485 tree->type = EX_VALUE;
2493 /*------------------------------------------------------------------*/
2494 /*----------------------------*/
2495 /* ++/-- operation */
2496 /*----------------------------*/
2500 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2501 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2502 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2503 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2512 /*------------------------------------------------------------------*/
2513 /*----------------------------*/
2515 /*----------------------------*/
2516 case '&': /* can be unary */
2517 /* if right is NULL then unary operation */
2518 if (tree->right) /* not an unary operation */
2521 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2523 werror (E_BITWISE_OP);
2524 werror (W_CONTINUE, "left & right types are ");
2525 printTypeChain (LTYPE (tree), stderr);
2526 fprintf (stderr, ",");
2527 printTypeChain (RTYPE (tree), stderr);
2528 fprintf (stderr, "\n");
2529 goto errorTreeReturn;
2532 /* if they are both literal */
2533 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2535 tree->type = EX_VALUE;
2536 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2537 valFromType (RETYPE (tree)), '&');
2539 tree->right = tree->left = NULL;
2540 TETYPE (tree) = tree->opval.val->etype;
2541 TTYPE (tree) = tree->opval.val->type;
2545 /* see if this is a GETHBIT operation if yes
2548 ast *otree = optimizeGetHbit (tree);
2551 return decorateType (otree, RESULT_CHECK);
2554 tree->left = addCast (tree->left, resultType, FALSE);
2555 tree->right = addCast (tree->right, resultType, FALSE);
2556 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2557 TETYPE (tree) = getSpec (TTYPE (tree));
2559 /* if left is a literal exchange left & right */
2560 if (IS_LITERAL (LTYPE (tree)))
2562 ast *tTree = tree->left;
2563 tree->left = tree->right;
2564 tree->right = tTree;
2567 /* if right is a literal and */
2568 /* we can find a 2nd literal in a and-tree then */
2569 /* rearrange the tree */
2570 if (IS_LITERAL (RTYPE (tree)))
2573 ast *litTree = searchLitOp (tree, &parent, "&");
2576 ast *tTree = litTree->left;
2577 litTree->left = tree->right;
2578 tree->right = tTree;
2579 /* both operands in tTree are literal now */
2580 decorateType (parent, RESULT_CHECK);
2584 LRVAL (tree) = RRVAL (tree) = 1;
2589 /*------------------------------------------------------------------*/
2590 /*----------------------------*/
2592 /*----------------------------*/
2593 p = newLink (DECLARATOR);
2594 /* if bit field then error */
2595 if (IS_BITVAR (tree->left->etype))
2597 werror (E_ILLEGAL_ADDR, "address of bit variable");
2598 goto errorTreeReturn;
2601 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2603 werror (E_ILLEGAL_ADDR, "address of register variable");
2604 goto errorTreeReturn;
2607 if (IS_FUNC (LTYPE (tree)))
2609 // this ought to be ignored
2610 return (tree->left);
2613 if (IS_LITERAL(LTYPE(tree)))
2615 werror (E_ILLEGAL_ADDR, "address of literal");
2616 goto errorTreeReturn;
2621 werror (E_LVALUE_REQUIRED, "address of");
2622 goto errorTreeReturn;
2625 DCL_TYPE (p) = POINTER;
2626 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2627 DCL_TYPE (p) = CPOINTER;
2628 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2629 DCL_TYPE (p) = FPOINTER;
2630 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2631 DCL_TYPE (p) = PPOINTER;
2632 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2633 DCL_TYPE (p) = IPOINTER;
2634 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2635 DCL_TYPE (p) = EEPPOINTER;
2636 else if (SPEC_OCLS(tree->left->etype))
2637 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2639 DCL_TYPE (p) = POINTER;
2641 if (IS_AST_SYM_VALUE (tree->left))
2643 AST_SYMBOL (tree->left)->addrtaken = 1;
2644 AST_SYMBOL (tree->left)->allocreq = 1;
2647 p->next = LTYPE (tree);
2649 TETYPE (tree) = getSpec (TTYPE (tree));
2654 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2655 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2657 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2658 AST_SYMBOL(tree->left->right));
2659 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2660 valueFromLit(element->offset));
2663 tree->type = EX_VALUE;
2664 tree->values.literalFromCast = 1;
2670 /*------------------------------------------------------------------*/
2671 /*----------------------------*/
2673 /*----------------------------*/
2675 /* if the rewrite succeeds then don't go any furthur */
2677 ast *wtree = optimizeRRCRLC (tree);
2679 return decorateType (wtree, RESULT_CHECK);
2681 wtree = optimizeSWAP (tree);
2683 return decorateType (wtree, RESULT_CHECK);
2686 /* if left is a literal exchange left & right */
2687 if (IS_LITERAL (LTYPE (tree)))
2689 ast *tTree = tree->left;
2690 tree->left = tree->right;
2691 tree->right = tTree;
2694 /* if right is a literal and */
2695 /* we can find a 2nd literal in a or-tree then */
2696 /* rearrange the tree */
2697 if (IS_LITERAL (RTYPE (tree)))
2700 ast *litTree = searchLitOp (tree, &parent, "|");
2703 ast *tTree = litTree->left;
2704 litTree->left = tree->right;
2705 tree->right = tTree;
2706 /* both operands in tTree are literal now */
2707 decorateType (parent, RESULT_CHECK);
2712 /*------------------------------------------------------------------*/
2713 /*----------------------------*/
2715 /*----------------------------*/
2717 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2719 werror (E_BITWISE_OP);
2720 werror (W_CONTINUE, "left & right types are ");
2721 printTypeChain (LTYPE (tree), stderr);
2722 fprintf (stderr, ",");
2723 printTypeChain (RTYPE (tree), stderr);
2724 fprintf (stderr, "\n");
2725 goto errorTreeReturn;
2728 /* if they are both literal then */
2729 /* rewrite the tree */
2730 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2732 tree->type = EX_VALUE;
2733 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2734 valFromType (RETYPE (tree)),
2736 tree->right = tree->left = NULL;
2737 TETYPE (tree) = tree->opval.val->etype;
2738 TTYPE (tree) = tree->opval.val->type;
2742 /* if left is a literal exchange left & right */
2743 if (IS_LITERAL (LTYPE (tree)))
2745 ast *tTree = tree->left;
2746 tree->left = tree->right;
2747 tree->right = tTree;
2750 /* if right is a literal and */
2751 /* we can find a 2nd literal in a xor-tree then */
2752 /* rearrange the tree */
2753 if (IS_LITERAL (RTYPE (tree)) &&
2754 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2757 ast *litTree = searchLitOp (tree, &parent, "^");
2760 ast *tTree = litTree->left;
2761 litTree->left = tree->right;
2762 tree->right = tTree;
2763 /* both operands in litTree are literal now */
2764 decorateType (parent, RESULT_CHECK);
2768 LRVAL (tree) = RRVAL (tree) = 1;
2769 tree->left = addCast (tree->left, resultType, FALSE);
2770 tree->right = addCast (tree->right, resultType, FALSE);
2771 TETYPE (tree) = getSpec (TTYPE (tree) =
2772 computeType (LTYPE (tree),
2778 /*------------------------------------------------------------------*/
2779 /*----------------------------*/
2781 /*----------------------------*/
2783 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2785 werror (E_INVALID_OP, "divide");
2786 goto errorTreeReturn;
2788 /* if they are both literal then */
2789 /* rewrite the tree */
2790 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2792 tree->type = EX_VALUE;
2793 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2794 valFromType (RETYPE (tree)));
2795 tree->right = tree->left = NULL;
2796 TETYPE (tree) = getSpec (TTYPE (tree) =
2797 tree->opval.val->type);
2801 LRVAL (tree) = RRVAL (tree) = 1;
2803 TETYPE (tree) = getSpec (TTYPE (tree) =
2804 computeType (LTYPE (tree),
2806 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2808 /* if right is a literal and */
2809 /* left is also a division by a literal then */
2810 /* rearrange the tree */
2811 if (IS_LITERAL (RTYPE (tree))
2812 /* avoid infinite loop */
2813 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2816 ast *litTree = searchLitOp (tree, &parent, "/");
2819 if (IS_LITERAL (RTYPE (litTree)))
2822 litTree->right = newNode ('*', litTree->right, tree->right);
2823 litTree->right->lineno = tree->lineno;
2825 tree->right->opval.val = constVal ("1");
2826 decorateType (parent, RESULT_CHECK);
2830 /* litTree->left is literal: no gcse possible.
2831 We can't call decorateType(parent, RESULT_CHECK), because
2832 this would cause an infinit loop. */
2833 parent->decorated = 1;
2834 decorateType (litTree, RESULT_CHECK);
2841 /*------------------------------------------------------------------*/
2842 /*----------------------------*/
2844 /*----------------------------*/
2846 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2848 werror (E_BITWISE_OP);
2849 werror (W_CONTINUE, "left & right types are ");
2850 printTypeChain (LTYPE (tree), stderr);
2851 fprintf (stderr, ",");
2852 printTypeChain (RTYPE (tree), stderr);
2853 fprintf (stderr, "\n");
2854 goto errorTreeReturn;
2856 /* if they are both literal then */
2857 /* rewrite the tree */
2858 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2860 tree->type = EX_VALUE;
2861 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2862 valFromType (RETYPE (tree)));
2863 tree->right = tree->left = NULL;
2864 TETYPE (tree) = getSpec (TTYPE (tree) =
2865 tree->opval.val->type);
2868 LRVAL (tree) = RRVAL (tree) = 1;
2869 TETYPE (tree) = getSpec (TTYPE (tree) =
2870 computeType (LTYPE (tree),
2872 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2875 /*------------------------------------------------------------------*/
2876 /*----------------------------*/
2877 /* address dereference */
2878 /*----------------------------*/
2879 case '*': /* can be unary : if right is null then unary operation */
2882 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2884 werror (E_PTR_REQD);
2885 goto errorTreeReturn;
2890 werror (E_LVALUE_REQUIRED, "pointer deref");
2891 goto errorTreeReturn;
2893 if (IS_ADDRESS_OF_OP(tree->left))
2895 /* replace *&obj with obj */
2896 return tree->left->left;
2898 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2899 TETYPE (tree) = getSpec (TTYPE (tree));
2900 /* adjust the storage class */
2901 switch (DCL_TYPE(tree->left->ftype)) {
2903 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2906 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2909 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2912 SPEC_SCLS (TETYPE (tree)) = 0;
2915 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2918 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2921 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2924 SPEC_SCLS (TETYPE (tree)) = 0;
2933 /*------------------------------------------------------------------*/
2934 /*----------------------------*/
2935 /* multiplication */
2936 /*----------------------------*/
2937 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2939 werror (E_INVALID_OP, "multiplication");
2940 goto errorTreeReturn;
2943 /* if they are both literal then */
2944 /* rewrite the tree */
2945 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2947 tree->type = EX_VALUE;
2948 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2949 valFromType (RETYPE (tree)));
2950 tree->right = tree->left = NULL;
2951 TETYPE (tree) = getSpec (TTYPE (tree) =
2952 tree->opval.val->type);
2956 /* if left is a literal exchange left & right */
2957 if (IS_LITERAL (LTYPE (tree)))
2959 ast *tTree = tree->left;
2960 tree->left = tree->right;
2961 tree->right = tTree;
2964 /* if right is a literal and */
2965 /* we can find a 2nd literal in a mul-tree then */
2966 /* rearrange the tree */
2967 if (IS_LITERAL (RTYPE (tree)))
2970 ast *litTree = searchLitOp (tree, &parent, "*");
2973 ast *tTree = litTree->left;
2974 litTree->left = tree->right;
2975 tree->right = tTree;
2976 /* both operands in litTree are literal now */
2977 decorateType (parent, RESULT_CHECK);
2981 LRVAL (tree) = RRVAL (tree) = 1;
2982 tree->left = addCast (tree->left, resultType, FALSE);
2983 tree->right = addCast (tree->right, resultType, FALSE);
2984 TETYPE (tree) = getSpec (TTYPE (tree) =
2985 computeType (LTYPE (tree),
2987 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2991 /*------------------------------------------------------------------*/
2992 /*----------------------------*/
2993 /* unary '+' operator */
2994 /*----------------------------*/
2999 if (!IS_ARITHMETIC (LTYPE (tree)))
3001 werror (E_UNARY_OP, '+');
3002 goto errorTreeReturn;
3005 /* if left is a literal then do it */
3006 if (IS_LITERAL (LTYPE (tree)))
3008 tree->type = EX_VALUE;
3009 tree->opval.val = valFromType (LETYPE (tree));
3011 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3015 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3019 /*------------------------------------------------------------------*/
3020 /*----------------------------*/
3022 /*----------------------------*/
3024 /* this is not a unary operation */
3025 /* if both pointers then problem */
3026 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3027 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3029 werror (E_PTR_PLUS_PTR);
3030 goto errorTreeReturn;
3033 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3034 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3036 werror (E_PLUS_INVALID, "+");
3037 goto errorTreeReturn;
3040 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3041 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3043 werror (E_PLUS_INVALID, "+");
3044 goto errorTreeReturn;
3046 /* if they are both literal then */
3047 /* rewrite the tree */
3048 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3050 tree->type = EX_VALUE;
3051 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3052 valFromType (RETYPE (tree)));
3053 tree->right = tree->left = NULL;
3054 TETYPE (tree) = getSpec (TTYPE (tree) =
3055 tree->opval.val->type);
3059 /* if the right is a pointer or left is a literal
3060 xchange left & right */
3061 if (IS_ARRAY (RTYPE (tree)) ||
3062 IS_PTR (RTYPE (tree)) ||
3063 IS_LITERAL (LTYPE (tree)))
3065 ast *tTree = tree->left;
3066 tree->left = tree->right;
3067 tree->right = tTree;
3070 /* if right is a literal and */
3071 /* left is also an addition/subtraction with a literal then */
3072 /* rearrange the tree */
3073 if (IS_LITERAL (RTYPE (tree)))
3075 ast *litTree, *parent;
3076 litTree = searchLitOp (tree, &parent, "+-");
3079 if (litTree->opval.op == '+')
3082 ast *tTree = litTree->left;
3083 litTree->left = tree->right;
3084 tree->right = tree->left;
3087 else if (litTree->opval.op == '-')
3089 if (IS_LITERAL (RTYPE (litTree)))
3092 ast *tTree = litTree->left;
3093 litTree->left = tree->right;
3094 tree->right = tTree;
3099 ast *tTree = litTree->right;
3100 litTree->right = tree->right;
3101 tree->right = tTree;
3102 litTree->opval.op = '+';
3103 tree->opval.op = '-';
3106 decorateType (parent, RESULT_CHECK);
3110 LRVAL (tree) = RRVAL (tree) = 1;
3111 /* if the left is a pointer */
3112 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3113 TETYPE (tree) = getSpec (TTYPE (tree) =
3117 tree->left = addCast (tree->left, resultType, TRUE);
3118 tree->right = addCast (tree->right, resultType, TRUE);
3119 TETYPE (tree) = getSpec (TTYPE (tree) =
3120 computeType (LTYPE (tree),
3122 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3127 /*------------------------------------------------------------------*/
3128 /*----------------------------*/
3130 /*----------------------------*/
3131 case '-': /* can be unary */
3132 /* if right is null then unary */
3136 if (!IS_ARITHMETIC (LTYPE (tree)))
3138 werror (E_UNARY_OP, tree->opval.op);
3139 goto errorTreeReturn;
3142 /* if left is a literal then do it */
3143 if (IS_LITERAL (LTYPE (tree)))
3145 tree->type = EX_VALUE;
3146 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3148 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3149 SPEC_USIGN(TETYPE(tree)) = 0;
3153 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3157 /*------------------------------------------------------------------*/
3158 /*----------------------------*/
3160 /*----------------------------*/
3162 if (!(IS_PTR (LTYPE (tree)) ||
3163 IS_ARRAY (LTYPE (tree)) ||
3164 IS_ARITHMETIC (LTYPE (tree))))
3166 werror (E_PLUS_INVALID, "-");
3167 goto errorTreeReturn;
3170 if (!(IS_PTR (RTYPE (tree)) ||
3171 IS_ARRAY (RTYPE (tree)) ||
3172 IS_ARITHMETIC (RTYPE (tree))))
3174 werror (E_PLUS_INVALID, "-");
3175 goto errorTreeReturn;
3178 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3179 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3180 IS_INTEGRAL (RTYPE (tree))))
3182 werror (E_PLUS_INVALID, "-");
3183 goto errorTreeReturn;
3186 /* if they are both literal then */
3187 /* rewrite the tree */
3188 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3190 tree->type = EX_VALUE;
3191 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3192 valFromType (RETYPE (tree)));
3193 tree->right = tree->left = NULL;
3194 TETYPE (tree) = getSpec (TTYPE (tree) =
3195 tree->opval.val->type);
3199 /* if the left & right are equal then zero */
3200 if (isAstEqual (tree->left, tree->right))
3202 tree->type = EX_VALUE;
3203 tree->left = tree->right = NULL;
3204 tree->opval.val = constVal ("0");
3205 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3209 /* if both of them are pointers or arrays then */
3210 /* the result is going to be an integer */
3211 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3212 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3213 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3215 /* if only the left is a pointer */
3216 /* then result is a pointer */
3217 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3218 TETYPE (tree) = getSpec (TTYPE (tree) =
3222 tree->left = addCast (tree->left, resultType, TRUE);
3223 tree->right = addCast (tree->right, resultType, TRUE);
3224 TETYPE (tree) = getSpec (TTYPE (tree) =
3225 computeType (LTYPE (tree),
3227 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3230 LRVAL (tree) = RRVAL (tree) = 1;
3232 /* if right is a literal and */
3233 /* left is also an addition/subtraction with a literal then */
3234 /* rearrange the tree */
3235 if (IS_LITERAL (RTYPE (tree))
3236 /* avoid infinite loop */
3237 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3239 ast *litTree, *litParent;
3240 litTree = searchLitOp (tree, &litParent, "+-");
3243 if (litTree->opval.op == '+')
3246 litTree->right = newNode ('-', litTree->right, tree->right);
3247 litTree->right->lineno = tree->lineno;
3249 tree->right->opval.val = constVal ("0");
3251 else if (litTree->opval.op == '-')
3253 if (IS_LITERAL (RTYPE (litTree)))
3256 litTree->right = newNode ('+', tree->right, litTree->right);
3257 litTree->right->lineno = tree->lineno;
3259 tree->right->opval.val = constVal ("0");
3264 ast *tTree = litTree->right;
3265 litTree->right = tree->right;
3266 tree->right = tTree;
3269 decorateType (litParent, RESULT_CHECK);
3274 /*------------------------------------------------------------------*/
3275 /*----------------------------*/
3277 /*----------------------------*/
3279 /* can be only integral type */
3280 if (!IS_INTEGRAL (LTYPE (tree)))
3282 werror (E_UNARY_OP, tree->opval.op);
3283 goto errorTreeReturn;
3286 /* if left is a literal then do it */
3287 if (IS_LITERAL (LTYPE (tree)))
3289 tree->type = EX_VALUE;
3290 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3292 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3296 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3299 /*------------------------------------------------------------------*/
3300 /*----------------------------*/
3302 /*----------------------------*/
3304 /* can be pointer */
3305 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3306 !IS_PTR (LTYPE (tree)) &&
3307 !IS_ARRAY (LTYPE (tree)))
3309 werror (E_UNARY_OP, tree->opval.op);
3310 goto errorTreeReturn;
3313 /* if left is a literal then do it */
3314 if (IS_LITERAL (LTYPE (tree)))
3316 tree->type = EX_VALUE;
3317 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3319 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3323 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3326 /*------------------------------------------------------------------*/
3327 /*----------------------------*/
3329 /*----------------------------*/
3333 TTYPE (tree) = LTYPE (tree);
3334 TETYPE (tree) = LETYPE (tree);
3338 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3343 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3345 werror (E_SHIFT_OP_INVALID);
3346 werror (W_CONTINUE, "left & right types are ");
3347 printTypeChain (LTYPE (tree), stderr);
3348 fprintf (stderr, ",");
3349 printTypeChain (RTYPE (tree), stderr);
3350 fprintf (stderr, "\n");
3351 goto errorTreeReturn;
3354 /* if they are both literal then */
3355 /* rewrite the tree */
3356 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3358 tree->type = EX_VALUE;
3359 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3360 valFromType (RETYPE (tree)),
3361 (tree->opval.op == LEFT_OP ? 1 : 0));
3362 tree->right = tree->left = NULL;
3363 TETYPE (tree) = getSpec (TTYPE (tree) =
3364 tree->opval.val->type);
3368 LRVAL (tree) = RRVAL (tree) = 1;
3369 if (tree->opval.op == LEFT_OP)
3371 tree->left = addCast (tree->left, resultType, TRUE);
3372 TETYPE (tree) = getSpec (TTYPE (tree) =
3373 computeType (LTYPE (tree),
3375 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3379 /* no promotion necessary */
3380 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3381 if (IS_LITERAL (TTYPE (tree)))
3382 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3385 /* if only the right side is a literal & we are
3386 shifting more than size of the left operand then zero */
3387 if (IS_LITERAL (RTYPE (tree)) &&
3388 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3389 (getSize (TETYPE (tree)) * 8))
3391 if (tree->opval.op==LEFT_OP ||
3392 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3394 lineno=tree->lineno;
3395 werror (W_SHIFT_CHANGED,
3396 (tree->opval.op == LEFT_OP ? "left" : "right"));
3397 tree->type = EX_VALUE;
3398 tree->left = tree->right = NULL;
3399 tree->opval.val = constVal ("0");
3400 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3407 /*------------------------------------------------------------------*/
3408 /*----------------------------*/
3410 /*----------------------------*/
3411 case CAST: /* change the type */
3412 /* cannot cast to an aggregate type */
3413 if (IS_AGGREGATE (LTYPE (tree)))
3415 werror (E_CAST_ILLEGAL);
3416 goto errorTreeReturn;
3419 /* make sure the type is complete and sane */
3420 checkTypeSanity(LETYPE(tree), "(cast)");
3422 /* If code memory is read only, then pointers to code memory */
3423 /* implicitly point to constants -- make this explicit */
3425 sym_link *t = LTYPE(tree);
3426 while (t && t->next)
3428 if (IS_CODEPTR(t) && port->mem.code_ro)
3430 if (IS_SPEC(t->next))
3431 SPEC_CONST (t->next) = 1;
3433 DCL_PTR_CONST (t->next) = 1;
3440 /* if the right is a literal replace the tree */
3441 if (IS_LITERAL (RETYPE (tree))) {
3442 if (!IS_PTR (LTYPE (tree))) {
3443 tree->type = EX_VALUE;
3445 valCastLiteral (LTYPE (tree),
3446 floatFromVal (valFromType (RETYPE (tree))));
3449 TTYPE (tree) = tree->opval.val->type;
3450 tree->values.literalFromCast = 1;
3451 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3452 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3453 sym_link *rest = LTYPE(tree)->next;
3454 werror(W_LITERAL_GENERIC);
3455 TTYPE(tree) = newLink(DECLARATOR);
3456 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3457 TTYPE(tree)->next = rest;
3458 tree->left->opval.lnk = TTYPE(tree);
3461 TTYPE (tree) = LTYPE (tree);
3465 TTYPE (tree) = LTYPE (tree);
3469 #if 0 // this is already checked, now this could be explicit
3470 /* if pointer to struct then check names */
3471 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3472 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3473 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3475 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3476 SPEC_STRUCT(LETYPE(tree))->tag);
3479 if (IS_ADDRESS_OF_OP(tree->right)
3480 && IS_AST_SYM_VALUE (tree->right->left)
3481 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3483 tree->type = EX_VALUE;
3485 valCastLiteral (LTYPE (tree),
3486 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3487 TTYPE (tree) = tree->opval.val->type;
3488 TETYPE (tree) = getSpec (TTYPE (tree));
3491 tree->values.literalFromCast = 1;
3495 /* handle offsetof macro: */
3496 /* #define offsetof(TYPE, MEMBER) \ */
3497 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3498 if (IS_ADDRESS_OF_OP(tree->right)
3499 && IS_AST_OP (tree->right->left)
3500 && tree->right->left->opval.op == PTR_OP
3501 && IS_AST_OP (tree->right->left->left)
3502 && tree->right->left->left->opval.op == CAST
3503 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3505 symbol *element = getStructElement (
3506 SPEC_STRUCT (LETYPE(tree->right->left)),
3507 AST_SYMBOL(tree->right->left->right)
3511 tree->type = EX_VALUE;
3512 tree->opval.val = valCastLiteral (
3515 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3518 TTYPE (tree) = tree->opval.val->type;
3519 TETYPE (tree) = getSpec (TTYPE (tree));
3526 /* if the right is a literal replace the tree */
3527 if (IS_LITERAL (RETYPE (tree))) {
3529 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3530 /* rewrite (type *)litaddr
3532 and define type at litaddr temp
3533 (but only if type's storage class is not generic)
3535 ast *newTree = newNode ('&', NULL, NULL);
3538 TTYPE (newTree) = LTYPE (tree);
3539 TETYPE (newTree) = getSpec(LTYPE (tree));
3541 /* define a global symbol at the casted address*/
3542 sym = newSymbol(genSymName (0), 0);
3543 sym->type = LTYPE (tree)->next;
3545 sym->type = newLink (V_VOID);
3546 sym->etype = getSpec(sym->type);
3547 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3548 sym->lineDef = tree->lineno;
3551 SPEC_STAT (sym->etype) = 1;
3552 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3553 SPEC_ABSA(sym->etype) = 1;
3554 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3557 newTree->left = newAst_VALUE(symbolVal(sym));
3558 newTree->left->lineno = tree->lineno;
3559 LTYPE (newTree) = sym->type;
3560 LETYPE (newTree) = sym->etype;
3561 LLVAL (newTree) = 1;
3562 LRVAL (newTree) = 0;
3563 TLVAL (newTree) = 1;
3567 if (!IS_PTR (LTYPE (tree))) {
3568 tree->type = EX_VALUE;
3570 valCastLiteral (LTYPE (tree),
3571 floatFromVal (valFromType (RTYPE (tree))));
3572 TTYPE (tree) = tree->opval.val->type;
3575 tree->values.literalFromCast = 1;
3576 TETYPE (tree) = getSpec (TTYPE (tree));
3580 TTYPE (tree) = LTYPE (tree);
3584 TETYPE (tree) = getSpec (TTYPE (tree));
3588 /*------------------------------------------------------------------*/
3589 /*----------------------------*/
3590 /* logical &&, || */
3591 /*----------------------------*/
3594 /* each must me arithmetic type or be a pointer */
3595 if (!IS_PTR (LTYPE (tree)) &&
3596 !IS_ARRAY (LTYPE (tree)) &&
3597 !IS_INTEGRAL (LTYPE (tree)))
3599 werror (E_COMPARE_OP);
3600 goto errorTreeReturn;
3603 if (!IS_PTR (RTYPE (tree)) &&
3604 !IS_ARRAY (RTYPE (tree)) &&
3605 !IS_INTEGRAL (RTYPE (tree)))
3607 werror (E_COMPARE_OP);
3608 goto errorTreeReturn;
3610 /* if they are both literal then */
3611 /* rewrite the tree */
3612 if (IS_LITERAL (RTYPE (tree)) &&
3613 IS_LITERAL (LTYPE (tree)))
3615 tree->type = EX_VALUE;
3616 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3617 valFromType (RTYPE (tree)),
3619 tree->right = tree->left = NULL;
3620 TETYPE (tree) = getSpec (TTYPE (tree) =
3621 tree->opval.val->type);
3624 LRVAL (tree) = RRVAL (tree) = 1;
3625 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3628 /*------------------------------------------------------------------*/
3629 /*----------------------------*/
3630 /* comparison operators */
3631 /*----------------------------*/
3639 ast *lt = optimizeCompare (tree);
3645 /* if they are pointers they must be castable */
3646 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3648 if (tree->opval.op==EQ_OP &&
3649 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3650 // we cannot cast a gptr to a !gptr: switch the leaves
3651 struct ast *s=tree->left;
3652 tree->left=tree->right;
3655 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3657 werror (E_COMPARE_OP);
3658 fprintf (stderr, "comparing type ");
3659 printTypeChain (LTYPE (tree), stderr);
3660 fprintf (stderr, "to type ");
3661 printTypeChain (RTYPE (tree), stderr);
3662 fprintf (stderr, "\n");
3663 goto errorTreeReturn;
3666 /* else they should be promotable to one another */
3669 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3670 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3672 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3674 werror (E_COMPARE_OP);
3675 fprintf (stderr, "comparing type ");
3676 printTypeChain (LTYPE (tree), stderr);
3677 fprintf (stderr, "to type ");
3678 printTypeChain (RTYPE (tree), stderr);
3679 fprintf (stderr, "\n");
3680 goto errorTreeReturn;
3683 /* if unsigned value < 0 then always false */
3684 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3685 if (SPEC_USIGN(LETYPE(tree)) &&
3686 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3687 IS_LITERAL(RTYPE(tree)) &&
3688 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3690 if (tree->opval.op == '<')
3694 if (tree->opval.op == '>')
3696 if (resultType == RESULT_TYPE_IFX)
3698 /* the parent is an ifx: */
3699 /* if (unsigned value) */
3703 /* (unsigned value) ? 1 : 0 */
3704 tree->opval.op = '?';
3705 tree->right = newNode (':',
3706 newAst_VALUE (constVal ("1")),
3707 tree->right); /* val 0 */
3708 tree->right->lineno = tree->lineno;
3709 tree->right->left->lineno = tree->lineno;
3710 decorateType (tree->right, RESULT_CHECK);
3713 /* if they are both literal then */
3714 /* rewrite the tree */
3715 if (IS_LITERAL (RTYPE (tree)) &&
3716 IS_LITERAL (LTYPE (tree)))
3718 tree->type = EX_VALUE;
3719 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3720 valFromType (RETYPE (tree)),
3722 tree->right = tree->left = NULL;
3723 TETYPE (tree) = getSpec (TTYPE (tree) =
3724 tree->opval.val->type);
3727 LRVAL (tree) = RRVAL (tree) = 1;
3728 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3731 /*------------------------------------------------------------------*/
3732 /*----------------------------*/
3734 /*----------------------------*/
3735 case SIZEOF: /* evaluate wihout code generation */
3736 /* change the type to a integer */
3738 int size = getSize (tree->right->ftype);
3739 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3740 if (!size && !IS_VOID(tree->right->ftype))
3741 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3743 tree->type = EX_VALUE;
3744 tree->opval.val = constVal (buffer);
3745 tree->right = tree->left = NULL;
3746 TETYPE (tree) = getSpec (TTYPE (tree) =
3747 tree->opval.val->type);
3750 /*------------------------------------------------------------------*/
3751 /*----------------------------*/
3753 /*----------------------------*/
3755 /* return typeof enum value */
3756 tree->type = EX_VALUE;
3759 if (IS_SPEC(tree->right->ftype)) {
3760 switch (SPEC_NOUN(tree->right->ftype)) {
3762 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3763 else typeofv = TYPEOF_INT;
3766 typeofv = TYPEOF_FLOAT;
3769 typeofv = TYPEOF_CHAR;
3772 typeofv = TYPEOF_VOID;
3775 typeofv = TYPEOF_STRUCT;
3778 typeofv = TYPEOF_BITFIELD;
3781 typeofv = TYPEOF_BIT;
3784 typeofv = TYPEOF_SBIT;
3790 switch (DCL_TYPE(tree->right->ftype)) {
3792 typeofv = TYPEOF_POINTER;
3795 typeofv = TYPEOF_FPOINTER;
3798 typeofv = TYPEOF_CPOINTER;
3801 typeofv = TYPEOF_GPOINTER;
3804 typeofv = TYPEOF_PPOINTER;
3807 typeofv = TYPEOF_IPOINTER;
3810 typeofv = TYPEOF_ARRAY;
3813 typeofv = TYPEOF_FUNCTION;
3819 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3820 tree->opval.val = constVal (buffer);
3821 tree->right = tree->left = NULL;
3822 TETYPE (tree) = getSpec (TTYPE (tree) =
3823 tree->opval.val->type);
3826 /*------------------------------------------------------------------*/
3827 /*----------------------------*/
3828 /* conditional operator '?' */
3829 /*----------------------------*/
3831 /* the type is value of the colon operator (on the right) */
3832 assert (IS_COLON_OP (tree->right));
3833 /* if already known then replace the tree : optimizer will do it
3834 but faster to do it here */
3835 if (IS_LITERAL (LTYPE (tree)))
3837 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3838 return decorateType (tree->right->left, resultTypeProp);
3840 return decorateType (tree->right->right, resultTypeProp);
3844 tree->right = decorateType (tree->right, resultTypeProp);
3845 TTYPE (tree) = RTYPE (tree);
3846 TETYPE (tree) = getSpec (TTYPE (tree));
3851 /* if they don't match we have a problem */
3852 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3854 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3855 goto errorTreeReturn;
3858 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3859 TETYPE (tree) = getSpec (TTYPE (tree));
3863 #if 0 // assignment operators are converted by the parser
3864 /*------------------------------------------------------------------*/
3865 /*----------------------------*/
3866 /* assignment operators */
3867 /*----------------------------*/
3870 /* for these it must be both must be integral */
3871 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3872 !IS_ARITHMETIC (RTYPE (tree)))
3874 werror (E_OPS_INTEGRAL);
3875 goto errorTreeReturn;
3878 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3880 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3881 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3885 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3886 goto errorTreeReturn;
3897 /* for these it must be both must be integral */
3898 if (!IS_INTEGRAL (LTYPE (tree)) ||
3899 !IS_INTEGRAL (RTYPE (tree)))
3901 werror (E_OPS_INTEGRAL);
3902 goto errorTreeReturn;
3905 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3907 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3908 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3912 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3913 goto errorTreeReturn;
3919 /*------------------------------------------------------------------*/
3920 /*----------------------------*/
3922 /*----------------------------*/
3924 if (!(IS_PTR (LTYPE (tree)) ||
3925 IS_ARITHMETIC (LTYPE (tree))))
3927 werror (E_PLUS_INVALID, "-=");
3928 goto errorTreeReturn;
3931 if (!(IS_PTR (RTYPE (tree)) ||
3932 IS_ARITHMETIC (RTYPE (tree))))
3934 werror (E_PLUS_INVALID, "-=");
3935 goto errorTreeReturn;
3938 TETYPE (tree) = getSpec (TTYPE (tree) =
3939 computeType (LTYPE (tree),
3943 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3944 werror (E_CODE_WRITE, "-=");
3948 werror (E_LVALUE_REQUIRED, "-=");
3949 goto errorTreeReturn;
3955 /*------------------------------------------------------------------*/
3956 /*----------------------------*/
3958 /*----------------------------*/
3960 /* this is not a unary operation */
3961 /* if both pointers then problem */
3962 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3964 werror (E_PTR_PLUS_PTR);
3965 goto errorTreeReturn;
3968 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3970 werror (E_PLUS_INVALID, "+=");
3971 goto errorTreeReturn;
3974 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3976 werror (E_PLUS_INVALID, "+=");
3977 goto errorTreeReturn;
3980 TETYPE (tree) = getSpec (TTYPE (tree) =
3981 computeType (LTYPE (tree),
3985 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3986 werror (E_CODE_WRITE, "+=");
3990 werror (E_LVALUE_REQUIRED, "+=");
3991 goto errorTreeReturn;
3994 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3995 tree->opval.op = '=';
4000 /*------------------------------------------------------------------*/
4001 /*----------------------------*/
4002 /* straight assignemnt */
4003 /*----------------------------*/
4005 /* cannot be an aggregate */
4006 if (IS_AGGREGATE (LTYPE (tree)))
4008 werror (E_AGGR_ASSIGN);
4009 goto errorTreeReturn;
4012 /* they should either match or be castable */
4013 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4015 werror (E_TYPE_MISMATCH, "assignment", " ");
4016 printFromToType(RTYPE(tree),LTYPE(tree));
4019 /* if the left side of the tree is of type void
4020 then report error */
4021 if (IS_VOID (LTYPE (tree)))
4023 werror (E_CAST_ZERO);
4024 printFromToType(RTYPE(tree), LTYPE(tree));
4027 TETYPE (tree) = getSpec (TTYPE (tree) =
4031 if (!tree->initMode ) {
4032 if (IS_CONSTANT(LTYPE(tree)))
4033 werror (E_CODE_WRITE, "=");
4037 werror (E_LVALUE_REQUIRED, "=");
4038 goto errorTreeReturn;
4043 /*------------------------------------------------------------------*/
4044 /*----------------------------*/
4045 /* comma operator */
4046 /*----------------------------*/
4048 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4051 /*------------------------------------------------------------------*/
4052 /*----------------------------*/
4054 /*----------------------------*/
4057 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4058 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4060 if (tree->left->opval.op == '*' && !tree->left->right)
4061 tree->left = tree->left->left;
4064 /* require a function or pointer to function */
4065 if (!IS_FUNC (LTYPE (tree))
4066 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4068 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4069 goto errorTreeReturn;
4076 if (IS_CODEPTR(LTYPE(tree)))
4077 functype = LTYPE (tree)->next;
4079 functype = LTYPE (tree);
4081 if (processParms (tree->left, FUNC_ARGS(functype),
4082 tree->right, &parmNumber, TRUE)) {
4083 goto errorTreeReturn;
4086 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4087 !IFFUNC_ISBUILTIN(functype))
4089 reverseParms (tree->right);
4092 TTYPE (tree) = functype->next;
4093 TETYPE (tree) = getSpec (TTYPE (tree));
4097 /*------------------------------------------------------------------*/
4098 /*----------------------------*/
4099 /* return statement */
4100 /*----------------------------*/
4105 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4107 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4108 printFromToType (RTYPE(tree), currFunc->type->next);
4109 goto errorTreeReturn;
4112 if (IS_VOID (currFunc->type->next)
4114 !IS_VOID (RTYPE (tree)))
4116 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4117 goto errorTreeReturn;
4120 /* if there is going to be a casting required then add it */
4121 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4124 decorateType (newNode (CAST,
4125 newAst_LINK (copyLinkChain (currFunc->type->next)),
4135 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4137 werror (W_VOID_FUNC, currFunc->name);
4138 goto errorTreeReturn;
4141 TTYPE (tree) = TETYPE (tree) = NULL;
4144 /*------------------------------------------------------------------*/
4145 /*----------------------------*/
4146 /* switch statement */
4147 /*----------------------------*/
4149 /* the switch value must be an integer */
4150 if (!IS_INTEGRAL (LTYPE (tree)))
4152 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4153 goto errorTreeReturn;
4156 TTYPE (tree) = TETYPE (tree) = NULL;
4159 /*------------------------------------------------------------------*/
4160 /*----------------------------*/
4162 /*----------------------------*/
4164 tree->left = backPatchLabels (tree->left,
4167 TTYPE (tree) = TETYPE (tree) = NULL;
4170 /*------------------------------------------------------------------*/
4171 /*----------------------------*/
4173 /*----------------------------*/
4176 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4177 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4178 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4180 /* if the for loop is reversible then
4181 reverse it otherwise do what we normally
4187 if (isLoopReversible (tree, &sym, &init, &end))
4188 return reverseLoop (tree, sym, init, end);
4190 return decorateType (createFor (AST_FOR (tree, trueLabel),
4191 AST_FOR (tree, continueLabel),
4192 AST_FOR (tree, falseLabel),
4193 AST_FOR (tree, condLabel),
4194 AST_FOR (tree, initExpr),
4195 AST_FOR (tree, condExpr),
4196 AST_FOR (tree, loopExpr),
4197 tree->left), RESULT_CHECK);
4200 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4201 "node PARAM shouldn't be processed here");
4202 /* but in processParams() */
4205 TTYPE (tree) = TETYPE (tree) = NULL;
4209 /* some error found this tree will be killed */
4211 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4212 tree->opval.op = NULLOP;
4218 /*-----------------------------------------------------------------*/
4219 /* sizeofOp - processes size of operation */
4220 /*-----------------------------------------------------------------*/
4222 sizeofOp (sym_link * type)
4227 /* make sure the type is complete and sane */
4228 checkTypeSanity(type, "(sizeof)");
4230 /* get the size and convert it to character */
4231 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4232 if (!size && !IS_VOID(type))
4233 werror (E_SIZEOF_INCOMPLETE_TYPE);
4235 /* now convert into value */
4236 return constVal (buff);
4240 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4241 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4242 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4243 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4244 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4245 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4246 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4248 /*-----------------------------------------------------------------*/
4249 /* backPatchLabels - change and or not operators to flow control */
4250 /*-----------------------------------------------------------------*/
4252 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4258 if (!(IS_ANDORNOT (tree)))
4261 /* if this an and */
4264 static int localLbl = 0;
4267 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4268 localLabel = newSymbol (buffer, NestLevel);
4270 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4272 /* if left is already a IFX then just change the if true label in that */
4273 if (!IS_IFX (tree->left))
4274 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4276 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4277 /* right is a IFX then just join */
4278 if (IS_IFX (tree->right))
4279 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4281 tree->right = createLabel (localLabel, tree->right);
4282 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4284 return newNode (NULLOP, tree->left, tree->right);
4287 /* if this is an or operation */
4290 static int localLbl = 0;
4293 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4294 localLabel = newSymbol (buffer, NestLevel);
4296 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4298 /* if left is already a IFX then just change the if true label in that */
4299 if (!IS_IFX (tree->left))
4300 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4302 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4303 /* right is a IFX then just join */
4304 if (IS_IFX (tree->right))
4305 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4307 tree->right = createLabel (localLabel, tree->right);
4308 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4310 return newNode (NULLOP, tree->left, tree->right);
4316 int wasnot = IS_NOT (tree->left);
4317 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4319 /* if the left is already a IFX */
4320 if (!IS_IFX (tree->left))
4321 tree->left = newNode (IFX, tree->left, NULL);
4325 tree->left->trueLabel = trueLabel;
4326 tree->left->falseLabel = falseLabel;
4330 tree->left->trueLabel = falseLabel;
4331 tree->left->falseLabel = trueLabel;
4338 tree->trueLabel = trueLabel;
4339 tree->falseLabel = falseLabel;
4346 /*-----------------------------------------------------------------*/
4347 /* createBlock - create expression tree for block */
4348 /*-----------------------------------------------------------------*/
4350 createBlock (symbol * decl, ast * body)
4354 /* if the block has nothing */
4358 ex = newNode (BLOCK, NULL, body);
4359 ex->values.sym = decl;
4361 ex->right = ex->right;
4367 /*-----------------------------------------------------------------*/
4368 /* createLabel - creates the expression tree for labels */
4369 /*-----------------------------------------------------------------*/
4371 createLabel (symbol * label, ast * stmnt)
4374 char name[SDCC_NAME_MAX + 1];
4377 /* must create fresh symbol if the symbol name */
4378 /* exists in the symbol table, since there can */
4379 /* be a variable with the same name as the labl */
4380 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4381 (csym->level == label->level))
4382 label = newSymbol (label->name, label->level);
4384 /* change the name before putting it in add _ */
4385 SNPRINTF(name, sizeof(name), "%s", label->name);
4387 /* put the label in the LabelSymbol table */
4388 /* but first check if a label of the same */
4390 if ((csym = findSym (LabelTab, NULL, name)))
4391 werror (E_DUPLICATE_LABEL, label->name);
4393 addSym (LabelTab, label, name, label->level, 0, 0);
4396 label->key = labelKey++;
4397 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4403 /*-----------------------------------------------------------------*/
4404 /* createCase - generates the parsetree for a case statement */
4405 /*-----------------------------------------------------------------*/
4407 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4409 char caseLbl[SDCC_NAME_MAX + 1];
4413 /* if the switch statement does not exist */
4414 /* then case is out of context */
4417 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4421 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4422 /* if not a constant then error */
4423 if (!IS_LITERAL (caseVal->ftype))
4425 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4429 /* if not a integer than error */
4430 if (!IS_INTEGRAL (caseVal->ftype))
4432 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4436 /* find the end of the switch values chain */
4437 if (!(val = swStat->values.switchVals.swVals))
4438 swStat->values.switchVals.swVals = caseVal->opval.val;
4441 /* also order the cases according to value */
4443 int cVal = (int) floatFromVal (caseVal->opval.val);
4444 while (val && (int) floatFromVal (val) < cVal)
4450 /* if we reached the end then */
4453 pval->next = caseVal->opval.val;
4455 else if ((int) floatFromVal (val) == cVal)
4457 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4463 /* we found a value greater than */
4464 /* the current value we must add this */
4465 /* before the value */
4466 caseVal->opval.val->next = val;
4468 /* if this was the first in chain */
4469 if (swStat->values.switchVals.swVals == val)
4470 swStat->values.switchVals.swVals =
4473 pval->next = caseVal->opval.val;
4478 /* create the case label */
4479 SNPRINTF(caseLbl, sizeof(caseLbl),
4481 swStat->values.switchVals.swNum,
4482 (int) floatFromVal (caseVal->opval.val));
4484 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4489 /*-----------------------------------------------------------------*/
4490 /* createDefault - creates the parse tree for the default statement */
4491 /*-----------------------------------------------------------------*/
4493 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4495 char defLbl[SDCC_NAME_MAX + 1];
4497 /* if the switch statement does not exist */
4498 /* then case is out of context */
4501 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4505 if (swStat->values.switchVals.swDefault)
4507 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4512 /* turn on the default flag */
4513 swStat->values.switchVals.swDefault = 1;
4515 /* create the label */
4516 SNPRINTF (defLbl, sizeof(defLbl),
4517 "_default_%d", swStat->values.switchVals.swNum);
4518 return createLabel (newSymbol (defLbl, 0), stmnt);
4521 /*-----------------------------------------------------------------*/
4522 /* createIf - creates the parsetree for the if statement */
4523 /*-----------------------------------------------------------------*/
4525 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4527 static int Lblnum = 0;
4529 symbol *ifTrue, *ifFalse, *ifEnd;
4531 /* if neither exists */
4532 if (!elseBody && !ifBody) {
4533 // if there are no side effects (i++, j() etc)
4534 if (!hasSEFcalls(condAst)) {
4539 /* create the labels */
4540 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4541 ifFalse = newSymbol (buffer, NestLevel);
4542 /* if no else body then end == false */
4547 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4548 ifEnd = newSymbol (buffer, NestLevel);
4551 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4552 ifTrue = newSymbol (buffer, NestLevel);
4556 /* attach the ifTrue label to the top of it body */
4557 ifBody = createLabel (ifTrue, ifBody);
4558 /* attach a goto end to the ifBody if else is present */
4561 ifBody = newNode (NULLOP, ifBody,
4563 newAst_VALUE (symbolVal (ifEnd)),
4565 /* put the elseLabel on the else body */
4566 elseBody = createLabel (ifFalse, elseBody);
4567 /* out the end at the end of the body */
4568 elseBody = newNode (NULLOP,
4570 createLabel (ifEnd, NULL));
4574 ifBody = newNode (NULLOP, ifBody,
4575 createLabel (ifFalse, NULL));
4577 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4578 if (IS_IFX (condAst))
4581 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4583 return newNode (NULLOP, ifTree,
4584 newNode (NULLOP, ifBody, elseBody));
4588 /*-----------------------------------------------------------------*/
4589 /* createDo - creates parse tree for do */
4592 /* _docontinue_n: */
4593 /* condition_expression +-> trueLabel -> _dobody_n */
4595 /* +-> falseLabel-> _dobreak_n */
4597 /*-----------------------------------------------------------------*/
4599 createDo (symbol * trueLabel, symbol * continueLabel,
4600 symbol * falseLabel, ast * condAst, ast * doBody)
4605 /* if the body does not exist then it is simple */
4608 condAst = backPatchLabels (condAst, continueLabel, NULL);
4609 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4610 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4611 doTree->trueLabel = continueLabel;
4612 doTree->falseLabel = NULL;
4616 /* otherwise we have a body */
4617 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4619 /* attach the body label to the top */
4620 doBody = createLabel (trueLabel, doBody);
4621 /* attach the continue label to end of body */
4622 doBody = newNode (NULLOP, doBody,
4623 createLabel (continueLabel, NULL));
4625 /* now put the break label at the end */
4626 if (IS_IFX (condAst))
4629 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4631 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4633 /* putting it together */
4634 return newNode (NULLOP, doBody, doTree);
4637 /*-----------------------------------------------------------------*/
4638 /* createFor - creates parse tree for 'for' statement */
4641 /* condExpr +-> trueLabel -> _forbody_n */
4643 /* +-> falseLabel-> _forbreak_n */
4646 /* _forcontinue_n: */
4648 /* goto _forcond_n ; */
4650 /*-----------------------------------------------------------------*/
4652 createFor (symbol * trueLabel, symbol * continueLabel,
4653 symbol * falseLabel, symbol * condLabel,
4654 ast * initExpr, ast * condExpr, ast * loopExpr,
4659 /* if loopexpression not present then we can generate it */
4660 /* the same way as a while */
4662 return newNode (NULLOP, initExpr,
4663 createWhile (trueLabel, continueLabel,
4664 falseLabel, condExpr, forBody));
4665 /* vanilla for statement */
4666 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4668 if (condExpr && !IS_IFX (condExpr))
4669 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4672 /* attach condition label to condition */
4673 condExpr = createLabel (condLabel, condExpr);
4675 /* attach body label to body */
4676 forBody = createLabel (trueLabel, forBody);
4678 /* attach continue to forLoop expression & attach */
4679 /* goto the forcond @ and of loopExpression */
4680 loopExpr = createLabel (continueLabel,
4684 newAst_VALUE (symbolVal (condLabel)),
4686 /* now start putting them together */
4687 forTree = newNode (NULLOP, initExpr, condExpr);
4688 forTree = newNode (NULLOP, forTree, forBody);
4689 forTree = newNode (NULLOP, forTree, loopExpr);
4690 /* finally add the break label */
4691 forTree = newNode (NULLOP, forTree,
4692 createLabel (falseLabel, NULL));
4696 /*-----------------------------------------------------------------*/
4697 /* createWhile - creates parse tree for while statement */
4698 /* the while statement will be created as follows */
4700 /* _while_continue_n: */
4701 /* condition_expression +-> trueLabel -> _while_boby_n */
4703 /* +-> falseLabel -> _while_break_n */
4704 /* _while_body_n: */
4706 /* goto _while_continue_n */
4707 /* _while_break_n: */
4708 /*-----------------------------------------------------------------*/
4710 createWhile (symbol * trueLabel, symbol * continueLabel,
4711 symbol * falseLabel, ast * condExpr, ast * whileBody)
4715 /* put the continue label */
4716 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4717 condExpr = createLabel (continueLabel, condExpr);
4718 condExpr->lineno = 0;
4720 /* put the body label in front of the body */
4721 whileBody = createLabel (trueLabel, whileBody);
4722 whileBody->lineno = 0;
4723 /* put a jump to continue at the end of the body */
4724 /* and put break label at the end of the body */
4725 whileBody = newNode (NULLOP,
4728 newAst_VALUE (symbolVal (continueLabel)),
4729 createLabel (falseLabel, NULL)));
4731 /* put it all together */
4732 if (IS_IFX (condExpr))
4733 whileTree = condExpr;
4736 whileTree = newNode (IFX, condExpr, NULL);
4737 /* put the true & false labels in place */
4738 whileTree->trueLabel = trueLabel;
4739 whileTree->falseLabel = falseLabel;
4742 return newNode (NULLOP, whileTree, whileBody);
4745 /*-----------------------------------------------------------------*/
4746 /* optimizeGetHbit - get highest order bit of the expression */
4747 /*-----------------------------------------------------------------*/
4749 optimizeGetHbit (ast * tree)
4752 /* if this is not a bit and */
4753 if (!IS_BITAND (tree))
4756 /* will look for tree of the form
4757 ( expr >> ((sizeof expr) -1) ) & 1 */
4758 if (!IS_AST_LIT_VALUE (tree->right))
4761 if (AST_LIT_VALUE (tree->right) != 1)
4764 if (!IS_RIGHT_OP (tree->left))
4767 if (!IS_AST_LIT_VALUE (tree->left->right))
4770 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4771 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4774 /* make sure the port supports GETHBIT */
4775 if (port->hasExtBitOp
4776 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4779 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4783 /*-----------------------------------------------------------------*/
4784 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4785 /*-----------------------------------------------------------------*/
4787 optimizeRRCRLC (ast * root)
4789 /* will look for trees of the form
4790 (?expr << 1) | (?expr >> 7) or
4791 (?expr >> 7) | (?expr << 1) will make that
4792 into a RLC : operation ..
4794 (?expr >> 1) | (?expr << 7) or
4795 (?expr << 7) | (?expr >> 1) will make that
4796 into a RRC operation
4797 note : by 7 I mean (number of bits required to hold the
4799 /* if the root operations is not a | operation the not */
4800 if (!IS_BITOR (root))
4803 /* I have to think of a better way to match patterns this sucks */
4804 /* that aside let start looking for the first case : I use a the
4805 negative check a lot to improve the efficiency */
4806 /* (?expr << 1) | (?expr >> 7) */
4807 if (IS_LEFT_OP (root->left) &&
4808 IS_RIGHT_OP (root->right))
4811 if (!SPEC_USIGN (TETYPE (root->left->left)))
4814 if (!IS_AST_LIT_VALUE (root->left->right) ||
4815 !IS_AST_LIT_VALUE (root->right->right))
4818 /* make sure it is the same expression */
4819 if (!isAstEqual (root->left->left,
4823 if (AST_LIT_VALUE (root->left->right) != 1)
4826 if (AST_LIT_VALUE (root->right->right) !=
4827 (getSize (TTYPE (root->left->left)) * 8 - 1))
4830 /* make sure the port supports RLC */
4831 if (port->hasExtBitOp
4832 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4835 /* whew got the first case : create the AST */
4836 return newNode (RLC, root->left->left, NULL);
4840 /* check for second case */
4841 /* (?expr >> 7) | (?expr << 1) */
4842 if (IS_LEFT_OP (root->right) &&
4843 IS_RIGHT_OP (root->left))
4846 if (!SPEC_USIGN (TETYPE (root->left->left)))
4849 if (!IS_AST_LIT_VALUE (root->left->right) ||
4850 !IS_AST_LIT_VALUE (root->right->right))
4853 /* make sure it is the same symbol */
4854 if (!isAstEqual (root->left->left,
4858 if (AST_LIT_VALUE (root->right->right) != 1)
4861 if (AST_LIT_VALUE (root->left->right) !=
4862 (getSize (TTYPE (root->left->left)) * 8 - 1))
4865 /* make sure the port supports RLC */
4866 if (port->hasExtBitOp
4867 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4870 /* whew got the first case : create the AST */
4871 return newNode (RLC, root->left->left, NULL);
4876 /* third case for RRC */
4877 /* (?symbol >> 1) | (?symbol << 7) */
4878 if (IS_LEFT_OP (root->right) &&
4879 IS_RIGHT_OP (root->left))
4882 if (!SPEC_USIGN (TETYPE (root->left->left)))
4885 if (!IS_AST_LIT_VALUE (root->left->right) ||
4886 !IS_AST_LIT_VALUE (root->right->right))
4889 /* make sure it is the same symbol */
4890 if (!isAstEqual (root->left->left,
4894 if (AST_LIT_VALUE (root->left->right) != 1)
4897 if (AST_LIT_VALUE (root->right->right) !=
4898 (getSize (TTYPE (root->left->left)) * 8 - 1))
4901 /* make sure the port supports RRC */
4902 if (port->hasExtBitOp
4903 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4906 /* whew got the first case : create the AST */
4907 return newNode (RRC, root->left->left, NULL);
4911 /* fourth and last case for now */
4912 /* (?symbol << 7) | (?symbol >> 1) */
4913 if (IS_RIGHT_OP (root->right) &&
4914 IS_LEFT_OP (root->left))
4917 if (!SPEC_USIGN (TETYPE (root->left->left)))
4920 if (!IS_AST_LIT_VALUE (root->left->right) ||
4921 !IS_AST_LIT_VALUE (root->right->right))
4924 /* make sure it is the same symbol */
4925 if (!isAstEqual (root->left->left,
4929 if (AST_LIT_VALUE (root->right->right) != 1)
4932 if (AST_LIT_VALUE (root->left->right) !=
4933 (getSize (TTYPE (root->left->left)) * 8 - 1))
4936 /* make sure the port supports RRC */
4937 if (port->hasExtBitOp
4938 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4941 /* whew got the first case : create the AST */
4942 return newNode (RRC, root->left->left, NULL);
4946 /* not found return root */
4950 /*-----------------------------------------------------------------*/
4951 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4952 /*-----------------------------------------------------------------*/
4954 optimizeSWAP (ast * root)
4956 /* will look for trees of the form
4957 (?expr << 4) | (?expr >> 4) or
4958 (?expr >> 4) | (?expr << 4) will make that
4959 into a SWAP : operation ..
4960 note : by 4 I mean (number of bits required to hold the
4962 /* if the root operations is not a | operation the not */
4963 if (!IS_BITOR (root))
4966 /* (?expr << 4) | (?expr >> 4) */
4967 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4968 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4971 if (!SPEC_USIGN (TETYPE (root->left->left)))
4974 if (!IS_AST_LIT_VALUE (root->left->right) ||
4975 !IS_AST_LIT_VALUE (root->right->right))
4978 /* make sure it is the same expression */
4979 if (!isAstEqual (root->left->left,
4983 if (AST_LIT_VALUE (root->left->right) !=
4984 (getSize (TTYPE (root->left->left)) * 4))
4987 if (AST_LIT_VALUE (root->right->right) !=
4988 (getSize (TTYPE (root->left->left)) * 4))
4991 /* make sure the port supports SWAP */
4992 if (port->hasExtBitOp
4993 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4996 /* found it : create the AST */
4997 return newNode (SWAP, root->left->left, NULL);
5001 /* not found return root */
5005 /*-----------------------------------------------------------------*/
5006 /* optimizeCompare - otimizes compares for bit variables */
5007 /*-----------------------------------------------------------------*/
5009 optimizeCompare (ast * root)
5011 ast *optExpr = NULL;
5014 unsigned int litValue;
5016 /* if nothing then return nothing */
5020 /* if not a compare op then do leaves */
5021 if (!IS_COMPARE_OP (root))
5023 root->left = optimizeCompare (root->left);
5024 root->right = optimizeCompare (root->right);
5028 /* if left & right are the same then depending
5029 of the operation do */
5030 if (isAstEqual (root->left, root->right))
5032 switch (root->opval.op)
5037 optExpr = newAst_VALUE (constVal ("0"));
5042 optExpr = newAst_VALUE (constVal ("1"));
5046 return decorateType (optExpr, RESULT_CHECK);
5049 vleft = (root->left->type == EX_VALUE ?
5050 root->left->opval.val : NULL);
5052 vright = (root->right->type == EX_VALUE ?
5053 root->right->opval.val : NULL);
5055 /* if left is a BITVAR in BITSPACE */
5056 /* and right is a LITERAL then opt- */
5057 /* imize else do nothing */
5058 if (vleft && vright &&
5059 IS_BITVAR (vleft->etype) &&
5060 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5061 IS_LITERAL (vright->etype))
5064 /* if right side > 1 then comparison may never succeed */
5065 if ((litValue = (int) floatFromVal (vright)) > 1)
5067 werror (W_BAD_COMPARE);
5073 switch (root->opval.op)
5075 case '>': /* bit value greater than 1 cannot be */
5076 werror (W_BAD_COMPARE);
5080 case '<': /* bit value < 1 means 0 */
5082 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5085 case LE_OP: /* bit value <= 1 means no check */
5086 optExpr = newAst_VALUE (vright);
5089 case GE_OP: /* bit value >= 1 means only check for = */
5091 optExpr = newAst_VALUE (vleft);
5096 { /* literal is zero */
5097 switch (root->opval.op)
5099 case '<': /* bit value < 0 cannot be */
5100 werror (W_BAD_COMPARE);
5104 case '>': /* bit value > 0 means 1 */
5106 optExpr = newAst_VALUE (vleft);
5109 case LE_OP: /* bit value <= 0 means no check */
5110 case GE_OP: /* bit value >= 0 means no check */
5111 werror (W_BAD_COMPARE);
5115 case EQ_OP: /* bit == 0 means ! of bit */
5116 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5120 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5121 } /* end-of-if of BITVAR */
5126 /*-----------------------------------------------------------------*/
5127 /* addSymToBlock : adds the symbol to the first block we find */
5128 /*-----------------------------------------------------------------*/
5130 addSymToBlock (symbol * sym, ast * tree)
5132 /* reached end of tree or a leaf */
5133 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5137 if (IS_AST_OP (tree) &&
5138 tree->opval.op == BLOCK)
5141 symbol *lsym = copySymbol (sym);
5143 lsym->next = AST_VALUES (tree, sym);
5144 AST_VALUES (tree, sym) = lsym;
5148 addSymToBlock (sym, tree->left);
5149 addSymToBlock (sym, tree->right);
5152 /*-----------------------------------------------------------------*/
5153 /* processRegParms - do processing for register parameters */
5154 /*-----------------------------------------------------------------*/
5156 processRegParms (value * args, ast * body)
5160 if (IS_REGPARM (args->etype))
5161 addSymToBlock (args->sym, body);
5166 /*-----------------------------------------------------------------*/
5167 /* resetParmKey - resets the operandkeys for the symbols */
5168 /*-----------------------------------------------------------------*/
5169 DEFSETFUNC (resetParmKey)
5180 /*-----------------------------------------------------------------*/
5181 /* createFunction - This is the key node that calls the iCode for */
5182 /* generating the code for a function. Note code */
5183 /* is generated function by function, later when */
5184 /* add inter-procedural analysis this will change */
5185 /*-----------------------------------------------------------------*/
5187 createFunction (symbol * name, ast * body)
5193 iCode *piCode = NULL;
5195 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5196 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5198 /* if check function return 0 then some problem */
5199 if (checkFunction (name, NULL) == 0)
5202 /* create a dummy block if none exists */
5204 body = newNode (BLOCK, NULL, NULL);
5208 /* check if the function name already in the symbol table */
5209 if ((csym = findSym (SymbolTab, NULL, name->name)))
5212 /* special case for compiler defined functions
5213 we need to add the name to the publics list : this
5214 actually means we are now compiling the compiler
5218 addSet (&publics, name);
5224 allocVariables (name);
5226 name->lastLine = mylineno;
5229 /* set the stack pointer */
5230 /* PENDING: check this for the mcs51 */
5231 stackPtr = -port->stack.direction * port->stack.call_overhead;
5232 if (IFFUNC_ISISR (name->type))
5233 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5234 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5235 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5237 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5239 fetype = getSpec (name->type); /* get the specifier for the function */
5240 /* if this is a reentrant function then */
5241 if (IFFUNC_ISREENT (name->type))
5244 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5246 /* do processing for parameters that are passed in registers */
5247 processRegParms (FUNC_ARGS(name->type), body);
5249 /* set the stack pointer */
5253 /* allocate & autoinit the block variables */
5254 processBlockVars (body, &stack, ALLOCATE);
5256 /* save the stack information */
5257 if (options.useXstack)
5258 name->xstack = SPEC_STAK (fetype) = stack;
5260 name->stack = SPEC_STAK (fetype) = stack;
5262 /* name needs to be mangled */
5263 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5265 body = resolveSymbols (body); /* resolve the symbols */
5266 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5269 ex = newAst_VALUE (symbolVal (name)); /* create name */
5270 ex = newNode (FUNCTION, ex, body);
5271 ex->values.args = FUNC_ARGS(name->type);
5273 if (options.dump_tree) PA(ex);
5276 werror (E_FUNC_NO_CODE, name->name);
5280 /* create the node & generate intermediate code */
5282 codeOutFile = code->oFile;
5283 piCode = iCodeFromAst (ex);
5287 werror (E_FUNC_NO_CODE, name->name);
5291 eBBlockFromiCode (piCode);
5293 /* if there are any statics then do them */
5296 GcurMemmap = statsg;
5297 codeOutFile = statsg->oFile;
5298 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5304 /* dealloc the block variables */
5305 processBlockVars (body, &stack, DEALLOCATE);
5306 outputDebugStackSymbols();
5307 /* deallocate paramaters */
5308 deallocParms (FUNC_ARGS(name->type));
5310 if (IFFUNC_ISREENT (name->type))
5313 /* we are done freeup memory & cleanup */
5315 if (port->reset_labelKey) labelKey = 1;
5317 FUNC_HASBODY(name->type) = 1;
5318 addSet (&operKeyReset, name);
5319 applyToSet (operKeyReset, resetParmKey);
5324 cleanUpLevel (LabelTab, 0);
5325 cleanUpBlock (StructTab, 1);
5326 cleanUpBlock (TypedefTab, 1);
5328 xstack->syms = NULL;
5329 istack->syms = NULL;
5334 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5335 /*-----------------------------------------------------------------*/
5336 /* ast_print : prints the ast (for debugging purposes) */
5337 /*-----------------------------------------------------------------*/
5339 void ast_print (ast * tree, FILE *outfile, int indent)
5344 /* can print only decorated trees */
5345 if (!tree->decorated) return;
5347 /* if any child is an error | this one is an error do nothing */
5348 if (tree->isError ||
5349 (tree->left && tree->left->isError) ||
5350 (tree->right && tree->right->isError)) {
5351 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5355 /* print the line */
5356 /* if not block & function */
5357 if (tree->type == EX_OP &&
5358 (tree->opval.op != FUNCTION &&
5359 tree->opval.op != BLOCK &&
5360 tree->opval.op != NULLOP)) {
5363 if (tree->opval.op == FUNCTION) {
5365 value *args=FUNC_ARGS(tree->left->opval.val->type);
5366 fprintf(outfile,"FUNCTION (%s=%p) type (",
5367 tree->left->opval.val->name, tree);
5368 printTypeChain (tree->left->opval.val->type->next,outfile);
5369 fprintf(outfile,") args (");
5372 fprintf (outfile, ", ");
5374 printTypeChain (args ? args->type : NULL, outfile);
5376 args= args ? args->next : NULL;
5378 fprintf(outfile,")\n");
5379 ast_print(tree->left,outfile,indent);
5380 ast_print(tree->right,outfile,indent);
5383 if (tree->opval.op == BLOCK) {
5384 symbol *decls = tree->values.sym;
5385 INDENT(indent,outfile);
5386 fprintf(outfile,"{\n");
5388 INDENT(indent+2,outfile);
5389 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5390 decls->name, decls);
5391 printTypeChain(decls->type,outfile);
5392 fprintf(outfile,")\n");
5394 decls = decls->next;
5396 ast_print(tree->right,outfile,indent+2);
5397 INDENT(indent,outfile);
5398 fprintf(outfile,"}\n");
5401 if (tree->opval.op == NULLOP) {
5402 ast_print(tree->left,outfile,indent);
5403 ast_print(tree->right,outfile,indent);
5406 INDENT(indent,outfile);
5408 /*------------------------------------------------------------------*/
5409 /*----------------------------*/
5410 /* leaf has been reached */
5411 /*----------------------------*/
5412 /* if this is of type value */
5413 /* just get the type */
5414 if (tree->type == EX_VALUE) {
5416 if (IS_LITERAL (tree->opval.val->etype)) {
5417 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5418 if (SPEC_USIGN (tree->opval.val->etype))
5419 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5421 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5422 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5423 floatFromVal(tree->opval.val));
5424 } else if (tree->opval.val->sym) {
5425 /* if the undefined flag is set then give error message */
5426 if (tree->opval.val->sym->undefined) {
5427 fprintf(outfile,"UNDEFINED SYMBOL ");
5429 fprintf(outfile,"SYMBOL ");
5431 fprintf(outfile,"(%s=%p)",
5432 tree->opval.val->sym->name,tree);
5435 fprintf(outfile," type (");
5436 printTypeChain(tree->ftype,outfile);
5437 fprintf(outfile,")\n");
5439 fprintf(outfile,"\n");
5444 /* if type link for the case of cast */
5445 if (tree->type == EX_LINK) {
5446 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5447 printTypeChain(tree->opval.lnk,outfile);
5448 fprintf(outfile,")\n");
5453 /* depending on type of operator do */
5455 switch (tree->opval.op) {
5456 /*------------------------------------------------------------------*/
5457 /*----------------------------*/
5459 /*----------------------------*/
5461 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5462 printTypeChain(tree->ftype,outfile);
5463 fprintf(outfile,")\n");
5464 ast_print(tree->left,outfile,indent+2);
5465 ast_print(tree->right,outfile,indent+2);
5468 /*------------------------------------------------------------------*/
5469 /*----------------------------*/
5471 /*----------------------------*/
5473 fprintf(outfile,"STRUCT_ACCESS (%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 /*------------------------------------------------------------------*/
5481 /*----------------------------*/
5482 /* struct/union pointer */
5483 /*----------------------------*/
5485 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5486 printTypeChain(tree->ftype,outfile);
5487 fprintf(outfile,")\n");
5488 ast_print(tree->left,outfile,indent+2);
5489 ast_print(tree->right,outfile,indent+2);
5492 /*------------------------------------------------------------------*/
5493 /*----------------------------*/
5494 /* ++/-- operation */
5495 /*----------------------------*/
5498 fprintf(outfile,"post-");
5500 fprintf(outfile,"pre-");
5501 fprintf(outfile,"INC_OP (%p) type (",tree);
5502 printTypeChain(tree->ftype,outfile);
5503 fprintf(outfile,")\n");
5504 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5505 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5510 fprintf(outfile,"post-");
5512 fprintf(outfile,"pre-");
5513 fprintf(outfile,"DEC_OP (%p) type (",tree);
5514 printTypeChain(tree->ftype,outfile);
5515 fprintf(outfile,")\n");
5516 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5517 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5520 /*------------------------------------------------------------------*/
5521 /*----------------------------*/
5523 /*----------------------------*/
5526 fprintf(outfile,"& (%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);
5532 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5533 printTypeChain(tree->ftype,outfile);
5534 fprintf(outfile,")\n");
5535 ast_print(tree->left,outfile,indent+2);
5536 ast_print(tree->right,outfile,indent+2);
5539 /*----------------------------*/
5541 /*----------------------------*/
5543 fprintf(outfile,"OR (%p) type (",tree);
5544 printTypeChain(tree->ftype,outfile);
5545 fprintf(outfile,")\n");
5546 ast_print(tree->left,outfile,indent+2);
5547 ast_print(tree->right,outfile,indent+2);
5549 /*------------------------------------------------------------------*/
5550 /*----------------------------*/
5552 /*----------------------------*/
5554 fprintf(outfile,"XOR (%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);
5561 /*------------------------------------------------------------------*/
5562 /*----------------------------*/
5564 /*----------------------------*/
5566 fprintf(outfile,"DIV (%p) type (",tree);
5567 printTypeChain(tree->ftype,outfile);
5568 fprintf(outfile,")\n");
5569 ast_print(tree->left,outfile,indent+2);
5570 ast_print(tree->right,outfile,indent+2);
5572 /*------------------------------------------------------------------*/
5573 /*----------------------------*/
5575 /*----------------------------*/
5577 fprintf(outfile,"MOD (%p) type (",tree);
5578 printTypeChain(tree->ftype,outfile);
5579 fprintf(outfile,")\n");
5580 ast_print(tree->left,outfile,indent+2);
5581 ast_print(tree->right,outfile,indent+2);
5584 /*------------------------------------------------------------------*/
5585 /*----------------------------*/
5586 /* address dereference */
5587 /*----------------------------*/
5588 case '*': /* can be unary : if right is null then unary operation */
5590 fprintf(outfile,"DEREF (%p) type (",tree);
5591 printTypeChain(tree->ftype,outfile);
5592 fprintf(outfile,")\n");
5593 ast_print(tree->left,outfile,indent+2);
5596 /*------------------------------------------------------------------*/
5597 /*----------------------------*/
5598 /* multiplication */
5599 /*----------------------------*/
5600 fprintf(outfile,"MULT (%p) type (",tree);
5601 printTypeChain(tree->ftype,outfile);
5602 fprintf(outfile,")\n");
5603 ast_print(tree->left,outfile,indent+2);
5604 ast_print(tree->right,outfile,indent+2);
5608 /*------------------------------------------------------------------*/
5609 /*----------------------------*/
5610 /* unary '+' operator */
5611 /*----------------------------*/
5615 fprintf(outfile,"UPLUS (%p) type (",tree);
5616 printTypeChain(tree->ftype,outfile);
5617 fprintf(outfile,")\n");
5618 ast_print(tree->left,outfile,indent+2);
5620 /*------------------------------------------------------------------*/
5621 /*----------------------------*/
5623 /*----------------------------*/
5624 fprintf(outfile,"ADD (%p) type (",tree);
5625 printTypeChain(tree->ftype,outfile);
5626 fprintf(outfile,")\n");
5627 ast_print(tree->left,outfile,indent+2);
5628 ast_print(tree->right,outfile,indent+2);
5631 /*------------------------------------------------------------------*/
5632 /*----------------------------*/
5634 /*----------------------------*/
5635 case '-': /* can be unary */
5637 fprintf(outfile,"UMINUS (%p) type (",tree);
5638 printTypeChain(tree->ftype,outfile);
5639 fprintf(outfile,")\n");
5640 ast_print(tree->left,outfile,indent+2);
5642 /*------------------------------------------------------------------*/
5643 /*----------------------------*/
5645 /*----------------------------*/
5646 fprintf(outfile,"SUB (%p) type (",tree);
5647 printTypeChain(tree->ftype,outfile);
5648 fprintf(outfile,")\n");
5649 ast_print(tree->left,outfile,indent+2);
5650 ast_print(tree->right,outfile,indent+2);
5653 /*------------------------------------------------------------------*/
5654 /*----------------------------*/
5656 /*----------------------------*/
5658 fprintf(outfile,"COMPL (%p) type (",tree);
5659 printTypeChain(tree->ftype,outfile);
5660 fprintf(outfile,")\n");
5661 ast_print(tree->left,outfile,indent+2);
5663 /*------------------------------------------------------------------*/
5664 /*----------------------------*/
5666 /*----------------------------*/
5668 fprintf(outfile,"NOT (%p) type (",tree);
5669 printTypeChain(tree->ftype,outfile);
5670 fprintf(outfile,")\n");
5671 ast_print(tree->left,outfile,indent+2);
5673 /*------------------------------------------------------------------*/
5674 /*----------------------------*/
5676 /*----------------------------*/
5678 fprintf(outfile,"RRC (%p) type (",tree);
5679 printTypeChain(tree->ftype,outfile);
5680 fprintf(outfile,")\n");
5681 ast_print(tree->left,outfile,indent+2);
5685 fprintf(outfile,"RLC (%p) type (",tree);
5686 printTypeChain(tree->ftype,outfile);
5687 fprintf(outfile,")\n");
5688 ast_print(tree->left,outfile,indent+2);
5691 fprintf(outfile,"SWAP (%p) type (",tree);
5692 printTypeChain(tree->ftype,outfile);
5693 fprintf(outfile,")\n");
5694 ast_print(tree->left,outfile,indent+2);
5697 fprintf(outfile,"GETHBIT (%p) type (",tree);
5698 printTypeChain(tree->ftype,outfile);
5699 fprintf(outfile,")\n");
5700 ast_print(tree->left,outfile,indent+2);
5703 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5704 printTypeChain(tree->ftype,outfile);
5705 fprintf(outfile,")\n");
5706 ast_print(tree->left,outfile,indent+2);
5707 ast_print(tree->right,outfile,indent+2);
5710 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5711 printTypeChain(tree->ftype,outfile);
5712 fprintf(outfile,")\n");
5713 ast_print(tree->left,outfile,indent+2);
5714 ast_print(tree->right,outfile,indent+2);
5716 /*------------------------------------------------------------------*/
5717 /*----------------------------*/
5719 /*----------------------------*/
5720 case CAST: /* change the type */
5721 fprintf(outfile,"CAST (%p) from type (",tree);
5722 printTypeChain(tree->right->ftype,outfile);
5723 fprintf(outfile,") to type (");
5724 printTypeChain(tree->ftype,outfile);
5725 fprintf(outfile,")\n");
5726 ast_print(tree->right,outfile,indent+2);
5730 fprintf(outfile,"ANDAND (%p) type (",tree);
5731 printTypeChain(tree->ftype,outfile);
5732 fprintf(outfile,")\n");
5733 ast_print(tree->left,outfile,indent+2);
5734 ast_print(tree->right,outfile,indent+2);
5737 fprintf(outfile,"OROR (%p) type (",tree);
5738 printTypeChain(tree->ftype,outfile);
5739 fprintf(outfile,")\n");
5740 ast_print(tree->left,outfile,indent+2);
5741 ast_print(tree->right,outfile,indent+2);
5744 /*------------------------------------------------------------------*/
5745 /*----------------------------*/
5746 /* comparison operators */
5747 /*----------------------------*/
5749 fprintf(outfile,"GT(>) (%p) type (",tree);
5750 printTypeChain(tree->ftype,outfile);
5751 fprintf(outfile,")\n");
5752 ast_print(tree->left,outfile,indent+2);
5753 ast_print(tree->right,outfile,indent+2);
5756 fprintf(outfile,"LT(<) (%p) type (",tree);
5757 printTypeChain(tree->ftype,outfile);
5758 fprintf(outfile,")\n");
5759 ast_print(tree->left,outfile,indent+2);
5760 ast_print(tree->right,outfile,indent+2);
5763 fprintf(outfile,"LE(<=) (%p) type (",tree);
5764 printTypeChain(tree->ftype,outfile);
5765 fprintf(outfile,")\n");
5766 ast_print(tree->left,outfile,indent+2);
5767 ast_print(tree->right,outfile,indent+2);
5770 fprintf(outfile,"GE(>=) (%p) type (",tree);
5771 printTypeChain(tree->ftype,outfile);
5772 fprintf(outfile,")\n");
5773 ast_print(tree->left,outfile,indent+2);
5774 ast_print(tree->right,outfile,indent+2);
5777 fprintf(outfile,"EQ(==) (%p) type (",tree);
5778 printTypeChain(tree->ftype,outfile);
5779 fprintf(outfile,")\n");
5780 ast_print(tree->left,outfile,indent+2);
5781 ast_print(tree->right,outfile,indent+2);
5784 fprintf(outfile,"NE(!=) (%p) type (",tree);
5785 printTypeChain(tree->ftype,outfile);
5786 fprintf(outfile,")\n");
5787 ast_print(tree->left,outfile,indent+2);
5788 ast_print(tree->right,outfile,indent+2);
5789 /*------------------------------------------------------------------*/
5790 /*----------------------------*/
5792 /*----------------------------*/
5793 case SIZEOF: /* evaluate wihout code generation */
5794 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5797 /*------------------------------------------------------------------*/
5798 /*----------------------------*/
5799 /* conditional operator '?' */
5800 /*----------------------------*/
5802 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5803 printTypeChain(tree->ftype,outfile);
5804 fprintf(outfile,")\n");
5805 ast_print(tree->left,outfile,indent+2);
5806 ast_print(tree->right,outfile,indent+2);
5810 fprintf(outfile,"COLON(:) (%p) type (",tree);
5811 printTypeChain(tree->ftype,outfile);
5812 fprintf(outfile,")\n");
5813 ast_print(tree->left,outfile,indent+2);
5814 ast_print(tree->right,outfile,indent+2);
5817 /*------------------------------------------------------------------*/
5818 /*----------------------------*/
5819 /* assignment operators */
5820 /*----------------------------*/
5822 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5823 printTypeChain(tree->ftype,outfile);
5824 fprintf(outfile,")\n");
5825 ast_print(tree->left,outfile,indent+2);
5826 ast_print(tree->right,outfile,indent+2);
5829 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5830 printTypeChain(tree->ftype,outfile);
5831 fprintf(outfile,")\n");
5832 ast_print(tree->left,outfile,indent+2);
5833 ast_print(tree->right,outfile,indent+2);
5836 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5837 printTypeChain(tree->ftype,outfile);
5838 fprintf(outfile,")\n");
5839 ast_print(tree->left,outfile,indent+2);
5840 ast_print(tree->right,outfile,indent+2);
5843 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5844 printTypeChain(tree->ftype,outfile);
5845 fprintf(outfile,")\n");
5846 ast_print(tree->left,outfile,indent+2);
5847 ast_print(tree->right,outfile,indent+2);
5850 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5851 printTypeChain(tree->ftype,outfile);
5852 fprintf(outfile,")\n");
5853 ast_print(tree->left,outfile,indent+2);
5854 ast_print(tree->right,outfile,indent+2);
5857 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5858 printTypeChain(tree->ftype,outfile);
5859 fprintf(outfile,")\n");
5860 ast_print(tree->left,outfile,indent+2);
5861 ast_print(tree->right,outfile,indent+2);
5864 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5865 printTypeChain(tree->ftype,outfile);
5866 fprintf(outfile,")\n");
5867 ast_print(tree->left,outfile,indent+2);
5868 ast_print(tree->right,outfile,indent+2);
5870 /*------------------------------------------------------------------*/
5871 /*----------------------------*/
5873 /*----------------------------*/
5875 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5876 printTypeChain(tree->ftype,outfile);
5877 fprintf(outfile,")\n");
5878 ast_print(tree->left,outfile,indent+2);
5879 ast_print(tree->right,outfile,indent+2);
5881 /*------------------------------------------------------------------*/
5882 /*----------------------------*/
5884 /*----------------------------*/
5886 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5887 printTypeChain(tree->ftype,outfile);
5888 fprintf(outfile,")\n");
5889 ast_print(tree->left,outfile,indent+2);
5890 ast_print(tree->right,outfile,indent+2);
5892 /*------------------------------------------------------------------*/
5893 /*----------------------------*/
5894 /* straight assignemnt */
5895 /*----------------------------*/
5897 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5898 printTypeChain(tree->ftype,outfile);
5899 fprintf(outfile,")\n");
5900 ast_print(tree->left,outfile,indent+2);
5901 ast_print(tree->right,outfile,indent+2);
5903 /*------------------------------------------------------------------*/
5904 /*----------------------------*/
5905 /* comma operator */
5906 /*----------------------------*/
5908 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5909 printTypeChain(tree->ftype,outfile);
5910 fprintf(outfile,")\n");
5911 ast_print(tree->left,outfile,indent+2);
5912 ast_print(tree->right,outfile,indent+2);
5914 /*------------------------------------------------------------------*/
5915 /*----------------------------*/
5917 /*----------------------------*/
5920 fprintf(outfile,"CALL (%p) type (",tree);
5921 printTypeChain(tree->ftype,outfile);
5922 fprintf(outfile,")\n");
5923 ast_print(tree->left,outfile,indent+2);
5924 ast_print(tree->right,outfile,indent+2);
5927 fprintf(outfile,"PARMS\n");
5928 ast_print(tree->left,outfile,indent+2);
5929 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5930 ast_print(tree->right,outfile,indent+2);
5933 /*------------------------------------------------------------------*/
5934 /*----------------------------*/
5935 /* return statement */
5936 /*----------------------------*/
5938 fprintf(outfile,"RETURN (%p) type (",tree);
5940 printTypeChain(tree->right->ftype,outfile);
5942 fprintf(outfile,")\n");
5943 ast_print(tree->right,outfile,indent+2);
5945 /*------------------------------------------------------------------*/
5946 /*----------------------------*/
5947 /* label statement */
5948 /*----------------------------*/
5950 fprintf(outfile,"LABEL (%p)\n",tree);
5951 ast_print(tree->left,outfile,indent+2);
5952 ast_print(tree->right,outfile,indent);
5954 /*------------------------------------------------------------------*/
5955 /*----------------------------*/
5956 /* switch statement */
5957 /*----------------------------*/
5961 fprintf(outfile,"SWITCH (%p) ",tree);
5962 ast_print(tree->left,outfile,0);
5963 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5964 INDENT(indent+2,outfile);
5965 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5966 (int) floatFromVal(val),
5967 tree->values.switchVals.swNum,
5968 (int) floatFromVal(val));
5970 ast_print(tree->right,outfile,indent);
5973 /*------------------------------------------------------------------*/
5974 /*----------------------------*/
5976 /*----------------------------*/
5978 fprintf(outfile,"IF (%p) \n",tree);
5979 ast_print(tree->left,outfile,indent+2);
5980 if (tree->trueLabel) {
5981 INDENT(indent+2,outfile);
5982 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5984 if (tree->falseLabel) {
5985 INDENT(indent+2,outfile);
5986 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5988 ast_print(tree->right,outfile,indent+2);
5990 /*----------------------------*/
5991 /* goto Statement */
5992 /*----------------------------*/
5994 fprintf(outfile,"GOTO (%p) \n",tree);
5995 ast_print(tree->left,outfile,indent+2);
5996 fprintf(outfile,"\n");
5998 /*------------------------------------------------------------------*/
5999 /*----------------------------*/
6001 /*----------------------------*/
6003 fprintf(outfile,"FOR (%p) \n",tree);
6004 if (AST_FOR( tree, initExpr)) {
6005 INDENT(indent+2,outfile);
6006 fprintf(outfile,"INIT EXPR ");
6007 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6009 if (AST_FOR( tree, condExpr)) {
6010 INDENT(indent+2,outfile);
6011 fprintf(outfile,"COND EXPR ");
6012 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6014 if (AST_FOR( tree, loopExpr)) {
6015 INDENT(indent+2,outfile);
6016 fprintf(outfile,"LOOP EXPR ");
6017 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6019 fprintf(outfile,"FOR LOOP BODY \n");
6020 ast_print(tree->left,outfile,indent+2);
6023 fprintf(outfile,"CRITICAL (%p) \n",tree);
6024 ast_print(tree->left,outfile,indent+2);
6032 ast_print(t,stdout,0);
6037 /*-----------------------------------------------------------------*/
6038 /* astErrors : returns non-zero if errors present in tree */
6039 /*-----------------------------------------------------------------*/
6040 int astErrors(ast *t)
6049 if (t->type == EX_VALUE
6050 && t->opval.val->sym
6051 && t->opval.val->sym->undefined)
6054 errors += astErrors(t->left);
6055 errors += astErrors(t->right);