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)
636 /* The various functions expect the parameter tree to be right heavy. */
637 /* Rotate the tree to be left heavy so that after reversal it is */
638 /* right heavy again. */
639 while ((ttree = ptree->right) && ttree->type == EX_OP &&
640 ttree->opval.op == PARAM)
642 ptree->right = ttree->right;
643 ttree->right = ttree->left;
644 ttree->left = ptree->left;
650 ptree->left = ptree->right;
651 ptree->right = ttree;
653 reverseParms (ptree->left);
654 reverseParms (ptree->right);
660 /*-----------------------------------------------------------------*/
661 /* processParms - makes sure the parameters are okay and do some */
662 /* processing with them */
663 /*-----------------------------------------------------------------*/
665 processParms (ast *func,
668 int *parmNumber, /* unused, although updated */
671 RESULT_TYPE resultType;
674 /* if none of them exist */
675 if (!defParm && !*actParm)
680 if (getenv("DEBUG_SANITY"))
682 fprintf (stderr, "processParms: %s ", defParm->name);
684 /* make sure the type is complete and sane */
685 checkTypeSanity(defParm->etype, defParm->name);
688 if (IS_CODEPTR (func->ftype))
689 functype = func->ftype->next;
691 functype = func->ftype;
693 /* if the function is being called via a pointer & */
694 /* it has not been defined a reentrant then we cannot */
695 /* have parameters */
696 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
698 werror (W_NONRENT_ARGS);
703 /* if defined parameters ended but actual parameters */
704 /* exist and this is not defined as a variable arg */
705 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
707 werror (E_TOO_MANY_PARMS);
711 /* if defined parameters present but no actual parameters */
712 if (defParm && !*actParm)
714 werror (E_TOO_FEW_PARMS);
718 /* if this is a PARAM node then match left & right */
719 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
721 (*actParm)->decorated = 1;
722 return (processParms (func, defParm,
723 &(*actParm)->left, parmNumber, FALSE) ||
724 processParms (func, defParm ? defParm->next : NULL,
725 &(*actParm)->right, parmNumber, rightmost));
727 else if (defParm) /* not vararg */
729 /* If we have found a value node by following only right-hand links,
730 * then we know that there are no more values after us.
732 * Therefore, if there are more defined parameters, the caller didn't
735 if (rightmost && defParm->next)
737 werror (E_TOO_FEW_PARMS);
742 /* decorate parameter */
743 resultType = defParm ? getResultTypeFromType (defParm->etype) :
745 *actParm = decorateType (*actParm, resultType);
747 if (IS_VOID((*actParm)->ftype))
749 werror (E_VOID_VALUE_USED);
753 /* If this is a varargs function... */
754 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
759 if (IS_CAST_OP (*actParm)
760 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
762 /* Parameter was explicitly typecast; don't touch it. */
766 ftype = (*actParm)->ftype;
768 /* If it's a char, upcast to int. */
769 if (IS_INTEGRAL (ftype)
770 && (getSize (ftype) < (unsigned) INTSIZE))
772 newType = newAst_LINK(INTTYPE);
775 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
777 newType = newAst_LINK (copyLinkChain(ftype));
778 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
781 if (IS_AGGREGATE (ftype))
783 newType = newAst_LINK (copyLinkChain (ftype));
784 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
789 /* cast required; change this op to a cast. */
790 (*actParm)->decorated = 0;
791 *actParm = newNode (CAST, newType, *actParm);
792 (*actParm)->lineno = (*actParm)->right->lineno;
794 decorateType (*actParm, RESULT_TYPE_NONE);
799 /* if defined parameters ended but actual has not & */
801 if (!defParm && *actParm &&
802 (options.stackAuto || IFFUNC_ISREENT (functype)))
805 resolveSymbols (*actParm);
807 /* the parameter type must be at least castable */
808 if (compareType (defParm->type, (*actParm)->ftype) == 0)
810 werror (E_INCOMPAT_TYPES);
811 printFromToType ((*actParm)->ftype, defParm->type);
815 /* if the parameter is castable then add the cast */
816 if (compareType (defParm->type, (*actParm)->ftype) < 0)
820 resultType = getResultTypeFromType (defParm->etype);
821 pTree = resolveSymbols (copyAst (*actParm));
823 /* now change the current one to a cast */
824 (*actParm)->type = EX_OP;
825 (*actParm)->opval.op = CAST;
826 (*actParm)->left = newAst_LINK (defParm->type);
827 (*actParm)->right = pTree;
828 (*actParm)->decorated = 0; /* force typechecking */
829 decorateType (*actParm, resultType);
832 /* make a copy and change the regparm type to the defined parm */
833 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
834 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
835 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
840 /*-----------------------------------------------------------------*/
841 /* createIvalType - generates ival for basic types */
842 /*-----------------------------------------------------------------*/
844 createIvalType (ast * sym, sym_link * type, initList * ilist)
848 /* if initList is deep */
849 if (ilist->type == INIT_DEEP)
850 ilist = ilist->init.deep;
852 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
853 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
856 /*-----------------------------------------------------------------*/
857 /* createIvalStruct - generates initial value for structures */
858 /*-----------------------------------------------------------------*/
860 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
867 sflds = SPEC_STRUCT (type)->fields;
868 if (ilist->type != INIT_DEEP)
870 werror (E_INIT_STRUCT, "");
874 iloop = ilist->init.deep;
876 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
878 /* if we have come to end */
882 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
883 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
884 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_TYPE_NONE);
888 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
889 W_EXCESS_INITIALIZERS, "struct",
890 sym->opval.val->sym->name);
897 /*-----------------------------------------------------------------*/
898 /* createIvalArray - generates code for array initialization */
899 /*-----------------------------------------------------------------*/
901 createIvalArray (ast * sym, sym_link * type, initList * ilist)
905 int lcnt = 0, size = 0;
906 literalList *literalL;
908 /* take care of the special case */
909 /* array of characters can be init */
911 if (IS_CHAR (type->next))
912 if ((rast = createIvalCharPtr (sym,
914 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
916 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
918 /* not the special case */
919 if (ilist->type != INIT_DEEP)
921 werror (E_INIT_STRUCT, "");
925 iloop = ilist->init.deep;
926 lcnt = DCL_ELEM (type);
928 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
932 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
934 rast = newNode(ARRAYINIT, aSym, NULL);
935 rast->values.constlist = literalL;
937 // Make sure size is set to length of initializer list.
944 if (lcnt && size > lcnt)
946 // Array size was specified, and we have more initializers than needed.
947 char *name=sym->opval.val->sym->name;
948 int lineno=sym->opval.val->sym->lineDef;
949 char *filename=sym->opval.val->sym->fileDef;
951 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
960 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
961 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
962 rast = createIval (aSym, type->next, iloop, rast);
963 iloop = (iloop ? iloop->next : NULL);
969 /* no of elements given and we */
970 /* have generated for all of them */
973 // is this a better way? at least it won't crash
974 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
975 int lineno = iloop->lineno;
976 char *filename = iloop->filename;
977 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
984 /* if we have not been given a size */
985 if (!DCL_ELEM (type))
987 /* but this still updates the typedef instead of the instance ! see bug 770487 */
988 DCL_ELEM (type) = size;
991 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
995 /*-----------------------------------------------------------------*/
996 /* createIvalCharPtr - generates initial values for char pointers */
997 /*-----------------------------------------------------------------*/
999 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1003 /* if this is a pointer & right is a literal array then */
1004 /* just assignment will do */
1005 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1006 SPEC_SCLS (iexpr->etype) == S_CODE)
1007 && IS_ARRAY (iexpr->ftype)))
1008 return newNode ('=', sym, iexpr);
1010 /* left side is an array so we have to assign each */
1012 if ((IS_LITERAL (iexpr->etype) ||
1013 SPEC_SCLS (iexpr->etype) == S_CODE)
1014 && IS_ARRAY (iexpr->ftype))
1016 /* for each character generate an assignment */
1017 /* to the array element */
1018 char *s = SPEC_CVAL (iexpr->etype).v_char;
1020 int size = getSize (iexpr->ftype);
1021 int symsize = getSize (type);
1025 if (size>(symsize+1))
1026 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1027 "string", sym->opval.val->sym->name);
1031 for (i=0;i<size;i++)
1033 rast = newNode (NULLOP,
1037 newAst_VALUE (valueFromLit ((float) i))),
1038 newAst_VALUE (valueFromLit (*s))));
1042 // now WE don't need iexpr's symbol anymore
1043 freeStringSymbol(AST_SYMBOL(iexpr));
1045 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1051 /*-----------------------------------------------------------------*/
1052 /* createIvalPtr - generates initial value for pointers */
1053 /*-----------------------------------------------------------------*/
1055 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1061 if (ilist->type == INIT_DEEP)
1062 ilist = ilist->init.deep;
1064 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1066 /* if character pointer */
1067 if (IS_CHAR (type->next))
1068 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1071 return newNode ('=', sym, iexpr);
1074 /*-----------------------------------------------------------------*/
1075 /* createIval - generates code for initial value */
1076 /*-----------------------------------------------------------------*/
1078 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1085 /* if structure then */
1086 if (IS_STRUCT (type))
1087 rast = createIvalStruct (sym, type, ilist);
1089 /* if this is a pointer */
1091 rast = createIvalPtr (sym, type, ilist);
1093 /* if this is an array */
1094 if (IS_ARRAY (type))
1095 rast = createIvalArray (sym, type, ilist);
1097 /* if type is SPECIFIER */
1099 rast = createIvalType (sym, type, ilist);
1102 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1104 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1107 /*-----------------------------------------------------------------*/
1108 /* initAggregates - initialises aggregate variables with initv */
1109 /*-----------------------------------------------------------------*/
1110 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1111 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1114 /*-----------------------------------------------------------------*/
1115 /* gatherAutoInit - creates assignment expressions for initial */
1117 /*-----------------------------------------------------------------*/
1119 gatherAutoInit (symbol * autoChain)
1126 for (sym = autoChain; sym; sym = sym->next)
1129 /* resolve the symbols in the ival */
1131 resolveIvalSym (sym->ival, sym->type);
1133 /* if this is a static variable & has an */
1134 /* initial value the code needs to be lifted */
1135 /* here to the main portion since they can be */
1136 /* initialised only once at the start */
1137 if (IS_STATIC (sym->etype) && sym->ival &&
1138 SPEC_SCLS (sym->etype) != S_CODE)
1142 /* insert the symbol into the symbol table */
1143 /* with level = 0 & name = rname */
1144 newSym = copySymbol (sym);
1145 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1147 /* now lift the code to main */
1148 if (IS_AGGREGATE (sym->type)) {
1149 work = initAggregates (sym, sym->ival, NULL);
1151 if (getNelements(sym->type, sym->ival)>1) {
1152 werrorfl (sym->fileDef, sym->lineDef,
1153 W_EXCESS_INITIALIZERS, "scalar",
1156 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1157 list2expr (sym->ival));
1160 setAstLineno (work, sym->lineDef);
1164 staticAutos = newNode (NULLOP, staticAutos, work);
1171 /* if there is an initial value */
1172 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1174 initList *ilist=sym->ival;
1176 while (ilist->type == INIT_DEEP) {
1177 ilist = ilist->init.deep;
1180 /* update lineno for error msg */
1181 lineno=sym->lineDef;
1182 setAstLineno (ilist->init.node, lineno);
1184 if (IS_AGGREGATE (sym->type)) {
1185 work = initAggregates (sym, sym->ival, NULL);
1187 if (getNelements(sym->type, sym->ival)>1) {
1188 werrorfl (sym->fileDef, sym->lineDef,
1189 W_EXCESS_INITIALIZERS, "scalar",
1192 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1193 list2expr (sym->ival));
1197 setAstLineno (work, sym->lineDef);
1201 init = newNode (NULLOP, init, work);
1210 /*-----------------------------------------------------------------*/
1211 /* freeStringSymbol - delete a literal string if no more usage */
1212 /*-----------------------------------------------------------------*/
1213 void freeStringSymbol(symbol *sym) {
1214 /* make sure this is a literal string */
1215 assert (sym->isstrlit);
1216 if (--sym->isstrlit == 0) { // lower the usage count
1217 memmap *segment=SPEC_OCLS(sym->etype);
1219 deleteSetItem(&segment->syms, sym);
1224 /*-----------------------------------------------------------------*/
1225 /* stringToSymbol - creates a symbol from a literal string */
1226 /*-----------------------------------------------------------------*/
1228 stringToSymbol (value * val)
1230 char name[SDCC_NAME_MAX + 1];
1231 static int charLbl = 0;
1236 // have we heard this before?
1237 for (sp=statsg->syms; sp; sp=sp->next) {
1239 size = getSize (sym->type);
1240 if (sym->isstrlit && size == getSize (val->type) &&
1241 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1242 // yes, this is old news. Don't publish it again.
1243 sym->isstrlit++; // but raise the usage count
1244 return symbolVal(sym);
1248 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1249 sym = newSymbol (name, 0); /* make it @ level 0 */
1250 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1252 /* copy the type from the value passed */
1253 sym->type = copyLinkChain (val->type);
1254 sym->etype = getSpec (sym->type);
1255 /* change to storage class & output class */
1256 SPEC_SCLS (sym->etype) = S_CODE;
1257 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1258 SPEC_STAT (sym->etype) = 1;
1259 /* make the level & block = 0 */
1260 sym->block = sym->level = 0;
1262 /* create an ival */
1263 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1268 allocVariables (sym);
1271 return symbolVal (sym);
1275 /*-----------------------------------------------------------------*/
1276 /* processBlockVars - will go thru the ast looking for block if */
1277 /* a block is found then will allocate the syms */
1278 /* will also gather the auto inits present */
1279 /*-----------------------------------------------------------------*/
1281 processBlockVars (ast * tree, int *stack, int action)
1286 /* if this is a block */
1287 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1291 if (action == ALLOCATE)
1293 *stack += allocVariables (tree->values.sym);
1294 autoInit = gatherAutoInit (tree->values.sym);
1296 /* if there are auto inits then do them */
1298 tree->left = newNode (NULLOP, autoInit, tree->left);
1300 else /* action is deallocate */
1301 deallocLocal (tree->values.sym);
1304 processBlockVars (tree->left, stack, action);
1305 processBlockVars (tree->right, stack, action);
1310 /*-------------------------------------------------------------*/
1311 /* constExprTree - returns TRUE if this tree is a constant */
1313 /*-------------------------------------------------------------*/
1314 bool constExprTree (ast *cexpr) {
1320 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1322 switch (cexpr->type)
1325 if (IS_AST_LIT_VALUE(cexpr)) {
1326 // this is a literal
1329 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1330 // a function's address will never change
1333 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1334 // an array's address will never change
1337 if (IS_AST_SYM_VALUE(cexpr) &&
1338 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1339 // a symbol in code space will never change
1340 // This is only for the 'char *s="hallo"' case and will have to leave
1341 //printf(" code space symbol");
1346 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1347 "unexpected link in expression tree\n");
1350 if (cexpr->opval.op==ARRAYINIT) {
1351 // this is a list of literals
1354 if (cexpr->opval.op=='=') {
1355 return constExprTree(cexpr->right);
1357 if (cexpr->opval.op==CAST) {
1358 // cast ignored, maybe we should throw a warning here?
1359 return constExprTree(cexpr->right);
1361 if (cexpr->opval.op=='&') {
1364 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1367 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1372 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1377 /*-----------------------------------------------------------------*/
1378 /* constExprValue - returns the value of a constant expression */
1379 /* or NULL if it is not a constant expression */
1380 /*-----------------------------------------------------------------*/
1382 constExprValue (ast * cexpr, int check)
1384 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1386 /* if this is not a constant then */
1387 if (!IS_LITERAL (cexpr->ftype))
1389 /* then check if this is a literal array
1391 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1392 SPEC_CVAL (cexpr->etype).v_char &&
1393 IS_ARRAY (cexpr->ftype))
1395 value *val = valFromType (cexpr->ftype);
1396 SPEC_SCLS (val->etype) = S_LITERAL;
1397 val->sym = cexpr->opval.val->sym;
1398 val->sym->type = copyLinkChain (cexpr->ftype);
1399 val->sym->etype = getSpec (val->sym->type);
1400 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1404 /* if we are casting a literal value then */
1405 if (IS_AST_OP (cexpr) &&
1406 cexpr->opval.op == CAST &&
1407 IS_LITERAL (cexpr->right->ftype))
1409 return valCastLiteral (cexpr->ftype,
1410 floatFromVal (cexpr->right->opval.val));
1413 if (IS_AST_VALUE (cexpr))
1415 return cexpr->opval.val;
1419 werror (E_CONST_EXPECTED, "found expression");
1424 /* return the value */
1425 return cexpr->opval.val;
1429 /*-----------------------------------------------------------------*/
1430 /* isLabelInAst - will return true if a given label is found */
1431 /*-----------------------------------------------------------------*/
1433 isLabelInAst (symbol * label, ast * tree)
1435 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1438 if (IS_AST_OP (tree) &&
1439 tree->opval.op == LABEL &&
1440 isSymbolEqual (AST_SYMBOL (tree->left), label))
1443 return isLabelInAst (label, tree->right) &&
1444 isLabelInAst (label, tree->left);
1448 /*-----------------------------------------------------------------*/
1449 /* isLoopCountable - return true if the loop count can be determi- */
1450 /* -ned at compile time . */
1451 /*-----------------------------------------------------------------*/
1453 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1454 symbol ** sym, ast ** init, ast ** end)
1457 /* the loop is considered countable if the following
1458 conditions are true :-
1460 a) initExpr :- <sym> = <const>
1461 b) condExpr :- <sym> < <const1>
1462 c) loopExpr :- <sym> ++
1465 /* first check the initExpr */
1466 if (IS_AST_OP (initExpr) &&
1467 initExpr->opval.op == '=' && /* is assignment */
1468 IS_AST_SYM_VALUE (initExpr->left))
1469 { /* left is a symbol */
1471 *sym = AST_SYMBOL (initExpr->left);
1472 *init = initExpr->right;
1477 /* for now the symbol has to be of
1479 if (!IS_INTEGRAL ((*sym)->type))
1482 /* now check condExpr */
1483 if (IS_AST_OP (condExpr))
1486 switch (condExpr->opval.op)
1489 if (IS_AST_SYM_VALUE (condExpr->left) &&
1490 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1491 IS_AST_LIT_VALUE (condExpr->right))
1493 *end = condExpr->right;
1499 if (IS_AST_OP (condExpr->left) &&
1500 condExpr->left->opval.op == '>' &&
1501 IS_AST_LIT_VALUE (condExpr->left->right) &&
1502 IS_AST_SYM_VALUE (condExpr->left->left) &&
1503 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1506 *end = newNode ('+', condExpr->left->right,
1507 newAst_VALUE (constVal ("1")));
1518 /* check loop expression is of the form <sym>++ */
1519 if (!IS_AST_OP (loopExpr))
1522 /* check if <sym> ++ */
1523 if (loopExpr->opval.op == INC_OP)
1529 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1530 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1537 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1538 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1546 if (loopExpr->opval.op == ADD_ASSIGN)
1549 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1550 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1551 IS_AST_LIT_VALUE (loopExpr->right) &&
1552 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1560 /*-----------------------------------------------------------------*/
1561 /* astHasVolatile - returns true if ast contains any volatile */
1562 /*-----------------------------------------------------------------*/
1564 astHasVolatile (ast * tree)
1569 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1572 if (IS_AST_OP (tree))
1573 return astHasVolatile (tree->left) ||
1574 astHasVolatile (tree->right);
1579 /*-----------------------------------------------------------------*/
1580 /* astHasPointer - return true if the ast contains any ptr variable */
1581 /*-----------------------------------------------------------------*/
1583 astHasPointer (ast * tree)
1588 if (IS_AST_LINK (tree))
1591 /* if we hit an array expression then check
1592 only the left side */
1593 if (IS_AST_OP (tree) && tree->opval.op == '[')
1594 return astHasPointer (tree->left);
1596 if (IS_AST_VALUE (tree))
1597 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1599 return astHasPointer (tree->left) ||
1600 astHasPointer (tree->right);
1604 /*-----------------------------------------------------------------*/
1605 /* astHasSymbol - return true if the ast has the given symbol */
1606 /*-----------------------------------------------------------------*/
1608 astHasSymbol (ast * tree, symbol * sym)
1610 if (!tree || IS_AST_LINK (tree))
1613 if (IS_AST_VALUE (tree))
1615 if (IS_AST_SYM_VALUE (tree))
1616 return isSymbolEqual (AST_SYMBOL (tree), sym);
1621 return astHasSymbol (tree->left, sym) ||
1622 astHasSymbol (tree->right, sym);
1625 /*-----------------------------------------------------------------*/
1626 /* astHasDeref - return true if the ast has an indirect access */
1627 /*-----------------------------------------------------------------*/
1629 astHasDeref (ast * tree)
1631 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1634 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1636 return astHasDeref (tree->left) || astHasDeref (tree->right);
1639 /*-----------------------------------------------------------------*/
1640 /* isConformingBody - the loop body has to conform to a set of rules */
1641 /* for the loop to be considered reversible read on for rules */
1642 /*-----------------------------------------------------------------*/
1644 isConformingBody (ast * pbody, symbol * sym, ast * body)
1647 /* we are going to do a pre-order traversal of the
1648 tree && check for the following conditions. (essentially
1649 a set of very shallow tests )
1650 a) the sym passed does not participate in
1651 any arithmetic operation
1652 b) There are no function calls
1653 c) all jumps are within the body
1654 d) address of loop control variable not taken
1655 e) if an assignment has a pointer on the
1656 left hand side make sure right does not have
1657 loop control variable */
1659 /* if we reach the end or a leaf then true */
1660 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1663 /* if anything else is "volatile" */
1664 if (IS_VOLATILE (TETYPE (pbody)))
1667 /* we will walk the body in a pre-order traversal for
1669 switch (pbody->opval.op)
1671 /*------------------------------------------------------------------*/
1673 // if the loopvar is used as an index
1674 /* array op is commutative -- must check both left & right */
1675 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1678 return isConformingBody (pbody->right, sym, body)
1679 && isConformingBody (pbody->left, sym, body);
1681 /*------------------------------------------------------------------*/
1686 /*------------------------------------------------------------------*/
1690 /* sure we are not sym is not modified */
1692 IS_AST_SYM_VALUE (pbody->left) &&
1693 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1697 IS_AST_SYM_VALUE (pbody->right) &&
1698 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1703 /*------------------------------------------------------------------*/
1705 case '*': /* can be unary : if right is null then unary operation */
1710 /* if right is NULL then unary operation */
1711 /*------------------------------------------------------------------*/
1712 /*----------------------------*/
1714 /*----------------------------*/
1717 if (IS_AST_SYM_VALUE (pbody->left) &&
1718 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1721 return isConformingBody (pbody->left, sym, body);
1725 if (astHasSymbol (pbody->left, sym) ||
1726 astHasSymbol (pbody->right, sym))
1731 /*------------------------------------------------------------------*/
1739 if (IS_AST_SYM_VALUE (pbody->left) &&
1740 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1743 if (IS_AST_SYM_VALUE (pbody->right) &&
1744 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1747 return isConformingBody (pbody->left, sym, body) &&
1748 isConformingBody (pbody->right, sym, body);
1756 if (IS_AST_SYM_VALUE (pbody->left) &&
1757 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1759 return isConformingBody (pbody->left, sym, body);
1761 /*------------------------------------------------------------------*/
1773 case SIZEOF: /* evaluate wihout code generation */
1775 if (IS_AST_SYM_VALUE (pbody->left) &&
1776 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1779 if (IS_AST_SYM_VALUE (pbody->right) &&
1780 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1783 return isConformingBody (pbody->left, sym, body) &&
1784 isConformingBody (pbody->right, sym, body);
1786 /*------------------------------------------------------------------*/
1789 /* if left has a pointer & right has loop
1790 control variable then we cannot */
1791 if (astHasPointer (pbody->left) &&
1792 astHasSymbol (pbody->right, sym))
1794 if (astHasVolatile (pbody->left))
1797 if (IS_AST_SYM_VALUE (pbody->left)) {
1798 // if the loopvar has an assignment
1799 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1801 // if the loopvar is used in another (maybe conditional) block
1802 if (astHasSymbol (pbody->right, sym) &&
1803 (pbody->level >= body->level)) {
1808 if (astHasVolatile (pbody->left))
1811 if (astHasDeref(pbody->right)) return FALSE;
1813 return isConformingBody (pbody->left, sym, body) &&
1814 isConformingBody (pbody->right, sym, body);
1825 assert ("Parser should not have generated this\n");
1827 /*------------------------------------------------------------------*/
1828 /*----------------------------*/
1829 /* comma operator */
1830 /*----------------------------*/
1832 return isConformingBody (pbody->left, sym, body) &&
1833 isConformingBody (pbody->right, sym, body);
1835 /*------------------------------------------------------------------*/
1836 /*----------------------------*/
1838 /*----------------------------*/
1840 /* if local & not passed as paramater then ok */
1841 if (sym->level && !astHasSymbol(pbody->right,sym))
1845 /*------------------------------------------------------------------*/
1846 /*----------------------------*/
1847 /* return statement */
1848 /*----------------------------*/
1853 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1858 if (astHasSymbol (pbody->left, sym))
1865 return isConformingBody (pbody->left, sym, body) &&
1866 isConformingBody (pbody->right, sym, body);
1872 /*-----------------------------------------------------------------*/
1873 /* isLoopReversible - takes a for loop as input && returns true */
1874 /* if the for loop is reversible. If yes will set the value of */
1875 /* the loop control var & init value & termination value */
1876 /*-----------------------------------------------------------------*/
1878 isLoopReversible (ast * loop, symbol ** loopCntrl,
1879 ast ** init, ast ** end)
1881 /* if option says don't do it then don't */
1882 if (optimize.noLoopReverse)
1884 /* there are several tests to determine this */
1886 /* for loop has to be of the form
1887 for ( <sym> = <const1> ;
1888 [<sym> < <const2>] ;
1889 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1891 if (!isLoopCountable (AST_FOR (loop, initExpr),
1892 AST_FOR (loop, condExpr),
1893 AST_FOR (loop, loopExpr),
1894 loopCntrl, init, end))
1897 /* now do some serious checking on the body of the loop
1900 return isConformingBody (loop->left, *loopCntrl, loop->left);
1904 /*-----------------------------------------------------------------*/
1905 /* replLoopSym - replace the loop sym by loop sym -1 */
1906 /*-----------------------------------------------------------------*/
1908 replLoopSym (ast * body, symbol * sym)
1911 if (!body || IS_AST_LINK (body))
1914 if (IS_AST_SYM_VALUE (body))
1917 if (isSymbolEqual (AST_SYMBOL (body), sym))
1921 body->opval.op = '-';
1922 body->left = newAst_VALUE (symbolVal (sym));
1923 body->right = newAst_VALUE (constVal ("1"));
1931 replLoopSym (body->left, sym);
1932 replLoopSym (body->right, sym);
1936 /*-----------------------------------------------------------------*/
1937 /* reverseLoop - do the actual loop reversal */
1938 /*-----------------------------------------------------------------*/
1940 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1944 /* create the following tree
1949 if (sym) goto for_continue ;
1952 /* put it together piece by piece */
1953 rloop = newNode (NULLOP,
1954 createIf (newAst_VALUE (symbolVal (sym)),
1956 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1959 newAst_VALUE (symbolVal (sym)),
1962 replLoopSym (loop->left, sym);
1963 setAstLineno (rloop, init->lineno);
1965 rloop = newNode (NULLOP,
1967 newAst_VALUE (symbolVal (sym)),
1968 newNode ('-', end, init)),
1969 createLabel (AST_FOR (loop, continueLabel),
1973 newNode (SUB_ASSIGN,
1974 newAst_VALUE (symbolVal (sym)),
1975 newAst_VALUE (constVal ("1"))),
1978 rloop->lineno=init->lineno;
1979 return decorateType (rloop, RESULT_TYPE_NONE);
1983 /*-----------------------------------------------------------------*/
1984 /* searchLitOp - search tree (*ops only) for an ast with literal */
1985 /*-----------------------------------------------------------------*/
1987 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
1991 if (tree && optimize.global_cse)
1993 /* is there a literal operand? */
1995 IS_AST_OP(tree->right) &&
1996 tree->right->right &&
1997 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1999 if (IS_LITERAL (RTYPE (tree->right)) !=
2000 IS_LITERAL (LTYPE (tree->right)))
2002 tree->right->decorated = 0;
2003 tree->decorated = 0;
2007 ret = searchLitOp (tree->right, parent, ops);
2012 IS_AST_OP(tree->left) &&
2013 tree->left->right &&
2014 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2016 if (IS_LITERAL (RTYPE (tree->left)) !=
2017 IS_LITERAL (LTYPE (tree->left)))
2019 tree->left->decorated = 0;
2020 tree->decorated = 0;
2024 ret = searchLitOp (tree->left, parent, ops);
2032 /*-----------------------------------------------------------------*/
2033 /* getResultFromType */
2034 /*-----------------------------------------------------------------*/
2036 getResultTypeFromType (sym_link *type)
2038 /* type = getSpec (type); */
2040 return RESULT_TYPE_BIT;
2041 if (IS_BITFIELD (type))
2043 int blen = SPEC_BLEN (type);
2046 return RESULT_TYPE_BIT;
2048 return RESULT_TYPE_CHAR;
2049 return RESULT_TYPE_INT;
2052 return RESULT_TYPE_CHAR;
2055 return RESULT_TYPE_INT;
2056 return RESULT_TYPE_OTHER;
2059 /*-----------------------------------------------------------------*/
2060 /* addCast - adds casts to a type specified by RESULT_TYPE */
2061 /*-----------------------------------------------------------------*/
2063 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2066 bool upCasted = FALSE;
2070 case RESULT_TYPE_NONE:
2071 /* char: promote to int */
2073 getSize (tree->etype) >= INTSIZE)
2075 newLink = newIntLink();
2078 case RESULT_TYPE_CHAR:
2079 if (IS_CHAR (tree->etype) ||
2080 IS_FLOAT(tree->etype))
2082 newLink = newCharLink();
2084 case RESULT_TYPE_INT:
2086 if (getSize (tree->etype) > INTSIZE)
2088 /* warn ("Loosing significant digits"); */
2092 /* char: promote to int */
2094 getSize (tree->etype) >= INTSIZE)
2096 newLink = newIntLink();
2099 case RESULT_TYPE_OTHER:
2102 /* return type is long, float: promote char to int */
2103 if (getSize (tree->etype) >= INTSIZE)
2105 newLink = newIntLink();
2111 tree->decorated = 0;
2112 tree = newNode (CAST, newAst_LINK (newLink), tree);
2113 tree->lineno = tree->right->lineno;
2114 /* keep unsigned type during cast to smaller type,
2115 but not when promoting from char to int */
2117 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2118 return decorateType (tree, resultType);
2121 /*-----------------------------------------------------------------*/
2122 /* resultTypePropagate - decides if resultType can be propagated */
2123 /*-----------------------------------------------------------------*/
2125 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2127 switch (tree->opval.op)
2143 return RESULT_TYPE_NONE;
2147 return RESULT_TYPE_IFX;
2149 return RESULT_TYPE_NONE;
2153 /*-----------------------------------------------------------------*/
2154 /* getLeftResultType - gets type from left branch for propagation */
2155 /*-----------------------------------------------------------------*/
2157 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2159 switch (tree->opval.op)
2163 if (IS_PTR (LTYPE (tree)))
2164 return RESULT_TYPE_NONE;
2166 return getResultTypeFromType (LETYPE (tree));
2168 if (IS_PTR (currFunc->type->next))
2169 return RESULT_TYPE_NONE;
2171 return getResultTypeFromType (currFunc->type->next);
2173 if (!IS_ARRAY (LTYPE (tree)))
2175 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2176 return RESULT_TYPE_CHAR;
2183 /*--------------------------------------------------------------------*/
2184 /* decorateType - compute type for this tree, also does type checking.*/
2185 /* This is done bottom up, since type has to flow upwards. */
2186 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2187 /* result is a char and the operand(s) are int's. */
2188 /* It also does constant folding, and parameter checking. */
2189 /*--------------------------------------------------------------------*/
2191 decorateType (ast * tree, RESULT_TYPE resultType)
2195 RESULT_TYPE resultTypeProp;
2200 /* if already has type then do nothing */
2201 if (tree->decorated)
2204 tree->decorated = 1;
2207 /* print the line */
2208 /* if not block & function */
2209 if (tree->type == EX_OP &&
2210 (tree->opval.op != FUNCTION &&
2211 tree->opval.op != BLOCK &&
2212 tree->opval.op != NULLOP))
2214 filename = tree->filename;
2215 lineno = tree->lineno;
2219 /* if any child is an error | this one is an error do nothing */
2220 if (tree->isError ||
2221 (tree->left && tree->left->isError) ||
2222 (tree->right && tree->right->isError))
2225 /*------------------------------------------------------------------*/
2226 /*----------------------------*/
2227 /* leaf has been reached */
2228 /*----------------------------*/
2229 lineno=tree->lineno;
2230 /* if this is of type value */
2231 /* just get the type */
2232 if (tree->type == EX_VALUE)
2235 if (IS_LITERAL (tree->opval.val->etype))
2238 /* if this is a character array then declare it */
2239 if (IS_ARRAY (tree->opval.val->type))
2240 tree->opval.val = stringToSymbol (tree->opval.val);
2242 /* otherwise just copy the type information */
2243 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2247 if (tree->opval.val->sym)
2249 /* if the undefined flag is set then give error message */
2250 if (tree->opval.val->sym->undefined)
2252 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2254 TTYPE (tree) = TETYPE (tree) =
2255 tree->opval.val->type = tree->opval.val->sym->type =
2256 tree->opval.val->etype = tree->opval.val->sym->etype =
2257 copyLinkChain (INTTYPE);
2262 /* if impilicit i.e. struct/union member then no type */
2263 if (tree->opval.val->sym->implicit)
2264 TTYPE (tree) = TETYPE (tree) = NULL;
2269 /* else copy the type */
2270 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2272 /* and mark it as referenced */
2273 tree->opval.val->sym->isref = 1;
2281 /* if type link for the case of cast */
2282 if (tree->type == EX_LINK)
2284 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2292 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2294 if (tree->left && tree->left->type == EX_OPERAND
2295 && (tree->left->opval.op == INC_OP
2296 || tree->left->opval.op == DEC_OP)
2297 && tree->left->left)
2299 tree->left->right = tree->left->left;
2300 tree->left->left = NULL;
2302 if (tree->right && tree->right->type == EX_OPERAND
2303 && (tree->right->opval.op == INC_OP
2304 || tree->right->opval.op == DEC_OP)
2305 && tree->right->left)
2307 tree->right->right = tree->right->left;
2308 tree->right->left = NULL;
2313 /* Before decorating the left branch we've to decide in dependence
2314 upon tree->opval.op, if resultType can be propagated */
2315 resultTypeProp = resultTypePropagate (tree, resultType);
2317 if (tree->opval.op == '?')
2318 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2320 dtl = decorateType (tree->left, resultTypeProp);
2322 /* if an array node, we may need to swap branches */
2323 if (tree->opval.op == '[')
2325 /* determine which is the array & which the index */
2326 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2327 IS_INTEGRAL (LTYPE (tree)))
2329 ast *tempTree = tree->left;
2330 tree->left = tree->right;
2331 tree->right = tempTree;
2335 /* After decorating the left branch there's type information available
2336 in tree->left->?type. If the op is e.g. '=' we extract the type
2337 information from there and propagate it to the right branch. */
2338 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2340 switch (tree->opval.op)
2343 /* delay right side for '?' operator since conditional macro
2344 expansions might rely on this */
2348 /* decorate right side for CALL (parameter list) in processParms();
2349 there is resultType available */
2353 dtr = decorateType (tree->right, resultTypeProp);
2357 /* this is to take care of situations
2358 when the tree gets rewritten */
2359 if (dtl != tree->left)
2361 if (dtr != tree->right)
2363 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2367 /* depending on type of operator do */
2369 switch (tree->opval.op)
2371 /*------------------------------------------------------------------*/
2372 /*----------------------------*/
2374 /*----------------------------*/
2377 /* first check if this is a array or a pointer */
2378 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2380 werror (E_NEED_ARRAY_PTR, "[]");
2381 goto errorTreeReturn;
2384 /* check if the type of the idx */
2385 if (!IS_INTEGRAL (RTYPE (tree)))
2387 werror (E_IDX_NOT_INT);
2388 goto errorTreeReturn;
2391 /* if the left is an rvalue then error */
2394 werror (E_LVALUE_REQUIRED, "array access");
2395 goto errorTreeReturn;
2398 if (IS_LITERAL (RTYPE (tree)))
2400 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2401 int arraySize = DCL_ELEM (LTYPE (tree));
2402 if (arraySize && arrayIndex >= arraySize)
2404 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2409 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2412 /*------------------------------------------------------------------*/
2413 /*----------------------------*/
2415 /*----------------------------*/
2417 /* if this is not a structure */
2418 if (!IS_STRUCT (LTYPE (tree)))
2420 werror (E_STRUCT_UNION, ".");
2421 goto errorTreeReturn;
2423 TTYPE (tree) = structElemType (LTYPE (tree),
2424 (tree->right->type == EX_VALUE ?
2425 tree->right->opval.val : NULL));
2426 TETYPE (tree) = getSpec (TTYPE (tree));
2429 /*------------------------------------------------------------------*/
2430 /*----------------------------*/
2431 /* struct/union pointer */
2432 /*----------------------------*/
2434 /* if not pointer to a structure */
2435 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2437 werror (E_PTR_REQD);
2438 goto errorTreeReturn;
2441 if (!IS_STRUCT (LTYPE (tree)->next))
2443 werror (E_STRUCT_UNION, "->");
2444 goto errorTreeReturn;
2447 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2448 (tree->right->type == EX_VALUE ?
2449 tree->right->opval.val : NULL));
2450 TETYPE (tree) = getSpec (TTYPE (tree));
2452 /* adjust the storage class */
2453 switch (DCL_TYPE(tree->left->ftype)) {
2455 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2458 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2461 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2464 SPEC_SCLS (TETYPE (tree)) = 0;
2467 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2470 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2473 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2476 SPEC_SCLS (TETYPE (tree)) = 0;
2483 /* This breaks with extern declarations, bitfields, and perhaps other */
2484 /* cases (gcse). Let's leave this optimization disabled for now and */
2485 /* ponder if there's a safe way to do this. -- EEP */
2487 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2488 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2490 /* If defined struct type at addr var
2491 then rewrite (&struct var)->member
2493 and define membertype at (addr+offsetof(struct var,member)) temp
2496 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2497 AST_SYMBOL(tree->right));
2499 sym = newSymbol(genSymName (0), 0);
2500 sym->type = TTYPE (tree);
2501 sym->etype = getSpec(sym->type);
2502 sym->lineDef = tree->lineno;
2505 SPEC_STAT (sym->etype) = 1;
2506 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2508 SPEC_ABSA(sym->etype) = 1;
2509 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2512 AST_VALUE (tree) = symbolVal(sym);
2515 tree->type = EX_VALUE;
2523 /*------------------------------------------------------------------*/
2524 /*----------------------------*/
2525 /* ++/-- operation */
2526 /*----------------------------*/
2530 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2531 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2532 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2533 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2542 /*------------------------------------------------------------------*/
2543 /*----------------------------*/
2545 /*----------------------------*/
2546 case '&': /* can be unary */
2547 /* if right is NULL then unary operation */
2548 if (tree->right) /* not an unary operation */
2551 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2553 werror (E_BITWISE_OP);
2554 werror (W_CONTINUE, "left & right types are ");
2555 printTypeChain (LTYPE (tree), stderr);
2556 fprintf (stderr, ",");
2557 printTypeChain (RTYPE (tree), stderr);
2558 fprintf (stderr, "\n");
2559 goto errorTreeReturn;
2562 /* if they are both literal */
2563 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2565 tree->type = EX_VALUE;
2566 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2567 valFromType (RETYPE (tree)), '&');
2569 tree->right = tree->left = NULL;
2570 TETYPE (tree) = tree->opval.val->etype;
2571 TTYPE (tree) = tree->opval.val->type;
2575 /* see if this is a GETHBIT operation if yes
2578 ast *otree = optimizeGetHbit (tree);
2581 return decorateType (otree, RESULT_TYPE_NONE);
2584 /* if left is a literal exchange left & right */
2585 if (IS_LITERAL (LTYPE (tree)))
2587 ast *tTree = tree->left;
2588 tree->left = tree->right;
2589 tree->right = tTree;
2592 /* if right is a literal and */
2593 /* we can find a 2nd literal in an and-tree then */
2594 /* rearrange the tree */
2595 if (IS_LITERAL (RTYPE (tree)))
2598 ast *litTree = searchLitOp (tree, &parent, "&");
2602 ast *tTree = litTree->left;
2603 litTree->left = tree->right;
2604 tree->right = tTree;
2605 /* both operands in litTree are literal now */
2606 decorateType (parent, resultType);
2610 LRVAL (tree) = RRVAL (tree) = 1;
2612 TTYPE (tree) = computeType (LTYPE (tree),
2616 TETYPE (tree) = getSpec (TTYPE (tree));
2621 /*------------------------------------------------------------------*/
2622 /*----------------------------*/
2624 /*----------------------------*/
2625 p = newLink (DECLARATOR);
2626 /* if bit field then error */
2627 if (IS_BITVAR (tree->left->etype))
2629 werror (E_ILLEGAL_ADDR, "address of bit variable");
2630 goto errorTreeReturn;
2633 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2635 werror (E_ILLEGAL_ADDR, "address of register variable");
2636 goto errorTreeReturn;
2639 if (IS_FUNC (LTYPE (tree)))
2641 // this ought to be ignored
2642 return (tree->left);
2645 if (IS_LITERAL(LTYPE(tree)))
2647 werror (E_ILLEGAL_ADDR, "address of literal");
2648 goto errorTreeReturn;
2653 werror (E_LVALUE_REQUIRED, "address of");
2654 goto errorTreeReturn;
2657 DCL_TYPE (p) = POINTER;
2658 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2659 DCL_TYPE (p) = CPOINTER;
2660 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2661 DCL_TYPE (p) = FPOINTER;
2662 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2663 DCL_TYPE (p) = PPOINTER;
2664 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2665 DCL_TYPE (p) = IPOINTER;
2666 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2667 DCL_TYPE (p) = EEPPOINTER;
2668 else if (SPEC_OCLS(tree->left->etype))
2669 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2671 DCL_TYPE (p) = POINTER;
2673 if (IS_AST_SYM_VALUE (tree->left))
2675 AST_SYMBOL (tree->left)->addrtaken = 1;
2676 AST_SYMBOL (tree->left)->allocreq = 1;
2679 p->next = LTYPE (tree);
2681 TETYPE (tree) = getSpec (TTYPE (tree));
2686 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2687 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2689 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2690 AST_SYMBOL(tree->left->right));
2691 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2692 valueFromLit(element->offset));
2695 tree->type = EX_VALUE;
2696 tree->values.literalFromCast = 1;
2702 /*------------------------------------------------------------------*/
2703 /*----------------------------*/
2705 /*----------------------------*/
2707 /* if the rewrite succeeds then don't go any furthur */
2709 ast *wtree = optimizeRRCRLC (tree);
2711 return decorateType (wtree, RESULT_TYPE_NONE);
2713 wtree = optimizeSWAP (tree);
2715 return decorateType (wtree, RESULT_TYPE_NONE);
2718 /* if left is a literal exchange left & right */
2719 if (IS_LITERAL (LTYPE (tree)))
2721 ast *tTree = tree->left;
2722 tree->left = tree->right;
2723 tree->right = tTree;
2726 /* if right is a literal and */
2727 /* we can find a 2nd literal in an or-tree then */
2728 /* rearrange the tree */
2729 if (IS_LITERAL (RTYPE (tree)))
2732 ast *litTree = searchLitOp (tree, &parent, "|");
2736 ast *tTree = litTree->left;
2737 litTree->left = tree->right;
2738 tree->right = tTree;
2739 /* both operands in tTree are literal now */
2740 decorateType (parent, resultType);
2745 /*------------------------------------------------------------------*/
2746 /*----------------------------*/
2748 /*----------------------------*/
2750 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2752 werror (E_BITWISE_OP);
2753 werror (W_CONTINUE, "left & right types are ");
2754 printTypeChain (LTYPE (tree), stderr);
2755 fprintf (stderr, ",");
2756 printTypeChain (RTYPE (tree), stderr);
2757 fprintf (stderr, "\n");
2758 goto errorTreeReturn;
2761 /* if they are both literal then rewrite the tree */
2762 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2764 tree->type = EX_VALUE;
2765 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2766 valFromType (RETYPE (tree)),
2768 tree->right = tree->left = NULL;
2769 TETYPE (tree) = tree->opval.val->etype;
2770 TTYPE (tree) = tree->opval.val->type;
2774 /* if left is a literal exchange left & right */
2775 if (IS_LITERAL (LTYPE (tree)))
2777 ast *tTree = tree->left;
2778 tree->left = tree->right;
2779 tree->right = tTree;
2782 /* if right is a literal and */
2783 /* we can find a 2nd literal in a xor-tree then */
2784 /* rearrange the tree */
2785 if (IS_LITERAL (RTYPE (tree)) &&
2786 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2789 ast *litTree = searchLitOp (tree, &parent, "^");
2793 ast *tTree = litTree->left;
2794 litTree->left = tree->right;
2795 tree->right = tTree;
2796 /* both operands in litTree are literal now */
2797 decorateType (parent, resultType);
2801 LRVAL (tree) = RRVAL (tree) = 1;
2803 TTYPE (tree) = computeType (LTYPE (tree),
2807 TETYPE (tree) = getSpec (TTYPE (tree));
2811 /*------------------------------------------------------------------*/
2812 /*----------------------------*/
2814 /*----------------------------*/
2816 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2818 werror (E_INVALID_OP, "divide");
2819 goto errorTreeReturn;
2821 /* if they are both literal then */
2822 /* rewrite the tree */
2823 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2825 tree->type = EX_VALUE;
2826 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2827 valFromType (RETYPE (tree)));
2828 tree->right = tree->left = NULL;
2829 TETYPE (tree) = getSpec (TTYPE (tree) =
2830 tree->opval.val->type);
2834 LRVAL (tree) = RRVAL (tree) = 1;
2836 TETYPE (tree) = getSpec (TTYPE (tree) =
2837 computeType (LTYPE (tree),
2842 /* if right is a literal and */
2843 /* left is also a division by a literal then */
2844 /* rearrange the tree */
2845 if (IS_LITERAL (RTYPE (tree))
2846 /* avoid infinite loop */
2847 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2850 ast *litTree = searchLitOp (tree, &parent, "/");
2853 if (IS_LITERAL (RTYPE (litTree)))
2857 litTree->right = newNode ('*',
2859 copyAst (tree->right));
2860 litTree->right->lineno = tree->lineno;
2862 tree->right->opval.val = constVal ("1");
2863 decorateType (parent, resultType);
2867 /* litTree->left is literal: no gcse possible.
2868 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2869 this would cause an infinit loop. */
2870 parent->decorated = 1;
2871 decorateType (litTree, resultType);
2878 /*------------------------------------------------------------------*/
2879 /*----------------------------*/
2881 /*----------------------------*/
2883 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2885 werror (E_BITWISE_OP);
2886 werror (W_CONTINUE, "left & right types are ");
2887 printTypeChain (LTYPE (tree), stderr);
2888 fprintf (stderr, ",");
2889 printTypeChain (RTYPE (tree), stderr);
2890 fprintf (stderr, "\n");
2891 goto errorTreeReturn;
2893 /* if they are both literal then */
2894 /* rewrite the tree */
2895 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2897 tree->type = EX_VALUE;
2898 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2899 valFromType (RETYPE (tree)));
2900 tree->right = tree->left = NULL;
2901 TETYPE (tree) = getSpec (TTYPE (tree) =
2902 tree->opval.val->type);
2905 LRVAL (tree) = RRVAL (tree) = 1;
2906 TETYPE (tree) = getSpec (TTYPE (tree) =
2907 computeType (LTYPE (tree),
2913 /*------------------------------------------------------------------*/
2914 /*----------------------------*/
2915 /* address dereference */
2916 /*----------------------------*/
2917 case '*': /* can be unary : if right is null then unary operation */
2920 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2922 werror (E_PTR_REQD);
2923 goto errorTreeReturn;
2928 werror (E_LVALUE_REQUIRED, "pointer deref");
2929 goto errorTreeReturn;
2931 if (IS_ADDRESS_OF_OP(tree->left))
2933 /* replace *&obj with obj */
2934 return tree->left->left;
2936 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2937 TETYPE (tree) = getSpec (TTYPE (tree));
2938 /* adjust the storage class */
2939 switch (DCL_TYPE(tree->left->ftype)) {
2941 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2944 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2947 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2950 SPEC_SCLS (TETYPE (tree)) = 0;
2953 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2956 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2959 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2962 SPEC_SCLS (TETYPE (tree)) = 0;
2971 /*------------------------------------------------------------------*/
2972 /*----------------------------*/
2973 /* multiplication */
2974 /*----------------------------*/
2975 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2977 werror (E_INVALID_OP, "multiplication");
2978 goto errorTreeReturn;
2981 /* if they are both literal then */
2982 /* rewrite the tree */
2983 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2985 tree->type = EX_VALUE;
2986 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2987 valFromType (RETYPE (tree)));
2988 tree->right = tree->left = NULL;
2989 TETYPE (tree) = getSpec (TTYPE (tree) =
2990 tree->opval.val->type);
2994 /* if left is a literal exchange left & right */
2995 if (IS_LITERAL (LTYPE (tree)))
2997 ast *tTree = tree->left;
2998 tree->left = tree->right;
2999 tree->right = tTree;
3002 /* if right is a literal and */
3003 /* we can find a 2nd literal in a mul-tree then */
3004 /* rearrange the tree */
3005 if (IS_LITERAL (RTYPE (tree)))
3008 ast *litTree = searchLitOp (tree, &parent, "*");
3012 ast *tTree = litTree->left;
3013 litTree->left = tree->right;
3014 tree->right = tTree;
3015 /* both operands in litTree are literal now */
3016 decorateType (parent, resultType);
3020 LRVAL (tree) = RRVAL (tree) = 1;
3021 tree->left = addCast (tree->left, resultType, FALSE);
3022 tree->right = addCast (tree->right, resultType, FALSE);
3023 TETYPE (tree) = getSpec (TTYPE (tree) =
3024 computeType (LTYPE (tree),
3031 /*------------------------------------------------------------------*/
3032 /*----------------------------*/
3033 /* unary '+' operator */
3034 /*----------------------------*/
3039 if (!IS_ARITHMETIC (LTYPE (tree)))
3041 werror (E_UNARY_OP, '+');
3042 goto errorTreeReturn;
3045 /* if left is a literal then do it */
3046 if (IS_LITERAL (LTYPE (tree)))
3048 tree->type = EX_VALUE;
3049 tree->opval.val = valFromType (LETYPE (tree));
3051 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3055 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3059 /*------------------------------------------------------------------*/
3060 /*----------------------------*/
3062 /*----------------------------*/
3064 /* this is not a unary operation */
3065 /* if both pointers then problem */
3066 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3067 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3069 werror (E_PTR_PLUS_PTR);
3070 goto errorTreeReturn;
3073 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3074 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3076 werror (E_PLUS_INVALID, "+");
3077 goto errorTreeReturn;
3080 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3081 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3083 werror (E_PLUS_INVALID, "+");
3084 goto errorTreeReturn;
3086 /* if they are both literal then */
3087 /* rewrite the tree */
3088 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3090 tree->type = EX_VALUE;
3091 tree->left = addCast (tree->left, resultType, TRUE);
3092 tree->right = addCast (tree->right, resultType, TRUE);
3093 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3094 valFromType (RETYPE (tree)));
3095 tree->right = tree->left = NULL;
3096 TETYPE (tree) = getSpec (TTYPE (tree) =
3097 tree->opval.val->type);
3101 /* if the right is a pointer or left is a literal
3102 xchange left & right */
3103 if (IS_ARRAY (RTYPE (tree)) ||
3104 IS_PTR (RTYPE (tree)) ||
3105 IS_LITERAL (LTYPE (tree)))
3107 ast *tTree = tree->left;
3108 tree->left = tree->right;
3109 tree->right = tTree;
3112 /* if right is a literal and */
3113 /* left is also an addition/subtraction with a literal then */
3114 /* rearrange the tree */
3115 if (IS_LITERAL (RTYPE (tree)))
3117 ast *litTree, *parent;
3118 litTree = searchLitOp (tree, &parent, "+-");
3121 if (litTree->opval.op == '+')
3125 ast *tTree = litTree->left;
3126 litTree->left = tree->right;
3127 tree->right = tree->left;
3130 else if (litTree->opval.op == '-')
3132 if (IS_LITERAL (RTYPE (litTree)))
3136 ast *tTree = litTree->left;
3137 litTree->left = tree->right;
3138 tree->right = tTree;
3144 ast *tTree = litTree->right;
3145 litTree->right = tree->right;
3146 tree->right = tTree;
3147 litTree->opval.op = '+';
3148 tree->opval.op = '-';
3151 decorateType (parent, resultType);
3155 LRVAL (tree) = RRVAL (tree) = 1;
3156 /* if the left is a pointer */
3157 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3158 TETYPE (tree) = getSpec (TTYPE (tree) =
3162 tree->left = addCast (tree->left, resultType, TRUE);
3163 tree->right = addCast (tree->right, resultType, TRUE);
3164 TETYPE (tree) = getSpec (TTYPE (tree) =
3165 computeType (LTYPE (tree),
3173 /*------------------------------------------------------------------*/
3174 /*----------------------------*/
3176 /*----------------------------*/
3177 case '-': /* can be unary */
3178 /* if right is null then unary */
3182 if (!IS_ARITHMETIC (LTYPE (tree)))
3184 werror (E_UNARY_OP, tree->opval.op);
3185 goto errorTreeReturn;
3188 /* if left is a literal then do it */
3189 if (IS_LITERAL (LTYPE (tree)))
3191 tree->type = EX_VALUE;
3192 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3194 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3195 SPEC_USIGN(TETYPE(tree)) = 0;
3199 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3203 /*------------------------------------------------------------------*/
3204 /*----------------------------*/
3206 /*----------------------------*/
3208 if (!(IS_PTR (LTYPE (tree)) ||
3209 IS_ARRAY (LTYPE (tree)) ||
3210 IS_ARITHMETIC (LTYPE (tree))))
3212 werror (E_PLUS_INVALID, "-");
3213 goto errorTreeReturn;
3216 if (!(IS_PTR (RTYPE (tree)) ||
3217 IS_ARRAY (RTYPE (tree)) ||
3218 IS_ARITHMETIC (RTYPE (tree))))
3220 werror (E_PLUS_INVALID, "-");
3221 goto errorTreeReturn;
3224 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3225 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3226 IS_INTEGRAL (RTYPE (tree))))
3228 werror (E_PLUS_INVALID, "-");
3229 goto errorTreeReturn;
3232 /* if they are both literal then */
3233 /* rewrite the tree */
3234 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3236 tree->type = EX_VALUE;
3237 tree->left = addCast (tree->left, resultType, TRUE);
3238 tree->right = addCast (tree->right, resultType, TRUE);
3239 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3240 valFromType (RETYPE (tree)));
3241 tree->right = tree->left = NULL;
3242 TETYPE (tree) = getSpec (TTYPE (tree) =
3243 tree->opval.val->type);
3247 /* if the left & right are equal then zero */
3248 if (isAstEqual (tree->left, tree->right))
3250 tree->type = EX_VALUE;
3251 tree->left = tree->right = NULL;
3252 tree->opval.val = constVal ("0");
3253 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3257 /* if both of them are pointers or arrays then */
3258 /* the result is going to be an integer */
3259 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3260 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3261 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3263 /* if only the left is a pointer */
3264 /* then result is a pointer */
3265 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3266 TETYPE (tree) = getSpec (TTYPE (tree) =
3270 tree->left = addCast (tree->left, resultType, TRUE);
3271 tree->right = addCast (tree->right, resultType, TRUE);
3273 TETYPE (tree) = getSpec (TTYPE (tree) =
3274 computeType (LTYPE (tree),
3280 LRVAL (tree) = RRVAL (tree) = 1;
3282 /* if right is a literal and */
3283 /* left is also an addition/subtraction with a literal then */
3284 /* rearrange the tree */
3285 if (IS_LITERAL (RTYPE (tree))
3286 /* avoid infinite loop */
3287 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3289 ast *litTree, *litParent;
3290 litTree = searchLitOp (tree, &litParent, "+-");
3293 if (litTree->opval.op == '+')
3297 ast *tTree = litTree->left;
3298 litTree->left = litTree->right;
3299 litTree->right = tree->right;
3300 tree->right = tTree;
3301 tree->opval.op = '+';
3302 litTree->opval.op = '-';
3304 else if (litTree->opval.op == '-')
3306 if (IS_LITERAL (RTYPE (litTree)))
3310 ast *tTree = litTree->left;
3311 litTree->left = tree->right;
3312 tree->right = litParent->left;
3313 litParent->left = tTree;
3314 litTree->opval.op = '+';
3316 tree->decorated = 0;
3317 decorateType (tree, resultType);
3323 ast *tTree = litTree->right;
3324 litTree->right = tree->right;
3325 tree->right = tTree;
3328 decorateType (litParent, resultType);
3333 /*------------------------------------------------------------------*/
3334 /*----------------------------*/
3336 /*----------------------------*/
3338 /* can be only integral type */
3339 if (!IS_INTEGRAL (LTYPE (tree)))
3341 werror (E_UNARY_OP, tree->opval.op);
3342 goto errorTreeReturn;
3345 /* if left is a literal then do it */
3346 if (IS_LITERAL (LTYPE (tree)))
3348 tree->type = EX_VALUE;
3349 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3351 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3352 return addCast (tree, resultType, TRUE);
3354 tree->left = addCast (tree->left, resultType, TRUE);
3356 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3359 /*------------------------------------------------------------------*/
3360 /*----------------------------*/
3362 /*----------------------------*/
3364 /* can be pointer */
3365 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3366 !IS_PTR (LTYPE (tree)) &&
3367 !IS_ARRAY (LTYPE (tree)))
3369 werror (E_UNARY_OP, tree->opval.op);
3370 goto errorTreeReturn;
3373 /* if left is a literal then do it */
3374 if (IS_LITERAL (LTYPE (tree)))
3376 tree->type = EX_VALUE;
3377 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3379 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3383 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3386 /*------------------------------------------------------------------*/
3387 /*----------------------------*/
3389 /*----------------------------*/
3393 TTYPE (tree) = LTYPE (tree);
3394 TETYPE (tree) = LETYPE (tree);
3398 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3403 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3405 werror (E_SHIFT_OP_INVALID);
3406 werror (W_CONTINUE, "left & right types are ");
3407 printTypeChain (LTYPE (tree), stderr);
3408 fprintf (stderr, ",");
3409 printTypeChain (RTYPE (tree), stderr);
3410 fprintf (stderr, "\n");
3411 goto errorTreeReturn;
3414 /* make smaller type only if it's a LEFT_OP */
3415 if (tree->opval.op == LEFT_OP)
3416 tree->left = addCast (tree->left, resultType, TRUE);
3418 /* if they are both literal then */
3419 /* rewrite the tree */
3420 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3422 tree->type = EX_VALUE;
3423 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3424 valFromType (RETYPE (tree)),
3425 (tree->opval.op == LEFT_OP ? 1 : 0));
3426 tree->right = tree->left = NULL;
3427 TETYPE (tree) = getSpec (TTYPE (tree) =
3428 tree->opval.val->type);
3432 LRVAL (tree) = RRVAL (tree) = 1;
3433 if (tree->opval.op == LEFT_OP)
3435 TETYPE (tree) = getSpec (TTYPE (tree) =
3436 computeType (LTYPE (tree),
3443 /* no promotion necessary */
3444 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3445 if (IS_LITERAL (TTYPE (tree)))
3446 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3449 /* if only the right side is a literal & we are
3450 shifting more than size of the left operand then zero */
3451 if (IS_LITERAL (RTYPE (tree)) &&
3452 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3453 (getSize (TETYPE (tree)) * 8))
3455 if (tree->opval.op==LEFT_OP ||
3456 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3458 lineno=tree->lineno;
3459 werror (W_SHIFT_CHANGED,
3460 (tree->opval.op == LEFT_OP ? "left" : "right"));
3461 tree->type = EX_VALUE;
3462 tree->left = tree->right = NULL;
3463 tree->opval.val = constVal ("0");
3464 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3471 /*------------------------------------------------------------------*/
3472 /*----------------------------*/
3474 /*----------------------------*/
3475 case CAST: /* change the type */
3476 /* cannot cast to an aggregate type */
3477 if (IS_AGGREGATE (LTYPE (tree)))
3479 werror (E_CAST_ILLEGAL);
3480 goto errorTreeReturn;
3483 /* make sure the type is complete and sane */
3484 changePointer(LTYPE(tree));
3485 checkTypeSanity(LETYPE(tree), "(cast)");
3487 /* If code memory is read only, then pointers to code memory */
3488 /* implicitly point to constants -- make this explicit */
3490 sym_link *t = LTYPE(tree);
3491 while (t && t->next)
3493 if (IS_CODEPTR(t) && port->mem.code_ro)
3495 if (IS_SPEC(t->next))
3496 SPEC_CONST (t->next) = 1;
3498 DCL_PTR_CONST (t->next) = 1;
3505 /* if the right is a literal replace the tree */
3506 if (IS_LITERAL (RETYPE (tree))) {
3507 if (!IS_PTR (LTYPE (tree))) {
3508 tree->type = EX_VALUE;
3510 valCastLiteral (LTYPE (tree),
3511 floatFromVal (valFromType (RETYPE (tree))));
3514 TTYPE (tree) = tree->opval.val->type;
3515 tree->values.literalFromCast = 1;
3516 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3517 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3518 sym_link *rest = LTYPE(tree)->next;
3519 werror(W_LITERAL_GENERIC);
3520 TTYPE(tree) = newLink(DECLARATOR);
3521 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3522 TTYPE(tree)->next = rest;
3523 tree->left->opval.lnk = TTYPE(tree);
3526 TTYPE (tree) = LTYPE (tree);
3530 TTYPE (tree) = LTYPE (tree);
3534 #if 0 // this is already checked, now this could be explicit
3535 /* if pointer to struct then check names */
3536 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3537 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3538 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3540 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3541 SPEC_STRUCT(LETYPE(tree))->tag);
3544 if (IS_ADDRESS_OF_OP(tree->right)
3545 && IS_AST_SYM_VALUE (tree->right->left)
3546 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3548 tree->type = EX_VALUE;
3550 valCastLiteral (LTYPE (tree),
3551 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3552 TTYPE (tree) = tree->opval.val->type;
3553 TETYPE (tree) = getSpec (TTYPE (tree));
3556 tree->values.literalFromCast = 1;
3560 /* handle offsetof macro: */
3561 /* #define offsetof(TYPE, MEMBER) \ */
3562 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3563 if (IS_ADDRESS_OF_OP(tree->right)
3564 && IS_AST_OP (tree->right->left)
3565 && tree->right->left->opval.op == PTR_OP
3566 && IS_AST_OP (tree->right->left->left)
3567 && tree->right->left->left->opval.op == CAST
3568 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3570 symbol *element = getStructElement (
3571 SPEC_STRUCT (LETYPE(tree->right->left)),
3572 AST_SYMBOL(tree->right->left->right)
3576 tree->type = EX_VALUE;
3577 tree->opval.val = valCastLiteral (
3580 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3583 TTYPE (tree) = tree->opval.val->type;
3584 TETYPE (tree) = getSpec (TTYPE (tree));
3591 /* if the right is a literal replace the tree */
3592 if (IS_LITERAL (RETYPE (tree))) {
3594 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3595 /* rewrite (type *)litaddr
3597 and define type at litaddr temp
3598 (but only if type's storage class is not generic)
3600 ast *newTree = newNode ('&', NULL, NULL);
3603 TTYPE (newTree) = LTYPE (tree);
3604 TETYPE (newTree) = getSpec(LTYPE (tree));
3606 /* define a global symbol at the casted address*/
3607 sym = newSymbol(genSymName (0), 0);
3608 sym->type = LTYPE (tree)->next;
3610 sym->type = newLink (V_VOID);
3611 sym->etype = getSpec(sym->type);
3612 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3613 sym->lineDef = tree->lineno;
3616 SPEC_STAT (sym->etype) = 1;
3617 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3618 SPEC_ABSA(sym->etype) = 1;
3619 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3622 newTree->left = newAst_VALUE(symbolVal(sym));
3623 newTree->left->lineno = tree->lineno;
3624 LTYPE (newTree) = sym->type;
3625 LETYPE (newTree) = sym->etype;
3626 LLVAL (newTree) = 1;
3627 LRVAL (newTree) = 0;
3628 TLVAL (newTree) = 1;
3632 if (!IS_PTR (LTYPE (tree))) {
3633 tree->type = EX_VALUE;
3635 valCastLiteral (LTYPE (tree),
3636 floatFromVal (valFromType (RTYPE (tree))));
3637 TTYPE (tree) = tree->opval.val->type;
3640 tree->values.literalFromCast = 1;
3641 TETYPE (tree) = getSpec (TTYPE (tree));
3645 TTYPE (tree) = LTYPE (tree);
3649 TETYPE (tree) = getSpec (TTYPE (tree));
3653 /*------------------------------------------------------------------*/
3654 /*----------------------------*/
3655 /* logical &&, || */
3656 /*----------------------------*/
3659 /* each must be arithmetic type or be a pointer */
3660 if (!IS_PTR (LTYPE (tree)) &&
3661 !IS_ARRAY (LTYPE (tree)) &&
3662 !IS_INTEGRAL (LTYPE (tree)))
3664 werror (E_COMPARE_OP);
3665 goto errorTreeReturn;
3668 if (!IS_PTR (RTYPE (tree)) &&
3669 !IS_ARRAY (RTYPE (tree)) &&
3670 !IS_INTEGRAL (RTYPE (tree)))
3672 werror (E_COMPARE_OP);
3673 goto errorTreeReturn;
3675 /* if they are both literal then */
3676 /* rewrite the tree */
3677 if (IS_LITERAL (RTYPE (tree)) &&
3678 IS_LITERAL (LTYPE (tree)))
3680 tree->type = EX_VALUE;
3681 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3682 valFromType (RTYPE (tree)),
3684 tree->right = tree->left = NULL;
3685 TETYPE (tree) = getSpec (TTYPE (tree) =
3686 tree->opval.val->type);
3689 LRVAL (tree) = RRVAL (tree) = 1;
3690 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3693 /*------------------------------------------------------------------*/
3694 /*----------------------------*/
3695 /* comparison operators */
3696 /*----------------------------*/
3704 ast *lt = optimizeCompare (tree);
3710 /* if they are pointers they must be castable */
3711 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3713 if (tree->opval.op==EQ_OP &&
3714 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3715 // we cannot cast a gptr to a !gptr: switch the leaves
3716 struct ast *s=tree->left;
3717 tree->left=tree->right;
3720 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3722 werror (E_COMPARE_OP);
3723 fprintf (stderr, "comparing type ");
3724 printTypeChain (LTYPE (tree), stderr);
3725 fprintf (stderr, "to type ");
3726 printTypeChain (RTYPE (tree), stderr);
3727 fprintf (stderr, "\n");
3728 goto errorTreeReturn;
3731 /* else they should be promotable to one another */
3734 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3735 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3737 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3739 werror (E_COMPARE_OP);
3740 fprintf (stderr, "comparing type ");
3741 printTypeChain (LTYPE (tree), stderr);
3742 fprintf (stderr, "to type ");
3743 printTypeChain (RTYPE (tree), stderr);
3744 fprintf (stderr, "\n");
3745 goto errorTreeReturn;
3748 /* if unsigned value < 0 then always false */
3749 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3750 if (SPEC_USIGN(LETYPE(tree)) &&
3751 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3752 IS_LITERAL(RTYPE(tree)) &&
3753 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3755 if (tree->opval.op == '<')
3759 if (tree->opval.op == '>')
3761 if (resultType == RESULT_TYPE_IFX)
3763 /* the parent is an ifx: */
3764 /* if (unsigned value) */
3768 /* (unsigned value) ? 1 : 0 */
3769 tree->opval.op = '?';
3770 tree->right = newNode (':',
3771 newAst_VALUE (constVal ("1")),
3772 tree->right); /* val 0 */
3773 tree->right->lineno = tree->lineno;
3774 tree->right->left->lineno = tree->lineno;
3775 decorateType (tree->right, RESULT_TYPE_NONE);
3778 /* if they are both literal then */
3779 /* rewrite the tree */
3780 if (IS_LITERAL (RTYPE (tree)) &&
3781 IS_LITERAL (LTYPE (tree)))
3783 tree->type = EX_VALUE;
3784 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3785 valFromType (RETYPE (tree)),
3787 tree->right = tree->left = NULL;
3788 TETYPE (tree) = getSpec (TTYPE (tree) =
3789 tree->opval.val->type);
3792 LRVAL (tree) = RRVAL (tree) = 1;
3793 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3796 /*------------------------------------------------------------------*/
3797 /*----------------------------*/
3799 /*----------------------------*/
3800 case SIZEOF: /* evaluate wihout code generation */
3801 /* change the type to a integer */
3803 int size = getSize (tree->right->ftype);
3804 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3805 if (!size && !IS_VOID(tree->right->ftype))
3806 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3808 tree->type = EX_VALUE;
3809 tree->opval.val = constVal (buffer);
3810 tree->right = tree->left = NULL;
3811 TETYPE (tree) = getSpec (TTYPE (tree) =
3812 tree->opval.val->type);
3815 /*------------------------------------------------------------------*/
3816 /*----------------------------*/
3818 /*----------------------------*/
3820 /* return typeof enum value */
3821 tree->type = EX_VALUE;
3824 if (IS_SPEC(tree->right->ftype)) {
3825 switch (SPEC_NOUN(tree->right->ftype)) {
3827 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3828 else typeofv = TYPEOF_INT;
3831 typeofv = TYPEOF_FLOAT;
3834 typeofv = TYPEOF_CHAR;
3837 typeofv = TYPEOF_VOID;
3840 typeofv = TYPEOF_STRUCT;
3843 typeofv = TYPEOF_BITFIELD;
3846 typeofv = TYPEOF_BIT;
3849 typeofv = TYPEOF_SBIT;
3855 switch (DCL_TYPE(tree->right->ftype)) {
3857 typeofv = TYPEOF_POINTER;
3860 typeofv = TYPEOF_FPOINTER;
3863 typeofv = TYPEOF_CPOINTER;
3866 typeofv = TYPEOF_GPOINTER;
3869 typeofv = TYPEOF_PPOINTER;
3872 typeofv = TYPEOF_IPOINTER;
3875 typeofv = TYPEOF_ARRAY;
3878 typeofv = TYPEOF_FUNCTION;
3884 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3885 tree->opval.val = constVal (buffer);
3886 tree->right = tree->left = NULL;
3887 TETYPE (tree) = getSpec (TTYPE (tree) =
3888 tree->opval.val->type);
3891 /*------------------------------------------------------------------*/
3892 /*----------------------------*/
3893 /* conditional operator '?' */
3894 /*----------------------------*/
3896 /* the type is value of the colon operator (on the right) */
3897 assert (IS_COLON_OP (tree->right));
3898 /* if already known then replace the tree : optimizer will do it
3899 but faster to do it here */
3900 if (IS_LITERAL (LTYPE (tree)))
3902 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3903 return decorateType (tree->right->left, resultTypeProp);
3905 return decorateType (tree->right->right, resultTypeProp);
3909 tree->right = decorateType (tree->right, resultTypeProp);
3910 TTYPE (tree) = RTYPE (tree);
3911 TETYPE (tree) = getSpec (TTYPE (tree));
3916 /* if they don't match we have a problem */
3917 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3919 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3920 goto errorTreeReturn;
3923 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3924 resultType, tree->opval.op);
3925 TETYPE (tree) = getSpec (TTYPE (tree));
3929 #if 0 // assignment operators are converted by the parser
3930 /*------------------------------------------------------------------*/
3931 /*----------------------------*/
3932 /* assignment operators */
3933 /*----------------------------*/
3936 /* for these it must be both must be integral */
3937 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3938 !IS_ARITHMETIC (RTYPE (tree)))
3940 werror (E_OPS_INTEGRAL);
3941 goto errorTreeReturn;
3944 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3946 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3947 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3951 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3952 goto errorTreeReturn;
3963 /* for these it must be both must be integral */
3964 if (!IS_INTEGRAL (LTYPE (tree)) ||
3965 !IS_INTEGRAL (RTYPE (tree)))
3967 werror (E_OPS_INTEGRAL);
3968 goto errorTreeReturn;
3971 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3973 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3974 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3978 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3979 goto errorTreeReturn;
3985 /*------------------------------------------------------------------*/
3986 /*----------------------------*/
3988 /*----------------------------*/
3990 if (!(IS_PTR (LTYPE (tree)) ||
3991 IS_ARITHMETIC (LTYPE (tree))))
3993 werror (E_PLUS_INVALID, "-=");
3994 goto errorTreeReturn;
3997 if (!(IS_PTR (RTYPE (tree)) ||
3998 IS_ARITHMETIC (RTYPE (tree))))
4000 werror (E_PLUS_INVALID, "-=");
4001 goto errorTreeReturn;
4004 TETYPE (tree) = getSpec (TTYPE (tree) =
4005 computeType (LTYPE (tree),
4010 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4011 werror (E_CODE_WRITE, "-=");
4015 werror (E_LVALUE_REQUIRED, "-=");
4016 goto errorTreeReturn;
4022 /*------------------------------------------------------------------*/
4023 /*----------------------------*/
4025 /*----------------------------*/
4027 /* this is not a unary operation */
4028 /* if both pointers then problem */
4029 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4031 werror (E_PTR_PLUS_PTR);
4032 goto errorTreeReturn;
4035 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4037 werror (E_PLUS_INVALID, "+=");
4038 goto errorTreeReturn;
4041 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4043 werror (E_PLUS_INVALID, "+=");
4044 goto errorTreeReturn;
4047 TETYPE (tree) = getSpec (TTYPE (tree) =
4048 computeType (LTYPE (tree),
4053 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4054 werror (E_CODE_WRITE, "+=");
4058 werror (E_LVALUE_REQUIRED, "+=");
4059 goto errorTreeReturn;
4062 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4063 tree->opval.op = '=';
4068 /*------------------------------------------------------------------*/
4069 /*----------------------------*/
4070 /* straight assignemnt */
4071 /*----------------------------*/
4073 /* cannot be an aggregate */
4074 if (IS_AGGREGATE (LTYPE (tree)))
4076 werror (E_AGGR_ASSIGN);
4077 goto errorTreeReturn;
4080 /* they should either match or be castable */
4081 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4083 werror (E_TYPE_MISMATCH, "assignment", " ");
4084 printFromToType(RTYPE(tree),LTYPE(tree));
4087 /* if the left side of the tree is of type void
4088 then report error */
4089 if (IS_VOID (LTYPE (tree)))
4091 werror (E_CAST_ZERO);
4092 printFromToType(RTYPE(tree), LTYPE(tree));
4095 TETYPE (tree) = getSpec (TTYPE (tree) =
4099 if (!tree->initMode ) {
4100 if (IS_CONSTANT(LTYPE(tree)))
4101 werror (E_CODE_WRITE, "=");
4105 werror (E_LVALUE_REQUIRED, "=");
4106 goto errorTreeReturn;
4111 /*------------------------------------------------------------------*/
4112 /*----------------------------*/
4113 /* comma operator */
4114 /*----------------------------*/
4116 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4119 /*------------------------------------------------------------------*/
4120 /*----------------------------*/
4122 /*----------------------------*/
4125 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4126 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4128 if (tree->left->opval.op == '*' && !tree->left->right)
4129 tree->left = tree->left->left;
4132 /* require a function or pointer to function */
4133 if (!IS_FUNC (LTYPE (tree))
4134 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4136 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4137 goto errorTreeReturn;
4140 /* if there are parms, make sure that
4141 parms are decorate / process / reverse only once */
4143 !tree->right->decorated)
4148 if (IS_CODEPTR(LTYPE(tree)))
4149 functype = LTYPE (tree)->next;
4151 functype = LTYPE (tree);
4153 if (processParms (tree->left, FUNC_ARGS(functype),
4154 &tree->right, &parmNumber, TRUE))
4156 goto errorTreeReturn;
4159 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4160 !IFFUNC_ISBUILTIN(functype))
4162 reverseParms (tree->right);
4165 TTYPE (tree) = functype->next;
4166 TETYPE (tree) = getSpec (TTYPE (tree));
4170 /*------------------------------------------------------------------*/
4171 /*----------------------------*/
4172 /* return statement */
4173 /*----------------------------*/
4178 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4180 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4181 printFromToType (RTYPE(tree), currFunc->type->next);
4182 goto errorTreeReturn;
4185 if (IS_VOID (currFunc->type->next)
4187 !IS_VOID (RTYPE (tree)))
4189 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4190 goto errorTreeReturn;
4193 /* if there is going to be a casting required then add it */
4194 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4197 decorateType (newNode (CAST,
4198 newAst_LINK (copyLinkChain (currFunc->type->next)),
4208 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4210 werror (W_VOID_FUNC, currFunc->name);
4211 goto errorTreeReturn;
4214 TTYPE (tree) = TETYPE (tree) = NULL;
4217 /*------------------------------------------------------------------*/
4218 /*----------------------------*/
4219 /* switch statement */
4220 /*----------------------------*/
4222 /* the switch value must be an integer */
4223 if (!IS_INTEGRAL (LTYPE (tree)))
4225 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4226 goto errorTreeReturn;
4229 TTYPE (tree) = TETYPE (tree) = NULL;
4232 /*------------------------------------------------------------------*/
4233 /*----------------------------*/
4235 /*----------------------------*/
4237 tree->left = backPatchLabels (tree->left,
4240 TTYPE (tree) = TETYPE (tree) = NULL;
4243 /*------------------------------------------------------------------*/
4244 /*----------------------------*/
4246 /*----------------------------*/
4249 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4250 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4251 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4253 /* if the for loop is reversible then
4254 reverse it otherwise do what we normally
4260 if (isLoopReversible (tree, &sym, &init, &end))
4261 return reverseLoop (tree, sym, init, end);
4263 return decorateType (createFor (AST_FOR (tree, trueLabel),
4264 AST_FOR (tree, continueLabel),
4265 AST_FOR (tree, falseLabel),
4266 AST_FOR (tree, condLabel),
4267 AST_FOR (tree, initExpr),
4268 AST_FOR (tree, condExpr),
4269 AST_FOR (tree, loopExpr),
4270 tree->left), RESULT_TYPE_NONE);
4273 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4274 "node PARAM shouldn't be processed here");
4275 /* but in processParams() */
4278 TTYPE (tree) = TETYPE (tree) = NULL;
4282 /* some error found this tree will be killed */
4284 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4285 tree->opval.op = NULLOP;
4291 /*-----------------------------------------------------------------*/
4292 /* sizeofOp - processes size of operation */
4293 /*-----------------------------------------------------------------*/
4295 sizeofOp (sym_link * type)
4300 /* make sure the type is complete and sane */
4301 checkTypeSanity(type, "(sizeof)");
4303 /* get the size and convert it to character */
4304 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4305 if (!size && !IS_VOID(type))
4306 werror (E_SIZEOF_INCOMPLETE_TYPE);
4308 /* now convert into value */
4309 return constVal (buff);
4313 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4314 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4315 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4316 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4317 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4318 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4319 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4321 /*-----------------------------------------------------------------*/
4322 /* backPatchLabels - change and or not operators to flow control */
4323 /*-----------------------------------------------------------------*/
4325 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4331 if (!(IS_ANDORNOT (tree)))
4334 /* if this an and */
4337 static int localLbl = 0;
4340 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4341 localLabel = newSymbol (buffer, NestLevel);
4343 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4345 /* if left is already a IFX then just change the if true label in that */
4346 if (!IS_IFX (tree->left))
4347 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4349 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4350 /* right is a IFX then just join */
4351 if (IS_IFX (tree->right))
4352 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4354 tree->right = createLabel (localLabel, tree->right);
4355 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4357 return newNode (NULLOP, tree->left, tree->right);
4360 /* if this is an or operation */
4363 static int localLbl = 0;
4366 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4367 localLabel = newSymbol (buffer, NestLevel);
4369 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4371 /* if left is already a IFX then just change the if true label in that */
4372 if (!IS_IFX (tree->left))
4373 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4375 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4376 /* right is a IFX then just join */
4377 if (IS_IFX (tree->right))
4378 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4380 tree->right = createLabel (localLabel, tree->right);
4381 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4383 return newNode (NULLOP, tree->left, tree->right);
4389 int wasnot = IS_NOT (tree->left);
4390 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4392 /* if the left is already a IFX */
4393 if (!IS_IFX (tree->left))
4394 tree->left = newNode (IFX, tree->left, NULL);
4398 tree->left->trueLabel = trueLabel;
4399 tree->left->falseLabel = falseLabel;
4403 tree->left->trueLabel = falseLabel;
4404 tree->left->falseLabel = trueLabel;
4411 tree->trueLabel = trueLabel;
4412 tree->falseLabel = falseLabel;
4419 /*-----------------------------------------------------------------*/
4420 /* createBlock - create expression tree for block */
4421 /*-----------------------------------------------------------------*/
4423 createBlock (symbol * decl, ast * body)
4427 /* if the block has nothing */
4431 ex = newNode (BLOCK, NULL, body);
4432 ex->values.sym = decl;
4439 /*-----------------------------------------------------------------*/
4440 /* createLabel - creates the expression tree for labels */
4441 /*-----------------------------------------------------------------*/
4443 createLabel (symbol * label, ast * stmnt)
4446 char name[SDCC_NAME_MAX + 1];
4449 /* must create fresh symbol if the symbol name */
4450 /* exists in the symbol table, since there can */
4451 /* be a variable with the same name as the labl */
4452 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4453 (csym->level == label->level))
4454 label = newSymbol (label->name, label->level);
4456 /* change the name before putting it in add _ */
4457 SNPRINTF(name, sizeof(name), "%s", label->name);
4459 /* put the label in the LabelSymbol table */
4460 /* but first check if a label of the same */
4462 if ((csym = findSym (LabelTab, NULL, name)))
4463 werror (E_DUPLICATE_LABEL, label->name);
4465 addSym (LabelTab, label, name, label->level, 0, 0);
4469 label->key = labelKey++;
4470 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4476 /*-----------------------------------------------------------------*/
4477 /* createCase - generates the parsetree for a case statement */
4478 /*-----------------------------------------------------------------*/
4480 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4482 char caseLbl[SDCC_NAME_MAX + 1];
4486 /* if the switch statement does not exist */
4487 /* then case is out of context */
4490 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4494 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4495 /* if not a constant then error */
4496 if (!IS_LITERAL (caseVal->ftype))
4498 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4502 /* if not a integer than error */
4503 if (!IS_INTEGRAL (caseVal->ftype))
4505 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4509 /* find the end of the switch values chain */
4510 if (!(val = swStat->values.switchVals.swVals))
4511 swStat->values.switchVals.swVals = caseVal->opval.val;
4514 /* also order the cases according to value */
4516 int cVal = (int) floatFromVal (caseVal->opval.val);
4517 while (val && (int) floatFromVal (val) < cVal)
4523 /* if we reached the end then */
4526 pval->next = caseVal->opval.val;
4528 else if ((int) floatFromVal (val) == cVal)
4530 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4536 /* we found a value greater than */
4537 /* the current value we must add this */
4538 /* before the value */
4539 caseVal->opval.val->next = val;
4541 /* if this was the first in chain */
4542 if (swStat->values.switchVals.swVals == val)
4543 swStat->values.switchVals.swVals =
4546 pval->next = caseVal->opval.val;
4551 /* create the case label */
4552 SNPRINTF(caseLbl, sizeof(caseLbl),
4554 swStat->values.switchVals.swNum,
4555 (int) floatFromVal (caseVal->opval.val));
4557 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4562 /*-----------------------------------------------------------------*/
4563 /* createDefault - creates the parse tree for the default statement */
4564 /*-----------------------------------------------------------------*/
4566 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4568 char defLbl[SDCC_NAME_MAX + 1];
4570 /* if the switch statement does not exist */
4571 /* then case is out of context */
4574 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4578 if (swStat->values.switchVals.swDefault)
4580 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4585 /* turn on the default flag */
4586 swStat->values.switchVals.swDefault = 1;
4588 /* create the label */
4589 SNPRINTF (defLbl, sizeof(defLbl),
4590 "_default_%d", swStat->values.switchVals.swNum);
4591 return createLabel (newSymbol (defLbl, 0), stmnt);
4594 /*-----------------------------------------------------------------*/
4595 /* createIf - creates the parsetree for the if statement */
4596 /*-----------------------------------------------------------------*/
4598 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4600 static int Lblnum = 0;
4602 symbol *ifTrue, *ifFalse, *ifEnd;
4604 /* if neither exists */
4605 if (!elseBody && !ifBody) {
4606 // if there are no side effects (i++, j() etc)
4607 if (!hasSEFcalls(condAst)) {
4612 /* create the labels */
4613 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4614 ifFalse = newSymbol (buffer, NestLevel);
4615 /* if no else body then end == false */
4620 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4621 ifEnd = newSymbol (buffer, NestLevel);
4624 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4625 ifTrue = newSymbol (buffer, NestLevel);
4629 /* attach the ifTrue label to the top of it body */
4630 ifBody = createLabel (ifTrue, ifBody);
4631 /* attach a goto end to the ifBody if else is present */
4634 ifBody = newNode (NULLOP, ifBody,
4636 newAst_VALUE (symbolVal (ifEnd)),
4638 /* put the elseLabel on the else body */
4639 elseBody = createLabel (ifFalse, elseBody);
4640 /* out the end at the end of the body */
4641 elseBody = newNode (NULLOP,
4643 createLabel (ifEnd, NULL));
4647 ifBody = newNode (NULLOP, ifBody,
4648 createLabel (ifFalse, NULL));
4650 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4651 if (IS_IFX (condAst))
4654 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4656 return newNode (NULLOP, ifTree,
4657 newNode (NULLOP, ifBody, elseBody));
4661 /*-----------------------------------------------------------------*/
4662 /* createDo - creates parse tree for do */
4665 /* _docontinue_n: */
4666 /* condition_expression +-> trueLabel -> _dobody_n */
4668 /* +-> falseLabel-> _dobreak_n */
4670 /*-----------------------------------------------------------------*/
4672 createDo (symbol * trueLabel, symbol * continueLabel,
4673 symbol * falseLabel, ast * condAst, ast * doBody)
4678 /* if the body does not exist then it is simple */
4681 condAst = backPatchLabels (condAst, continueLabel, NULL);
4682 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4683 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4684 doTree->trueLabel = continueLabel;
4685 doTree->falseLabel = NULL;
4689 /* otherwise we have a body */
4690 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4692 /* attach the body label to the top */
4693 doBody = createLabel (trueLabel, doBody);
4694 /* attach the continue label to end of body */
4695 doBody = newNode (NULLOP, doBody,
4696 createLabel (continueLabel, NULL));
4698 /* now put the break label at the end */
4699 if (IS_IFX (condAst))
4702 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4704 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4706 /* putting it together */
4707 return newNode (NULLOP, doBody, doTree);
4710 /*-----------------------------------------------------------------*/
4711 /* createFor - creates parse tree for 'for' statement */
4714 /* condExpr +-> trueLabel -> _forbody_n */
4716 /* +-> falseLabel-> _forbreak_n */
4719 /* _forcontinue_n: */
4721 /* goto _forcond_n ; */
4723 /*-----------------------------------------------------------------*/
4725 createFor (symbol * trueLabel, symbol * continueLabel,
4726 symbol * falseLabel, symbol * condLabel,
4727 ast * initExpr, ast * condExpr, ast * loopExpr,
4732 /* if loopexpression not present then we can generate it */
4733 /* the same way as a while */
4735 return newNode (NULLOP, initExpr,
4736 createWhile (trueLabel, continueLabel,
4737 falseLabel, condExpr, forBody));
4738 /* vanilla for statement */
4739 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4741 if (condExpr && !IS_IFX (condExpr))
4742 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4745 /* attach condition label to condition */
4746 condExpr = createLabel (condLabel, condExpr);
4748 /* attach body label to body */
4749 forBody = createLabel (trueLabel, forBody);
4751 /* attach continue to forLoop expression & attach */
4752 /* goto the forcond @ and of loopExpression */
4753 loopExpr = createLabel (continueLabel,
4757 newAst_VALUE (symbolVal (condLabel)),
4759 /* now start putting them together */
4760 forTree = newNode (NULLOP, initExpr, condExpr);
4761 forTree = newNode (NULLOP, forTree, forBody);
4762 forTree = newNode (NULLOP, forTree, loopExpr);
4763 /* finally add the break label */
4764 forTree = newNode (NULLOP, forTree,
4765 createLabel (falseLabel, NULL));
4769 /*-----------------------------------------------------------------*/
4770 /* createWhile - creates parse tree for while statement */
4771 /* the while statement will be created as follows */
4773 /* _while_continue_n: */
4774 /* condition_expression +-> trueLabel -> _while_boby_n */
4776 /* +-> falseLabel -> _while_break_n */
4777 /* _while_body_n: */
4779 /* goto _while_continue_n */
4780 /* _while_break_n: */
4781 /*-----------------------------------------------------------------*/
4783 createWhile (symbol * trueLabel, symbol * continueLabel,
4784 symbol * falseLabel, ast * condExpr, ast * whileBody)
4788 /* put the continue label */
4789 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4790 condExpr = createLabel (continueLabel, condExpr);
4791 condExpr->lineno = 0;
4793 /* put the body label in front of the body */
4794 whileBody = createLabel (trueLabel, whileBody);
4795 whileBody->lineno = 0;
4796 /* put a jump to continue at the end of the body */
4797 /* and put break label at the end of the body */
4798 whileBody = newNode (NULLOP,
4801 newAst_VALUE (symbolVal (continueLabel)),
4802 createLabel (falseLabel, NULL)));
4804 /* put it all together */
4805 if (IS_IFX (condExpr))
4806 whileTree = condExpr;
4809 whileTree = newNode (IFX, condExpr, NULL);
4810 /* put the true & false labels in place */
4811 whileTree->trueLabel = trueLabel;
4812 whileTree->falseLabel = falseLabel;
4815 return newNode (NULLOP, whileTree, whileBody);
4818 /*-----------------------------------------------------------------*/
4819 /* optimizeGetHbit - get highest order bit of the expression */
4820 /*-----------------------------------------------------------------*/
4822 optimizeGetHbit (ast * tree)
4825 /* if this is not a bit and */
4826 if (!IS_BITAND (tree))
4829 /* will look for tree of the form
4830 ( expr >> ((sizeof expr) -1) ) & 1 */
4831 if (!IS_AST_LIT_VALUE (tree->right))
4834 if (AST_LIT_VALUE (tree->right) != 1)
4837 if (!IS_RIGHT_OP (tree->left))
4840 if (!IS_AST_LIT_VALUE (tree->left->right))
4843 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4844 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4847 /* make sure the port supports GETHBIT */
4848 if (port->hasExtBitOp
4849 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4852 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_TYPE_NONE);
4856 /*-----------------------------------------------------------------*/
4857 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4858 /*-----------------------------------------------------------------*/
4860 optimizeRRCRLC (ast * root)
4862 /* will look for trees of the form
4863 (?expr << 1) | (?expr >> 7) or
4864 (?expr >> 7) | (?expr << 1) will make that
4865 into a RLC : operation ..
4867 (?expr >> 1) | (?expr << 7) or
4868 (?expr << 7) | (?expr >> 1) will make that
4869 into a RRC operation
4870 note : by 7 I mean (number of bits required to hold the
4872 /* if the root operations is not a | operation the not */
4873 if (!IS_BITOR (root))
4876 /* I have to think of a better way to match patterns this sucks */
4877 /* that aside let start looking for the first case : I use a the
4878 negative check a lot to improve the efficiency */
4879 /* (?expr << 1) | (?expr >> 7) */
4880 if (IS_LEFT_OP (root->left) &&
4881 IS_RIGHT_OP (root->right))
4884 if (!SPEC_USIGN (TETYPE (root->left->left)))
4887 if (!IS_AST_LIT_VALUE (root->left->right) ||
4888 !IS_AST_LIT_VALUE (root->right->right))
4891 /* make sure it is the same expression */
4892 if (!isAstEqual (root->left->left,
4896 if (AST_LIT_VALUE (root->left->right) != 1)
4899 if (AST_LIT_VALUE (root->right->right) !=
4900 (getSize (TTYPE (root->left->left)) * 8 - 1))
4903 /* make sure the port supports RLC */
4904 if (port->hasExtBitOp
4905 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4908 /* whew got the first case : create the AST */
4909 return newNode (RLC, root->left->left, NULL);
4913 /* check for second case */
4914 /* (?expr >> 7) | (?expr << 1) */
4915 if (IS_LEFT_OP (root->right) &&
4916 IS_RIGHT_OP (root->left))
4919 if (!SPEC_USIGN (TETYPE (root->left->left)))
4922 if (!IS_AST_LIT_VALUE (root->left->right) ||
4923 !IS_AST_LIT_VALUE (root->right->right))
4926 /* make sure it is the same symbol */
4927 if (!isAstEqual (root->left->left,
4931 if (AST_LIT_VALUE (root->right->right) != 1)
4934 if (AST_LIT_VALUE (root->left->right) !=
4935 (getSize (TTYPE (root->left->left)) * 8 - 1))
4938 /* make sure the port supports RLC */
4939 if (port->hasExtBitOp
4940 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4943 /* whew got the first case : create the AST */
4944 return newNode (RLC, root->left->left, NULL);
4949 /* third case for RRC */
4950 /* (?symbol >> 1) | (?symbol << 7) */
4951 if (IS_LEFT_OP (root->right) &&
4952 IS_RIGHT_OP (root->left))
4955 if (!SPEC_USIGN (TETYPE (root->left->left)))
4958 if (!IS_AST_LIT_VALUE (root->left->right) ||
4959 !IS_AST_LIT_VALUE (root->right->right))
4962 /* make sure it is the same symbol */
4963 if (!isAstEqual (root->left->left,
4967 if (AST_LIT_VALUE (root->left->right) != 1)
4970 if (AST_LIT_VALUE (root->right->right) !=
4971 (getSize (TTYPE (root->left->left)) * 8 - 1))
4974 /* make sure the port supports RRC */
4975 if (port->hasExtBitOp
4976 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4979 /* whew got the first case : create the AST */
4980 return newNode (RRC, root->left->left, NULL);
4984 /* fourth and last case for now */
4985 /* (?symbol << 7) | (?symbol >> 1) */
4986 if (IS_RIGHT_OP (root->right) &&
4987 IS_LEFT_OP (root->left))
4990 if (!SPEC_USIGN (TETYPE (root->left->left)))
4993 if (!IS_AST_LIT_VALUE (root->left->right) ||
4994 !IS_AST_LIT_VALUE (root->right->right))
4997 /* make sure it is the same symbol */
4998 if (!isAstEqual (root->left->left,
5002 if (AST_LIT_VALUE (root->right->right) != 1)
5005 if (AST_LIT_VALUE (root->left->right) !=
5006 (getSize (TTYPE (root->left->left)) * 8 - 1))
5009 /* make sure the port supports RRC */
5010 if (port->hasExtBitOp
5011 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5014 /* whew got the first case : create the AST */
5015 return newNode (RRC, root->left->left, NULL);
5019 /* not found return root */
5023 /*-----------------------------------------------------------------*/
5024 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5025 /*-----------------------------------------------------------------*/
5027 optimizeSWAP (ast * root)
5029 /* will look for trees of the form
5030 (?expr << 4) | (?expr >> 4) or
5031 (?expr >> 4) | (?expr << 4) will make that
5032 into a SWAP : operation ..
5033 note : by 4 I mean (number of bits required to hold the
5035 /* if the root operations is not a | operation the not */
5036 if (!IS_BITOR (root))
5039 /* (?expr << 4) | (?expr >> 4) */
5040 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5041 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5044 if (!SPEC_USIGN (TETYPE (root->left->left)))
5047 if (!IS_AST_LIT_VALUE (root->left->right) ||
5048 !IS_AST_LIT_VALUE (root->right->right))
5051 /* make sure it is the same expression */
5052 if (!isAstEqual (root->left->left,
5056 if (AST_LIT_VALUE (root->left->right) !=
5057 (getSize (TTYPE (root->left->left)) * 4))
5060 if (AST_LIT_VALUE (root->right->right) !=
5061 (getSize (TTYPE (root->left->left)) * 4))
5064 /* make sure the port supports SWAP */
5065 if (port->hasExtBitOp
5066 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5069 /* found it : create the AST */
5070 return newNode (SWAP, root->left->left, NULL);
5074 /* not found return root */
5078 /*-----------------------------------------------------------------*/
5079 /* optimizeCompare - otimizes compares for bit variables */
5080 /*-----------------------------------------------------------------*/
5082 optimizeCompare (ast * root)
5084 ast *optExpr = NULL;
5087 unsigned int litValue;
5089 /* if nothing then return nothing */
5093 /* if not a compare op then do leaves */
5094 if (!IS_COMPARE_OP (root))
5096 root->left = optimizeCompare (root->left);
5097 root->right = optimizeCompare (root->right);
5101 /* if left & right are the same then depending
5102 of the operation do */
5103 if (isAstEqual (root->left, root->right))
5105 switch (root->opval.op)
5110 optExpr = newAst_VALUE (constVal ("0"));
5115 optExpr = newAst_VALUE (constVal ("1"));
5119 return decorateType (optExpr, RESULT_TYPE_NONE);
5122 vleft = (root->left->type == EX_VALUE ?
5123 root->left->opval.val : NULL);
5125 vright = (root->right->type == EX_VALUE ?
5126 root->right->opval.val : NULL);
5128 /* if left is a BITVAR in BITSPACE */
5129 /* and right is a LITERAL then opt- */
5130 /* imize else do nothing */
5131 if (vleft && vright &&
5132 IS_BITVAR (vleft->etype) &&
5133 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5134 IS_LITERAL (vright->etype))
5137 /* if right side > 1 then comparison may never succeed */
5138 if ((litValue = (int) floatFromVal (vright)) > 1)
5140 werror (W_BAD_COMPARE);
5146 switch (root->opval.op)
5148 case '>': /* bit value greater than 1 cannot be */
5149 werror (W_BAD_COMPARE);
5153 case '<': /* bit value < 1 means 0 */
5155 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5158 case LE_OP: /* bit value <= 1 means no check */
5159 optExpr = newAst_VALUE (vright);
5162 case GE_OP: /* bit value >= 1 means only check for = */
5164 optExpr = newAst_VALUE (vleft);
5169 { /* literal is zero */
5170 switch (root->opval.op)
5172 case '<': /* bit value < 0 cannot be */
5173 werror (W_BAD_COMPARE);
5177 case '>': /* bit value > 0 means 1 */
5179 optExpr = newAst_VALUE (vleft);
5182 case LE_OP: /* bit value <= 0 means no check */
5183 case GE_OP: /* bit value >= 0 means no check */
5184 werror (W_BAD_COMPARE);
5188 case EQ_OP: /* bit == 0 means ! of bit */
5189 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5193 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5194 } /* end-of-if of BITVAR */
5199 /*-----------------------------------------------------------------*/
5200 /* addSymToBlock : adds the symbol to the first block we find */
5201 /*-----------------------------------------------------------------*/
5203 addSymToBlock (symbol * sym, ast * tree)
5205 /* reached end of tree or a leaf */
5206 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5210 if (IS_AST_OP (tree) &&
5211 tree->opval.op == BLOCK)
5214 symbol *lsym = copySymbol (sym);
5216 lsym->next = AST_VALUES (tree, sym);
5217 AST_VALUES (tree, sym) = lsym;
5221 addSymToBlock (sym, tree->left);
5222 addSymToBlock (sym, tree->right);
5225 /*-----------------------------------------------------------------*/
5226 /* processRegParms - do processing for register parameters */
5227 /*-----------------------------------------------------------------*/
5229 processRegParms (value * args, ast * body)
5233 if (IS_REGPARM (args->etype))
5234 addSymToBlock (args->sym, body);
5239 /*-----------------------------------------------------------------*/
5240 /* resetParmKey - resets the operandkeys for the symbols */
5241 /*-----------------------------------------------------------------*/
5242 DEFSETFUNC (resetParmKey)
5253 /*-----------------------------------------------------------------*/
5254 /* createFunction - This is the key node that calls the iCode for */
5255 /* generating the code for a function. Note code */
5256 /* is generated function by function, later when */
5257 /* add inter-procedural analysis this will change */
5258 /*-----------------------------------------------------------------*/
5260 createFunction (symbol * name, ast * body)
5266 iCode *piCode = NULL;
5268 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5269 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5271 /* if check function return 0 then some problem */
5272 if (checkFunction (name, NULL) == 0)
5275 /* create a dummy block if none exists */
5277 body = newNode (BLOCK, NULL, NULL);
5281 /* check if the function name already in the symbol table */
5282 if ((csym = findSym (SymbolTab, NULL, name->name)))
5285 /* special case for compiler defined functions
5286 we need to add the name to the publics list : this
5287 actually means we are now compiling the compiler
5291 addSet (&publics, name);
5297 allocVariables (name);
5299 name->lastLine = mylineno;
5302 /* set the stack pointer */
5303 stackPtr = -port->stack.direction * port->stack.call_overhead;
5304 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5306 if (IFFUNC_ISISR (name->type))
5307 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5309 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5311 if (options.useXstack)
5312 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5314 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5317 fetype = getSpec (name->type); /* get the specifier for the function */
5318 /* if this is a reentrant function then */
5319 if (IFFUNC_ISREENT (name->type))
5322 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5324 /* do processing for parameters that are passed in registers */
5325 processRegParms (FUNC_ARGS(name->type), body);
5327 /* set the stack pointer */
5331 /* allocate & autoinit the block variables */
5332 processBlockVars (body, &stack, ALLOCATE);
5334 /* save the stack information */
5335 if (options.useXstack)
5336 name->xstack = SPEC_STAK (fetype) = stack;
5338 name->stack = SPEC_STAK (fetype) = stack;
5340 /* name needs to be mangled */
5341 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5343 body = resolveSymbols (body); /* resolve the symbols */
5344 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5347 ex = newAst_VALUE (symbolVal (name)); /* create name */
5348 ex = newNode (FUNCTION, ex, body);
5349 ex->values.args = FUNC_ARGS(name->type);
5351 if (options.dump_tree) PA(ex);
5354 werror (E_FUNC_NO_CODE, name->name);
5358 /* create the node & generate intermediate code */
5360 codeOutFile = code->oFile;
5361 piCode = iCodeFromAst (ex);
5365 werror (E_FUNC_NO_CODE, name->name);
5369 eBBlockFromiCode (piCode);
5371 /* if there are any statics then do them */
5374 GcurMemmap = statsg;
5375 codeOutFile = statsg->oFile;
5376 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5382 /* dealloc the block variables */
5383 processBlockVars (body, &stack, DEALLOCATE);
5384 outputDebugStackSymbols();
5385 /* deallocate paramaters */
5386 deallocParms (FUNC_ARGS(name->type));
5388 if (IFFUNC_ISREENT (name->type))
5391 /* we are done freeup memory & cleanup */
5393 if (port->reset_labelKey) labelKey = 1;
5395 FUNC_HASBODY(name->type) = 1;
5396 addSet (&operKeyReset, name);
5397 applyToSet (operKeyReset, resetParmKey);
5402 cleanUpLevel (LabelTab, 0);
5403 cleanUpBlock (StructTab, 1);
5404 cleanUpBlock (TypedefTab, 1);
5406 xstack->syms = NULL;
5407 istack->syms = NULL;
5412 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5413 /*-----------------------------------------------------------------*/
5414 /* ast_print : prints the ast (for debugging purposes) */
5415 /*-----------------------------------------------------------------*/
5417 void ast_print (ast * tree, FILE *outfile, int indent)
5422 /* can print only decorated trees */
5423 if (!tree->decorated) return;
5425 /* if any child is an error | this one is an error do nothing */
5426 if (tree->isError ||
5427 (tree->left && tree->left->isError) ||
5428 (tree->right && tree->right->isError)) {
5429 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5433 /* print the line */
5434 /* if not block & function */
5435 if (tree->type == EX_OP &&
5436 (tree->opval.op != FUNCTION &&
5437 tree->opval.op != BLOCK &&
5438 tree->opval.op != NULLOP)) {
5441 if (tree->opval.op == FUNCTION) {
5443 value *args=FUNC_ARGS(tree->left->opval.val->type);
5444 fprintf(outfile,"FUNCTION (%s=%p) type (",
5445 tree->left->opval.val->name, tree);
5446 printTypeChain (tree->left->opval.val->type->next,outfile);
5447 fprintf(outfile,") args (");
5450 fprintf (outfile, ", ");
5452 printTypeChain (args ? args->type : NULL, outfile);
5454 args= args ? args->next : NULL;
5456 fprintf(outfile,")\n");
5457 ast_print(tree->left,outfile,indent);
5458 ast_print(tree->right,outfile,indent);
5461 if (tree->opval.op == BLOCK) {
5462 symbol *decls = tree->values.sym;
5463 INDENT(indent,outfile);
5464 fprintf(outfile,"{\n");
5466 INDENT(indent+2,outfile);
5467 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5468 decls->name, decls);
5469 printTypeChain(decls->type,outfile);
5470 fprintf(outfile,")\n");
5472 decls = decls->next;
5474 ast_print(tree->right,outfile,indent+2);
5475 INDENT(indent,outfile);
5476 fprintf(outfile,"}\n");
5479 if (tree->opval.op == NULLOP) {
5480 ast_print(tree->left,outfile,indent);
5481 ast_print(tree->right,outfile,indent);
5484 INDENT(indent,outfile);
5486 /*------------------------------------------------------------------*/
5487 /*----------------------------*/
5488 /* leaf has been reached */
5489 /*----------------------------*/
5490 /* if this is of type value */
5491 /* just get the type */
5492 if (tree->type == EX_VALUE) {
5494 if (IS_LITERAL (tree->opval.val->etype)) {
5495 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5496 if (SPEC_USIGN (tree->opval.val->etype))
5497 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5499 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5500 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5501 floatFromVal(tree->opval.val));
5502 } else if (tree->opval.val->sym) {
5503 /* if the undefined flag is set then give error message */
5504 if (tree->opval.val->sym->undefined) {
5505 fprintf(outfile,"UNDEFINED SYMBOL ");
5507 fprintf(outfile,"SYMBOL ");
5509 fprintf(outfile,"(%s=%p)",
5510 tree->opval.val->sym->name,tree);
5513 fprintf(outfile," type (");
5514 printTypeChain(tree->ftype,outfile);
5515 fprintf(outfile,")\n");
5517 fprintf(outfile,"\n");
5522 /* if type link for the case of cast */
5523 if (tree->type == EX_LINK) {
5524 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5525 printTypeChain(tree->opval.lnk,outfile);
5526 fprintf(outfile,")\n");
5531 /* depending on type of operator do */
5533 switch (tree->opval.op) {
5534 /*------------------------------------------------------------------*/
5535 /*----------------------------*/
5537 /*----------------------------*/
5539 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5540 printTypeChain(tree->ftype,outfile);
5541 fprintf(outfile,")\n");
5542 ast_print(tree->left,outfile,indent+2);
5543 ast_print(tree->right,outfile,indent+2);
5546 /*------------------------------------------------------------------*/
5547 /*----------------------------*/
5549 /*----------------------------*/
5551 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5552 printTypeChain(tree->ftype,outfile);
5553 fprintf(outfile,")\n");
5554 ast_print(tree->left,outfile,indent+2);
5555 ast_print(tree->right,outfile,indent+2);
5558 /*------------------------------------------------------------------*/
5559 /*----------------------------*/
5560 /* struct/union pointer */
5561 /*----------------------------*/
5563 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5564 printTypeChain(tree->ftype,outfile);
5565 fprintf(outfile,")\n");
5566 ast_print(tree->left,outfile,indent+2);
5567 ast_print(tree->right,outfile,indent+2);
5570 /*------------------------------------------------------------------*/
5571 /*----------------------------*/
5572 /* ++/-- operation */
5573 /*----------------------------*/
5576 fprintf(outfile,"post-");
5578 fprintf(outfile,"pre-");
5579 fprintf(outfile,"INC_OP (%p) type (",tree);
5580 printTypeChain(tree->ftype,outfile);
5581 fprintf(outfile,")\n");
5582 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5583 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5588 fprintf(outfile,"post-");
5590 fprintf(outfile,"pre-");
5591 fprintf(outfile,"DEC_OP (%p) type (",tree);
5592 printTypeChain(tree->ftype,outfile);
5593 fprintf(outfile,")\n");
5594 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5595 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5598 /*------------------------------------------------------------------*/
5599 /*----------------------------*/
5601 /*----------------------------*/
5604 fprintf(outfile,"& (%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 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5611 printTypeChain(tree->ftype,outfile);
5612 fprintf(outfile,")\n");
5613 ast_print(tree->left,outfile,indent+2);
5614 ast_print(tree->right,outfile,indent+2);
5617 /*----------------------------*/
5619 /*----------------------------*/
5621 fprintf(outfile,"OR (%p) type (",tree);
5622 printTypeChain(tree->ftype,outfile);
5623 fprintf(outfile,")\n");
5624 ast_print(tree->left,outfile,indent+2);
5625 ast_print(tree->right,outfile,indent+2);
5627 /*------------------------------------------------------------------*/
5628 /*----------------------------*/
5630 /*----------------------------*/
5632 fprintf(outfile,"XOR (%p) type (",tree);
5633 printTypeChain(tree->ftype,outfile);
5634 fprintf(outfile,")\n");
5635 ast_print(tree->left,outfile,indent+2);
5636 ast_print(tree->right,outfile,indent+2);
5639 /*------------------------------------------------------------------*/
5640 /*----------------------------*/
5642 /*----------------------------*/
5644 fprintf(outfile,"DIV (%p) type (",tree);
5645 printTypeChain(tree->ftype,outfile);
5646 fprintf(outfile,")\n");
5647 ast_print(tree->left,outfile,indent+2);
5648 ast_print(tree->right,outfile,indent+2);
5650 /*------------------------------------------------------------------*/
5651 /*----------------------------*/
5653 /*----------------------------*/
5655 fprintf(outfile,"MOD (%p) type (",tree);
5656 printTypeChain(tree->ftype,outfile);
5657 fprintf(outfile,")\n");
5658 ast_print(tree->left,outfile,indent+2);
5659 ast_print(tree->right,outfile,indent+2);
5662 /*------------------------------------------------------------------*/
5663 /*----------------------------*/
5664 /* address dereference */
5665 /*----------------------------*/
5666 case '*': /* can be unary : if right is null then unary operation */
5668 fprintf(outfile,"DEREF (%p) type (",tree);
5669 printTypeChain(tree->ftype,outfile);
5670 fprintf(outfile,")\n");
5671 ast_print(tree->left,outfile,indent+2);
5674 /*------------------------------------------------------------------*/
5675 /*----------------------------*/
5676 /* multiplication */
5677 /*----------------------------*/
5678 fprintf(outfile,"MULT (%p) type (",tree);
5679 printTypeChain(tree->ftype,outfile);
5680 fprintf(outfile,")\n");
5681 ast_print(tree->left,outfile,indent+2);
5682 ast_print(tree->right,outfile,indent+2);
5686 /*------------------------------------------------------------------*/
5687 /*----------------------------*/
5688 /* unary '+' operator */
5689 /*----------------------------*/
5693 fprintf(outfile,"UPLUS (%p) type (",tree);
5694 printTypeChain(tree->ftype,outfile);
5695 fprintf(outfile,")\n");
5696 ast_print(tree->left,outfile,indent+2);
5698 /*------------------------------------------------------------------*/
5699 /*----------------------------*/
5701 /*----------------------------*/
5702 fprintf(outfile,"ADD (%p) type (",tree);
5703 printTypeChain(tree->ftype,outfile);
5704 fprintf(outfile,")\n");
5705 ast_print(tree->left,outfile,indent+2);
5706 ast_print(tree->right,outfile,indent+2);
5709 /*------------------------------------------------------------------*/
5710 /*----------------------------*/
5712 /*----------------------------*/
5713 case '-': /* can be unary */
5715 fprintf(outfile,"UMINUS (%p) type (",tree);
5716 printTypeChain(tree->ftype,outfile);
5717 fprintf(outfile,")\n");
5718 ast_print(tree->left,outfile,indent+2);
5720 /*------------------------------------------------------------------*/
5721 /*----------------------------*/
5723 /*----------------------------*/
5724 fprintf(outfile,"SUB (%p) type (",tree);
5725 printTypeChain(tree->ftype,outfile);
5726 fprintf(outfile,")\n");
5727 ast_print(tree->left,outfile,indent+2);
5728 ast_print(tree->right,outfile,indent+2);
5731 /*------------------------------------------------------------------*/
5732 /*----------------------------*/
5734 /*----------------------------*/
5736 fprintf(outfile,"COMPL (%p) type (",tree);
5737 printTypeChain(tree->ftype,outfile);
5738 fprintf(outfile,")\n");
5739 ast_print(tree->left,outfile,indent+2);
5741 /*------------------------------------------------------------------*/
5742 /*----------------------------*/
5744 /*----------------------------*/
5746 fprintf(outfile,"NOT (%p) type (",tree);
5747 printTypeChain(tree->ftype,outfile);
5748 fprintf(outfile,")\n");
5749 ast_print(tree->left,outfile,indent+2);
5751 /*------------------------------------------------------------------*/
5752 /*----------------------------*/
5754 /*----------------------------*/
5756 fprintf(outfile,"RRC (%p) type (",tree);
5757 printTypeChain(tree->ftype,outfile);
5758 fprintf(outfile,")\n");
5759 ast_print(tree->left,outfile,indent+2);
5763 fprintf(outfile,"RLC (%p) type (",tree);
5764 printTypeChain(tree->ftype,outfile);
5765 fprintf(outfile,")\n");
5766 ast_print(tree->left,outfile,indent+2);
5769 fprintf(outfile,"SWAP (%p) type (",tree);
5770 printTypeChain(tree->ftype,outfile);
5771 fprintf(outfile,")\n");
5772 ast_print(tree->left,outfile,indent+2);
5775 fprintf(outfile,"GETHBIT (%p) type (",tree);
5776 printTypeChain(tree->ftype,outfile);
5777 fprintf(outfile,")\n");
5778 ast_print(tree->left,outfile,indent+2);
5781 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5782 printTypeChain(tree->ftype,outfile);
5783 fprintf(outfile,")\n");
5784 ast_print(tree->left,outfile,indent+2);
5785 ast_print(tree->right,outfile,indent+2);
5788 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5789 printTypeChain(tree->ftype,outfile);
5790 fprintf(outfile,")\n");
5791 ast_print(tree->left,outfile,indent+2);
5792 ast_print(tree->right,outfile,indent+2);
5794 /*------------------------------------------------------------------*/
5795 /*----------------------------*/
5797 /*----------------------------*/
5798 case CAST: /* change the type */
5799 fprintf(outfile,"CAST (%p) from type (",tree);
5800 printTypeChain(tree->right->ftype,outfile);
5801 fprintf(outfile,") to type (");
5802 printTypeChain(tree->ftype,outfile);
5803 fprintf(outfile,")\n");
5804 ast_print(tree->right,outfile,indent+2);
5808 fprintf(outfile,"ANDAND (%p) type (",tree);
5809 printTypeChain(tree->ftype,outfile);
5810 fprintf(outfile,")\n");
5811 ast_print(tree->left,outfile,indent+2);
5812 ast_print(tree->right,outfile,indent+2);
5815 fprintf(outfile,"OROR (%p) type (",tree);
5816 printTypeChain(tree->ftype,outfile);
5817 fprintf(outfile,")\n");
5818 ast_print(tree->left,outfile,indent+2);
5819 ast_print(tree->right,outfile,indent+2);
5822 /*------------------------------------------------------------------*/
5823 /*----------------------------*/
5824 /* comparison operators */
5825 /*----------------------------*/
5827 fprintf(outfile,"GT(>) (%p) type (",tree);
5828 printTypeChain(tree->ftype,outfile);
5829 fprintf(outfile,")\n");
5830 ast_print(tree->left,outfile,indent+2);
5831 ast_print(tree->right,outfile,indent+2);
5834 fprintf(outfile,"LT(<) (%p) type (",tree);
5835 printTypeChain(tree->ftype,outfile);
5836 fprintf(outfile,")\n");
5837 ast_print(tree->left,outfile,indent+2);
5838 ast_print(tree->right,outfile,indent+2);
5841 fprintf(outfile,"LE(<=) (%p) type (",tree);
5842 printTypeChain(tree->ftype,outfile);
5843 fprintf(outfile,")\n");
5844 ast_print(tree->left,outfile,indent+2);
5845 ast_print(tree->right,outfile,indent+2);
5848 fprintf(outfile,"GE(>=) (%p) type (",tree);
5849 printTypeChain(tree->ftype,outfile);
5850 fprintf(outfile,")\n");
5851 ast_print(tree->left,outfile,indent+2);
5852 ast_print(tree->right,outfile,indent+2);
5855 fprintf(outfile,"EQ(==) (%p) type (",tree);
5856 printTypeChain(tree->ftype,outfile);
5857 fprintf(outfile,")\n");
5858 ast_print(tree->left,outfile,indent+2);
5859 ast_print(tree->right,outfile,indent+2);
5862 fprintf(outfile,"NE(!=) (%p) type (",tree);
5863 printTypeChain(tree->ftype,outfile);
5864 fprintf(outfile,")\n");
5865 ast_print(tree->left,outfile,indent+2);
5866 ast_print(tree->right,outfile,indent+2);
5867 /*------------------------------------------------------------------*/
5868 /*----------------------------*/
5870 /*----------------------------*/
5871 case SIZEOF: /* evaluate wihout code generation */
5872 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5875 /*------------------------------------------------------------------*/
5876 /*----------------------------*/
5877 /* conditional operator '?' */
5878 /*----------------------------*/
5880 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5881 printTypeChain(tree->ftype,outfile);
5882 fprintf(outfile,")\n");
5883 ast_print(tree->left,outfile,indent+2);
5884 ast_print(tree->right,outfile,indent+2);
5888 fprintf(outfile,"COLON(:) (%p) type (",tree);
5889 printTypeChain(tree->ftype,outfile);
5890 fprintf(outfile,")\n");
5891 ast_print(tree->left,outfile,indent+2);
5892 ast_print(tree->right,outfile,indent+2);
5895 /*------------------------------------------------------------------*/
5896 /*----------------------------*/
5897 /* assignment operators */
5898 /*----------------------------*/
5900 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5901 printTypeChain(tree->ftype,outfile);
5902 fprintf(outfile,")\n");
5903 ast_print(tree->left,outfile,indent+2);
5904 ast_print(tree->right,outfile,indent+2);
5907 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5908 printTypeChain(tree->ftype,outfile);
5909 fprintf(outfile,")\n");
5910 ast_print(tree->left,outfile,indent+2);
5911 ast_print(tree->right,outfile,indent+2);
5914 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5915 printTypeChain(tree->ftype,outfile);
5916 fprintf(outfile,")\n");
5917 ast_print(tree->left,outfile,indent+2);
5918 ast_print(tree->right,outfile,indent+2);
5921 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5922 printTypeChain(tree->ftype,outfile);
5923 fprintf(outfile,")\n");
5924 ast_print(tree->left,outfile,indent+2);
5925 ast_print(tree->right,outfile,indent+2);
5928 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5929 printTypeChain(tree->ftype,outfile);
5930 fprintf(outfile,")\n");
5931 ast_print(tree->left,outfile,indent+2);
5932 ast_print(tree->right,outfile,indent+2);
5935 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5936 printTypeChain(tree->ftype,outfile);
5937 fprintf(outfile,")\n");
5938 ast_print(tree->left,outfile,indent+2);
5939 ast_print(tree->right,outfile,indent+2);
5942 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5943 printTypeChain(tree->ftype,outfile);
5944 fprintf(outfile,")\n");
5945 ast_print(tree->left,outfile,indent+2);
5946 ast_print(tree->right,outfile,indent+2);
5948 /*------------------------------------------------------------------*/
5949 /*----------------------------*/
5951 /*----------------------------*/
5953 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5954 printTypeChain(tree->ftype,outfile);
5955 fprintf(outfile,")\n");
5956 ast_print(tree->left,outfile,indent+2);
5957 ast_print(tree->right,outfile,indent+2);
5959 /*------------------------------------------------------------------*/
5960 /*----------------------------*/
5962 /*----------------------------*/
5964 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5965 printTypeChain(tree->ftype,outfile);
5966 fprintf(outfile,")\n");
5967 ast_print(tree->left,outfile,indent+2);
5968 ast_print(tree->right,outfile,indent+2);
5970 /*------------------------------------------------------------------*/
5971 /*----------------------------*/
5972 /* straight assignemnt */
5973 /*----------------------------*/
5975 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5976 printTypeChain(tree->ftype,outfile);
5977 fprintf(outfile,")\n");
5978 ast_print(tree->left,outfile,indent+2);
5979 ast_print(tree->right,outfile,indent+2);
5981 /*------------------------------------------------------------------*/
5982 /*----------------------------*/
5983 /* comma operator */
5984 /*----------------------------*/
5986 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5987 printTypeChain(tree->ftype,outfile);
5988 fprintf(outfile,")\n");
5989 ast_print(tree->left,outfile,indent+2);
5990 ast_print(tree->right,outfile,indent+2);
5992 /*------------------------------------------------------------------*/
5993 /*----------------------------*/
5995 /*----------------------------*/
5998 fprintf(outfile,"CALL (%p) type (",tree);
5999 printTypeChain(tree->ftype,outfile);
6000 fprintf(outfile,")\n");
6001 ast_print(tree->left,outfile,indent+2);
6002 ast_print(tree->right,outfile,indent+2);
6005 fprintf(outfile,"PARMS\n");
6006 ast_print(tree->left,outfile,indent+2);
6007 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6008 ast_print(tree->right,outfile,indent+2);
6011 /*------------------------------------------------------------------*/
6012 /*----------------------------*/
6013 /* return statement */
6014 /*----------------------------*/
6016 fprintf(outfile,"RETURN (%p) type (",tree);
6018 printTypeChain(tree->right->ftype,outfile);
6020 fprintf(outfile,")\n");
6021 ast_print(tree->right,outfile,indent+2);
6023 /*------------------------------------------------------------------*/
6024 /*----------------------------*/
6025 /* label statement */
6026 /*----------------------------*/
6028 fprintf(outfile,"LABEL (%p)\n",tree);
6029 ast_print(tree->left,outfile,indent+2);
6030 ast_print(tree->right,outfile,indent);
6032 /*------------------------------------------------------------------*/
6033 /*----------------------------*/
6034 /* switch statement */
6035 /*----------------------------*/
6039 fprintf(outfile,"SWITCH (%p) ",tree);
6040 ast_print(tree->left,outfile,0);
6041 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6042 INDENT(indent+2,outfile);
6043 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6044 (int) floatFromVal(val),
6045 tree->values.switchVals.swNum,
6046 (int) floatFromVal(val));
6048 ast_print(tree->right,outfile,indent);
6051 /*------------------------------------------------------------------*/
6052 /*----------------------------*/
6054 /*----------------------------*/
6056 fprintf(outfile,"IF (%p) \n",tree);
6057 ast_print(tree->left,outfile,indent+2);
6058 if (tree->trueLabel) {
6059 INDENT(indent+2,outfile);
6060 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6062 if (tree->falseLabel) {
6063 INDENT(indent+2,outfile);
6064 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6066 ast_print(tree->right,outfile,indent+2);
6068 /*----------------------------*/
6069 /* goto Statement */
6070 /*----------------------------*/
6072 fprintf(outfile,"GOTO (%p) \n",tree);
6073 ast_print(tree->left,outfile,indent+2);
6074 fprintf(outfile,"\n");
6076 /*------------------------------------------------------------------*/
6077 /*----------------------------*/
6079 /*----------------------------*/
6081 fprintf(outfile,"FOR (%p) \n",tree);
6082 if (AST_FOR( tree, initExpr)) {
6083 INDENT(indent+2,outfile);
6084 fprintf(outfile,"INIT EXPR ");
6085 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6087 if (AST_FOR( tree, condExpr)) {
6088 INDENT(indent+2,outfile);
6089 fprintf(outfile,"COND EXPR ");
6090 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6092 if (AST_FOR( tree, loopExpr)) {
6093 INDENT(indent+2,outfile);
6094 fprintf(outfile,"LOOP EXPR ");
6095 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6097 fprintf(outfile,"FOR LOOP BODY \n");
6098 ast_print(tree->left,outfile,indent+2);
6101 fprintf(outfile,"CRITICAL (%p) \n",tree);
6102 ast_print(tree->left,outfile,indent+2);
6110 ast_print(t,stdout,0);
6115 /*-----------------------------------------------------------------*/
6116 /* astErrors : returns non-zero if errors present in tree */
6117 /*-----------------------------------------------------------------*/
6118 int astErrors(ast *t)
6127 if (t->type == EX_VALUE
6128 && t->opval.val->sym
6129 && t->opval.val->sym->undefined)
6132 errors += astErrors(t->left);
6133 errors += astErrors(t->right);