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); */
2023 return RESULT_TYPE_BIT;
2024 if (IS_BITFIELD (type))
2026 int blen = SPEC_BLEN (type);
2029 return RESULT_TYPE_BIT;
2031 return RESULT_TYPE_CHAR;
2032 return RESULT_TYPE_INT;
2035 return RESULT_TYPE_CHAR;
2038 return RESULT_TYPE_INT;
2039 return RESULT_TYPE_OTHER;
2042 /*-----------------------------------------------------------------*/
2043 /* addCast - adds casts to a type specified by RESULT_TYPE */
2044 /*-----------------------------------------------------------------*/
2046 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2049 bool upCasted = FALSE;
2053 case RESULT_TYPE_NONE:
2054 /* char: promote to int */
2056 getSize (tree->etype) >= INTSIZE)
2058 newLink = newIntLink();
2061 case RESULT_TYPE_CHAR:
2062 if (IS_CHAR (tree->etype))
2064 newLink = newCharLink();
2066 case RESULT_TYPE_INT:
2068 if (getSize (tree->etype) > INTSIZE)
2070 /* warn ("Loosing significant digits"); */
2074 /* char: promote to int */
2076 getSize (tree->etype) >= INTSIZE)
2078 newLink = newIntLink();
2081 case RESULT_TYPE_OTHER:
2084 /* return type is long, float: promote char to int */
2085 if (getSize (tree->etype) >= INTSIZE)
2087 newLink = newIntLink();
2093 tree->decorated = 0;
2094 tree = newNode (CAST, newAst_LINK (newLink), tree);
2095 tree->lineno = tree->right->lineno;
2096 /* keep unsigned type during cast to smaller type,
2097 but not when promoting from char to int */
2099 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2100 return decorateType (tree, resultType);
2103 /*-----------------------------------------------------------------*/
2104 /* resultTypePropagate - decides if resultType can be propagated */
2105 /*-----------------------------------------------------------------*/
2107 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2109 switch (tree->opval.op)
2124 return RESULT_TYPE_NONE;
2128 return RESULT_TYPE_IFX;
2130 return RESULT_TYPE_NONE;
2134 /*-----------------------------------------------------------------*/
2135 /* getLeftResultType - gets type from left branch for propagation */
2136 /*-----------------------------------------------------------------*/
2138 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2140 switch (tree->opval.op)
2144 if (IS_PTR (LTYPE (tree)))
2145 return RESULT_TYPE_NONE;
2147 return getResultTypeFromType (LETYPE (tree));
2149 if (IS_PTR (currFunc->type->next))
2150 return RESULT_TYPE_NONE;
2152 return getResultTypeFromType (currFunc->type->next);
2154 if (!IS_ARRAY (LTYPE (tree)))
2156 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2157 return RESULT_TYPE_CHAR;
2164 /*--------------------------------------------------------------------*/
2165 /* decorateType - compute type for this tree, also does type checking.*/
2166 /* This is done bottom up, since type has to flow upwards. */
2167 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2168 /* result is a char and the operand(s) are int's. */
2169 /* It also does constant folding, and parameter checking. */
2170 /*--------------------------------------------------------------------*/
2172 decorateType (ast * tree, RESULT_TYPE resultType)
2176 RESULT_TYPE resultTypeProp;
2181 /* if already has type then do nothing */
2182 if (tree->decorated)
2185 tree->decorated = 1;
2188 /* print the line */
2189 /* if not block & function */
2190 if (tree->type == EX_OP &&
2191 (tree->opval.op != FUNCTION &&
2192 tree->opval.op != BLOCK &&
2193 tree->opval.op != NULLOP))
2195 filename = tree->filename;
2196 lineno = tree->lineno;
2200 /* if any child is an error | this one is an error do nothing */
2201 if (tree->isError ||
2202 (tree->left && tree->left->isError) ||
2203 (tree->right && tree->right->isError))
2206 /*------------------------------------------------------------------*/
2207 /*----------------------------*/
2208 /* leaf has been reached */
2209 /*----------------------------*/
2210 lineno=tree->lineno;
2211 /* if this is of type value */
2212 /* just get the type */
2213 if (tree->type == EX_VALUE)
2216 if (IS_LITERAL (tree->opval.val->etype))
2219 /* if this is a character array then declare it */
2220 if (IS_ARRAY (tree->opval.val->type))
2221 tree->opval.val = stringToSymbol (tree->opval.val);
2223 /* otherwise just copy the type information */
2224 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2228 if (tree->opval.val->sym)
2230 /* if the undefined flag is set then give error message */
2231 if (tree->opval.val->sym->undefined)
2233 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2235 TTYPE (tree) = TETYPE (tree) =
2236 tree->opval.val->type = tree->opval.val->sym->type =
2237 tree->opval.val->etype = tree->opval.val->sym->etype =
2238 copyLinkChain (INTTYPE);
2243 /* if impilicit i.e. struct/union member then no type */
2244 if (tree->opval.val->sym->implicit)
2245 TTYPE (tree) = TETYPE (tree) = NULL;
2250 /* else copy the type */
2251 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2253 /* and mark it as referenced */
2254 tree->opval.val->sym->isref = 1;
2262 /* if type link for the case of cast */
2263 if (tree->type == EX_LINK)
2265 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2273 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2275 if (tree->left && tree->left->type == EX_OPERAND
2276 && (tree->left->opval.op == INC_OP
2277 || tree->left->opval.op == DEC_OP)
2278 && tree->left->left)
2280 tree->left->right = tree->left->left;
2281 tree->left->left = NULL;
2283 if (tree->right && tree->right->type == EX_OPERAND
2284 && (tree->right->opval.op == INC_OP
2285 || tree->right->opval.op == DEC_OP)
2286 && tree->right->left)
2288 tree->right->right = tree->right->left;
2289 tree->right->left = NULL;
2294 /* Before decorating the left branch we've to decide in dependence
2295 upon tree->opval.op, if resultType can be propagated */
2296 resultTypeProp = resultTypePropagate (tree, resultType);
2298 if (tree->opval.op == '?')
2299 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2301 dtl = decorateType (tree->left, resultTypeProp);
2303 /* if an array node, we may need to swap branches */
2304 if (tree->opval.op == '[')
2306 /* determine which is the array & which the index */
2307 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2308 IS_INTEGRAL (LTYPE (tree)))
2310 ast *tempTree = tree->left;
2311 tree->left = tree->right;
2312 tree->right = tempTree;
2316 /* After decorating the left branch there's type information available
2317 in tree->left->?type. If the op is e.g. '=' we extract the type
2318 information from there and propagate it to the right branch. */
2319 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2321 switch (tree->opval.op)
2324 /* delay right side for '?' operator since conditional macro
2325 expansions might rely on this */
2329 /* decorate right side for CALL (parameter list) in processParms();
2330 there is resultType available */
2334 dtr = decorateType (tree->right, resultTypeProp);
2338 /* this is to take care of situations
2339 when the tree gets rewritten */
2340 if (dtl != tree->left)
2342 if (dtr != tree->right)
2344 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2348 /* depending on type of operator do */
2350 switch (tree->opval.op)
2352 /*------------------------------------------------------------------*/
2353 /*----------------------------*/
2355 /*----------------------------*/
2358 /* first check if this is a array or a pointer */
2359 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2361 werror (E_NEED_ARRAY_PTR, "[]");
2362 goto errorTreeReturn;
2365 /* check if the type of the idx */
2366 if (!IS_INTEGRAL (RTYPE (tree)))
2368 werror (E_IDX_NOT_INT);
2369 goto errorTreeReturn;
2372 /* if the left is an rvalue then error */
2375 werror (E_LVALUE_REQUIRED, "array access");
2376 goto errorTreeReturn;
2379 if (IS_LITERAL (RTYPE (tree)))
2381 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2382 int arraySize = DCL_ELEM (LTYPE (tree));
2383 if (arraySize && arrayIndex >= arraySize)
2385 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2390 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2393 /*------------------------------------------------------------------*/
2394 /*----------------------------*/
2396 /*----------------------------*/
2398 /* if this is not a structure */
2399 if (!IS_STRUCT (LTYPE (tree)))
2401 werror (E_STRUCT_UNION, ".");
2402 goto errorTreeReturn;
2404 TTYPE (tree) = structElemType (LTYPE (tree),
2405 (tree->right->type == EX_VALUE ?
2406 tree->right->opval.val : NULL));
2407 TETYPE (tree) = getSpec (TTYPE (tree));
2410 /*------------------------------------------------------------------*/
2411 /*----------------------------*/
2412 /* struct/union pointer */
2413 /*----------------------------*/
2415 /* if not pointer to a structure */
2416 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2418 werror (E_PTR_REQD);
2419 goto errorTreeReturn;
2422 if (!IS_STRUCT (LTYPE (tree)->next))
2424 werror (E_STRUCT_UNION, "->");
2425 goto errorTreeReturn;
2428 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2429 (tree->right->type == EX_VALUE ?
2430 tree->right->opval.val : NULL));
2431 TETYPE (tree) = getSpec (TTYPE (tree));
2433 /* adjust the storage class */
2434 switch (DCL_TYPE(tree->left->ftype)) {
2436 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2439 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2442 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2445 SPEC_SCLS (TETYPE (tree)) = 0;
2448 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2451 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2454 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2457 SPEC_SCLS (TETYPE (tree)) = 0;
2464 /* This breaks with extern declarations, bitfields, and perhaps other */
2465 /* cases (gcse). Let's leave this optimization disabled for now and */
2466 /* ponder if there's a safe way to do this. -- EEP */
2468 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2469 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2471 /* If defined struct type at addr var
2472 then rewrite (&struct var)->member
2474 and define membertype at (addr+offsetof(struct var,member)) temp
2477 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2478 AST_SYMBOL(tree->right));
2480 sym = newSymbol(genSymName (0), 0);
2481 sym->type = TTYPE (tree);
2482 sym->etype = getSpec(sym->type);
2483 sym->lineDef = tree->lineno;
2486 SPEC_STAT (sym->etype) = 1;
2487 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2489 SPEC_ABSA(sym->etype) = 1;
2490 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2493 AST_VALUE (tree) = symbolVal(sym);
2496 tree->type = EX_VALUE;
2504 /*------------------------------------------------------------------*/
2505 /*----------------------------*/
2506 /* ++/-- operation */
2507 /*----------------------------*/
2511 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2512 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2513 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2514 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2523 /*------------------------------------------------------------------*/
2524 /*----------------------------*/
2526 /*----------------------------*/
2527 case '&': /* can be unary */
2528 /* if right is NULL then unary operation */
2529 if (tree->right) /* not an unary operation */
2532 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2534 werror (E_BITWISE_OP);
2535 werror (W_CONTINUE, "left & right types are ");
2536 printTypeChain (LTYPE (tree), stderr);
2537 fprintf (stderr, ",");
2538 printTypeChain (RTYPE (tree), stderr);
2539 fprintf (stderr, "\n");
2540 goto errorTreeReturn;
2543 /* if they are both literal */
2544 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2546 tree->type = EX_VALUE;
2547 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2548 valFromType (RETYPE (tree)), '&');
2550 tree->right = tree->left = NULL;
2551 TETYPE (tree) = tree->opval.val->etype;
2552 TTYPE (tree) = tree->opval.val->type;
2556 /* see if this is a GETHBIT operation if yes
2559 ast *otree = optimizeGetHbit (tree);
2562 return decorateType (otree, RESULT_CHECK);
2565 TTYPE (tree) = computeType (LTYPE (tree),
2569 TETYPE (tree) = getSpec (TTYPE (tree));
2571 /* if left is a literal exchange left & right */
2572 if (IS_LITERAL (LTYPE (tree)))
2574 ast *tTree = tree->left;
2575 tree->left = tree->right;
2576 tree->right = tTree;
2579 /* if right is a literal and */
2580 /* we can find a 2nd literal in a and-tree then */
2581 /* rearrange the tree */
2582 if (IS_LITERAL (RTYPE (tree)))
2585 ast *litTree = searchLitOp (tree, &parent, "&");
2588 ast *tTree = litTree->left;
2589 litTree->left = tree->right;
2590 tree->right = tTree;
2591 /* both operands in tTree are literal now */
2592 decorateType (parent, RESULT_CHECK);
2596 LRVAL (tree) = RRVAL (tree) = 1;
2601 /*------------------------------------------------------------------*/
2602 /*----------------------------*/
2604 /*----------------------------*/
2605 p = newLink (DECLARATOR);
2606 /* if bit field then error */
2607 if (IS_BITVAR (tree->left->etype))
2609 werror (E_ILLEGAL_ADDR, "address of bit variable");
2610 goto errorTreeReturn;
2613 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2615 werror (E_ILLEGAL_ADDR, "address of register variable");
2616 goto errorTreeReturn;
2619 if (IS_FUNC (LTYPE (tree)))
2621 // this ought to be ignored
2622 return (tree->left);
2625 if (IS_LITERAL(LTYPE(tree)))
2627 werror (E_ILLEGAL_ADDR, "address of literal");
2628 goto errorTreeReturn;
2633 werror (E_LVALUE_REQUIRED, "address of");
2634 goto errorTreeReturn;
2637 DCL_TYPE (p) = POINTER;
2638 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2639 DCL_TYPE (p) = CPOINTER;
2640 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2641 DCL_TYPE (p) = FPOINTER;
2642 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2643 DCL_TYPE (p) = PPOINTER;
2644 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2645 DCL_TYPE (p) = IPOINTER;
2646 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2647 DCL_TYPE (p) = EEPPOINTER;
2648 else if (SPEC_OCLS(tree->left->etype))
2649 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2651 DCL_TYPE (p) = POINTER;
2653 if (IS_AST_SYM_VALUE (tree->left))
2655 AST_SYMBOL (tree->left)->addrtaken = 1;
2656 AST_SYMBOL (tree->left)->allocreq = 1;
2659 p->next = LTYPE (tree);
2661 TETYPE (tree) = getSpec (TTYPE (tree));
2666 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2667 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2669 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2670 AST_SYMBOL(tree->left->right));
2671 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2672 valueFromLit(element->offset));
2675 tree->type = EX_VALUE;
2676 tree->values.literalFromCast = 1;
2682 /*------------------------------------------------------------------*/
2683 /*----------------------------*/
2685 /*----------------------------*/
2687 /* if the rewrite succeeds then don't go any furthur */
2689 ast *wtree = optimizeRRCRLC (tree);
2691 return decorateType (wtree, RESULT_CHECK);
2693 wtree = optimizeSWAP (tree);
2695 return decorateType (wtree, RESULT_CHECK);
2698 /* if left is a literal exchange left & right */
2699 if (IS_LITERAL (LTYPE (tree)))
2701 ast *tTree = tree->left;
2702 tree->left = tree->right;
2703 tree->right = tTree;
2706 /* if right is a literal and */
2707 /* we can find a 2nd literal in a or-tree then */
2708 /* rearrange the tree */
2709 if (IS_LITERAL (RTYPE (tree)))
2712 ast *litTree = searchLitOp (tree, &parent, "|");
2715 ast *tTree = litTree->left;
2716 litTree->left = tree->right;
2717 tree->right = tTree;
2718 /* both operands in tTree are literal now */
2719 decorateType (parent, RESULT_CHECK);
2724 /*------------------------------------------------------------------*/
2725 /*----------------------------*/
2727 /*----------------------------*/
2729 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2731 werror (E_BITWISE_OP);
2732 werror (W_CONTINUE, "left & right types are ");
2733 printTypeChain (LTYPE (tree), stderr);
2734 fprintf (stderr, ",");
2735 printTypeChain (RTYPE (tree), stderr);
2736 fprintf (stderr, "\n");
2737 goto errorTreeReturn;
2740 /* if they are both literal then */
2741 /* rewrite the tree */
2742 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2744 tree->type = EX_VALUE;
2745 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2746 valFromType (RETYPE (tree)),
2748 tree->right = tree->left = NULL;
2749 TETYPE (tree) = tree->opval.val->etype;
2750 TTYPE (tree) = tree->opval.val->type;
2754 /* if left is a literal exchange left & right */
2755 if (IS_LITERAL (LTYPE (tree)))
2757 ast *tTree = tree->left;
2758 tree->left = tree->right;
2759 tree->right = tTree;
2762 /* if right is a literal and */
2763 /* we can find a 2nd literal in a xor-tree then */
2764 /* rearrange the tree */
2765 if (IS_LITERAL (RTYPE (tree)) &&
2766 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2769 ast *litTree = searchLitOp (tree, &parent, "^");
2772 ast *tTree = litTree->left;
2773 litTree->left = tree->right;
2774 tree->right = tTree;
2775 /* both operands in litTree are literal now */
2776 decorateType (parent, RESULT_CHECK);
2780 LRVAL (tree) = RRVAL (tree) = 1;
2781 TETYPE (tree) = getSpec (TTYPE (tree) =
2782 computeType (LTYPE (tree),
2789 /*------------------------------------------------------------------*/
2790 /*----------------------------*/
2792 /*----------------------------*/
2794 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2796 werror (E_INVALID_OP, "divide");
2797 goto errorTreeReturn;
2799 /* if they are both literal then */
2800 /* rewrite the tree */
2801 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2803 tree->type = EX_VALUE;
2804 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2805 valFromType (RETYPE (tree)));
2806 tree->right = tree->left = NULL;
2807 TETYPE (tree) = getSpec (TTYPE (tree) =
2808 tree->opval.val->type);
2812 LRVAL (tree) = RRVAL (tree) = 1;
2814 TETYPE (tree) = getSpec (TTYPE (tree) =
2815 computeType (LTYPE (tree),
2820 /* if right is a literal and */
2821 /* left is also a division by a literal then */
2822 /* rearrange the tree */
2823 if (IS_LITERAL (RTYPE (tree))
2824 /* avoid infinite loop */
2825 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2828 ast *litTree = searchLitOp (tree, &parent, "/");
2831 if (IS_LITERAL (RTYPE (litTree)))
2834 litTree->right = newNode ('*', litTree->right, tree->right);
2835 litTree->right->lineno = tree->lineno;
2837 tree->right->opval.val = constVal ("1");
2838 decorateType (parent, RESULT_CHECK);
2842 /* litTree->left is literal: no gcse possible.
2843 We can't call decorateType(parent, RESULT_CHECK), because
2844 this would cause an infinit loop. */
2845 parent->decorated = 1;
2846 decorateType (litTree, RESULT_CHECK);
2853 /*------------------------------------------------------------------*/
2854 /*----------------------------*/
2856 /*----------------------------*/
2858 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2860 werror (E_BITWISE_OP);
2861 werror (W_CONTINUE, "left & right types are ");
2862 printTypeChain (LTYPE (tree), stderr);
2863 fprintf (stderr, ",");
2864 printTypeChain (RTYPE (tree), stderr);
2865 fprintf (stderr, "\n");
2866 goto errorTreeReturn;
2868 /* if they are both literal then */
2869 /* rewrite the tree */
2870 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2872 tree->type = EX_VALUE;
2873 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2874 valFromType (RETYPE (tree)));
2875 tree->right = tree->left = NULL;
2876 TETYPE (tree) = getSpec (TTYPE (tree) =
2877 tree->opval.val->type);
2880 LRVAL (tree) = RRVAL (tree) = 1;
2881 TETYPE (tree) = getSpec (TTYPE (tree) =
2882 computeType (LTYPE (tree),
2888 /*------------------------------------------------------------------*/
2889 /*----------------------------*/
2890 /* address dereference */
2891 /*----------------------------*/
2892 case '*': /* can be unary : if right is null then unary operation */
2895 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2897 werror (E_PTR_REQD);
2898 goto errorTreeReturn;
2903 werror (E_LVALUE_REQUIRED, "pointer deref");
2904 goto errorTreeReturn;
2906 if (IS_ADDRESS_OF_OP(tree->left))
2908 /* replace *&obj with obj */
2909 return tree->left->left;
2911 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2912 TETYPE (tree) = getSpec (TTYPE (tree));
2913 /* adjust the storage class */
2914 switch (DCL_TYPE(tree->left->ftype)) {
2916 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2919 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2922 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2925 SPEC_SCLS (TETYPE (tree)) = 0;
2928 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2931 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2934 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2937 SPEC_SCLS (TETYPE (tree)) = 0;
2946 /*------------------------------------------------------------------*/
2947 /*----------------------------*/
2948 /* multiplication */
2949 /*----------------------------*/
2950 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2952 werror (E_INVALID_OP, "multiplication");
2953 goto errorTreeReturn;
2956 /* if they are both literal then */
2957 /* rewrite the tree */
2958 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2960 tree->type = EX_VALUE;
2961 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2962 valFromType (RETYPE (tree)));
2963 tree->right = tree->left = NULL;
2964 TETYPE (tree) = getSpec (TTYPE (tree) =
2965 tree->opval.val->type);
2969 /* if left is a literal exchange left & right */
2970 if (IS_LITERAL (LTYPE (tree)))
2972 ast *tTree = tree->left;
2973 tree->left = tree->right;
2974 tree->right = tTree;
2977 /* if right is a literal and */
2978 /* we can find a 2nd literal in a mul-tree then */
2979 /* rearrange the tree */
2980 if (IS_LITERAL (RTYPE (tree)))
2983 ast *litTree = searchLitOp (tree, &parent, "*");
2986 ast *tTree = litTree->left;
2987 litTree->left = tree->right;
2988 tree->right = tTree;
2989 /* both operands in litTree are literal now */
2990 decorateType (parent, RESULT_CHECK);
2994 LRVAL (tree) = RRVAL (tree) = 1;
2995 tree->left = addCast (tree->left, resultType, FALSE);
2996 tree->right = addCast (tree->right, resultType, FALSE);
2997 TETYPE (tree) = getSpec (TTYPE (tree) =
2998 computeType (LTYPE (tree),
3005 /*------------------------------------------------------------------*/
3006 /*----------------------------*/
3007 /* unary '+' operator */
3008 /*----------------------------*/
3013 if (!IS_ARITHMETIC (LTYPE (tree)))
3015 werror (E_UNARY_OP, '+');
3016 goto errorTreeReturn;
3019 /* if left is a literal then do it */
3020 if (IS_LITERAL (LTYPE (tree)))
3022 tree->type = EX_VALUE;
3023 tree->opval.val = valFromType (LETYPE (tree));
3025 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3029 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3033 /*------------------------------------------------------------------*/
3034 /*----------------------------*/
3036 /*----------------------------*/
3038 /* this is not a unary operation */
3039 /* if both pointers then problem */
3040 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3041 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3043 werror (E_PTR_PLUS_PTR);
3044 goto errorTreeReturn;
3047 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3048 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3050 werror (E_PLUS_INVALID, "+");
3051 goto errorTreeReturn;
3054 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3055 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3057 werror (E_PLUS_INVALID, "+");
3058 goto errorTreeReturn;
3060 /* if they are both literal then */
3061 /* rewrite the tree */
3062 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3064 tree->type = EX_VALUE;
3065 tree->left = addCast (tree->left, resultType, TRUE);
3066 tree->right = addCast (tree->right, resultType, TRUE);
3067 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3068 valFromType (RETYPE (tree)));
3069 tree->right = tree->left = NULL;
3070 TETYPE (tree) = getSpec (TTYPE (tree) =
3071 tree->opval.val->type);
3075 /* if the right is a pointer or left is a literal
3076 xchange left & right */
3077 if (IS_ARRAY (RTYPE (tree)) ||
3078 IS_PTR (RTYPE (tree)) ||
3079 IS_LITERAL (LTYPE (tree)))
3081 ast *tTree = tree->left;
3082 tree->left = tree->right;
3083 tree->right = tTree;
3086 /* if right is a literal and */
3087 /* left is also an addition/subtraction with a literal then */
3088 /* rearrange the tree */
3089 if (IS_LITERAL (RTYPE (tree)))
3091 ast *litTree, *parent;
3092 litTree = searchLitOp (tree, &parent, "+-");
3095 if (litTree->opval.op == '+')
3098 ast *tTree = litTree->left;
3099 litTree->left = tree->right;
3100 tree->right = tree->left;
3103 else if (litTree->opval.op == '-')
3105 if (IS_LITERAL (RTYPE (litTree)))
3108 ast *tTree = litTree->left;
3109 litTree->left = tree->right;
3110 tree->right = tTree;
3115 ast *tTree = litTree->right;
3116 litTree->right = tree->right;
3117 tree->right = tTree;
3118 litTree->opval.op = '+';
3119 tree->opval.op = '-';
3122 decorateType (parent, RESULT_CHECK);
3126 LRVAL (tree) = RRVAL (tree) = 1;
3127 /* if the left is a pointer */
3128 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3129 TETYPE (tree) = getSpec (TTYPE (tree) =
3133 tree->left = addCast (tree->left, resultType, TRUE);
3134 tree->right = addCast (tree->right, resultType, TRUE);
3135 TETYPE (tree) = getSpec (TTYPE (tree) =
3136 computeType (LTYPE (tree),
3144 /*------------------------------------------------------------------*/
3145 /*----------------------------*/
3147 /*----------------------------*/
3148 case '-': /* can be unary */
3149 /* if right is null then unary */
3153 if (!IS_ARITHMETIC (LTYPE (tree)))
3155 werror (E_UNARY_OP, tree->opval.op);
3156 goto errorTreeReturn;
3159 /* if left is a literal then do it */
3160 if (IS_LITERAL (LTYPE (tree)))
3162 tree->type = EX_VALUE;
3163 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3165 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3166 SPEC_USIGN(TETYPE(tree)) = 0;
3170 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3174 /*------------------------------------------------------------------*/
3175 /*----------------------------*/
3177 /*----------------------------*/
3179 if (!(IS_PTR (LTYPE (tree)) ||
3180 IS_ARRAY (LTYPE (tree)) ||
3181 IS_ARITHMETIC (LTYPE (tree))))
3183 werror (E_PLUS_INVALID, "-");
3184 goto errorTreeReturn;
3187 if (!(IS_PTR (RTYPE (tree)) ||
3188 IS_ARRAY (RTYPE (tree)) ||
3189 IS_ARITHMETIC (RTYPE (tree))))
3191 werror (E_PLUS_INVALID, "-");
3192 goto errorTreeReturn;
3195 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3196 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3197 IS_INTEGRAL (RTYPE (tree))))
3199 werror (E_PLUS_INVALID, "-");
3200 goto errorTreeReturn;
3203 /* if they are both literal then */
3204 /* rewrite the tree */
3205 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3207 tree->type = EX_VALUE;
3208 tree->left = addCast (tree->left, resultType, TRUE);
3209 tree->right = addCast (tree->right, resultType, TRUE);
3210 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3211 valFromType (RETYPE (tree)));
3212 tree->right = tree->left = NULL;
3213 TETYPE (tree) = getSpec (TTYPE (tree) =
3214 tree->opval.val->type);
3218 /* if the left & right are equal then zero */
3219 if (isAstEqual (tree->left, tree->right))
3221 tree->type = EX_VALUE;
3222 tree->left = tree->right = NULL;
3223 tree->opval.val = constVal ("0");
3224 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3228 /* if both of them are pointers or arrays then */
3229 /* the result is going to be an integer */
3230 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3231 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3232 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3234 /* if only the left is a pointer */
3235 /* then result is a pointer */
3236 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3237 TETYPE (tree) = getSpec (TTYPE (tree) =
3241 tree->left = addCast (tree->left, resultType, TRUE);
3242 tree->right = addCast (tree->right, resultType, TRUE);
3244 TETYPE (tree) = getSpec (TTYPE (tree) =
3245 computeType (LTYPE (tree),
3251 LRVAL (tree) = RRVAL (tree) = 1;
3253 /* if right is a literal and */
3254 /* left is also an addition/subtraction with a literal then */
3255 /* rearrange the tree */
3256 if (IS_LITERAL (RTYPE (tree))
3257 /* avoid infinite loop */
3258 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3260 ast *litTree, *litParent;
3261 litTree = searchLitOp (tree, &litParent, "+-");
3264 if (litTree->opval.op == '+')
3267 litTree->right = newNode ('-', litTree->right, tree->right);
3268 litTree->right->lineno = tree->lineno;
3270 tree->right->opval.val = constVal ("0");
3272 else if (litTree->opval.op == '-')
3274 if (IS_LITERAL (RTYPE (litTree)))
3277 litTree->right = newNode ('+', tree->right, litTree->right);
3278 litTree->right->lineno = tree->lineno;
3280 tree->right->opval.val = constVal ("0");
3285 ast *tTree = litTree->right;
3286 litTree->right = tree->right;
3287 tree->right = tTree;
3290 decorateType (litParent, RESULT_CHECK);
3295 /*------------------------------------------------------------------*/
3296 /*----------------------------*/
3298 /*----------------------------*/
3300 /* can be only integral type */
3301 if (!IS_INTEGRAL (LTYPE (tree)))
3303 werror (E_UNARY_OP, tree->opval.op);
3304 goto errorTreeReturn;
3307 /* if left is a literal then do it */
3308 if (IS_LITERAL (LTYPE (tree)))
3310 tree->type = EX_VALUE;
3311 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3313 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3317 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3320 /*------------------------------------------------------------------*/
3321 /*----------------------------*/
3323 /*----------------------------*/
3325 /* can be pointer */
3326 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3327 !IS_PTR (LTYPE (tree)) &&
3328 !IS_ARRAY (LTYPE (tree)))
3330 werror (E_UNARY_OP, tree->opval.op);
3331 goto errorTreeReturn;
3334 /* if left is a literal then do it */
3335 if (IS_LITERAL (LTYPE (tree)))
3337 tree->type = EX_VALUE;
3338 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3340 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3344 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3347 /*------------------------------------------------------------------*/
3348 /*----------------------------*/
3350 /*----------------------------*/
3354 TTYPE (tree) = LTYPE (tree);
3355 TETYPE (tree) = LETYPE (tree);
3359 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3364 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3366 werror (E_SHIFT_OP_INVALID);
3367 werror (W_CONTINUE, "left & right types are ");
3368 printTypeChain (LTYPE (tree), stderr);
3369 fprintf (stderr, ",");
3370 printTypeChain (RTYPE (tree), stderr);
3371 fprintf (stderr, "\n");
3372 goto errorTreeReturn;
3375 /* make smaller type only if it's a LEFT_OP */
3376 if (tree->opval.op == LEFT_OP)
3377 tree->left = addCast (tree->left, resultType, TRUE);
3379 /* if they are both literal then */
3380 /* rewrite the tree */
3381 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3383 tree->type = EX_VALUE;
3384 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3385 valFromType (RETYPE (tree)),
3386 (tree->opval.op == LEFT_OP ? 1 : 0));
3387 tree->right = tree->left = NULL;
3388 TETYPE (tree) = getSpec (TTYPE (tree) =
3389 tree->opval.val->type);
3393 LRVAL (tree) = RRVAL (tree) = 1;
3394 if (tree->opval.op == LEFT_OP)
3396 TETYPE (tree) = getSpec (TTYPE (tree) =
3397 computeType (LTYPE (tree),
3404 /* no promotion necessary */
3405 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3406 if (IS_LITERAL (TTYPE (tree)))
3407 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3410 /* if only the right side is a literal & we are
3411 shifting more than size of the left operand then zero */
3412 if (IS_LITERAL (RTYPE (tree)) &&
3413 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3414 (getSize (TETYPE (tree)) * 8))
3416 if (tree->opval.op==LEFT_OP ||
3417 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3419 lineno=tree->lineno;
3420 werror (W_SHIFT_CHANGED,
3421 (tree->opval.op == LEFT_OP ? "left" : "right"));
3422 tree->type = EX_VALUE;
3423 tree->left = tree->right = NULL;
3424 tree->opval.val = constVal ("0");
3425 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3432 /*------------------------------------------------------------------*/
3433 /*----------------------------*/
3435 /*----------------------------*/
3436 case CAST: /* change the type */
3437 /* cannot cast to an aggregate type */
3438 if (IS_AGGREGATE (LTYPE (tree)))
3440 werror (E_CAST_ILLEGAL);
3441 goto errorTreeReturn;
3444 /* make sure the type is complete and sane */
3445 checkTypeSanity(LETYPE(tree), "(cast)");
3447 /* If code memory is read only, then pointers to code memory */
3448 /* implicitly point to constants -- make this explicit */
3450 sym_link *t = LTYPE(tree);
3451 while (t && t->next)
3453 if (IS_CODEPTR(t) && port->mem.code_ro)
3455 if (IS_SPEC(t->next))
3456 SPEC_CONST (t->next) = 1;
3458 DCL_PTR_CONST (t->next) = 1;
3465 /* if the right is a literal replace the tree */
3466 if (IS_LITERAL (RETYPE (tree))) {
3467 if (!IS_PTR (LTYPE (tree))) {
3468 tree->type = EX_VALUE;
3470 valCastLiteral (LTYPE (tree),
3471 floatFromVal (valFromType (RETYPE (tree))));
3474 TTYPE (tree) = tree->opval.val->type;
3475 tree->values.literalFromCast = 1;
3476 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3477 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3478 sym_link *rest = LTYPE(tree)->next;
3479 werror(W_LITERAL_GENERIC);
3480 TTYPE(tree) = newLink(DECLARATOR);
3481 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3482 TTYPE(tree)->next = rest;
3483 tree->left->opval.lnk = TTYPE(tree);
3486 TTYPE (tree) = LTYPE (tree);
3490 TTYPE (tree) = LTYPE (tree);
3494 #if 0 // this is already checked, now this could be explicit
3495 /* if pointer to struct then check names */
3496 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3497 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3498 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3500 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3501 SPEC_STRUCT(LETYPE(tree))->tag);
3504 if (IS_ADDRESS_OF_OP(tree->right)
3505 && IS_AST_SYM_VALUE (tree->right->left)
3506 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3508 tree->type = EX_VALUE;
3510 valCastLiteral (LTYPE (tree),
3511 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3512 TTYPE (tree) = tree->opval.val->type;
3513 TETYPE (tree) = getSpec (TTYPE (tree));
3516 tree->values.literalFromCast = 1;
3520 /* handle offsetof macro: */
3521 /* #define offsetof(TYPE, MEMBER) \ */
3522 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3523 if (IS_ADDRESS_OF_OP(tree->right)
3524 && IS_AST_OP (tree->right->left)
3525 && tree->right->left->opval.op == PTR_OP
3526 && IS_AST_OP (tree->right->left->left)
3527 && tree->right->left->left->opval.op == CAST
3528 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3530 symbol *element = getStructElement (
3531 SPEC_STRUCT (LETYPE(tree->right->left)),
3532 AST_SYMBOL(tree->right->left->right)
3536 tree->type = EX_VALUE;
3537 tree->opval.val = valCastLiteral (
3540 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3543 TTYPE (tree) = tree->opval.val->type;
3544 TETYPE (tree) = getSpec (TTYPE (tree));
3551 /* if the right is a literal replace the tree */
3552 if (IS_LITERAL (RETYPE (tree))) {
3554 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3555 /* rewrite (type *)litaddr
3557 and define type at litaddr temp
3558 (but only if type's storage class is not generic)
3560 ast *newTree = newNode ('&', NULL, NULL);
3563 TTYPE (newTree) = LTYPE (tree);
3564 TETYPE (newTree) = getSpec(LTYPE (tree));
3566 /* define a global symbol at the casted address*/
3567 sym = newSymbol(genSymName (0), 0);
3568 sym->type = LTYPE (tree)->next;
3570 sym->type = newLink (V_VOID);
3571 sym->etype = getSpec(sym->type);
3572 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3573 sym->lineDef = tree->lineno;
3576 SPEC_STAT (sym->etype) = 1;
3577 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3578 SPEC_ABSA(sym->etype) = 1;
3579 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3582 newTree->left = newAst_VALUE(symbolVal(sym));
3583 newTree->left->lineno = tree->lineno;
3584 LTYPE (newTree) = sym->type;
3585 LETYPE (newTree) = sym->etype;
3586 LLVAL (newTree) = 1;
3587 LRVAL (newTree) = 0;
3588 TLVAL (newTree) = 1;
3592 if (!IS_PTR (LTYPE (tree))) {
3593 tree->type = EX_VALUE;
3595 valCastLiteral (LTYPE (tree),
3596 floatFromVal (valFromType (RTYPE (tree))));
3597 TTYPE (tree) = tree->opval.val->type;
3600 tree->values.literalFromCast = 1;
3601 TETYPE (tree) = getSpec (TTYPE (tree));
3605 TTYPE (tree) = LTYPE (tree);
3609 TETYPE (tree) = getSpec (TTYPE (tree));
3613 /*------------------------------------------------------------------*/
3614 /*----------------------------*/
3615 /* logical &&, || */
3616 /*----------------------------*/
3619 /* each must me arithmetic type or be a pointer */
3620 if (!IS_PTR (LTYPE (tree)) &&
3621 !IS_ARRAY (LTYPE (tree)) &&
3622 !IS_INTEGRAL (LTYPE (tree)))
3624 werror (E_COMPARE_OP);
3625 goto errorTreeReturn;
3628 if (!IS_PTR (RTYPE (tree)) &&
3629 !IS_ARRAY (RTYPE (tree)) &&
3630 !IS_INTEGRAL (RTYPE (tree)))
3632 werror (E_COMPARE_OP);
3633 goto errorTreeReturn;
3635 /* if they are both literal then */
3636 /* rewrite the tree */
3637 if (IS_LITERAL (RTYPE (tree)) &&
3638 IS_LITERAL (LTYPE (tree)))
3640 tree->type = EX_VALUE;
3641 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3642 valFromType (RTYPE (tree)),
3644 tree->right = tree->left = NULL;
3645 TETYPE (tree) = getSpec (TTYPE (tree) =
3646 tree->opval.val->type);
3649 LRVAL (tree) = RRVAL (tree) = 1;
3650 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3653 /*------------------------------------------------------------------*/
3654 /*----------------------------*/
3655 /* comparison operators */
3656 /*----------------------------*/
3664 ast *lt = optimizeCompare (tree);
3670 /* if they are pointers they must be castable */
3671 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3673 if (tree->opval.op==EQ_OP &&
3674 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3675 // we cannot cast a gptr to a !gptr: switch the leaves
3676 struct ast *s=tree->left;
3677 tree->left=tree->right;
3680 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3682 werror (E_COMPARE_OP);
3683 fprintf (stderr, "comparing type ");
3684 printTypeChain (LTYPE (tree), stderr);
3685 fprintf (stderr, "to type ");
3686 printTypeChain (RTYPE (tree), stderr);
3687 fprintf (stderr, "\n");
3688 goto errorTreeReturn;
3691 /* else they should be promotable to one another */
3694 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3695 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3697 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3699 werror (E_COMPARE_OP);
3700 fprintf (stderr, "comparing type ");
3701 printTypeChain (LTYPE (tree), stderr);
3702 fprintf (stderr, "to type ");
3703 printTypeChain (RTYPE (tree), stderr);
3704 fprintf (stderr, "\n");
3705 goto errorTreeReturn;
3708 /* if unsigned value < 0 then always false */
3709 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3710 if (SPEC_USIGN(LETYPE(tree)) &&
3711 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3712 IS_LITERAL(RTYPE(tree)) &&
3713 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3715 if (tree->opval.op == '<')
3719 if (tree->opval.op == '>')
3721 if (resultType == RESULT_TYPE_IFX)
3723 /* the parent is an ifx: */
3724 /* if (unsigned value) */
3728 /* (unsigned value) ? 1 : 0 */
3729 tree->opval.op = '?';
3730 tree->right = newNode (':',
3731 newAst_VALUE (constVal ("1")),
3732 tree->right); /* val 0 */
3733 tree->right->lineno = tree->lineno;
3734 tree->right->left->lineno = tree->lineno;
3735 decorateType (tree->right, RESULT_CHECK);
3738 /* if they are both literal then */
3739 /* rewrite the tree */
3740 if (IS_LITERAL (RTYPE (tree)) &&
3741 IS_LITERAL (LTYPE (tree)))
3743 tree->type = EX_VALUE;
3744 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3745 valFromType (RETYPE (tree)),
3747 tree->right = tree->left = NULL;
3748 TETYPE (tree) = getSpec (TTYPE (tree) =
3749 tree->opval.val->type);
3752 LRVAL (tree) = RRVAL (tree) = 1;
3753 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3756 /*------------------------------------------------------------------*/
3757 /*----------------------------*/
3759 /*----------------------------*/
3760 case SIZEOF: /* evaluate wihout code generation */
3761 /* change the type to a integer */
3763 int size = getSize (tree->right->ftype);
3764 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3765 if (!size && !IS_VOID(tree->right->ftype))
3766 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3768 tree->type = EX_VALUE;
3769 tree->opval.val = constVal (buffer);
3770 tree->right = tree->left = NULL;
3771 TETYPE (tree) = getSpec (TTYPE (tree) =
3772 tree->opval.val->type);
3775 /*------------------------------------------------------------------*/
3776 /*----------------------------*/
3778 /*----------------------------*/
3780 /* return typeof enum value */
3781 tree->type = EX_VALUE;
3784 if (IS_SPEC(tree->right->ftype)) {
3785 switch (SPEC_NOUN(tree->right->ftype)) {
3787 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3788 else typeofv = TYPEOF_INT;
3791 typeofv = TYPEOF_FLOAT;
3794 typeofv = TYPEOF_CHAR;
3797 typeofv = TYPEOF_VOID;
3800 typeofv = TYPEOF_STRUCT;
3803 typeofv = TYPEOF_BITFIELD;
3806 typeofv = TYPEOF_BIT;
3809 typeofv = TYPEOF_SBIT;
3815 switch (DCL_TYPE(tree->right->ftype)) {
3817 typeofv = TYPEOF_POINTER;
3820 typeofv = TYPEOF_FPOINTER;
3823 typeofv = TYPEOF_CPOINTER;
3826 typeofv = TYPEOF_GPOINTER;
3829 typeofv = TYPEOF_PPOINTER;
3832 typeofv = TYPEOF_IPOINTER;
3835 typeofv = TYPEOF_ARRAY;
3838 typeofv = TYPEOF_FUNCTION;
3844 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3845 tree->opval.val = constVal (buffer);
3846 tree->right = tree->left = NULL;
3847 TETYPE (tree) = getSpec (TTYPE (tree) =
3848 tree->opval.val->type);
3851 /*------------------------------------------------------------------*/
3852 /*----------------------------*/
3853 /* conditional operator '?' */
3854 /*----------------------------*/
3856 /* the type is value of the colon operator (on the right) */
3857 assert (IS_COLON_OP (tree->right));
3858 /* if already known then replace the tree : optimizer will do it
3859 but faster to do it here */
3860 if (IS_LITERAL (LTYPE (tree)))
3862 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3863 return decorateType (tree->right->left, resultTypeProp);
3865 return decorateType (tree->right->right, resultTypeProp);
3869 tree->right = decorateType (tree->right, resultTypeProp);
3870 TTYPE (tree) = RTYPE (tree);
3871 TETYPE (tree) = getSpec (TTYPE (tree));
3876 /* if they don't match we have a problem */
3877 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3879 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3880 goto errorTreeReturn;
3883 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3884 resultType, tree->opval.op);
3885 TETYPE (tree) = getSpec (TTYPE (tree));
3889 #if 0 // assignment operators are converted by the parser
3890 /*------------------------------------------------------------------*/
3891 /*----------------------------*/
3892 /* assignment operators */
3893 /*----------------------------*/
3896 /* for these it must be both must be integral */
3897 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3898 !IS_ARITHMETIC (RTYPE (tree)))
3900 werror (E_OPS_INTEGRAL);
3901 goto errorTreeReturn;
3904 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3906 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3907 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3911 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3912 goto errorTreeReturn;
3923 /* for these it must be both must be integral */
3924 if (!IS_INTEGRAL (LTYPE (tree)) ||
3925 !IS_INTEGRAL (RTYPE (tree)))
3927 werror (E_OPS_INTEGRAL);
3928 goto errorTreeReturn;
3931 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3933 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3934 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3938 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3939 goto errorTreeReturn;
3945 /*------------------------------------------------------------------*/
3946 /*----------------------------*/
3948 /*----------------------------*/
3950 if (!(IS_PTR (LTYPE (tree)) ||
3951 IS_ARITHMETIC (LTYPE (tree))))
3953 werror (E_PLUS_INVALID, "-=");
3954 goto errorTreeReturn;
3957 if (!(IS_PTR (RTYPE (tree)) ||
3958 IS_ARITHMETIC (RTYPE (tree))))
3960 werror (E_PLUS_INVALID, "-=");
3961 goto errorTreeReturn;
3964 TETYPE (tree) = getSpec (TTYPE (tree) =
3965 computeType (LTYPE (tree),
3970 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3971 werror (E_CODE_WRITE, "-=");
3975 werror (E_LVALUE_REQUIRED, "-=");
3976 goto errorTreeReturn;
3982 /*------------------------------------------------------------------*/
3983 /*----------------------------*/
3985 /*----------------------------*/
3987 /* this is not a unary operation */
3988 /* if both pointers then problem */
3989 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3991 werror (E_PTR_PLUS_PTR);
3992 goto errorTreeReturn;
3995 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3997 werror (E_PLUS_INVALID, "+=");
3998 goto errorTreeReturn;
4001 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4003 werror (E_PLUS_INVALID, "+=");
4004 goto errorTreeReturn;
4007 TETYPE (tree) = getSpec (TTYPE (tree) =
4008 computeType (LTYPE (tree),
4013 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4014 werror (E_CODE_WRITE, "+=");
4018 werror (E_LVALUE_REQUIRED, "+=");
4019 goto errorTreeReturn;
4022 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
4023 tree->opval.op = '=';
4028 /*------------------------------------------------------------------*/
4029 /*----------------------------*/
4030 /* straight assignemnt */
4031 /*----------------------------*/
4033 /* cannot be an aggregate */
4034 if (IS_AGGREGATE (LTYPE (tree)))
4036 werror (E_AGGR_ASSIGN);
4037 goto errorTreeReturn;
4040 /* they should either match or be castable */
4041 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4043 werror (E_TYPE_MISMATCH, "assignment", " ");
4044 printFromToType(RTYPE(tree),LTYPE(tree));
4047 /* if the left side of the tree is of type void
4048 then report error */
4049 if (IS_VOID (LTYPE (tree)))
4051 werror (E_CAST_ZERO);
4052 printFromToType(RTYPE(tree), LTYPE(tree));
4055 TETYPE (tree) = getSpec (TTYPE (tree) =
4059 if (!tree->initMode ) {
4060 if (IS_CONSTANT(LTYPE(tree)))
4061 werror (E_CODE_WRITE, "=");
4065 werror (E_LVALUE_REQUIRED, "=");
4066 goto errorTreeReturn;
4071 /*------------------------------------------------------------------*/
4072 /*----------------------------*/
4073 /* comma operator */
4074 /*----------------------------*/
4076 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4079 /*------------------------------------------------------------------*/
4080 /*----------------------------*/
4082 /*----------------------------*/
4085 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4086 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4088 if (tree->left->opval.op == '*' && !tree->left->right)
4089 tree->left = tree->left->left;
4092 /* require a function or pointer to function */
4093 if (!IS_FUNC (LTYPE (tree))
4094 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4096 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4097 goto errorTreeReturn;
4104 if (IS_CODEPTR(LTYPE(tree)))
4105 functype = LTYPE (tree)->next;
4107 functype = LTYPE (tree);
4109 if (processParms (tree->left, FUNC_ARGS(functype),
4110 tree->right, &parmNumber, TRUE)) {
4111 goto errorTreeReturn;
4114 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4115 !IFFUNC_ISBUILTIN(functype))
4117 reverseParms (tree->right);
4120 TTYPE (tree) = functype->next;
4121 TETYPE (tree) = getSpec (TTYPE (tree));
4125 /*------------------------------------------------------------------*/
4126 /*----------------------------*/
4127 /* return statement */
4128 /*----------------------------*/
4133 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4135 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4136 printFromToType (RTYPE(tree), currFunc->type->next);
4137 goto errorTreeReturn;
4140 if (IS_VOID (currFunc->type->next)
4142 !IS_VOID (RTYPE (tree)))
4144 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4145 goto errorTreeReturn;
4148 /* if there is going to be a casting required then add it */
4149 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4152 decorateType (newNode (CAST,
4153 newAst_LINK (copyLinkChain (currFunc->type->next)),
4163 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4165 werror (W_VOID_FUNC, currFunc->name);
4166 goto errorTreeReturn;
4169 TTYPE (tree) = TETYPE (tree) = NULL;
4172 /*------------------------------------------------------------------*/
4173 /*----------------------------*/
4174 /* switch statement */
4175 /*----------------------------*/
4177 /* the switch value must be an integer */
4178 if (!IS_INTEGRAL (LTYPE (tree)))
4180 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4181 goto errorTreeReturn;
4184 TTYPE (tree) = TETYPE (tree) = NULL;
4187 /*------------------------------------------------------------------*/
4188 /*----------------------------*/
4190 /*----------------------------*/
4192 tree->left = backPatchLabels (tree->left,
4195 TTYPE (tree) = TETYPE (tree) = NULL;
4198 /*------------------------------------------------------------------*/
4199 /*----------------------------*/
4201 /*----------------------------*/
4204 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4205 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4206 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4208 /* if the for loop is reversible then
4209 reverse it otherwise do what we normally
4215 if (isLoopReversible (tree, &sym, &init, &end))
4216 return reverseLoop (tree, sym, init, end);
4218 return decorateType (createFor (AST_FOR (tree, trueLabel),
4219 AST_FOR (tree, continueLabel),
4220 AST_FOR (tree, falseLabel),
4221 AST_FOR (tree, condLabel),
4222 AST_FOR (tree, initExpr),
4223 AST_FOR (tree, condExpr),
4224 AST_FOR (tree, loopExpr),
4225 tree->left), RESULT_CHECK);
4228 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4229 "node PARAM shouldn't be processed here");
4230 /* but in processParams() */
4233 TTYPE (tree) = TETYPE (tree) = NULL;
4237 /* some error found this tree will be killed */
4239 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4240 tree->opval.op = NULLOP;
4246 /*-----------------------------------------------------------------*/
4247 /* sizeofOp - processes size of operation */
4248 /*-----------------------------------------------------------------*/
4250 sizeofOp (sym_link * type)
4255 /* make sure the type is complete and sane */
4256 checkTypeSanity(type, "(sizeof)");
4258 /* get the size and convert it to character */
4259 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4260 if (!size && !IS_VOID(type))
4261 werror (E_SIZEOF_INCOMPLETE_TYPE);
4263 /* now convert into value */
4264 return constVal (buff);
4268 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4269 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4270 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4271 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4272 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4273 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4274 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4276 /*-----------------------------------------------------------------*/
4277 /* backPatchLabels - change and or not operators to flow control */
4278 /*-----------------------------------------------------------------*/
4280 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4286 if (!(IS_ANDORNOT (tree)))
4289 /* if this an and */
4292 static int localLbl = 0;
4295 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4296 localLabel = newSymbol (buffer, NestLevel);
4298 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4300 /* if left is already a IFX then just change the if true label in that */
4301 if (!IS_IFX (tree->left))
4302 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4304 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4305 /* right is a IFX then just join */
4306 if (IS_IFX (tree->right))
4307 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4309 tree->right = createLabel (localLabel, tree->right);
4310 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4312 return newNode (NULLOP, tree->left, tree->right);
4315 /* if this is an or operation */
4318 static int localLbl = 0;
4321 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4322 localLabel = newSymbol (buffer, NestLevel);
4324 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4326 /* if left is already a IFX then just change the if true label in that */
4327 if (!IS_IFX (tree->left))
4328 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4330 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4331 /* right is a IFX then just join */
4332 if (IS_IFX (tree->right))
4333 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4335 tree->right = createLabel (localLabel, tree->right);
4336 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4338 return newNode (NULLOP, tree->left, tree->right);
4344 int wasnot = IS_NOT (tree->left);
4345 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4347 /* if the left is already a IFX */
4348 if (!IS_IFX (tree->left))
4349 tree->left = newNode (IFX, tree->left, NULL);
4353 tree->left->trueLabel = trueLabel;
4354 tree->left->falseLabel = falseLabel;
4358 tree->left->trueLabel = falseLabel;
4359 tree->left->falseLabel = trueLabel;
4366 tree->trueLabel = trueLabel;
4367 tree->falseLabel = falseLabel;
4374 /*-----------------------------------------------------------------*/
4375 /* createBlock - create expression tree for block */
4376 /*-----------------------------------------------------------------*/
4378 createBlock (symbol * decl, ast * body)
4382 /* if the block has nothing */
4386 ex = newNode (BLOCK, NULL, body);
4387 ex->values.sym = decl;
4389 ex->right = ex->right;
4395 /*-----------------------------------------------------------------*/
4396 /* createLabel - creates the expression tree for labels */
4397 /*-----------------------------------------------------------------*/
4399 createLabel (symbol * label, ast * stmnt)
4402 char name[SDCC_NAME_MAX + 1];
4405 /* must create fresh symbol if the symbol name */
4406 /* exists in the symbol table, since there can */
4407 /* be a variable with the same name as the labl */
4408 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4409 (csym->level == label->level))
4410 label = newSymbol (label->name, label->level);
4412 /* change the name before putting it in add _ */
4413 SNPRINTF(name, sizeof(name), "%s", label->name);
4415 /* put the label in the LabelSymbol table */
4416 /* but first check if a label of the same */
4418 if ((csym = findSym (LabelTab, NULL, name)))
4419 werror (E_DUPLICATE_LABEL, label->name);
4421 addSym (LabelTab, label, name, label->level, 0, 0);
4424 label->key = labelKey++;
4425 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4431 /*-----------------------------------------------------------------*/
4432 /* createCase - generates the parsetree for a case statement */
4433 /*-----------------------------------------------------------------*/
4435 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4437 char caseLbl[SDCC_NAME_MAX + 1];
4441 /* if the switch statement does not exist */
4442 /* then case is out of context */
4445 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4449 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4450 /* if not a constant then error */
4451 if (!IS_LITERAL (caseVal->ftype))
4453 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4457 /* if not a integer than error */
4458 if (!IS_INTEGRAL (caseVal->ftype))
4460 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4464 /* find the end of the switch values chain */
4465 if (!(val = swStat->values.switchVals.swVals))
4466 swStat->values.switchVals.swVals = caseVal->opval.val;
4469 /* also order the cases according to value */
4471 int cVal = (int) floatFromVal (caseVal->opval.val);
4472 while (val && (int) floatFromVal (val) < cVal)
4478 /* if we reached the end then */
4481 pval->next = caseVal->opval.val;
4483 else if ((int) floatFromVal (val) == cVal)
4485 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4491 /* we found a value greater than */
4492 /* the current value we must add this */
4493 /* before the value */
4494 caseVal->opval.val->next = val;
4496 /* if this was the first in chain */
4497 if (swStat->values.switchVals.swVals == val)
4498 swStat->values.switchVals.swVals =
4501 pval->next = caseVal->opval.val;
4506 /* create the case label */
4507 SNPRINTF(caseLbl, sizeof(caseLbl),
4509 swStat->values.switchVals.swNum,
4510 (int) floatFromVal (caseVal->opval.val));
4512 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4517 /*-----------------------------------------------------------------*/
4518 /* createDefault - creates the parse tree for the default statement */
4519 /*-----------------------------------------------------------------*/
4521 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4523 char defLbl[SDCC_NAME_MAX + 1];
4525 /* if the switch statement does not exist */
4526 /* then case is out of context */
4529 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4533 if (swStat->values.switchVals.swDefault)
4535 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4540 /* turn on the default flag */
4541 swStat->values.switchVals.swDefault = 1;
4543 /* create the label */
4544 SNPRINTF (defLbl, sizeof(defLbl),
4545 "_default_%d", swStat->values.switchVals.swNum);
4546 return createLabel (newSymbol (defLbl, 0), stmnt);
4549 /*-----------------------------------------------------------------*/
4550 /* createIf - creates the parsetree for the if statement */
4551 /*-----------------------------------------------------------------*/
4553 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4555 static int Lblnum = 0;
4557 symbol *ifTrue, *ifFalse, *ifEnd;
4559 /* if neither exists */
4560 if (!elseBody && !ifBody) {
4561 // if there are no side effects (i++, j() etc)
4562 if (!hasSEFcalls(condAst)) {
4567 /* create the labels */
4568 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4569 ifFalse = newSymbol (buffer, NestLevel);
4570 /* if no else body then end == false */
4575 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4576 ifEnd = newSymbol (buffer, NestLevel);
4579 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4580 ifTrue = newSymbol (buffer, NestLevel);
4584 /* attach the ifTrue label to the top of it body */
4585 ifBody = createLabel (ifTrue, ifBody);
4586 /* attach a goto end to the ifBody if else is present */
4589 ifBody = newNode (NULLOP, ifBody,
4591 newAst_VALUE (symbolVal (ifEnd)),
4593 /* put the elseLabel on the else body */
4594 elseBody = createLabel (ifFalse, elseBody);
4595 /* out the end at the end of the body */
4596 elseBody = newNode (NULLOP,
4598 createLabel (ifEnd, NULL));
4602 ifBody = newNode (NULLOP, ifBody,
4603 createLabel (ifFalse, NULL));
4605 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4606 if (IS_IFX (condAst))
4609 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4611 return newNode (NULLOP, ifTree,
4612 newNode (NULLOP, ifBody, elseBody));
4616 /*-----------------------------------------------------------------*/
4617 /* createDo - creates parse tree for do */
4620 /* _docontinue_n: */
4621 /* condition_expression +-> trueLabel -> _dobody_n */
4623 /* +-> falseLabel-> _dobreak_n */
4625 /*-----------------------------------------------------------------*/
4627 createDo (symbol * trueLabel, symbol * continueLabel,
4628 symbol * falseLabel, ast * condAst, ast * doBody)
4633 /* if the body does not exist then it is simple */
4636 condAst = backPatchLabels (condAst, continueLabel, NULL);
4637 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4638 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4639 doTree->trueLabel = continueLabel;
4640 doTree->falseLabel = NULL;
4644 /* otherwise we have a body */
4645 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4647 /* attach the body label to the top */
4648 doBody = createLabel (trueLabel, doBody);
4649 /* attach the continue label to end of body */
4650 doBody = newNode (NULLOP, doBody,
4651 createLabel (continueLabel, NULL));
4653 /* now put the break label at the end */
4654 if (IS_IFX (condAst))
4657 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4659 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4661 /* putting it together */
4662 return newNode (NULLOP, doBody, doTree);
4665 /*-----------------------------------------------------------------*/
4666 /* createFor - creates parse tree for 'for' statement */
4669 /* condExpr +-> trueLabel -> _forbody_n */
4671 /* +-> falseLabel-> _forbreak_n */
4674 /* _forcontinue_n: */
4676 /* goto _forcond_n ; */
4678 /*-----------------------------------------------------------------*/
4680 createFor (symbol * trueLabel, symbol * continueLabel,
4681 symbol * falseLabel, symbol * condLabel,
4682 ast * initExpr, ast * condExpr, ast * loopExpr,
4687 /* if loopexpression not present then we can generate it */
4688 /* the same way as a while */
4690 return newNode (NULLOP, initExpr,
4691 createWhile (trueLabel, continueLabel,
4692 falseLabel, condExpr, forBody));
4693 /* vanilla for statement */
4694 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4696 if (condExpr && !IS_IFX (condExpr))
4697 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4700 /* attach condition label to condition */
4701 condExpr = createLabel (condLabel, condExpr);
4703 /* attach body label to body */
4704 forBody = createLabel (trueLabel, forBody);
4706 /* attach continue to forLoop expression & attach */
4707 /* goto the forcond @ and of loopExpression */
4708 loopExpr = createLabel (continueLabel,
4712 newAst_VALUE (symbolVal (condLabel)),
4714 /* now start putting them together */
4715 forTree = newNode (NULLOP, initExpr, condExpr);
4716 forTree = newNode (NULLOP, forTree, forBody);
4717 forTree = newNode (NULLOP, forTree, loopExpr);
4718 /* finally add the break label */
4719 forTree = newNode (NULLOP, forTree,
4720 createLabel (falseLabel, NULL));
4724 /*-----------------------------------------------------------------*/
4725 /* createWhile - creates parse tree for while statement */
4726 /* the while statement will be created as follows */
4728 /* _while_continue_n: */
4729 /* condition_expression +-> trueLabel -> _while_boby_n */
4731 /* +-> falseLabel -> _while_break_n */
4732 /* _while_body_n: */
4734 /* goto _while_continue_n */
4735 /* _while_break_n: */
4736 /*-----------------------------------------------------------------*/
4738 createWhile (symbol * trueLabel, symbol * continueLabel,
4739 symbol * falseLabel, ast * condExpr, ast * whileBody)
4743 /* put the continue label */
4744 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4745 condExpr = createLabel (continueLabel, condExpr);
4746 condExpr->lineno = 0;
4748 /* put the body label in front of the body */
4749 whileBody = createLabel (trueLabel, whileBody);
4750 whileBody->lineno = 0;
4751 /* put a jump to continue at the end of the body */
4752 /* and put break label at the end of the body */
4753 whileBody = newNode (NULLOP,
4756 newAst_VALUE (symbolVal (continueLabel)),
4757 createLabel (falseLabel, NULL)));
4759 /* put it all together */
4760 if (IS_IFX (condExpr))
4761 whileTree = condExpr;
4764 whileTree = newNode (IFX, condExpr, NULL);
4765 /* put the true & false labels in place */
4766 whileTree->trueLabel = trueLabel;
4767 whileTree->falseLabel = falseLabel;
4770 return newNode (NULLOP, whileTree, whileBody);
4773 /*-----------------------------------------------------------------*/
4774 /* optimizeGetHbit - get highest order bit of the expression */
4775 /*-----------------------------------------------------------------*/
4777 optimizeGetHbit (ast * tree)
4780 /* if this is not a bit and */
4781 if (!IS_BITAND (tree))
4784 /* will look for tree of the form
4785 ( expr >> ((sizeof expr) -1) ) & 1 */
4786 if (!IS_AST_LIT_VALUE (tree->right))
4789 if (AST_LIT_VALUE (tree->right) != 1)
4792 if (!IS_RIGHT_OP (tree->left))
4795 if (!IS_AST_LIT_VALUE (tree->left->right))
4798 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4799 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4802 /* make sure the port supports GETHBIT */
4803 if (port->hasExtBitOp
4804 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4807 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4811 /*-----------------------------------------------------------------*/
4812 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4813 /*-----------------------------------------------------------------*/
4815 optimizeRRCRLC (ast * root)
4817 /* will look for trees of the form
4818 (?expr << 1) | (?expr >> 7) or
4819 (?expr >> 7) | (?expr << 1) will make that
4820 into a RLC : operation ..
4822 (?expr >> 1) | (?expr << 7) or
4823 (?expr << 7) | (?expr >> 1) will make that
4824 into a RRC operation
4825 note : by 7 I mean (number of bits required to hold the
4827 /* if the root operations is not a | operation the not */
4828 if (!IS_BITOR (root))
4831 /* I have to think of a better way to match patterns this sucks */
4832 /* that aside let start looking for the first case : I use a the
4833 negative check a lot to improve the efficiency */
4834 /* (?expr << 1) | (?expr >> 7) */
4835 if (IS_LEFT_OP (root->left) &&
4836 IS_RIGHT_OP (root->right))
4839 if (!SPEC_USIGN (TETYPE (root->left->left)))
4842 if (!IS_AST_LIT_VALUE (root->left->right) ||
4843 !IS_AST_LIT_VALUE (root->right->right))
4846 /* make sure it is the same expression */
4847 if (!isAstEqual (root->left->left,
4851 if (AST_LIT_VALUE (root->left->right) != 1)
4854 if (AST_LIT_VALUE (root->right->right) !=
4855 (getSize (TTYPE (root->left->left)) * 8 - 1))
4858 /* make sure the port supports RLC */
4859 if (port->hasExtBitOp
4860 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4863 /* whew got the first case : create the AST */
4864 return newNode (RLC, root->left->left, NULL);
4868 /* check for second case */
4869 /* (?expr >> 7) | (?expr << 1) */
4870 if (IS_LEFT_OP (root->right) &&
4871 IS_RIGHT_OP (root->left))
4874 if (!SPEC_USIGN (TETYPE (root->left->left)))
4877 if (!IS_AST_LIT_VALUE (root->left->right) ||
4878 !IS_AST_LIT_VALUE (root->right->right))
4881 /* make sure it is the same symbol */
4882 if (!isAstEqual (root->left->left,
4886 if (AST_LIT_VALUE (root->right->right) != 1)
4889 if (AST_LIT_VALUE (root->left->right) !=
4890 (getSize (TTYPE (root->left->left)) * 8 - 1))
4893 /* make sure the port supports RLC */
4894 if (port->hasExtBitOp
4895 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4898 /* whew got the first case : create the AST */
4899 return newNode (RLC, root->left->left, NULL);
4904 /* third case for RRC */
4905 /* (?symbol >> 1) | (?symbol << 7) */
4906 if (IS_LEFT_OP (root->right) &&
4907 IS_RIGHT_OP (root->left))
4910 if (!SPEC_USIGN (TETYPE (root->left->left)))
4913 if (!IS_AST_LIT_VALUE (root->left->right) ||
4914 !IS_AST_LIT_VALUE (root->right->right))
4917 /* make sure it is the same symbol */
4918 if (!isAstEqual (root->left->left,
4922 if (AST_LIT_VALUE (root->left->right) != 1)
4925 if (AST_LIT_VALUE (root->right->right) !=
4926 (getSize (TTYPE (root->left->left)) * 8 - 1))
4929 /* make sure the port supports RRC */
4930 if (port->hasExtBitOp
4931 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4934 /* whew got the first case : create the AST */
4935 return newNode (RRC, root->left->left, NULL);
4939 /* fourth and last case for now */
4940 /* (?symbol << 7) | (?symbol >> 1) */
4941 if (IS_RIGHT_OP (root->right) &&
4942 IS_LEFT_OP (root->left))
4945 if (!SPEC_USIGN (TETYPE (root->left->left)))
4948 if (!IS_AST_LIT_VALUE (root->left->right) ||
4949 !IS_AST_LIT_VALUE (root->right->right))
4952 /* make sure it is the same symbol */
4953 if (!isAstEqual (root->left->left,
4957 if (AST_LIT_VALUE (root->right->right) != 1)
4960 if (AST_LIT_VALUE (root->left->right) !=
4961 (getSize (TTYPE (root->left->left)) * 8 - 1))
4964 /* make sure the port supports RRC */
4965 if (port->hasExtBitOp
4966 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4969 /* whew got the first case : create the AST */
4970 return newNode (RRC, root->left->left, NULL);
4974 /* not found return root */
4978 /*-----------------------------------------------------------------*/
4979 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4980 /*-----------------------------------------------------------------*/
4982 optimizeSWAP (ast * root)
4984 /* will look for trees of the form
4985 (?expr << 4) | (?expr >> 4) or
4986 (?expr >> 4) | (?expr << 4) will make that
4987 into a SWAP : operation ..
4988 note : by 4 I mean (number of bits required to hold the
4990 /* if the root operations is not a | operation the not */
4991 if (!IS_BITOR (root))
4994 /* (?expr << 4) | (?expr >> 4) */
4995 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4996 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4999 if (!SPEC_USIGN (TETYPE (root->left->left)))
5002 if (!IS_AST_LIT_VALUE (root->left->right) ||
5003 !IS_AST_LIT_VALUE (root->right->right))
5006 /* make sure it is the same expression */
5007 if (!isAstEqual (root->left->left,
5011 if (AST_LIT_VALUE (root->left->right) !=
5012 (getSize (TTYPE (root->left->left)) * 4))
5015 if (AST_LIT_VALUE (root->right->right) !=
5016 (getSize (TTYPE (root->left->left)) * 4))
5019 /* make sure the port supports SWAP */
5020 if (port->hasExtBitOp
5021 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5024 /* found it : create the AST */
5025 return newNode (SWAP, root->left->left, NULL);
5029 /* not found return root */
5033 /*-----------------------------------------------------------------*/
5034 /* optimizeCompare - otimizes compares for bit variables */
5035 /*-----------------------------------------------------------------*/
5037 optimizeCompare (ast * root)
5039 ast *optExpr = NULL;
5042 unsigned int litValue;
5044 /* if nothing then return nothing */
5048 /* if not a compare op then do leaves */
5049 if (!IS_COMPARE_OP (root))
5051 root->left = optimizeCompare (root->left);
5052 root->right = optimizeCompare (root->right);
5056 /* if left & right are the same then depending
5057 of the operation do */
5058 if (isAstEqual (root->left, root->right))
5060 switch (root->opval.op)
5065 optExpr = newAst_VALUE (constVal ("0"));
5070 optExpr = newAst_VALUE (constVal ("1"));
5074 return decorateType (optExpr, RESULT_CHECK);
5077 vleft = (root->left->type == EX_VALUE ?
5078 root->left->opval.val : NULL);
5080 vright = (root->right->type == EX_VALUE ?
5081 root->right->opval.val : NULL);
5083 /* if left is a BITVAR in BITSPACE */
5084 /* and right is a LITERAL then opt- */
5085 /* imize else do nothing */
5086 if (vleft && vright &&
5087 IS_BITVAR (vleft->etype) &&
5088 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5089 IS_LITERAL (vright->etype))
5092 /* if right side > 1 then comparison may never succeed */
5093 if ((litValue = (int) floatFromVal (vright)) > 1)
5095 werror (W_BAD_COMPARE);
5101 switch (root->opval.op)
5103 case '>': /* bit value greater than 1 cannot be */
5104 werror (W_BAD_COMPARE);
5108 case '<': /* bit value < 1 means 0 */
5110 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5113 case LE_OP: /* bit value <= 1 means no check */
5114 optExpr = newAst_VALUE (vright);
5117 case GE_OP: /* bit value >= 1 means only check for = */
5119 optExpr = newAst_VALUE (vleft);
5124 { /* literal is zero */
5125 switch (root->opval.op)
5127 case '<': /* bit value < 0 cannot be */
5128 werror (W_BAD_COMPARE);
5132 case '>': /* bit value > 0 means 1 */
5134 optExpr = newAst_VALUE (vleft);
5137 case LE_OP: /* bit value <= 0 means no check */
5138 case GE_OP: /* bit value >= 0 means no check */
5139 werror (W_BAD_COMPARE);
5143 case EQ_OP: /* bit == 0 means ! of bit */
5144 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5148 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5149 } /* end-of-if of BITVAR */
5154 /*-----------------------------------------------------------------*/
5155 /* addSymToBlock : adds the symbol to the first block we find */
5156 /*-----------------------------------------------------------------*/
5158 addSymToBlock (symbol * sym, ast * tree)
5160 /* reached end of tree or a leaf */
5161 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5165 if (IS_AST_OP (tree) &&
5166 tree->opval.op == BLOCK)
5169 symbol *lsym = copySymbol (sym);
5171 lsym->next = AST_VALUES (tree, sym);
5172 AST_VALUES (tree, sym) = lsym;
5176 addSymToBlock (sym, tree->left);
5177 addSymToBlock (sym, tree->right);
5180 /*-----------------------------------------------------------------*/
5181 /* processRegParms - do processing for register parameters */
5182 /*-----------------------------------------------------------------*/
5184 processRegParms (value * args, ast * body)
5188 if (IS_REGPARM (args->etype))
5189 addSymToBlock (args->sym, body);
5194 /*-----------------------------------------------------------------*/
5195 /* resetParmKey - resets the operandkeys for the symbols */
5196 /*-----------------------------------------------------------------*/
5197 DEFSETFUNC (resetParmKey)
5208 /*-----------------------------------------------------------------*/
5209 /* createFunction - This is the key node that calls the iCode for */
5210 /* generating the code for a function. Note code */
5211 /* is generated function by function, later when */
5212 /* add inter-procedural analysis this will change */
5213 /*-----------------------------------------------------------------*/
5215 createFunction (symbol * name, ast * body)
5221 iCode *piCode = NULL;
5223 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5224 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5226 /* if check function return 0 then some problem */
5227 if (checkFunction (name, NULL) == 0)
5230 /* create a dummy block if none exists */
5232 body = newNode (BLOCK, NULL, NULL);
5236 /* check if the function name already in the symbol table */
5237 if ((csym = findSym (SymbolTab, NULL, name->name)))
5240 /* special case for compiler defined functions
5241 we need to add the name to the publics list : this
5242 actually means we are now compiling the compiler
5246 addSet (&publics, name);
5252 allocVariables (name);
5254 name->lastLine = mylineno;
5257 /* set the stack pointer */
5258 /* PENDING: check this for the mcs51 */
5259 stackPtr = -port->stack.direction * port->stack.call_overhead;
5260 if (IFFUNC_ISISR (name->type))
5261 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5262 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5263 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5265 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5267 fetype = getSpec (name->type); /* get the specifier for the function */
5268 /* if this is a reentrant function then */
5269 if (IFFUNC_ISREENT (name->type))
5272 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5274 /* do processing for parameters that are passed in registers */
5275 processRegParms (FUNC_ARGS(name->type), body);
5277 /* set the stack pointer */
5281 /* allocate & autoinit the block variables */
5282 processBlockVars (body, &stack, ALLOCATE);
5284 /* save the stack information */
5285 if (options.useXstack)
5286 name->xstack = SPEC_STAK (fetype) = stack;
5288 name->stack = SPEC_STAK (fetype) = stack;
5290 /* name needs to be mangled */
5291 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5293 body = resolveSymbols (body); /* resolve the symbols */
5294 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5297 ex = newAst_VALUE (symbolVal (name)); /* create name */
5298 ex = newNode (FUNCTION, ex, body);
5299 ex->values.args = FUNC_ARGS(name->type);
5301 if (options.dump_tree) PA(ex);
5304 werror (E_FUNC_NO_CODE, name->name);
5308 /* create the node & generate intermediate code */
5310 codeOutFile = code->oFile;
5311 piCode = iCodeFromAst (ex);
5315 werror (E_FUNC_NO_CODE, name->name);
5319 eBBlockFromiCode (piCode);
5321 /* if there are any statics then do them */
5324 GcurMemmap = statsg;
5325 codeOutFile = statsg->oFile;
5326 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5332 /* dealloc the block variables */
5333 processBlockVars (body, &stack, DEALLOCATE);
5334 outputDebugStackSymbols();
5335 /* deallocate paramaters */
5336 deallocParms (FUNC_ARGS(name->type));
5338 if (IFFUNC_ISREENT (name->type))
5341 /* we are done freeup memory & cleanup */
5343 if (port->reset_labelKey) labelKey = 1;
5345 FUNC_HASBODY(name->type) = 1;
5346 addSet (&operKeyReset, name);
5347 applyToSet (operKeyReset, resetParmKey);
5352 cleanUpLevel (LabelTab, 0);
5353 cleanUpBlock (StructTab, 1);
5354 cleanUpBlock (TypedefTab, 1);
5356 xstack->syms = NULL;
5357 istack->syms = NULL;
5362 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5363 /*-----------------------------------------------------------------*/
5364 /* ast_print : prints the ast (for debugging purposes) */
5365 /*-----------------------------------------------------------------*/
5367 void ast_print (ast * tree, FILE *outfile, int indent)
5372 /* can print only decorated trees */
5373 if (!tree->decorated) return;
5375 /* if any child is an error | this one is an error do nothing */
5376 if (tree->isError ||
5377 (tree->left && tree->left->isError) ||
5378 (tree->right && tree->right->isError)) {
5379 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5383 /* print the line */
5384 /* if not block & function */
5385 if (tree->type == EX_OP &&
5386 (tree->opval.op != FUNCTION &&
5387 tree->opval.op != BLOCK &&
5388 tree->opval.op != NULLOP)) {
5391 if (tree->opval.op == FUNCTION) {
5393 value *args=FUNC_ARGS(tree->left->opval.val->type);
5394 fprintf(outfile,"FUNCTION (%s=%p) type (",
5395 tree->left->opval.val->name, tree);
5396 printTypeChain (tree->left->opval.val->type->next,outfile);
5397 fprintf(outfile,") args (");
5400 fprintf (outfile, ", ");
5402 printTypeChain (args ? args->type : NULL, outfile);
5404 args= args ? args->next : NULL;
5406 fprintf(outfile,")\n");
5407 ast_print(tree->left,outfile,indent);
5408 ast_print(tree->right,outfile,indent);
5411 if (tree->opval.op == BLOCK) {
5412 symbol *decls = tree->values.sym;
5413 INDENT(indent,outfile);
5414 fprintf(outfile,"{\n");
5416 INDENT(indent+2,outfile);
5417 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5418 decls->name, decls);
5419 printTypeChain(decls->type,outfile);
5420 fprintf(outfile,")\n");
5422 decls = decls->next;
5424 ast_print(tree->right,outfile,indent+2);
5425 INDENT(indent,outfile);
5426 fprintf(outfile,"}\n");
5429 if (tree->opval.op == NULLOP) {
5430 ast_print(tree->left,outfile,indent);
5431 ast_print(tree->right,outfile,indent);
5434 INDENT(indent,outfile);
5436 /*------------------------------------------------------------------*/
5437 /*----------------------------*/
5438 /* leaf has been reached */
5439 /*----------------------------*/
5440 /* if this is of type value */
5441 /* just get the type */
5442 if (tree->type == EX_VALUE) {
5444 if (IS_LITERAL (tree->opval.val->etype)) {
5445 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5446 if (SPEC_USIGN (tree->opval.val->etype))
5447 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5449 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5450 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5451 floatFromVal(tree->opval.val));
5452 } else if (tree->opval.val->sym) {
5453 /* if the undefined flag is set then give error message */
5454 if (tree->opval.val->sym->undefined) {
5455 fprintf(outfile,"UNDEFINED SYMBOL ");
5457 fprintf(outfile,"SYMBOL ");
5459 fprintf(outfile,"(%s=%p)",
5460 tree->opval.val->sym->name,tree);
5463 fprintf(outfile," type (");
5464 printTypeChain(tree->ftype,outfile);
5465 fprintf(outfile,")\n");
5467 fprintf(outfile,"\n");
5472 /* if type link for the case of cast */
5473 if (tree->type == EX_LINK) {
5474 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5475 printTypeChain(tree->opval.lnk,outfile);
5476 fprintf(outfile,")\n");
5481 /* depending on type of operator do */
5483 switch (tree->opval.op) {
5484 /*------------------------------------------------------------------*/
5485 /*----------------------------*/
5487 /*----------------------------*/
5489 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5490 printTypeChain(tree->ftype,outfile);
5491 fprintf(outfile,")\n");
5492 ast_print(tree->left,outfile,indent+2);
5493 ast_print(tree->right,outfile,indent+2);
5496 /*------------------------------------------------------------------*/
5497 /*----------------------------*/
5499 /*----------------------------*/
5501 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5502 printTypeChain(tree->ftype,outfile);
5503 fprintf(outfile,")\n");
5504 ast_print(tree->left,outfile,indent+2);
5505 ast_print(tree->right,outfile,indent+2);
5508 /*------------------------------------------------------------------*/
5509 /*----------------------------*/
5510 /* struct/union pointer */
5511 /*----------------------------*/
5513 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5514 printTypeChain(tree->ftype,outfile);
5515 fprintf(outfile,")\n");
5516 ast_print(tree->left,outfile,indent+2);
5517 ast_print(tree->right,outfile,indent+2);
5520 /*------------------------------------------------------------------*/
5521 /*----------------------------*/
5522 /* ++/-- operation */
5523 /*----------------------------*/
5526 fprintf(outfile,"post-");
5528 fprintf(outfile,"pre-");
5529 fprintf(outfile,"INC_OP (%p) type (",tree);
5530 printTypeChain(tree->ftype,outfile);
5531 fprintf(outfile,")\n");
5532 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5533 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5538 fprintf(outfile,"post-");
5540 fprintf(outfile,"pre-");
5541 fprintf(outfile,"DEC_OP (%p) type (",tree);
5542 printTypeChain(tree->ftype,outfile);
5543 fprintf(outfile,")\n");
5544 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5545 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5548 /*------------------------------------------------------------------*/
5549 /*----------------------------*/
5551 /*----------------------------*/
5554 fprintf(outfile,"& (%p) type (",tree);
5555 printTypeChain(tree->ftype,outfile);
5556 fprintf(outfile,")\n");
5557 ast_print(tree->left,outfile,indent+2);
5558 ast_print(tree->right,outfile,indent+2);
5560 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5561 printTypeChain(tree->ftype,outfile);
5562 fprintf(outfile,")\n");
5563 ast_print(tree->left,outfile,indent+2);
5564 ast_print(tree->right,outfile,indent+2);
5567 /*----------------------------*/
5569 /*----------------------------*/
5571 fprintf(outfile,"OR (%p) type (",tree);
5572 printTypeChain(tree->ftype,outfile);
5573 fprintf(outfile,")\n");
5574 ast_print(tree->left,outfile,indent+2);
5575 ast_print(tree->right,outfile,indent+2);
5577 /*------------------------------------------------------------------*/
5578 /*----------------------------*/
5580 /*----------------------------*/
5582 fprintf(outfile,"XOR (%p) type (",tree);
5583 printTypeChain(tree->ftype,outfile);
5584 fprintf(outfile,")\n");
5585 ast_print(tree->left,outfile,indent+2);
5586 ast_print(tree->right,outfile,indent+2);
5589 /*------------------------------------------------------------------*/
5590 /*----------------------------*/
5592 /*----------------------------*/
5594 fprintf(outfile,"DIV (%p) type (",tree);
5595 printTypeChain(tree->ftype,outfile);
5596 fprintf(outfile,")\n");
5597 ast_print(tree->left,outfile,indent+2);
5598 ast_print(tree->right,outfile,indent+2);
5600 /*------------------------------------------------------------------*/
5601 /*----------------------------*/
5603 /*----------------------------*/
5605 fprintf(outfile,"MOD (%p) type (",tree);
5606 printTypeChain(tree->ftype,outfile);
5607 fprintf(outfile,")\n");
5608 ast_print(tree->left,outfile,indent+2);
5609 ast_print(tree->right,outfile,indent+2);
5612 /*------------------------------------------------------------------*/
5613 /*----------------------------*/
5614 /* address dereference */
5615 /*----------------------------*/
5616 case '*': /* can be unary : if right is null then unary operation */
5618 fprintf(outfile,"DEREF (%p) type (",tree);
5619 printTypeChain(tree->ftype,outfile);
5620 fprintf(outfile,")\n");
5621 ast_print(tree->left,outfile,indent+2);
5624 /*------------------------------------------------------------------*/
5625 /*----------------------------*/
5626 /* multiplication */
5627 /*----------------------------*/
5628 fprintf(outfile,"MULT (%p) type (",tree);
5629 printTypeChain(tree->ftype,outfile);
5630 fprintf(outfile,")\n");
5631 ast_print(tree->left,outfile,indent+2);
5632 ast_print(tree->right,outfile,indent+2);
5636 /*------------------------------------------------------------------*/
5637 /*----------------------------*/
5638 /* unary '+' operator */
5639 /*----------------------------*/
5643 fprintf(outfile,"UPLUS (%p) type (",tree);
5644 printTypeChain(tree->ftype,outfile);
5645 fprintf(outfile,")\n");
5646 ast_print(tree->left,outfile,indent+2);
5648 /*------------------------------------------------------------------*/
5649 /*----------------------------*/
5651 /*----------------------------*/
5652 fprintf(outfile,"ADD (%p) type (",tree);
5653 printTypeChain(tree->ftype,outfile);
5654 fprintf(outfile,")\n");
5655 ast_print(tree->left,outfile,indent+2);
5656 ast_print(tree->right,outfile,indent+2);
5659 /*------------------------------------------------------------------*/
5660 /*----------------------------*/
5662 /*----------------------------*/
5663 case '-': /* can be unary */
5665 fprintf(outfile,"UMINUS (%p) type (",tree);
5666 printTypeChain(tree->ftype,outfile);
5667 fprintf(outfile,")\n");
5668 ast_print(tree->left,outfile,indent+2);
5670 /*------------------------------------------------------------------*/
5671 /*----------------------------*/
5673 /*----------------------------*/
5674 fprintf(outfile,"SUB (%p) type (",tree);
5675 printTypeChain(tree->ftype,outfile);
5676 fprintf(outfile,")\n");
5677 ast_print(tree->left,outfile,indent+2);
5678 ast_print(tree->right,outfile,indent+2);
5681 /*------------------------------------------------------------------*/
5682 /*----------------------------*/
5684 /*----------------------------*/
5686 fprintf(outfile,"COMPL (%p) type (",tree);
5687 printTypeChain(tree->ftype,outfile);
5688 fprintf(outfile,")\n");
5689 ast_print(tree->left,outfile,indent+2);
5691 /*------------------------------------------------------------------*/
5692 /*----------------------------*/
5694 /*----------------------------*/
5696 fprintf(outfile,"NOT (%p) type (",tree);
5697 printTypeChain(tree->ftype,outfile);
5698 fprintf(outfile,")\n");
5699 ast_print(tree->left,outfile,indent+2);
5701 /*------------------------------------------------------------------*/
5702 /*----------------------------*/
5704 /*----------------------------*/
5706 fprintf(outfile,"RRC (%p) type (",tree);
5707 printTypeChain(tree->ftype,outfile);
5708 fprintf(outfile,")\n");
5709 ast_print(tree->left,outfile,indent+2);
5713 fprintf(outfile,"RLC (%p) type (",tree);
5714 printTypeChain(tree->ftype,outfile);
5715 fprintf(outfile,")\n");
5716 ast_print(tree->left,outfile,indent+2);
5719 fprintf(outfile,"SWAP (%p) type (",tree);
5720 printTypeChain(tree->ftype,outfile);
5721 fprintf(outfile,")\n");
5722 ast_print(tree->left,outfile,indent+2);
5725 fprintf(outfile,"GETHBIT (%p) type (",tree);
5726 printTypeChain(tree->ftype,outfile);
5727 fprintf(outfile,")\n");
5728 ast_print(tree->left,outfile,indent+2);
5731 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5732 printTypeChain(tree->ftype,outfile);
5733 fprintf(outfile,")\n");
5734 ast_print(tree->left,outfile,indent+2);
5735 ast_print(tree->right,outfile,indent+2);
5738 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5739 printTypeChain(tree->ftype,outfile);
5740 fprintf(outfile,")\n");
5741 ast_print(tree->left,outfile,indent+2);
5742 ast_print(tree->right,outfile,indent+2);
5744 /*------------------------------------------------------------------*/
5745 /*----------------------------*/
5747 /*----------------------------*/
5748 case CAST: /* change the type */
5749 fprintf(outfile,"CAST (%p) from type (",tree);
5750 printTypeChain(tree->right->ftype,outfile);
5751 fprintf(outfile,") to type (");
5752 printTypeChain(tree->ftype,outfile);
5753 fprintf(outfile,")\n");
5754 ast_print(tree->right,outfile,indent+2);
5758 fprintf(outfile,"ANDAND (%p) type (",tree);
5759 printTypeChain(tree->ftype,outfile);
5760 fprintf(outfile,")\n");
5761 ast_print(tree->left,outfile,indent+2);
5762 ast_print(tree->right,outfile,indent+2);
5765 fprintf(outfile,"OROR (%p) type (",tree);
5766 printTypeChain(tree->ftype,outfile);
5767 fprintf(outfile,")\n");
5768 ast_print(tree->left,outfile,indent+2);
5769 ast_print(tree->right,outfile,indent+2);
5772 /*------------------------------------------------------------------*/
5773 /*----------------------------*/
5774 /* comparison operators */
5775 /*----------------------------*/
5777 fprintf(outfile,"GT(>) (%p) type (",tree);
5778 printTypeChain(tree->ftype,outfile);
5779 fprintf(outfile,")\n");
5780 ast_print(tree->left,outfile,indent+2);
5781 ast_print(tree->right,outfile,indent+2);
5784 fprintf(outfile,"LT(<) (%p) type (",tree);
5785 printTypeChain(tree->ftype,outfile);
5786 fprintf(outfile,")\n");
5787 ast_print(tree->left,outfile,indent+2);
5788 ast_print(tree->right,outfile,indent+2);
5791 fprintf(outfile,"LE(<=) (%p) type (",tree);
5792 printTypeChain(tree->ftype,outfile);
5793 fprintf(outfile,")\n");
5794 ast_print(tree->left,outfile,indent+2);
5795 ast_print(tree->right,outfile,indent+2);
5798 fprintf(outfile,"GE(>=) (%p) type (",tree);
5799 printTypeChain(tree->ftype,outfile);
5800 fprintf(outfile,")\n");
5801 ast_print(tree->left,outfile,indent+2);
5802 ast_print(tree->right,outfile,indent+2);
5805 fprintf(outfile,"EQ(==) (%p) type (",tree);
5806 printTypeChain(tree->ftype,outfile);
5807 fprintf(outfile,")\n");
5808 ast_print(tree->left,outfile,indent+2);
5809 ast_print(tree->right,outfile,indent+2);
5812 fprintf(outfile,"NE(!=) (%p) type (",tree);
5813 printTypeChain(tree->ftype,outfile);
5814 fprintf(outfile,")\n");
5815 ast_print(tree->left,outfile,indent+2);
5816 ast_print(tree->right,outfile,indent+2);
5817 /*------------------------------------------------------------------*/
5818 /*----------------------------*/
5820 /*----------------------------*/
5821 case SIZEOF: /* evaluate wihout code generation */
5822 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5825 /*------------------------------------------------------------------*/
5826 /*----------------------------*/
5827 /* conditional operator '?' */
5828 /*----------------------------*/
5830 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5831 printTypeChain(tree->ftype,outfile);
5832 fprintf(outfile,")\n");
5833 ast_print(tree->left,outfile,indent+2);
5834 ast_print(tree->right,outfile,indent+2);
5838 fprintf(outfile,"COLON(:) (%p) type (",tree);
5839 printTypeChain(tree->ftype,outfile);
5840 fprintf(outfile,")\n");
5841 ast_print(tree->left,outfile,indent+2);
5842 ast_print(tree->right,outfile,indent+2);
5845 /*------------------------------------------------------------------*/
5846 /*----------------------------*/
5847 /* assignment operators */
5848 /*----------------------------*/
5850 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5851 printTypeChain(tree->ftype,outfile);
5852 fprintf(outfile,")\n");
5853 ast_print(tree->left,outfile,indent+2);
5854 ast_print(tree->right,outfile,indent+2);
5857 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5858 printTypeChain(tree->ftype,outfile);
5859 fprintf(outfile,")\n");
5860 ast_print(tree->left,outfile,indent+2);
5861 ast_print(tree->right,outfile,indent+2);
5864 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5865 printTypeChain(tree->ftype,outfile);
5866 fprintf(outfile,")\n");
5867 ast_print(tree->left,outfile,indent+2);
5868 ast_print(tree->right,outfile,indent+2);
5871 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5872 printTypeChain(tree->ftype,outfile);
5873 fprintf(outfile,")\n");
5874 ast_print(tree->left,outfile,indent+2);
5875 ast_print(tree->right,outfile,indent+2);
5878 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5879 printTypeChain(tree->ftype,outfile);
5880 fprintf(outfile,")\n");
5881 ast_print(tree->left,outfile,indent+2);
5882 ast_print(tree->right,outfile,indent+2);
5885 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5886 printTypeChain(tree->ftype,outfile);
5887 fprintf(outfile,")\n");
5888 ast_print(tree->left,outfile,indent+2);
5889 ast_print(tree->right,outfile,indent+2);
5892 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5893 printTypeChain(tree->ftype,outfile);
5894 fprintf(outfile,")\n");
5895 ast_print(tree->left,outfile,indent+2);
5896 ast_print(tree->right,outfile,indent+2);
5898 /*------------------------------------------------------------------*/
5899 /*----------------------------*/
5901 /*----------------------------*/
5903 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5904 printTypeChain(tree->ftype,outfile);
5905 fprintf(outfile,")\n");
5906 ast_print(tree->left,outfile,indent+2);
5907 ast_print(tree->right,outfile,indent+2);
5909 /*------------------------------------------------------------------*/
5910 /*----------------------------*/
5912 /*----------------------------*/
5914 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5915 printTypeChain(tree->ftype,outfile);
5916 fprintf(outfile,")\n");
5917 ast_print(tree->left,outfile,indent+2);
5918 ast_print(tree->right,outfile,indent+2);
5920 /*------------------------------------------------------------------*/
5921 /*----------------------------*/
5922 /* straight assignemnt */
5923 /*----------------------------*/
5925 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5926 printTypeChain(tree->ftype,outfile);
5927 fprintf(outfile,")\n");
5928 ast_print(tree->left,outfile,indent+2);
5929 ast_print(tree->right,outfile,indent+2);
5931 /*------------------------------------------------------------------*/
5932 /*----------------------------*/
5933 /* comma operator */
5934 /*----------------------------*/
5936 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5937 printTypeChain(tree->ftype,outfile);
5938 fprintf(outfile,")\n");
5939 ast_print(tree->left,outfile,indent+2);
5940 ast_print(tree->right,outfile,indent+2);
5942 /*------------------------------------------------------------------*/
5943 /*----------------------------*/
5945 /*----------------------------*/
5948 fprintf(outfile,"CALL (%p) type (",tree);
5949 printTypeChain(tree->ftype,outfile);
5950 fprintf(outfile,")\n");
5951 ast_print(tree->left,outfile,indent+2);
5952 ast_print(tree->right,outfile,indent+2);
5955 fprintf(outfile,"PARMS\n");
5956 ast_print(tree->left,outfile,indent+2);
5957 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5958 ast_print(tree->right,outfile,indent+2);
5961 /*------------------------------------------------------------------*/
5962 /*----------------------------*/
5963 /* return statement */
5964 /*----------------------------*/
5966 fprintf(outfile,"RETURN (%p) type (",tree);
5968 printTypeChain(tree->right->ftype,outfile);
5970 fprintf(outfile,")\n");
5971 ast_print(tree->right,outfile,indent+2);
5973 /*------------------------------------------------------------------*/
5974 /*----------------------------*/
5975 /* label statement */
5976 /*----------------------------*/
5978 fprintf(outfile,"LABEL (%p)\n",tree);
5979 ast_print(tree->left,outfile,indent+2);
5980 ast_print(tree->right,outfile,indent);
5982 /*------------------------------------------------------------------*/
5983 /*----------------------------*/
5984 /* switch statement */
5985 /*----------------------------*/
5989 fprintf(outfile,"SWITCH (%p) ",tree);
5990 ast_print(tree->left,outfile,0);
5991 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5992 INDENT(indent+2,outfile);
5993 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5994 (int) floatFromVal(val),
5995 tree->values.switchVals.swNum,
5996 (int) floatFromVal(val));
5998 ast_print(tree->right,outfile,indent);
6001 /*------------------------------------------------------------------*/
6002 /*----------------------------*/
6004 /*----------------------------*/
6006 fprintf(outfile,"IF (%p) \n",tree);
6007 ast_print(tree->left,outfile,indent+2);
6008 if (tree->trueLabel) {
6009 INDENT(indent+2,outfile);
6010 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6012 if (tree->falseLabel) {
6013 INDENT(indent+2,outfile);
6014 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6016 ast_print(tree->right,outfile,indent+2);
6018 /*----------------------------*/
6019 /* goto Statement */
6020 /*----------------------------*/
6022 fprintf(outfile,"GOTO (%p) \n",tree);
6023 ast_print(tree->left,outfile,indent+2);
6024 fprintf(outfile,"\n");
6026 /*------------------------------------------------------------------*/
6027 /*----------------------------*/
6029 /*----------------------------*/
6031 fprintf(outfile,"FOR (%p) \n",tree);
6032 if (AST_FOR( tree, initExpr)) {
6033 INDENT(indent+2,outfile);
6034 fprintf(outfile,"INIT EXPR ");
6035 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6037 if (AST_FOR( tree, condExpr)) {
6038 INDENT(indent+2,outfile);
6039 fprintf(outfile,"COND EXPR ");
6040 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6042 if (AST_FOR( tree, loopExpr)) {
6043 INDENT(indent+2,outfile);
6044 fprintf(outfile,"LOOP EXPR ");
6045 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6047 fprintf(outfile,"FOR LOOP BODY \n");
6048 ast_print(tree->left,outfile,indent+2);
6051 fprintf(outfile,"CRITICAL (%p) \n",tree);
6052 ast_print(tree->left,outfile,indent+2);
6060 ast_print(t,stdout,0);
6065 /*-----------------------------------------------------------------*/
6066 /* astErrors : returns non-zero if errors present in tree */
6067 /*-----------------------------------------------------------------*/
6068 int astErrors(ast *t)
6077 if (t->type == EX_VALUE
6078 && t->opval.val->sym
6079 && t->opval.val->sym->undefined)
6082 errors += astErrors(t->left);
6083 errors += astErrors(t->right);