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 /* keep unsigned type during cast to smaller type,
2088 but not when promoting from char to int */
2090 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2091 return decorateType (tree, resultType);
2094 /*-----------------------------------------------------------------*/
2095 /* resultTypePropagate - decides if resultType can be propagated */
2096 /*-----------------------------------------------------------------*/
2098 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2100 switch (tree->opval.op)
2111 return RESULT_TYPE_NONE;
2115 return RESULT_TYPE_NONE;
2119 /*-----------------------------------------------------------------*/
2120 /* getLeftResultType - gets type from left branch for propagation */
2121 /*-----------------------------------------------------------------*/
2123 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2125 switch (tree->opval.op)
2129 if (IS_PTR (LTYPE (tree)))
2130 return RESULT_TYPE_NONE;
2132 return getResultTypeFromType (LETYPE (tree));
2134 if (IS_PTR (currFunc->type->next))
2135 return RESULT_TYPE_NONE;
2137 return getResultTypeFromType (currFunc->type->next);
2139 if (!IS_ARRAY (LTYPE (tree)))
2141 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2142 return RESULT_TYPE_CHAR;
2149 /*--------------------------------------------------------------------*/
2150 /* decorateType - compute type for this tree, also does type checking.*/
2151 /* This is done bottom up, since type has to flow upwards. */
2152 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2153 /* result is a char and the operand(s) are int's. */
2154 /* It also does constant folding, and parameter checking. */
2155 /*--------------------------------------------------------------------*/
2157 decorateType (ast * tree, RESULT_TYPE resultType)
2161 RESULT_TYPE resultTypeProp;
2166 /* if already has type then do nothing */
2167 if (tree->decorated)
2170 tree->decorated = 1;
2173 /* print the line */
2174 /* if not block & function */
2175 if (tree->type == EX_OP &&
2176 (tree->opval.op != FUNCTION &&
2177 tree->opval.op != BLOCK &&
2178 tree->opval.op != NULLOP))
2180 filename = tree->filename;
2181 lineno = tree->lineno;
2185 /* if any child is an error | this one is an error do nothing */
2186 if (tree->isError ||
2187 (tree->left && tree->left->isError) ||
2188 (tree->right && tree->right->isError))
2191 /*------------------------------------------------------------------*/
2192 /*----------------------------*/
2193 /* leaf has been reached */
2194 /*----------------------------*/
2195 lineno=tree->lineno;
2196 /* if this is of type value */
2197 /* just get the type */
2198 if (tree->type == EX_VALUE)
2201 if (IS_LITERAL (tree->opval.val->etype))
2204 /* if this is a character array then declare it */
2205 if (IS_ARRAY (tree->opval.val->type))
2206 tree->opval.val = stringToSymbol (tree->opval.val);
2208 /* otherwise just copy the type information */
2209 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2213 if (tree->opval.val->sym)
2215 /* if the undefined flag is set then give error message */
2216 if (tree->opval.val->sym->undefined)
2218 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2220 TTYPE (tree) = TETYPE (tree) =
2221 tree->opval.val->type = tree->opval.val->sym->type =
2222 tree->opval.val->etype = tree->opval.val->sym->etype =
2223 copyLinkChain (INTTYPE);
2228 /* if impilicit i.e. struct/union member then no type */
2229 if (tree->opval.val->sym->implicit)
2230 TTYPE (tree) = TETYPE (tree) = NULL;
2235 /* else copy the type */
2236 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2238 /* and mark it as referenced */
2239 tree->opval.val->sym->isref = 1;
2247 /* if type link for the case of cast */
2248 if (tree->type == EX_LINK)
2250 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2258 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2260 if (tree->left && tree->left->type == EX_OPERAND
2261 && (tree->left->opval.op == INC_OP
2262 || tree->left->opval.op == DEC_OP)
2263 && tree->left->left)
2265 tree->left->right = tree->left->left;
2266 tree->left->left = NULL;
2268 if (tree->right && tree->right->type == EX_OPERAND
2269 && (tree->right->opval.op == INC_OP
2270 || tree->right->opval.op == DEC_OP)
2271 && tree->right->left)
2273 tree->right->right = tree->right->left;
2274 tree->right->left = NULL;
2279 /* Before decorating the left branch we've to decide in dependence
2280 upon tree->opval.op, if resultType can be propagated */
2281 resultTypeProp = resultTypePropagate (tree, resultType);
2283 dtl = decorateType (tree->left, resultTypeProp);
2285 /* if an array node, we may need to swap branches */
2286 if (tree->opval.op == '[')
2288 /* determine which is the array & which the index */
2289 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2290 IS_INTEGRAL (LTYPE (tree)))
2292 ast *tempTree = tree->left;
2293 tree->left = tree->right;
2294 tree->right = tempTree;
2298 /* After decorating the left branch there's type information available
2299 in tree->left->?type. If the op is e.g. '=' we extract the type
2300 information from there and propagate it to the right branch. */
2301 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2303 switch (tree->opval.op)
2306 /* delay right side for '?' operator since conditional macro
2307 expansions might rely on this */
2311 /* decorate right side for CALL (parameter list) in processParms();
2312 there is resultType available */
2316 dtr = decorateType (tree->right, resultTypeProp);
2320 /* this is to take care of situations
2321 when the tree gets rewritten */
2322 if (dtl != tree->left)
2324 if (dtr != tree->right)
2326 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2330 /* depending on type of operator do */
2332 switch (tree->opval.op)
2334 /*------------------------------------------------------------------*/
2335 /*----------------------------*/
2337 /*----------------------------*/
2340 /* first check if this is a array or a pointer */
2341 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2343 werror (E_NEED_ARRAY_PTR, "[]");
2344 goto errorTreeReturn;
2347 /* check if the type of the idx */
2348 if (!IS_INTEGRAL (RTYPE (tree)))
2350 werror (E_IDX_NOT_INT);
2351 goto errorTreeReturn;
2354 /* if the left is an rvalue then error */
2357 werror (E_LVALUE_REQUIRED, "array access");
2358 goto errorTreeReturn;
2361 if (IS_LITERAL (RTYPE (tree)))
2363 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2364 int arraySize = DCL_ELEM (LTYPE (tree));
2365 if (arraySize && arrayIndex >= arraySize)
2367 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2372 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2375 /*------------------------------------------------------------------*/
2376 /*----------------------------*/
2378 /*----------------------------*/
2380 /* if this is not a structure */
2381 if (!IS_STRUCT (LTYPE (tree)))
2383 werror (E_STRUCT_UNION, ".");
2384 goto errorTreeReturn;
2386 TTYPE (tree) = structElemType (LTYPE (tree),
2387 (tree->right->type == EX_VALUE ?
2388 tree->right->opval.val : NULL));
2389 TETYPE (tree) = getSpec (TTYPE (tree));
2392 /*------------------------------------------------------------------*/
2393 /*----------------------------*/
2394 /* struct/union pointer */
2395 /*----------------------------*/
2397 /* if not pointer to a structure */
2398 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2400 werror (E_PTR_REQD);
2401 goto errorTreeReturn;
2404 if (!IS_STRUCT (LTYPE (tree)->next))
2406 werror (E_STRUCT_UNION, "->");
2407 goto errorTreeReturn;
2410 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2411 (tree->right->type == EX_VALUE ?
2412 tree->right->opval.val : NULL));
2413 TETYPE (tree) = getSpec (TTYPE (tree));
2415 /* adjust the storage class */
2416 switch (DCL_TYPE(tree->left->ftype)) {
2418 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2421 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2424 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2427 SPEC_SCLS (TETYPE (tree)) = 0;
2430 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2433 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2436 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2439 SPEC_SCLS (TETYPE (tree)) = 0;
2446 /* This breaks with extern declarations, bitfields, and perhaps other */
2447 /* cases (gcse). Let's leave this optimization disabled for now and */
2448 /* ponder if there's a safe way to do this. -- EEP */
2450 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2451 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2453 /* If defined struct type at addr var
2454 then rewrite (&struct var)->member
2456 and define membertype at (addr+offsetof(struct var,member)) temp
2459 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2460 AST_SYMBOL(tree->right));
2462 sym = newSymbol(genSymName (0), 0);
2463 sym->type = TTYPE (tree);
2464 sym->etype = getSpec(sym->type);
2465 sym->lineDef = tree->lineno;
2468 SPEC_STAT (sym->etype) = 1;
2469 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2471 SPEC_ABSA(sym->etype) = 1;
2472 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2475 AST_VALUE (tree) = symbolVal(sym);
2478 tree->type = EX_VALUE;
2486 /*------------------------------------------------------------------*/
2487 /*----------------------------*/
2488 /* ++/-- operation */
2489 /*----------------------------*/
2493 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2494 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2495 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2496 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2505 /*------------------------------------------------------------------*/
2506 /*----------------------------*/
2508 /*----------------------------*/
2509 case '&': /* can be unary */
2510 /* if right is NULL then unary operation */
2511 if (tree->right) /* not an unary operation */
2514 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2516 werror (E_BITWISE_OP);
2517 werror (W_CONTINUE, "left & right types are ");
2518 printTypeChain (LTYPE (tree), stderr);
2519 fprintf (stderr, ",");
2520 printTypeChain (RTYPE (tree), stderr);
2521 fprintf (stderr, "\n");
2522 goto errorTreeReturn;
2525 /* if they are both literal */
2526 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2528 tree->type = EX_VALUE;
2529 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2530 valFromType (RETYPE (tree)), '&');
2532 tree->right = tree->left = NULL;
2533 TETYPE (tree) = tree->opval.val->etype;
2534 TTYPE (tree) = tree->opval.val->type;
2538 /* see if this is a GETHBIT operation if yes
2541 ast *otree = optimizeGetHbit (tree);
2544 return decorateType (otree, RESULT_CHECK);
2547 tree->left = addCast (tree->left, resultType, FALSE);
2548 tree->right = addCast (tree->right, resultType, FALSE);
2549 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2550 TETYPE (tree) = getSpec (TTYPE (tree));
2552 /* if left is a literal exchange left & right */
2553 if (IS_LITERAL (LTYPE (tree)))
2555 ast *tTree = tree->left;
2556 tree->left = tree->right;
2557 tree->right = tTree;
2560 /* if right is a literal and */
2561 /* we can find a 2nd literal in a and-tree then */
2562 /* rearrange the tree */
2563 if (IS_LITERAL (RTYPE (tree)))
2566 ast *litTree = searchLitOp (tree, &parent, "&");
2569 ast *tTree = litTree->left;
2570 litTree->left = tree->right;
2571 tree->right = tTree;
2572 /* both operands in tTree are literal now */
2573 decorateType (parent, RESULT_CHECK);
2577 LRVAL (tree) = RRVAL (tree) = 1;
2582 /*------------------------------------------------------------------*/
2583 /*----------------------------*/
2585 /*----------------------------*/
2586 p = newLink (DECLARATOR);
2587 /* if bit field then error */
2588 if (IS_BITVAR (tree->left->etype))
2590 werror (E_ILLEGAL_ADDR, "address of bit variable");
2591 goto errorTreeReturn;
2594 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2596 werror (E_ILLEGAL_ADDR, "address of register variable");
2597 goto errorTreeReturn;
2600 if (IS_FUNC (LTYPE (tree)))
2602 // this ought to be ignored
2603 return (tree->left);
2606 if (IS_LITERAL(LTYPE(tree)))
2608 werror (E_ILLEGAL_ADDR, "address of literal");
2609 goto errorTreeReturn;
2614 werror (E_LVALUE_REQUIRED, "address of");
2615 goto errorTreeReturn;
2618 DCL_TYPE (p) = POINTER;
2619 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2620 DCL_TYPE (p) = CPOINTER;
2621 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2622 DCL_TYPE (p) = FPOINTER;
2623 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2624 DCL_TYPE (p) = PPOINTER;
2625 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2626 DCL_TYPE (p) = IPOINTER;
2627 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2628 DCL_TYPE (p) = EEPPOINTER;
2629 else if (SPEC_OCLS(tree->left->etype))
2630 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2632 DCL_TYPE (p) = POINTER;
2634 if (IS_AST_SYM_VALUE (tree->left))
2636 AST_SYMBOL (tree->left)->addrtaken = 1;
2637 AST_SYMBOL (tree->left)->allocreq = 1;
2640 p->next = LTYPE (tree);
2642 TETYPE (tree) = getSpec (TTYPE (tree));
2647 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2648 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2650 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2651 AST_SYMBOL(tree->left->right));
2652 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2653 valueFromLit(element->offset));
2656 tree->type = EX_VALUE;
2657 tree->values.literalFromCast = 1;
2663 /*------------------------------------------------------------------*/
2664 /*----------------------------*/
2666 /*----------------------------*/
2668 /* if the rewrite succeeds then don't go any furthur */
2670 ast *wtree = optimizeRRCRLC (tree);
2672 return decorateType (wtree, RESULT_CHECK);
2674 wtree = optimizeSWAP (tree);
2676 return decorateType (wtree, RESULT_CHECK);
2679 /* if left is a literal exchange left & right */
2680 if (IS_LITERAL (LTYPE (tree)))
2682 ast *tTree = tree->left;
2683 tree->left = tree->right;
2684 tree->right = tTree;
2687 /* if right is a literal and */
2688 /* we can find a 2nd literal in a or-tree then */
2689 /* rearrange the tree */
2690 if (IS_LITERAL (RTYPE (tree)))
2693 ast *litTree = searchLitOp (tree, &parent, "|");
2696 ast *tTree = litTree->left;
2697 litTree->left = tree->right;
2698 tree->right = tTree;
2699 /* both operands in tTree are literal now */
2700 decorateType (parent, RESULT_CHECK);
2705 /*------------------------------------------------------------------*/
2706 /*----------------------------*/
2708 /*----------------------------*/
2710 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2712 werror (E_BITWISE_OP);
2713 werror (W_CONTINUE, "left & right types are ");
2714 printTypeChain (LTYPE (tree), stderr);
2715 fprintf (stderr, ",");
2716 printTypeChain (RTYPE (tree), stderr);
2717 fprintf (stderr, "\n");
2718 goto errorTreeReturn;
2721 /* if they are both literal then */
2722 /* rewrite the tree */
2723 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2725 tree->type = EX_VALUE;
2726 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2727 valFromType (RETYPE (tree)),
2729 tree->right = tree->left = NULL;
2730 TETYPE (tree) = tree->opval.val->etype;
2731 TTYPE (tree) = tree->opval.val->type;
2735 /* if left is a literal exchange left & right */
2736 if (IS_LITERAL (LTYPE (tree)))
2738 ast *tTree = tree->left;
2739 tree->left = tree->right;
2740 tree->right = tTree;
2743 /* if right is a literal and */
2744 /* we can find a 2nd literal in a xor-tree then */
2745 /* rearrange the tree */
2746 if (IS_LITERAL (RTYPE (tree)) &&
2747 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2750 ast *litTree = searchLitOp (tree, &parent, "^");
2753 ast *tTree = litTree->left;
2754 litTree->left = tree->right;
2755 tree->right = tTree;
2756 /* both operands in litTree are literal now */
2757 decorateType (parent, RESULT_CHECK);
2761 LRVAL (tree) = RRVAL (tree) = 1;
2762 tree->left = addCast (tree->left, resultType, FALSE);
2763 tree->right = addCast (tree->right, resultType, FALSE);
2764 TETYPE (tree) = getSpec (TTYPE (tree) =
2765 computeType (LTYPE (tree),
2771 /*------------------------------------------------------------------*/
2772 /*----------------------------*/
2774 /*----------------------------*/
2776 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2778 werror (E_INVALID_OP, "divide");
2779 goto errorTreeReturn;
2781 /* if they are both literal then */
2782 /* rewrite the tree */
2783 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2785 tree->type = EX_VALUE;
2786 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2787 valFromType (RETYPE (tree)));
2788 tree->right = tree->left = NULL;
2789 TETYPE (tree) = getSpec (TTYPE (tree) =
2790 tree->opval.val->type);
2794 LRVAL (tree) = RRVAL (tree) = 1;
2795 TETYPE (tree) = getSpec (TTYPE (tree) =
2796 computeType (LTYPE (tree),
2798 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2800 /* if right is a literal and */
2801 /* left is also a division by a literal then */
2802 /* rearrange the tree */
2803 if (IS_LITERAL (RTYPE (tree))
2804 /* avoid infinite loop */
2805 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2808 ast *litTree = searchLitOp (tree, &parent, "/");
2811 if (IS_LITERAL (RTYPE (litTree)))
2814 litTree->right = newNode ('*', litTree->right, tree->right);
2815 litTree->right->lineno = tree->lineno;
2817 tree->right->opval.val = constVal ("1");
2818 decorateType (parent, RESULT_CHECK);
2822 /* litTree->left is literal: no gcse possible.
2823 We can't call decorateType(parent, RESULT_CHECK), because
2824 this would cause an infinit loop. */
2825 parent->decorated = 1;
2826 decorateType (litTree, RESULT_CHECK);
2833 /*------------------------------------------------------------------*/
2834 /*----------------------------*/
2836 /*----------------------------*/
2838 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2840 werror (E_BITWISE_OP);
2841 werror (W_CONTINUE, "left & right types are ");
2842 printTypeChain (LTYPE (tree), stderr);
2843 fprintf (stderr, ",");
2844 printTypeChain (RTYPE (tree), stderr);
2845 fprintf (stderr, "\n");
2846 goto errorTreeReturn;
2848 /* if they are both literal then */
2849 /* rewrite the tree */
2850 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2852 tree->type = EX_VALUE;
2853 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2854 valFromType (RETYPE (tree)));
2855 tree->right = tree->left = NULL;
2856 TETYPE (tree) = getSpec (TTYPE (tree) =
2857 tree->opval.val->type);
2860 LRVAL (tree) = RRVAL (tree) = 1;
2861 TETYPE (tree) = getSpec (TTYPE (tree) =
2862 computeType (LTYPE (tree),
2864 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2867 /*------------------------------------------------------------------*/
2868 /*----------------------------*/
2869 /* address dereference */
2870 /*----------------------------*/
2871 case '*': /* can be unary : if right is null then unary operation */
2874 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2876 werror (E_PTR_REQD);
2877 goto errorTreeReturn;
2882 werror (E_LVALUE_REQUIRED, "pointer deref");
2883 goto errorTreeReturn;
2885 if (IS_ADDRESS_OF_OP(tree->left))
2887 /* replace *&obj with obj */
2888 return tree->left->left;
2890 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2891 TETYPE (tree) = getSpec (TTYPE (tree));
2892 /* adjust the storage class */
2893 switch (DCL_TYPE(tree->left->ftype)) {
2895 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2898 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2901 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2904 SPEC_SCLS (TETYPE (tree)) = 0;
2907 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2910 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2913 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2916 SPEC_SCLS (TETYPE (tree)) = 0;
2925 /*------------------------------------------------------------------*/
2926 /*----------------------------*/
2927 /* multiplication */
2928 /*----------------------------*/
2929 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2931 werror (E_INVALID_OP, "multiplication");
2932 goto errorTreeReturn;
2935 /* if they are both literal then */
2936 /* rewrite the tree */
2937 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2939 tree->type = EX_VALUE;
2940 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2941 valFromType (RETYPE (tree)));
2942 tree->right = tree->left = NULL;
2943 TETYPE (tree) = getSpec (TTYPE (tree) =
2944 tree->opval.val->type);
2948 /* if left is a literal exchange left & right */
2949 if (IS_LITERAL (LTYPE (tree)))
2951 ast *tTree = tree->left;
2952 tree->left = tree->right;
2953 tree->right = tTree;
2956 /* if right is a literal and */
2957 /* we can find a 2nd literal in a mul-tree then */
2958 /* rearrange the tree */
2959 if (IS_LITERAL (RTYPE (tree)))
2962 ast *litTree = searchLitOp (tree, &parent, "*");
2965 ast *tTree = litTree->left;
2966 litTree->left = tree->right;
2967 tree->right = tTree;
2968 /* both operands in litTree are literal now */
2969 decorateType (parent, RESULT_CHECK);
2973 LRVAL (tree) = RRVAL (tree) = 1;
2974 tree->left = addCast (tree->left, resultType, FALSE);
2975 tree->right = addCast (tree->right, resultType, FALSE);
2976 TETYPE (tree) = getSpec (TTYPE (tree) =
2977 computeType (LTYPE (tree),
2979 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2983 /*------------------------------------------------------------------*/
2984 /*----------------------------*/
2985 /* unary '+' operator */
2986 /*----------------------------*/
2991 if (!IS_ARITHMETIC (LTYPE (tree)))
2993 werror (E_UNARY_OP, '+');
2994 goto errorTreeReturn;
2997 /* if left is a literal then do it */
2998 if (IS_LITERAL (LTYPE (tree)))
3000 tree->type = EX_VALUE;
3001 tree->opval.val = valFromType (LETYPE (tree));
3003 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3007 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3011 /*------------------------------------------------------------------*/
3012 /*----------------------------*/
3014 /*----------------------------*/
3016 /* this is not a unary operation */
3017 /* if both pointers then problem */
3018 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3019 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3021 werror (E_PTR_PLUS_PTR);
3022 goto errorTreeReturn;
3025 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3026 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3028 werror (E_PLUS_INVALID, "+");
3029 goto errorTreeReturn;
3032 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3033 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3035 werror (E_PLUS_INVALID, "+");
3036 goto errorTreeReturn;
3038 /* if they are both literal then */
3039 /* rewrite the tree */
3040 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3042 tree->type = EX_VALUE;
3043 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3044 valFromType (RETYPE (tree)));
3045 tree->right = tree->left = NULL;
3046 TETYPE (tree) = getSpec (TTYPE (tree) =
3047 tree->opval.val->type);
3051 /* if the right is a pointer or left is a literal
3052 xchange left & right */
3053 if (IS_ARRAY (RTYPE (tree)) ||
3054 IS_PTR (RTYPE (tree)) ||
3055 IS_LITERAL (LTYPE (tree)))
3057 ast *tTree = tree->left;
3058 tree->left = tree->right;
3059 tree->right = tTree;
3062 /* if right is a literal and */
3063 /* left is also an addition/subtraction with a literal then */
3064 /* rearrange the tree */
3065 if (IS_LITERAL (RTYPE (tree)))
3067 ast *litTree, *parent;
3068 litTree = searchLitOp (tree, &parent, "+-");
3071 if (litTree->opval.op == '+')
3074 ast *tTree = litTree->left;
3075 litTree->left = tree->right;
3076 tree->right = tree->left;
3079 else if (litTree->opval.op == '-')
3081 if (IS_LITERAL (RTYPE (litTree)))
3084 ast *tTree = litTree->left;
3085 litTree->left = tree->right;
3086 tree->right = tTree;
3091 ast *tTree = litTree->right;
3092 litTree->right = tree->right;
3093 tree->right = tTree;
3094 litTree->opval.op = '+';
3095 tree->opval.op = '-';
3098 decorateType (parent, RESULT_CHECK);
3102 LRVAL (tree) = RRVAL (tree) = 1;
3103 /* if the left is a pointer */
3104 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3105 TETYPE (tree) = getSpec (TTYPE (tree) =
3109 tree->left = addCast (tree->left, resultType, TRUE);
3110 tree->right = addCast (tree->right, resultType, TRUE);
3111 TETYPE (tree) = getSpec (TTYPE (tree) =
3112 computeType (LTYPE (tree),
3114 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3119 /*------------------------------------------------------------------*/
3120 /*----------------------------*/
3122 /*----------------------------*/
3123 case '-': /* can be unary */
3124 /* if right is null then unary */
3128 if (!IS_ARITHMETIC (LTYPE (tree)))
3130 werror (E_UNARY_OP, tree->opval.op);
3131 goto errorTreeReturn;
3134 /* if left is a literal then do it */
3135 if (IS_LITERAL (LTYPE (tree)))
3137 tree->type = EX_VALUE;
3138 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3140 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3141 SPEC_USIGN(TETYPE(tree)) = 0;
3145 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3149 /*------------------------------------------------------------------*/
3150 /*----------------------------*/
3152 /*----------------------------*/
3154 if (!(IS_PTR (LTYPE (tree)) ||
3155 IS_ARRAY (LTYPE (tree)) ||
3156 IS_ARITHMETIC (LTYPE (tree))))
3158 werror (E_PLUS_INVALID, "-");
3159 goto errorTreeReturn;
3162 if (!(IS_PTR (RTYPE (tree)) ||
3163 IS_ARRAY (RTYPE (tree)) ||
3164 IS_ARITHMETIC (RTYPE (tree))))
3166 werror (E_PLUS_INVALID, "-");
3167 goto errorTreeReturn;
3170 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3171 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3172 IS_INTEGRAL (RTYPE (tree))))
3174 werror (E_PLUS_INVALID, "-");
3175 goto errorTreeReturn;
3178 /* if they are both literal then */
3179 /* rewrite the tree */
3180 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3182 tree->type = EX_VALUE;
3183 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3184 valFromType (RETYPE (tree)));
3185 tree->right = tree->left = NULL;
3186 TETYPE (tree) = getSpec (TTYPE (tree) =
3187 tree->opval.val->type);
3191 /* if the left & right are equal then zero */
3192 if (isAstEqual (tree->left, tree->right))
3194 tree->type = EX_VALUE;
3195 tree->left = tree->right = NULL;
3196 tree->opval.val = constVal ("0");
3197 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3201 /* if both of them are pointers or arrays then */
3202 /* the result is going to be an integer */
3203 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3204 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3205 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3207 /* if only the left is a pointer */
3208 /* then result is a pointer */
3209 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3210 TETYPE (tree) = getSpec (TTYPE (tree) =
3214 tree->left = addCast (tree->left, resultType, TRUE);
3215 tree->right = addCast (tree->right, resultType, TRUE);
3216 TETYPE (tree) = getSpec (TTYPE (tree) =
3217 computeType (LTYPE (tree),
3219 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3222 LRVAL (tree) = RRVAL (tree) = 1;
3224 /* if right is a literal and */
3225 /* left is also an addition/subtraction with a literal then */
3226 /* rearrange the tree */
3227 if (IS_LITERAL (RTYPE (tree))
3228 /* avoid infinite loop */
3229 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3231 ast *litTree, *litParent;
3232 litTree = searchLitOp (tree, &litParent, "+-");
3235 if (litTree->opval.op == '+')
3238 litTree->right = newNode ('-', litTree->right, tree->right);
3239 litTree->right->lineno = tree->lineno;
3241 tree->right->opval.val = constVal ("0");
3243 else if (litTree->opval.op == '-')
3245 if (IS_LITERAL (RTYPE (litTree)))
3248 litTree->right = newNode ('+', tree->right, litTree->right);
3249 litTree->right->lineno = tree->lineno;
3251 tree->right->opval.val = constVal ("0");
3256 ast *tTree = litTree->right;
3257 litTree->right = tree->right;
3258 tree->right = tTree;
3261 decorateType (litParent, RESULT_CHECK);
3266 /*------------------------------------------------------------------*/
3267 /*----------------------------*/
3269 /*----------------------------*/
3271 /* can be only integral type */
3272 if (!IS_INTEGRAL (LTYPE (tree)))
3274 werror (E_UNARY_OP, tree->opval.op);
3275 goto errorTreeReturn;
3278 /* if left is a literal then do it */
3279 if (IS_LITERAL (LTYPE (tree)))
3281 tree->type = EX_VALUE;
3282 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3284 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3288 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3291 /*------------------------------------------------------------------*/
3292 /*----------------------------*/
3294 /*----------------------------*/
3296 /* can be pointer */
3297 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3298 !IS_PTR (LTYPE (tree)) &&
3299 !IS_ARRAY (LTYPE (tree)))
3301 werror (E_UNARY_OP, tree->opval.op);
3302 goto errorTreeReturn;
3305 /* if left is a literal then do it */
3306 if (IS_LITERAL (LTYPE (tree)))
3308 tree->type = EX_VALUE;
3309 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3311 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3315 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3318 /*------------------------------------------------------------------*/
3319 /*----------------------------*/
3321 /*----------------------------*/
3325 TTYPE (tree) = LTYPE (tree);
3326 TETYPE (tree) = LETYPE (tree);
3330 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3335 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3337 werror (E_SHIFT_OP_INVALID);
3338 werror (W_CONTINUE, "left & right types are ");
3339 printTypeChain (LTYPE (tree), stderr);
3340 fprintf (stderr, ",");
3341 printTypeChain (RTYPE (tree), stderr);
3342 fprintf (stderr, "\n");
3343 goto errorTreeReturn;
3346 /* if they are both literal then */
3347 /* rewrite the tree */
3348 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3350 tree->type = EX_VALUE;
3351 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3352 valFromType (RETYPE (tree)),
3353 (tree->opval.op == LEFT_OP ? 1 : 0));
3354 tree->right = tree->left = NULL;
3355 TETYPE (tree) = getSpec (TTYPE (tree) =
3356 tree->opval.val->type);
3360 LRVAL (tree) = RRVAL (tree) = 1;
3361 if (tree->opval.op == LEFT_OP)
3363 tree->left = addCast (tree->left, resultType, TRUE);
3364 TETYPE (tree) = getSpec (TTYPE (tree) =
3365 computeType (LTYPE (tree),
3367 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3371 /* no promotion necessary */
3372 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3373 if (IS_LITERAL (TTYPE (tree)))
3374 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3377 /* if only the right side is a literal & we are
3378 shifting more than size of the left operand then zero */
3379 if (IS_LITERAL (RTYPE (tree)) &&
3380 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3381 (getSize (TETYPE (tree)) * 8))
3383 if (tree->opval.op==LEFT_OP ||
3384 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3386 lineno=tree->lineno;
3387 werror (W_SHIFT_CHANGED,
3388 (tree->opval.op == LEFT_OP ? "left" : "right"));
3389 tree->type = EX_VALUE;
3390 tree->left = tree->right = NULL;
3391 tree->opval.val = constVal ("0");
3392 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3399 /*------------------------------------------------------------------*/
3400 /*----------------------------*/
3402 /*----------------------------*/
3403 case CAST: /* change the type */
3404 /* cannot cast to an aggregate type */
3405 if (IS_AGGREGATE (LTYPE (tree)))
3407 werror (E_CAST_ILLEGAL);
3408 goto errorTreeReturn;
3411 /* make sure the type is complete and sane */
3412 checkTypeSanity(LETYPE(tree), "(cast)");
3414 /* If code memory is read only, then pointers to code memory */
3415 /* implicitly point to constants -- make this explicit */
3417 sym_link *t = LTYPE(tree);
3418 while (t && t->next)
3420 if (IS_CODEPTR(t) && port->mem.code_ro)
3422 if (IS_SPEC(t->next))
3423 SPEC_CONST (t->next) = 1;
3425 DCL_PTR_CONST (t->next) = 1;
3432 /* if the right is a literal replace the tree */
3433 if (IS_LITERAL (RETYPE (tree))) {
3434 if (!IS_PTR (LTYPE (tree))) {
3435 tree->type = EX_VALUE;
3437 valCastLiteral (LTYPE (tree),
3438 floatFromVal (valFromType (RETYPE (tree))));
3441 TTYPE (tree) = tree->opval.val->type;
3442 tree->values.literalFromCast = 1;
3443 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3444 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3445 sym_link *rest = LTYPE(tree)->next;
3446 werror(W_LITERAL_GENERIC);
3447 TTYPE(tree) = newLink(DECLARATOR);
3448 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3449 TTYPE(tree)->next = rest;
3450 tree->left->opval.lnk = TTYPE(tree);
3453 TTYPE (tree) = LTYPE (tree);
3457 TTYPE (tree) = LTYPE (tree);
3461 #if 0 // this is already checked, now this could be explicit
3462 /* if pointer to struct then check names */
3463 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3464 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3465 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3467 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3468 SPEC_STRUCT(LETYPE(tree))->tag);
3471 if (IS_ADDRESS_OF_OP(tree->right)
3472 && IS_AST_SYM_VALUE (tree->right->left)
3473 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3475 tree->type = EX_VALUE;
3477 valCastLiteral (LTYPE (tree),
3478 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3479 TTYPE (tree) = tree->opval.val->type;
3480 TETYPE (tree) = getSpec (TTYPE (tree));
3483 tree->values.literalFromCast = 1;
3487 /* handle offsetof macro: */
3488 /* #define offsetof(TYPE, MEMBER) \ */
3489 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3490 if (IS_ADDRESS_OF_OP(tree->right)
3491 && IS_AST_OP (tree->right->left)
3492 && tree->right->left->opval.op == PTR_OP
3493 && IS_AST_OP (tree->right->left->left)
3494 && tree->right->left->left->opval.op == CAST
3495 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3497 symbol *element = getStructElement (
3498 SPEC_STRUCT (LETYPE(tree->right->left)),
3499 AST_SYMBOL(tree->right->left->right)
3503 tree->type = EX_VALUE;
3504 tree->opval.val = valCastLiteral (
3507 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3510 TTYPE (tree) = tree->opval.val->type;
3511 TETYPE (tree) = getSpec (TTYPE (tree));
3518 /* if the right is a literal replace the tree */
3519 if (IS_LITERAL (RETYPE (tree))) {
3521 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3522 /* rewrite (type *)litaddr
3524 and define type at litaddr temp
3525 (but only if type's storage class is not generic)
3527 ast *newTree = newNode ('&', NULL, NULL);
3530 TTYPE (newTree) = LTYPE (tree);
3531 TETYPE (newTree) = getSpec(LTYPE (tree));
3533 /* define a global symbol at the casted address*/
3534 sym = newSymbol(genSymName (0), 0);
3535 sym->type = LTYPE (tree)->next;
3537 sym->type = newLink (V_VOID);
3538 sym->etype = getSpec(sym->type);
3539 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3540 sym->lineDef = tree->lineno;
3543 SPEC_STAT (sym->etype) = 1;
3544 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3545 SPEC_ABSA(sym->etype) = 1;
3546 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3549 newTree->left = newAst_VALUE(symbolVal(sym));
3550 newTree->left->lineno = tree->lineno;
3551 LTYPE (newTree) = sym->type;
3552 LETYPE (newTree) = sym->etype;
3553 LLVAL (newTree) = 1;
3554 LRVAL (newTree) = 0;
3555 TLVAL (newTree) = 1;
3559 if (!IS_PTR (LTYPE (tree))) {
3560 tree->type = EX_VALUE;
3562 valCastLiteral (LTYPE (tree),
3563 floatFromVal (valFromType (RTYPE (tree))));
3564 TTYPE (tree) = tree->opval.val->type;
3567 tree->values.literalFromCast = 1;
3568 TETYPE (tree) = getSpec (TTYPE (tree));
3572 TTYPE (tree) = LTYPE (tree);
3576 TETYPE (tree) = getSpec (TTYPE (tree));
3580 /*------------------------------------------------------------------*/
3581 /*----------------------------*/
3582 /* logical &&, || */
3583 /*----------------------------*/
3586 /* each must me arithmetic type or be a pointer */
3587 if (!IS_PTR (LTYPE (tree)) &&
3588 !IS_ARRAY (LTYPE (tree)) &&
3589 !IS_INTEGRAL (LTYPE (tree)))
3591 werror (E_COMPARE_OP);
3592 goto errorTreeReturn;
3595 if (!IS_PTR (RTYPE (tree)) &&
3596 !IS_ARRAY (RTYPE (tree)) &&
3597 !IS_INTEGRAL (RTYPE (tree)))
3599 werror (E_COMPARE_OP);
3600 goto errorTreeReturn;
3602 /* if they are both literal then */
3603 /* rewrite the tree */
3604 if (IS_LITERAL (RTYPE (tree)) &&
3605 IS_LITERAL (LTYPE (tree)))
3607 tree->type = EX_VALUE;
3608 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3609 valFromType (RTYPE (tree)),
3611 tree->right = tree->left = NULL;
3612 TETYPE (tree) = getSpec (TTYPE (tree) =
3613 tree->opval.val->type);
3616 LRVAL (tree) = RRVAL (tree) = 1;
3617 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3620 /*------------------------------------------------------------------*/
3621 /*----------------------------*/
3622 /* comparison operators */
3623 /*----------------------------*/
3631 ast *lt = optimizeCompare (tree);
3637 /* if they are pointers they must be castable */
3638 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3640 if (tree->opval.op==EQ_OP &&
3641 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3642 // we cannot cast a gptr to a !gptr: switch the leaves
3643 struct ast *s=tree->left;
3644 tree->left=tree->right;
3647 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3649 werror (E_COMPARE_OP);
3650 fprintf (stderr, "comparing type ");
3651 printTypeChain (LTYPE (tree), stderr);
3652 fprintf (stderr, "to type ");
3653 printTypeChain (RTYPE (tree), stderr);
3654 fprintf (stderr, "\n");
3655 goto errorTreeReturn;
3658 /* else they should be promotable to one another */
3661 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3662 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3664 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3666 werror (E_COMPARE_OP);
3667 fprintf (stderr, "comparing type ");
3668 printTypeChain (LTYPE (tree), stderr);
3669 fprintf (stderr, "to type ");
3670 printTypeChain (RTYPE (tree), stderr);
3671 fprintf (stderr, "\n");
3672 goto errorTreeReturn;
3675 /* if unsigned value < 0 then always false */
3676 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3677 if (SPEC_USIGN(LETYPE(tree)) &&
3678 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3679 IS_LITERAL(RTYPE(tree)) &&
3680 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3682 if (tree->opval.op == '<')
3686 if (tree->opval.op == '>')
3688 /* if the parent is an ifx, then we could do */
3689 /* return tree->left; */
3690 tree->opval.op = '?';
3691 tree->right = newNode (':',
3692 newAst_VALUE (constVal ("1")),
3693 tree->right); /* val 0 */
3694 tree->right->lineno = tree->lineno;
3695 tree->right->left->lineno = tree->lineno;
3696 decorateType (tree->right, RESULT_CHECK);
3699 /* if they are both literal then */
3700 /* rewrite the tree */
3701 if (IS_LITERAL (RTYPE (tree)) &&
3702 IS_LITERAL (LTYPE (tree)))
3704 tree->type = EX_VALUE;
3705 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3706 valFromType (RETYPE (tree)),
3708 tree->right = tree->left = NULL;
3709 TETYPE (tree) = getSpec (TTYPE (tree) =
3710 tree->opval.val->type);
3713 LRVAL (tree) = RRVAL (tree) = 1;
3714 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3717 /*------------------------------------------------------------------*/
3718 /*----------------------------*/
3720 /*----------------------------*/
3721 case SIZEOF: /* evaluate wihout code generation */
3722 /* change the type to a integer */
3724 int size = getSize (tree->right->ftype);
3725 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3726 if (!size && !IS_VOID(tree->right->ftype))
3727 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3729 tree->type = EX_VALUE;
3730 tree->opval.val = constVal (buffer);
3731 tree->right = tree->left = NULL;
3732 TETYPE (tree) = getSpec (TTYPE (tree) =
3733 tree->opval.val->type);
3736 /*------------------------------------------------------------------*/
3737 /*----------------------------*/
3739 /*----------------------------*/
3741 /* return typeof enum value */
3742 tree->type = EX_VALUE;
3745 if (IS_SPEC(tree->right->ftype)) {
3746 switch (SPEC_NOUN(tree->right->ftype)) {
3748 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3749 else typeofv = TYPEOF_INT;
3752 typeofv = TYPEOF_FLOAT;
3755 typeofv = TYPEOF_CHAR;
3758 typeofv = TYPEOF_VOID;
3761 typeofv = TYPEOF_STRUCT;
3764 typeofv = TYPEOF_BITFIELD;
3767 typeofv = TYPEOF_BIT;
3770 typeofv = TYPEOF_SBIT;
3776 switch (DCL_TYPE(tree->right->ftype)) {
3778 typeofv = TYPEOF_POINTER;
3781 typeofv = TYPEOF_FPOINTER;
3784 typeofv = TYPEOF_CPOINTER;
3787 typeofv = TYPEOF_GPOINTER;
3790 typeofv = TYPEOF_PPOINTER;
3793 typeofv = TYPEOF_IPOINTER;
3796 typeofv = TYPEOF_ARRAY;
3799 typeofv = TYPEOF_FUNCTION;
3805 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3806 tree->opval.val = constVal (buffer);
3807 tree->right = tree->left = NULL;
3808 TETYPE (tree) = getSpec (TTYPE (tree) =
3809 tree->opval.val->type);
3812 /*------------------------------------------------------------------*/
3813 /*----------------------------*/
3814 /* conditional operator '?' */
3815 /*----------------------------*/
3817 /* the type is value of the colon operator (on the right) */
3818 assert (IS_COLON_OP (tree->right));
3819 /* if already known then replace the tree : optimizer will do it
3820 but faster to do it here */
3821 if (IS_LITERAL (LTYPE (tree)))
3823 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3824 return decorateType (tree->right->left, resultTypeProp);
3826 return decorateType (tree->right->right, resultTypeProp);
3830 tree->right = decorateType (tree->right, resultTypeProp);
3831 TTYPE (tree) = RTYPE (tree);
3832 TETYPE (tree) = getSpec (TTYPE (tree));
3837 /* if they don't match we have a problem */
3838 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3840 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3841 goto errorTreeReturn;
3844 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3845 TETYPE (tree) = getSpec (TTYPE (tree));
3849 #if 0 // assignment operators are converted by the parser
3850 /*------------------------------------------------------------------*/
3851 /*----------------------------*/
3852 /* assignment operators */
3853 /*----------------------------*/
3856 /* for these it must be both must be integral */
3857 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3858 !IS_ARITHMETIC (RTYPE (tree)))
3860 werror (E_OPS_INTEGRAL);
3861 goto errorTreeReturn;
3864 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3866 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3867 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3871 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3872 goto errorTreeReturn;
3883 /* for these it must be both must be integral */
3884 if (!IS_INTEGRAL (LTYPE (tree)) ||
3885 !IS_INTEGRAL (RTYPE (tree)))
3887 werror (E_OPS_INTEGRAL);
3888 goto errorTreeReturn;
3891 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3893 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3894 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3898 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3899 goto errorTreeReturn;
3905 /*------------------------------------------------------------------*/
3906 /*----------------------------*/
3908 /*----------------------------*/
3910 if (!(IS_PTR (LTYPE (tree)) ||
3911 IS_ARITHMETIC (LTYPE (tree))))
3913 werror (E_PLUS_INVALID, "-=");
3914 goto errorTreeReturn;
3917 if (!(IS_PTR (RTYPE (tree)) ||
3918 IS_ARITHMETIC (RTYPE (tree))))
3920 werror (E_PLUS_INVALID, "-=");
3921 goto errorTreeReturn;
3924 TETYPE (tree) = getSpec (TTYPE (tree) =
3925 computeType (LTYPE (tree),
3929 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3930 werror (E_CODE_WRITE, "-=");
3934 werror (E_LVALUE_REQUIRED, "-=");
3935 goto errorTreeReturn;
3941 /*------------------------------------------------------------------*/
3942 /*----------------------------*/
3944 /*----------------------------*/
3946 /* this is not a unary operation */
3947 /* if both pointers then problem */
3948 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3950 werror (E_PTR_PLUS_PTR);
3951 goto errorTreeReturn;
3954 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3956 werror (E_PLUS_INVALID, "+=");
3957 goto errorTreeReturn;
3960 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3962 werror (E_PLUS_INVALID, "+=");
3963 goto errorTreeReturn;
3966 TETYPE (tree) = getSpec (TTYPE (tree) =
3967 computeType (LTYPE (tree),
3971 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3972 werror (E_CODE_WRITE, "+=");
3976 werror (E_LVALUE_REQUIRED, "+=");
3977 goto errorTreeReturn;
3980 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3981 tree->opval.op = '=';
3986 /*------------------------------------------------------------------*/
3987 /*----------------------------*/
3988 /* straight assignemnt */
3989 /*----------------------------*/
3991 /* cannot be an aggregate */
3992 if (IS_AGGREGATE (LTYPE (tree)))
3994 werror (E_AGGR_ASSIGN);
3995 goto errorTreeReturn;
3998 /* they should either match or be castable */
3999 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4001 werror (E_TYPE_MISMATCH, "assignment", " ");
4002 printFromToType(RTYPE(tree),LTYPE(tree));
4005 /* if the left side of the tree is of type void
4006 then report error */
4007 if (IS_VOID (LTYPE (tree)))
4009 werror (E_CAST_ZERO);
4010 printFromToType(RTYPE(tree), LTYPE(tree));
4013 TETYPE (tree) = getSpec (TTYPE (tree) =
4017 if (!tree->initMode ) {
4018 if (IS_CONSTANT(LTYPE(tree)))
4019 werror (E_CODE_WRITE, "=");
4023 werror (E_LVALUE_REQUIRED, "=");
4024 goto errorTreeReturn;
4029 /*------------------------------------------------------------------*/
4030 /*----------------------------*/
4031 /* comma operator */
4032 /*----------------------------*/
4034 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4037 /*------------------------------------------------------------------*/
4038 /*----------------------------*/
4040 /*----------------------------*/
4043 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4044 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4046 if (tree->left->opval.op == '*' && !tree->left->right)
4047 tree->left = tree->left->left;
4050 /* require a function or pointer to function */
4051 if (!IS_FUNC (LTYPE (tree))
4052 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4054 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4055 goto errorTreeReturn;
4062 if (IS_CODEPTR(LTYPE(tree)))
4063 functype = LTYPE (tree)->next;
4065 functype = LTYPE (tree);
4067 if (processParms (tree->left, FUNC_ARGS(functype),
4068 tree->right, &parmNumber, TRUE)) {
4069 goto errorTreeReturn;
4072 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4073 !IFFUNC_ISBUILTIN(functype))
4075 reverseParms (tree->right);
4078 TTYPE (tree) = functype->next;
4079 TETYPE (tree) = getSpec (TTYPE (tree));
4083 /*------------------------------------------------------------------*/
4084 /*----------------------------*/
4085 /* return statement */
4086 /*----------------------------*/
4091 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4093 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4094 printFromToType (RTYPE(tree), currFunc->type->next);
4095 goto errorTreeReturn;
4098 if (IS_VOID (currFunc->type->next)
4100 !IS_VOID (RTYPE (tree)))
4102 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4103 goto errorTreeReturn;
4106 /* if there is going to be a casting required then add it */
4107 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4110 decorateType (newNode (CAST,
4111 newAst_LINK (copyLinkChain (currFunc->type->next)),
4121 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4123 werror (W_VOID_FUNC, currFunc->name);
4124 goto errorTreeReturn;
4127 TTYPE (tree) = TETYPE (tree) = NULL;
4130 /*------------------------------------------------------------------*/
4131 /*----------------------------*/
4132 /* switch statement */
4133 /*----------------------------*/
4135 /* the switch value must be an integer */
4136 if (!IS_INTEGRAL (LTYPE (tree)))
4138 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4139 goto errorTreeReturn;
4142 TTYPE (tree) = TETYPE (tree) = NULL;
4145 /*------------------------------------------------------------------*/
4146 /*----------------------------*/
4148 /*----------------------------*/
4150 tree->left = backPatchLabels (tree->left,
4153 TTYPE (tree) = TETYPE (tree) = NULL;
4156 /*------------------------------------------------------------------*/
4157 /*----------------------------*/
4159 /*----------------------------*/
4162 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4163 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4164 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4166 /* if the for loop is reversible then
4167 reverse it otherwise do what we normally
4173 if (isLoopReversible (tree, &sym, &init, &end))
4174 return reverseLoop (tree, sym, init, end);
4176 return decorateType (createFor (AST_FOR (tree, trueLabel),
4177 AST_FOR (tree, continueLabel),
4178 AST_FOR (tree, falseLabel),
4179 AST_FOR (tree, condLabel),
4180 AST_FOR (tree, initExpr),
4181 AST_FOR (tree, condExpr),
4182 AST_FOR (tree, loopExpr),
4183 tree->left), RESULT_CHECK);
4186 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4187 "node PARAM shouldn't be processed here");
4188 /* but in processParams() */
4191 TTYPE (tree) = TETYPE (tree) = NULL;
4195 /* some error found this tree will be killed */
4197 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4198 tree->opval.op = NULLOP;
4204 /*-----------------------------------------------------------------*/
4205 /* sizeofOp - processes size of operation */
4206 /*-----------------------------------------------------------------*/
4208 sizeofOp (sym_link * type)
4213 /* make sure the type is complete and sane */
4214 checkTypeSanity(type, "(sizeof)");
4216 /* get the size and convert it to character */
4217 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4218 if (!size && !IS_VOID(type))
4219 werror (E_SIZEOF_INCOMPLETE_TYPE);
4221 /* now convert into value */
4222 return constVal (buff);
4226 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4227 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4228 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4229 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4230 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4231 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4232 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4234 /*-----------------------------------------------------------------*/
4235 /* backPatchLabels - change and or not operators to flow control */
4236 /*-----------------------------------------------------------------*/
4238 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4244 if (!(IS_ANDORNOT (tree)))
4247 /* if this an and */
4250 static int localLbl = 0;
4253 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4254 localLabel = newSymbol (buffer, NestLevel);
4256 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4258 /* if left is already a IFX then just change the if true label in that */
4259 if (!IS_IFX (tree->left))
4260 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4262 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4263 /* right is a IFX then just join */
4264 if (IS_IFX (tree->right))
4265 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4267 tree->right = createLabel (localLabel, tree->right);
4268 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4270 return newNode (NULLOP, tree->left, tree->right);
4273 /* if this is an or operation */
4276 static int localLbl = 0;
4279 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4280 localLabel = newSymbol (buffer, NestLevel);
4282 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4284 /* if left is already a IFX then just change the if true label in that */
4285 if (!IS_IFX (tree->left))
4286 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4288 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4289 /* right is a IFX then just join */
4290 if (IS_IFX (tree->right))
4291 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4293 tree->right = createLabel (localLabel, tree->right);
4294 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4296 return newNode (NULLOP, tree->left, tree->right);
4302 int wasnot = IS_NOT (tree->left);
4303 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4305 /* if the left is already a IFX */
4306 if (!IS_IFX (tree->left))
4307 tree->left = newNode (IFX, tree->left, NULL);
4311 tree->left->trueLabel = trueLabel;
4312 tree->left->falseLabel = falseLabel;
4316 tree->left->trueLabel = falseLabel;
4317 tree->left->falseLabel = trueLabel;
4324 tree->trueLabel = trueLabel;
4325 tree->falseLabel = falseLabel;
4332 /*-----------------------------------------------------------------*/
4333 /* createBlock - create expression tree for block */
4334 /*-----------------------------------------------------------------*/
4336 createBlock (symbol * decl, ast * body)
4340 /* if the block has nothing */
4344 ex = newNode (BLOCK, NULL, body);
4345 ex->values.sym = decl;
4347 ex->right = ex->right;
4353 /*-----------------------------------------------------------------*/
4354 /* createLabel - creates the expression tree for labels */
4355 /*-----------------------------------------------------------------*/
4357 createLabel (symbol * label, ast * stmnt)
4360 char name[SDCC_NAME_MAX + 1];
4363 /* must create fresh symbol if the symbol name */
4364 /* exists in the symbol table, since there can */
4365 /* be a variable with the same name as the labl */
4366 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4367 (csym->level == label->level))
4368 label = newSymbol (label->name, label->level);
4370 /* change the name before putting it in add _ */
4371 SNPRINTF(name, sizeof(name), "%s", label->name);
4373 /* put the label in the LabelSymbol table */
4374 /* but first check if a label of the same */
4376 if ((csym = findSym (LabelTab, NULL, name)))
4377 werror (E_DUPLICATE_LABEL, label->name);
4379 addSym (LabelTab, label, name, label->level, 0, 0);
4382 label->key = labelKey++;
4383 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4389 /*-----------------------------------------------------------------*/
4390 /* createCase - generates the parsetree for a case statement */
4391 /*-----------------------------------------------------------------*/
4393 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4395 char caseLbl[SDCC_NAME_MAX + 1];
4399 /* if the switch statement does not exist */
4400 /* then case is out of context */
4403 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4407 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4408 /* if not a constant then error */
4409 if (!IS_LITERAL (caseVal->ftype))
4411 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4415 /* if not a integer than error */
4416 if (!IS_INTEGRAL (caseVal->ftype))
4418 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4422 /* find the end of the switch values chain */
4423 if (!(val = swStat->values.switchVals.swVals))
4424 swStat->values.switchVals.swVals = caseVal->opval.val;
4427 /* also order the cases according to value */
4429 int cVal = (int) floatFromVal (caseVal->opval.val);
4430 while (val && (int) floatFromVal (val) < cVal)
4436 /* if we reached the end then */
4439 pval->next = caseVal->opval.val;
4441 else if ((int) floatFromVal (val) == cVal)
4443 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4449 /* we found a value greater than */
4450 /* the current value we must add this */
4451 /* before the value */
4452 caseVal->opval.val->next = val;
4454 /* if this was the first in chain */
4455 if (swStat->values.switchVals.swVals == val)
4456 swStat->values.switchVals.swVals =
4459 pval->next = caseVal->opval.val;
4464 /* create the case label */
4465 SNPRINTF(caseLbl, sizeof(caseLbl),
4467 swStat->values.switchVals.swNum,
4468 (int) floatFromVal (caseVal->opval.val));
4470 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4475 /*-----------------------------------------------------------------*/
4476 /* createDefault - creates the parse tree for the default statement */
4477 /*-----------------------------------------------------------------*/
4479 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4481 char defLbl[SDCC_NAME_MAX + 1];
4483 /* if the switch statement does not exist */
4484 /* then case is out of context */
4487 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4491 if (swStat->values.switchVals.swDefault)
4493 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4498 /* turn on the default flag */
4499 swStat->values.switchVals.swDefault = 1;
4501 /* create the label */
4502 SNPRINTF (defLbl, sizeof(defLbl),
4503 "_default_%d", swStat->values.switchVals.swNum);
4504 return createLabel (newSymbol (defLbl, 0), stmnt);
4507 /*-----------------------------------------------------------------*/
4508 /* createIf - creates the parsetree for the if statement */
4509 /*-----------------------------------------------------------------*/
4511 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4513 static int Lblnum = 0;
4515 symbol *ifTrue, *ifFalse, *ifEnd;
4517 /* if neither exists */
4518 if (!elseBody && !ifBody) {
4519 // if there are no side effects (i++, j() etc)
4520 if (!hasSEFcalls(condAst)) {
4525 /* create the labels */
4526 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4527 ifFalse = newSymbol (buffer, NestLevel);
4528 /* if no else body then end == false */
4533 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4534 ifEnd = newSymbol (buffer, NestLevel);
4537 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4538 ifTrue = newSymbol (buffer, NestLevel);
4542 /* attach the ifTrue label to the top of it body */
4543 ifBody = createLabel (ifTrue, ifBody);
4544 /* attach a goto end to the ifBody if else is present */
4547 ifBody = newNode (NULLOP, ifBody,
4549 newAst_VALUE (symbolVal (ifEnd)),
4551 /* put the elseLabel on the else body */
4552 elseBody = createLabel (ifFalse, elseBody);
4553 /* out the end at the end of the body */
4554 elseBody = newNode (NULLOP,
4556 createLabel (ifEnd, NULL));
4560 ifBody = newNode (NULLOP, ifBody,
4561 createLabel (ifFalse, NULL));
4563 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4564 if (IS_IFX (condAst))
4567 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4569 return newNode (NULLOP, ifTree,
4570 newNode (NULLOP, ifBody, elseBody));
4574 /*-----------------------------------------------------------------*/
4575 /* createDo - creates parse tree for do */
4578 /* _docontinue_n: */
4579 /* condition_expression +-> trueLabel -> _dobody_n */
4581 /* +-> falseLabel-> _dobreak_n */
4583 /*-----------------------------------------------------------------*/
4585 createDo (symbol * trueLabel, symbol * continueLabel,
4586 symbol * falseLabel, ast * condAst, ast * doBody)
4591 /* if the body does not exist then it is simple */
4594 condAst = backPatchLabels (condAst, continueLabel, NULL);
4595 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4596 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4597 doTree->trueLabel = continueLabel;
4598 doTree->falseLabel = NULL;
4602 /* otherwise we have a body */
4603 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4605 /* attach the body label to the top */
4606 doBody = createLabel (trueLabel, doBody);
4607 /* attach the continue label to end of body */
4608 doBody = newNode (NULLOP, doBody,
4609 createLabel (continueLabel, NULL));
4611 /* now put the break label at the end */
4612 if (IS_IFX (condAst))
4615 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4617 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4619 /* putting it together */
4620 return newNode (NULLOP, doBody, doTree);
4623 /*-----------------------------------------------------------------*/
4624 /* createFor - creates parse tree for 'for' statement */
4627 /* condExpr +-> trueLabel -> _forbody_n */
4629 /* +-> falseLabel-> _forbreak_n */
4632 /* _forcontinue_n: */
4634 /* goto _forcond_n ; */
4636 /*-----------------------------------------------------------------*/
4638 createFor (symbol * trueLabel, symbol * continueLabel,
4639 symbol * falseLabel, symbol * condLabel,
4640 ast * initExpr, ast * condExpr, ast * loopExpr,
4645 /* if loopexpression not present then we can generate it */
4646 /* the same way as a while */
4648 return newNode (NULLOP, initExpr,
4649 createWhile (trueLabel, continueLabel,
4650 falseLabel, condExpr, forBody));
4651 /* vanilla for statement */
4652 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4654 if (condExpr && !IS_IFX (condExpr))
4655 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4658 /* attach condition label to condition */
4659 condExpr = createLabel (condLabel, condExpr);
4661 /* attach body label to body */
4662 forBody = createLabel (trueLabel, forBody);
4664 /* attach continue to forLoop expression & attach */
4665 /* goto the forcond @ and of loopExpression */
4666 loopExpr = createLabel (continueLabel,
4670 newAst_VALUE (symbolVal (condLabel)),
4672 /* now start putting them together */
4673 forTree = newNode (NULLOP, initExpr, condExpr);
4674 forTree = newNode (NULLOP, forTree, forBody);
4675 forTree = newNode (NULLOP, forTree, loopExpr);
4676 /* finally add the break label */
4677 forTree = newNode (NULLOP, forTree,
4678 createLabel (falseLabel, NULL));
4682 /*-----------------------------------------------------------------*/
4683 /* createWhile - creates parse tree for while statement */
4684 /* the while statement will be created as follows */
4686 /* _while_continue_n: */
4687 /* condition_expression +-> trueLabel -> _while_boby_n */
4689 /* +-> falseLabel -> _while_break_n */
4690 /* _while_body_n: */
4692 /* goto _while_continue_n */
4693 /* _while_break_n: */
4694 /*-----------------------------------------------------------------*/
4696 createWhile (symbol * trueLabel, symbol * continueLabel,
4697 symbol * falseLabel, ast * condExpr, ast * whileBody)
4701 /* put the continue label */
4702 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4703 condExpr = createLabel (continueLabel, condExpr);
4704 condExpr->lineno = 0;
4706 /* put the body label in front of the body */
4707 whileBody = createLabel (trueLabel, whileBody);
4708 whileBody->lineno = 0;
4709 /* put a jump to continue at the end of the body */
4710 /* and put break label at the end of the body */
4711 whileBody = newNode (NULLOP,
4714 newAst_VALUE (symbolVal (continueLabel)),
4715 createLabel (falseLabel, NULL)));
4717 /* put it all together */
4718 if (IS_IFX (condExpr))
4719 whileTree = condExpr;
4722 whileTree = newNode (IFX, condExpr, NULL);
4723 /* put the true & false labels in place */
4724 whileTree->trueLabel = trueLabel;
4725 whileTree->falseLabel = falseLabel;
4728 return newNode (NULLOP, whileTree, whileBody);
4731 /*-----------------------------------------------------------------*/
4732 /* optimizeGetHbit - get highest order bit of the expression */
4733 /*-----------------------------------------------------------------*/
4735 optimizeGetHbit (ast * tree)
4738 /* if this is not a bit and */
4739 if (!IS_BITAND (tree))
4742 /* will look for tree of the form
4743 ( expr >> ((sizeof expr) -1) ) & 1 */
4744 if (!IS_AST_LIT_VALUE (tree->right))
4747 if (AST_LIT_VALUE (tree->right) != 1)
4750 if (!IS_RIGHT_OP (tree->left))
4753 if (!IS_AST_LIT_VALUE (tree->left->right))
4756 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4757 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4760 /* make sure the port supports GETHBIT */
4761 if (port->hasExtBitOp
4762 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4765 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4769 /*-----------------------------------------------------------------*/
4770 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4771 /*-----------------------------------------------------------------*/
4773 optimizeRRCRLC (ast * root)
4775 /* will look for trees of the form
4776 (?expr << 1) | (?expr >> 7) or
4777 (?expr >> 7) | (?expr << 1) will make that
4778 into a RLC : operation ..
4780 (?expr >> 1) | (?expr << 7) or
4781 (?expr << 7) | (?expr >> 1) will make that
4782 into a RRC operation
4783 note : by 7 I mean (number of bits required to hold the
4785 /* if the root operations is not a | operation the not */
4786 if (!IS_BITOR (root))
4789 /* I have to think of a better way to match patterns this sucks */
4790 /* that aside let start looking for the first case : I use a the
4791 negative check a lot to improve the efficiency */
4792 /* (?expr << 1) | (?expr >> 7) */
4793 if (IS_LEFT_OP (root->left) &&
4794 IS_RIGHT_OP (root->right))
4797 if (!SPEC_USIGN (TETYPE (root->left->left)))
4800 if (!IS_AST_LIT_VALUE (root->left->right) ||
4801 !IS_AST_LIT_VALUE (root->right->right))
4804 /* make sure it is the same expression */
4805 if (!isAstEqual (root->left->left,
4809 if (AST_LIT_VALUE (root->left->right) != 1)
4812 if (AST_LIT_VALUE (root->right->right) !=
4813 (getSize (TTYPE (root->left->left)) * 8 - 1))
4816 /* make sure the port supports RLC */
4817 if (port->hasExtBitOp
4818 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4821 /* whew got the first case : create the AST */
4822 return newNode (RLC, root->left->left, NULL);
4826 /* check for second case */
4827 /* (?expr >> 7) | (?expr << 1) */
4828 if (IS_LEFT_OP (root->right) &&
4829 IS_RIGHT_OP (root->left))
4832 if (!SPEC_USIGN (TETYPE (root->left->left)))
4835 if (!IS_AST_LIT_VALUE (root->left->right) ||
4836 !IS_AST_LIT_VALUE (root->right->right))
4839 /* make sure it is the same symbol */
4840 if (!isAstEqual (root->left->left,
4844 if (AST_LIT_VALUE (root->right->right) != 1)
4847 if (AST_LIT_VALUE (root->left->right) !=
4848 (getSize (TTYPE (root->left->left)) * 8 - 1))
4851 /* make sure the port supports RLC */
4852 if (port->hasExtBitOp
4853 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4856 /* whew got the first case : create the AST */
4857 return newNode (RLC, root->left->left, NULL);
4862 /* third case for RRC */
4863 /* (?symbol >> 1) | (?symbol << 7) */
4864 if (IS_LEFT_OP (root->right) &&
4865 IS_RIGHT_OP (root->left))
4868 if (!SPEC_USIGN (TETYPE (root->left->left)))
4871 if (!IS_AST_LIT_VALUE (root->left->right) ||
4872 !IS_AST_LIT_VALUE (root->right->right))
4875 /* make sure it is the same symbol */
4876 if (!isAstEqual (root->left->left,
4880 if (AST_LIT_VALUE (root->left->right) != 1)
4883 if (AST_LIT_VALUE (root->right->right) !=
4884 (getSize (TTYPE (root->left->left)) * 8 - 1))
4887 /* make sure the port supports RRC */
4888 if (port->hasExtBitOp
4889 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4892 /* whew got the first case : create the AST */
4893 return newNode (RRC, root->left->left, NULL);
4897 /* fourth and last case for now */
4898 /* (?symbol << 7) | (?symbol >> 1) */
4899 if (IS_RIGHT_OP (root->right) &&
4900 IS_LEFT_OP (root->left))
4903 if (!SPEC_USIGN (TETYPE (root->left->left)))
4906 if (!IS_AST_LIT_VALUE (root->left->right) ||
4907 !IS_AST_LIT_VALUE (root->right->right))
4910 /* make sure it is the same symbol */
4911 if (!isAstEqual (root->left->left,
4915 if (AST_LIT_VALUE (root->right->right) != 1)
4918 if (AST_LIT_VALUE (root->left->right) !=
4919 (getSize (TTYPE (root->left->left)) * 8 - 1))
4922 /* make sure the port supports RRC */
4923 if (port->hasExtBitOp
4924 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4927 /* whew got the first case : create the AST */
4928 return newNode (RRC, root->left->left, NULL);
4932 /* not found return root */
4936 /*-----------------------------------------------------------------*/
4937 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4938 /*-----------------------------------------------------------------*/
4940 optimizeSWAP (ast * root)
4942 /* will look for trees of the form
4943 (?expr << 4) | (?expr >> 4) or
4944 (?expr >> 4) | (?expr << 4) will make that
4945 into a SWAP : operation ..
4946 note : by 4 I mean (number of bits required to hold the
4948 /* if the root operations is not a | operation the not */
4949 if (!IS_BITOR (root))
4952 /* (?expr << 4) | (?expr >> 4) */
4953 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4954 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4957 if (!SPEC_USIGN (TETYPE (root->left->left)))
4960 if (!IS_AST_LIT_VALUE (root->left->right) ||
4961 !IS_AST_LIT_VALUE (root->right->right))
4964 /* make sure it is the same expression */
4965 if (!isAstEqual (root->left->left,
4969 if (AST_LIT_VALUE (root->left->right) !=
4970 (getSize (TTYPE (root->left->left)) * 4))
4973 if (AST_LIT_VALUE (root->right->right) !=
4974 (getSize (TTYPE (root->left->left)) * 4))
4977 /* make sure the port supports SWAP */
4978 if (port->hasExtBitOp
4979 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4982 /* found it : create the AST */
4983 return newNode (SWAP, root->left->left, NULL);
4987 /* not found return root */
4991 /*-----------------------------------------------------------------*/
4992 /* optimizeCompare - otimizes compares for bit variables */
4993 /*-----------------------------------------------------------------*/
4995 optimizeCompare (ast * root)
4997 ast *optExpr = NULL;
5000 unsigned int litValue;
5002 /* if nothing then return nothing */
5006 /* if not a compare op then do leaves */
5007 if (!IS_COMPARE_OP (root))
5009 root->left = optimizeCompare (root->left);
5010 root->right = optimizeCompare (root->right);
5014 /* if left & right are the same then depending
5015 of the operation do */
5016 if (isAstEqual (root->left, root->right))
5018 switch (root->opval.op)
5023 optExpr = newAst_VALUE (constVal ("0"));
5028 optExpr = newAst_VALUE (constVal ("1"));
5032 return decorateType (optExpr, RESULT_CHECK);
5035 vleft = (root->left->type == EX_VALUE ?
5036 root->left->opval.val : NULL);
5038 vright = (root->right->type == EX_VALUE ?
5039 root->right->opval.val : NULL);
5041 /* if left is a BITVAR in BITSPACE */
5042 /* and right is a LITERAL then opt- */
5043 /* imize else do nothing */
5044 if (vleft && vright &&
5045 IS_BITVAR (vleft->etype) &&
5046 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5047 IS_LITERAL (vright->etype))
5050 /* if right side > 1 then comparison may never succeed */
5051 if ((litValue = (int) floatFromVal (vright)) > 1)
5053 werror (W_BAD_COMPARE);
5059 switch (root->opval.op)
5061 case '>': /* bit value greater than 1 cannot be */
5062 werror (W_BAD_COMPARE);
5066 case '<': /* bit value < 1 means 0 */
5068 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5071 case LE_OP: /* bit value <= 1 means no check */
5072 optExpr = newAst_VALUE (vright);
5075 case GE_OP: /* bit value >= 1 means only check for = */
5077 optExpr = newAst_VALUE (vleft);
5082 { /* literal is zero */
5083 switch (root->opval.op)
5085 case '<': /* bit value < 0 cannot be */
5086 werror (W_BAD_COMPARE);
5090 case '>': /* bit value > 0 means 1 */
5092 optExpr = newAst_VALUE (vleft);
5095 case LE_OP: /* bit value <= 0 means no check */
5096 case GE_OP: /* bit value >= 0 means no check */
5097 werror (W_BAD_COMPARE);
5101 case EQ_OP: /* bit == 0 means ! of bit */
5102 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5106 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5107 } /* end-of-if of BITVAR */
5112 /*-----------------------------------------------------------------*/
5113 /* addSymToBlock : adds the symbol to the first block we find */
5114 /*-----------------------------------------------------------------*/
5116 addSymToBlock (symbol * sym, ast * tree)
5118 /* reached end of tree or a leaf */
5119 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5123 if (IS_AST_OP (tree) &&
5124 tree->opval.op == BLOCK)
5127 symbol *lsym = copySymbol (sym);
5129 lsym->next = AST_VALUES (tree, sym);
5130 AST_VALUES (tree, sym) = lsym;
5134 addSymToBlock (sym, tree->left);
5135 addSymToBlock (sym, tree->right);
5138 /*-----------------------------------------------------------------*/
5139 /* processRegParms - do processing for register parameters */
5140 /*-----------------------------------------------------------------*/
5142 processRegParms (value * args, ast * body)
5146 if (IS_REGPARM (args->etype))
5147 addSymToBlock (args->sym, body);
5152 /*-----------------------------------------------------------------*/
5153 /* resetParmKey - resets the operandkeys for the symbols */
5154 /*-----------------------------------------------------------------*/
5155 DEFSETFUNC (resetParmKey)
5166 /*-----------------------------------------------------------------*/
5167 /* createFunction - This is the key node that calls the iCode for */
5168 /* generating the code for a function. Note code */
5169 /* is generated function by function, later when */
5170 /* add inter-procedural analysis this will change */
5171 /*-----------------------------------------------------------------*/
5173 createFunction (symbol * name, ast * body)
5179 iCode *piCode = NULL;
5181 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5182 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5184 /* if check function return 0 then some problem */
5185 if (checkFunction (name, NULL) == 0)
5188 /* create a dummy block if none exists */
5190 body = newNode (BLOCK, NULL, NULL);
5194 /* check if the function name already in the symbol table */
5195 if ((csym = findSym (SymbolTab, NULL, name->name)))
5198 /* special case for compiler defined functions
5199 we need to add the name to the publics list : this
5200 actually means we are now compiling the compiler
5204 addSet (&publics, name);
5210 allocVariables (name);
5212 name->lastLine = mylineno;
5215 /* set the stack pointer */
5216 /* PENDING: check this for the mcs51 */
5217 stackPtr = -port->stack.direction * port->stack.call_overhead;
5218 if (IFFUNC_ISISR (name->type))
5219 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5220 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5221 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5223 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5225 fetype = getSpec (name->type); /* get the specifier for the function */
5226 /* if this is a reentrant function then */
5227 if (IFFUNC_ISREENT (name->type))
5230 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5232 /* do processing for parameters that are passed in registers */
5233 processRegParms (FUNC_ARGS(name->type), body);
5235 /* set the stack pointer */
5239 /* allocate & autoinit the block variables */
5240 processBlockVars (body, &stack, ALLOCATE);
5242 /* save the stack information */
5243 if (options.useXstack)
5244 name->xstack = SPEC_STAK (fetype) = stack;
5246 name->stack = SPEC_STAK (fetype) = stack;
5248 /* name needs to be mangled */
5249 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5251 body = resolveSymbols (body); /* resolve the symbols */
5252 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5255 ex = newAst_VALUE (symbolVal (name)); /* create name */
5256 ex = newNode (FUNCTION, ex, body);
5257 ex->values.args = FUNC_ARGS(name->type);
5259 if (options.dump_tree) PA(ex);
5262 werror (E_FUNC_NO_CODE, name->name);
5266 /* create the node & generate intermediate code */
5268 codeOutFile = code->oFile;
5269 piCode = iCodeFromAst (ex);
5273 werror (E_FUNC_NO_CODE, name->name);
5277 eBBlockFromiCode (piCode);
5279 /* if there are any statics then do them */
5282 GcurMemmap = statsg;
5283 codeOutFile = statsg->oFile;
5284 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5290 /* dealloc the block variables */
5291 processBlockVars (body, &stack, DEALLOCATE);
5292 outputDebugStackSymbols();
5293 /* deallocate paramaters */
5294 deallocParms (FUNC_ARGS(name->type));
5296 if (IFFUNC_ISREENT (name->type))
5299 /* we are done freeup memory & cleanup */
5301 if (port->reset_labelKey) labelKey = 1;
5303 FUNC_HASBODY(name->type) = 1;
5304 addSet (&operKeyReset, name);
5305 applyToSet (operKeyReset, resetParmKey);
5310 cleanUpLevel (LabelTab, 0);
5311 cleanUpBlock (StructTab, 1);
5312 cleanUpBlock (TypedefTab, 1);
5314 xstack->syms = NULL;
5315 istack->syms = NULL;
5320 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5321 /*-----------------------------------------------------------------*/
5322 /* ast_print : prints the ast (for debugging purposes) */
5323 /*-----------------------------------------------------------------*/
5325 void ast_print (ast * tree, FILE *outfile, int indent)
5330 /* can print only decorated trees */
5331 if (!tree->decorated) return;
5333 /* if any child is an error | this one is an error do nothing */
5334 if (tree->isError ||
5335 (tree->left && tree->left->isError) ||
5336 (tree->right && tree->right->isError)) {
5337 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5341 /* print the line */
5342 /* if not block & function */
5343 if (tree->type == EX_OP &&
5344 (tree->opval.op != FUNCTION &&
5345 tree->opval.op != BLOCK &&
5346 tree->opval.op != NULLOP)) {
5349 if (tree->opval.op == FUNCTION) {
5351 value *args=FUNC_ARGS(tree->left->opval.val->type);
5352 fprintf(outfile,"FUNCTION (%s=%p) type (",
5353 tree->left->opval.val->name, tree);
5354 printTypeChain (tree->left->opval.val->type->next,outfile);
5355 fprintf(outfile,") args (");
5358 fprintf (outfile, ", ");
5360 printTypeChain (args ? args->type : NULL, outfile);
5362 args= args ? args->next : NULL;
5364 fprintf(outfile,")\n");
5365 ast_print(tree->left,outfile,indent);
5366 ast_print(tree->right,outfile,indent);
5369 if (tree->opval.op == BLOCK) {
5370 symbol *decls = tree->values.sym;
5371 INDENT(indent,outfile);
5372 fprintf(outfile,"{\n");
5374 INDENT(indent+2,outfile);
5375 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5376 decls->name, decls);
5377 printTypeChain(decls->type,outfile);
5378 fprintf(outfile,")\n");
5380 decls = decls->next;
5382 ast_print(tree->right,outfile,indent+2);
5383 INDENT(indent,outfile);
5384 fprintf(outfile,"}\n");
5387 if (tree->opval.op == NULLOP) {
5388 ast_print(tree->left,outfile,indent);
5389 ast_print(tree->right,outfile,indent);
5392 INDENT(indent,outfile);
5394 /*------------------------------------------------------------------*/
5395 /*----------------------------*/
5396 /* leaf has been reached */
5397 /*----------------------------*/
5398 /* if this is of type value */
5399 /* just get the type */
5400 if (tree->type == EX_VALUE) {
5402 if (IS_LITERAL (tree->opval.val->etype)) {
5403 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5404 if (SPEC_USIGN (tree->opval.val->etype))
5405 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5407 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5408 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5409 floatFromVal(tree->opval.val));
5410 } else if (tree->opval.val->sym) {
5411 /* if the undefined flag is set then give error message */
5412 if (tree->opval.val->sym->undefined) {
5413 fprintf(outfile,"UNDEFINED SYMBOL ");
5415 fprintf(outfile,"SYMBOL ");
5417 fprintf(outfile,"(%s=%p)",
5418 tree->opval.val->sym->name,tree);
5421 fprintf(outfile," type (");
5422 printTypeChain(tree->ftype,outfile);
5423 fprintf(outfile,")\n");
5425 fprintf(outfile,"\n");
5430 /* if type link for the case of cast */
5431 if (tree->type == EX_LINK) {
5432 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5433 printTypeChain(tree->opval.lnk,outfile);
5434 fprintf(outfile,")\n");
5439 /* depending on type of operator do */
5441 switch (tree->opval.op) {
5442 /*------------------------------------------------------------------*/
5443 /*----------------------------*/
5445 /*----------------------------*/
5447 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5448 printTypeChain(tree->ftype,outfile);
5449 fprintf(outfile,")\n");
5450 ast_print(tree->left,outfile,indent+2);
5451 ast_print(tree->right,outfile,indent+2);
5454 /*------------------------------------------------------------------*/
5455 /*----------------------------*/
5457 /*----------------------------*/
5459 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5460 printTypeChain(tree->ftype,outfile);
5461 fprintf(outfile,")\n");
5462 ast_print(tree->left,outfile,indent+2);
5463 ast_print(tree->right,outfile,indent+2);
5466 /*------------------------------------------------------------------*/
5467 /*----------------------------*/
5468 /* struct/union pointer */
5469 /*----------------------------*/
5471 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5472 printTypeChain(tree->ftype,outfile);
5473 fprintf(outfile,")\n");
5474 ast_print(tree->left,outfile,indent+2);
5475 ast_print(tree->right,outfile,indent+2);
5478 /*------------------------------------------------------------------*/
5479 /*----------------------------*/
5480 /* ++/-- operation */
5481 /*----------------------------*/
5484 fprintf(outfile,"post-");
5486 fprintf(outfile,"pre-");
5487 fprintf(outfile,"INC_OP (%p) type (",tree);
5488 printTypeChain(tree->ftype,outfile);
5489 fprintf(outfile,")\n");
5490 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5491 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5496 fprintf(outfile,"post-");
5498 fprintf(outfile,"pre-");
5499 fprintf(outfile,"DEC_OP (%p) type (",tree);
5500 printTypeChain(tree->ftype,outfile);
5501 fprintf(outfile,")\n");
5502 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5503 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5506 /*------------------------------------------------------------------*/
5507 /*----------------------------*/
5509 /*----------------------------*/
5512 fprintf(outfile,"& (%p) type (",tree);
5513 printTypeChain(tree->ftype,outfile);
5514 fprintf(outfile,")\n");
5515 ast_print(tree->left,outfile,indent+2);
5516 ast_print(tree->right,outfile,indent+2);
5518 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5519 printTypeChain(tree->ftype,outfile);
5520 fprintf(outfile,")\n");
5521 ast_print(tree->left,outfile,indent+2);
5522 ast_print(tree->right,outfile,indent+2);
5525 /*----------------------------*/
5527 /*----------------------------*/
5529 fprintf(outfile,"OR (%p) type (",tree);
5530 printTypeChain(tree->ftype,outfile);
5531 fprintf(outfile,")\n");
5532 ast_print(tree->left,outfile,indent+2);
5533 ast_print(tree->right,outfile,indent+2);
5535 /*------------------------------------------------------------------*/
5536 /*----------------------------*/
5538 /*----------------------------*/
5540 fprintf(outfile,"XOR (%p) type (",tree);
5541 printTypeChain(tree->ftype,outfile);
5542 fprintf(outfile,")\n");
5543 ast_print(tree->left,outfile,indent+2);
5544 ast_print(tree->right,outfile,indent+2);
5547 /*------------------------------------------------------------------*/
5548 /*----------------------------*/
5550 /*----------------------------*/
5552 fprintf(outfile,"DIV (%p) type (",tree);
5553 printTypeChain(tree->ftype,outfile);
5554 fprintf(outfile,")\n");
5555 ast_print(tree->left,outfile,indent+2);
5556 ast_print(tree->right,outfile,indent+2);
5558 /*------------------------------------------------------------------*/
5559 /*----------------------------*/
5561 /*----------------------------*/
5563 fprintf(outfile,"MOD (%p) type (",tree);
5564 printTypeChain(tree->ftype,outfile);
5565 fprintf(outfile,")\n");
5566 ast_print(tree->left,outfile,indent+2);
5567 ast_print(tree->right,outfile,indent+2);
5570 /*------------------------------------------------------------------*/
5571 /*----------------------------*/
5572 /* address dereference */
5573 /*----------------------------*/
5574 case '*': /* can be unary : if right is null then unary operation */
5576 fprintf(outfile,"DEREF (%p) type (",tree);
5577 printTypeChain(tree->ftype,outfile);
5578 fprintf(outfile,")\n");
5579 ast_print(tree->left,outfile,indent+2);
5582 /*------------------------------------------------------------------*/
5583 /*----------------------------*/
5584 /* multiplication */
5585 /*----------------------------*/
5586 fprintf(outfile,"MULT (%p) type (",tree);
5587 printTypeChain(tree->ftype,outfile);
5588 fprintf(outfile,")\n");
5589 ast_print(tree->left,outfile,indent+2);
5590 ast_print(tree->right,outfile,indent+2);
5594 /*------------------------------------------------------------------*/
5595 /*----------------------------*/
5596 /* unary '+' operator */
5597 /*----------------------------*/
5601 fprintf(outfile,"UPLUS (%p) type (",tree);
5602 printTypeChain(tree->ftype,outfile);
5603 fprintf(outfile,")\n");
5604 ast_print(tree->left,outfile,indent+2);
5606 /*------------------------------------------------------------------*/
5607 /*----------------------------*/
5609 /*----------------------------*/
5610 fprintf(outfile,"ADD (%p) type (",tree);
5611 printTypeChain(tree->ftype,outfile);
5612 fprintf(outfile,")\n");
5613 ast_print(tree->left,outfile,indent+2);
5614 ast_print(tree->right,outfile,indent+2);
5617 /*------------------------------------------------------------------*/
5618 /*----------------------------*/
5620 /*----------------------------*/
5621 case '-': /* can be unary */
5623 fprintf(outfile,"UMINUS (%p) type (",tree);
5624 printTypeChain(tree->ftype,outfile);
5625 fprintf(outfile,")\n");
5626 ast_print(tree->left,outfile,indent+2);
5628 /*------------------------------------------------------------------*/
5629 /*----------------------------*/
5631 /*----------------------------*/
5632 fprintf(outfile,"SUB (%p) type (",tree);
5633 printTypeChain(tree->ftype,outfile);
5634 fprintf(outfile,")\n");
5635 ast_print(tree->left,outfile,indent+2);
5636 ast_print(tree->right,outfile,indent+2);
5639 /*------------------------------------------------------------------*/
5640 /*----------------------------*/
5642 /*----------------------------*/
5644 fprintf(outfile,"COMPL (%p) type (",tree);
5645 printTypeChain(tree->ftype,outfile);
5646 fprintf(outfile,")\n");
5647 ast_print(tree->left,outfile,indent+2);
5649 /*------------------------------------------------------------------*/
5650 /*----------------------------*/
5652 /*----------------------------*/
5654 fprintf(outfile,"NOT (%p) type (",tree);
5655 printTypeChain(tree->ftype,outfile);
5656 fprintf(outfile,")\n");
5657 ast_print(tree->left,outfile,indent+2);
5659 /*------------------------------------------------------------------*/
5660 /*----------------------------*/
5662 /*----------------------------*/
5664 fprintf(outfile,"RRC (%p) type (",tree);
5665 printTypeChain(tree->ftype,outfile);
5666 fprintf(outfile,")\n");
5667 ast_print(tree->left,outfile,indent+2);
5671 fprintf(outfile,"RLC (%p) type (",tree);
5672 printTypeChain(tree->ftype,outfile);
5673 fprintf(outfile,")\n");
5674 ast_print(tree->left,outfile,indent+2);
5677 fprintf(outfile,"SWAP (%p) type (",tree);
5678 printTypeChain(tree->ftype,outfile);
5679 fprintf(outfile,")\n");
5680 ast_print(tree->left,outfile,indent+2);
5683 fprintf(outfile,"GETHBIT (%p) type (",tree);
5684 printTypeChain(tree->ftype,outfile);
5685 fprintf(outfile,")\n");
5686 ast_print(tree->left,outfile,indent+2);
5689 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5690 printTypeChain(tree->ftype,outfile);
5691 fprintf(outfile,")\n");
5692 ast_print(tree->left,outfile,indent+2);
5693 ast_print(tree->right,outfile,indent+2);
5696 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5697 printTypeChain(tree->ftype,outfile);
5698 fprintf(outfile,")\n");
5699 ast_print(tree->left,outfile,indent+2);
5700 ast_print(tree->right,outfile,indent+2);
5702 /*------------------------------------------------------------------*/
5703 /*----------------------------*/
5705 /*----------------------------*/
5706 case CAST: /* change the type */
5707 fprintf(outfile,"CAST (%p) from type (",tree);
5708 printTypeChain(tree->right->ftype,outfile);
5709 fprintf(outfile,") to type (");
5710 printTypeChain(tree->ftype,outfile);
5711 fprintf(outfile,")\n");
5712 ast_print(tree->right,outfile,indent+2);
5716 fprintf(outfile,"ANDAND (%p) type (",tree);
5717 printTypeChain(tree->ftype,outfile);
5718 fprintf(outfile,")\n");
5719 ast_print(tree->left,outfile,indent+2);
5720 ast_print(tree->right,outfile,indent+2);
5723 fprintf(outfile,"OROR (%p) type (",tree);
5724 printTypeChain(tree->ftype,outfile);
5725 fprintf(outfile,")\n");
5726 ast_print(tree->left,outfile,indent+2);
5727 ast_print(tree->right,outfile,indent+2);
5730 /*------------------------------------------------------------------*/
5731 /*----------------------------*/
5732 /* comparison operators */
5733 /*----------------------------*/
5735 fprintf(outfile,"GT(>) (%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,"LT(<) (%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 fprintf(outfile,"LE(<=) (%p) type (",tree);
5750 printTypeChain(tree->ftype,outfile);
5751 fprintf(outfile,")\n");
5752 ast_print(tree->left,outfile,indent+2);
5753 ast_print(tree->right,outfile,indent+2);
5756 fprintf(outfile,"GE(>=) (%p) type (",tree);
5757 printTypeChain(tree->ftype,outfile);
5758 fprintf(outfile,")\n");
5759 ast_print(tree->left,outfile,indent+2);
5760 ast_print(tree->right,outfile,indent+2);
5763 fprintf(outfile,"EQ(==) (%p) type (",tree);
5764 printTypeChain(tree->ftype,outfile);
5765 fprintf(outfile,")\n");
5766 ast_print(tree->left,outfile,indent+2);
5767 ast_print(tree->right,outfile,indent+2);
5770 fprintf(outfile,"NE(!=) (%p) type (",tree);
5771 printTypeChain(tree->ftype,outfile);
5772 fprintf(outfile,")\n");
5773 ast_print(tree->left,outfile,indent+2);
5774 ast_print(tree->right,outfile,indent+2);
5775 /*------------------------------------------------------------------*/
5776 /*----------------------------*/
5778 /*----------------------------*/
5779 case SIZEOF: /* evaluate wihout code generation */
5780 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5783 /*------------------------------------------------------------------*/
5784 /*----------------------------*/
5785 /* conditional operator '?' */
5786 /*----------------------------*/
5788 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5789 printTypeChain(tree->ftype,outfile);
5790 fprintf(outfile,")\n");
5791 ast_print(tree->left,outfile,indent+2);
5792 ast_print(tree->right,outfile,indent+2);
5796 fprintf(outfile,"COLON(:) (%p) type (",tree);
5797 printTypeChain(tree->ftype,outfile);
5798 fprintf(outfile,")\n");
5799 ast_print(tree->left,outfile,indent+2);
5800 ast_print(tree->right,outfile,indent+2);
5803 /*------------------------------------------------------------------*/
5804 /*----------------------------*/
5805 /* assignment operators */
5806 /*----------------------------*/
5808 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5809 printTypeChain(tree->ftype,outfile);
5810 fprintf(outfile,")\n");
5811 ast_print(tree->left,outfile,indent+2);
5812 ast_print(tree->right,outfile,indent+2);
5815 fprintf(outfile,"DIVASS(/=) (%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 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5823 printTypeChain(tree->ftype,outfile);
5824 fprintf(outfile,")\n");
5825 ast_print(tree->left,outfile,indent+2);
5826 ast_print(tree->right,outfile,indent+2);
5829 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5830 printTypeChain(tree->ftype,outfile);
5831 fprintf(outfile,")\n");
5832 ast_print(tree->left,outfile,indent+2);
5833 ast_print(tree->right,outfile,indent+2);
5836 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5837 printTypeChain(tree->ftype,outfile);
5838 fprintf(outfile,")\n");
5839 ast_print(tree->left,outfile,indent+2);
5840 ast_print(tree->right,outfile,indent+2);
5843 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5844 printTypeChain(tree->ftype,outfile);
5845 fprintf(outfile,")\n");
5846 ast_print(tree->left,outfile,indent+2);
5847 ast_print(tree->right,outfile,indent+2);
5850 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5851 printTypeChain(tree->ftype,outfile);
5852 fprintf(outfile,")\n");
5853 ast_print(tree->left,outfile,indent+2);
5854 ast_print(tree->right,outfile,indent+2);
5856 /*------------------------------------------------------------------*/
5857 /*----------------------------*/
5859 /*----------------------------*/
5861 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5862 printTypeChain(tree->ftype,outfile);
5863 fprintf(outfile,")\n");
5864 ast_print(tree->left,outfile,indent+2);
5865 ast_print(tree->right,outfile,indent+2);
5867 /*------------------------------------------------------------------*/
5868 /*----------------------------*/
5870 /*----------------------------*/
5872 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5873 printTypeChain(tree->ftype,outfile);
5874 fprintf(outfile,")\n");
5875 ast_print(tree->left,outfile,indent+2);
5876 ast_print(tree->right,outfile,indent+2);
5878 /*------------------------------------------------------------------*/
5879 /*----------------------------*/
5880 /* straight assignemnt */
5881 /*----------------------------*/
5883 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5884 printTypeChain(tree->ftype,outfile);
5885 fprintf(outfile,")\n");
5886 ast_print(tree->left,outfile,indent+2);
5887 ast_print(tree->right,outfile,indent+2);
5889 /*------------------------------------------------------------------*/
5890 /*----------------------------*/
5891 /* comma operator */
5892 /*----------------------------*/
5894 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5895 printTypeChain(tree->ftype,outfile);
5896 fprintf(outfile,")\n");
5897 ast_print(tree->left,outfile,indent+2);
5898 ast_print(tree->right,outfile,indent+2);
5900 /*------------------------------------------------------------------*/
5901 /*----------------------------*/
5903 /*----------------------------*/
5906 fprintf(outfile,"CALL (%p) type (",tree);
5907 printTypeChain(tree->ftype,outfile);
5908 fprintf(outfile,")\n");
5909 ast_print(tree->left,outfile,indent+2);
5910 ast_print(tree->right,outfile,indent+2);
5913 fprintf(outfile,"PARMS\n");
5914 ast_print(tree->left,outfile,indent+2);
5915 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5916 ast_print(tree->right,outfile,indent+2);
5919 /*------------------------------------------------------------------*/
5920 /*----------------------------*/
5921 /* return statement */
5922 /*----------------------------*/
5924 fprintf(outfile,"RETURN (%p) type (",tree);
5926 printTypeChain(tree->right->ftype,outfile);
5928 fprintf(outfile,")\n");
5929 ast_print(tree->right,outfile,indent+2);
5931 /*------------------------------------------------------------------*/
5932 /*----------------------------*/
5933 /* label statement */
5934 /*----------------------------*/
5936 fprintf(outfile,"LABEL (%p)\n",tree);
5937 ast_print(tree->left,outfile,indent+2);
5938 ast_print(tree->right,outfile,indent);
5940 /*------------------------------------------------------------------*/
5941 /*----------------------------*/
5942 /* switch statement */
5943 /*----------------------------*/
5947 fprintf(outfile,"SWITCH (%p) ",tree);
5948 ast_print(tree->left,outfile,0);
5949 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5950 INDENT(indent+2,outfile);
5951 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5952 (int) floatFromVal(val),
5953 tree->values.switchVals.swNum,
5954 (int) floatFromVal(val));
5956 ast_print(tree->right,outfile,indent);
5959 /*------------------------------------------------------------------*/
5960 /*----------------------------*/
5962 /*----------------------------*/
5964 fprintf(outfile,"IF (%p) \n",tree);
5965 ast_print(tree->left,outfile,indent+2);
5966 if (tree->trueLabel) {
5967 INDENT(indent+2,outfile);
5968 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5970 if (tree->falseLabel) {
5971 INDENT(indent+2,outfile);
5972 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5974 ast_print(tree->right,outfile,indent+2);
5976 /*----------------------------*/
5977 /* goto Statement */
5978 /*----------------------------*/
5980 fprintf(outfile,"GOTO (%p) \n",tree);
5981 ast_print(tree->left,outfile,indent+2);
5982 fprintf(outfile,"\n");
5984 /*------------------------------------------------------------------*/
5985 /*----------------------------*/
5987 /*----------------------------*/
5989 fprintf(outfile,"FOR (%p) \n",tree);
5990 if (AST_FOR( tree, initExpr)) {
5991 INDENT(indent+2,outfile);
5992 fprintf(outfile,"INIT EXPR ");
5993 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5995 if (AST_FOR( tree, condExpr)) {
5996 INDENT(indent+2,outfile);
5997 fprintf(outfile,"COND EXPR ");
5998 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6000 if (AST_FOR( tree, loopExpr)) {
6001 INDENT(indent+2,outfile);
6002 fprintf(outfile,"LOOP EXPR ");
6003 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6005 fprintf(outfile,"FOR LOOP BODY \n");
6006 ast_print(tree->left,outfile,indent+2);
6009 fprintf(outfile,"CRITICAL (%p) \n",tree);
6010 ast_print(tree->left,outfile,indent+2);
6018 ast_print(t,stdout,0);
6023 /*-----------------------------------------------------------------*/
6024 /* astErrors : returns non-zero if errors present in tree */
6025 /*-----------------------------------------------------------------*/
6026 int astErrors(ast *t)
6035 if (t->type == EX_VALUE
6036 && t->opval.val->sym
6037 && t->opval.val->sym->undefined)
6040 errors += astErrors(t->left);
6041 errors += astErrors(t->right);