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 (getSize (tree->etype) <= 1)
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 tree->left = addCast (tree->left, resultType, FALSE);
2566 tree->right = addCast (tree->right, resultType, FALSE);
2567 TTYPE (tree) = computeType (LTYPE (tree),
2571 TETYPE (tree) = getSpec (TTYPE (tree));
2573 /* if left is a literal exchange left & right */
2574 if (IS_LITERAL (LTYPE (tree)))
2576 ast *tTree = tree->left;
2577 tree->left = tree->right;
2578 tree->right = tTree;
2581 /* if right is a literal and */
2582 /* we can find a 2nd literal in a and-tree then */
2583 /* rearrange the tree */
2584 if (IS_LITERAL (RTYPE (tree)))
2587 ast *litTree = searchLitOp (tree, &parent, "&");
2590 ast *tTree = litTree->left;
2591 litTree->left = tree->right;
2592 tree->right = tTree;
2593 /* both operands in tTree are literal now */
2594 decorateType (parent, RESULT_CHECK);
2598 LRVAL (tree) = RRVAL (tree) = 1;
2603 /*------------------------------------------------------------------*/
2604 /*----------------------------*/
2606 /*----------------------------*/
2607 p = newLink (DECLARATOR);
2608 /* if bit field then error */
2609 if (IS_BITVAR (tree->left->etype))
2611 werror (E_ILLEGAL_ADDR, "address of bit variable");
2612 goto errorTreeReturn;
2615 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2617 werror (E_ILLEGAL_ADDR, "address of register variable");
2618 goto errorTreeReturn;
2621 if (IS_FUNC (LTYPE (tree)))
2623 // this ought to be ignored
2624 return (tree->left);
2627 if (IS_LITERAL(LTYPE(tree)))
2629 werror (E_ILLEGAL_ADDR, "address of literal");
2630 goto errorTreeReturn;
2635 werror (E_LVALUE_REQUIRED, "address of");
2636 goto errorTreeReturn;
2639 DCL_TYPE (p) = POINTER;
2640 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2641 DCL_TYPE (p) = CPOINTER;
2642 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2643 DCL_TYPE (p) = FPOINTER;
2644 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2645 DCL_TYPE (p) = PPOINTER;
2646 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2647 DCL_TYPE (p) = IPOINTER;
2648 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2649 DCL_TYPE (p) = EEPPOINTER;
2650 else if (SPEC_OCLS(tree->left->etype))
2651 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2653 DCL_TYPE (p) = POINTER;
2655 if (IS_AST_SYM_VALUE (tree->left))
2657 AST_SYMBOL (tree->left)->addrtaken = 1;
2658 AST_SYMBOL (tree->left)->allocreq = 1;
2661 p->next = LTYPE (tree);
2663 TETYPE (tree) = getSpec (TTYPE (tree));
2668 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2669 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2671 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2672 AST_SYMBOL(tree->left->right));
2673 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2674 valueFromLit(element->offset));
2677 tree->type = EX_VALUE;
2678 tree->values.literalFromCast = 1;
2684 /*------------------------------------------------------------------*/
2685 /*----------------------------*/
2687 /*----------------------------*/
2689 /* if the rewrite succeeds then don't go any furthur */
2691 ast *wtree = optimizeRRCRLC (tree);
2693 return decorateType (wtree, RESULT_CHECK);
2695 wtree = optimizeSWAP (tree);
2697 return decorateType (wtree, RESULT_CHECK);
2700 /* if left is a literal exchange left & right */
2701 if (IS_LITERAL (LTYPE (tree)))
2703 ast *tTree = tree->left;
2704 tree->left = tree->right;
2705 tree->right = tTree;
2708 /* if right is a literal and */
2709 /* we can find a 2nd literal in a or-tree then */
2710 /* rearrange the tree */
2711 if (IS_LITERAL (RTYPE (tree)))
2714 ast *litTree = searchLitOp (tree, &parent, "|");
2717 ast *tTree = litTree->left;
2718 litTree->left = tree->right;
2719 tree->right = tTree;
2720 /* both operands in tTree are literal now */
2721 decorateType (parent, RESULT_CHECK);
2726 /*------------------------------------------------------------------*/
2727 /*----------------------------*/
2729 /*----------------------------*/
2731 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2733 werror (E_BITWISE_OP);
2734 werror (W_CONTINUE, "left & right types are ");
2735 printTypeChain (LTYPE (tree), stderr);
2736 fprintf (stderr, ",");
2737 printTypeChain (RTYPE (tree), stderr);
2738 fprintf (stderr, "\n");
2739 goto errorTreeReturn;
2742 /* if they are both literal then */
2743 /* rewrite the tree */
2744 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2746 tree->type = EX_VALUE;
2747 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2748 valFromType (RETYPE (tree)),
2750 tree->right = tree->left = NULL;
2751 TETYPE (tree) = tree->opval.val->etype;
2752 TTYPE (tree) = tree->opval.val->type;
2756 /* if left is a literal exchange left & right */
2757 if (IS_LITERAL (LTYPE (tree)))
2759 ast *tTree = tree->left;
2760 tree->left = tree->right;
2761 tree->right = tTree;
2764 /* if right is a literal and */
2765 /* we can find a 2nd literal in a xor-tree then */
2766 /* rearrange the tree */
2767 if (IS_LITERAL (RTYPE (tree)) &&
2768 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2771 ast *litTree = searchLitOp (tree, &parent, "^");
2774 ast *tTree = litTree->left;
2775 litTree->left = tree->right;
2776 tree->right = tTree;
2777 /* both operands in litTree are literal now */
2778 decorateType (parent, RESULT_CHECK);
2782 LRVAL (tree) = RRVAL (tree) = 1;
2783 tree->left = addCast (tree->left, resultType, FALSE);
2784 tree->right = addCast (tree->right, resultType, FALSE);
2785 TETYPE (tree) = getSpec (TTYPE (tree) =
2786 computeType (LTYPE (tree),
2793 /*------------------------------------------------------------------*/
2794 /*----------------------------*/
2796 /*----------------------------*/
2798 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2800 werror (E_INVALID_OP, "divide");
2801 goto errorTreeReturn;
2803 /* if they are both literal then */
2804 /* rewrite the tree */
2805 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2807 tree->type = EX_VALUE;
2808 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2809 valFromType (RETYPE (tree)));
2810 tree->right = tree->left = NULL;
2811 TETYPE (tree) = getSpec (TTYPE (tree) =
2812 tree->opval.val->type);
2816 LRVAL (tree) = RRVAL (tree) = 1;
2818 TETYPE (tree) = getSpec (TTYPE (tree) =
2819 computeType (LTYPE (tree),
2824 /* if right is a literal and */
2825 /* left is also a division by a literal then */
2826 /* rearrange the tree */
2827 if (IS_LITERAL (RTYPE (tree))
2828 /* avoid infinite loop */
2829 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2832 ast *litTree = searchLitOp (tree, &parent, "/");
2835 if (IS_LITERAL (RTYPE (litTree)))
2838 litTree->right = newNode ('*', litTree->right, tree->right);
2839 litTree->right->lineno = tree->lineno;
2841 tree->right->opval.val = constVal ("1");
2842 decorateType (parent, RESULT_CHECK);
2846 /* litTree->left is literal: no gcse possible.
2847 We can't call decorateType(parent, RESULT_CHECK), because
2848 this would cause an infinit loop. */
2849 parent->decorated = 1;
2850 decorateType (litTree, RESULT_CHECK);
2857 /*------------------------------------------------------------------*/
2858 /*----------------------------*/
2860 /*----------------------------*/
2862 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2864 werror (E_BITWISE_OP);
2865 werror (W_CONTINUE, "left & right types are ");
2866 printTypeChain (LTYPE (tree), stderr);
2867 fprintf (stderr, ",");
2868 printTypeChain (RTYPE (tree), stderr);
2869 fprintf (stderr, "\n");
2870 goto errorTreeReturn;
2872 /* if they are both literal then */
2873 /* rewrite the tree */
2874 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2876 tree->type = EX_VALUE;
2877 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2878 valFromType (RETYPE (tree)));
2879 tree->right = tree->left = NULL;
2880 TETYPE (tree) = getSpec (TTYPE (tree) =
2881 tree->opval.val->type);
2884 LRVAL (tree) = RRVAL (tree) = 1;
2885 TETYPE (tree) = getSpec (TTYPE (tree) =
2886 computeType (LTYPE (tree),
2892 /*------------------------------------------------------------------*/
2893 /*----------------------------*/
2894 /* address dereference */
2895 /*----------------------------*/
2896 case '*': /* can be unary : if right is null then unary operation */
2899 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2901 werror (E_PTR_REQD);
2902 goto errorTreeReturn;
2907 werror (E_LVALUE_REQUIRED, "pointer deref");
2908 goto errorTreeReturn;
2910 if (IS_ADDRESS_OF_OP(tree->left))
2912 /* replace *&obj with obj */
2913 return tree->left->left;
2915 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2916 TETYPE (tree) = getSpec (TTYPE (tree));
2917 /* adjust the storage class */
2918 switch (DCL_TYPE(tree->left->ftype)) {
2920 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2923 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2926 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2929 SPEC_SCLS (TETYPE (tree)) = 0;
2932 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2935 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2938 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2941 SPEC_SCLS (TETYPE (tree)) = 0;
2950 /*------------------------------------------------------------------*/
2951 /*----------------------------*/
2952 /* multiplication */
2953 /*----------------------------*/
2954 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2956 werror (E_INVALID_OP, "multiplication");
2957 goto errorTreeReturn;
2960 /* if they are both literal then */
2961 /* rewrite the tree */
2962 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2964 tree->type = EX_VALUE;
2965 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2966 valFromType (RETYPE (tree)));
2967 tree->right = tree->left = NULL;
2968 TETYPE (tree) = getSpec (TTYPE (tree) =
2969 tree->opval.val->type);
2973 /* if left is a literal exchange left & right */
2974 if (IS_LITERAL (LTYPE (tree)))
2976 ast *tTree = tree->left;
2977 tree->left = tree->right;
2978 tree->right = tTree;
2981 /* if right is a literal and */
2982 /* we can find a 2nd literal in a mul-tree then */
2983 /* rearrange the tree */
2984 if (IS_LITERAL (RTYPE (tree)))
2987 ast *litTree = searchLitOp (tree, &parent, "*");
2990 ast *tTree = litTree->left;
2991 litTree->left = tree->right;
2992 tree->right = tTree;
2993 /* both operands in litTree are literal now */
2994 decorateType (parent, RESULT_CHECK);
2998 LRVAL (tree) = RRVAL (tree) = 1;
2999 tree->left = addCast (tree->left, resultType, FALSE);
3000 tree->right = addCast (tree->right, resultType, FALSE);
3001 TETYPE (tree) = getSpec (TTYPE (tree) =
3002 computeType (LTYPE (tree),
3009 /*------------------------------------------------------------------*/
3010 /*----------------------------*/
3011 /* unary '+' operator */
3012 /*----------------------------*/
3017 if (!IS_ARITHMETIC (LTYPE (tree)))
3019 werror (E_UNARY_OP, '+');
3020 goto errorTreeReturn;
3023 /* if left is a literal then do it */
3024 if (IS_LITERAL (LTYPE (tree)))
3026 tree->type = EX_VALUE;
3027 tree->opval.val = valFromType (LETYPE (tree));
3029 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3033 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3037 /*------------------------------------------------------------------*/
3038 /*----------------------------*/
3040 /*----------------------------*/
3042 /* this is not a unary operation */
3043 /* if both pointers then problem */
3044 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3045 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3047 werror (E_PTR_PLUS_PTR);
3048 goto errorTreeReturn;
3051 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3052 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3054 werror (E_PLUS_INVALID, "+");
3055 goto errorTreeReturn;
3058 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3059 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3061 werror (E_PLUS_INVALID, "+");
3062 goto errorTreeReturn;
3064 /* if they are both literal then */
3065 /* rewrite the tree */
3066 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3068 tree->type = EX_VALUE;
3069 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3070 valFromType (RETYPE (tree)));
3071 tree->right = tree->left = NULL;
3072 TETYPE (tree) = getSpec (TTYPE (tree) =
3073 tree->opval.val->type);
3077 /* if the right is a pointer or left is a literal
3078 xchange left & right */
3079 if (IS_ARRAY (RTYPE (tree)) ||
3080 IS_PTR (RTYPE (tree)) ||
3081 IS_LITERAL (LTYPE (tree)))
3083 ast *tTree = tree->left;
3084 tree->left = tree->right;
3085 tree->right = tTree;
3088 /* if right is a literal and */
3089 /* left is also an addition/subtraction with a literal then */
3090 /* rearrange the tree */
3091 if (IS_LITERAL (RTYPE (tree)))
3093 ast *litTree, *parent;
3094 litTree = searchLitOp (tree, &parent, "+-");
3097 if (litTree->opval.op == '+')
3100 ast *tTree = litTree->left;
3101 litTree->left = tree->right;
3102 tree->right = tree->left;
3105 else if (litTree->opval.op == '-')
3107 if (IS_LITERAL (RTYPE (litTree)))
3110 ast *tTree = litTree->left;
3111 litTree->left = tree->right;
3112 tree->right = tTree;
3117 ast *tTree = litTree->right;
3118 litTree->right = tree->right;
3119 tree->right = tTree;
3120 litTree->opval.op = '+';
3121 tree->opval.op = '-';
3124 decorateType (parent, RESULT_CHECK);
3128 LRVAL (tree) = RRVAL (tree) = 1;
3129 /* if the left is a pointer */
3130 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3131 TETYPE (tree) = getSpec (TTYPE (tree) =
3135 tree->left = addCast (tree->left, resultType, TRUE);
3136 tree->right = addCast (tree->right, resultType, TRUE);
3137 TETYPE (tree) = getSpec (TTYPE (tree) =
3138 computeType (LTYPE (tree),
3146 /*------------------------------------------------------------------*/
3147 /*----------------------------*/
3149 /*----------------------------*/
3150 case '-': /* can be unary */
3151 /* if right is null then unary */
3155 if (!IS_ARITHMETIC (LTYPE (tree)))
3157 werror (E_UNARY_OP, tree->opval.op);
3158 goto errorTreeReturn;
3161 /* if left is a literal then do it */
3162 if (IS_LITERAL (LTYPE (tree)))
3164 tree->type = EX_VALUE;
3165 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3167 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3168 SPEC_USIGN(TETYPE(tree)) = 0;
3172 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3176 /*------------------------------------------------------------------*/
3177 /*----------------------------*/
3179 /*----------------------------*/
3181 if (!(IS_PTR (LTYPE (tree)) ||
3182 IS_ARRAY (LTYPE (tree)) ||
3183 IS_ARITHMETIC (LTYPE (tree))))
3185 werror (E_PLUS_INVALID, "-");
3186 goto errorTreeReturn;
3189 if (!(IS_PTR (RTYPE (tree)) ||
3190 IS_ARRAY (RTYPE (tree)) ||
3191 IS_ARITHMETIC (RTYPE (tree))))
3193 werror (E_PLUS_INVALID, "-");
3194 goto errorTreeReturn;
3197 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3198 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3199 IS_INTEGRAL (RTYPE (tree))))
3201 werror (E_PLUS_INVALID, "-");
3202 goto errorTreeReturn;
3205 /* if they are both literal then */
3206 /* rewrite the tree */
3207 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3209 tree->type = EX_VALUE;
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);
3243 TETYPE (tree) = getSpec (TTYPE (tree) =
3244 computeType (LTYPE (tree),
3250 LRVAL (tree) = RRVAL (tree) = 1;
3252 /* if right is a literal and */
3253 /* left is also an addition/subtraction with a literal then */
3254 /* rearrange the tree */
3255 if (IS_LITERAL (RTYPE (tree))
3256 /* avoid infinite loop */
3257 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3259 ast *litTree, *litParent;
3260 litTree = searchLitOp (tree, &litParent, "+-");
3263 if (litTree->opval.op == '+')
3266 litTree->right = newNode ('-', litTree->right, tree->right);
3267 litTree->right->lineno = tree->lineno;
3269 tree->right->opval.val = constVal ("0");
3271 else if (litTree->opval.op == '-')
3273 if (IS_LITERAL (RTYPE (litTree)))
3276 litTree->right = newNode ('+', tree->right, litTree->right);
3277 litTree->right->lineno = tree->lineno;
3279 tree->right->opval.val = constVal ("0");
3284 ast *tTree = litTree->right;
3285 litTree->right = tree->right;
3286 tree->right = tTree;
3289 decorateType (litParent, RESULT_CHECK);
3294 /*------------------------------------------------------------------*/
3295 /*----------------------------*/
3297 /*----------------------------*/
3299 /* can be only integral type */
3300 if (!IS_INTEGRAL (LTYPE (tree)))
3302 werror (E_UNARY_OP, tree->opval.op);
3303 goto errorTreeReturn;
3306 /* if left is a literal then do it */
3307 if (IS_LITERAL (LTYPE (tree)))
3309 tree->type = EX_VALUE;
3310 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3312 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3316 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3319 /*------------------------------------------------------------------*/
3320 /*----------------------------*/
3322 /*----------------------------*/
3324 /* can be pointer */
3325 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3326 !IS_PTR (LTYPE (tree)) &&
3327 !IS_ARRAY (LTYPE (tree)))
3329 werror (E_UNARY_OP, tree->opval.op);
3330 goto errorTreeReturn;
3333 /* if left is a literal then do it */
3334 if (IS_LITERAL (LTYPE (tree)))
3336 tree->type = EX_VALUE;
3337 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3339 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3343 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3346 /*------------------------------------------------------------------*/
3347 /*----------------------------*/
3349 /*----------------------------*/
3353 TTYPE (tree) = LTYPE (tree);
3354 TETYPE (tree) = LETYPE (tree);
3358 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3363 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3365 werror (E_SHIFT_OP_INVALID);
3366 werror (W_CONTINUE, "left & right types are ");
3367 printTypeChain (LTYPE (tree), stderr);
3368 fprintf (stderr, ",");
3369 printTypeChain (RTYPE (tree), stderr);
3370 fprintf (stderr, "\n");
3371 goto errorTreeReturn;
3374 /* if they are both literal then */
3375 /* rewrite the tree */
3376 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3378 tree->type = EX_VALUE;
3379 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3380 valFromType (RETYPE (tree)),
3381 (tree->opval.op == LEFT_OP ? 1 : 0));
3382 tree->right = tree->left = NULL;
3383 TETYPE (tree) = getSpec (TTYPE (tree) =
3384 tree->opval.val->type);
3388 LRVAL (tree) = RRVAL (tree) = 1;
3389 if (tree->opval.op == LEFT_OP)
3391 tree->left = addCast (tree->left, resultType, TRUE);
3392 TETYPE (tree) = getSpec (TTYPE (tree) =
3393 computeType (LTYPE (tree),
3400 /* no promotion necessary */
3401 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3402 if (IS_LITERAL (TTYPE (tree)))
3403 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3406 /* if only the right side is a literal & we are
3407 shifting more than size of the left operand then zero */
3408 if (IS_LITERAL (RTYPE (tree)) &&
3409 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3410 (getSize (TETYPE (tree)) * 8))
3412 if (tree->opval.op==LEFT_OP ||
3413 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3415 lineno=tree->lineno;
3416 werror (W_SHIFT_CHANGED,
3417 (tree->opval.op == LEFT_OP ? "left" : "right"));
3418 tree->type = EX_VALUE;
3419 tree->left = tree->right = NULL;
3420 tree->opval.val = constVal ("0");
3421 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3428 /*------------------------------------------------------------------*/
3429 /*----------------------------*/
3431 /*----------------------------*/
3432 case CAST: /* change the type */
3433 /* cannot cast to an aggregate type */
3434 if (IS_AGGREGATE (LTYPE (tree)))
3436 werror (E_CAST_ILLEGAL);
3437 goto errorTreeReturn;
3440 /* make sure the type is complete and sane */
3441 checkTypeSanity(LETYPE(tree), "(cast)");
3443 /* If code memory is read only, then pointers to code memory */
3444 /* implicitly point to constants -- make this explicit */
3446 sym_link *t = LTYPE(tree);
3447 while (t && t->next)
3449 if (IS_CODEPTR(t) && port->mem.code_ro)
3451 if (IS_SPEC(t->next))
3452 SPEC_CONST (t->next) = 1;
3454 DCL_PTR_CONST (t->next) = 1;
3461 /* if the right is a literal replace the tree */
3462 if (IS_LITERAL (RETYPE (tree))) {
3463 if (!IS_PTR (LTYPE (tree))) {
3464 tree->type = EX_VALUE;
3466 valCastLiteral (LTYPE (tree),
3467 floatFromVal (valFromType (RETYPE (tree))));
3470 TTYPE (tree) = tree->opval.val->type;
3471 tree->values.literalFromCast = 1;
3472 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3473 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3474 sym_link *rest = LTYPE(tree)->next;
3475 werror(W_LITERAL_GENERIC);
3476 TTYPE(tree) = newLink(DECLARATOR);
3477 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3478 TTYPE(tree)->next = rest;
3479 tree->left->opval.lnk = TTYPE(tree);
3482 TTYPE (tree) = LTYPE (tree);
3486 TTYPE (tree) = LTYPE (tree);
3490 #if 0 // this is already checked, now this could be explicit
3491 /* if pointer to struct then check names */
3492 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3493 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3494 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3496 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3497 SPEC_STRUCT(LETYPE(tree))->tag);
3500 if (IS_ADDRESS_OF_OP(tree->right)
3501 && IS_AST_SYM_VALUE (tree->right->left)
3502 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3504 tree->type = EX_VALUE;
3506 valCastLiteral (LTYPE (tree),
3507 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3508 TTYPE (tree) = tree->opval.val->type;
3509 TETYPE (tree) = getSpec (TTYPE (tree));
3512 tree->values.literalFromCast = 1;
3516 /* handle offsetof macro: */
3517 /* #define offsetof(TYPE, MEMBER) \ */
3518 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3519 if (IS_ADDRESS_OF_OP(tree->right)
3520 && IS_AST_OP (tree->right->left)
3521 && tree->right->left->opval.op == PTR_OP
3522 && IS_AST_OP (tree->right->left->left)
3523 && tree->right->left->left->opval.op == CAST
3524 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3526 symbol *element = getStructElement (
3527 SPEC_STRUCT (LETYPE(tree->right->left)),
3528 AST_SYMBOL(tree->right->left->right)
3532 tree->type = EX_VALUE;
3533 tree->opval.val = valCastLiteral (
3536 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3539 TTYPE (tree) = tree->opval.val->type;
3540 TETYPE (tree) = getSpec (TTYPE (tree));
3547 /* if the right is a literal replace the tree */
3548 if (IS_LITERAL (RETYPE (tree))) {
3550 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3551 /* rewrite (type *)litaddr
3553 and define type at litaddr temp
3554 (but only if type's storage class is not generic)
3556 ast *newTree = newNode ('&', NULL, NULL);
3559 TTYPE (newTree) = LTYPE (tree);
3560 TETYPE (newTree) = getSpec(LTYPE (tree));
3562 /* define a global symbol at the casted address*/
3563 sym = newSymbol(genSymName (0), 0);
3564 sym->type = LTYPE (tree)->next;
3566 sym->type = newLink (V_VOID);
3567 sym->etype = getSpec(sym->type);
3568 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3569 sym->lineDef = tree->lineno;
3572 SPEC_STAT (sym->etype) = 1;
3573 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3574 SPEC_ABSA(sym->etype) = 1;
3575 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3578 newTree->left = newAst_VALUE(symbolVal(sym));
3579 newTree->left->lineno = tree->lineno;
3580 LTYPE (newTree) = sym->type;
3581 LETYPE (newTree) = sym->etype;
3582 LLVAL (newTree) = 1;
3583 LRVAL (newTree) = 0;
3584 TLVAL (newTree) = 1;
3588 if (!IS_PTR (LTYPE (tree))) {
3589 tree->type = EX_VALUE;
3591 valCastLiteral (LTYPE (tree),
3592 floatFromVal (valFromType (RTYPE (tree))));
3593 TTYPE (tree) = tree->opval.val->type;
3596 tree->values.literalFromCast = 1;
3597 TETYPE (tree) = getSpec (TTYPE (tree));
3601 TTYPE (tree) = LTYPE (tree);
3605 TETYPE (tree) = getSpec (TTYPE (tree));
3609 /*------------------------------------------------------------------*/
3610 /*----------------------------*/
3611 /* logical &&, || */
3612 /*----------------------------*/
3615 /* each must me arithmetic type or be a pointer */
3616 if (!IS_PTR (LTYPE (tree)) &&
3617 !IS_ARRAY (LTYPE (tree)) &&
3618 !IS_INTEGRAL (LTYPE (tree)))
3620 werror (E_COMPARE_OP);
3621 goto errorTreeReturn;
3624 if (!IS_PTR (RTYPE (tree)) &&
3625 !IS_ARRAY (RTYPE (tree)) &&
3626 !IS_INTEGRAL (RTYPE (tree)))
3628 werror (E_COMPARE_OP);
3629 goto errorTreeReturn;
3631 /* if they are both literal then */
3632 /* rewrite the tree */
3633 if (IS_LITERAL (RTYPE (tree)) &&
3634 IS_LITERAL (LTYPE (tree)))
3636 tree->type = EX_VALUE;
3637 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3638 valFromType (RTYPE (tree)),
3640 tree->right = tree->left = NULL;
3641 TETYPE (tree) = getSpec (TTYPE (tree) =
3642 tree->opval.val->type);
3645 LRVAL (tree) = RRVAL (tree) = 1;
3646 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3649 /*------------------------------------------------------------------*/
3650 /*----------------------------*/
3651 /* comparison operators */
3652 /*----------------------------*/
3660 ast *lt = optimizeCompare (tree);
3666 /* if they are pointers they must be castable */
3667 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3669 if (tree->opval.op==EQ_OP &&
3670 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3671 // we cannot cast a gptr to a !gptr: switch the leaves
3672 struct ast *s=tree->left;
3673 tree->left=tree->right;
3676 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3678 werror (E_COMPARE_OP);
3679 fprintf (stderr, "comparing type ");
3680 printTypeChain (LTYPE (tree), stderr);
3681 fprintf (stderr, "to type ");
3682 printTypeChain (RTYPE (tree), stderr);
3683 fprintf (stderr, "\n");
3684 goto errorTreeReturn;
3687 /* else they should be promotable to one another */
3690 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3691 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3693 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3695 werror (E_COMPARE_OP);
3696 fprintf (stderr, "comparing type ");
3697 printTypeChain (LTYPE (tree), stderr);
3698 fprintf (stderr, "to type ");
3699 printTypeChain (RTYPE (tree), stderr);
3700 fprintf (stderr, "\n");
3701 goto errorTreeReturn;
3704 /* if unsigned value < 0 then always false */
3705 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3706 if (SPEC_USIGN(LETYPE(tree)) &&
3707 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3708 IS_LITERAL(RTYPE(tree)) &&
3709 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3711 if (tree->opval.op == '<')
3715 if (tree->opval.op == '>')
3717 if (resultType == RESULT_TYPE_IFX)
3719 /* the parent is an ifx: */
3720 /* if (unsigned value) */
3724 /* (unsigned value) ? 1 : 0 */
3725 tree->opval.op = '?';
3726 tree->right = newNode (':',
3727 newAst_VALUE (constVal ("1")),
3728 tree->right); /* val 0 */
3729 tree->right->lineno = tree->lineno;
3730 tree->right->left->lineno = tree->lineno;
3731 decorateType (tree->right, RESULT_CHECK);
3734 /* if they are both literal then */
3735 /* rewrite the tree */
3736 if (IS_LITERAL (RTYPE (tree)) &&
3737 IS_LITERAL (LTYPE (tree)))
3739 tree->type = EX_VALUE;
3740 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3741 valFromType (RETYPE (tree)),
3743 tree->right = tree->left = NULL;
3744 TETYPE (tree) = getSpec (TTYPE (tree) =
3745 tree->opval.val->type);
3748 LRVAL (tree) = RRVAL (tree) = 1;
3749 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3752 /*------------------------------------------------------------------*/
3753 /*----------------------------*/
3755 /*----------------------------*/
3756 case SIZEOF: /* evaluate wihout code generation */
3757 /* change the type to a integer */
3759 int size = getSize (tree->right->ftype);
3760 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3761 if (!size && !IS_VOID(tree->right->ftype))
3762 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3764 tree->type = EX_VALUE;
3765 tree->opval.val = constVal (buffer);
3766 tree->right = tree->left = NULL;
3767 TETYPE (tree) = getSpec (TTYPE (tree) =
3768 tree->opval.val->type);
3771 /*------------------------------------------------------------------*/
3772 /*----------------------------*/
3774 /*----------------------------*/
3776 /* return typeof enum value */
3777 tree->type = EX_VALUE;
3780 if (IS_SPEC(tree->right->ftype)) {
3781 switch (SPEC_NOUN(tree->right->ftype)) {
3783 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3784 else typeofv = TYPEOF_INT;
3787 typeofv = TYPEOF_FLOAT;
3790 typeofv = TYPEOF_CHAR;
3793 typeofv = TYPEOF_VOID;
3796 typeofv = TYPEOF_STRUCT;
3799 typeofv = TYPEOF_BITFIELD;
3802 typeofv = TYPEOF_BIT;
3805 typeofv = TYPEOF_SBIT;
3811 switch (DCL_TYPE(tree->right->ftype)) {
3813 typeofv = TYPEOF_POINTER;
3816 typeofv = TYPEOF_FPOINTER;
3819 typeofv = TYPEOF_CPOINTER;
3822 typeofv = TYPEOF_GPOINTER;
3825 typeofv = TYPEOF_PPOINTER;
3828 typeofv = TYPEOF_IPOINTER;
3831 typeofv = TYPEOF_ARRAY;
3834 typeofv = TYPEOF_FUNCTION;
3840 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3841 tree->opval.val = constVal (buffer);
3842 tree->right = tree->left = NULL;
3843 TETYPE (tree) = getSpec (TTYPE (tree) =
3844 tree->opval.val->type);
3847 /*------------------------------------------------------------------*/
3848 /*----------------------------*/
3849 /* conditional operator '?' */
3850 /*----------------------------*/
3852 /* the type is value of the colon operator (on the right) */
3853 assert (IS_COLON_OP (tree->right));
3854 /* if already known then replace the tree : optimizer will do it
3855 but faster to do it here */
3856 if (IS_LITERAL (LTYPE (tree)))
3858 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3859 return decorateType (tree->right->left, resultTypeProp);
3861 return decorateType (tree->right->right, resultTypeProp);
3865 tree->right = decorateType (tree->right, resultTypeProp);
3866 TTYPE (tree) = RTYPE (tree);
3867 TETYPE (tree) = getSpec (TTYPE (tree));
3872 /* if they don't match we have a problem */
3873 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3875 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3876 goto errorTreeReturn;
3879 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3880 resultType, tree->opval.op);
3881 TETYPE (tree) = getSpec (TTYPE (tree));
3885 #if 0 // assignment operators are converted by the parser
3886 /*------------------------------------------------------------------*/
3887 /*----------------------------*/
3888 /* assignment operators */
3889 /*----------------------------*/
3892 /* for these it must be both must be integral */
3893 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3894 !IS_ARITHMETIC (RTYPE (tree)))
3896 werror (E_OPS_INTEGRAL);
3897 goto errorTreeReturn;
3900 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3902 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3903 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3907 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3908 goto errorTreeReturn;
3919 /* for these it must be both must be integral */
3920 if (!IS_INTEGRAL (LTYPE (tree)) ||
3921 !IS_INTEGRAL (RTYPE (tree)))
3923 werror (E_OPS_INTEGRAL);
3924 goto errorTreeReturn;
3927 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3929 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3930 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3934 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3935 goto errorTreeReturn;
3941 /*------------------------------------------------------------------*/
3942 /*----------------------------*/
3944 /*----------------------------*/
3946 if (!(IS_PTR (LTYPE (tree)) ||
3947 IS_ARITHMETIC (LTYPE (tree))))
3949 werror (E_PLUS_INVALID, "-=");
3950 goto errorTreeReturn;
3953 if (!(IS_PTR (RTYPE (tree)) ||
3954 IS_ARITHMETIC (RTYPE (tree))))
3956 werror (E_PLUS_INVALID, "-=");
3957 goto errorTreeReturn;
3960 TETYPE (tree) = getSpec (TTYPE (tree) =
3961 computeType (LTYPE (tree),
3966 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3967 werror (E_CODE_WRITE, "-=");
3971 werror (E_LVALUE_REQUIRED, "-=");
3972 goto errorTreeReturn;
3978 /*------------------------------------------------------------------*/
3979 /*----------------------------*/
3981 /*----------------------------*/
3983 /* this is not a unary operation */
3984 /* if both pointers then problem */
3985 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3987 werror (E_PTR_PLUS_PTR);
3988 goto errorTreeReturn;
3991 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3993 werror (E_PLUS_INVALID, "+=");
3994 goto errorTreeReturn;
3997 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3999 werror (E_PLUS_INVALID, "+=");
4000 goto errorTreeReturn;
4003 TETYPE (tree) = getSpec (TTYPE (tree) =
4004 computeType (LTYPE (tree),
4009 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4010 werror (E_CODE_WRITE, "+=");
4014 werror (E_LVALUE_REQUIRED, "+=");
4015 goto errorTreeReturn;
4018 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
4019 tree->opval.op = '=';
4024 /*------------------------------------------------------------------*/
4025 /*----------------------------*/
4026 /* straight assignemnt */
4027 /*----------------------------*/
4029 /* cannot be an aggregate */
4030 if (IS_AGGREGATE (LTYPE (tree)))
4032 werror (E_AGGR_ASSIGN);
4033 goto errorTreeReturn;
4036 /* they should either match or be castable */
4037 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4039 werror (E_TYPE_MISMATCH, "assignment", " ");
4040 printFromToType(RTYPE(tree),LTYPE(tree));
4043 /* if the left side of the tree is of type void
4044 then report error */
4045 if (IS_VOID (LTYPE (tree)))
4047 werror (E_CAST_ZERO);
4048 printFromToType(RTYPE(tree), LTYPE(tree));
4051 TETYPE (tree) = getSpec (TTYPE (tree) =
4055 if (!tree->initMode ) {
4056 if (IS_CONSTANT(LTYPE(tree)))
4057 werror (E_CODE_WRITE, "=");
4061 werror (E_LVALUE_REQUIRED, "=");
4062 goto errorTreeReturn;
4067 /*------------------------------------------------------------------*/
4068 /*----------------------------*/
4069 /* comma operator */
4070 /*----------------------------*/
4072 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4075 /*------------------------------------------------------------------*/
4076 /*----------------------------*/
4078 /*----------------------------*/
4081 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4082 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4084 if (tree->left->opval.op == '*' && !tree->left->right)
4085 tree->left = tree->left->left;
4088 /* require a function or pointer to function */
4089 if (!IS_FUNC (LTYPE (tree))
4090 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4092 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4093 goto errorTreeReturn;
4100 if (IS_CODEPTR(LTYPE(tree)))
4101 functype = LTYPE (tree)->next;
4103 functype = LTYPE (tree);
4105 if (processParms (tree->left, FUNC_ARGS(functype),
4106 tree->right, &parmNumber, TRUE)) {
4107 goto errorTreeReturn;
4110 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4111 !IFFUNC_ISBUILTIN(functype))
4113 reverseParms (tree->right);
4116 TTYPE (tree) = functype->next;
4117 TETYPE (tree) = getSpec (TTYPE (tree));
4121 /*------------------------------------------------------------------*/
4122 /*----------------------------*/
4123 /* return statement */
4124 /*----------------------------*/
4129 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4131 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4132 printFromToType (RTYPE(tree), currFunc->type->next);
4133 goto errorTreeReturn;
4136 if (IS_VOID (currFunc->type->next)
4138 !IS_VOID (RTYPE (tree)))
4140 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4141 goto errorTreeReturn;
4144 /* if there is going to be a casting required then add it */
4145 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4148 decorateType (newNode (CAST,
4149 newAst_LINK (copyLinkChain (currFunc->type->next)),
4159 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4161 werror (W_VOID_FUNC, currFunc->name);
4162 goto errorTreeReturn;
4165 TTYPE (tree) = TETYPE (tree) = NULL;
4168 /*------------------------------------------------------------------*/
4169 /*----------------------------*/
4170 /* switch statement */
4171 /*----------------------------*/
4173 /* the switch value must be an integer */
4174 if (!IS_INTEGRAL (LTYPE (tree)))
4176 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4177 goto errorTreeReturn;
4180 TTYPE (tree) = TETYPE (tree) = NULL;
4183 /*------------------------------------------------------------------*/
4184 /*----------------------------*/
4186 /*----------------------------*/
4188 tree->left = backPatchLabels (tree->left,
4191 TTYPE (tree) = TETYPE (tree) = NULL;
4194 /*------------------------------------------------------------------*/
4195 /*----------------------------*/
4197 /*----------------------------*/
4200 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4201 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4202 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4204 /* if the for loop is reversible then
4205 reverse it otherwise do what we normally
4211 if (isLoopReversible (tree, &sym, &init, &end))
4212 return reverseLoop (tree, sym, init, end);
4214 return decorateType (createFor (AST_FOR (tree, trueLabel),
4215 AST_FOR (tree, continueLabel),
4216 AST_FOR (tree, falseLabel),
4217 AST_FOR (tree, condLabel),
4218 AST_FOR (tree, initExpr),
4219 AST_FOR (tree, condExpr),
4220 AST_FOR (tree, loopExpr),
4221 tree->left), RESULT_CHECK);
4224 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4225 "node PARAM shouldn't be processed here");
4226 /* but in processParams() */
4229 TTYPE (tree) = TETYPE (tree) = NULL;
4233 /* some error found this tree will be killed */
4235 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4236 tree->opval.op = NULLOP;
4242 /*-----------------------------------------------------------------*/
4243 /* sizeofOp - processes size of operation */
4244 /*-----------------------------------------------------------------*/
4246 sizeofOp (sym_link * type)
4251 /* make sure the type is complete and sane */
4252 checkTypeSanity(type, "(sizeof)");
4254 /* get the size and convert it to character */
4255 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4256 if (!size && !IS_VOID(type))
4257 werror (E_SIZEOF_INCOMPLETE_TYPE);
4259 /* now convert into value */
4260 return constVal (buff);
4264 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4265 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4266 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4267 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4268 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4269 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4270 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4272 /*-----------------------------------------------------------------*/
4273 /* backPatchLabels - change and or not operators to flow control */
4274 /*-----------------------------------------------------------------*/
4276 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4282 if (!(IS_ANDORNOT (tree)))
4285 /* if this an and */
4288 static int localLbl = 0;
4291 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4292 localLabel = newSymbol (buffer, NestLevel);
4294 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4296 /* if left is already a IFX then just change the if true label in that */
4297 if (!IS_IFX (tree->left))
4298 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4300 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4301 /* right is a IFX then just join */
4302 if (IS_IFX (tree->right))
4303 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4305 tree->right = createLabel (localLabel, tree->right);
4306 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4308 return newNode (NULLOP, tree->left, tree->right);
4311 /* if this is an or operation */
4314 static int localLbl = 0;
4317 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4318 localLabel = newSymbol (buffer, NestLevel);
4320 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4322 /* if left is already a IFX then just change the if true label in that */
4323 if (!IS_IFX (tree->left))
4324 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4326 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4327 /* right is a IFX then just join */
4328 if (IS_IFX (tree->right))
4329 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4331 tree->right = createLabel (localLabel, tree->right);
4332 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4334 return newNode (NULLOP, tree->left, tree->right);
4340 int wasnot = IS_NOT (tree->left);
4341 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4343 /* if the left is already a IFX */
4344 if (!IS_IFX (tree->left))
4345 tree->left = newNode (IFX, tree->left, NULL);
4349 tree->left->trueLabel = trueLabel;
4350 tree->left->falseLabel = falseLabel;
4354 tree->left->trueLabel = falseLabel;
4355 tree->left->falseLabel = trueLabel;
4362 tree->trueLabel = trueLabel;
4363 tree->falseLabel = falseLabel;
4370 /*-----------------------------------------------------------------*/
4371 /* createBlock - create expression tree for block */
4372 /*-----------------------------------------------------------------*/
4374 createBlock (symbol * decl, ast * body)
4378 /* if the block has nothing */
4382 ex = newNode (BLOCK, NULL, body);
4383 ex->values.sym = decl;
4385 ex->right = ex->right;
4391 /*-----------------------------------------------------------------*/
4392 /* createLabel - creates the expression tree for labels */
4393 /*-----------------------------------------------------------------*/
4395 createLabel (symbol * label, ast * stmnt)
4398 char name[SDCC_NAME_MAX + 1];
4401 /* must create fresh symbol if the symbol name */
4402 /* exists in the symbol table, since there can */
4403 /* be a variable with the same name as the labl */
4404 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4405 (csym->level == label->level))
4406 label = newSymbol (label->name, label->level);
4408 /* change the name before putting it in add _ */
4409 SNPRINTF(name, sizeof(name), "%s", label->name);
4411 /* put the label in the LabelSymbol table */
4412 /* but first check if a label of the same */
4414 if ((csym = findSym (LabelTab, NULL, name)))
4415 werror (E_DUPLICATE_LABEL, label->name);
4417 addSym (LabelTab, label, name, label->level, 0, 0);
4420 label->key = labelKey++;
4421 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4427 /*-----------------------------------------------------------------*/
4428 /* createCase - generates the parsetree for a case statement */
4429 /*-----------------------------------------------------------------*/
4431 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4433 char caseLbl[SDCC_NAME_MAX + 1];
4437 /* if the switch statement does not exist */
4438 /* then case is out of context */
4441 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4445 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4446 /* if not a constant then error */
4447 if (!IS_LITERAL (caseVal->ftype))
4449 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4453 /* if not a integer than error */
4454 if (!IS_INTEGRAL (caseVal->ftype))
4456 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4460 /* find the end of the switch values chain */
4461 if (!(val = swStat->values.switchVals.swVals))
4462 swStat->values.switchVals.swVals = caseVal->opval.val;
4465 /* also order the cases according to value */
4467 int cVal = (int) floatFromVal (caseVal->opval.val);
4468 while (val && (int) floatFromVal (val) < cVal)
4474 /* if we reached the end then */
4477 pval->next = caseVal->opval.val;
4479 else if ((int) floatFromVal (val) == cVal)
4481 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4487 /* we found a value greater than */
4488 /* the current value we must add this */
4489 /* before the value */
4490 caseVal->opval.val->next = val;
4492 /* if this was the first in chain */
4493 if (swStat->values.switchVals.swVals == val)
4494 swStat->values.switchVals.swVals =
4497 pval->next = caseVal->opval.val;
4502 /* create the case label */
4503 SNPRINTF(caseLbl, sizeof(caseLbl),
4505 swStat->values.switchVals.swNum,
4506 (int) floatFromVal (caseVal->opval.val));
4508 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4513 /*-----------------------------------------------------------------*/
4514 /* createDefault - creates the parse tree for the default statement */
4515 /*-----------------------------------------------------------------*/
4517 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4519 char defLbl[SDCC_NAME_MAX + 1];
4521 /* if the switch statement does not exist */
4522 /* then case is out of context */
4525 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4529 if (swStat->values.switchVals.swDefault)
4531 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4536 /* turn on the default flag */
4537 swStat->values.switchVals.swDefault = 1;
4539 /* create the label */
4540 SNPRINTF (defLbl, sizeof(defLbl),
4541 "_default_%d", swStat->values.switchVals.swNum);
4542 return createLabel (newSymbol (defLbl, 0), stmnt);
4545 /*-----------------------------------------------------------------*/
4546 /* createIf - creates the parsetree for the if statement */
4547 /*-----------------------------------------------------------------*/
4549 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4551 static int Lblnum = 0;
4553 symbol *ifTrue, *ifFalse, *ifEnd;
4555 /* if neither exists */
4556 if (!elseBody && !ifBody) {
4557 // if there are no side effects (i++, j() etc)
4558 if (!hasSEFcalls(condAst)) {
4563 /* create the labels */
4564 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4565 ifFalse = newSymbol (buffer, NestLevel);
4566 /* if no else body then end == false */
4571 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4572 ifEnd = newSymbol (buffer, NestLevel);
4575 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4576 ifTrue = newSymbol (buffer, NestLevel);
4580 /* attach the ifTrue label to the top of it body */
4581 ifBody = createLabel (ifTrue, ifBody);
4582 /* attach a goto end to the ifBody if else is present */
4585 ifBody = newNode (NULLOP, ifBody,
4587 newAst_VALUE (symbolVal (ifEnd)),
4589 /* put the elseLabel on the else body */
4590 elseBody = createLabel (ifFalse, elseBody);
4591 /* out the end at the end of the body */
4592 elseBody = newNode (NULLOP,
4594 createLabel (ifEnd, NULL));
4598 ifBody = newNode (NULLOP, ifBody,
4599 createLabel (ifFalse, NULL));
4601 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4602 if (IS_IFX (condAst))
4605 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4607 return newNode (NULLOP, ifTree,
4608 newNode (NULLOP, ifBody, elseBody));
4612 /*-----------------------------------------------------------------*/
4613 /* createDo - creates parse tree for do */
4616 /* _docontinue_n: */
4617 /* condition_expression +-> trueLabel -> _dobody_n */
4619 /* +-> falseLabel-> _dobreak_n */
4621 /*-----------------------------------------------------------------*/
4623 createDo (symbol * trueLabel, symbol * continueLabel,
4624 symbol * falseLabel, ast * condAst, ast * doBody)
4629 /* if the body does not exist then it is simple */
4632 condAst = backPatchLabels (condAst, continueLabel, NULL);
4633 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4634 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4635 doTree->trueLabel = continueLabel;
4636 doTree->falseLabel = NULL;
4640 /* otherwise we have a body */
4641 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4643 /* attach the body label to the top */
4644 doBody = createLabel (trueLabel, doBody);
4645 /* attach the continue label to end of body */
4646 doBody = newNode (NULLOP, doBody,
4647 createLabel (continueLabel, NULL));
4649 /* now put the break label at the end */
4650 if (IS_IFX (condAst))
4653 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4655 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4657 /* putting it together */
4658 return newNode (NULLOP, doBody, doTree);
4661 /*-----------------------------------------------------------------*/
4662 /* createFor - creates parse tree for 'for' statement */
4665 /* condExpr +-> trueLabel -> _forbody_n */
4667 /* +-> falseLabel-> _forbreak_n */
4670 /* _forcontinue_n: */
4672 /* goto _forcond_n ; */
4674 /*-----------------------------------------------------------------*/
4676 createFor (symbol * trueLabel, symbol * continueLabel,
4677 symbol * falseLabel, symbol * condLabel,
4678 ast * initExpr, ast * condExpr, ast * loopExpr,
4683 /* if loopexpression not present then we can generate it */
4684 /* the same way as a while */
4686 return newNode (NULLOP, initExpr,
4687 createWhile (trueLabel, continueLabel,
4688 falseLabel, condExpr, forBody));
4689 /* vanilla for statement */
4690 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4692 if (condExpr && !IS_IFX (condExpr))
4693 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4696 /* attach condition label to condition */
4697 condExpr = createLabel (condLabel, condExpr);
4699 /* attach body label to body */
4700 forBody = createLabel (trueLabel, forBody);
4702 /* attach continue to forLoop expression & attach */
4703 /* goto the forcond @ and of loopExpression */
4704 loopExpr = createLabel (continueLabel,
4708 newAst_VALUE (symbolVal (condLabel)),
4710 /* now start putting them together */
4711 forTree = newNode (NULLOP, initExpr, condExpr);
4712 forTree = newNode (NULLOP, forTree, forBody);
4713 forTree = newNode (NULLOP, forTree, loopExpr);
4714 /* finally add the break label */
4715 forTree = newNode (NULLOP, forTree,
4716 createLabel (falseLabel, NULL));
4720 /*-----------------------------------------------------------------*/
4721 /* createWhile - creates parse tree for while statement */
4722 /* the while statement will be created as follows */
4724 /* _while_continue_n: */
4725 /* condition_expression +-> trueLabel -> _while_boby_n */
4727 /* +-> falseLabel -> _while_break_n */
4728 /* _while_body_n: */
4730 /* goto _while_continue_n */
4731 /* _while_break_n: */
4732 /*-----------------------------------------------------------------*/
4734 createWhile (symbol * trueLabel, symbol * continueLabel,
4735 symbol * falseLabel, ast * condExpr, ast * whileBody)
4739 /* put the continue label */
4740 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4741 condExpr = createLabel (continueLabel, condExpr);
4742 condExpr->lineno = 0;
4744 /* put the body label in front of the body */
4745 whileBody = createLabel (trueLabel, whileBody);
4746 whileBody->lineno = 0;
4747 /* put a jump to continue at the end of the body */
4748 /* and put break label at the end of the body */
4749 whileBody = newNode (NULLOP,
4752 newAst_VALUE (symbolVal (continueLabel)),
4753 createLabel (falseLabel, NULL)));
4755 /* put it all together */
4756 if (IS_IFX (condExpr))
4757 whileTree = condExpr;
4760 whileTree = newNode (IFX, condExpr, NULL);
4761 /* put the true & false labels in place */
4762 whileTree->trueLabel = trueLabel;
4763 whileTree->falseLabel = falseLabel;
4766 return newNode (NULLOP, whileTree, whileBody);
4769 /*-----------------------------------------------------------------*/
4770 /* optimizeGetHbit - get highest order bit of the expression */
4771 /*-----------------------------------------------------------------*/
4773 optimizeGetHbit (ast * tree)
4776 /* if this is not a bit and */
4777 if (!IS_BITAND (tree))
4780 /* will look for tree of the form
4781 ( expr >> ((sizeof expr) -1) ) & 1 */
4782 if (!IS_AST_LIT_VALUE (tree->right))
4785 if (AST_LIT_VALUE (tree->right) != 1)
4788 if (!IS_RIGHT_OP (tree->left))
4791 if (!IS_AST_LIT_VALUE (tree->left->right))
4794 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4795 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4798 /* make sure the port supports GETHBIT */
4799 if (port->hasExtBitOp
4800 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4803 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4807 /*-----------------------------------------------------------------*/
4808 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4809 /*-----------------------------------------------------------------*/
4811 optimizeRRCRLC (ast * root)
4813 /* will look for trees of the form
4814 (?expr << 1) | (?expr >> 7) or
4815 (?expr >> 7) | (?expr << 1) will make that
4816 into a RLC : operation ..
4818 (?expr >> 1) | (?expr << 7) or
4819 (?expr << 7) | (?expr >> 1) will make that
4820 into a RRC operation
4821 note : by 7 I mean (number of bits required to hold the
4823 /* if the root operations is not a | operation the not */
4824 if (!IS_BITOR (root))
4827 /* I have to think of a better way to match patterns this sucks */
4828 /* that aside let start looking for the first case : I use a the
4829 negative check a lot to improve the efficiency */
4830 /* (?expr << 1) | (?expr >> 7) */
4831 if (IS_LEFT_OP (root->left) &&
4832 IS_RIGHT_OP (root->right))
4835 if (!SPEC_USIGN (TETYPE (root->left->left)))
4838 if (!IS_AST_LIT_VALUE (root->left->right) ||
4839 !IS_AST_LIT_VALUE (root->right->right))
4842 /* make sure it is the same expression */
4843 if (!isAstEqual (root->left->left,
4847 if (AST_LIT_VALUE (root->left->right) != 1)
4850 if (AST_LIT_VALUE (root->right->right) !=
4851 (getSize (TTYPE (root->left->left)) * 8 - 1))
4854 /* make sure the port supports RLC */
4855 if (port->hasExtBitOp
4856 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4859 /* whew got the first case : create the AST */
4860 return newNode (RLC, root->left->left, NULL);
4864 /* check for second case */
4865 /* (?expr >> 7) | (?expr << 1) */
4866 if (IS_LEFT_OP (root->right) &&
4867 IS_RIGHT_OP (root->left))
4870 if (!SPEC_USIGN (TETYPE (root->left->left)))
4873 if (!IS_AST_LIT_VALUE (root->left->right) ||
4874 !IS_AST_LIT_VALUE (root->right->right))
4877 /* make sure it is the same symbol */
4878 if (!isAstEqual (root->left->left,
4882 if (AST_LIT_VALUE (root->right->right) != 1)
4885 if (AST_LIT_VALUE (root->left->right) !=
4886 (getSize (TTYPE (root->left->left)) * 8 - 1))
4889 /* make sure the port supports RLC */
4890 if (port->hasExtBitOp
4891 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4894 /* whew got the first case : create the AST */
4895 return newNode (RLC, root->left->left, NULL);
4900 /* third case for RRC */
4901 /* (?symbol >> 1) | (?symbol << 7) */
4902 if (IS_LEFT_OP (root->right) &&
4903 IS_RIGHT_OP (root->left))
4906 if (!SPEC_USIGN (TETYPE (root->left->left)))
4909 if (!IS_AST_LIT_VALUE (root->left->right) ||
4910 !IS_AST_LIT_VALUE (root->right->right))
4913 /* make sure it is the same symbol */
4914 if (!isAstEqual (root->left->left,
4918 if (AST_LIT_VALUE (root->left->right) != 1)
4921 if (AST_LIT_VALUE (root->right->right) !=
4922 (getSize (TTYPE (root->left->left)) * 8 - 1))
4925 /* make sure the port supports RRC */
4926 if (port->hasExtBitOp
4927 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4930 /* whew got the first case : create the AST */
4931 return newNode (RRC, root->left->left, NULL);
4935 /* fourth and last case for now */
4936 /* (?symbol << 7) | (?symbol >> 1) */
4937 if (IS_RIGHT_OP (root->right) &&
4938 IS_LEFT_OP (root->left))
4941 if (!SPEC_USIGN (TETYPE (root->left->left)))
4944 if (!IS_AST_LIT_VALUE (root->left->right) ||
4945 !IS_AST_LIT_VALUE (root->right->right))
4948 /* make sure it is the same symbol */
4949 if (!isAstEqual (root->left->left,
4953 if (AST_LIT_VALUE (root->right->right) != 1)
4956 if (AST_LIT_VALUE (root->left->right) !=
4957 (getSize (TTYPE (root->left->left)) * 8 - 1))
4960 /* make sure the port supports RRC */
4961 if (port->hasExtBitOp
4962 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4965 /* whew got the first case : create the AST */
4966 return newNode (RRC, root->left->left, NULL);
4970 /* not found return root */
4974 /*-----------------------------------------------------------------*/
4975 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4976 /*-----------------------------------------------------------------*/
4978 optimizeSWAP (ast * root)
4980 /* will look for trees of the form
4981 (?expr << 4) | (?expr >> 4) or
4982 (?expr >> 4) | (?expr << 4) will make that
4983 into a SWAP : operation ..
4984 note : by 4 I mean (number of bits required to hold the
4986 /* if the root operations is not a | operation the not */
4987 if (!IS_BITOR (root))
4990 /* (?expr << 4) | (?expr >> 4) */
4991 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4992 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4995 if (!SPEC_USIGN (TETYPE (root->left->left)))
4998 if (!IS_AST_LIT_VALUE (root->left->right) ||
4999 !IS_AST_LIT_VALUE (root->right->right))
5002 /* make sure it is the same expression */
5003 if (!isAstEqual (root->left->left,
5007 if (AST_LIT_VALUE (root->left->right) !=
5008 (getSize (TTYPE (root->left->left)) * 4))
5011 if (AST_LIT_VALUE (root->right->right) !=
5012 (getSize (TTYPE (root->left->left)) * 4))
5015 /* make sure the port supports SWAP */
5016 if (port->hasExtBitOp
5017 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5020 /* found it : create the AST */
5021 return newNode (SWAP, root->left->left, NULL);
5025 /* not found return root */
5029 /*-----------------------------------------------------------------*/
5030 /* optimizeCompare - otimizes compares for bit variables */
5031 /*-----------------------------------------------------------------*/
5033 optimizeCompare (ast * root)
5035 ast *optExpr = NULL;
5038 unsigned int litValue;
5040 /* if nothing then return nothing */
5044 /* if not a compare op then do leaves */
5045 if (!IS_COMPARE_OP (root))
5047 root->left = optimizeCompare (root->left);
5048 root->right = optimizeCompare (root->right);
5052 /* if left & right are the same then depending
5053 of the operation do */
5054 if (isAstEqual (root->left, root->right))
5056 switch (root->opval.op)
5061 optExpr = newAst_VALUE (constVal ("0"));
5066 optExpr = newAst_VALUE (constVal ("1"));
5070 return decorateType (optExpr, RESULT_CHECK);
5073 vleft = (root->left->type == EX_VALUE ?
5074 root->left->opval.val : NULL);
5076 vright = (root->right->type == EX_VALUE ?
5077 root->right->opval.val : NULL);
5079 /* if left is a BITVAR in BITSPACE */
5080 /* and right is a LITERAL then opt- */
5081 /* imize else do nothing */
5082 if (vleft && vright &&
5083 IS_BITVAR (vleft->etype) &&
5084 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5085 IS_LITERAL (vright->etype))
5088 /* if right side > 1 then comparison may never succeed */
5089 if ((litValue = (int) floatFromVal (vright)) > 1)
5091 werror (W_BAD_COMPARE);
5097 switch (root->opval.op)
5099 case '>': /* bit value greater than 1 cannot be */
5100 werror (W_BAD_COMPARE);
5104 case '<': /* bit value < 1 means 0 */
5106 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5109 case LE_OP: /* bit value <= 1 means no check */
5110 optExpr = newAst_VALUE (vright);
5113 case GE_OP: /* bit value >= 1 means only check for = */
5115 optExpr = newAst_VALUE (vleft);
5120 { /* literal is zero */
5121 switch (root->opval.op)
5123 case '<': /* bit value < 0 cannot be */
5124 werror (W_BAD_COMPARE);
5128 case '>': /* bit value > 0 means 1 */
5130 optExpr = newAst_VALUE (vleft);
5133 case LE_OP: /* bit value <= 0 means no check */
5134 case GE_OP: /* bit value >= 0 means no check */
5135 werror (W_BAD_COMPARE);
5139 case EQ_OP: /* bit == 0 means ! of bit */
5140 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5144 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5145 } /* end-of-if of BITVAR */
5150 /*-----------------------------------------------------------------*/
5151 /* addSymToBlock : adds the symbol to the first block we find */
5152 /*-----------------------------------------------------------------*/
5154 addSymToBlock (symbol * sym, ast * tree)
5156 /* reached end of tree or a leaf */
5157 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5161 if (IS_AST_OP (tree) &&
5162 tree->opval.op == BLOCK)
5165 symbol *lsym = copySymbol (sym);
5167 lsym->next = AST_VALUES (tree, sym);
5168 AST_VALUES (tree, sym) = lsym;
5172 addSymToBlock (sym, tree->left);
5173 addSymToBlock (sym, tree->right);
5176 /*-----------------------------------------------------------------*/
5177 /* processRegParms - do processing for register parameters */
5178 /*-----------------------------------------------------------------*/
5180 processRegParms (value * args, ast * body)
5184 if (IS_REGPARM (args->etype))
5185 addSymToBlock (args->sym, body);
5190 /*-----------------------------------------------------------------*/
5191 /* resetParmKey - resets the operandkeys for the symbols */
5192 /*-----------------------------------------------------------------*/
5193 DEFSETFUNC (resetParmKey)
5204 /*-----------------------------------------------------------------*/
5205 /* createFunction - This is the key node that calls the iCode for */
5206 /* generating the code for a function. Note code */
5207 /* is generated function by function, later when */
5208 /* add inter-procedural analysis this will change */
5209 /*-----------------------------------------------------------------*/
5211 createFunction (symbol * name, ast * body)
5217 iCode *piCode = NULL;
5219 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5220 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5222 /* if check function return 0 then some problem */
5223 if (checkFunction (name, NULL) == 0)
5226 /* create a dummy block if none exists */
5228 body = newNode (BLOCK, NULL, NULL);
5232 /* check if the function name already in the symbol table */
5233 if ((csym = findSym (SymbolTab, NULL, name->name)))
5236 /* special case for compiler defined functions
5237 we need to add the name to the publics list : this
5238 actually means we are now compiling the compiler
5242 addSet (&publics, name);
5248 allocVariables (name);
5250 name->lastLine = mylineno;
5253 /* set the stack pointer */
5254 /* PENDING: check this for the mcs51 */
5255 stackPtr = -port->stack.direction * port->stack.call_overhead;
5256 if (IFFUNC_ISISR (name->type))
5257 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5258 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5259 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5261 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5263 fetype = getSpec (name->type); /* get the specifier for the function */
5264 /* if this is a reentrant function then */
5265 if (IFFUNC_ISREENT (name->type))
5268 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5270 /* do processing for parameters that are passed in registers */
5271 processRegParms (FUNC_ARGS(name->type), body);
5273 /* set the stack pointer */
5277 /* allocate & autoinit the block variables */
5278 processBlockVars (body, &stack, ALLOCATE);
5280 /* save the stack information */
5281 if (options.useXstack)
5282 name->xstack = SPEC_STAK (fetype) = stack;
5284 name->stack = SPEC_STAK (fetype) = stack;
5286 /* name needs to be mangled */
5287 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5289 body = resolveSymbols (body); /* resolve the symbols */
5290 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5293 ex = newAst_VALUE (symbolVal (name)); /* create name */
5294 ex = newNode (FUNCTION, ex, body);
5295 ex->values.args = FUNC_ARGS(name->type);
5297 if (options.dump_tree) PA(ex);
5300 werror (E_FUNC_NO_CODE, name->name);
5304 /* create the node & generate intermediate code */
5306 codeOutFile = code->oFile;
5307 piCode = iCodeFromAst (ex);
5311 werror (E_FUNC_NO_CODE, name->name);
5315 eBBlockFromiCode (piCode);
5317 /* if there are any statics then do them */
5320 GcurMemmap = statsg;
5321 codeOutFile = statsg->oFile;
5322 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5328 /* dealloc the block variables */
5329 processBlockVars (body, &stack, DEALLOCATE);
5330 outputDebugStackSymbols();
5331 /* deallocate paramaters */
5332 deallocParms (FUNC_ARGS(name->type));
5334 if (IFFUNC_ISREENT (name->type))
5337 /* we are done freeup memory & cleanup */
5339 if (port->reset_labelKey) labelKey = 1;
5341 FUNC_HASBODY(name->type) = 1;
5342 addSet (&operKeyReset, name);
5343 applyToSet (operKeyReset, resetParmKey);
5348 cleanUpLevel (LabelTab, 0);
5349 cleanUpBlock (StructTab, 1);
5350 cleanUpBlock (TypedefTab, 1);
5352 xstack->syms = NULL;
5353 istack->syms = NULL;
5358 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5359 /*-----------------------------------------------------------------*/
5360 /* ast_print : prints the ast (for debugging purposes) */
5361 /*-----------------------------------------------------------------*/
5363 void ast_print (ast * tree, FILE *outfile, int indent)
5368 /* can print only decorated trees */
5369 if (!tree->decorated) return;
5371 /* if any child is an error | this one is an error do nothing */
5372 if (tree->isError ||
5373 (tree->left && tree->left->isError) ||
5374 (tree->right && tree->right->isError)) {
5375 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5379 /* print the line */
5380 /* if not block & function */
5381 if (tree->type == EX_OP &&
5382 (tree->opval.op != FUNCTION &&
5383 tree->opval.op != BLOCK &&
5384 tree->opval.op != NULLOP)) {
5387 if (tree->opval.op == FUNCTION) {
5389 value *args=FUNC_ARGS(tree->left->opval.val->type);
5390 fprintf(outfile,"FUNCTION (%s=%p) type (",
5391 tree->left->opval.val->name, tree);
5392 printTypeChain (tree->left->opval.val->type->next,outfile);
5393 fprintf(outfile,") args (");
5396 fprintf (outfile, ", ");
5398 printTypeChain (args ? args->type : NULL, outfile);
5400 args= args ? args->next : NULL;
5402 fprintf(outfile,")\n");
5403 ast_print(tree->left,outfile,indent);
5404 ast_print(tree->right,outfile,indent);
5407 if (tree->opval.op == BLOCK) {
5408 symbol *decls = tree->values.sym;
5409 INDENT(indent,outfile);
5410 fprintf(outfile,"{\n");
5412 INDENT(indent+2,outfile);
5413 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5414 decls->name, decls);
5415 printTypeChain(decls->type,outfile);
5416 fprintf(outfile,")\n");
5418 decls = decls->next;
5420 ast_print(tree->right,outfile,indent+2);
5421 INDENT(indent,outfile);
5422 fprintf(outfile,"}\n");
5425 if (tree->opval.op == NULLOP) {
5426 ast_print(tree->left,outfile,indent);
5427 ast_print(tree->right,outfile,indent);
5430 INDENT(indent,outfile);
5432 /*------------------------------------------------------------------*/
5433 /*----------------------------*/
5434 /* leaf has been reached */
5435 /*----------------------------*/
5436 /* if this is of type value */
5437 /* just get the type */
5438 if (tree->type == EX_VALUE) {
5440 if (IS_LITERAL (tree->opval.val->etype)) {
5441 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5442 if (SPEC_USIGN (tree->opval.val->etype))
5443 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5445 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5446 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5447 floatFromVal(tree->opval.val));
5448 } else if (tree->opval.val->sym) {
5449 /* if the undefined flag is set then give error message */
5450 if (tree->opval.val->sym->undefined) {
5451 fprintf(outfile,"UNDEFINED SYMBOL ");
5453 fprintf(outfile,"SYMBOL ");
5455 fprintf(outfile,"(%s=%p)",
5456 tree->opval.val->sym->name,tree);
5459 fprintf(outfile," type (");
5460 printTypeChain(tree->ftype,outfile);
5461 fprintf(outfile,")\n");
5463 fprintf(outfile,"\n");
5468 /* if type link for the case of cast */
5469 if (tree->type == EX_LINK) {
5470 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5471 printTypeChain(tree->opval.lnk,outfile);
5472 fprintf(outfile,")\n");
5477 /* depending on type of operator do */
5479 switch (tree->opval.op) {
5480 /*------------------------------------------------------------------*/
5481 /*----------------------------*/
5483 /*----------------------------*/
5485 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5486 printTypeChain(tree->ftype,outfile);
5487 fprintf(outfile,")\n");
5488 ast_print(tree->left,outfile,indent+2);
5489 ast_print(tree->right,outfile,indent+2);
5492 /*------------------------------------------------------------------*/
5493 /*----------------------------*/
5495 /*----------------------------*/
5497 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5498 printTypeChain(tree->ftype,outfile);
5499 fprintf(outfile,")\n");
5500 ast_print(tree->left,outfile,indent+2);
5501 ast_print(tree->right,outfile,indent+2);
5504 /*------------------------------------------------------------------*/
5505 /*----------------------------*/
5506 /* struct/union pointer */
5507 /*----------------------------*/
5509 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5510 printTypeChain(tree->ftype,outfile);
5511 fprintf(outfile,")\n");
5512 ast_print(tree->left,outfile,indent+2);
5513 ast_print(tree->right,outfile,indent+2);
5516 /*------------------------------------------------------------------*/
5517 /*----------------------------*/
5518 /* ++/-- operation */
5519 /*----------------------------*/
5522 fprintf(outfile,"post-");
5524 fprintf(outfile,"pre-");
5525 fprintf(outfile,"INC_OP (%p) type (",tree);
5526 printTypeChain(tree->ftype,outfile);
5527 fprintf(outfile,")\n");
5528 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5529 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5534 fprintf(outfile,"post-");
5536 fprintf(outfile,"pre-");
5537 fprintf(outfile,"DEC_OP (%p) type (",tree);
5538 printTypeChain(tree->ftype,outfile);
5539 fprintf(outfile,")\n");
5540 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5541 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5544 /*------------------------------------------------------------------*/
5545 /*----------------------------*/
5547 /*----------------------------*/
5550 fprintf(outfile,"& (%p) type (",tree);
5551 printTypeChain(tree->ftype,outfile);
5552 fprintf(outfile,")\n");
5553 ast_print(tree->left,outfile,indent+2);
5554 ast_print(tree->right,outfile,indent+2);
5556 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5557 printTypeChain(tree->ftype,outfile);
5558 fprintf(outfile,")\n");
5559 ast_print(tree->left,outfile,indent+2);
5560 ast_print(tree->right,outfile,indent+2);
5563 /*----------------------------*/
5565 /*----------------------------*/
5567 fprintf(outfile,"OR (%p) type (",tree);
5568 printTypeChain(tree->ftype,outfile);
5569 fprintf(outfile,")\n");
5570 ast_print(tree->left,outfile,indent+2);
5571 ast_print(tree->right,outfile,indent+2);
5573 /*------------------------------------------------------------------*/
5574 /*----------------------------*/
5576 /*----------------------------*/
5578 fprintf(outfile,"XOR (%p) type (",tree);
5579 printTypeChain(tree->ftype,outfile);
5580 fprintf(outfile,")\n");
5581 ast_print(tree->left,outfile,indent+2);
5582 ast_print(tree->right,outfile,indent+2);
5585 /*------------------------------------------------------------------*/
5586 /*----------------------------*/
5588 /*----------------------------*/
5590 fprintf(outfile,"DIV (%p) type (",tree);
5591 printTypeChain(tree->ftype,outfile);
5592 fprintf(outfile,")\n");
5593 ast_print(tree->left,outfile,indent+2);
5594 ast_print(tree->right,outfile,indent+2);
5596 /*------------------------------------------------------------------*/
5597 /*----------------------------*/
5599 /*----------------------------*/
5601 fprintf(outfile,"MOD (%p) type (",tree);
5602 printTypeChain(tree->ftype,outfile);
5603 fprintf(outfile,")\n");
5604 ast_print(tree->left,outfile,indent+2);
5605 ast_print(tree->right,outfile,indent+2);
5608 /*------------------------------------------------------------------*/
5609 /*----------------------------*/
5610 /* address dereference */
5611 /*----------------------------*/
5612 case '*': /* can be unary : if right is null then unary operation */
5614 fprintf(outfile,"DEREF (%p) type (",tree);
5615 printTypeChain(tree->ftype,outfile);
5616 fprintf(outfile,")\n");
5617 ast_print(tree->left,outfile,indent+2);
5620 /*------------------------------------------------------------------*/
5621 /*----------------------------*/
5622 /* multiplication */
5623 /*----------------------------*/
5624 fprintf(outfile,"MULT (%p) type (",tree);
5625 printTypeChain(tree->ftype,outfile);
5626 fprintf(outfile,")\n");
5627 ast_print(tree->left,outfile,indent+2);
5628 ast_print(tree->right,outfile,indent+2);
5632 /*------------------------------------------------------------------*/
5633 /*----------------------------*/
5634 /* unary '+' operator */
5635 /*----------------------------*/
5639 fprintf(outfile,"UPLUS (%p) type (",tree);
5640 printTypeChain(tree->ftype,outfile);
5641 fprintf(outfile,")\n");
5642 ast_print(tree->left,outfile,indent+2);
5644 /*------------------------------------------------------------------*/
5645 /*----------------------------*/
5647 /*----------------------------*/
5648 fprintf(outfile,"ADD (%p) type (",tree);
5649 printTypeChain(tree->ftype,outfile);
5650 fprintf(outfile,")\n");
5651 ast_print(tree->left,outfile,indent+2);
5652 ast_print(tree->right,outfile,indent+2);
5655 /*------------------------------------------------------------------*/
5656 /*----------------------------*/
5658 /*----------------------------*/
5659 case '-': /* can be unary */
5661 fprintf(outfile,"UMINUS (%p) type (",tree);
5662 printTypeChain(tree->ftype,outfile);
5663 fprintf(outfile,")\n");
5664 ast_print(tree->left,outfile,indent+2);
5666 /*------------------------------------------------------------------*/
5667 /*----------------------------*/
5669 /*----------------------------*/
5670 fprintf(outfile,"SUB (%p) type (",tree);
5671 printTypeChain(tree->ftype,outfile);
5672 fprintf(outfile,")\n");
5673 ast_print(tree->left,outfile,indent+2);
5674 ast_print(tree->right,outfile,indent+2);
5677 /*------------------------------------------------------------------*/
5678 /*----------------------------*/
5680 /*----------------------------*/
5682 fprintf(outfile,"COMPL (%p) type (",tree);
5683 printTypeChain(tree->ftype,outfile);
5684 fprintf(outfile,")\n");
5685 ast_print(tree->left,outfile,indent+2);
5687 /*------------------------------------------------------------------*/
5688 /*----------------------------*/
5690 /*----------------------------*/
5692 fprintf(outfile,"NOT (%p) type (",tree);
5693 printTypeChain(tree->ftype,outfile);
5694 fprintf(outfile,")\n");
5695 ast_print(tree->left,outfile,indent+2);
5697 /*------------------------------------------------------------------*/
5698 /*----------------------------*/
5700 /*----------------------------*/
5702 fprintf(outfile,"RRC (%p) type (",tree);
5703 printTypeChain(tree->ftype,outfile);
5704 fprintf(outfile,")\n");
5705 ast_print(tree->left,outfile,indent+2);
5709 fprintf(outfile,"RLC (%p) type (",tree);
5710 printTypeChain(tree->ftype,outfile);
5711 fprintf(outfile,")\n");
5712 ast_print(tree->left,outfile,indent+2);
5715 fprintf(outfile,"SWAP (%p) type (",tree);
5716 printTypeChain(tree->ftype,outfile);
5717 fprintf(outfile,")\n");
5718 ast_print(tree->left,outfile,indent+2);
5721 fprintf(outfile,"GETHBIT (%p) type (",tree);
5722 printTypeChain(tree->ftype,outfile);
5723 fprintf(outfile,")\n");
5724 ast_print(tree->left,outfile,indent+2);
5727 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5728 printTypeChain(tree->ftype,outfile);
5729 fprintf(outfile,")\n");
5730 ast_print(tree->left,outfile,indent+2);
5731 ast_print(tree->right,outfile,indent+2);
5734 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5735 printTypeChain(tree->ftype,outfile);
5736 fprintf(outfile,")\n");
5737 ast_print(tree->left,outfile,indent+2);
5738 ast_print(tree->right,outfile,indent+2);
5740 /*------------------------------------------------------------------*/
5741 /*----------------------------*/
5743 /*----------------------------*/
5744 case CAST: /* change the type */
5745 fprintf(outfile,"CAST (%p) from type (",tree);
5746 printTypeChain(tree->right->ftype,outfile);
5747 fprintf(outfile,") to type (");
5748 printTypeChain(tree->ftype,outfile);
5749 fprintf(outfile,")\n");
5750 ast_print(tree->right,outfile,indent+2);
5754 fprintf(outfile,"ANDAND (%p) type (",tree);
5755 printTypeChain(tree->ftype,outfile);
5756 fprintf(outfile,")\n");
5757 ast_print(tree->left,outfile,indent+2);
5758 ast_print(tree->right,outfile,indent+2);
5761 fprintf(outfile,"OROR (%p) type (",tree);
5762 printTypeChain(tree->ftype,outfile);
5763 fprintf(outfile,")\n");
5764 ast_print(tree->left,outfile,indent+2);
5765 ast_print(tree->right,outfile,indent+2);
5768 /*------------------------------------------------------------------*/
5769 /*----------------------------*/
5770 /* comparison operators */
5771 /*----------------------------*/
5773 fprintf(outfile,"GT(>) (%p) type (",tree);
5774 printTypeChain(tree->ftype,outfile);
5775 fprintf(outfile,")\n");
5776 ast_print(tree->left,outfile,indent+2);
5777 ast_print(tree->right,outfile,indent+2);
5780 fprintf(outfile,"LT(<) (%p) type (",tree);
5781 printTypeChain(tree->ftype,outfile);
5782 fprintf(outfile,")\n");
5783 ast_print(tree->left,outfile,indent+2);
5784 ast_print(tree->right,outfile,indent+2);
5787 fprintf(outfile,"LE(<=) (%p) type (",tree);
5788 printTypeChain(tree->ftype,outfile);
5789 fprintf(outfile,")\n");
5790 ast_print(tree->left,outfile,indent+2);
5791 ast_print(tree->right,outfile,indent+2);
5794 fprintf(outfile,"GE(>=) (%p) type (",tree);
5795 printTypeChain(tree->ftype,outfile);
5796 fprintf(outfile,")\n");
5797 ast_print(tree->left,outfile,indent+2);
5798 ast_print(tree->right,outfile,indent+2);
5801 fprintf(outfile,"EQ(==) (%p) type (",tree);
5802 printTypeChain(tree->ftype,outfile);
5803 fprintf(outfile,")\n");
5804 ast_print(tree->left,outfile,indent+2);
5805 ast_print(tree->right,outfile,indent+2);
5808 fprintf(outfile,"NE(!=) (%p) type (",tree);
5809 printTypeChain(tree->ftype,outfile);
5810 fprintf(outfile,")\n");
5811 ast_print(tree->left,outfile,indent+2);
5812 ast_print(tree->right,outfile,indent+2);
5813 /*------------------------------------------------------------------*/
5814 /*----------------------------*/
5816 /*----------------------------*/
5817 case SIZEOF: /* evaluate wihout code generation */
5818 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5821 /*------------------------------------------------------------------*/
5822 /*----------------------------*/
5823 /* conditional operator '?' */
5824 /*----------------------------*/
5826 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5827 printTypeChain(tree->ftype,outfile);
5828 fprintf(outfile,")\n");
5829 ast_print(tree->left,outfile,indent+2);
5830 ast_print(tree->right,outfile,indent+2);
5834 fprintf(outfile,"COLON(:) (%p) type (",tree);
5835 printTypeChain(tree->ftype,outfile);
5836 fprintf(outfile,")\n");
5837 ast_print(tree->left,outfile,indent+2);
5838 ast_print(tree->right,outfile,indent+2);
5841 /*------------------------------------------------------------------*/
5842 /*----------------------------*/
5843 /* assignment operators */
5844 /*----------------------------*/
5846 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5847 printTypeChain(tree->ftype,outfile);
5848 fprintf(outfile,")\n");
5849 ast_print(tree->left,outfile,indent+2);
5850 ast_print(tree->right,outfile,indent+2);
5853 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5854 printTypeChain(tree->ftype,outfile);
5855 fprintf(outfile,")\n");
5856 ast_print(tree->left,outfile,indent+2);
5857 ast_print(tree->right,outfile,indent+2);
5860 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5861 printTypeChain(tree->ftype,outfile);
5862 fprintf(outfile,")\n");
5863 ast_print(tree->left,outfile,indent+2);
5864 ast_print(tree->right,outfile,indent+2);
5867 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5868 printTypeChain(tree->ftype,outfile);
5869 fprintf(outfile,")\n");
5870 ast_print(tree->left,outfile,indent+2);
5871 ast_print(tree->right,outfile,indent+2);
5874 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5875 printTypeChain(tree->ftype,outfile);
5876 fprintf(outfile,")\n");
5877 ast_print(tree->left,outfile,indent+2);
5878 ast_print(tree->right,outfile,indent+2);
5881 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5882 printTypeChain(tree->ftype,outfile);
5883 fprintf(outfile,")\n");
5884 ast_print(tree->left,outfile,indent+2);
5885 ast_print(tree->right,outfile,indent+2);
5888 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5889 printTypeChain(tree->ftype,outfile);
5890 fprintf(outfile,")\n");
5891 ast_print(tree->left,outfile,indent+2);
5892 ast_print(tree->right,outfile,indent+2);
5894 /*------------------------------------------------------------------*/
5895 /*----------------------------*/
5897 /*----------------------------*/
5899 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5900 printTypeChain(tree->ftype,outfile);
5901 fprintf(outfile,")\n");
5902 ast_print(tree->left,outfile,indent+2);
5903 ast_print(tree->right,outfile,indent+2);
5905 /*------------------------------------------------------------------*/
5906 /*----------------------------*/
5908 /*----------------------------*/
5910 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5911 printTypeChain(tree->ftype,outfile);
5912 fprintf(outfile,")\n");
5913 ast_print(tree->left,outfile,indent+2);
5914 ast_print(tree->right,outfile,indent+2);
5916 /*------------------------------------------------------------------*/
5917 /*----------------------------*/
5918 /* straight assignemnt */
5919 /*----------------------------*/
5921 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5922 printTypeChain(tree->ftype,outfile);
5923 fprintf(outfile,")\n");
5924 ast_print(tree->left,outfile,indent+2);
5925 ast_print(tree->right,outfile,indent+2);
5927 /*------------------------------------------------------------------*/
5928 /*----------------------------*/
5929 /* comma operator */
5930 /*----------------------------*/
5932 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5933 printTypeChain(tree->ftype,outfile);
5934 fprintf(outfile,")\n");
5935 ast_print(tree->left,outfile,indent+2);
5936 ast_print(tree->right,outfile,indent+2);
5938 /*------------------------------------------------------------------*/
5939 /*----------------------------*/
5941 /*----------------------------*/
5944 fprintf(outfile,"CALL (%p) type (",tree);
5945 printTypeChain(tree->ftype,outfile);
5946 fprintf(outfile,")\n");
5947 ast_print(tree->left,outfile,indent+2);
5948 ast_print(tree->right,outfile,indent+2);
5951 fprintf(outfile,"PARMS\n");
5952 ast_print(tree->left,outfile,indent+2);
5953 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5954 ast_print(tree->right,outfile,indent+2);
5957 /*------------------------------------------------------------------*/
5958 /*----------------------------*/
5959 /* return statement */
5960 /*----------------------------*/
5962 fprintf(outfile,"RETURN (%p) type (",tree);
5964 printTypeChain(tree->right->ftype,outfile);
5966 fprintf(outfile,")\n");
5967 ast_print(tree->right,outfile,indent+2);
5969 /*------------------------------------------------------------------*/
5970 /*----------------------------*/
5971 /* label statement */
5972 /*----------------------------*/
5974 fprintf(outfile,"LABEL (%p)\n",tree);
5975 ast_print(tree->left,outfile,indent+2);
5976 ast_print(tree->right,outfile,indent);
5978 /*------------------------------------------------------------------*/
5979 /*----------------------------*/
5980 /* switch statement */
5981 /*----------------------------*/
5985 fprintf(outfile,"SWITCH (%p) ",tree);
5986 ast_print(tree->left,outfile,0);
5987 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5988 INDENT(indent+2,outfile);
5989 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5990 (int) floatFromVal(val),
5991 tree->values.switchVals.swNum,
5992 (int) floatFromVal(val));
5994 ast_print(tree->right,outfile,indent);
5997 /*------------------------------------------------------------------*/
5998 /*----------------------------*/
6000 /*----------------------------*/
6002 fprintf(outfile,"IF (%p) \n",tree);
6003 ast_print(tree->left,outfile,indent+2);
6004 if (tree->trueLabel) {
6005 INDENT(indent+2,outfile);
6006 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6008 if (tree->falseLabel) {
6009 INDENT(indent+2,outfile);
6010 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6012 ast_print(tree->right,outfile,indent+2);
6014 /*----------------------------*/
6015 /* goto Statement */
6016 /*----------------------------*/
6018 fprintf(outfile,"GOTO (%p) \n",tree);
6019 ast_print(tree->left,outfile,indent+2);
6020 fprintf(outfile,"\n");
6022 /*------------------------------------------------------------------*/
6023 /*----------------------------*/
6025 /*----------------------------*/
6027 fprintf(outfile,"FOR (%p) \n",tree);
6028 if (AST_FOR( tree, initExpr)) {
6029 INDENT(indent+2,outfile);
6030 fprintf(outfile,"INIT EXPR ");
6031 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6033 if (AST_FOR( tree, condExpr)) {
6034 INDENT(indent+2,outfile);
6035 fprintf(outfile,"COND EXPR ");
6036 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6038 if (AST_FOR( tree, loopExpr)) {
6039 INDENT(indent+2,outfile);
6040 fprintf(outfile,"LOOP EXPR ");
6041 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6043 fprintf(outfile,"FOR LOOP BODY \n");
6044 ast_print(tree->left,outfile,indent+2);
6047 fprintf(outfile,"CRITICAL (%p) \n",tree);
6048 ast_print(tree->left,outfile,indent+2);
6056 ast_print(t,stdout,0);
6061 /*-----------------------------------------------------------------*/
6062 /* astErrors : returns non-zero if errors present in tree */
6063 /*-----------------------------------------------------------------*/
6064 int astErrors(ast *t)
6073 if (t->type == EX_VALUE
6074 && t->opval.val->sym
6075 && t->opval.val->sym->undefined)
6078 errors += astErrors(t->left);
6079 errors += astErrors(t->right);