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 if (tree->opval.op == '?')
2291 dtl = decorateType (tree->left, RESULT_TYPE_NONE);
2293 dtl = decorateType (tree->left, resultTypeProp);
2295 /* if an array node, we may need to swap branches */
2296 if (tree->opval.op == '[')
2298 /* determine which is the array & which the index */
2299 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2300 IS_INTEGRAL (LTYPE (tree)))
2302 ast *tempTree = tree->left;
2303 tree->left = tree->right;
2304 tree->right = tempTree;
2308 /* After decorating the left branch there's type information available
2309 in tree->left->?type. If the op is e.g. '=' we extract the type
2310 information from there and propagate it to the right branch. */
2311 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2313 switch (tree->opval.op)
2316 /* delay right side for '?' operator since conditional macro
2317 expansions might rely on this */
2321 /* decorate right side for CALL (parameter list) in processParms();
2322 there is resultType available */
2326 dtr = decorateType (tree->right, resultTypeProp);
2330 /* this is to take care of situations
2331 when the tree gets rewritten */
2332 if (dtl != tree->left)
2334 if (dtr != tree->right)
2336 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2340 /* depending on type of operator do */
2342 switch (tree->opval.op)
2344 /*------------------------------------------------------------------*/
2345 /*----------------------------*/
2347 /*----------------------------*/
2350 /* first check if this is a array or a pointer */
2351 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2353 werror (E_NEED_ARRAY_PTR, "[]");
2354 goto errorTreeReturn;
2357 /* check if the type of the idx */
2358 if (!IS_INTEGRAL (RTYPE (tree)))
2360 werror (E_IDX_NOT_INT);
2361 goto errorTreeReturn;
2364 /* if the left is an rvalue then error */
2367 werror (E_LVALUE_REQUIRED, "array access");
2368 goto errorTreeReturn;
2371 if (IS_LITERAL (RTYPE (tree)))
2373 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2374 int arraySize = DCL_ELEM (LTYPE (tree));
2375 if (arraySize && arrayIndex >= arraySize)
2377 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2382 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2385 /*------------------------------------------------------------------*/
2386 /*----------------------------*/
2388 /*----------------------------*/
2390 /* if this is not a structure */
2391 if (!IS_STRUCT (LTYPE (tree)))
2393 werror (E_STRUCT_UNION, ".");
2394 goto errorTreeReturn;
2396 TTYPE (tree) = structElemType (LTYPE (tree),
2397 (tree->right->type == EX_VALUE ?
2398 tree->right->opval.val : NULL));
2399 TETYPE (tree) = getSpec (TTYPE (tree));
2402 /*------------------------------------------------------------------*/
2403 /*----------------------------*/
2404 /* struct/union pointer */
2405 /*----------------------------*/
2407 /* if not pointer to a structure */
2408 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2410 werror (E_PTR_REQD);
2411 goto errorTreeReturn;
2414 if (!IS_STRUCT (LTYPE (tree)->next))
2416 werror (E_STRUCT_UNION, "->");
2417 goto errorTreeReturn;
2420 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2421 (tree->right->type == EX_VALUE ?
2422 tree->right->opval.val : NULL));
2423 TETYPE (tree) = getSpec (TTYPE (tree));
2425 /* adjust the storage class */
2426 switch (DCL_TYPE(tree->left->ftype)) {
2428 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2431 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2434 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2437 SPEC_SCLS (TETYPE (tree)) = 0;
2440 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2443 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2446 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2449 SPEC_SCLS (TETYPE (tree)) = 0;
2456 /* This breaks with extern declarations, bitfields, and perhaps other */
2457 /* cases (gcse). Let's leave this optimization disabled for now and */
2458 /* ponder if there's a safe way to do this. -- EEP */
2460 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2461 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2463 /* If defined struct type at addr var
2464 then rewrite (&struct var)->member
2466 and define membertype at (addr+offsetof(struct var,member)) temp
2469 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2470 AST_SYMBOL(tree->right));
2472 sym = newSymbol(genSymName (0), 0);
2473 sym->type = TTYPE (tree);
2474 sym->etype = getSpec(sym->type);
2475 sym->lineDef = tree->lineno;
2478 SPEC_STAT (sym->etype) = 1;
2479 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2481 SPEC_ABSA(sym->etype) = 1;
2482 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2485 AST_VALUE (tree) = symbolVal(sym);
2488 tree->type = EX_VALUE;
2496 /*------------------------------------------------------------------*/
2497 /*----------------------------*/
2498 /* ++/-- operation */
2499 /*----------------------------*/
2503 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2504 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2505 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2506 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2515 /*------------------------------------------------------------------*/
2516 /*----------------------------*/
2518 /*----------------------------*/
2519 case '&': /* can be unary */
2520 /* if right is NULL then unary operation */
2521 if (tree->right) /* not an unary operation */
2524 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2526 werror (E_BITWISE_OP);
2527 werror (W_CONTINUE, "left & right types are ");
2528 printTypeChain (LTYPE (tree), stderr);
2529 fprintf (stderr, ",");
2530 printTypeChain (RTYPE (tree), stderr);
2531 fprintf (stderr, "\n");
2532 goto errorTreeReturn;
2535 /* if they are both literal */
2536 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2538 tree->type = EX_VALUE;
2539 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2540 valFromType (RETYPE (tree)), '&');
2542 tree->right = tree->left = NULL;
2543 TETYPE (tree) = tree->opval.val->etype;
2544 TTYPE (tree) = tree->opval.val->type;
2548 /* see if this is a GETHBIT operation if yes
2551 ast *otree = optimizeGetHbit (tree);
2554 return decorateType (otree, RESULT_CHECK);
2557 tree->left = addCast (tree->left, resultType, FALSE);
2558 tree->right = addCast (tree->right, resultType, FALSE);
2559 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2560 TETYPE (tree) = getSpec (TTYPE (tree));
2562 /* if left is a literal exchange left & right */
2563 if (IS_LITERAL (LTYPE (tree)))
2565 ast *tTree = tree->left;
2566 tree->left = tree->right;
2567 tree->right = tTree;
2570 /* if right is a literal and */
2571 /* we can find a 2nd literal in a and-tree then */
2572 /* rearrange the tree */
2573 if (IS_LITERAL (RTYPE (tree)))
2576 ast *litTree = searchLitOp (tree, &parent, "&");
2579 ast *tTree = litTree->left;
2580 litTree->left = tree->right;
2581 tree->right = tTree;
2582 /* both operands in tTree are literal now */
2583 decorateType (parent, RESULT_CHECK);
2587 LRVAL (tree) = RRVAL (tree) = 1;
2592 /*------------------------------------------------------------------*/
2593 /*----------------------------*/
2595 /*----------------------------*/
2596 p = newLink (DECLARATOR);
2597 /* if bit field then error */
2598 if (IS_BITVAR (tree->left->etype))
2600 werror (E_ILLEGAL_ADDR, "address of bit variable");
2601 goto errorTreeReturn;
2604 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2606 werror (E_ILLEGAL_ADDR, "address of register variable");
2607 goto errorTreeReturn;
2610 if (IS_FUNC (LTYPE (tree)))
2612 // this ought to be ignored
2613 return (tree->left);
2616 if (IS_LITERAL(LTYPE(tree)))
2618 werror (E_ILLEGAL_ADDR, "address of literal");
2619 goto errorTreeReturn;
2624 werror (E_LVALUE_REQUIRED, "address of");
2625 goto errorTreeReturn;
2628 DCL_TYPE (p) = POINTER;
2629 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2630 DCL_TYPE (p) = CPOINTER;
2631 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2632 DCL_TYPE (p) = FPOINTER;
2633 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2634 DCL_TYPE (p) = PPOINTER;
2635 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2636 DCL_TYPE (p) = IPOINTER;
2637 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2638 DCL_TYPE (p) = EEPPOINTER;
2639 else if (SPEC_OCLS(tree->left->etype))
2640 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2642 DCL_TYPE (p) = POINTER;
2644 if (IS_AST_SYM_VALUE (tree->left))
2646 AST_SYMBOL (tree->left)->addrtaken = 1;
2647 AST_SYMBOL (tree->left)->allocreq = 1;
2650 p->next = LTYPE (tree);
2652 TETYPE (tree) = getSpec (TTYPE (tree));
2657 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2658 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2660 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2661 AST_SYMBOL(tree->left->right));
2662 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2663 valueFromLit(element->offset));
2666 tree->type = EX_VALUE;
2667 tree->values.literalFromCast = 1;
2673 /*------------------------------------------------------------------*/
2674 /*----------------------------*/
2676 /*----------------------------*/
2678 /* if the rewrite succeeds then don't go any furthur */
2680 ast *wtree = optimizeRRCRLC (tree);
2682 return decorateType (wtree, RESULT_CHECK);
2684 wtree = optimizeSWAP (tree);
2686 return decorateType (wtree, RESULT_CHECK);
2689 /* if left is a literal exchange left & right */
2690 if (IS_LITERAL (LTYPE (tree)))
2692 ast *tTree = tree->left;
2693 tree->left = tree->right;
2694 tree->right = tTree;
2697 /* if right is a literal and */
2698 /* we can find a 2nd literal in a or-tree then */
2699 /* rearrange the tree */
2700 if (IS_LITERAL (RTYPE (tree)))
2703 ast *litTree = searchLitOp (tree, &parent, "|");
2706 ast *tTree = litTree->left;
2707 litTree->left = tree->right;
2708 tree->right = tTree;
2709 /* both operands in tTree are literal now */
2710 decorateType (parent, RESULT_CHECK);
2715 /*------------------------------------------------------------------*/
2716 /*----------------------------*/
2718 /*----------------------------*/
2720 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2722 werror (E_BITWISE_OP);
2723 werror (W_CONTINUE, "left & right types are ");
2724 printTypeChain (LTYPE (tree), stderr);
2725 fprintf (stderr, ",");
2726 printTypeChain (RTYPE (tree), stderr);
2727 fprintf (stderr, "\n");
2728 goto errorTreeReturn;
2731 /* if they are both literal then */
2732 /* rewrite the tree */
2733 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2735 tree->type = EX_VALUE;
2736 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2737 valFromType (RETYPE (tree)),
2739 tree->right = tree->left = NULL;
2740 TETYPE (tree) = tree->opval.val->etype;
2741 TTYPE (tree) = tree->opval.val->type;
2745 /* if left is a literal exchange left & right */
2746 if (IS_LITERAL (LTYPE (tree)))
2748 ast *tTree = tree->left;
2749 tree->left = tree->right;
2750 tree->right = tTree;
2753 /* if right is a literal and */
2754 /* we can find a 2nd literal in a xor-tree then */
2755 /* rearrange the tree */
2756 if (IS_LITERAL (RTYPE (tree)) &&
2757 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2760 ast *litTree = searchLitOp (tree, &parent, "^");
2763 ast *tTree = litTree->left;
2764 litTree->left = tree->right;
2765 tree->right = tTree;
2766 /* both operands in litTree are literal now */
2767 decorateType (parent, RESULT_CHECK);
2771 LRVAL (tree) = RRVAL (tree) = 1;
2772 tree->left = addCast (tree->left, resultType, FALSE);
2773 tree->right = addCast (tree->right, resultType, FALSE);
2774 TETYPE (tree) = getSpec (TTYPE (tree) =
2775 computeType (LTYPE (tree),
2781 /*------------------------------------------------------------------*/
2782 /*----------------------------*/
2784 /*----------------------------*/
2786 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2788 werror (E_INVALID_OP, "divide");
2789 goto errorTreeReturn;
2791 /* if they are both literal then */
2792 /* rewrite the tree */
2793 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2795 tree->type = EX_VALUE;
2796 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2797 valFromType (RETYPE (tree)),
2798 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE);
2799 tree->right = tree->left = NULL;
2800 TETYPE (tree) = getSpec (TTYPE (tree) =
2801 tree->opval.val->type);
2805 LRVAL (tree) = RRVAL (tree) = 1;
2807 TETYPE (tree) = getSpec (TTYPE (tree) =
2808 computeType (LTYPE (tree),
2810 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2812 /* if right is a literal and */
2813 /* left is also a division by a literal then */
2814 /* rearrange the tree */
2815 if (IS_LITERAL (RTYPE (tree))
2816 /* avoid infinite loop */
2817 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2820 ast *litTree = searchLitOp (tree, &parent, "/");
2823 if (IS_LITERAL (RTYPE (litTree)))
2826 litTree->right = newNode ('*', litTree->right, tree->right);
2827 litTree->right->lineno = tree->lineno;
2829 tree->right->opval.val = constVal ("1");
2830 decorateType (parent, RESULT_CHECK);
2834 /* litTree->left is literal: no gcse possible.
2835 We can't call decorateType(parent, RESULT_CHECK), because
2836 this would cause an infinit loop. */
2837 parent->decorated = 1;
2838 decorateType (litTree, RESULT_CHECK);
2845 /*------------------------------------------------------------------*/
2846 /*----------------------------*/
2848 /*----------------------------*/
2850 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2852 werror (E_BITWISE_OP);
2853 werror (W_CONTINUE, "left & right types are ");
2854 printTypeChain (LTYPE (tree), stderr);
2855 fprintf (stderr, ",");
2856 printTypeChain (RTYPE (tree), stderr);
2857 fprintf (stderr, "\n");
2858 goto errorTreeReturn;
2860 /* if they are both literal then */
2861 /* rewrite the tree */
2862 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2864 tree->type = EX_VALUE;
2865 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2866 valFromType (RETYPE (tree)));
2867 tree->right = tree->left = NULL;
2868 TETYPE (tree) = getSpec (TTYPE (tree) =
2869 tree->opval.val->type);
2872 LRVAL (tree) = RRVAL (tree) = 1;
2873 TETYPE (tree) = getSpec (TTYPE (tree) =
2874 computeType (LTYPE (tree),
2876 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2879 /*------------------------------------------------------------------*/
2880 /*----------------------------*/
2881 /* address dereference */
2882 /*----------------------------*/
2883 case '*': /* can be unary : if right is null then unary operation */
2886 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2888 werror (E_PTR_REQD);
2889 goto errorTreeReturn;
2894 werror (E_LVALUE_REQUIRED, "pointer deref");
2895 goto errorTreeReturn;
2897 if (IS_ADDRESS_OF_OP(tree->left))
2899 /* replace *&obj with obj */
2900 return tree->left->left;
2902 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2903 TETYPE (tree) = getSpec (TTYPE (tree));
2904 /* adjust the storage class */
2905 switch (DCL_TYPE(tree->left->ftype)) {
2907 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2910 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2913 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2916 SPEC_SCLS (TETYPE (tree)) = 0;
2919 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2922 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2925 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2928 SPEC_SCLS (TETYPE (tree)) = 0;
2937 /*------------------------------------------------------------------*/
2938 /*----------------------------*/
2939 /* multiplication */
2940 /*----------------------------*/
2941 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2943 werror (E_INVALID_OP, "multiplication");
2944 goto errorTreeReturn;
2947 /* if they are both literal then */
2948 /* rewrite the tree */
2949 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2951 tree->type = EX_VALUE;
2952 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2953 valFromType (RETYPE (tree)),
2954 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE);
2955 tree->right = tree->left = NULL;
2956 TETYPE (tree) = getSpec (TTYPE (tree) =
2957 tree->opval.val->type);
2961 /* if left is a literal exchange left & right */
2962 if (IS_LITERAL (LTYPE (tree)))
2964 ast *tTree = tree->left;
2965 tree->left = tree->right;
2966 tree->right = tTree;
2969 /* if right is a literal and */
2970 /* we can find a 2nd literal in a mul-tree then */
2971 /* rearrange the tree */
2972 if (IS_LITERAL (RTYPE (tree)))
2975 ast *litTree = searchLitOp (tree, &parent, "*");
2978 ast *tTree = litTree->left;
2979 litTree->left = tree->right;
2980 tree->right = tTree;
2981 /* both operands in litTree are literal now */
2982 decorateType (parent, RESULT_CHECK);
2986 LRVAL (tree) = RRVAL (tree) = 1;
2987 tree->left = addCast (tree->left, resultType, FALSE);
2988 tree->right = addCast (tree->right, resultType, FALSE);
2989 TETYPE (tree) = getSpec (TTYPE (tree) =
2990 computeType (LTYPE (tree),
2992 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2996 /*------------------------------------------------------------------*/
2997 /*----------------------------*/
2998 /* unary '+' operator */
2999 /*----------------------------*/
3004 if (!IS_ARITHMETIC (LTYPE (tree)))
3006 werror (E_UNARY_OP, '+');
3007 goto errorTreeReturn;
3010 /* if left is a literal then do it */
3011 if (IS_LITERAL (LTYPE (tree)))
3013 tree->type = EX_VALUE;
3014 tree->opval.val = valFromType (LETYPE (tree));
3016 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3020 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3024 /*------------------------------------------------------------------*/
3025 /*----------------------------*/
3027 /*----------------------------*/
3029 /* this is not a unary operation */
3030 /* if both pointers then problem */
3031 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3032 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3034 werror (E_PTR_PLUS_PTR);
3035 goto errorTreeReturn;
3038 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3039 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3041 werror (E_PLUS_INVALID, "+");
3042 goto errorTreeReturn;
3045 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3046 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3048 werror (E_PLUS_INVALID, "+");
3049 goto errorTreeReturn;
3051 /* if they are both literal then */
3052 /* rewrite the tree */
3053 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3055 tree->type = EX_VALUE;
3056 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3057 valFromType (RETYPE (tree)));
3058 tree->right = tree->left = NULL;
3059 TETYPE (tree) = getSpec (TTYPE (tree) =
3060 tree->opval.val->type);
3064 /* if the right is a pointer or left is a literal
3065 xchange left & right */
3066 if (IS_ARRAY (RTYPE (tree)) ||
3067 IS_PTR (RTYPE (tree)) ||
3068 IS_LITERAL (LTYPE (tree)))
3070 ast *tTree = tree->left;
3071 tree->left = tree->right;
3072 tree->right = tTree;
3075 /* if right is a literal and */
3076 /* left is also an addition/subtraction with a literal then */
3077 /* rearrange the tree */
3078 if (IS_LITERAL (RTYPE (tree)))
3080 ast *litTree, *parent;
3081 litTree = searchLitOp (tree, &parent, "+-");
3084 if (litTree->opval.op == '+')
3087 ast *tTree = litTree->left;
3088 litTree->left = tree->right;
3089 tree->right = tree->left;
3092 else if (litTree->opval.op == '-')
3094 if (IS_LITERAL (RTYPE (litTree)))
3097 ast *tTree = litTree->left;
3098 litTree->left = tree->right;
3099 tree->right = tTree;
3104 ast *tTree = litTree->right;
3105 litTree->right = tree->right;
3106 tree->right = tTree;
3107 litTree->opval.op = '+';
3108 tree->opval.op = '-';
3111 decorateType (parent, RESULT_CHECK);
3115 LRVAL (tree) = RRVAL (tree) = 1;
3116 /* if the left is a pointer */
3117 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3118 TETYPE (tree) = getSpec (TTYPE (tree) =
3122 tree->left = addCast (tree->left, resultType, TRUE);
3123 tree->right = addCast (tree->right, resultType, TRUE);
3124 TETYPE (tree) = getSpec (TTYPE (tree) =
3125 computeType (LTYPE (tree),
3127 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3132 /*------------------------------------------------------------------*/
3133 /*----------------------------*/
3135 /*----------------------------*/
3136 case '-': /* can be unary */
3137 /* if right is null then unary */
3141 if (!IS_ARITHMETIC (LTYPE (tree)))
3143 werror (E_UNARY_OP, tree->opval.op);
3144 goto errorTreeReturn;
3147 /* if left is a literal then do it */
3148 if (IS_LITERAL (LTYPE (tree)))
3150 tree->type = EX_VALUE;
3151 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3153 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3154 SPEC_USIGN(TETYPE(tree)) = 0;
3158 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3162 /*------------------------------------------------------------------*/
3163 /*----------------------------*/
3165 /*----------------------------*/
3167 if (!(IS_PTR (LTYPE (tree)) ||
3168 IS_ARRAY (LTYPE (tree)) ||
3169 IS_ARITHMETIC (LTYPE (tree))))
3171 werror (E_PLUS_INVALID, "-");
3172 goto errorTreeReturn;
3175 if (!(IS_PTR (RTYPE (tree)) ||
3176 IS_ARRAY (RTYPE (tree)) ||
3177 IS_ARITHMETIC (RTYPE (tree))))
3179 werror (E_PLUS_INVALID, "-");
3180 goto errorTreeReturn;
3183 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3184 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3185 IS_INTEGRAL (RTYPE (tree))))
3187 werror (E_PLUS_INVALID, "-");
3188 goto errorTreeReturn;
3191 /* if they are both literal then */
3192 /* rewrite the tree */
3193 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3195 tree->type = EX_VALUE;
3196 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3197 valFromType (RETYPE (tree)));
3198 tree->right = tree->left = NULL;
3199 TETYPE (tree) = getSpec (TTYPE (tree) =
3200 tree->opval.val->type);
3204 /* if the left & right are equal then zero */
3205 if (isAstEqual (tree->left, tree->right))
3207 tree->type = EX_VALUE;
3208 tree->left = tree->right = NULL;
3209 tree->opval.val = constVal ("0");
3210 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3214 /* if both of them are pointers or arrays then */
3215 /* the result is going to be an integer */
3216 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3217 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3218 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3220 /* if only the left is a pointer */
3221 /* then result is a pointer */
3222 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3223 TETYPE (tree) = getSpec (TTYPE (tree) =
3227 tree->left = addCast (tree->left, resultType, TRUE);
3228 tree->right = addCast (tree->right, resultType, TRUE);
3229 TETYPE (tree) = getSpec (TTYPE (tree) =
3230 computeType (LTYPE (tree),
3232 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3235 LRVAL (tree) = RRVAL (tree) = 1;
3237 /* if right is a literal and */
3238 /* left is also an addition/subtraction with a literal then */
3239 /* rearrange the tree */
3240 if (IS_LITERAL (RTYPE (tree))
3241 /* avoid infinite loop */
3242 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3244 ast *litTree, *litParent;
3245 litTree = searchLitOp (tree, &litParent, "+-");
3248 if (litTree->opval.op == '+')
3251 litTree->right = newNode ('-', litTree->right, tree->right);
3252 litTree->right->lineno = tree->lineno;
3254 tree->right->opval.val = constVal ("0");
3256 else if (litTree->opval.op == '-')
3258 if (IS_LITERAL (RTYPE (litTree)))
3261 litTree->right = newNode ('+', tree->right, litTree->right);
3262 litTree->right->lineno = tree->lineno;
3264 tree->right->opval.val = constVal ("0");
3269 ast *tTree = litTree->right;
3270 litTree->right = tree->right;
3271 tree->right = tTree;
3274 decorateType (litParent, RESULT_CHECK);
3279 /*------------------------------------------------------------------*/
3280 /*----------------------------*/
3282 /*----------------------------*/
3284 /* can be only integral type */
3285 if (!IS_INTEGRAL (LTYPE (tree)))
3287 werror (E_UNARY_OP, tree->opval.op);
3288 goto errorTreeReturn;
3291 /* if left is a literal then do it */
3292 if (IS_LITERAL (LTYPE (tree)))
3294 tree->type = EX_VALUE;
3295 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3297 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3301 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3304 /*------------------------------------------------------------------*/
3305 /*----------------------------*/
3307 /*----------------------------*/
3309 /* can be pointer */
3310 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3311 !IS_PTR (LTYPE (tree)) &&
3312 !IS_ARRAY (LTYPE (tree)))
3314 werror (E_UNARY_OP, tree->opval.op);
3315 goto errorTreeReturn;
3318 /* if left is a literal then do it */
3319 if (IS_LITERAL (LTYPE (tree)))
3321 tree->type = EX_VALUE;
3322 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3324 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3328 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3331 /*------------------------------------------------------------------*/
3332 /*----------------------------*/
3334 /*----------------------------*/
3338 TTYPE (tree) = LTYPE (tree);
3339 TETYPE (tree) = LETYPE (tree);
3343 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3348 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3350 werror (E_SHIFT_OP_INVALID);
3351 werror (W_CONTINUE, "left & right types are ");
3352 printTypeChain (LTYPE (tree), stderr);
3353 fprintf (stderr, ",");
3354 printTypeChain (RTYPE (tree), stderr);
3355 fprintf (stderr, "\n");
3356 goto errorTreeReturn;
3359 /* if they are both literal then */
3360 /* rewrite the tree */
3361 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3363 tree->type = EX_VALUE;
3364 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3365 valFromType (RETYPE (tree)),
3366 (tree->opval.op == LEFT_OP ? 1 : 0));
3367 tree->right = tree->left = NULL;
3368 TETYPE (tree) = getSpec (TTYPE (tree) =
3369 tree->opval.val->type);
3373 LRVAL (tree) = RRVAL (tree) = 1;
3374 if (tree->opval.op == LEFT_OP)
3376 tree->left = addCast (tree->left, resultType, TRUE);
3377 TETYPE (tree) = getSpec (TTYPE (tree) =
3378 computeType (LTYPE (tree),
3380 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3384 /* no promotion necessary */
3385 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3386 if (IS_LITERAL (TTYPE (tree)))
3387 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3390 /* if only the right side is a literal & we are
3391 shifting more than size of the left operand then zero */
3392 if (IS_LITERAL (RTYPE (tree)) &&
3393 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3394 (getSize (TETYPE (tree)) * 8))
3396 if (tree->opval.op==LEFT_OP ||
3397 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3399 lineno=tree->lineno;
3400 werror (W_SHIFT_CHANGED,
3401 (tree->opval.op == LEFT_OP ? "left" : "right"));
3402 tree->type = EX_VALUE;
3403 tree->left = tree->right = NULL;
3404 tree->opval.val = constVal ("0");
3405 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3412 /*------------------------------------------------------------------*/
3413 /*----------------------------*/
3415 /*----------------------------*/
3416 case CAST: /* change the type */
3417 /* cannot cast to an aggregate type */
3418 if (IS_AGGREGATE (LTYPE (tree)))
3420 werror (E_CAST_ILLEGAL);
3421 goto errorTreeReturn;
3424 /* make sure the type is complete and sane */
3425 checkTypeSanity(LETYPE(tree), "(cast)");
3427 /* If code memory is read only, then pointers to code memory */
3428 /* implicitly point to constants -- make this explicit */
3430 sym_link *t = LTYPE(tree);
3431 while (t && t->next)
3433 if (IS_CODEPTR(t) && port->mem.code_ro)
3435 if (IS_SPEC(t->next))
3436 SPEC_CONST (t->next) = 1;
3438 DCL_PTR_CONST (t->next) = 1;
3445 /* if the right is a literal replace the tree */
3446 if (IS_LITERAL (RETYPE (tree))) {
3447 if (!IS_PTR (LTYPE (tree))) {
3448 tree->type = EX_VALUE;
3450 valCastLiteral (LTYPE (tree),
3451 floatFromVal (valFromType (RETYPE (tree))));
3454 TTYPE (tree) = tree->opval.val->type;
3455 tree->values.literalFromCast = 1;
3456 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3457 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3458 sym_link *rest = LTYPE(tree)->next;
3459 werror(W_LITERAL_GENERIC);
3460 TTYPE(tree) = newLink(DECLARATOR);
3461 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3462 TTYPE(tree)->next = rest;
3463 tree->left->opval.lnk = TTYPE(tree);
3466 TTYPE (tree) = LTYPE (tree);
3470 TTYPE (tree) = LTYPE (tree);
3474 #if 0 // this is already checked, now this could be explicit
3475 /* if pointer to struct then check names */
3476 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3477 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3478 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3480 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3481 SPEC_STRUCT(LETYPE(tree))->tag);
3484 if (IS_ADDRESS_OF_OP(tree->right)
3485 && IS_AST_SYM_VALUE (tree->right->left)
3486 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3488 tree->type = EX_VALUE;
3490 valCastLiteral (LTYPE (tree),
3491 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3492 TTYPE (tree) = tree->opval.val->type;
3493 TETYPE (tree) = getSpec (TTYPE (tree));
3496 tree->values.literalFromCast = 1;
3500 /* handle offsetof macro: */
3501 /* #define offsetof(TYPE, MEMBER) \ */
3502 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3503 if (IS_ADDRESS_OF_OP(tree->right)
3504 && IS_AST_OP (tree->right->left)
3505 && tree->right->left->opval.op == PTR_OP
3506 && IS_AST_OP (tree->right->left->left)
3507 && tree->right->left->left->opval.op == CAST
3508 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3510 symbol *element = getStructElement (
3511 SPEC_STRUCT (LETYPE(tree->right->left)),
3512 AST_SYMBOL(tree->right->left->right)
3516 tree->type = EX_VALUE;
3517 tree->opval.val = valCastLiteral (
3520 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3523 TTYPE (tree) = tree->opval.val->type;
3524 TETYPE (tree) = getSpec (TTYPE (tree));
3531 /* if the right is a literal replace the tree */
3532 if (IS_LITERAL (RETYPE (tree))) {
3534 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3535 /* rewrite (type *)litaddr
3537 and define type at litaddr temp
3538 (but only if type's storage class is not generic)
3540 ast *newTree = newNode ('&', NULL, NULL);
3543 TTYPE (newTree) = LTYPE (tree);
3544 TETYPE (newTree) = getSpec(LTYPE (tree));
3546 /* define a global symbol at the casted address*/
3547 sym = newSymbol(genSymName (0), 0);
3548 sym->type = LTYPE (tree)->next;
3550 sym->type = newLink (V_VOID);
3551 sym->etype = getSpec(sym->type);
3552 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3553 sym->lineDef = tree->lineno;
3556 SPEC_STAT (sym->etype) = 1;
3557 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3558 SPEC_ABSA(sym->etype) = 1;
3559 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3562 newTree->left = newAst_VALUE(symbolVal(sym));
3563 newTree->left->lineno = tree->lineno;
3564 LTYPE (newTree) = sym->type;
3565 LETYPE (newTree) = sym->etype;
3566 LLVAL (newTree) = 1;
3567 LRVAL (newTree) = 0;
3568 TLVAL (newTree) = 1;
3572 if (!IS_PTR (LTYPE (tree))) {
3573 tree->type = EX_VALUE;
3575 valCastLiteral (LTYPE (tree),
3576 floatFromVal (valFromType (RTYPE (tree))));
3577 TTYPE (tree) = tree->opval.val->type;
3580 tree->values.literalFromCast = 1;
3581 TETYPE (tree) = getSpec (TTYPE (tree));
3585 TTYPE (tree) = LTYPE (tree);
3589 TETYPE (tree) = getSpec (TTYPE (tree));
3593 /*------------------------------------------------------------------*/
3594 /*----------------------------*/
3595 /* logical &&, || */
3596 /*----------------------------*/
3599 /* each must me arithmetic type or be a pointer */
3600 if (!IS_PTR (LTYPE (tree)) &&
3601 !IS_ARRAY (LTYPE (tree)) &&
3602 !IS_INTEGRAL (LTYPE (tree)))
3604 werror (E_COMPARE_OP);
3605 goto errorTreeReturn;
3608 if (!IS_PTR (RTYPE (tree)) &&
3609 !IS_ARRAY (RTYPE (tree)) &&
3610 !IS_INTEGRAL (RTYPE (tree)))
3612 werror (E_COMPARE_OP);
3613 goto errorTreeReturn;
3615 /* if they are both literal then */
3616 /* rewrite the tree */
3617 if (IS_LITERAL (RTYPE (tree)) &&
3618 IS_LITERAL (LTYPE (tree)))
3620 tree->type = EX_VALUE;
3621 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3622 valFromType (RTYPE (tree)),
3624 tree->right = tree->left = NULL;
3625 TETYPE (tree) = getSpec (TTYPE (tree) =
3626 tree->opval.val->type);
3629 LRVAL (tree) = RRVAL (tree) = 1;
3630 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3633 /*------------------------------------------------------------------*/
3634 /*----------------------------*/
3635 /* comparison operators */
3636 /*----------------------------*/
3644 ast *lt = optimizeCompare (tree);
3650 /* if they are pointers they must be castable */
3651 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3653 if (tree->opval.op==EQ_OP &&
3654 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3655 // we cannot cast a gptr to a !gptr: switch the leaves
3656 struct ast *s=tree->left;
3657 tree->left=tree->right;
3660 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3662 werror (E_COMPARE_OP);
3663 fprintf (stderr, "comparing type ");
3664 printTypeChain (LTYPE (tree), stderr);
3665 fprintf (stderr, "to type ");
3666 printTypeChain (RTYPE (tree), stderr);
3667 fprintf (stderr, "\n");
3668 goto errorTreeReturn;
3671 /* else they should be promotable to one another */
3674 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3675 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3677 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3679 werror (E_COMPARE_OP);
3680 fprintf (stderr, "comparing type ");
3681 printTypeChain (LTYPE (tree), stderr);
3682 fprintf (stderr, "to type ");
3683 printTypeChain (RTYPE (tree), stderr);
3684 fprintf (stderr, "\n");
3685 goto errorTreeReturn;
3688 /* if unsigned value < 0 then always false */
3689 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3690 if (SPEC_USIGN(LETYPE(tree)) &&
3691 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3692 IS_LITERAL(RTYPE(tree)) &&
3693 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3695 if (tree->opval.op == '<')
3699 if (tree->opval.op == '>')
3701 if (resultType == RESULT_TYPE_IFX)
3703 /* the parent is an ifx: */
3704 /* if (unsigned value) */
3708 /* (unsigned value) ? 1 : 0 */
3709 tree->opval.op = '?';
3710 tree->right = newNode (':',
3711 newAst_VALUE (constVal ("1")),
3712 tree->right); /* val 0 */
3713 tree->right->lineno = tree->lineno;
3714 tree->right->left->lineno = tree->lineno;
3715 decorateType (tree->right, RESULT_CHECK);
3718 /* if they are both literal then */
3719 /* rewrite the tree */
3720 if (IS_LITERAL (RTYPE (tree)) &&
3721 IS_LITERAL (LTYPE (tree)))
3723 tree->type = EX_VALUE;
3724 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3725 valFromType (RETYPE (tree)),
3727 tree->right = tree->left = NULL;
3728 TETYPE (tree) = getSpec (TTYPE (tree) =
3729 tree->opval.val->type);
3732 LRVAL (tree) = RRVAL (tree) = 1;
3733 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3736 /*------------------------------------------------------------------*/
3737 /*----------------------------*/
3739 /*----------------------------*/
3740 case SIZEOF: /* evaluate wihout code generation */
3741 /* change the type to a integer */
3743 int size = getSize (tree->right->ftype);
3744 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3745 if (!size && !IS_VOID(tree->right->ftype))
3746 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3748 tree->type = EX_VALUE;
3749 tree->opval.val = constVal (buffer);
3750 tree->right = tree->left = NULL;
3751 TETYPE (tree) = getSpec (TTYPE (tree) =
3752 tree->opval.val->type);
3755 /*------------------------------------------------------------------*/
3756 /*----------------------------*/
3758 /*----------------------------*/
3760 /* return typeof enum value */
3761 tree->type = EX_VALUE;
3764 if (IS_SPEC(tree->right->ftype)) {
3765 switch (SPEC_NOUN(tree->right->ftype)) {
3767 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3768 else typeofv = TYPEOF_INT;
3771 typeofv = TYPEOF_FLOAT;
3774 typeofv = TYPEOF_CHAR;
3777 typeofv = TYPEOF_VOID;
3780 typeofv = TYPEOF_STRUCT;
3783 typeofv = TYPEOF_BITFIELD;
3786 typeofv = TYPEOF_BIT;
3789 typeofv = TYPEOF_SBIT;
3795 switch (DCL_TYPE(tree->right->ftype)) {
3797 typeofv = TYPEOF_POINTER;
3800 typeofv = TYPEOF_FPOINTER;
3803 typeofv = TYPEOF_CPOINTER;
3806 typeofv = TYPEOF_GPOINTER;
3809 typeofv = TYPEOF_PPOINTER;
3812 typeofv = TYPEOF_IPOINTER;
3815 typeofv = TYPEOF_ARRAY;
3818 typeofv = TYPEOF_FUNCTION;
3824 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3825 tree->opval.val = constVal (buffer);
3826 tree->right = tree->left = NULL;
3827 TETYPE (tree) = getSpec (TTYPE (tree) =
3828 tree->opval.val->type);
3831 /*------------------------------------------------------------------*/
3832 /*----------------------------*/
3833 /* conditional operator '?' */
3834 /*----------------------------*/
3836 /* the type is value of the colon operator (on the right) */
3837 assert (IS_COLON_OP (tree->right));
3838 /* if already known then replace the tree : optimizer will do it
3839 but faster to do it here */
3840 if (IS_LITERAL (LTYPE (tree)))
3842 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3843 return decorateType (tree->right->left, resultTypeProp);
3845 return decorateType (tree->right->right, resultTypeProp);
3849 tree->right = decorateType (tree->right, resultTypeProp);
3850 TTYPE (tree) = RTYPE (tree);
3851 TETYPE (tree) = getSpec (TTYPE (tree));
3856 /* if they don't match we have a problem */
3857 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3859 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3860 goto errorTreeReturn;
3863 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3864 TETYPE (tree) = getSpec (TTYPE (tree));
3868 #if 0 // assignment operators are converted by the parser
3869 /*------------------------------------------------------------------*/
3870 /*----------------------------*/
3871 /* assignment operators */
3872 /*----------------------------*/
3875 /* for these it must be both must be integral */
3876 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3877 !IS_ARITHMETIC (RTYPE (tree)))
3879 werror (E_OPS_INTEGRAL);
3880 goto errorTreeReturn;
3883 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3885 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3886 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3890 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3891 goto errorTreeReturn;
3902 /* for these it must be both must be integral */
3903 if (!IS_INTEGRAL (LTYPE (tree)) ||
3904 !IS_INTEGRAL (RTYPE (tree)))
3906 werror (E_OPS_INTEGRAL);
3907 goto errorTreeReturn;
3910 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3912 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3913 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3917 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3918 goto errorTreeReturn;
3924 /*------------------------------------------------------------------*/
3925 /*----------------------------*/
3927 /*----------------------------*/
3929 if (!(IS_PTR (LTYPE (tree)) ||
3930 IS_ARITHMETIC (LTYPE (tree))))
3932 werror (E_PLUS_INVALID, "-=");
3933 goto errorTreeReturn;
3936 if (!(IS_PTR (RTYPE (tree)) ||
3937 IS_ARITHMETIC (RTYPE (tree))))
3939 werror (E_PLUS_INVALID, "-=");
3940 goto errorTreeReturn;
3943 TETYPE (tree) = getSpec (TTYPE (tree) =
3944 computeType (LTYPE (tree),
3948 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3949 werror (E_CODE_WRITE, "-=");
3953 werror (E_LVALUE_REQUIRED, "-=");
3954 goto errorTreeReturn;
3960 /*------------------------------------------------------------------*/
3961 /*----------------------------*/
3963 /*----------------------------*/
3965 /* this is not a unary operation */
3966 /* if both pointers then problem */
3967 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3969 werror (E_PTR_PLUS_PTR);
3970 goto errorTreeReturn;
3973 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3975 werror (E_PLUS_INVALID, "+=");
3976 goto errorTreeReturn;
3979 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3981 werror (E_PLUS_INVALID, "+=");
3982 goto errorTreeReturn;
3985 TETYPE (tree) = getSpec (TTYPE (tree) =
3986 computeType (LTYPE (tree),
3990 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3991 werror (E_CODE_WRITE, "+=");
3995 werror (E_LVALUE_REQUIRED, "+=");
3996 goto errorTreeReturn;
3999 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
4000 tree->opval.op = '=';
4005 /*------------------------------------------------------------------*/
4006 /*----------------------------*/
4007 /* straight assignemnt */
4008 /*----------------------------*/
4010 /* cannot be an aggregate */
4011 if (IS_AGGREGATE (LTYPE (tree)))
4013 werror (E_AGGR_ASSIGN);
4014 goto errorTreeReturn;
4017 /* they should either match or be castable */
4018 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4020 werror (E_TYPE_MISMATCH, "assignment", " ");
4021 printFromToType(RTYPE(tree),LTYPE(tree));
4024 /* if the left side of the tree is of type void
4025 then report error */
4026 if (IS_VOID (LTYPE (tree)))
4028 werror (E_CAST_ZERO);
4029 printFromToType(RTYPE(tree), LTYPE(tree));
4032 TETYPE (tree) = getSpec (TTYPE (tree) =
4036 if (!tree->initMode ) {
4037 if (IS_CONSTANT(LTYPE(tree)))
4038 werror (E_CODE_WRITE, "=");
4042 werror (E_LVALUE_REQUIRED, "=");
4043 goto errorTreeReturn;
4048 /*------------------------------------------------------------------*/
4049 /*----------------------------*/
4050 /* comma operator */
4051 /*----------------------------*/
4053 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4056 /*------------------------------------------------------------------*/
4057 /*----------------------------*/
4059 /*----------------------------*/
4062 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4063 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4065 if (tree->left->opval.op == '*' && !tree->left->right)
4066 tree->left = tree->left->left;
4069 /* require a function or pointer to function */
4070 if (!IS_FUNC (LTYPE (tree))
4071 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4073 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4074 goto errorTreeReturn;
4081 if (IS_CODEPTR(LTYPE(tree)))
4082 functype = LTYPE (tree)->next;
4084 functype = LTYPE (tree);
4086 if (processParms (tree->left, FUNC_ARGS(functype),
4087 tree->right, &parmNumber, TRUE)) {
4088 goto errorTreeReturn;
4091 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4092 !IFFUNC_ISBUILTIN(functype))
4094 reverseParms (tree->right);
4097 TTYPE (tree) = functype->next;
4098 TETYPE (tree) = getSpec (TTYPE (tree));
4102 /*------------------------------------------------------------------*/
4103 /*----------------------------*/
4104 /* return statement */
4105 /*----------------------------*/
4110 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4112 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4113 printFromToType (RTYPE(tree), currFunc->type->next);
4114 goto errorTreeReturn;
4117 if (IS_VOID (currFunc->type->next)
4119 !IS_VOID (RTYPE (tree)))
4121 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4122 goto errorTreeReturn;
4125 /* if there is going to be a casting required then add it */
4126 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4129 decorateType (newNode (CAST,
4130 newAst_LINK (copyLinkChain (currFunc->type->next)),
4140 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4142 werror (W_VOID_FUNC, currFunc->name);
4143 goto errorTreeReturn;
4146 TTYPE (tree) = TETYPE (tree) = NULL;
4149 /*------------------------------------------------------------------*/
4150 /*----------------------------*/
4151 /* switch statement */
4152 /*----------------------------*/
4154 /* the switch value must be an integer */
4155 if (!IS_INTEGRAL (LTYPE (tree)))
4157 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4158 goto errorTreeReturn;
4161 TTYPE (tree) = TETYPE (tree) = NULL;
4164 /*------------------------------------------------------------------*/
4165 /*----------------------------*/
4167 /*----------------------------*/
4169 tree->left = backPatchLabels (tree->left,
4172 TTYPE (tree) = TETYPE (tree) = NULL;
4175 /*------------------------------------------------------------------*/
4176 /*----------------------------*/
4178 /*----------------------------*/
4181 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4182 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4183 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4185 /* if the for loop is reversible then
4186 reverse it otherwise do what we normally
4192 if (isLoopReversible (tree, &sym, &init, &end))
4193 return reverseLoop (tree, sym, init, end);
4195 return decorateType (createFor (AST_FOR (tree, trueLabel),
4196 AST_FOR (tree, continueLabel),
4197 AST_FOR (tree, falseLabel),
4198 AST_FOR (tree, condLabel),
4199 AST_FOR (tree, initExpr),
4200 AST_FOR (tree, condExpr),
4201 AST_FOR (tree, loopExpr),
4202 tree->left), RESULT_CHECK);
4205 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4206 "node PARAM shouldn't be processed here");
4207 /* but in processParams() */
4210 TTYPE (tree) = TETYPE (tree) = NULL;
4214 /* some error found this tree will be killed */
4216 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4217 tree->opval.op = NULLOP;
4223 /*-----------------------------------------------------------------*/
4224 /* sizeofOp - processes size of operation */
4225 /*-----------------------------------------------------------------*/
4227 sizeofOp (sym_link * type)
4232 /* make sure the type is complete and sane */
4233 checkTypeSanity(type, "(sizeof)");
4235 /* get the size and convert it to character */
4236 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4237 if (!size && !IS_VOID(type))
4238 werror (E_SIZEOF_INCOMPLETE_TYPE);
4240 /* now convert into value */
4241 return constVal (buff);
4245 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4246 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4247 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4248 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4249 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4250 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4251 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4253 /*-----------------------------------------------------------------*/
4254 /* backPatchLabels - change and or not operators to flow control */
4255 /*-----------------------------------------------------------------*/
4257 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4263 if (!(IS_ANDORNOT (tree)))
4266 /* if this an and */
4269 static int localLbl = 0;
4272 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4273 localLabel = newSymbol (buffer, NestLevel);
4275 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4277 /* if left is already a IFX then just change the if true label in that */
4278 if (!IS_IFX (tree->left))
4279 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4281 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4282 /* right is a IFX then just join */
4283 if (IS_IFX (tree->right))
4284 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4286 tree->right = createLabel (localLabel, tree->right);
4287 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4289 return newNode (NULLOP, tree->left, tree->right);
4292 /* if this is an or operation */
4295 static int localLbl = 0;
4298 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4299 localLabel = newSymbol (buffer, NestLevel);
4301 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4303 /* if left is already a IFX then just change the if true label in that */
4304 if (!IS_IFX (tree->left))
4305 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4307 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4308 /* right is a IFX then just join */
4309 if (IS_IFX (tree->right))
4310 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4312 tree->right = createLabel (localLabel, tree->right);
4313 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4315 return newNode (NULLOP, tree->left, tree->right);
4321 int wasnot = IS_NOT (tree->left);
4322 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4324 /* if the left is already a IFX */
4325 if (!IS_IFX (tree->left))
4326 tree->left = newNode (IFX, tree->left, NULL);
4330 tree->left->trueLabel = trueLabel;
4331 tree->left->falseLabel = falseLabel;
4335 tree->left->trueLabel = falseLabel;
4336 tree->left->falseLabel = trueLabel;
4343 tree->trueLabel = trueLabel;
4344 tree->falseLabel = falseLabel;
4351 /*-----------------------------------------------------------------*/
4352 /* createBlock - create expression tree for block */
4353 /*-----------------------------------------------------------------*/
4355 createBlock (symbol * decl, ast * body)
4359 /* if the block has nothing */
4363 ex = newNode (BLOCK, NULL, body);
4364 ex->values.sym = decl;
4366 ex->right = ex->right;
4372 /*-----------------------------------------------------------------*/
4373 /* createLabel - creates the expression tree for labels */
4374 /*-----------------------------------------------------------------*/
4376 createLabel (symbol * label, ast * stmnt)
4379 char name[SDCC_NAME_MAX + 1];
4382 /* must create fresh symbol if the symbol name */
4383 /* exists in the symbol table, since there can */
4384 /* be a variable with the same name as the labl */
4385 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4386 (csym->level == label->level))
4387 label = newSymbol (label->name, label->level);
4389 /* change the name before putting it in add _ */
4390 SNPRINTF(name, sizeof(name), "%s", label->name);
4392 /* put the label in the LabelSymbol table */
4393 /* but first check if a label of the same */
4395 if ((csym = findSym (LabelTab, NULL, name)))
4396 werror (E_DUPLICATE_LABEL, label->name);
4398 addSym (LabelTab, label, name, label->level, 0, 0);
4401 label->key = labelKey++;
4402 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4408 /*-----------------------------------------------------------------*/
4409 /* createCase - generates the parsetree for a case statement */
4410 /*-----------------------------------------------------------------*/
4412 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4414 char caseLbl[SDCC_NAME_MAX + 1];
4418 /* if the switch statement does not exist */
4419 /* then case is out of context */
4422 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4426 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4427 /* if not a constant then error */
4428 if (!IS_LITERAL (caseVal->ftype))
4430 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4434 /* if not a integer than error */
4435 if (!IS_INTEGRAL (caseVal->ftype))
4437 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4441 /* find the end of the switch values chain */
4442 if (!(val = swStat->values.switchVals.swVals))
4443 swStat->values.switchVals.swVals = caseVal->opval.val;
4446 /* also order the cases according to value */
4448 int cVal = (int) floatFromVal (caseVal->opval.val);
4449 while (val && (int) floatFromVal (val) < cVal)
4455 /* if we reached the end then */
4458 pval->next = caseVal->opval.val;
4460 else if ((int) floatFromVal (val) == cVal)
4462 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4468 /* we found a value greater than */
4469 /* the current value we must add this */
4470 /* before the value */
4471 caseVal->opval.val->next = val;
4473 /* if this was the first in chain */
4474 if (swStat->values.switchVals.swVals == val)
4475 swStat->values.switchVals.swVals =
4478 pval->next = caseVal->opval.val;
4483 /* create the case label */
4484 SNPRINTF(caseLbl, sizeof(caseLbl),
4486 swStat->values.switchVals.swNum,
4487 (int) floatFromVal (caseVal->opval.val));
4489 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4494 /*-----------------------------------------------------------------*/
4495 /* createDefault - creates the parse tree for the default statement */
4496 /*-----------------------------------------------------------------*/
4498 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4500 char defLbl[SDCC_NAME_MAX + 1];
4502 /* if the switch statement does not exist */
4503 /* then case is out of context */
4506 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4510 if (swStat->values.switchVals.swDefault)
4512 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4517 /* turn on the default flag */
4518 swStat->values.switchVals.swDefault = 1;
4520 /* create the label */
4521 SNPRINTF (defLbl, sizeof(defLbl),
4522 "_default_%d", swStat->values.switchVals.swNum);
4523 return createLabel (newSymbol (defLbl, 0), stmnt);
4526 /*-----------------------------------------------------------------*/
4527 /* createIf - creates the parsetree for the if statement */
4528 /*-----------------------------------------------------------------*/
4530 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4532 static int Lblnum = 0;
4534 symbol *ifTrue, *ifFalse, *ifEnd;
4536 /* if neither exists */
4537 if (!elseBody && !ifBody) {
4538 // if there are no side effects (i++, j() etc)
4539 if (!hasSEFcalls(condAst)) {
4544 /* create the labels */
4545 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4546 ifFalse = newSymbol (buffer, NestLevel);
4547 /* if no else body then end == false */
4552 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4553 ifEnd = newSymbol (buffer, NestLevel);
4556 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4557 ifTrue = newSymbol (buffer, NestLevel);
4561 /* attach the ifTrue label to the top of it body */
4562 ifBody = createLabel (ifTrue, ifBody);
4563 /* attach a goto end to the ifBody if else is present */
4566 ifBody = newNode (NULLOP, ifBody,
4568 newAst_VALUE (symbolVal (ifEnd)),
4570 /* put the elseLabel on the else body */
4571 elseBody = createLabel (ifFalse, elseBody);
4572 /* out the end at the end of the body */
4573 elseBody = newNode (NULLOP,
4575 createLabel (ifEnd, NULL));
4579 ifBody = newNode (NULLOP, ifBody,
4580 createLabel (ifFalse, NULL));
4582 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4583 if (IS_IFX (condAst))
4586 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4588 return newNode (NULLOP, ifTree,
4589 newNode (NULLOP, ifBody, elseBody));
4593 /*-----------------------------------------------------------------*/
4594 /* createDo - creates parse tree for do */
4597 /* _docontinue_n: */
4598 /* condition_expression +-> trueLabel -> _dobody_n */
4600 /* +-> falseLabel-> _dobreak_n */
4602 /*-----------------------------------------------------------------*/
4604 createDo (symbol * trueLabel, symbol * continueLabel,
4605 symbol * falseLabel, ast * condAst, ast * doBody)
4610 /* if the body does not exist then it is simple */
4613 condAst = backPatchLabels (condAst, continueLabel, NULL);
4614 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4615 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4616 doTree->trueLabel = continueLabel;
4617 doTree->falseLabel = NULL;
4621 /* otherwise we have a body */
4622 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4624 /* attach the body label to the top */
4625 doBody = createLabel (trueLabel, doBody);
4626 /* attach the continue label to end of body */
4627 doBody = newNode (NULLOP, doBody,
4628 createLabel (continueLabel, NULL));
4630 /* now put the break label at the end */
4631 if (IS_IFX (condAst))
4634 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4636 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4638 /* putting it together */
4639 return newNode (NULLOP, doBody, doTree);
4642 /*-----------------------------------------------------------------*/
4643 /* createFor - creates parse tree for 'for' statement */
4646 /* condExpr +-> trueLabel -> _forbody_n */
4648 /* +-> falseLabel-> _forbreak_n */
4651 /* _forcontinue_n: */
4653 /* goto _forcond_n ; */
4655 /*-----------------------------------------------------------------*/
4657 createFor (symbol * trueLabel, symbol * continueLabel,
4658 symbol * falseLabel, symbol * condLabel,
4659 ast * initExpr, ast * condExpr, ast * loopExpr,
4664 /* if loopexpression not present then we can generate it */
4665 /* the same way as a while */
4667 return newNode (NULLOP, initExpr,
4668 createWhile (trueLabel, continueLabel,
4669 falseLabel, condExpr, forBody));
4670 /* vanilla for statement */
4671 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4673 if (condExpr && !IS_IFX (condExpr))
4674 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4677 /* attach condition label to condition */
4678 condExpr = createLabel (condLabel, condExpr);
4680 /* attach body label to body */
4681 forBody = createLabel (trueLabel, forBody);
4683 /* attach continue to forLoop expression & attach */
4684 /* goto the forcond @ and of loopExpression */
4685 loopExpr = createLabel (continueLabel,
4689 newAst_VALUE (symbolVal (condLabel)),
4691 /* now start putting them together */
4692 forTree = newNode (NULLOP, initExpr, condExpr);
4693 forTree = newNode (NULLOP, forTree, forBody);
4694 forTree = newNode (NULLOP, forTree, loopExpr);
4695 /* finally add the break label */
4696 forTree = newNode (NULLOP, forTree,
4697 createLabel (falseLabel, NULL));
4701 /*-----------------------------------------------------------------*/
4702 /* createWhile - creates parse tree for while statement */
4703 /* the while statement will be created as follows */
4705 /* _while_continue_n: */
4706 /* condition_expression +-> trueLabel -> _while_boby_n */
4708 /* +-> falseLabel -> _while_break_n */
4709 /* _while_body_n: */
4711 /* goto _while_continue_n */
4712 /* _while_break_n: */
4713 /*-----------------------------------------------------------------*/
4715 createWhile (symbol * trueLabel, symbol * continueLabel,
4716 symbol * falseLabel, ast * condExpr, ast * whileBody)
4720 /* put the continue label */
4721 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4722 condExpr = createLabel (continueLabel, condExpr);
4723 condExpr->lineno = 0;
4725 /* put the body label in front of the body */
4726 whileBody = createLabel (trueLabel, whileBody);
4727 whileBody->lineno = 0;
4728 /* put a jump to continue at the end of the body */
4729 /* and put break label at the end of the body */
4730 whileBody = newNode (NULLOP,
4733 newAst_VALUE (symbolVal (continueLabel)),
4734 createLabel (falseLabel, NULL)));
4736 /* put it all together */
4737 if (IS_IFX (condExpr))
4738 whileTree = condExpr;
4741 whileTree = newNode (IFX, condExpr, NULL);
4742 /* put the true & false labels in place */
4743 whileTree->trueLabel = trueLabel;
4744 whileTree->falseLabel = falseLabel;
4747 return newNode (NULLOP, whileTree, whileBody);
4750 /*-----------------------------------------------------------------*/
4751 /* optimizeGetHbit - get highest order bit of the expression */
4752 /*-----------------------------------------------------------------*/
4754 optimizeGetHbit (ast * tree)
4757 /* if this is not a bit and */
4758 if (!IS_BITAND (tree))
4761 /* will look for tree of the form
4762 ( expr >> ((sizeof expr) -1) ) & 1 */
4763 if (!IS_AST_LIT_VALUE (tree->right))
4766 if (AST_LIT_VALUE (tree->right) != 1)
4769 if (!IS_RIGHT_OP (tree->left))
4772 if (!IS_AST_LIT_VALUE (tree->left->right))
4775 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4776 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4779 /* make sure the port supports GETHBIT */
4780 if (port->hasExtBitOp
4781 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4784 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4788 /*-----------------------------------------------------------------*/
4789 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4790 /*-----------------------------------------------------------------*/
4792 optimizeRRCRLC (ast * root)
4794 /* will look for trees of the form
4795 (?expr << 1) | (?expr >> 7) or
4796 (?expr >> 7) | (?expr << 1) will make that
4797 into a RLC : operation ..
4799 (?expr >> 1) | (?expr << 7) or
4800 (?expr << 7) | (?expr >> 1) will make that
4801 into a RRC operation
4802 note : by 7 I mean (number of bits required to hold the
4804 /* if the root operations is not a | operation the not */
4805 if (!IS_BITOR (root))
4808 /* I have to think of a better way to match patterns this sucks */
4809 /* that aside let start looking for the first case : I use a the
4810 negative check a lot to improve the efficiency */
4811 /* (?expr << 1) | (?expr >> 7) */
4812 if (IS_LEFT_OP (root->left) &&
4813 IS_RIGHT_OP (root->right))
4816 if (!SPEC_USIGN (TETYPE (root->left->left)))
4819 if (!IS_AST_LIT_VALUE (root->left->right) ||
4820 !IS_AST_LIT_VALUE (root->right->right))
4823 /* make sure it is the same expression */
4824 if (!isAstEqual (root->left->left,
4828 if (AST_LIT_VALUE (root->left->right) != 1)
4831 if (AST_LIT_VALUE (root->right->right) !=
4832 (getSize (TTYPE (root->left->left)) * 8 - 1))
4835 /* make sure the port supports RLC */
4836 if (port->hasExtBitOp
4837 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4840 /* whew got the first case : create the AST */
4841 return newNode (RLC, root->left->left, NULL);
4845 /* check for second case */
4846 /* (?expr >> 7) | (?expr << 1) */
4847 if (IS_LEFT_OP (root->right) &&
4848 IS_RIGHT_OP (root->left))
4851 if (!SPEC_USIGN (TETYPE (root->left->left)))
4854 if (!IS_AST_LIT_VALUE (root->left->right) ||
4855 !IS_AST_LIT_VALUE (root->right->right))
4858 /* make sure it is the same symbol */
4859 if (!isAstEqual (root->left->left,
4863 if (AST_LIT_VALUE (root->right->right) != 1)
4866 if (AST_LIT_VALUE (root->left->right) !=
4867 (getSize (TTYPE (root->left->left)) * 8 - 1))
4870 /* make sure the port supports RLC */
4871 if (port->hasExtBitOp
4872 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4875 /* whew got the first case : create the AST */
4876 return newNode (RLC, root->left->left, NULL);
4881 /* third case for RRC */
4882 /* (?symbol >> 1) | (?symbol << 7) */
4883 if (IS_LEFT_OP (root->right) &&
4884 IS_RIGHT_OP (root->left))
4887 if (!SPEC_USIGN (TETYPE (root->left->left)))
4890 if (!IS_AST_LIT_VALUE (root->left->right) ||
4891 !IS_AST_LIT_VALUE (root->right->right))
4894 /* make sure it is the same symbol */
4895 if (!isAstEqual (root->left->left,
4899 if (AST_LIT_VALUE (root->left->right) != 1)
4902 if (AST_LIT_VALUE (root->right->right) !=
4903 (getSize (TTYPE (root->left->left)) * 8 - 1))
4906 /* make sure the port supports RRC */
4907 if (port->hasExtBitOp
4908 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4911 /* whew got the first case : create the AST */
4912 return newNode (RRC, root->left->left, NULL);
4916 /* fourth and last case for now */
4917 /* (?symbol << 7) | (?symbol >> 1) */
4918 if (IS_RIGHT_OP (root->right) &&
4919 IS_LEFT_OP (root->left))
4922 if (!SPEC_USIGN (TETYPE (root->left->left)))
4925 if (!IS_AST_LIT_VALUE (root->left->right) ||
4926 !IS_AST_LIT_VALUE (root->right->right))
4929 /* make sure it is the same symbol */
4930 if (!isAstEqual (root->left->left,
4934 if (AST_LIT_VALUE (root->right->right) != 1)
4937 if (AST_LIT_VALUE (root->left->right) !=
4938 (getSize (TTYPE (root->left->left)) * 8 - 1))
4941 /* make sure the port supports RRC */
4942 if (port->hasExtBitOp
4943 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4946 /* whew got the first case : create the AST */
4947 return newNode (RRC, root->left->left, NULL);
4951 /* not found return root */
4955 /*-----------------------------------------------------------------*/
4956 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4957 /*-----------------------------------------------------------------*/
4959 optimizeSWAP (ast * root)
4961 /* will look for trees of the form
4962 (?expr << 4) | (?expr >> 4) or
4963 (?expr >> 4) | (?expr << 4) will make that
4964 into a SWAP : operation ..
4965 note : by 4 I mean (number of bits required to hold the
4967 /* if the root operations is not a | operation the not */
4968 if (!IS_BITOR (root))
4971 /* (?expr << 4) | (?expr >> 4) */
4972 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4973 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4976 if (!SPEC_USIGN (TETYPE (root->left->left)))
4979 if (!IS_AST_LIT_VALUE (root->left->right) ||
4980 !IS_AST_LIT_VALUE (root->right->right))
4983 /* make sure it is the same expression */
4984 if (!isAstEqual (root->left->left,
4988 if (AST_LIT_VALUE (root->left->right) !=
4989 (getSize (TTYPE (root->left->left)) * 4))
4992 if (AST_LIT_VALUE (root->right->right) !=
4993 (getSize (TTYPE (root->left->left)) * 4))
4996 /* make sure the port supports SWAP */
4997 if (port->hasExtBitOp
4998 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5001 /* found it : create the AST */
5002 return newNode (SWAP, root->left->left, NULL);
5006 /* not found return root */
5010 /*-----------------------------------------------------------------*/
5011 /* optimizeCompare - otimizes compares for bit variables */
5012 /*-----------------------------------------------------------------*/
5014 optimizeCompare (ast * root)
5016 ast *optExpr = NULL;
5019 unsigned int litValue;
5021 /* if nothing then return nothing */
5025 /* if not a compare op then do leaves */
5026 if (!IS_COMPARE_OP (root))
5028 root->left = optimizeCompare (root->left);
5029 root->right = optimizeCompare (root->right);
5033 /* if left & right are the same then depending
5034 of the operation do */
5035 if (isAstEqual (root->left, root->right))
5037 switch (root->opval.op)
5042 optExpr = newAst_VALUE (constVal ("0"));
5047 optExpr = newAst_VALUE (constVal ("1"));
5051 return decorateType (optExpr, RESULT_CHECK);
5054 vleft = (root->left->type == EX_VALUE ?
5055 root->left->opval.val : NULL);
5057 vright = (root->right->type == EX_VALUE ?
5058 root->right->opval.val : NULL);
5060 /* if left is a BITVAR in BITSPACE */
5061 /* and right is a LITERAL then opt- */
5062 /* imize else do nothing */
5063 if (vleft && vright &&
5064 IS_BITVAR (vleft->etype) &&
5065 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5066 IS_LITERAL (vright->etype))
5069 /* if right side > 1 then comparison may never succeed */
5070 if ((litValue = (int) floatFromVal (vright)) > 1)
5072 werror (W_BAD_COMPARE);
5078 switch (root->opval.op)
5080 case '>': /* bit value greater than 1 cannot be */
5081 werror (W_BAD_COMPARE);
5085 case '<': /* bit value < 1 means 0 */
5087 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5090 case LE_OP: /* bit value <= 1 means no check */
5091 optExpr = newAst_VALUE (vright);
5094 case GE_OP: /* bit value >= 1 means only check for = */
5096 optExpr = newAst_VALUE (vleft);
5101 { /* literal is zero */
5102 switch (root->opval.op)
5104 case '<': /* bit value < 0 cannot be */
5105 werror (W_BAD_COMPARE);
5109 case '>': /* bit value > 0 means 1 */
5111 optExpr = newAst_VALUE (vleft);
5114 case LE_OP: /* bit value <= 0 means no check */
5115 case GE_OP: /* bit value >= 0 means no check */
5116 werror (W_BAD_COMPARE);
5120 case EQ_OP: /* bit == 0 means ! of bit */
5121 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5125 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5126 } /* end-of-if of BITVAR */
5131 /*-----------------------------------------------------------------*/
5132 /* addSymToBlock : adds the symbol to the first block we find */
5133 /*-----------------------------------------------------------------*/
5135 addSymToBlock (symbol * sym, ast * tree)
5137 /* reached end of tree or a leaf */
5138 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5142 if (IS_AST_OP (tree) &&
5143 tree->opval.op == BLOCK)
5146 symbol *lsym = copySymbol (sym);
5148 lsym->next = AST_VALUES (tree, sym);
5149 AST_VALUES (tree, sym) = lsym;
5153 addSymToBlock (sym, tree->left);
5154 addSymToBlock (sym, tree->right);
5157 /*-----------------------------------------------------------------*/
5158 /* processRegParms - do processing for register parameters */
5159 /*-----------------------------------------------------------------*/
5161 processRegParms (value * args, ast * body)
5165 if (IS_REGPARM (args->etype))
5166 addSymToBlock (args->sym, body);
5171 /*-----------------------------------------------------------------*/
5172 /* resetParmKey - resets the operandkeys for the symbols */
5173 /*-----------------------------------------------------------------*/
5174 DEFSETFUNC (resetParmKey)
5185 /*-----------------------------------------------------------------*/
5186 /* createFunction - This is the key node that calls the iCode for */
5187 /* generating the code for a function. Note code */
5188 /* is generated function by function, later when */
5189 /* add inter-procedural analysis this will change */
5190 /*-----------------------------------------------------------------*/
5192 createFunction (symbol * name, ast * body)
5198 iCode *piCode = NULL;
5200 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5201 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5203 /* if check function return 0 then some problem */
5204 if (checkFunction (name, NULL) == 0)
5207 /* create a dummy block if none exists */
5209 body = newNode (BLOCK, NULL, NULL);
5213 /* check if the function name already in the symbol table */
5214 if ((csym = findSym (SymbolTab, NULL, name->name)))
5217 /* special case for compiler defined functions
5218 we need to add the name to the publics list : this
5219 actually means we are now compiling the compiler
5223 addSet (&publics, name);
5229 allocVariables (name);
5231 name->lastLine = mylineno;
5234 /* set the stack pointer */
5235 /* PENDING: check this for the mcs51 */
5236 stackPtr = -port->stack.direction * port->stack.call_overhead;
5237 if (IFFUNC_ISISR (name->type))
5238 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5239 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5240 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5242 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5244 fetype = getSpec (name->type); /* get the specifier for the function */
5245 /* if this is a reentrant function then */
5246 if (IFFUNC_ISREENT (name->type))
5249 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5251 /* do processing for parameters that are passed in registers */
5252 processRegParms (FUNC_ARGS(name->type), body);
5254 /* set the stack pointer */
5258 /* allocate & autoinit the block variables */
5259 processBlockVars (body, &stack, ALLOCATE);
5261 /* save the stack information */
5262 if (options.useXstack)
5263 name->xstack = SPEC_STAK (fetype) = stack;
5265 name->stack = SPEC_STAK (fetype) = stack;
5267 /* name needs to be mangled */
5268 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5270 body = resolveSymbols (body); /* resolve the symbols */
5271 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5274 ex = newAst_VALUE (symbolVal (name)); /* create name */
5275 ex = newNode (FUNCTION, ex, body);
5276 ex->values.args = FUNC_ARGS(name->type);
5278 if (options.dump_tree) PA(ex);
5281 werror (E_FUNC_NO_CODE, name->name);
5285 /* create the node & generate intermediate code */
5287 codeOutFile = code->oFile;
5288 piCode = iCodeFromAst (ex);
5292 werror (E_FUNC_NO_CODE, name->name);
5296 eBBlockFromiCode (piCode);
5298 /* if there are any statics then do them */
5301 GcurMemmap = statsg;
5302 codeOutFile = statsg->oFile;
5303 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5309 /* dealloc the block variables */
5310 processBlockVars (body, &stack, DEALLOCATE);
5311 outputDebugStackSymbols();
5312 /* deallocate paramaters */
5313 deallocParms (FUNC_ARGS(name->type));
5315 if (IFFUNC_ISREENT (name->type))
5318 /* we are done freeup memory & cleanup */
5320 if (port->reset_labelKey) labelKey = 1;
5322 FUNC_HASBODY(name->type) = 1;
5323 addSet (&operKeyReset, name);
5324 applyToSet (operKeyReset, resetParmKey);
5329 cleanUpLevel (LabelTab, 0);
5330 cleanUpBlock (StructTab, 1);
5331 cleanUpBlock (TypedefTab, 1);
5333 xstack->syms = NULL;
5334 istack->syms = NULL;
5339 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5340 /*-----------------------------------------------------------------*/
5341 /* ast_print : prints the ast (for debugging purposes) */
5342 /*-----------------------------------------------------------------*/
5344 void ast_print (ast * tree, FILE *outfile, int indent)
5349 /* can print only decorated trees */
5350 if (!tree->decorated) return;
5352 /* if any child is an error | this one is an error do nothing */
5353 if (tree->isError ||
5354 (tree->left && tree->left->isError) ||
5355 (tree->right && tree->right->isError)) {
5356 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5360 /* print the line */
5361 /* if not block & function */
5362 if (tree->type == EX_OP &&
5363 (tree->opval.op != FUNCTION &&
5364 tree->opval.op != BLOCK &&
5365 tree->opval.op != NULLOP)) {
5368 if (tree->opval.op == FUNCTION) {
5370 value *args=FUNC_ARGS(tree->left->opval.val->type);
5371 fprintf(outfile,"FUNCTION (%s=%p) type (",
5372 tree->left->opval.val->name, tree);
5373 printTypeChain (tree->left->opval.val->type->next,outfile);
5374 fprintf(outfile,") args (");
5377 fprintf (outfile, ", ");
5379 printTypeChain (args ? args->type : NULL, outfile);
5381 args= args ? args->next : NULL;
5383 fprintf(outfile,")\n");
5384 ast_print(tree->left,outfile,indent);
5385 ast_print(tree->right,outfile,indent);
5388 if (tree->opval.op == BLOCK) {
5389 symbol *decls = tree->values.sym;
5390 INDENT(indent,outfile);
5391 fprintf(outfile,"{\n");
5393 INDENT(indent+2,outfile);
5394 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5395 decls->name, decls);
5396 printTypeChain(decls->type,outfile);
5397 fprintf(outfile,")\n");
5399 decls = decls->next;
5401 ast_print(tree->right,outfile,indent+2);
5402 INDENT(indent,outfile);
5403 fprintf(outfile,"}\n");
5406 if (tree->opval.op == NULLOP) {
5407 ast_print(tree->left,outfile,indent);
5408 ast_print(tree->right,outfile,indent);
5411 INDENT(indent,outfile);
5413 /*------------------------------------------------------------------*/
5414 /*----------------------------*/
5415 /* leaf has been reached */
5416 /*----------------------------*/
5417 /* if this is of type value */
5418 /* just get the type */
5419 if (tree->type == EX_VALUE) {
5421 if (IS_LITERAL (tree->opval.val->etype)) {
5422 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5423 if (SPEC_USIGN (tree->opval.val->etype))
5424 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5426 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5427 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5428 floatFromVal(tree->opval.val));
5429 } else if (tree->opval.val->sym) {
5430 /* if the undefined flag is set then give error message */
5431 if (tree->opval.val->sym->undefined) {
5432 fprintf(outfile,"UNDEFINED SYMBOL ");
5434 fprintf(outfile,"SYMBOL ");
5436 fprintf(outfile,"(%s=%p)",
5437 tree->opval.val->sym->name,tree);
5440 fprintf(outfile," type (");
5441 printTypeChain(tree->ftype,outfile);
5442 fprintf(outfile,")\n");
5444 fprintf(outfile,"\n");
5449 /* if type link for the case of cast */
5450 if (tree->type == EX_LINK) {
5451 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5452 printTypeChain(tree->opval.lnk,outfile);
5453 fprintf(outfile,")\n");
5458 /* depending on type of operator do */
5460 switch (tree->opval.op) {
5461 /*------------------------------------------------------------------*/
5462 /*----------------------------*/
5464 /*----------------------------*/
5466 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5467 printTypeChain(tree->ftype,outfile);
5468 fprintf(outfile,")\n");
5469 ast_print(tree->left,outfile,indent+2);
5470 ast_print(tree->right,outfile,indent+2);
5473 /*------------------------------------------------------------------*/
5474 /*----------------------------*/
5476 /*----------------------------*/
5478 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5479 printTypeChain(tree->ftype,outfile);
5480 fprintf(outfile,")\n");
5481 ast_print(tree->left,outfile,indent+2);
5482 ast_print(tree->right,outfile,indent+2);
5485 /*------------------------------------------------------------------*/
5486 /*----------------------------*/
5487 /* struct/union pointer */
5488 /*----------------------------*/
5490 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5491 printTypeChain(tree->ftype,outfile);
5492 fprintf(outfile,")\n");
5493 ast_print(tree->left,outfile,indent+2);
5494 ast_print(tree->right,outfile,indent+2);
5497 /*------------------------------------------------------------------*/
5498 /*----------------------------*/
5499 /* ++/-- operation */
5500 /*----------------------------*/
5503 fprintf(outfile,"post-");
5505 fprintf(outfile,"pre-");
5506 fprintf(outfile,"INC_OP (%p) type (",tree);
5507 printTypeChain(tree->ftype,outfile);
5508 fprintf(outfile,")\n");
5509 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5510 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5515 fprintf(outfile,"post-");
5517 fprintf(outfile,"pre-");
5518 fprintf(outfile,"DEC_OP (%p) type (",tree);
5519 printTypeChain(tree->ftype,outfile);
5520 fprintf(outfile,")\n");
5521 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5522 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5525 /*------------------------------------------------------------------*/
5526 /*----------------------------*/
5528 /*----------------------------*/
5531 fprintf(outfile,"& (%p) type (",tree);
5532 printTypeChain(tree->ftype,outfile);
5533 fprintf(outfile,")\n");
5534 ast_print(tree->left,outfile,indent+2);
5535 ast_print(tree->right,outfile,indent+2);
5537 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5538 printTypeChain(tree->ftype,outfile);
5539 fprintf(outfile,")\n");
5540 ast_print(tree->left,outfile,indent+2);
5541 ast_print(tree->right,outfile,indent+2);
5544 /*----------------------------*/
5546 /*----------------------------*/
5548 fprintf(outfile,"OR (%p) type (",tree);
5549 printTypeChain(tree->ftype,outfile);
5550 fprintf(outfile,")\n");
5551 ast_print(tree->left,outfile,indent+2);
5552 ast_print(tree->right,outfile,indent+2);
5554 /*------------------------------------------------------------------*/
5555 /*----------------------------*/
5557 /*----------------------------*/
5559 fprintf(outfile,"XOR (%p) type (",tree);
5560 printTypeChain(tree->ftype,outfile);
5561 fprintf(outfile,")\n");
5562 ast_print(tree->left,outfile,indent+2);
5563 ast_print(tree->right,outfile,indent+2);
5566 /*------------------------------------------------------------------*/
5567 /*----------------------------*/
5569 /*----------------------------*/
5571 fprintf(outfile,"DIV (%p) type (",tree);
5572 printTypeChain(tree->ftype,outfile);
5573 fprintf(outfile,")\n");
5574 ast_print(tree->left,outfile,indent+2);
5575 ast_print(tree->right,outfile,indent+2);
5577 /*------------------------------------------------------------------*/
5578 /*----------------------------*/
5580 /*----------------------------*/
5582 fprintf(outfile,"MOD (%p) type (",tree);
5583 printTypeChain(tree->ftype,outfile);
5584 fprintf(outfile,")\n");
5585 ast_print(tree->left,outfile,indent+2);
5586 ast_print(tree->right,outfile,indent+2);
5589 /*------------------------------------------------------------------*/
5590 /*----------------------------*/
5591 /* address dereference */
5592 /*----------------------------*/
5593 case '*': /* can be unary : if right is null then unary operation */
5595 fprintf(outfile,"DEREF (%p) type (",tree);
5596 printTypeChain(tree->ftype,outfile);
5597 fprintf(outfile,")\n");
5598 ast_print(tree->left,outfile,indent+2);
5601 /*------------------------------------------------------------------*/
5602 /*----------------------------*/
5603 /* multiplication */
5604 /*----------------------------*/
5605 fprintf(outfile,"MULT (%p) type (",tree);
5606 printTypeChain(tree->ftype,outfile);
5607 fprintf(outfile,")\n");
5608 ast_print(tree->left,outfile,indent+2);
5609 ast_print(tree->right,outfile,indent+2);
5613 /*------------------------------------------------------------------*/
5614 /*----------------------------*/
5615 /* unary '+' operator */
5616 /*----------------------------*/
5620 fprintf(outfile,"UPLUS (%p) type (",tree);
5621 printTypeChain(tree->ftype,outfile);
5622 fprintf(outfile,")\n");
5623 ast_print(tree->left,outfile,indent+2);
5625 /*------------------------------------------------------------------*/
5626 /*----------------------------*/
5628 /*----------------------------*/
5629 fprintf(outfile,"ADD (%p) type (",tree);
5630 printTypeChain(tree->ftype,outfile);
5631 fprintf(outfile,")\n");
5632 ast_print(tree->left,outfile,indent+2);
5633 ast_print(tree->right,outfile,indent+2);
5636 /*------------------------------------------------------------------*/
5637 /*----------------------------*/
5639 /*----------------------------*/
5640 case '-': /* can be unary */
5642 fprintf(outfile,"UMINUS (%p) type (",tree);
5643 printTypeChain(tree->ftype,outfile);
5644 fprintf(outfile,")\n");
5645 ast_print(tree->left,outfile,indent+2);
5647 /*------------------------------------------------------------------*/
5648 /*----------------------------*/
5650 /*----------------------------*/
5651 fprintf(outfile,"SUB (%p) type (",tree);
5652 printTypeChain(tree->ftype,outfile);
5653 fprintf(outfile,")\n");
5654 ast_print(tree->left,outfile,indent+2);
5655 ast_print(tree->right,outfile,indent+2);
5658 /*------------------------------------------------------------------*/
5659 /*----------------------------*/
5661 /*----------------------------*/
5663 fprintf(outfile,"COMPL (%p) type (",tree);
5664 printTypeChain(tree->ftype,outfile);
5665 fprintf(outfile,")\n");
5666 ast_print(tree->left,outfile,indent+2);
5668 /*------------------------------------------------------------------*/
5669 /*----------------------------*/
5671 /*----------------------------*/
5673 fprintf(outfile,"NOT (%p) type (",tree);
5674 printTypeChain(tree->ftype,outfile);
5675 fprintf(outfile,")\n");
5676 ast_print(tree->left,outfile,indent+2);
5678 /*------------------------------------------------------------------*/
5679 /*----------------------------*/
5681 /*----------------------------*/
5683 fprintf(outfile,"RRC (%p) type (",tree);
5684 printTypeChain(tree->ftype,outfile);
5685 fprintf(outfile,")\n");
5686 ast_print(tree->left,outfile,indent+2);
5690 fprintf(outfile,"RLC (%p) type (",tree);
5691 printTypeChain(tree->ftype,outfile);
5692 fprintf(outfile,")\n");
5693 ast_print(tree->left,outfile,indent+2);
5696 fprintf(outfile,"SWAP (%p) type (",tree);
5697 printTypeChain(tree->ftype,outfile);
5698 fprintf(outfile,")\n");
5699 ast_print(tree->left,outfile,indent+2);
5702 fprintf(outfile,"GETHBIT (%p) type (",tree);
5703 printTypeChain(tree->ftype,outfile);
5704 fprintf(outfile,")\n");
5705 ast_print(tree->left,outfile,indent+2);
5708 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5709 printTypeChain(tree->ftype,outfile);
5710 fprintf(outfile,")\n");
5711 ast_print(tree->left,outfile,indent+2);
5712 ast_print(tree->right,outfile,indent+2);
5715 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5716 printTypeChain(tree->ftype,outfile);
5717 fprintf(outfile,")\n");
5718 ast_print(tree->left,outfile,indent+2);
5719 ast_print(tree->right,outfile,indent+2);
5721 /*------------------------------------------------------------------*/
5722 /*----------------------------*/
5724 /*----------------------------*/
5725 case CAST: /* change the type */
5726 fprintf(outfile,"CAST (%p) from type (",tree);
5727 printTypeChain(tree->right->ftype,outfile);
5728 fprintf(outfile,") to type (");
5729 printTypeChain(tree->ftype,outfile);
5730 fprintf(outfile,")\n");
5731 ast_print(tree->right,outfile,indent+2);
5735 fprintf(outfile,"ANDAND (%p) type (",tree);
5736 printTypeChain(tree->ftype,outfile);
5737 fprintf(outfile,")\n");
5738 ast_print(tree->left,outfile,indent+2);
5739 ast_print(tree->right,outfile,indent+2);
5742 fprintf(outfile,"OROR (%p) type (",tree);
5743 printTypeChain(tree->ftype,outfile);
5744 fprintf(outfile,")\n");
5745 ast_print(tree->left,outfile,indent+2);
5746 ast_print(tree->right,outfile,indent+2);
5749 /*------------------------------------------------------------------*/
5750 /*----------------------------*/
5751 /* comparison operators */
5752 /*----------------------------*/
5754 fprintf(outfile,"GT(>) (%p) type (",tree);
5755 printTypeChain(tree->ftype,outfile);
5756 fprintf(outfile,")\n");
5757 ast_print(tree->left,outfile,indent+2);
5758 ast_print(tree->right,outfile,indent+2);
5761 fprintf(outfile,"LT(<) (%p) type (",tree);
5762 printTypeChain(tree->ftype,outfile);
5763 fprintf(outfile,")\n");
5764 ast_print(tree->left,outfile,indent+2);
5765 ast_print(tree->right,outfile,indent+2);
5768 fprintf(outfile,"LE(<=) (%p) type (",tree);
5769 printTypeChain(tree->ftype,outfile);
5770 fprintf(outfile,")\n");
5771 ast_print(tree->left,outfile,indent+2);
5772 ast_print(tree->right,outfile,indent+2);
5775 fprintf(outfile,"GE(>=) (%p) type (",tree);
5776 printTypeChain(tree->ftype,outfile);
5777 fprintf(outfile,")\n");
5778 ast_print(tree->left,outfile,indent+2);
5779 ast_print(tree->right,outfile,indent+2);
5782 fprintf(outfile,"EQ(==) (%p) type (",tree);
5783 printTypeChain(tree->ftype,outfile);
5784 fprintf(outfile,")\n");
5785 ast_print(tree->left,outfile,indent+2);
5786 ast_print(tree->right,outfile,indent+2);
5789 fprintf(outfile,"NE(!=) (%p) type (",tree);
5790 printTypeChain(tree->ftype,outfile);
5791 fprintf(outfile,")\n");
5792 ast_print(tree->left,outfile,indent+2);
5793 ast_print(tree->right,outfile,indent+2);
5794 /*------------------------------------------------------------------*/
5795 /*----------------------------*/
5797 /*----------------------------*/
5798 case SIZEOF: /* evaluate wihout code generation */
5799 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5802 /*------------------------------------------------------------------*/
5803 /*----------------------------*/
5804 /* conditional operator '?' */
5805 /*----------------------------*/
5807 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5808 printTypeChain(tree->ftype,outfile);
5809 fprintf(outfile,")\n");
5810 ast_print(tree->left,outfile,indent+2);
5811 ast_print(tree->right,outfile,indent+2);
5815 fprintf(outfile,"COLON(:) (%p) type (",tree);
5816 printTypeChain(tree->ftype,outfile);
5817 fprintf(outfile,")\n");
5818 ast_print(tree->left,outfile,indent+2);
5819 ast_print(tree->right,outfile,indent+2);
5822 /*------------------------------------------------------------------*/
5823 /*----------------------------*/
5824 /* assignment operators */
5825 /*----------------------------*/
5827 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5828 printTypeChain(tree->ftype,outfile);
5829 fprintf(outfile,")\n");
5830 ast_print(tree->left,outfile,indent+2);
5831 ast_print(tree->right,outfile,indent+2);
5834 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5835 printTypeChain(tree->ftype,outfile);
5836 fprintf(outfile,")\n");
5837 ast_print(tree->left,outfile,indent+2);
5838 ast_print(tree->right,outfile,indent+2);
5841 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5842 printTypeChain(tree->ftype,outfile);
5843 fprintf(outfile,")\n");
5844 ast_print(tree->left,outfile,indent+2);
5845 ast_print(tree->right,outfile,indent+2);
5848 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5849 printTypeChain(tree->ftype,outfile);
5850 fprintf(outfile,")\n");
5851 ast_print(tree->left,outfile,indent+2);
5852 ast_print(tree->right,outfile,indent+2);
5855 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5856 printTypeChain(tree->ftype,outfile);
5857 fprintf(outfile,")\n");
5858 ast_print(tree->left,outfile,indent+2);
5859 ast_print(tree->right,outfile,indent+2);
5862 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5863 printTypeChain(tree->ftype,outfile);
5864 fprintf(outfile,")\n");
5865 ast_print(tree->left,outfile,indent+2);
5866 ast_print(tree->right,outfile,indent+2);
5869 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5870 printTypeChain(tree->ftype,outfile);
5871 fprintf(outfile,")\n");
5872 ast_print(tree->left,outfile,indent+2);
5873 ast_print(tree->right,outfile,indent+2);
5875 /*------------------------------------------------------------------*/
5876 /*----------------------------*/
5878 /*----------------------------*/
5880 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5881 printTypeChain(tree->ftype,outfile);
5882 fprintf(outfile,")\n");
5883 ast_print(tree->left,outfile,indent+2);
5884 ast_print(tree->right,outfile,indent+2);
5886 /*------------------------------------------------------------------*/
5887 /*----------------------------*/
5889 /*----------------------------*/
5891 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5892 printTypeChain(tree->ftype,outfile);
5893 fprintf(outfile,")\n");
5894 ast_print(tree->left,outfile,indent+2);
5895 ast_print(tree->right,outfile,indent+2);
5897 /*------------------------------------------------------------------*/
5898 /*----------------------------*/
5899 /* straight assignemnt */
5900 /*----------------------------*/
5902 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5903 printTypeChain(tree->ftype,outfile);
5904 fprintf(outfile,")\n");
5905 ast_print(tree->left,outfile,indent+2);
5906 ast_print(tree->right,outfile,indent+2);
5908 /*------------------------------------------------------------------*/
5909 /*----------------------------*/
5910 /* comma operator */
5911 /*----------------------------*/
5913 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5914 printTypeChain(tree->ftype,outfile);
5915 fprintf(outfile,")\n");
5916 ast_print(tree->left,outfile,indent+2);
5917 ast_print(tree->right,outfile,indent+2);
5919 /*------------------------------------------------------------------*/
5920 /*----------------------------*/
5922 /*----------------------------*/
5925 fprintf(outfile,"CALL (%p) type (",tree);
5926 printTypeChain(tree->ftype,outfile);
5927 fprintf(outfile,")\n");
5928 ast_print(tree->left,outfile,indent+2);
5929 ast_print(tree->right,outfile,indent+2);
5932 fprintf(outfile,"PARMS\n");
5933 ast_print(tree->left,outfile,indent+2);
5934 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5935 ast_print(tree->right,outfile,indent+2);
5938 /*------------------------------------------------------------------*/
5939 /*----------------------------*/
5940 /* return statement */
5941 /*----------------------------*/
5943 fprintf(outfile,"RETURN (%p) type (",tree);
5945 printTypeChain(tree->right->ftype,outfile);
5947 fprintf(outfile,")\n");
5948 ast_print(tree->right,outfile,indent+2);
5950 /*------------------------------------------------------------------*/
5951 /*----------------------------*/
5952 /* label statement */
5953 /*----------------------------*/
5955 fprintf(outfile,"LABEL (%p)\n",tree);
5956 ast_print(tree->left,outfile,indent+2);
5957 ast_print(tree->right,outfile,indent);
5959 /*------------------------------------------------------------------*/
5960 /*----------------------------*/
5961 /* switch statement */
5962 /*----------------------------*/
5966 fprintf(outfile,"SWITCH (%p) ",tree);
5967 ast_print(tree->left,outfile,0);
5968 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5969 INDENT(indent+2,outfile);
5970 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5971 (int) floatFromVal(val),
5972 tree->values.switchVals.swNum,
5973 (int) floatFromVal(val));
5975 ast_print(tree->right,outfile,indent);
5978 /*------------------------------------------------------------------*/
5979 /*----------------------------*/
5981 /*----------------------------*/
5983 fprintf(outfile,"IF (%p) \n",tree);
5984 ast_print(tree->left,outfile,indent+2);
5985 if (tree->trueLabel) {
5986 INDENT(indent+2,outfile);
5987 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5989 if (tree->falseLabel) {
5990 INDENT(indent+2,outfile);
5991 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5993 ast_print(tree->right,outfile,indent+2);
5995 /*----------------------------*/
5996 /* goto Statement */
5997 /*----------------------------*/
5999 fprintf(outfile,"GOTO (%p) \n",tree);
6000 ast_print(tree->left,outfile,indent+2);
6001 fprintf(outfile,"\n");
6003 /*------------------------------------------------------------------*/
6004 /*----------------------------*/
6006 /*----------------------------*/
6008 fprintf(outfile,"FOR (%p) \n",tree);
6009 if (AST_FOR( tree, initExpr)) {
6010 INDENT(indent+2,outfile);
6011 fprintf(outfile,"INIT EXPR ");
6012 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6014 if (AST_FOR( tree, condExpr)) {
6015 INDENT(indent+2,outfile);
6016 fprintf(outfile,"COND EXPR ");
6017 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6019 if (AST_FOR( tree, loopExpr)) {
6020 INDENT(indent+2,outfile);
6021 fprintf(outfile,"LOOP EXPR ");
6022 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6024 fprintf(outfile,"FOR LOOP BODY \n");
6025 ast_print(tree->left,outfile,indent+2);
6028 fprintf(outfile,"CRITICAL (%p) \n",tree);
6029 ast_print(tree->left,outfile,indent+2);
6037 ast_print(t,stdout,0);
6042 /*-----------------------------------------------------------------*/
6043 /* astErrors : returns non-zero if errors present in tree */
6044 /*-----------------------------------------------------------------*/
6045 int astErrors(ast *t)
6054 if (t->type == EX_VALUE
6055 && t->opval.val->sym
6056 && t->opval.val->sym->undefined)
6059 errors += astErrors(t->left);
6060 errors += astErrors(t->right);