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 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
221 dest->reversed = src->reversed;
224 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
226 /* if this is a leaf */
228 if (src->type == EX_VALUE)
230 dest->opval.val = copyValue (src->opval.val);
235 if (src->type == EX_LINK)
237 dest->opval.lnk = copyLinkChain (src->opval.lnk);
241 dest->opval.op = src->opval.op;
243 /* if this is a node that has special values */
244 copyAstValues (dest, src);
246 dest->trueLabel = copySymbol (src->trueLabel);
247 dest->falseLabel = copySymbol (src->falseLabel);
248 dest->left = copyAst (src->left);
249 dest->right = copyAst (src->right);
255 /*-----------------------------------------------------------------*/
256 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
257 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
258 /*-----------------------------------------------------------------*/
259 ast *removeIncDecOps (ast * tree) {
261 // traverse the tree and remove inc/dec ops
266 if (tree->type == EX_OP &&
267 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
274 tree->left=removeIncDecOps(tree->left);
275 tree->right=removeIncDecOps(tree->right);
280 /*-----------------------------------------------------------------*/
281 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
282 /* "*++s += 3" -> "*++s = *++s + 3" */
283 /*-----------------------------------------------------------------*/
284 ast *removePreIncDecOps (ast * tree) {
286 // traverse the tree and remove pre-inc/dec ops
291 if (tree->type == EX_OP &&
292 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
297 tree->left=removePreIncDecOps(tree->left);
298 tree->right=removePreIncDecOps(tree->right);
303 /*-----------------------------------------------------------------*/
304 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
305 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
306 /*-----------------------------------------------------------------*/
307 ast *removePostIncDecOps (ast * tree) {
309 // traverse the tree and remove pre-inc/dec ops
314 if (tree->type == EX_OP &&
315 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
320 tree->left=removePostIncDecOps(tree->left);
321 tree->right=removePostIncDecOps(tree->right);
326 /*-----------------------------------------------------------------*/
327 /* hasSEFcalls - returns TRUE if tree has a function call */
328 /*-----------------------------------------------------------------*/
330 hasSEFcalls (ast * tree)
335 if (tree->type == EX_OP &&
336 (tree->opval.op == CALL ||
337 tree->opval.op == PCALL ||
338 tree->opval.op == '=' ||
339 tree->opval.op == INC_OP ||
340 tree->opval.op == DEC_OP))
343 return (hasSEFcalls (tree->left) |
344 hasSEFcalls (tree->right));
347 /*-----------------------------------------------------------------*/
348 /* isAstEqual - compares two asts & returns 1 if they are equal */
349 /*-----------------------------------------------------------------*/
351 isAstEqual (ast * t1, ast * t2)
360 if (t1->type != t2->type)
366 if (t1->opval.op != t2->opval.op)
368 return (isAstEqual (t1->left, t2->left) &&
369 isAstEqual (t1->right, t2->right));
373 if (t1->opval.val->sym)
375 if (!t2->opval.val->sym)
378 return isSymbolEqual (t1->opval.val->sym,
383 if (t2->opval.val->sym)
386 return (floatFromVal (t1->opval.val) ==
387 floatFromVal (t2->opval.val));
391 /* only compare these two types */
399 /*-----------------------------------------------------------------*/
400 /* resolveSymbols - resolve symbols from the symbol table */
401 /*-----------------------------------------------------------------*/
403 resolveSymbols (ast * tree)
405 /* walk the entire tree and check for values */
406 /* with symbols if we find one then replace */
407 /* symbol with that from the symbol table */
414 /* if not block & function */
415 if (tree->type == EX_OP &&
416 (tree->opval.op != FUNCTION &&
417 tree->opval.op != BLOCK &&
418 tree->opval.op != NULLOP))
420 filename = tree->filename;
421 lineno = tree->lineno;
425 /* make sure we resolve the true & false labels for ifx */
426 if (tree->type == EX_OP && tree->opval.op == IFX)
432 if ((csym = findSym (LabelTab, tree->trueLabel,
433 tree->trueLabel->name)))
434 tree->trueLabel = csym;
436 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
437 tree->trueLabel->name);
440 if (tree->falseLabel)
442 if ((csym = findSym (LabelTab,
444 tree->falseLabel->name)))
445 tree->falseLabel = csym;
447 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
448 tree->falseLabel->name);
453 /* if this is a label resolve it from the labelTab */
454 if (IS_AST_VALUE (tree) &&
455 tree->opval.val->sym &&
456 tree->opval.val->sym->islbl)
459 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
460 tree->opval.val->sym->name);
463 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
464 tree->opval.val->sym->name);
466 tree->opval.val->sym = csym;
468 goto resolveChildren;
471 /* do only for leafs */
472 if (IS_AST_VALUE (tree) &&
473 tree->opval.val->sym &&
474 !tree->opval.val->sym->implicit)
477 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
479 /* if found in the symbol table & they r not the same */
480 if (csym && tree->opval.val->sym != csym)
482 tree->opval.val->sym = csym;
483 tree->opval.val->type = csym->type;
484 tree->opval.val->etype = csym->etype;
487 /* if not found in the symbol table */
488 /* mark it as undefined assume it is */
489 /* an integer in data space */
490 if (!csym && !tree->opval.val->sym->implicit)
493 /* if this is a function name then */
494 /* mark it as returning an int */
497 tree->opval.val->sym->type = newLink (DECLARATOR);
498 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
499 tree->opval.val->sym->type->next =
500 tree->opval.val->sym->etype = newIntLink ();
501 tree->opval.val->etype = tree->opval.val->etype;
502 tree->opval.val->type = tree->opval.val->sym->type;
503 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
504 tree->opval.val->sym->name);
505 //tree->opval.val->sym->undefined = 1;
506 allocVariables (tree->opval.val->sym);
510 tree->opval.val->sym->undefined = 1;
511 tree->opval.val->type =
512 tree->opval.val->etype = newIntLink ();
513 tree->opval.val->sym->type =
514 tree->opval.val->sym->etype = newIntLink ();
520 resolveSymbols (tree->left);
521 resolveSymbols (tree->right);
526 /*-----------------------------------------------------------------*/
527 /* setAstLineno - walks a ast tree & sets the line number */
528 /*-----------------------------------------------------------------*/
529 int setAstLineno (ast * tree, int lineno)
534 tree->lineno = lineno;
535 setAstLineno (tree->left, lineno);
536 setAstLineno (tree->right, lineno);
540 /*-----------------------------------------------------------------*/
541 /* funcOfType :- function of type with name */
542 /*-----------------------------------------------------------------*/
544 funcOfType (char *name, sym_link * type, sym_link * argType,
548 /* create the symbol */
549 sym = newSymbol (name, 0);
551 /* setup return value */
552 sym->type = newLink (DECLARATOR);
553 DCL_TYPE (sym->type) = FUNCTION;
554 sym->type->next = copyLinkChain (type);
555 sym->etype = getSpec (sym->type);
556 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
558 /* if arguments required */
562 args = FUNC_ARGS(sym->type) = newValue ();
566 args->type = copyLinkChain (argType);
567 args->etype = getSpec (args->type);
568 SPEC_EXTR(args->etype)=1;
571 args = args->next = newValue ();
578 allocVariables (sym);
583 /*-----------------------------------------------------------------*/
584 /* funcOfTypeVarg :- function of type with name and argtype */
585 /*-----------------------------------------------------------------*/
587 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
592 /* create the symbol */
593 sym = newSymbol (name, 0);
595 /* setup return value */
596 sym->type = newLink (DECLARATOR);
597 DCL_TYPE (sym->type) = FUNCTION;
598 sym->type->next = typeFromStr(rtype);
599 sym->etype = getSpec (sym->type);
601 /* if arguments required */
604 args = FUNC_ARGS(sym->type) = newValue ();
606 for ( i = 0 ; i < nArgs ; i++ ) {
607 args->type = typeFromStr(atypes[i]);
608 args->etype = getSpec (args->type);
609 SPEC_EXTR(args->etype)=1;
610 if ((i + 1) == nArgs) break;
611 args = args->next = newValue ();
618 allocVariables (sym);
623 /*-----------------------------------------------------------------*/
624 /* reverseParms - will reverse a parameter tree */
625 /*-----------------------------------------------------------------*/
627 reverseParms (ast * ptree)
633 /* top down if we find a nonParm tree then quit */
634 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
637 ptree->left = ptree->right;
638 ptree->right = ttree;
640 reverseParms (ptree->left);
641 reverseParms (ptree->right);
647 /*-----------------------------------------------------------------*/
648 /* processParms - makes sure the parameters are okay and do some */
649 /* processing with them */
650 /*-----------------------------------------------------------------*/
652 processParms (ast *func,
655 int *parmNumber, /* unused, although updated */
658 RESULT_TYPE resultType;
661 /* if none of them exist */
662 if (!defParm && !*actParm)
667 if (getenv("DEBUG_SANITY"))
669 fprintf (stderr, "processParms: %s ", defParm->name);
671 /* make sure the type is complete and sane */
672 checkTypeSanity(defParm->etype, defParm->name);
675 if (IS_CODEPTR (func->ftype))
676 functype = func->ftype->next;
678 functype = func->ftype;
680 /* if the function is being called via a pointer & */
681 /* it has not been defined a reentrant then we cannot */
682 /* have parameters */
683 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
685 werror (W_NONRENT_ARGS);
690 /* if defined parameters ended but actual parameters */
691 /* exist and this is not defined as a variable arg */
692 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
694 werror (E_TOO_MANY_PARMS);
698 /* if defined parameters present but no actual parameters */
699 if (defParm && !*actParm)
701 werror (E_TOO_FEW_PARMS);
705 /* if this is a PARAM node then match left & right */
706 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
708 (*actParm)->decorated = 1;
709 return (processParms (func, defParm,
710 &(*actParm)->left, parmNumber, FALSE) ||
711 processParms (func, defParm ? defParm->next : NULL,
712 &(*actParm)->right, parmNumber, rightmost));
714 else if (defParm) /* not vararg */
716 /* If we have found a value node by following only right-hand links,
717 * then we know that there are no more values after us.
719 * Therefore, if there are more defined parameters, the caller didn't
722 if (rightmost && defParm->next)
724 werror (E_TOO_FEW_PARMS);
729 /* decorate parameter */
730 resultType = defParm ? getResultTypeFromType (defParm->etype) :
732 *actParm = decorateType (*actParm, resultType);
734 if (IS_VOID((*actParm)->ftype))
736 werror (E_VOID_VALUE_USED);
740 /* If this is a varargs function... */
741 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
746 if (IS_CAST_OP (*actParm)
747 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
749 /* Parameter was explicitly typecast; don't touch it. */
753 ftype = (*actParm)->ftype;
755 /* If it's a char, upcast to int. */
756 if (IS_INTEGRAL (ftype)
757 && (getSize (ftype) < (unsigned) INTSIZE))
759 newType = newAst_LINK(INTTYPE);
762 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
764 newType = newAst_LINK (copyLinkChain(ftype));
765 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
768 if (IS_AGGREGATE (ftype))
770 newType = newAst_LINK (copyLinkChain (ftype));
771 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
776 /* cast required; change this op to a cast. */
777 (*actParm)->decorated = 0;
778 *actParm = newNode (CAST, newType, *actParm);
779 (*actParm)->lineno = (*actParm)->right->lineno;
781 decorateType (*actParm, RESULT_TYPE_NONE);
786 /* if defined parameters ended but actual has not & */
788 if (!defParm && *actParm &&
789 (options.stackAuto || IFFUNC_ISREENT (functype)))
792 resolveSymbols (*actParm);
794 /* the parameter type must be at least castable */
795 if (compareType (defParm->type, (*actParm)->ftype) == 0)
797 werror (E_INCOMPAT_TYPES);
798 printFromToType ((*actParm)->ftype, defParm->type);
802 /* if the parameter is castable then add the cast */
803 if (compareType (defParm->type, (*actParm)->ftype) < 0)
807 resultType = getResultTypeFromType (defParm->etype);
808 pTree = resolveSymbols (copyAst (*actParm));
810 /* now change the current one to a cast */
811 (*actParm)->type = EX_OP;
812 (*actParm)->opval.op = CAST;
813 (*actParm)->left = newAst_LINK (defParm->type);
814 (*actParm)->right = pTree;
815 (*actParm)->decorated = 0; /* force typechecking */
816 decorateType (*actParm, resultType);
819 /* make a copy and change the regparm type to the defined parm */
820 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
821 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
822 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
827 /*-----------------------------------------------------------------*/
828 /* createIvalType - generates ival for basic types */
829 /*-----------------------------------------------------------------*/
831 createIvalType (ast * sym, sym_link * type, initList * ilist)
835 /* if initList is deep */
836 if (ilist->type == INIT_DEEP)
837 ilist = ilist->init.deep;
839 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
840 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
843 /*-----------------------------------------------------------------*/
844 /* createIvalStruct - generates initial value for structures */
845 /*-----------------------------------------------------------------*/
847 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
854 sflds = SPEC_STRUCT (type)->fields;
855 if (ilist->type != INIT_DEEP)
857 werror (E_INIT_STRUCT, "");
861 iloop = ilist->init.deep;
863 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
865 /* if we have come to end */
869 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
870 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
871 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
875 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
876 W_EXCESS_INITIALIZERS, "struct",
877 sym->opval.val->sym->name);
884 /*-----------------------------------------------------------------*/
885 /* createIvalArray - generates code for array initialization */
886 /*-----------------------------------------------------------------*/
888 createIvalArray (ast * sym, sym_link * type, initList * ilist)
892 int lcnt = 0, size = 0;
893 literalList *literalL;
895 /* take care of the special case */
896 /* array of characters can be init */
898 if (IS_CHAR (type->next))
899 if ((rast = createIvalCharPtr (sym,
901 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
903 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
905 /* not the special case */
906 if (ilist->type != INIT_DEEP)
908 werror (E_INIT_STRUCT, "");
912 iloop = ilist->init.deep;
913 lcnt = DCL_ELEM (type);
915 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
919 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
921 rast = newNode(ARRAYINIT, aSym, NULL);
922 rast->values.constlist = literalL;
924 // Make sure size is set to length of initializer list.
931 if (lcnt && size > lcnt)
933 // Array size was specified, and we have more initializers than needed.
934 char *name=sym->opval.val->sym->name;
935 int lineno=sym->opval.val->sym->lineDef;
936 char *filename=sym->opval.val->sym->fileDef;
938 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
947 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
948 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
949 rast = createIval (aSym, type->next, iloop, rast);
950 iloop = (iloop ? iloop->next : NULL);
956 /* no of elements given and we */
957 /* have generated for all of them */
960 // is this a better way? at least it won't crash
961 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
962 int lineno = iloop->lineno;
963 char *filename = iloop->filename;
964 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
971 /* if we have not been given a size */
972 if (!DCL_ELEM (type))
974 /* but this still updates the typedef instead of the instance ! see bug 770487 */
975 DCL_ELEM (type) = size;
978 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
982 /*-----------------------------------------------------------------*/
983 /* createIvalCharPtr - generates initial values for char pointers */
984 /*-----------------------------------------------------------------*/
986 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
990 /* if this is a pointer & right is a literal array then */
991 /* just assignment will do */
992 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
993 SPEC_SCLS (iexpr->etype) == S_CODE)
994 && IS_ARRAY (iexpr->ftype)))
995 return newNode ('=', sym, iexpr);
997 /* left side is an array so we have to assign each */
999 if ((IS_LITERAL (iexpr->etype) ||
1000 SPEC_SCLS (iexpr->etype) == S_CODE)
1001 && IS_ARRAY (iexpr->ftype))
1003 /* for each character generate an assignment */
1004 /* to the array element */
1005 char *s = SPEC_CVAL (iexpr->etype).v_char;
1007 int size = getSize (iexpr->ftype);
1008 int symsize = getSize (type);
1012 if (size>(symsize+1))
1013 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1014 "string", sym->opval.val->sym->name);
1018 for (i=0;i<size;i++)
1020 rast = newNode (NULLOP,
1024 newAst_VALUE (valueFromLit ((float) i))),
1025 newAst_VALUE (valueFromLit (*s))));
1029 // now WE don't need iexpr's symbol anymore
1030 freeStringSymbol(AST_SYMBOL(iexpr));
1032 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1038 /*-----------------------------------------------------------------*/
1039 /* createIvalPtr - generates initial value for pointers */
1040 /*-----------------------------------------------------------------*/
1042 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1048 if (ilist->type == INIT_DEEP)
1049 ilist = ilist->init.deep;
1051 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1053 /* if character pointer */
1054 if (IS_CHAR (type->next))
1055 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1058 return newNode ('=', sym, iexpr);
1061 /*-----------------------------------------------------------------*/
1062 /* createIval - generates code for initial value */
1063 /*-----------------------------------------------------------------*/
1065 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1072 /* if structure then */
1073 if (IS_STRUCT (type))
1074 rast = createIvalStruct (sym, type, ilist);
1076 /* if this is a pointer */
1078 rast = createIvalPtr (sym, type, ilist);
1080 /* if this is an array */
1081 if (IS_ARRAY (type))
1082 rast = createIvalArray (sym, type, ilist);
1084 /* if type is SPECIFIER */
1086 rast = createIvalType (sym, type, ilist);
1089 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1091 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1094 /*-----------------------------------------------------------------*/
1095 /* initAggregates - initialises aggregate variables with initv */
1096 /*-----------------------------------------------------------------*/
1097 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1098 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1101 /*-----------------------------------------------------------------*/
1102 /* gatherAutoInit - creates assignment expressions for initial */
1104 /*-----------------------------------------------------------------*/
1106 gatherAutoInit (symbol * autoChain)
1113 for (sym = autoChain; sym; sym = sym->next)
1116 /* resolve the symbols in the ival */
1118 resolveIvalSym (sym->ival, sym->type);
1120 /* if this is a static variable & has an */
1121 /* initial value the code needs to be lifted */
1122 /* here to the main portion since they can be */
1123 /* initialised only once at the start */
1124 if (IS_STATIC (sym->etype) && sym->ival &&
1125 SPEC_SCLS (sym->etype) != S_CODE)
1129 /* insert the symbol into the symbol table */
1130 /* with level = 0 & name = rname */
1131 newSym = copySymbol (sym);
1132 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1134 /* now lift the code to main */
1135 if (IS_AGGREGATE (sym->type)) {
1136 work = initAggregates (sym, sym->ival, NULL);
1138 if (getNelements(sym->type, sym->ival)>1) {
1139 werrorfl (sym->fileDef, sym->lineDef,
1140 W_EXCESS_INITIALIZERS, "scalar",
1143 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1144 list2expr (sym->ival));
1147 setAstLineno (work, sym->lineDef);
1151 staticAutos = newNode (NULLOP, staticAutos, work);
1158 /* if there is an initial value */
1159 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1161 initList *ilist=sym->ival;
1163 while (ilist->type == INIT_DEEP) {
1164 ilist = ilist->init.deep;
1167 /* update lineno for error msg */
1168 lineno=sym->lineDef;
1169 setAstLineno (ilist->init.node, lineno);
1171 if (IS_AGGREGATE (sym->type)) {
1172 work = initAggregates (sym, sym->ival, NULL);
1174 if (getNelements(sym->type, sym->ival)>1) {
1175 werrorfl (sym->fileDef, sym->lineDef,
1176 W_EXCESS_INITIALIZERS, "scalar",
1179 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1180 list2expr (sym->ival));
1184 setAstLineno (work, sym->lineDef);
1188 init = newNode (NULLOP, init, work);
1197 /*-----------------------------------------------------------------*/
1198 /* freeStringSymbol - delete a literal string if no more usage */
1199 /*-----------------------------------------------------------------*/
1200 void freeStringSymbol(symbol *sym) {
1201 /* make sure this is a literal string */
1202 assert (sym->isstrlit);
1203 if (--sym->isstrlit == 0) { // lower the usage count
1204 memmap *segment=SPEC_OCLS(sym->etype);
1206 deleteSetItem(&segment->syms, sym);
1211 /*-----------------------------------------------------------------*/
1212 /* stringToSymbol - creates a symbol from a literal string */
1213 /*-----------------------------------------------------------------*/
1215 stringToSymbol (value * val)
1217 char name[SDCC_NAME_MAX + 1];
1218 static int charLbl = 0;
1223 // have we heard this before?
1224 for (sp=statsg->syms; sp; sp=sp->next) {
1226 size = getSize (sym->type);
1227 if (sym->isstrlit && size == getSize (val->type) &&
1228 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1229 // yes, this is old news. Don't publish it again.
1230 sym->isstrlit++; // but raise the usage count
1231 return symbolVal(sym);
1235 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1236 sym = newSymbol (name, 0); /* make it @ level 0 */
1237 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1239 /* copy the type from the value passed */
1240 sym->type = copyLinkChain (val->type);
1241 sym->etype = getSpec (sym->type);
1242 /* change to storage class & output class */
1243 SPEC_SCLS (sym->etype) = S_CODE;
1244 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1245 SPEC_STAT (sym->etype) = 1;
1246 /* make the level & block = 0 */
1247 sym->block = sym->level = 0;
1249 /* create an ival */
1250 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1255 allocVariables (sym);
1258 return symbolVal (sym);
1262 /*-----------------------------------------------------------------*/
1263 /* processBlockVars - will go thru the ast looking for block if */
1264 /* a block is found then will allocate the syms */
1265 /* will also gather the auto inits present */
1266 /*-----------------------------------------------------------------*/
1268 processBlockVars (ast * tree, int *stack, int action)
1273 /* if this is a block */
1274 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1278 if (action == ALLOCATE)
1280 *stack += allocVariables (tree->values.sym);
1281 autoInit = gatherAutoInit (tree->values.sym);
1283 /* if there are auto inits then do them */
1285 tree->left = newNode (NULLOP, autoInit, tree->left);
1287 else /* action is deallocate */
1288 deallocLocal (tree->values.sym);
1291 processBlockVars (tree->left, stack, action);
1292 processBlockVars (tree->right, stack, action);
1297 /*-------------------------------------------------------------*/
1298 /* constExprTree - returns TRUE if this tree is a constant */
1300 /*-------------------------------------------------------------*/
1301 bool constExprTree (ast *cexpr) {
1307 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1309 switch (cexpr->type)
1312 if (IS_AST_LIT_VALUE(cexpr)) {
1313 // this is a literal
1316 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1317 // a function's address will never change
1320 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1321 // an array's address will never change
1324 if (IS_AST_SYM_VALUE(cexpr) &&
1325 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1326 // a symbol in code space will never change
1327 // This is only for the 'char *s="hallo"' case and will have to leave
1328 //printf(" code space symbol");
1333 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1334 "unexpected link in expression tree\n");
1337 if (cexpr->opval.op==ARRAYINIT) {
1338 // this is a list of literals
1341 if (cexpr->opval.op=='=') {
1342 return constExprTree(cexpr->right);
1344 if (cexpr->opval.op==CAST) {
1345 // cast ignored, maybe we should throw a warning here?
1346 return constExprTree(cexpr->right);
1348 if (cexpr->opval.op=='&') {
1351 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1354 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1359 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1364 /*-----------------------------------------------------------------*/
1365 /* constExprValue - returns the value of a constant expression */
1366 /* or NULL if it is not a constant expression */
1367 /*-----------------------------------------------------------------*/
1369 constExprValue (ast * cexpr, int check)
1371 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1373 /* if this is not a constant then */
1374 if (!IS_LITERAL (cexpr->ftype))
1376 /* then check if this is a literal array
1378 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1379 SPEC_CVAL (cexpr->etype).v_char &&
1380 IS_ARRAY (cexpr->ftype))
1382 value *val = valFromType (cexpr->ftype);
1383 SPEC_SCLS (val->etype) = S_LITERAL;
1384 val->sym = cexpr->opval.val->sym;
1385 val->sym->type = copyLinkChain (cexpr->ftype);
1386 val->sym->etype = getSpec (val->sym->type);
1387 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1391 /* if we are casting a literal value then */
1392 if (IS_AST_OP (cexpr) &&
1393 cexpr->opval.op == CAST &&
1394 IS_LITERAL (cexpr->right->ftype))
1396 return valCastLiteral (cexpr->ftype,
1397 floatFromVal (cexpr->right->opval.val));
1400 if (IS_AST_VALUE (cexpr))
1402 return cexpr->opval.val;
1406 werror (E_CONST_EXPECTED, "found expression");
1411 /* return the value */
1412 return cexpr->opval.val;
1416 /*-----------------------------------------------------------------*/
1417 /* isLabelInAst - will return true if a given label is found */
1418 /*-----------------------------------------------------------------*/
1420 isLabelInAst (symbol * label, ast * tree)
1422 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1425 if (IS_AST_OP (tree) &&
1426 tree->opval.op == LABEL &&
1427 isSymbolEqual (AST_SYMBOL (tree->left), label))
1430 return isLabelInAst (label, tree->right) &&
1431 isLabelInAst (label, tree->left);
1435 /*-----------------------------------------------------------------*/
1436 /* isLoopCountable - return true if the loop count can be determi- */
1437 /* -ned at compile time . */
1438 /*-----------------------------------------------------------------*/
1440 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1441 symbol ** sym, ast ** init, ast ** end)
1444 /* the loop is considered countable if the following
1445 conditions are true :-
1447 a) initExpr :- <sym> = <const>
1448 b) condExpr :- <sym> < <const1>
1449 c) loopExpr :- <sym> ++
1452 /* first check the initExpr */
1453 if (IS_AST_OP (initExpr) &&
1454 initExpr->opval.op == '=' && /* is assignment */
1455 IS_AST_SYM_VALUE (initExpr->left))
1456 { /* left is a symbol */
1458 *sym = AST_SYMBOL (initExpr->left);
1459 *init = initExpr->right;
1464 /* for now the symbol has to be of
1466 if (!IS_INTEGRAL ((*sym)->type))
1469 /* now check condExpr */
1470 if (IS_AST_OP (condExpr))
1473 switch (condExpr->opval.op)
1476 if (IS_AST_SYM_VALUE (condExpr->left) &&
1477 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1478 IS_AST_LIT_VALUE (condExpr->right))
1480 *end = condExpr->right;
1486 if (IS_AST_OP (condExpr->left) &&
1487 condExpr->left->opval.op == '>' &&
1488 IS_AST_LIT_VALUE (condExpr->left->right) &&
1489 IS_AST_SYM_VALUE (condExpr->left->left) &&
1490 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1493 *end = newNode ('+', condExpr->left->right,
1494 newAst_VALUE (constVal ("1")));
1505 /* check loop expression is of the form <sym>++ */
1506 if (!IS_AST_OP (loopExpr))
1509 /* check if <sym> ++ */
1510 if (loopExpr->opval.op == INC_OP)
1516 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1517 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1524 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1525 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1533 if (loopExpr->opval.op == ADD_ASSIGN)
1536 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1537 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1538 IS_AST_LIT_VALUE (loopExpr->right) &&
1539 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1547 /*-----------------------------------------------------------------*/
1548 /* astHasVolatile - returns true if ast contains any volatile */
1549 /*-----------------------------------------------------------------*/
1551 astHasVolatile (ast * tree)
1556 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1559 if (IS_AST_OP (tree))
1560 return astHasVolatile (tree->left) ||
1561 astHasVolatile (tree->right);
1566 /*-----------------------------------------------------------------*/
1567 /* astHasPointer - return true if the ast contains any ptr variable */
1568 /*-----------------------------------------------------------------*/
1570 astHasPointer (ast * tree)
1575 if (IS_AST_LINK (tree))
1578 /* if we hit an array expression then check
1579 only the left side */
1580 if (IS_AST_OP (tree) && tree->opval.op == '[')
1581 return astHasPointer (tree->left);
1583 if (IS_AST_VALUE (tree))
1584 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1586 return astHasPointer (tree->left) ||
1587 astHasPointer (tree->right);
1591 /*-----------------------------------------------------------------*/
1592 /* astHasSymbol - return true if the ast has the given symbol */
1593 /*-----------------------------------------------------------------*/
1595 astHasSymbol (ast * tree, symbol * sym)
1597 if (!tree || IS_AST_LINK (tree))
1600 if (IS_AST_VALUE (tree))
1602 if (IS_AST_SYM_VALUE (tree))
1603 return isSymbolEqual (AST_SYMBOL (tree), sym);
1608 return astHasSymbol (tree->left, sym) ||
1609 astHasSymbol (tree->right, sym);
1612 /*-----------------------------------------------------------------*/
1613 /* astHasDeref - return true if the ast has an indirect access */
1614 /*-----------------------------------------------------------------*/
1616 astHasDeref (ast * tree)
1618 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1621 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1623 return astHasDeref (tree->left) || astHasDeref (tree->right);
1626 /*-----------------------------------------------------------------*/
1627 /* isConformingBody - the loop body has to conform to a set of rules */
1628 /* for the loop to be considered reversible read on for rules */
1629 /*-----------------------------------------------------------------*/
1631 isConformingBody (ast * pbody, symbol * sym, ast * body)
1634 /* we are going to do a pre-order traversal of the
1635 tree && check for the following conditions. (essentially
1636 a set of very shallow tests )
1637 a) the sym passed does not participate in
1638 any arithmetic operation
1639 b) There are no function calls
1640 c) all jumps are within the body
1641 d) address of loop control variable not taken
1642 e) if an assignment has a pointer on the
1643 left hand side make sure right does not have
1644 loop control variable */
1646 /* if we reach the end or a leaf then true */
1647 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1650 /* if anything else is "volatile" */
1651 if (IS_VOLATILE (TETYPE (pbody)))
1654 /* we will walk the body in a pre-order traversal for
1656 switch (pbody->opval.op)
1658 /*------------------------------------------------------------------*/
1660 // if the loopvar is used as an index
1661 /* array op is commutative -- must check both left & right */
1662 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1665 return isConformingBody (pbody->right, sym, body)
1666 && isConformingBody (pbody->left, sym, body);
1668 /*------------------------------------------------------------------*/
1673 /*------------------------------------------------------------------*/
1677 /* sure we are not sym is not modified */
1679 IS_AST_SYM_VALUE (pbody->left) &&
1680 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1684 IS_AST_SYM_VALUE (pbody->right) &&
1685 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1690 /*------------------------------------------------------------------*/
1692 case '*': /* can be unary : if right is null then unary operation */
1697 /* if right is NULL then unary operation */
1698 /*------------------------------------------------------------------*/
1699 /*----------------------------*/
1701 /*----------------------------*/
1704 if (IS_AST_SYM_VALUE (pbody->left) &&
1705 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1708 return isConformingBody (pbody->left, sym, body);
1712 if (astHasSymbol (pbody->left, sym) ||
1713 astHasSymbol (pbody->right, sym))
1718 /*------------------------------------------------------------------*/
1726 if (IS_AST_SYM_VALUE (pbody->left) &&
1727 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1730 if (IS_AST_SYM_VALUE (pbody->right) &&
1731 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1734 return isConformingBody (pbody->left, sym, body) &&
1735 isConformingBody (pbody->right, sym, body);
1743 if (IS_AST_SYM_VALUE (pbody->left) &&
1744 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1746 return isConformingBody (pbody->left, sym, body);
1748 /*------------------------------------------------------------------*/
1760 case SIZEOF: /* evaluate wihout code generation */
1762 if (IS_AST_SYM_VALUE (pbody->left) &&
1763 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1766 if (IS_AST_SYM_VALUE (pbody->right) &&
1767 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1770 return isConformingBody (pbody->left, sym, body) &&
1771 isConformingBody (pbody->right, sym, body);
1773 /*------------------------------------------------------------------*/
1776 /* if left has a pointer & right has loop
1777 control variable then we cannot */
1778 if (astHasPointer (pbody->left) &&
1779 astHasSymbol (pbody->right, sym))
1781 if (astHasVolatile (pbody->left))
1784 if (IS_AST_SYM_VALUE (pbody->left)) {
1785 // if the loopvar has an assignment
1786 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1788 // if the loopvar is used in another (maybe conditional) block
1789 if (astHasSymbol (pbody->right, sym) &&
1790 (pbody->level >= body->level)) {
1795 if (astHasVolatile (pbody->left))
1798 if (astHasDeref(pbody->right)) return FALSE;
1800 return isConformingBody (pbody->left, sym, body) &&
1801 isConformingBody (pbody->right, sym, body);
1812 assert ("Parser should not have generated this\n");
1814 /*------------------------------------------------------------------*/
1815 /*----------------------------*/
1816 /* comma operator */
1817 /*----------------------------*/
1819 return isConformingBody (pbody->left, sym, body) &&
1820 isConformingBody (pbody->right, sym, body);
1822 /*------------------------------------------------------------------*/
1823 /*----------------------------*/
1825 /*----------------------------*/
1827 /* if local & not passed as paramater then ok */
1828 if (sym->level && !astHasSymbol(pbody->right,sym))
1832 /*------------------------------------------------------------------*/
1833 /*----------------------------*/
1834 /* return statement */
1835 /*----------------------------*/
1840 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1845 if (astHasSymbol (pbody->left, sym))
1852 return isConformingBody (pbody->left, sym, body) &&
1853 isConformingBody (pbody->right, sym, body);
1859 /*-----------------------------------------------------------------*/
1860 /* isLoopReversible - takes a for loop as input && returns true */
1861 /* if the for loop is reversible. If yes will set the value of */
1862 /* the loop control var & init value & termination value */
1863 /*-----------------------------------------------------------------*/
1865 isLoopReversible (ast * loop, symbol ** loopCntrl,
1866 ast ** init, ast ** end)
1868 /* if option says don't do it then don't */
1869 if (optimize.noLoopReverse)
1871 /* there are several tests to determine this */
1873 /* for loop has to be of the form
1874 for ( <sym> = <const1> ;
1875 [<sym> < <const2>] ;
1876 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1878 if (!isLoopCountable (AST_FOR (loop, initExpr),
1879 AST_FOR (loop, condExpr),
1880 AST_FOR (loop, loopExpr),
1881 loopCntrl, init, end))
1884 /* now do some serious checking on the body of the loop
1887 return isConformingBody (loop->left, *loopCntrl, loop->left);
1891 /*-----------------------------------------------------------------*/
1892 /* replLoopSym - replace the loop sym by loop sym -1 */
1893 /*-----------------------------------------------------------------*/
1895 replLoopSym (ast * body, symbol * sym)
1898 if (!body || IS_AST_LINK (body))
1901 if (IS_AST_SYM_VALUE (body))
1904 if (isSymbolEqual (AST_SYMBOL (body), sym))
1908 body->opval.op = '-';
1909 body->left = newAst_VALUE (symbolVal (sym));
1910 body->right = newAst_VALUE (constVal ("1"));
1918 replLoopSym (body->left, sym);
1919 replLoopSym (body->right, sym);
1923 /*-----------------------------------------------------------------*/
1924 /* reverseLoop - do the actual loop reversal */
1925 /*-----------------------------------------------------------------*/
1927 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1931 /* create the following tree
1936 if (sym) goto for_continue ;
1939 /* put it together piece by piece */
1940 rloop = newNode (NULLOP,
1941 createIf (newAst_VALUE (symbolVal (sym)),
1943 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1946 newAst_VALUE (symbolVal (sym)),
1949 replLoopSym (loop->left, sym);
1950 setAstLineno (rloop, init->lineno);
1952 rloop = newNode (NULLOP,
1954 newAst_VALUE (symbolVal (sym)),
1955 newNode ('-', end, init)),
1956 createLabel (AST_FOR (loop, continueLabel),
1960 newNode (SUB_ASSIGN,
1961 newAst_VALUE (symbolVal (sym)),
1962 newAst_VALUE (constVal ("1"))),
1965 rloop->lineno=init->lineno;
1966 return decorateType (rloop, RESULT_TYPE_NONE);
1970 /*-----------------------------------------------------------------*/
1971 /* searchLitOp - search tree (*ops only) for an ast with literal */
1972 /*-----------------------------------------------------------------*/
1974 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
1978 if (tree && optimize.global_cse)
1980 /* is there a literal operand? */
1982 IS_AST_OP(tree->right) &&
1983 tree->right->right &&
1984 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1986 if (IS_LITERAL (RTYPE (tree->right)) !=
1987 IS_LITERAL (LTYPE (tree->right)))
1989 tree->right->decorated = 0;
1990 tree->decorated = 0;
1994 ret = searchLitOp (tree->right, parent, ops);
1999 IS_AST_OP(tree->left) &&
2000 tree->left->right &&
2001 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2003 if (IS_LITERAL (RTYPE (tree->left)) !=
2004 IS_LITERAL (LTYPE (tree->left)))
2006 tree->left->decorated = 0;
2007 tree->decorated = 0;
2011 ret = searchLitOp (tree->left, parent, ops);
2019 /*-----------------------------------------------------------------*/
2020 /* getResultFromType */
2021 /*-----------------------------------------------------------------*/
2023 getResultTypeFromType (sym_link *type)
2025 /* type = getSpec (type); */
2027 return RESULT_TYPE_BIT;
2028 if (IS_BITFIELD (type))
2030 int blen = SPEC_BLEN (type);
2033 return RESULT_TYPE_BIT;
2035 return RESULT_TYPE_CHAR;
2036 return RESULT_TYPE_INT;
2039 return RESULT_TYPE_CHAR;
2042 return RESULT_TYPE_INT;
2043 return RESULT_TYPE_OTHER;
2046 /*-----------------------------------------------------------------*/
2047 /* addCast - adds casts to a type specified by RESULT_TYPE */
2048 /*-----------------------------------------------------------------*/
2050 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2053 bool upCasted = FALSE;
2057 case RESULT_TYPE_NONE:
2058 /* char: promote to int */
2060 getSize (tree->etype) >= INTSIZE)
2062 newLink = newIntLink();
2065 case RESULT_TYPE_CHAR:
2066 if (IS_CHAR (tree->etype) ||
2067 IS_FLOAT(tree->etype))
2069 newLink = newCharLink();
2071 case RESULT_TYPE_INT:
2073 if (getSize (tree->etype) > INTSIZE)
2075 /* warn ("Loosing significant digits"); */
2079 /* char: promote to int */
2081 getSize (tree->etype) >= INTSIZE)
2083 newLink = newIntLink();
2086 case RESULT_TYPE_OTHER:
2089 /* return type is long, float: promote char to int */
2090 if (getSize (tree->etype) >= INTSIZE)
2092 newLink = newIntLink();
2098 tree->decorated = 0;
2099 tree = newNode (CAST, newAst_LINK (newLink), tree);
2100 tree->lineno = tree->right->lineno;
2101 /* keep unsigned type during cast to smaller type,
2102 but not when promoting from char to int */
2104 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2105 return decorateType (tree, resultType);
2108 /*-----------------------------------------------------------------*/
2109 /* resultTypePropagate - decides if resultType can be propagated */
2110 /*-----------------------------------------------------------------*/
2112 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2114 switch (tree->opval.op)
2130 return RESULT_TYPE_NONE;
2134 return RESULT_TYPE_IFX;
2136 return RESULT_TYPE_NONE;
2140 /*-----------------------------------------------------------------*/
2141 /* getLeftResultType - gets type from left branch for propagation */
2142 /*-----------------------------------------------------------------*/
2144 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2146 switch (tree->opval.op)
2150 if (IS_PTR (LTYPE (tree)))
2151 return RESULT_TYPE_NONE;
2153 return getResultTypeFromType (LETYPE (tree));
2155 if (IS_PTR (currFunc->type->next))
2156 return RESULT_TYPE_NONE;
2158 return getResultTypeFromType (currFunc->type->next);
2160 if (!IS_ARRAY (LTYPE (tree)))
2162 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2163 return RESULT_TYPE_CHAR;
2170 /*--------------------------------------------------------------------*/
2171 /* decorateType - compute type for this tree, also does type checking.*/
2172 /* This is done bottom up, since type has to flow upwards. */
2173 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2174 /* result is a char and the operand(s) are int's. */
2175 /* It also does constant folding, and parameter checking. */
2176 /*--------------------------------------------------------------------*/
2178 decorateType (ast * tree, RESULT_TYPE resultType)
2182 RESULT_TYPE resultTypeProp;
2187 /* if already has type then do nothing */
2188 if (tree->decorated)
2191 tree->decorated = 1;
2194 /* print the line */
2195 /* if not block & function */
2196 if (tree->type == EX_OP &&
2197 (tree->opval.op != FUNCTION &&
2198 tree->opval.op != BLOCK &&
2199 tree->opval.op != NULLOP))
2201 filename = tree->filename;
2202 lineno = tree->lineno;
2206 /* if any child is an error | this one is an error do nothing */
2207 if (tree->isError ||
2208 (tree->left && tree->left->isError) ||
2209 (tree->right && tree->right->isError))
2212 /*------------------------------------------------------------------*/
2213 /*----------------------------*/
2214 /* leaf has been reached */
2215 /*----------------------------*/
2216 lineno=tree->lineno;
2217 /* if this is of type value */
2218 /* just get the type */
2219 if (tree->type == EX_VALUE)
2222 if (IS_LITERAL (tree->opval.val->etype))
2225 /* if this is a character array then declare it */
2226 if (IS_ARRAY (tree->opval.val->type))
2227 tree->opval.val = stringToSymbol (tree->opval.val);
2229 /* otherwise just copy the type information */
2230 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2234 if (tree->opval.val->sym)
2236 /* if the undefined flag is set then give error message */
2237 if (tree->opval.val->sym->undefined)
2239 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2241 TTYPE (tree) = TETYPE (tree) =
2242 tree->opval.val->type = tree->opval.val->sym->type =
2243 tree->opval.val->etype = tree->opval.val->sym->etype =
2244 copyLinkChain (INTTYPE);
2249 /* if impilicit i.e. struct/union member then no type */
2250 if (tree->opval.val->sym->implicit)
2251 TTYPE (tree) = TETYPE (tree) = NULL;
2256 /* else copy the type */
2257 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2259 /* and mark it as referenced */
2260 tree->opval.val->sym->isref = 1;
2268 /* if type link for the case of cast */
2269 if (tree->type == EX_LINK)
2271 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2279 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2281 if (tree->left && tree->left->type == EX_OPERAND
2282 && (tree->left->opval.op == INC_OP
2283 || tree->left->opval.op == DEC_OP)
2284 && tree->left->left)
2286 tree->left->right = tree->left->left;
2287 tree->left->left = NULL;
2289 if (tree->right && tree->right->type == EX_OPERAND
2290 && (tree->right->opval.op == INC_OP
2291 || tree->right->opval.op == DEC_OP)
2292 && tree->right->left)
2294 tree->right->right = tree->right->left;
2295 tree->right->left = NULL;
2300 /* Before decorating the left branch we've to decide in dependence
2301 upon tree->opval.op, if resultType can be propagated */
2302 resultTypeProp = resultTypePropagate (tree, resultType);
2304 if (tree->opval.op == '?')
2305 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2307 dtl = decorateType (tree->left, resultTypeProp);
2309 /* if an array node, we may need to swap branches */
2310 if (tree->opval.op == '[')
2312 /* determine which is the array & which the index */
2313 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2314 IS_INTEGRAL (LTYPE (tree)))
2316 ast *tempTree = tree->left;
2317 tree->left = tree->right;
2318 tree->right = tempTree;
2322 /* After decorating the left branch there's type information available
2323 in tree->left->?type. If the op is e.g. '=' we extract the type
2324 information from there and propagate it to the right branch. */
2325 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2327 switch (tree->opval.op)
2330 /* delay right side for '?' operator since conditional macro
2331 expansions might rely on this */
2335 /* decorate right side for CALL (parameter list) in processParms();
2336 there is resultType available */
2340 dtr = decorateType (tree->right, resultTypeProp);
2344 /* this is to take care of situations
2345 when the tree gets rewritten */
2346 if (dtl != tree->left)
2348 if (dtr != tree->right)
2350 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2354 /* depending on type of operator do */
2356 switch (tree->opval.op)
2358 /*------------------------------------------------------------------*/
2359 /*----------------------------*/
2361 /*----------------------------*/
2364 /* first check if this is a array or a pointer */
2365 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2367 werror (E_NEED_ARRAY_PTR, "[]");
2368 goto errorTreeReturn;
2371 /* check if the type of the idx */
2372 if (!IS_INTEGRAL (RTYPE (tree)))
2374 werror (E_IDX_NOT_INT);
2375 goto errorTreeReturn;
2378 /* if the left is an rvalue then error */
2381 werror (E_LVALUE_REQUIRED, "array access");
2382 goto errorTreeReturn;
2385 if (IS_LITERAL (RTYPE (tree)))
2387 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2388 int arraySize = DCL_ELEM (LTYPE (tree));
2389 if (arraySize && arrayIndex >= arraySize)
2391 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2396 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2399 /*------------------------------------------------------------------*/
2400 /*----------------------------*/
2402 /*----------------------------*/
2404 /* if this is not a structure */
2405 if (!IS_STRUCT (LTYPE (tree)))
2407 werror (E_STRUCT_UNION, ".");
2408 goto errorTreeReturn;
2410 TTYPE (tree) = structElemType (LTYPE (tree),
2411 (tree->right->type == EX_VALUE ?
2412 tree->right->opval.val : NULL));
2413 TETYPE (tree) = getSpec (TTYPE (tree));
2416 /*------------------------------------------------------------------*/
2417 /*----------------------------*/
2418 /* struct/union pointer */
2419 /*----------------------------*/
2421 /* if not pointer to a structure */
2422 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2424 werror (E_PTR_REQD);
2425 goto errorTreeReturn;
2428 if (!IS_STRUCT (LTYPE (tree)->next))
2430 werror (E_STRUCT_UNION, "->");
2431 goto errorTreeReturn;
2434 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2435 (tree->right->type == EX_VALUE ?
2436 tree->right->opval.val : NULL));
2437 TETYPE (tree) = getSpec (TTYPE (tree));
2439 /* adjust the storage class */
2440 switch (DCL_TYPE(tree->left->ftype)) {
2442 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2445 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2448 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2451 SPEC_SCLS (TETYPE (tree)) = 0;
2454 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2457 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2460 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2463 SPEC_SCLS (TETYPE (tree)) = 0;
2470 /* This breaks with extern declarations, bitfields, and perhaps other */
2471 /* cases (gcse). Let's leave this optimization disabled for now and */
2472 /* ponder if there's a safe way to do this. -- EEP */
2474 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2475 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2477 /* If defined struct type at addr var
2478 then rewrite (&struct var)->member
2480 and define membertype at (addr+offsetof(struct var,member)) temp
2483 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2484 AST_SYMBOL(tree->right));
2486 sym = newSymbol(genSymName (0), 0);
2487 sym->type = TTYPE (tree);
2488 sym->etype = getSpec(sym->type);
2489 sym->lineDef = tree->lineno;
2492 SPEC_STAT (sym->etype) = 1;
2493 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2495 SPEC_ABSA(sym->etype) = 1;
2496 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2499 AST_VALUE (tree) = symbolVal(sym);
2502 tree->type = EX_VALUE;
2510 /*------------------------------------------------------------------*/
2511 /*----------------------------*/
2512 /* ++/-- operation */
2513 /*----------------------------*/
2517 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2518 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2519 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2520 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2529 /*------------------------------------------------------------------*/
2530 /*----------------------------*/
2532 /*----------------------------*/
2533 case '&': /* can be unary */
2534 /* if right is NULL then unary operation */
2535 if (tree->right) /* not an unary operation */
2538 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2540 werror (E_BITWISE_OP);
2541 werror (W_CONTINUE, "left & right types are ");
2542 printTypeChain (LTYPE (tree), stderr);
2543 fprintf (stderr, ",");
2544 printTypeChain (RTYPE (tree), stderr);
2545 fprintf (stderr, "\n");
2546 goto errorTreeReturn;
2549 /* if they are both literal */
2550 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2552 tree->type = EX_VALUE;
2553 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2554 valFromType (RETYPE (tree)), '&');
2556 tree->right = tree->left = NULL;
2557 TETYPE (tree) = tree->opval.val->etype;
2558 TTYPE (tree) = tree->opval.val->type;
2562 /* see if this is a GETHBIT operation if yes
2565 ast *otree = optimizeGetHbit (tree);
2568 return decorateType (otree, RESULT_TYPE_NONE);
2571 /* if left is a literal exchange left & right */
2572 if (IS_LITERAL (LTYPE (tree)))
2574 ast *tTree = tree->left;
2575 tree->left = tree->right;
2576 tree->right = tTree;
2579 /* if right is a literal and */
2580 /* we can find a 2nd literal in an and-tree then */
2581 /* rearrange the tree */
2582 if (IS_LITERAL (RTYPE (tree)))
2585 ast *litTree = searchLitOp (tree, &parent, "&");
2589 ast *tTree = litTree->left;
2590 litTree->left = tree->right;
2591 tree->right = tTree;
2592 /* both operands in litTree are literal now */
2593 decorateType (parent, resultType);
2597 LRVAL (tree) = RRVAL (tree) = 1;
2599 TTYPE (tree) = computeType (LTYPE (tree),
2603 TETYPE (tree) = getSpec (TTYPE (tree));
2608 /*------------------------------------------------------------------*/
2609 /*----------------------------*/
2611 /*----------------------------*/
2612 p = newLink (DECLARATOR);
2613 /* if bit field then error */
2614 if (IS_BITVAR (tree->left->etype))
2616 werror (E_ILLEGAL_ADDR, "address of bit variable");
2617 goto errorTreeReturn;
2620 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2622 werror (E_ILLEGAL_ADDR, "address of register variable");
2623 goto errorTreeReturn;
2626 if (IS_FUNC (LTYPE (tree)))
2628 // this ought to be ignored
2629 return (tree->left);
2632 if (IS_LITERAL(LTYPE(tree)))
2634 werror (E_ILLEGAL_ADDR, "address of literal");
2635 goto errorTreeReturn;
2640 werror (E_LVALUE_REQUIRED, "address of");
2641 goto errorTreeReturn;
2644 DCL_TYPE (p) = POINTER;
2645 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2646 DCL_TYPE (p) = CPOINTER;
2647 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2648 DCL_TYPE (p) = FPOINTER;
2649 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2650 DCL_TYPE (p) = PPOINTER;
2651 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2652 DCL_TYPE (p) = IPOINTER;
2653 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2654 DCL_TYPE (p) = EEPPOINTER;
2655 else if (SPEC_OCLS(tree->left->etype))
2656 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2658 DCL_TYPE (p) = POINTER;
2660 if (IS_AST_SYM_VALUE (tree->left))
2662 AST_SYMBOL (tree->left)->addrtaken = 1;
2663 AST_SYMBOL (tree->left)->allocreq = 1;
2666 p->next = LTYPE (tree);
2668 TETYPE (tree) = getSpec (TTYPE (tree));
2673 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2674 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2676 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2677 AST_SYMBOL(tree->left->right));
2678 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2679 valueFromLit(element->offset));
2682 tree->type = EX_VALUE;
2683 tree->values.literalFromCast = 1;
2689 /*------------------------------------------------------------------*/
2690 /*----------------------------*/
2692 /*----------------------------*/
2694 /* if the rewrite succeeds then don't go any furthur */
2696 ast *wtree = optimizeRRCRLC (tree);
2698 return decorateType (wtree, RESULT_TYPE_NONE);
2700 wtree = optimizeSWAP (tree);
2702 return decorateType (wtree, RESULT_TYPE_NONE);
2705 /* if left is a literal exchange left & right */
2706 if (IS_LITERAL (LTYPE (tree)))
2708 ast *tTree = tree->left;
2709 tree->left = tree->right;
2710 tree->right = tTree;
2713 /* if right is a literal and */
2714 /* we can find a 2nd literal in an or-tree then */
2715 /* rearrange the tree */
2716 if (IS_LITERAL (RTYPE (tree)))
2719 ast *litTree = searchLitOp (tree, &parent, "|");
2723 ast *tTree = litTree->left;
2724 litTree->left = tree->right;
2725 tree->right = tTree;
2726 /* both operands in tTree are literal now */
2727 decorateType (parent, resultType);
2732 /*------------------------------------------------------------------*/
2733 /*----------------------------*/
2735 /*----------------------------*/
2737 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2739 werror (E_BITWISE_OP);
2740 werror (W_CONTINUE, "left & right types are ");
2741 printTypeChain (LTYPE (tree), stderr);
2742 fprintf (stderr, ",");
2743 printTypeChain (RTYPE (tree), stderr);
2744 fprintf (stderr, "\n");
2745 goto errorTreeReturn;
2748 /* if they are both literal then rewrite the tree */
2749 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2751 tree->type = EX_VALUE;
2752 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2753 valFromType (RETYPE (tree)),
2755 tree->right = tree->left = NULL;
2756 TETYPE (tree) = tree->opval.val->etype;
2757 TTYPE (tree) = tree->opval.val->type;
2761 /* if left is a literal exchange left & right */
2762 if (IS_LITERAL (LTYPE (tree)))
2764 ast *tTree = tree->left;
2765 tree->left = tree->right;
2766 tree->right = tTree;
2769 /* if right is a literal and */
2770 /* we can find a 2nd literal in a xor-tree then */
2771 /* rearrange the tree */
2772 if (IS_LITERAL (RTYPE (tree)) &&
2773 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2776 ast *litTree = searchLitOp (tree, &parent, "^");
2780 ast *tTree = litTree->left;
2781 litTree->left = tree->right;
2782 tree->right = tTree;
2783 /* both operands in litTree are literal now */
2784 decorateType (parent, resultType);
2788 LRVAL (tree) = RRVAL (tree) = 1;
2790 TTYPE (tree) = computeType (LTYPE (tree),
2794 TETYPE (tree) = getSpec (TTYPE (tree));
2798 /*------------------------------------------------------------------*/
2799 /*----------------------------*/
2801 /*----------------------------*/
2803 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2805 werror (E_INVALID_OP, "divide");
2806 goto errorTreeReturn;
2808 /* if they are both literal then */
2809 /* rewrite the tree */
2810 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2812 tree->type = EX_VALUE;
2813 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2814 valFromType (RETYPE (tree)));
2815 tree->right = tree->left = NULL;
2816 TETYPE (tree) = getSpec (TTYPE (tree) =
2817 tree->opval.val->type);
2821 LRVAL (tree) = RRVAL (tree) = 1;
2823 TETYPE (tree) = getSpec (TTYPE (tree) =
2824 computeType (LTYPE (tree),
2829 /* if right is a literal and */
2830 /* left is also a division by a literal then */
2831 /* rearrange the tree */
2832 if (IS_LITERAL (RTYPE (tree))
2833 /* avoid infinite loop */
2834 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2837 ast *litTree = searchLitOp (tree, &parent, "/");
2840 if (IS_LITERAL (RTYPE (litTree)))
2844 litTree->right = newNode ('*',
2846 copyAst (tree->right));
2847 litTree->right->lineno = tree->lineno;
2849 tree->right->opval.val = constVal ("1");
2850 decorateType (parent, resultType);
2854 /* litTree->left is literal: no gcse possible.
2855 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2856 this would cause an infinit loop. */
2857 parent->decorated = 1;
2858 decorateType (litTree, resultType);
2865 /*------------------------------------------------------------------*/
2866 /*----------------------------*/
2868 /*----------------------------*/
2870 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2872 werror (E_BITWISE_OP);
2873 werror (W_CONTINUE, "left & right types are ");
2874 printTypeChain (LTYPE (tree), stderr);
2875 fprintf (stderr, ",");
2876 printTypeChain (RTYPE (tree), stderr);
2877 fprintf (stderr, "\n");
2878 goto errorTreeReturn;
2880 /* if they are both literal then */
2881 /* rewrite the tree */
2882 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2884 tree->type = EX_VALUE;
2885 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2886 valFromType (RETYPE (tree)));
2887 tree->right = tree->left = NULL;
2888 TETYPE (tree) = getSpec (TTYPE (tree) =
2889 tree->opval.val->type);
2892 LRVAL (tree) = RRVAL (tree) = 1;
2893 TETYPE (tree) = getSpec (TTYPE (tree) =
2894 computeType (LTYPE (tree),
2900 /*------------------------------------------------------------------*/
2901 /*----------------------------*/
2902 /* address dereference */
2903 /*----------------------------*/
2904 case '*': /* can be unary : if right is null then unary operation */
2907 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2909 werror (E_PTR_REQD);
2910 goto errorTreeReturn;
2915 werror (E_LVALUE_REQUIRED, "pointer deref");
2916 goto errorTreeReturn;
2918 if (IS_ADDRESS_OF_OP(tree->left))
2920 /* replace *&obj with obj */
2921 return tree->left->left;
2923 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2924 TETYPE (tree) = getSpec (TTYPE (tree));
2925 /* adjust the storage class */
2926 switch (DCL_TYPE(tree->left->ftype)) {
2928 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2931 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2934 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2937 SPEC_SCLS (TETYPE (tree)) = 0;
2940 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2943 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2946 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2949 SPEC_SCLS (TETYPE (tree)) = 0;
2958 /*------------------------------------------------------------------*/
2959 /*----------------------------*/
2960 /* multiplication */
2961 /*----------------------------*/
2962 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2964 werror (E_INVALID_OP, "multiplication");
2965 goto errorTreeReturn;
2968 /* if they are both literal then */
2969 /* rewrite the tree */
2970 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2972 tree->type = EX_VALUE;
2973 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2974 valFromType (RETYPE (tree)));
2975 tree->right = tree->left = NULL;
2976 TETYPE (tree) = getSpec (TTYPE (tree) =
2977 tree->opval.val->type);
2981 /* if left is a literal exchange left & right */
2982 if (IS_LITERAL (LTYPE (tree)))
2984 ast *tTree = tree->left;
2985 tree->left = tree->right;
2986 tree->right = tTree;
2989 /* if right is a literal and */
2990 /* we can find a 2nd literal in a mul-tree then */
2991 /* rearrange the tree */
2992 if (IS_LITERAL (RTYPE (tree)))
2995 ast *litTree = searchLitOp (tree, &parent, "*");
2999 ast *tTree = litTree->left;
3000 litTree->left = tree->right;
3001 tree->right = tTree;
3002 /* both operands in litTree are literal now */
3003 decorateType (parent, resultType);
3007 LRVAL (tree) = RRVAL (tree) = 1;
3008 tree->left = addCast (tree->left, resultType, FALSE);
3009 tree->right = addCast (tree->right, resultType, FALSE);
3010 TETYPE (tree) = getSpec (TTYPE (tree) =
3011 computeType (LTYPE (tree),
3018 /*------------------------------------------------------------------*/
3019 /*----------------------------*/
3020 /* unary '+' operator */
3021 /*----------------------------*/
3026 if (!IS_ARITHMETIC (LTYPE (tree)))
3028 werror (E_UNARY_OP, '+');
3029 goto errorTreeReturn;
3032 /* if left is a literal then do it */
3033 if (IS_LITERAL (LTYPE (tree)))
3035 tree->type = EX_VALUE;
3036 tree->opval.val = valFromType (LETYPE (tree));
3038 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3042 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3046 /*------------------------------------------------------------------*/
3047 /*----------------------------*/
3049 /*----------------------------*/
3051 /* this is not a unary operation */
3052 /* if both pointers then problem */
3053 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3054 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3056 werror (E_PTR_PLUS_PTR);
3057 goto errorTreeReturn;
3060 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3061 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3063 werror (E_PLUS_INVALID, "+");
3064 goto errorTreeReturn;
3067 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3068 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3070 werror (E_PLUS_INVALID, "+");
3071 goto errorTreeReturn;
3073 /* if they are both literal then */
3074 /* rewrite the tree */
3075 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3077 tree->type = EX_VALUE;
3078 tree->left = addCast (tree->left, resultType, TRUE);
3079 tree->right = addCast (tree->right, resultType, TRUE);
3080 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3081 valFromType (RETYPE (tree)));
3082 tree->right = tree->left = NULL;
3083 TETYPE (tree) = getSpec (TTYPE (tree) =
3084 tree->opval.val->type);
3088 /* if the right is a pointer or left is a literal
3089 xchange left & right */
3090 if (IS_ARRAY (RTYPE (tree)) ||
3091 IS_PTR (RTYPE (tree)) ||
3092 IS_LITERAL (LTYPE (tree)))
3094 ast *tTree = tree->left;
3095 tree->left = tree->right;
3096 tree->right = tTree;
3099 /* if right is a literal and */
3100 /* left is also an addition/subtraction with a literal then */
3101 /* rearrange the tree */
3102 if (IS_LITERAL (RTYPE (tree)))
3104 ast *litTree, *parent;
3105 litTree = searchLitOp (tree, &parent, "+-");
3108 if (litTree->opval.op == '+')
3112 ast *tTree = litTree->left;
3113 litTree->left = tree->right;
3114 tree->right = tree->left;
3117 else if (litTree->opval.op == '-')
3119 if (IS_LITERAL (RTYPE (litTree)))
3123 ast *tTree = litTree->left;
3124 litTree->left = tree->right;
3125 tree->right = tTree;
3131 ast *tTree = litTree->right;
3132 litTree->right = tree->right;
3133 tree->right = tTree;
3134 litTree->opval.op = '+';
3135 tree->opval.op = '-';
3138 decorateType (parent, resultType);
3142 LRVAL (tree) = RRVAL (tree) = 1;
3143 /* if the left is a pointer */
3144 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3145 TETYPE (tree) = getSpec (TTYPE (tree) =
3149 tree->left = addCast (tree->left, resultType, TRUE);
3150 tree->right = addCast (tree->right, resultType, TRUE);
3151 TETYPE (tree) = getSpec (TTYPE (tree) =
3152 computeType (LTYPE (tree),
3160 /*------------------------------------------------------------------*/
3161 /*----------------------------*/
3163 /*----------------------------*/
3164 case '-': /* can be unary */
3165 /* if right is null then unary */
3169 if (!IS_ARITHMETIC (LTYPE (tree)))
3171 werror (E_UNARY_OP, tree->opval.op);
3172 goto errorTreeReturn;
3175 /* if left is a literal then do it */
3176 if (IS_LITERAL (LTYPE (tree)))
3178 tree->type = EX_VALUE;
3179 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3181 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3182 SPEC_USIGN(TETYPE(tree)) = 0;
3186 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3190 /*------------------------------------------------------------------*/
3191 /*----------------------------*/
3193 /*----------------------------*/
3195 if (!(IS_PTR (LTYPE (tree)) ||
3196 IS_ARRAY (LTYPE (tree)) ||
3197 IS_ARITHMETIC (LTYPE (tree))))
3199 werror (E_PLUS_INVALID, "-");
3200 goto errorTreeReturn;
3203 if (!(IS_PTR (RTYPE (tree)) ||
3204 IS_ARRAY (RTYPE (tree)) ||
3205 IS_ARITHMETIC (RTYPE (tree))))
3207 werror (E_PLUS_INVALID, "-");
3208 goto errorTreeReturn;
3211 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3212 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3213 IS_INTEGRAL (RTYPE (tree))))
3215 werror (E_PLUS_INVALID, "-");
3216 goto errorTreeReturn;
3219 /* if they are both literal then */
3220 /* rewrite the tree */
3221 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3223 tree->type = EX_VALUE;
3224 tree->left = addCast (tree->left, resultType, TRUE);
3225 tree->right = addCast (tree->right, resultType, TRUE);
3226 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3227 valFromType (RETYPE (tree)));
3228 tree->right = tree->left = NULL;
3229 TETYPE (tree) = getSpec (TTYPE (tree) =
3230 tree->opval.val->type);
3234 /* if the left & right are equal then zero */
3235 if (isAstEqual (tree->left, tree->right))
3237 tree->type = EX_VALUE;
3238 tree->left = tree->right = NULL;
3239 tree->opval.val = constVal ("0");
3240 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3244 /* if both of them are pointers or arrays then */
3245 /* the result is going to be an integer */
3246 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3247 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3248 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3250 /* if only the left is a pointer */
3251 /* then result is a pointer */
3252 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3253 TETYPE (tree) = getSpec (TTYPE (tree) =
3257 tree->left = addCast (tree->left, resultType, TRUE);
3258 tree->right = addCast (tree->right, resultType, TRUE);
3260 TETYPE (tree) = getSpec (TTYPE (tree) =
3261 computeType (LTYPE (tree),
3267 LRVAL (tree) = RRVAL (tree) = 1;
3269 /* if right is a literal and */
3270 /* left is also an addition/subtraction with a literal then */
3271 /* rearrange the tree */
3272 if (IS_LITERAL (RTYPE (tree))
3273 /* avoid infinite loop */
3274 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3276 ast *litTree, *litParent;
3277 litTree = searchLitOp (tree, &litParent, "+-");
3280 if (litTree->opval.op == '+')
3284 ast *tTree = litTree->left;
3285 litTree->left = litTree->right;
3286 litTree->right = tree->right;
3287 tree->right = tTree;
3288 tree->opval.op = '+';
3289 litTree->opval.op = '-';
3291 else if (litTree->opval.op == '-')
3293 if (IS_LITERAL (RTYPE (litTree)))
3297 ast *tTree = litTree->left;
3298 litTree->left = tree->right;
3299 tree->right = litParent->left;
3300 litParent->left = tTree;
3301 litTree->opval.op = '+';
3303 tree->decorated = 0;
3304 decorateType (tree, resultType);
3310 ast *tTree = litTree->right;
3311 litTree->right = tree->right;
3312 tree->right = tTree;
3315 decorateType (litParent, resultType);
3320 /*------------------------------------------------------------------*/
3321 /*----------------------------*/
3323 /*----------------------------*/
3325 /* can be only integral type */
3326 if (!IS_INTEGRAL (LTYPE (tree)))
3328 werror (E_UNARY_OP, tree->opval.op);
3329 goto errorTreeReturn;
3332 /* if left is a literal then do it */
3333 if (IS_LITERAL (LTYPE (tree)))
3335 tree->type = EX_VALUE;
3336 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3338 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3339 return addCast (tree, resultType, TRUE);
3341 tree->left = addCast (tree->left, resultType, TRUE);
3343 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3346 /*------------------------------------------------------------------*/
3347 /*----------------------------*/
3349 /*----------------------------*/
3351 /* can be pointer */
3352 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3353 !IS_PTR (LTYPE (tree)) &&
3354 !IS_ARRAY (LTYPE (tree)))
3356 werror (E_UNARY_OP, tree->opval.op);
3357 goto errorTreeReturn;
3360 /* if left is a literal then do it */
3361 if (IS_LITERAL (LTYPE (tree)))
3363 tree->type = EX_VALUE;
3364 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3366 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3370 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3373 /*------------------------------------------------------------------*/
3374 /*----------------------------*/
3376 /*----------------------------*/
3380 TTYPE (tree) = LTYPE (tree);
3381 TETYPE (tree) = LETYPE (tree);
3385 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3390 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3392 werror (E_SHIFT_OP_INVALID);
3393 werror (W_CONTINUE, "left & right types are ");
3394 printTypeChain (LTYPE (tree), stderr);
3395 fprintf (stderr, ",");
3396 printTypeChain (RTYPE (tree), stderr);
3397 fprintf (stderr, "\n");
3398 goto errorTreeReturn;
3401 /* make smaller type only if it's a LEFT_OP */
3402 if (tree->opval.op == LEFT_OP)
3403 tree->left = addCast (tree->left, resultType, TRUE);
3405 /* if they are both literal then */
3406 /* rewrite the tree */
3407 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3409 tree->type = EX_VALUE;
3410 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3411 valFromType (RETYPE (tree)),
3412 (tree->opval.op == LEFT_OP ? 1 : 0));
3413 tree->right = tree->left = NULL;
3414 TETYPE (tree) = getSpec (TTYPE (tree) =
3415 tree->opval.val->type);
3419 LRVAL (tree) = RRVAL (tree) = 1;
3420 if (tree->opval.op == LEFT_OP)
3422 TETYPE (tree) = getSpec (TTYPE (tree) =
3423 computeType (LTYPE (tree),
3430 /* no promotion necessary */
3431 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3432 if (IS_LITERAL (TTYPE (tree)))
3433 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3436 /* if only the right side is a literal & we are
3437 shifting more than size of the left operand then zero */
3438 if (IS_LITERAL (RTYPE (tree)) &&
3439 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3440 (getSize (TETYPE (tree)) * 8))
3442 if (tree->opval.op==LEFT_OP ||
3443 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3445 lineno=tree->lineno;
3446 werror (W_SHIFT_CHANGED,
3447 (tree->opval.op == LEFT_OP ? "left" : "right"));
3448 tree->type = EX_VALUE;
3449 tree->left = tree->right = NULL;
3450 tree->opval.val = constVal ("0");
3451 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3458 /*------------------------------------------------------------------*/
3459 /*----------------------------*/
3461 /*----------------------------*/
3462 case CAST: /* change the type */
3463 /* cannot cast to an aggregate type */
3464 if (IS_AGGREGATE (LTYPE (tree)))
3466 werror (E_CAST_ILLEGAL);
3467 goto errorTreeReturn;
3470 /* make sure the type is complete and sane */
3471 changePointer(LTYPE(tree));
3472 checkTypeSanity(LETYPE(tree), "(cast)");
3474 /* If code memory is read only, then pointers to code memory */
3475 /* implicitly point to constants -- make this explicit */
3477 sym_link *t = LTYPE(tree);
3478 while (t && t->next)
3480 if (IS_CODEPTR(t) && port->mem.code_ro)
3482 if (IS_SPEC(t->next))
3483 SPEC_CONST (t->next) = 1;
3485 DCL_PTR_CONST (t->next) = 1;
3492 /* if the right is a literal replace the tree */
3493 if (IS_LITERAL (RETYPE (tree))) {
3494 if (!IS_PTR (LTYPE (tree))) {
3495 tree->type = EX_VALUE;
3497 valCastLiteral (LTYPE (tree),
3498 floatFromVal (valFromType (RETYPE (tree))));
3501 TTYPE (tree) = tree->opval.val->type;
3502 tree->values.literalFromCast = 1;
3503 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3504 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3505 sym_link *rest = LTYPE(tree)->next;
3506 werror(W_LITERAL_GENERIC);
3507 TTYPE(tree) = newLink(DECLARATOR);
3508 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3509 TTYPE(tree)->next = rest;
3510 tree->left->opval.lnk = TTYPE(tree);
3513 TTYPE (tree) = LTYPE (tree);
3517 TTYPE (tree) = LTYPE (tree);
3521 #if 0 // this is already checked, now this could be explicit
3522 /* if pointer to struct then check names */
3523 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3524 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3525 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3527 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3528 SPEC_STRUCT(LETYPE(tree))->tag);
3531 if (IS_ADDRESS_OF_OP(tree->right)
3532 && IS_AST_SYM_VALUE (tree->right->left)
3533 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3535 tree->type = EX_VALUE;
3537 valCastLiteral (LTYPE (tree),
3538 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3539 TTYPE (tree) = tree->opval.val->type;
3540 TETYPE (tree) = getSpec (TTYPE (tree));
3543 tree->values.literalFromCast = 1;
3547 /* handle offsetof macro: */
3548 /* #define offsetof(TYPE, MEMBER) \ */
3549 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3550 if (IS_ADDRESS_OF_OP(tree->right)
3551 && IS_AST_OP (tree->right->left)
3552 && tree->right->left->opval.op == PTR_OP
3553 && IS_AST_OP (tree->right->left->left)
3554 && tree->right->left->left->opval.op == CAST
3555 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3557 symbol *element = getStructElement (
3558 SPEC_STRUCT (LETYPE(tree->right->left)),
3559 AST_SYMBOL(tree->right->left->right)
3563 tree->type = EX_VALUE;
3564 tree->opval.val = valCastLiteral (
3567 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3570 TTYPE (tree) = tree->opval.val->type;
3571 TETYPE (tree) = getSpec (TTYPE (tree));
3578 /* if the right is a literal replace the tree */
3579 if (IS_LITERAL (RETYPE (tree))) {
3581 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3582 /* rewrite (type *)litaddr
3584 and define type at litaddr temp
3585 (but only if type's storage class is not generic)
3587 ast *newTree = newNode ('&', NULL, NULL);
3590 TTYPE (newTree) = LTYPE (tree);
3591 TETYPE (newTree) = getSpec(LTYPE (tree));
3593 /* define a global symbol at the casted address*/
3594 sym = newSymbol(genSymName (0), 0);
3595 sym->type = LTYPE (tree)->next;
3597 sym->type = newLink (V_VOID);
3598 sym->etype = getSpec(sym->type);
3599 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3600 sym->lineDef = tree->lineno;
3603 SPEC_STAT (sym->etype) = 1;
3604 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3605 SPEC_ABSA(sym->etype) = 1;
3606 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3609 newTree->left = newAst_VALUE(symbolVal(sym));
3610 newTree->left->lineno = tree->lineno;
3611 LTYPE (newTree) = sym->type;
3612 LETYPE (newTree) = sym->etype;
3613 LLVAL (newTree) = 1;
3614 LRVAL (newTree) = 0;
3615 TLVAL (newTree) = 1;
3619 if (!IS_PTR (LTYPE (tree))) {
3620 tree->type = EX_VALUE;
3622 valCastLiteral (LTYPE (tree),
3623 floatFromVal (valFromType (RTYPE (tree))));
3624 TTYPE (tree) = tree->opval.val->type;
3627 tree->values.literalFromCast = 1;
3628 TETYPE (tree) = getSpec (TTYPE (tree));
3632 TTYPE (tree) = LTYPE (tree);
3636 TETYPE (tree) = getSpec (TTYPE (tree));
3640 /*------------------------------------------------------------------*/
3641 /*----------------------------*/
3642 /* logical &&, || */
3643 /*----------------------------*/
3646 /* each must be arithmetic type or be a pointer */
3647 if (!IS_PTR (LTYPE (tree)) &&
3648 !IS_ARRAY (LTYPE (tree)) &&
3649 !IS_INTEGRAL (LTYPE (tree)))
3651 werror (E_COMPARE_OP);
3652 goto errorTreeReturn;
3655 if (!IS_PTR (RTYPE (tree)) &&
3656 !IS_ARRAY (RTYPE (tree)) &&
3657 !IS_INTEGRAL (RTYPE (tree)))
3659 werror (E_COMPARE_OP);
3660 goto errorTreeReturn;
3662 /* if they are both literal then */
3663 /* rewrite the tree */
3664 if (IS_LITERAL (RTYPE (tree)) &&
3665 IS_LITERAL (LTYPE (tree)))
3667 tree->type = EX_VALUE;
3668 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3669 valFromType (RTYPE (tree)),
3671 tree->right = tree->left = NULL;
3672 TETYPE (tree) = getSpec (TTYPE (tree) =
3673 tree->opval.val->type);
3676 LRVAL (tree) = RRVAL (tree) = 1;
3677 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3680 /*------------------------------------------------------------------*/
3681 /*----------------------------*/
3682 /* comparison operators */
3683 /*----------------------------*/
3691 ast *lt = optimizeCompare (tree);
3697 /* if they are pointers they must be castable */
3698 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3700 if (tree->opval.op==EQ_OP &&
3701 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3702 // we cannot cast a gptr to a !gptr: switch the leaves
3703 struct ast *s=tree->left;
3704 tree->left=tree->right;
3707 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3709 werror (E_COMPARE_OP);
3710 fprintf (stderr, "comparing type ");
3711 printTypeChain (LTYPE (tree), stderr);
3712 fprintf (stderr, "to type ");
3713 printTypeChain (RTYPE (tree), stderr);
3714 fprintf (stderr, "\n");
3715 goto errorTreeReturn;
3718 /* else they should be promotable to one another */
3721 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3722 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3724 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3726 werror (E_COMPARE_OP);
3727 fprintf (stderr, "comparing type ");
3728 printTypeChain (LTYPE (tree), stderr);
3729 fprintf (stderr, "to type ");
3730 printTypeChain (RTYPE (tree), stderr);
3731 fprintf (stderr, "\n");
3732 goto errorTreeReturn;
3735 /* if unsigned value < 0 then always false */
3736 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3737 if (SPEC_USIGN(LETYPE(tree)) &&
3738 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3739 IS_LITERAL(RTYPE(tree)) &&
3740 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3742 if (tree->opval.op == '<')
3746 if (tree->opval.op == '>')
3748 if (resultType == RESULT_TYPE_IFX)
3750 /* the parent is an ifx: */
3751 /* if (unsigned value) */
3755 /* (unsigned value) ? 1 : 0 */
3756 tree->opval.op = '?';
3757 tree->right = newNode (':',
3758 newAst_VALUE (constVal ("1")),
3759 tree->right); /* val 0 */
3760 tree->right->lineno = tree->lineno;
3761 tree->right->left->lineno = tree->lineno;
3762 decorateType (tree->right, RESULT_TYPE_NONE);
3765 /* if they are both literal then */
3766 /* rewrite the tree */
3767 if (IS_LITERAL (RTYPE (tree)) &&
3768 IS_LITERAL (LTYPE (tree)))
3770 tree->type = EX_VALUE;
3771 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3772 valFromType (RETYPE (tree)),
3774 tree->right = tree->left = NULL;
3775 TETYPE (tree) = getSpec (TTYPE (tree) =
3776 tree->opval.val->type);
3779 LRVAL (tree) = RRVAL (tree) = 1;
3780 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3783 /*------------------------------------------------------------------*/
3784 /*----------------------------*/
3786 /*----------------------------*/
3787 case SIZEOF: /* evaluate wihout code generation */
3788 /* change the type to a integer */
3790 int size = getSize (tree->right->ftype);
3791 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3792 if (!size && !IS_VOID(tree->right->ftype))
3793 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3795 tree->type = EX_VALUE;
3796 tree->opval.val = constVal (buffer);
3797 tree->right = tree->left = NULL;
3798 TETYPE (tree) = getSpec (TTYPE (tree) =
3799 tree->opval.val->type);
3802 /*------------------------------------------------------------------*/
3803 /*----------------------------*/
3805 /*----------------------------*/
3807 /* return typeof enum value */
3808 tree->type = EX_VALUE;
3811 if (IS_SPEC(tree->right->ftype)) {
3812 switch (SPEC_NOUN(tree->right->ftype)) {
3814 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3815 else typeofv = TYPEOF_INT;
3818 typeofv = TYPEOF_FLOAT;
3821 typeofv = TYPEOF_CHAR;
3824 typeofv = TYPEOF_VOID;
3827 typeofv = TYPEOF_STRUCT;
3830 typeofv = TYPEOF_BITFIELD;
3833 typeofv = TYPEOF_BIT;
3836 typeofv = TYPEOF_SBIT;
3842 switch (DCL_TYPE(tree->right->ftype)) {
3844 typeofv = TYPEOF_POINTER;
3847 typeofv = TYPEOF_FPOINTER;
3850 typeofv = TYPEOF_CPOINTER;
3853 typeofv = TYPEOF_GPOINTER;
3856 typeofv = TYPEOF_PPOINTER;
3859 typeofv = TYPEOF_IPOINTER;
3862 typeofv = TYPEOF_ARRAY;
3865 typeofv = TYPEOF_FUNCTION;
3871 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3872 tree->opval.val = constVal (buffer);
3873 tree->right = tree->left = NULL;
3874 TETYPE (tree) = getSpec (TTYPE (tree) =
3875 tree->opval.val->type);
3878 /*------------------------------------------------------------------*/
3879 /*----------------------------*/
3880 /* conditional operator '?' */
3881 /*----------------------------*/
3883 /* the type is value of the colon operator (on the right) */
3884 assert (IS_COLON_OP (tree->right));
3885 /* if already known then replace the tree : optimizer will do it
3886 but faster to do it here */
3887 if (IS_LITERAL (LTYPE (tree)))
3889 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3890 return decorateType (tree->right->left, resultTypeProp);
3892 return decorateType (tree->right->right, resultTypeProp);
3896 tree->right = decorateType (tree->right, resultTypeProp);
3897 TTYPE (tree) = RTYPE (tree);
3898 TETYPE (tree) = getSpec (TTYPE (tree));
3903 /* if they don't match we have a problem */
3904 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3906 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3907 goto errorTreeReturn;
3910 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3911 resultType, tree->opval.op);
3912 TETYPE (tree) = getSpec (TTYPE (tree));
3916 #if 0 // assignment operators are converted by the parser
3917 /*------------------------------------------------------------------*/
3918 /*----------------------------*/
3919 /* assignment operators */
3920 /*----------------------------*/
3923 /* for these it must be both must be integral */
3924 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3925 !IS_ARITHMETIC (RTYPE (tree)))
3927 werror (E_OPS_INTEGRAL);
3928 goto errorTreeReturn;
3931 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3933 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3934 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3938 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3939 goto errorTreeReturn;
3950 /* for these it must be both must be integral */
3951 if (!IS_INTEGRAL (LTYPE (tree)) ||
3952 !IS_INTEGRAL (RTYPE (tree)))
3954 werror (E_OPS_INTEGRAL);
3955 goto errorTreeReturn;
3958 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3960 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3961 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3965 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3966 goto errorTreeReturn;
3972 /*------------------------------------------------------------------*/
3973 /*----------------------------*/
3975 /*----------------------------*/
3977 if (!(IS_PTR (LTYPE (tree)) ||
3978 IS_ARITHMETIC (LTYPE (tree))))
3980 werror (E_PLUS_INVALID, "-=");
3981 goto errorTreeReturn;
3984 if (!(IS_PTR (RTYPE (tree)) ||
3985 IS_ARITHMETIC (RTYPE (tree))))
3987 werror (E_PLUS_INVALID, "-=");
3988 goto errorTreeReturn;
3991 TETYPE (tree) = getSpec (TTYPE (tree) =
3992 computeType (LTYPE (tree),
3997 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3998 werror (E_CODE_WRITE, "-=");
4002 werror (E_LVALUE_REQUIRED, "-=");
4003 goto errorTreeReturn;
4009 /*------------------------------------------------------------------*/
4010 /*----------------------------*/
4012 /*----------------------------*/
4014 /* this is not a unary operation */
4015 /* if both pointers then problem */
4016 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4018 werror (E_PTR_PLUS_PTR);
4019 goto errorTreeReturn;
4022 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4024 werror (E_PLUS_INVALID, "+=");
4025 goto errorTreeReturn;
4028 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4030 werror (E_PLUS_INVALID, "+=");
4031 goto errorTreeReturn;
4034 TETYPE (tree) = getSpec (TTYPE (tree) =
4035 computeType (LTYPE (tree),
4040 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4041 werror (E_CODE_WRITE, "+=");
4045 werror (E_LVALUE_REQUIRED, "+=");
4046 goto errorTreeReturn;
4049 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4050 tree->opval.op = '=';
4055 /*------------------------------------------------------------------*/
4056 /*----------------------------*/
4057 /* straight assignemnt */
4058 /*----------------------------*/
4060 /* cannot be an aggregate */
4061 if (IS_AGGREGATE (LTYPE (tree)))
4063 werror (E_AGGR_ASSIGN);
4064 goto errorTreeReturn;
4067 /* they should either match or be castable */
4068 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4070 werror (E_TYPE_MISMATCH, "assignment", " ");
4071 printFromToType(RTYPE(tree),LTYPE(tree));
4074 /* if the left side of the tree is of type void
4075 then report error */
4076 if (IS_VOID (LTYPE (tree)))
4078 werror (E_CAST_ZERO);
4079 printFromToType(RTYPE(tree), LTYPE(tree));
4082 TETYPE (tree) = getSpec (TTYPE (tree) =
4086 if (!tree->initMode ) {
4087 if (IS_CONSTANT(LTYPE(tree)))
4088 werror (E_CODE_WRITE, "=");
4092 werror (E_LVALUE_REQUIRED, "=");
4093 goto errorTreeReturn;
4098 /*------------------------------------------------------------------*/
4099 /*----------------------------*/
4100 /* comma operator */
4101 /*----------------------------*/
4103 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4106 /*------------------------------------------------------------------*/
4107 /*----------------------------*/
4109 /*----------------------------*/
4112 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4113 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4115 if (tree->left->opval.op == '*' && !tree->left->right)
4116 tree->left = tree->left->left;
4119 /* require a function or pointer to function */
4120 if (!IS_FUNC (LTYPE (tree))
4121 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4123 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4124 goto errorTreeReturn;
4127 /* if there are parms, make sure that
4128 parms are decorate / process / reverse only once */
4130 !tree->right->decorated)
4135 if (IS_CODEPTR(LTYPE(tree)))
4136 functype = LTYPE (tree)->next;
4138 functype = LTYPE (tree);
4140 if (processParms (tree->left, FUNC_ARGS(functype),
4141 &tree->right, &parmNumber, TRUE))
4143 goto errorTreeReturn;
4146 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4147 !IFFUNC_ISBUILTIN(functype))
4149 reverseParms (tree->right);
4152 TTYPE (tree) = functype->next;
4153 TETYPE (tree) = getSpec (TTYPE (tree));
4157 /*------------------------------------------------------------------*/
4158 /*----------------------------*/
4159 /* return statement */
4160 /*----------------------------*/
4165 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4167 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4168 printFromToType (RTYPE(tree), currFunc->type->next);
4169 goto errorTreeReturn;
4172 if (IS_VOID (currFunc->type->next)
4174 !IS_VOID (RTYPE (tree)))
4176 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4177 goto errorTreeReturn;
4180 /* if there is going to be a casting required then add it */
4181 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4184 decorateType (newNode (CAST,
4185 newAst_LINK (copyLinkChain (currFunc->type->next)),
4195 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4197 werror (W_VOID_FUNC, currFunc->name);
4198 goto errorTreeReturn;
4201 TTYPE (tree) = TETYPE (tree) = NULL;
4204 /*------------------------------------------------------------------*/
4205 /*----------------------------*/
4206 /* switch statement */
4207 /*----------------------------*/
4209 /* the switch value must be an integer */
4210 if (!IS_INTEGRAL (LTYPE (tree)))
4212 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4213 goto errorTreeReturn;
4216 TTYPE (tree) = TETYPE (tree) = NULL;
4219 /*------------------------------------------------------------------*/
4220 /*----------------------------*/
4222 /*----------------------------*/
4224 tree->left = backPatchLabels (tree->left,
4227 TTYPE (tree) = TETYPE (tree) = NULL;
4230 /*------------------------------------------------------------------*/
4231 /*----------------------------*/
4233 /*----------------------------*/
4236 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4237 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4238 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4240 /* if the for loop is reversible then
4241 reverse it otherwise do what we normally
4247 if (isLoopReversible (tree, &sym, &init, &end))
4248 return reverseLoop (tree, sym, init, end);
4250 return decorateType (createFor (AST_FOR (tree, trueLabel),
4251 AST_FOR (tree, continueLabel),
4252 AST_FOR (tree, falseLabel),
4253 AST_FOR (tree, condLabel),
4254 AST_FOR (tree, initExpr),
4255 AST_FOR (tree, condExpr),
4256 AST_FOR (tree, loopExpr),
4257 tree->left), RESULT_TYPE_NONE);
4260 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4261 "node PARAM shouldn't be processed here");
4262 /* but in processParams() */
4265 TTYPE (tree) = TETYPE (tree) = NULL;
4269 /* some error found this tree will be killed */
4271 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4272 tree->opval.op = NULLOP;
4278 /*-----------------------------------------------------------------*/
4279 /* sizeofOp - processes size of operation */
4280 /*-----------------------------------------------------------------*/
4282 sizeofOp (sym_link * type)
4287 /* make sure the type is complete and sane */
4288 checkTypeSanity(type, "(sizeof)");
4290 /* get the size and convert it to character */
4291 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4292 if (!size && !IS_VOID(type))
4293 werror (E_SIZEOF_INCOMPLETE_TYPE);
4295 /* now convert into value */
4296 return constVal (buff);
4300 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4301 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4302 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4303 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4304 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4305 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4306 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4308 /*-----------------------------------------------------------------*/
4309 /* backPatchLabels - change and or not operators to flow control */
4310 /*-----------------------------------------------------------------*/
4312 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4318 if (!(IS_ANDORNOT (tree)))
4321 /* if this an and */
4324 static int localLbl = 0;
4327 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4328 localLabel = newSymbol (buffer, NestLevel);
4330 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4332 /* if left is already a IFX then just change the if true label in that */
4333 if (!IS_IFX (tree->left))
4334 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4336 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4337 /* right is a IFX then just join */
4338 if (IS_IFX (tree->right))
4339 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4341 tree->right = createLabel (localLabel, tree->right);
4342 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4344 return newNode (NULLOP, tree->left, tree->right);
4347 /* if this is an or operation */
4350 static int localLbl = 0;
4353 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4354 localLabel = newSymbol (buffer, NestLevel);
4356 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4358 /* if left is already a IFX then just change the if true label in that */
4359 if (!IS_IFX (tree->left))
4360 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4362 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4363 /* right is a IFX then just join */
4364 if (IS_IFX (tree->right))
4365 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4367 tree->right = createLabel (localLabel, tree->right);
4368 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4370 return newNode (NULLOP, tree->left, tree->right);
4376 int wasnot = IS_NOT (tree->left);
4377 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4379 /* if the left is already a IFX */
4380 if (!IS_IFX (tree->left))
4381 tree->left = newNode (IFX, tree->left, NULL);
4385 tree->left->trueLabel = trueLabel;
4386 tree->left->falseLabel = falseLabel;
4390 tree->left->trueLabel = falseLabel;
4391 tree->left->falseLabel = trueLabel;
4398 tree->trueLabel = trueLabel;
4399 tree->falseLabel = falseLabel;
4406 /*-----------------------------------------------------------------*/
4407 /* createBlock - create expression tree for block */
4408 /*-----------------------------------------------------------------*/
4410 createBlock (symbol * decl, ast * body)
4414 /* if the block has nothing */
4418 ex = newNode (BLOCK, NULL, body);
4419 ex->values.sym = decl;
4421 ex->right = ex->right;///?????
4427 /*-----------------------------------------------------------------*/
4428 /* createLabel - creates the expression tree for labels */
4429 /*-----------------------------------------------------------------*/
4431 createLabel (symbol * label, ast * stmnt)
4434 char name[SDCC_NAME_MAX + 1];
4437 /* must create fresh symbol if the symbol name */
4438 /* exists in the symbol table, since there can */
4439 /* be a variable with the same name as the labl */
4440 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4441 (csym->level == label->level))
4442 label = newSymbol (label->name, label->level);
4444 /* change the name before putting it in add _ */
4445 SNPRINTF(name, sizeof(name), "%s", label->name);
4447 /* put the label in the LabelSymbol table */
4448 /* but first check if a label of the same */
4450 if ((csym = findSym (LabelTab, NULL, name)))
4451 werror (E_DUPLICATE_LABEL, label->name);
4453 addSym (LabelTab, label, name, label->level, 0, 0);
4457 label->key = labelKey++;
4458 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4464 /*-----------------------------------------------------------------*/
4465 /* createCase - generates the parsetree for a case statement */
4466 /*-----------------------------------------------------------------*/
4468 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4470 char caseLbl[SDCC_NAME_MAX + 1];
4474 /* if the switch statement does not exist */
4475 /* then case is out of context */
4478 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4482 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4483 /* if not a constant then error */
4484 if (!IS_LITERAL (caseVal->ftype))
4486 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4490 /* if not a integer than error */
4491 if (!IS_INTEGRAL (caseVal->ftype))
4493 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4497 /* find the end of the switch values chain */
4498 if (!(val = swStat->values.switchVals.swVals))
4499 swStat->values.switchVals.swVals = caseVal->opval.val;
4502 /* also order the cases according to value */
4504 int cVal = (int) floatFromVal (caseVal->opval.val);
4505 while (val && (int) floatFromVal (val) < cVal)
4511 /* if we reached the end then */
4514 pval->next = caseVal->opval.val;
4516 else if ((int) floatFromVal (val) == cVal)
4518 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4524 /* we found a value greater than */
4525 /* the current value we must add this */
4526 /* before the value */
4527 caseVal->opval.val->next = val;
4529 /* if this was the first in chain */
4530 if (swStat->values.switchVals.swVals == val)
4531 swStat->values.switchVals.swVals =
4534 pval->next = caseVal->opval.val;
4539 /* create the case label */
4540 SNPRINTF(caseLbl, sizeof(caseLbl),
4542 swStat->values.switchVals.swNum,
4543 (int) floatFromVal (caseVal->opval.val));
4545 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4550 /*-----------------------------------------------------------------*/
4551 /* createDefault - creates the parse tree for the default statement */
4552 /*-----------------------------------------------------------------*/
4554 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4556 char defLbl[SDCC_NAME_MAX + 1];
4558 /* if the switch statement does not exist */
4559 /* then case is out of context */
4562 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4566 if (swStat->values.switchVals.swDefault)
4568 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4573 /* turn on the default flag */
4574 swStat->values.switchVals.swDefault = 1;
4576 /* create the label */
4577 SNPRINTF (defLbl, sizeof(defLbl),
4578 "_default_%d", swStat->values.switchVals.swNum);
4579 return createLabel (newSymbol (defLbl, 0), stmnt);
4582 /*-----------------------------------------------------------------*/
4583 /* createIf - creates the parsetree for the if statement */
4584 /*-----------------------------------------------------------------*/
4586 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4588 static int Lblnum = 0;
4590 symbol *ifTrue, *ifFalse, *ifEnd;
4592 /* if neither exists */
4593 if (!elseBody && !ifBody) {
4594 // if there are no side effects (i++, j() etc)
4595 if (!hasSEFcalls(condAst)) {
4600 /* create the labels */
4601 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4602 ifFalse = newSymbol (buffer, NestLevel);
4603 /* if no else body then end == false */
4608 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4609 ifEnd = newSymbol (buffer, NestLevel);
4612 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4613 ifTrue = newSymbol (buffer, NestLevel);
4617 /* attach the ifTrue label to the top of it body */
4618 ifBody = createLabel (ifTrue, ifBody);
4619 /* attach a goto end to the ifBody if else is present */
4622 ifBody = newNode (NULLOP, ifBody,
4624 newAst_VALUE (symbolVal (ifEnd)),
4626 /* put the elseLabel on the else body */
4627 elseBody = createLabel (ifFalse, elseBody);
4628 /* out the end at the end of the body */
4629 elseBody = newNode (NULLOP,
4631 createLabel (ifEnd, NULL));
4635 ifBody = newNode (NULLOP, ifBody,
4636 createLabel (ifFalse, NULL));
4638 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4639 if (IS_IFX (condAst))
4642 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4644 return newNode (NULLOP, ifTree,
4645 newNode (NULLOP, ifBody, elseBody));
4649 /*-----------------------------------------------------------------*/
4650 /* createDo - creates parse tree for do */
4653 /* _docontinue_n: */
4654 /* condition_expression +-> trueLabel -> _dobody_n */
4656 /* +-> falseLabel-> _dobreak_n */
4658 /*-----------------------------------------------------------------*/
4660 createDo (symbol * trueLabel, symbol * continueLabel,
4661 symbol * falseLabel, ast * condAst, ast * doBody)
4666 /* if the body does not exist then it is simple */
4669 condAst = backPatchLabels (condAst, continueLabel, NULL);
4670 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4671 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4672 doTree->trueLabel = continueLabel;
4673 doTree->falseLabel = NULL;
4677 /* otherwise we have a body */
4678 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4680 /* attach the body label to the top */
4681 doBody = createLabel (trueLabel, doBody);
4682 /* attach the continue label to end of body */
4683 doBody = newNode (NULLOP, doBody,
4684 createLabel (continueLabel, NULL));
4686 /* now put the break label at the end */
4687 if (IS_IFX (condAst))
4690 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4692 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4694 /* putting it together */
4695 return newNode (NULLOP, doBody, doTree);
4698 /*-----------------------------------------------------------------*/
4699 /* createFor - creates parse tree for 'for' statement */
4702 /* condExpr +-> trueLabel -> _forbody_n */
4704 /* +-> falseLabel-> _forbreak_n */
4707 /* _forcontinue_n: */
4709 /* goto _forcond_n ; */
4711 /*-----------------------------------------------------------------*/
4713 createFor (symbol * trueLabel, symbol * continueLabel,
4714 symbol * falseLabel, symbol * condLabel,
4715 ast * initExpr, ast * condExpr, ast * loopExpr,
4720 /* if loopexpression not present then we can generate it */
4721 /* the same way as a while */
4723 return newNode (NULLOP, initExpr,
4724 createWhile (trueLabel, continueLabel,
4725 falseLabel, condExpr, forBody));
4726 /* vanilla for statement */
4727 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4729 if (condExpr && !IS_IFX (condExpr))
4730 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4733 /* attach condition label to condition */
4734 condExpr = createLabel (condLabel, condExpr);
4736 /* attach body label to body */
4737 forBody = createLabel (trueLabel, forBody);
4739 /* attach continue to forLoop expression & attach */
4740 /* goto the forcond @ and of loopExpression */
4741 loopExpr = createLabel (continueLabel,
4745 newAst_VALUE (symbolVal (condLabel)),
4747 /* now start putting them together */
4748 forTree = newNode (NULLOP, initExpr, condExpr);
4749 forTree = newNode (NULLOP, forTree, forBody);
4750 forTree = newNode (NULLOP, forTree, loopExpr);
4751 /* finally add the break label */
4752 forTree = newNode (NULLOP, forTree,
4753 createLabel (falseLabel, NULL));
4757 /*-----------------------------------------------------------------*/
4758 /* createWhile - creates parse tree for while statement */
4759 /* the while statement will be created as follows */
4761 /* _while_continue_n: */
4762 /* condition_expression +-> trueLabel -> _while_boby_n */
4764 /* +-> falseLabel -> _while_break_n */
4765 /* _while_body_n: */
4767 /* goto _while_continue_n */
4768 /* _while_break_n: */
4769 /*-----------------------------------------------------------------*/
4771 createWhile (symbol * trueLabel, symbol * continueLabel,
4772 symbol * falseLabel, ast * condExpr, ast * whileBody)
4776 /* put the continue label */
4777 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4778 condExpr = createLabel (continueLabel, condExpr);
4779 condExpr->lineno = 0;
4781 /* put the body label in front of the body */
4782 whileBody = createLabel (trueLabel, whileBody);
4783 whileBody->lineno = 0;
4784 /* put a jump to continue at the end of the body */
4785 /* and put break label at the end of the body */
4786 whileBody = newNode (NULLOP,
4789 newAst_VALUE (symbolVal (continueLabel)),
4790 createLabel (falseLabel, NULL)));
4792 /* put it all together */
4793 if (IS_IFX (condExpr))
4794 whileTree = condExpr;
4797 whileTree = newNode (IFX, condExpr, NULL);
4798 /* put the true & false labels in place */
4799 whileTree->trueLabel = trueLabel;
4800 whileTree->falseLabel = falseLabel;
4803 return newNode (NULLOP, whileTree, whileBody);
4806 /*-----------------------------------------------------------------*/
4807 /* optimizeGetHbit - get highest order bit of the expression */
4808 /*-----------------------------------------------------------------*/
4810 optimizeGetHbit (ast * tree)
4813 /* if this is not a bit and */
4814 if (!IS_BITAND (tree))
4817 /* will look for tree of the form
4818 ( expr >> ((sizeof expr) -1) ) & 1 */
4819 if (!IS_AST_LIT_VALUE (tree->right))
4822 if (AST_LIT_VALUE (tree->right) != 1)
4825 if (!IS_RIGHT_OP (tree->left))
4828 if (!IS_AST_LIT_VALUE (tree->left->right))
4831 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4832 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4835 /* make sure the port supports GETHBIT */
4836 if (port->hasExtBitOp
4837 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4840 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4844 /*-----------------------------------------------------------------*/
4845 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4846 /*-----------------------------------------------------------------*/
4848 optimizeRRCRLC (ast * root)
4850 /* will look for trees of the form
4851 (?expr << 1) | (?expr >> 7) or
4852 (?expr >> 7) | (?expr << 1) will make that
4853 into a RLC : operation ..
4855 (?expr >> 1) | (?expr << 7) or
4856 (?expr << 7) | (?expr >> 1) will make that
4857 into a RRC operation
4858 note : by 7 I mean (number of bits required to hold the
4860 /* if the root operations is not a | operation the not */
4861 if (!IS_BITOR (root))
4864 /* I have to think of a better way to match patterns this sucks */
4865 /* that aside let start looking for the first case : I use a the
4866 negative check a lot to improve the efficiency */
4867 /* (?expr << 1) | (?expr >> 7) */
4868 if (IS_LEFT_OP (root->left) &&
4869 IS_RIGHT_OP (root->right))
4872 if (!SPEC_USIGN (TETYPE (root->left->left)))
4875 if (!IS_AST_LIT_VALUE (root->left->right) ||
4876 !IS_AST_LIT_VALUE (root->right->right))
4879 /* make sure it is the same expression */
4880 if (!isAstEqual (root->left->left,
4884 if (AST_LIT_VALUE (root->left->right) != 1)
4887 if (AST_LIT_VALUE (root->right->right) !=
4888 (getSize (TTYPE (root->left->left)) * 8 - 1))
4891 /* make sure the port supports RLC */
4892 if (port->hasExtBitOp
4893 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4896 /* whew got the first case : create the AST */
4897 return newNode (RLC, root->left->left, NULL);
4901 /* check for second case */
4902 /* (?expr >> 7) | (?expr << 1) */
4903 if (IS_LEFT_OP (root->right) &&
4904 IS_RIGHT_OP (root->left))
4907 if (!SPEC_USIGN (TETYPE (root->left->left)))
4910 if (!IS_AST_LIT_VALUE (root->left->right) ||
4911 !IS_AST_LIT_VALUE (root->right->right))
4914 /* make sure it is the same symbol */
4915 if (!isAstEqual (root->left->left,
4919 if (AST_LIT_VALUE (root->right->right) != 1)
4922 if (AST_LIT_VALUE (root->left->right) !=
4923 (getSize (TTYPE (root->left->left)) * 8 - 1))
4926 /* make sure the port supports RLC */
4927 if (port->hasExtBitOp
4928 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4931 /* whew got the first case : create the AST */
4932 return newNode (RLC, root->left->left, NULL);
4937 /* third case for RRC */
4938 /* (?symbol >> 1) | (?symbol << 7) */
4939 if (IS_LEFT_OP (root->right) &&
4940 IS_RIGHT_OP (root->left))
4943 if (!SPEC_USIGN (TETYPE (root->left->left)))
4946 if (!IS_AST_LIT_VALUE (root->left->right) ||
4947 !IS_AST_LIT_VALUE (root->right->right))
4950 /* make sure it is the same symbol */
4951 if (!isAstEqual (root->left->left,
4955 if (AST_LIT_VALUE (root->left->right) != 1)
4958 if (AST_LIT_VALUE (root->right->right) !=
4959 (getSize (TTYPE (root->left->left)) * 8 - 1))
4962 /* make sure the port supports RRC */
4963 if (port->hasExtBitOp
4964 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4967 /* whew got the first case : create the AST */
4968 return newNode (RRC, root->left->left, NULL);
4972 /* fourth and last case for now */
4973 /* (?symbol << 7) | (?symbol >> 1) */
4974 if (IS_RIGHT_OP (root->right) &&
4975 IS_LEFT_OP (root->left))
4978 if (!SPEC_USIGN (TETYPE (root->left->left)))
4981 if (!IS_AST_LIT_VALUE (root->left->right) ||
4982 !IS_AST_LIT_VALUE (root->right->right))
4985 /* make sure it is the same symbol */
4986 if (!isAstEqual (root->left->left,
4990 if (AST_LIT_VALUE (root->right->right) != 1)
4993 if (AST_LIT_VALUE (root->left->right) !=
4994 (getSize (TTYPE (root->left->left)) * 8 - 1))
4997 /* make sure the port supports RRC */
4998 if (port->hasExtBitOp
4999 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5002 /* whew got the first case : create the AST */
5003 return newNode (RRC, root->left->left, NULL);
5007 /* not found return root */
5011 /*-----------------------------------------------------------------*/
5012 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5013 /*-----------------------------------------------------------------*/
5015 optimizeSWAP (ast * root)
5017 /* will look for trees of the form
5018 (?expr << 4) | (?expr >> 4) or
5019 (?expr >> 4) | (?expr << 4) will make that
5020 into a SWAP : operation ..
5021 note : by 4 I mean (number of bits required to hold the
5023 /* if the root operations is not a | operation the not */
5024 if (!IS_BITOR (root))
5027 /* (?expr << 4) | (?expr >> 4) */
5028 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5029 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5032 if (!SPEC_USIGN (TETYPE (root->left->left)))
5035 if (!IS_AST_LIT_VALUE (root->left->right) ||
5036 !IS_AST_LIT_VALUE (root->right->right))
5039 /* make sure it is the same expression */
5040 if (!isAstEqual (root->left->left,
5044 if (AST_LIT_VALUE (root->left->right) !=
5045 (getSize (TTYPE (root->left->left)) * 4))
5048 if (AST_LIT_VALUE (root->right->right) !=
5049 (getSize (TTYPE (root->left->left)) * 4))
5052 /* make sure the port supports SWAP */
5053 if (port->hasExtBitOp
5054 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5057 /* found it : create the AST */
5058 return newNode (SWAP, root->left->left, NULL);
5062 /* not found return root */
5066 /*-----------------------------------------------------------------*/
5067 /* optimizeCompare - otimizes compares for bit variables */
5068 /*-----------------------------------------------------------------*/
5070 optimizeCompare (ast * root)
5072 ast *optExpr = NULL;
5075 unsigned int litValue;
5077 /* if nothing then return nothing */
5081 /* if not a compare op then do leaves */
5082 if (!IS_COMPARE_OP (root))
5084 root->left = optimizeCompare (root->left);
5085 root->right = optimizeCompare (root->right);
5089 /* if left & right are the same then depending
5090 of the operation do */
5091 if (isAstEqual (root->left, root->right))
5093 switch (root->opval.op)
5098 optExpr = newAst_VALUE (constVal ("0"));
5103 optExpr = newAst_VALUE (constVal ("1"));
5107 return decorateType (optExpr, RESULT_TYPE_NONE);
5110 vleft = (root->left->type == EX_VALUE ?
5111 root->left->opval.val : NULL);
5113 vright = (root->right->type == EX_VALUE ?
5114 root->right->opval.val : NULL);
5116 /* if left is a BITVAR in BITSPACE */
5117 /* and right is a LITERAL then opt- */
5118 /* imize else do nothing */
5119 if (vleft && vright &&
5120 IS_BITVAR (vleft->etype) &&
5121 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5122 IS_LITERAL (vright->etype))
5125 /* if right side > 1 then comparison may never succeed */
5126 if ((litValue = (int) floatFromVal (vright)) > 1)
5128 werror (W_BAD_COMPARE);
5134 switch (root->opval.op)
5136 case '>': /* bit value greater than 1 cannot be */
5137 werror (W_BAD_COMPARE);
5141 case '<': /* bit value < 1 means 0 */
5143 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5146 case LE_OP: /* bit value <= 1 means no check */
5147 optExpr = newAst_VALUE (vright);
5150 case GE_OP: /* bit value >= 1 means only check for = */
5152 optExpr = newAst_VALUE (vleft);
5157 { /* literal is zero */
5158 switch (root->opval.op)
5160 case '<': /* bit value < 0 cannot be */
5161 werror (W_BAD_COMPARE);
5165 case '>': /* bit value > 0 means 1 */
5167 optExpr = newAst_VALUE (vleft);
5170 case LE_OP: /* bit value <= 0 means no check */
5171 case GE_OP: /* bit value >= 0 means no check */
5172 werror (W_BAD_COMPARE);
5176 case EQ_OP: /* bit == 0 means ! of bit */
5177 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5181 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5182 } /* end-of-if of BITVAR */
5187 /*-----------------------------------------------------------------*/
5188 /* addSymToBlock : adds the symbol to the first block we find */
5189 /*-----------------------------------------------------------------*/
5191 addSymToBlock (symbol * sym, ast * tree)
5193 /* reached end of tree or a leaf */
5194 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5198 if (IS_AST_OP (tree) &&
5199 tree->opval.op == BLOCK)
5202 symbol *lsym = copySymbol (sym);
5204 lsym->next = AST_VALUES (tree, sym);
5205 AST_VALUES (tree, sym) = lsym;
5209 addSymToBlock (sym, tree->left);
5210 addSymToBlock (sym, tree->right);
5213 /*-----------------------------------------------------------------*/
5214 /* processRegParms - do processing for register parameters */
5215 /*-----------------------------------------------------------------*/
5217 processRegParms (value * args, ast * body)
5221 if (IS_REGPARM (args->etype))
5222 addSymToBlock (args->sym, body);
5227 /*-----------------------------------------------------------------*/
5228 /* resetParmKey - resets the operandkeys for the symbols */
5229 /*-----------------------------------------------------------------*/
5230 DEFSETFUNC (resetParmKey)
5241 /*-----------------------------------------------------------------*/
5242 /* createFunction - This is the key node that calls the iCode for */
5243 /* generating the code for a function. Note code */
5244 /* is generated function by function, later when */
5245 /* add inter-procedural analysis this will change */
5246 /*-----------------------------------------------------------------*/
5248 createFunction (symbol * name, ast * body)
5254 iCode *piCode = NULL;
5256 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5257 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5259 /* if check function return 0 then some problem */
5260 if (checkFunction (name, NULL) == 0)
5263 /* create a dummy block if none exists */
5265 body = newNode (BLOCK, NULL, NULL);
5269 /* check if the function name already in the symbol table */
5270 if ((csym = findSym (SymbolTab, NULL, name->name)))
5273 /* special case for compiler defined functions
5274 we need to add the name to the publics list : this
5275 actually means we are now compiling the compiler
5279 addSet (&publics, name);
5285 allocVariables (name);
5287 name->lastLine = mylineno;
5290 /* set the stack pointer */
5291 /* PENDING: check this for the mcs51 */
5292 stackPtr = -port->stack.direction * port->stack.call_overhead;
5293 if (IFFUNC_ISISR (name->type))
5294 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5295 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5296 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5298 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5300 fetype = getSpec (name->type); /* get the specifier for the function */
5301 /* if this is a reentrant function then */
5302 if (IFFUNC_ISREENT (name->type))
5305 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5307 /* do processing for parameters that are passed in registers */
5308 processRegParms (FUNC_ARGS(name->type), body);
5310 /* set the stack pointer */
5314 /* allocate & autoinit the block variables */
5315 processBlockVars (body, &stack, ALLOCATE);
5317 /* save the stack information */
5318 if (options.useXstack)
5319 name->xstack = SPEC_STAK (fetype) = stack;
5321 name->stack = SPEC_STAK (fetype) = stack;
5323 /* name needs to be mangled */
5324 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5326 body = resolveSymbols (body); /* resolve the symbols */
5327 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5330 ex = newAst_VALUE (symbolVal (name)); /* create name */
5331 ex = newNode (FUNCTION, ex, body);
5332 ex->values.args = FUNC_ARGS(name->type);
5334 if (options.dump_tree) PA(ex);
5337 werror (E_FUNC_NO_CODE, name->name);
5341 /* create the node & generate intermediate code */
5343 codeOutFile = code->oFile;
5344 piCode = iCodeFromAst (ex);
5348 werror (E_FUNC_NO_CODE, name->name);
5352 eBBlockFromiCode (piCode);
5354 /* if there are any statics then do them */
5357 GcurMemmap = statsg;
5358 codeOutFile = statsg->oFile;
5359 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5365 /* dealloc the block variables */
5366 processBlockVars (body, &stack, DEALLOCATE);
5367 outputDebugStackSymbols();
5368 /* deallocate paramaters */
5369 deallocParms (FUNC_ARGS(name->type));
5371 if (IFFUNC_ISREENT (name->type))
5374 /* we are done freeup memory & cleanup */
5376 if (port->reset_labelKey) labelKey = 1;
5378 FUNC_HASBODY(name->type) = 1;
5379 addSet (&operKeyReset, name);
5380 applyToSet (operKeyReset, resetParmKey);
5385 cleanUpLevel (LabelTab, 0);
5386 cleanUpBlock (StructTab, 1);
5387 cleanUpBlock (TypedefTab, 1);
5389 xstack->syms = NULL;
5390 istack->syms = NULL;
5395 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5396 /*-----------------------------------------------------------------*/
5397 /* ast_print : prints the ast (for debugging purposes) */
5398 /*-----------------------------------------------------------------*/
5400 void ast_print (ast * tree, FILE *outfile, int indent)
5405 /* can print only decorated trees */
5406 if (!tree->decorated) return;
5408 /* if any child is an error | this one is an error do nothing */
5409 if (tree->isError ||
5410 (tree->left && tree->left->isError) ||
5411 (tree->right && tree->right->isError)) {
5412 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5416 /* print the line */
5417 /* if not block & function */
5418 if (tree->type == EX_OP &&
5419 (tree->opval.op != FUNCTION &&
5420 tree->opval.op != BLOCK &&
5421 tree->opval.op != NULLOP)) {
5424 if (tree->opval.op == FUNCTION) {
5426 value *args=FUNC_ARGS(tree->left->opval.val->type);
5427 fprintf(outfile,"FUNCTION (%s=%p) type (",
5428 tree->left->opval.val->name, tree);
5429 printTypeChain (tree->left->opval.val->type->next,outfile);
5430 fprintf(outfile,") args (");
5433 fprintf (outfile, ", ");
5435 printTypeChain (args ? args->type : NULL, outfile);
5437 args= args ? args->next : NULL;
5439 fprintf(outfile,")\n");
5440 ast_print(tree->left,outfile,indent);
5441 ast_print(tree->right,outfile,indent);
5444 if (tree->opval.op == BLOCK) {
5445 symbol *decls = tree->values.sym;
5446 INDENT(indent,outfile);
5447 fprintf(outfile,"{\n");
5449 INDENT(indent+2,outfile);
5450 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5451 decls->name, decls);
5452 printTypeChain(decls->type,outfile);
5453 fprintf(outfile,")\n");
5455 decls = decls->next;
5457 ast_print(tree->right,outfile,indent+2);
5458 INDENT(indent,outfile);
5459 fprintf(outfile,"}\n");
5462 if (tree->opval.op == NULLOP) {
5463 ast_print(tree->left,outfile,indent);
5464 ast_print(tree->right,outfile,indent);
5467 INDENT(indent,outfile);
5469 /*------------------------------------------------------------------*/
5470 /*----------------------------*/
5471 /* leaf has been reached */
5472 /*----------------------------*/
5473 /* if this is of type value */
5474 /* just get the type */
5475 if (tree->type == EX_VALUE) {
5477 if (IS_LITERAL (tree->opval.val->etype)) {
5478 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5479 if (SPEC_USIGN (tree->opval.val->etype))
5480 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5482 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5483 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5484 floatFromVal(tree->opval.val));
5485 } else if (tree->opval.val->sym) {
5486 /* if the undefined flag is set then give error message */
5487 if (tree->opval.val->sym->undefined) {
5488 fprintf(outfile,"UNDEFINED SYMBOL ");
5490 fprintf(outfile,"SYMBOL ");
5492 fprintf(outfile,"(%s=%p)",
5493 tree->opval.val->sym->name,tree);
5496 fprintf(outfile," type (");
5497 printTypeChain(tree->ftype,outfile);
5498 fprintf(outfile,")\n");
5500 fprintf(outfile,"\n");
5505 /* if type link for the case of cast */
5506 if (tree->type == EX_LINK) {
5507 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5508 printTypeChain(tree->opval.lnk,outfile);
5509 fprintf(outfile,")\n");
5514 /* depending on type of operator do */
5516 switch (tree->opval.op) {
5517 /*------------------------------------------------------------------*/
5518 /*----------------------------*/
5520 /*----------------------------*/
5522 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5523 printTypeChain(tree->ftype,outfile);
5524 fprintf(outfile,")\n");
5525 ast_print(tree->left,outfile,indent+2);
5526 ast_print(tree->right,outfile,indent+2);
5529 /*------------------------------------------------------------------*/
5530 /*----------------------------*/
5532 /*----------------------------*/
5534 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5535 printTypeChain(tree->ftype,outfile);
5536 fprintf(outfile,")\n");
5537 ast_print(tree->left,outfile,indent+2);
5538 ast_print(tree->right,outfile,indent+2);
5541 /*------------------------------------------------------------------*/
5542 /*----------------------------*/
5543 /* struct/union pointer */
5544 /*----------------------------*/
5546 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5547 printTypeChain(tree->ftype,outfile);
5548 fprintf(outfile,")\n");
5549 ast_print(tree->left,outfile,indent+2);
5550 ast_print(tree->right,outfile,indent+2);
5553 /*------------------------------------------------------------------*/
5554 /*----------------------------*/
5555 /* ++/-- operation */
5556 /*----------------------------*/
5559 fprintf(outfile,"post-");
5561 fprintf(outfile,"pre-");
5562 fprintf(outfile,"INC_OP (%p) type (",tree);
5563 printTypeChain(tree->ftype,outfile);
5564 fprintf(outfile,")\n");
5565 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5566 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5571 fprintf(outfile,"post-");
5573 fprintf(outfile,"pre-");
5574 fprintf(outfile,"DEC_OP (%p) type (",tree);
5575 printTypeChain(tree->ftype,outfile);
5576 fprintf(outfile,")\n");
5577 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5578 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5581 /*------------------------------------------------------------------*/
5582 /*----------------------------*/
5584 /*----------------------------*/
5587 fprintf(outfile,"& (%p) type (",tree);
5588 printTypeChain(tree->ftype,outfile);
5589 fprintf(outfile,")\n");
5590 ast_print(tree->left,outfile,indent+2);
5591 ast_print(tree->right,outfile,indent+2);
5593 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5594 printTypeChain(tree->ftype,outfile);
5595 fprintf(outfile,")\n");
5596 ast_print(tree->left,outfile,indent+2);
5597 ast_print(tree->right,outfile,indent+2);
5600 /*----------------------------*/
5602 /*----------------------------*/
5604 fprintf(outfile,"OR (%p) type (",tree);
5605 printTypeChain(tree->ftype,outfile);
5606 fprintf(outfile,")\n");
5607 ast_print(tree->left,outfile,indent+2);
5608 ast_print(tree->right,outfile,indent+2);
5610 /*------------------------------------------------------------------*/
5611 /*----------------------------*/
5613 /*----------------------------*/
5615 fprintf(outfile,"XOR (%p) type (",tree);
5616 printTypeChain(tree->ftype,outfile);
5617 fprintf(outfile,")\n");
5618 ast_print(tree->left,outfile,indent+2);
5619 ast_print(tree->right,outfile,indent+2);
5622 /*------------------------------------------------------------------*/
5623 /*----------------------------*/
5625 /*----------------------------*/
5627 fprintf(outfile,"DIV (%p) type (",tree);
5628 printTypeChain(tree->ftype,outfile);
5629 fprintf(outfile,")\n");
5630 ast_print(tree->left,outfile,indent+2);
5631 ast_print(tree->right,outfile,indent+2);
5633 /*------------------------------------------------------------------*/
5634 /*----------------------------*/
5636 /*----------------------------*/
5638 fprintf(outfile,"MOD (%p) type (",tree);
5639 printTypeChain(tree->ftype,outfile);
5640 fprintf(outfile,")\n");
5641 ast_print(tree->left,outfile,indent+2);
5642 ast_print(tree->right,outfile,indent+2);
5645 /*------------------------------------------------------------------*/
5646 /*----------------------------*/
5647 /* address dereference */
5648 /*----------------------------*/
5649 case '*': /* can be unary : if right is null then unary operation */
5651 fprintf(outfile,"DEREF (%p) type (",tree);
5652 printTypeChain(tree->ftype,outfile);
5653 fprintf(outfile,")\n");
5654 ast_print(tree->left,outfile,indent+2);
5657 /*------------------------------------------------------------------*/
5658 /*----------------------------*/
5659 /* multiplication */
5660 /*----------------------------*/
5661 fprintf(outfile,"MULT (%p) type (",tree);
5662 printTypeChain(tree->ftype,outfile);
5663 fprintf(outfile,")\n");
5664 ast_print(tree->left,outfile,indent+2);
5665 ast_print(tree->right,outfile,indent+2);
5669 /*------------------------------------------------------------------*/
5670 /*----------------------------*/
5671 /* unary '+' operator */
5672 /*----------------------------*/
5676 fprintf(outfile,"UPLUS (%p) type (",tree);
5677 printTypeChain(tree->ftype,outfile);
5678 fprintf(outfile,")\n");
5679 ast_print(tree->left,outfile,indent+2);
5681 /*------------------------------------------------------------------*/
5682 /*----------------------------*/
5684 /*----------------------------*/
5685 fprintf(outfile,"ADD (%p) type (",tree);
5686 printTypeChain(tree->ftype,outfile);
5687 fprintf(outfile,")\n");
5688 ast_print(tree->left,outfile,indent+2);
5689 ast_print(tree->right,outfile,indent+2);
5692 /*------------------------------------------------------------------*/
5693 /*----------------------------*/
5695 /*----------------------------*/
5696 case '-': /* can be unary */
5698 fprintf(outfile,"UMINUS (%p) type (",tree);
5699 printTypeChain(tree->ftype,outfile);
5700 fprintf(outfile,")\n");
5701 ast_print(tree->left,outfile,indent+2);
5703 /*------------------------------------------------------------------*/
5704 /*----------------------------*/
5706 /*----------------------------*/
5707 fprintf(outfile,"SUB (%p) type (",tree);
5708 printTypeChain(tree->ftype,outfile);
5709 fprintf(outfile,")\n");
5710 ast_print(tree->left,outfile,indent+2);
5711 ast_print(tree->right,outfile,indent+2);
5714 /*------------------------------------------------------------------*/
5715 /*----------------------------*/
5717 /*----------------------------*/
5719 fprintf(outfile,"COMPL (%p) type (",tree);
5720 printTypeChain(tree->ftype,outfile);
5721 fprintf(outfile,")\n");
5722 ast_print(tree->left,outfile,indent+2);
5724 /*------------------------------------------------------------------*/
5725 /*----------------------------*/
5727 /*----------------------------*/
5729 fprintf(outfile,"NOT (%p) type (",tree);
5730 printTypeChain(tree->ftype,outfile);
5731 fprintf(outfile,")\n");
5732 ast_print(tree->left,outfile,indent+2);
5734 /*------------------------------------------------------------------*/
5735 /*----------------------------*/
5737 /*----------------------------*/
5739 fprintf(outfile,"RRC (%p) type (",tree);
5740 printTypeChain(tree->ftype,outfile);
5741 fprintf(outfile,")\n");
5742 ast_print(tree->left,outfile,indent+2);
5746 fprintf(outfile,"RLC (%p) type (",tree);
5747 printTypeChain(tree->ftype,outfile);
5748 fprintf(outfile,")\n");
5749 ast_print(tree->left,outfile,indent+2);
5752 fprintf(outfile,"SWAP (%p) type (",tree);
5753 printTypeChain(tree->ftype,outfile);
5754 fprintf(outfile,")\n");
5755 ast_print(tree->left,outfile,indent+2);
5758 fprintf(outfile,"GETHBIT (%p) type (",tree);
5759 printTypeChain(tree->ftype,outfile);
5760 fprintf(outfile,")\n");
5761 ast_print(tree->left,outfile,indent+2);
5764 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5765 printTypeChain(tree->ftype,outfile);
5766 fprintf(outfile,")\n");
5767 ast_print(tree->left,outfile,indent+2);
5768 ast_print(tree->right,outfile,indent+2);
5771 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5772 printTypeChain(tree->ftype,outfile);
5773 fprintf(outfile,")\n");
5774 ast_print(tree->left,outfile,indent+2);
5775 ast_print(tree->right,outfile,indent+2);
5777 /*------------------------------------------------------------------*/
5778 /*----------------------------*/
5780 /*----------------------------*/
5781 case CAST: /* change the type */
5782 fprintf(outfile,"CAST (%p) from type (",tree);
5783 printTypeChain(tree->right->ftype,outfile);
5784 fprintf(outfile,") to type (");
5785 printTypeChain(tree->ftype,outfile);
5786 fprintf(outfile,")\n");
5787 ast_print(tree->right,outfile,indent+2);
5791 fprintf(outfile,"ANDAND (%p) type (",tree);
5792 printTypeChain(tree->ftype,outfile);
5793 fprintf(outfile,")\n");
5794 ast_print(tree->left,outfile,indent+2);
5795 ast_print(tree->right,outfile,indent+2);
5798 fprintf(outfile,"OROR (%p) type (",tree);
5799 printTypeChain(tree->ftype,outfile);
5800 fprintf(outfile,")\n");
5801 ast_print(tree->left,outfile,indent+2);
5802 ast_print(tree->right,outfile,indent+2);
5805 /*------------------------------------------------------------------*/
5806 /*----------------------------*/
5807 /* comparison operators */
5808 /*----------------------------*/
5810 fprintf(outfile,"GT(>) (%p) type (",tree);
5811 printTypeChain(tree->ftype,outfile);
5812 fprintf(outfile,")\n");
5813 ast_print(tree->left,outfile,indent+2);
5814 ast_print(tree->right,outfile,indent+2);
5817 fprintf(outfile,"LT(<) (%p) type (",tree);
5818 printTypeChain(tree->ftype,outfile);
5819 fprintf(outfile,")\n");
5820 ast_print(tree->left,outfile,indent+2);
5821 ast_print(tree->right,outfile,indent+2);
5824 fprintf(outfile,"LE(<=) (%p) type (",tree);
5825 printTypeChain(tree->ftype,outfile);
5826 fprintf(outfile,")\n");
5827 ast_print(tree->left,outfile,indent+2);
5828 ast_print(tree->right,outfile,indent+2);
5831 fprintf(outfile,"GE(>=) (%p) type (",tree);
5832 printTypeChain(tree->ftype,outfile);
5833 fprintf(outfile,")\n");
5834 ast_print(tree->left,outfile,indent+2);
5835 ast_print(tree->right,outfile,indent+2);
5838 fprintf(outfile,"EQ(==) (%p) type (",tree);
5839 printTypeChain(tree->ftype,outfile);
5840 fprintf(outfile,")\n");
5841 ast_print(tree->left,outfile,indent+2);
5842 ast_print(tree->right,outfile,indent+2);
5845 fprintf(outfile,"NE(!=) (%p) type (",tree);
5846 printTypeChain(tree->ftype,outfile);
5847 fprintf(outfile,")\n");
5848 ast_print(tree->left,outfile,indent+2);
5849 ast_print(tree->right,outfile,indent+2);
5850 /*------------------------------------------------------------------*/
5851 /*----------------------------*/
5853 /*----------------------------*/
5854 case SIZEOF: /* evaluate wihout code generation */
5855 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5858 /*------------------------------------------------------------------*/
5859 /*----------------------------*/
5860 /* conditional operator '?' */
5861 /*----------------------------*/
5863 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5864 printTypeChain(tree->ftype,outfile);
5865 fprintf(outfile,")\n");
5866 ast_print(tree->left,outfile,indent+2);
5867 ast_print(tree->right,outfile,indent+2);
5871 fprintf(outfile,"COLON(:) (%p) type (",tree);
5872 printTypeChain(tree->ftype,outfile);
5873 fprintf(outfile,")\n");
5874 ast_print(tree->left,outfile,indent+2);
5875 ast_print(tree->right,outfile,indent+2);
5878 /*------------------------------------------------------------------*/
5879 /*----------------------------*/
5880 /* assignment operators */
5881 /*----------------------------*/
5883 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5884 printTypeChain(tree->ftype,outfile);
5885 fprintf(outfile,")\n");
5886 ast_print(tree->left,outfile,indent+2);
5887 ast_print(tree->right,outfile,indent+2);
5890 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5891 printTypeChain(tree->ftype,outfile);
5892 fprintf(outfile,")\n");
5893 ast_print(tree->left,outfile,indent+2);
5894 ast_print(tree->right,outfile,indent+2);
5897 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5898 printTypeChain(tree->ftype,outfile);
5899 fprintf(outfile,")\n");
5900 ast_print(tree->left,outfile,indent+2);
5901 ast_print(tree->right,outfile,indent+2);
5904 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5905 printTypeChain(tree->ftype,outfile);
5906 fprintf(outfile,")\n");
5907 ast_print(tree->left,outfile,indent+2);
5908 ast_print(tree->right,outfile,indent+2);
5911 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5912 printTypeChain(tree->ftype,outfile);
5913 fprintf(outfile,")\n");
5914 ast_print(tree->left,outfile,indent+2);
5915 ast_print(tree->right,outfile,indent+2);
5918 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5919 printTypeChain(tree->ftype,outfile);
5920 fprintf(outfile,")\n");
5921 ast_print(tree->left,outfile,indent+2);
5922 ast_print(tree->right,outfile,indent+2);
5925 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5926 printTypeChain(tree->ftype,outfile);
5927 fprintf(outfile,")\n");
5928 ast_print(tree->left,outfile,indent+2);
5929 ast_print(tree->right,outfile,indent+2);
5931 /*------------------------------------------------------------------*/
5932 /*----------------------------*/
5934 /*----------------------------*/
5936 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5937 printTypeChain(tree->ftype,outfile);
5938 fprintf(outfile,")\n");
5939 ast_print(tree->left,outfile,indent+2);
5940 ast_print(tree->right,outfile,indent+2);
5942 /*------------------------------------------------------------------*/
5943 /*----------------------------*/
5945 /*----------------------------*/
5947 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5948 printTypeChain(tree->ftype,outfile);
5949 fprintf(outfile,")\n");
5950 ast_print(tree->left,outfile,indent+2);
5951 ast_print(tree->right,outfile,indent+2);
5953 /*------------------------------------------------------------------*/
5954 /*----------------------------*/
5955 /* straight assignemnt */
5956 /*----------------------------*/
5958 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5959 printTypeChain(tree->ftype,outfile);
5960 fprintf(outfile,")\n");
5961 ast_print(tree->left,outfile,indent+2);
5962 ast_print(tree->right,outfile,indent+2);
5964 /*------------------------------------------------------------------*/
5965 /*----------------------------*/
5966 /* comma operator */
5967 /*----------------------------*/
5969 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5970 printTypeChain(tree->ftype,outfile);
5971 fprintf(outfile,")\n");
5972 ast_print(tree->left,outfile,indent+2);
5973 ast_print(tree->right,outfile,indent+2);
5975 /*------------------------------------------------------------------*/
5976 /*----------------------------*/
5978 /*----------------------------*/
5981 fprintf(outfile,"CALL (%p) type (",tree);
5982 printTypeChain(tree->ftype,outfile);
5983 fprintf(outfile,")\n");
5984 ast_print(tree->left,outfile,indent+2);
5985 ast_print(tree->right,outfile,indent+2);
5988 fprintf(outfile,"PARMS\n");
5989 ast_print(tree->left,outfile,indent+2);
5990 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5991 ast_print(tree->right,outfile,indent+2);
5994 /*------------------------------------------------------------------*/
5995 /*----------------------------*/
5996 /* return statement */
5997 /*----------------------------*/
5999 fprintf(outfile,"RETURN (%p) type (",tree);
6001 printTypeChain(tree->right->ftype,outfile);
6003 fprintf(outfile,")\n");
6004 ast_print(tree->right,outfile,indent+2);
6006 /*------------------------------------------------------------------*/
6007 /*----------------------------*/
6008 /* label statement */
6009 /*----------------------------*/
6011 fprintf(outfile,"LABEL (%p)\n",tree);
6012 ast_print(tree->left,outfile,indent+2);
6013 ast_print(tree->right,outfile,indent);
6015 /*------------------------------------------------------------------*/
6016 /*----------------------------*/
6017 /* switch statement */
6018 /*----------------------------*/
6022 fprintf(outfile,"SWITCH (%p) ",tree);
6023 ast_print(tree->left,outfile,0);
6024 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6025 INDENT(indent+2,outfile);
6026 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6027 (int) floatFromVal(val),
6028 tree->values.switchVals.swNum,
6029 (int) floatFromVal(val));
6031 ast_print(tree->right,outfile,indent);
6034 /*------------------------------------------------------------------*/
6035 /*----------------------------*/
6037 /*----------------------------*/
6039 fprintf(outfile,"IF (%p) \n",tree);
6040 ast_print(tree->left,outfile,indent+2);
6041 if (tree->trueLabel) {
6042 INDENT(indent+2,outfile);
6043 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6045 if (tree->falseLabel) {
6046 INDENT(indent+2,outfile);
6047 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6049 ast_print(tree->right,outfile,indent+2);
6051 /*----------------------------*/
6052 /* goto Statement */
6053 /*----------------------------*/
6055 fprintf(outfile,"GOTO (%p) \n",tree);
6056 ast_print(tree->left,outfile,indent+2);
6057 fprintf(outfile,"\n");
6059 /*------------------------------------------------------------------*/
6060 /*----------------------------*/
6062 /*----------------------------*/
6064 fprintf(outfile,"FOR (%p) \n",tree);
6065 if (AST_FOR( tree, initExpr)) {
6066 INDENT(indent+2,outfile);
6067 fprintf(outfile,"INIT EXPR ");
6068 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6070 if (AST_FOR( tree, condExpr)) {
6071 INDENT(indent+2,outfile);
6072 fprintf(outfile,"COND EXPR ");
6073 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6075 if (AST_FOR( tree, loopExpr)) {
6076 INDENT(indent+2,outfile);
6077 fprintf(outfile,"LOOP EXPR ");
6078 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6080 fprintf(outfile,"FOR LOOP BODY \n");
6081 ast_print(tree->left,outfile,indent+2);
6084 fprintf(outfile,"CRITICAL (%p) \n",tree);
6085 ast_print(tree->left,outfile,indent+2);
6093 ast_print(t,stdout,0);
6098 /*-----------------------------------------------------------------*/
6099 /* astErrors : returns non-zero if errors present in tree */
6100 /*-----------------------------------------------------------------*/
6101 int astErrors(ast *t)
6110 if (t->type == EX_VALUE
6111 && t->opval.val->sym
6112 && t->opval.val->sym->undefined)
6115 errors += astErrors(t->left);
6116 errors += astErrors(t->right);