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 *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *, RESULT_TYPE);
59 ast *optimizeGetAbit (ast *, RESULT_TYPE);
60 ast *optimizeGetByte (ast *, RESULT_TYPE);
61 ast *optimizeGetWord (ast *, RESULT_TYPE);
62 static ast *backPatchLabels (ast *, symbol *, symbol *);
65 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
70 printTypeChain (tree->ftype, stdout);
75 /*-----------------------------------------------------------------*/
76 /* newAst - creates a fresh node for an expression tree */
77 /*-----------------------------------------------------------------*/
79 newAst_ (unsigned type)
82 static int oldLineno = 0;
84 ex = Safe_alloc ( sizeof (ast));
87 ex->lineno = (noLineno ? oldLineno : mylineno);
88 ex->filename = currFname;
89 ex->level = NestLevel;
90 ex->block = currBlockno;
91 ex->initMode = inInitMode;
92 ex->seqPoint = seqPointNo;
97 newAst_VALUE (value * val)
99 ast *ex = newAst_ (EX_VALUE);
105 newAst_OP (unsigned op)
107 ast *ex = newAst_ (EX_OP);
113 newAst_LINK (sym_link * val)
115 ast *ex = newAst_ (EX_LINK);
120 /*-----------------------------------------------------------------*/
121 /* newNode - creates a new node */
122 /*-----------------------------------------------------------------*/
124 newNode (long op, ast * left, ast * right)
135 /*-----------------------------------------------------------------*/
136 /* newIfxNode - creates a new Ifx Node */
137 /*-----------------------------------------------------------------*/
139 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
143 /* if this is a literal then we already know the result */
144 if (condAst->etype && IS_LITERAL (condAst->etype))
146 /* then depending on the expression value */
147 if (floatFromVal (condAst->opval.val))
148 ifxNode = newNode (GOTO,
149 newAst_VALUE (symbolVal (trueLabel)),
152 ifxNode = newNode (GOTO,
153 newAst_VALUE (symbolVal (falseLabel)),
158 ifxNode = newNode (IFX, condAst, NULL);
159 ifxNode->trueLabel = trueLabel;
160 ifxNode->falseLabel = falseLabel;
166 /*-----------------------------------------------------------------*/
167 /* copyAstValues - copies value portion of ast if needed */
168 /*-----------------------------------------------------------------*/
170 copyAstValues (ast * dest, ast * src)
172 switch (src->opval.op)
175 dest->values.sym = copySymbolChain (src->values.sym);
179 dest->values.switchVals.swVals =
180 copyValue (src->values.switchVals.swVals);
181 dest->values.switchVals.swDefault =
182 src->values.switchVals.swDefault;
183 dest->values.switchVals.swNum =
184 src->values.switchVals.swNum;
188 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
192 dest->values.constlist = copyLiteralList(src->values.constlist);
196 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
197 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
198 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
199 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
200 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
201 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
202 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
207 /*-----------------------------------------------------------------*/
208 /* copyAst - makes a copy of a given astession */
209 /*-----------------------------------------------------------------*/
218 dest = Safe_alloc ( sizeof (ast));
220 dest->type = src->type;
221 dest->lineno = src->lineno;
222 dest->level = src->level;
223 dest->funcName = src->funcName;
224 dest->reversed = src->reversed;
227 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
229 /* if this is a leaf */
231 if (src->type == EX_VALUE)
233 dest->opval.val = copyValue (src->opval.val);
238 if (src->type == EX_LINK)
240 dest->opval.lnk = copyLinkChain (src->opval.lnk);
244 dest->opval.op = src->opval.op;
246 /* if this is a node that has special values */
247 copyAstValues (dest, src);
249 dest->trueLabel = copySymbol (src->trueLabel);
250 dest->falseLabel = copySymbol (src->falseLabel);
251 dest->left = copyAst (src->left);
252 dest->right = copyAst (src->right);
258 /*-----------------------------------------------------------------*/
259 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
260 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
261 /*-----------------------------------------------------------------*/
262 ast *removeIncDecOps (ast * tree) {
264 // traverse the tree and remove inc/dec ops
269 if (tree->type == EX_OP &&
270 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
277 tree->left=removeIncDecOps(tree->left);
278 tree->right=removeIncDecOps(tree->right);
283 /*-----------------------------------------------------------------*/
284 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
285 /* "*++s += 3" -> "*++s = *++s + 3" */
286 /*-----------------------------------------------------------------*/
287 ast *removePreIncDecOps (ast * tree) {
289 // traverse the tree and remove pre-inc/dec ops
294 if (tree->type == EX_OP &&
295 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
300 tree->left=removePreIncDecOps(tree->left);
301 tree->right=removePreIncDecOps(tree->right);
306 /*-----------------------------------------------------------------*/
307 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
308 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
309 /*-----------------------------------------------------------------*/
310 ast *removePostIncDecOps (ast * tree) {
312 // traverse the tree and remove pre-inc/dec ops
317 if (tree->type == EX_OP &&
318 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
323 tree->left=removePostIncDecOps(tree->left);
324 tree->right=removePostIncDecOps(tree->right);
329 /*-----------------------------------------------------------------*/
330 /* hasSEFcalls - returns TRUE if tree has a function call */
331 /*-----------------------------------------------------------------*/
333 hasSEFcalls (ast * tree)
338 if (tree->type == EX_OP &&
339 (tree->opval.op == CALL ||
340 tree->opval.op == PCALL ||
341 tree->opval.op == '=' ||
342 tree->opval.op == INC_OP ||
343 tree->opval.op == DEC_OP))
346 return (hasSEFcalls (tree->left) |
347 hasSEFcalls (tree->right));
350 /*-----------------------------------------------------------------*/
351 /* isAstEqual - compares two asts & returns 1 if they are equal */
352 /*-----------------------------------------------------------------*/
354 isAstEqual (ast * t1, ast * t2)
363 if (t1->type != t2->type)
369 if (t1->opval.op != t2->opval.op)
371 return (isAstEqual (t1->left, t2->left) &&
372 isAstEqual (t1->right, t2->right));
376 if (t1->opval.val->sym)
378 if (!t2->opval.val->sym)
381 return isSymbolEqual (t1->opval.val->sym,
386 if (t2->opval.val->sym)
389 return (floatFromVal (t1->opval.val) ==
390 floatFromVal (t2->opval.val));
394 /* only compare these two types */
402 /*-----------------------------------------------------------------*/
403 /* resolveSymbols - resolve symbols from the symbol table */
404 /*-----------------------------------------------------------------*/
406 resolveSymbols (ast * tree)
408 /* walk the entire tree and check for values */
409 /* with symbols if we find one then replace */
410 /* symbol with that from the symbol table */
417 /* if not block & function */
418 if (tree->type == EX_OP &&
419 (tree->opval.op != FUNCTION &&
420 tree->opval.op != BLOCK &&
421 tree->opval.op != NULLOP))
423 filename = tree->filename;
424 lineno = tree->lineno;
428 /* make sure we resolve the true & false labels for ifx */
429 if (tree->type == EX_OP && tree->opval.op == IFX)
435 if ((csym = findSym (LabelTab, tree->trueLabel,
436 tree->trueLabel->name)))
437 tree->trueLabel = csym;
439 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
440 tree->trueLabel->name);
443 if (tree->falseLabel)
445 if ((csym = findSym (LabelTab,
447 tree->falseLabel->name)))
448 tree->falseLabel = csym;
450 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
451 tree->falseLabel->name);
456 /* if this is a label resolve it from the labelTab */
457 if (IS_AST_VALUE (tree) &&
458 tree->opval.val->sym &&
459 tree->opval.val->sym->islbl)
462 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
463 tree->opval.val->sym->name);
466 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
467 tree->opval.val->sym->name);
469 tree->opval.val->sym = csym;
471 goto resolveChildren;
474 /* do only for leafs */
475 if (IS_AST_VALUE (tree) &&
476 tree->opval.val->sym &&
477 !tree->opval.val->sym->implicit)
480 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
482 /* if found in the symbol table & they r not the same */
483 if (csym && tree->opval.val->sym != csym)
485 tree->opval.val->sym = csym;
486 tree->opval.val->type = csym->type;
487 tree->opval.val->etype = csym->etype;
490 /* if not found in the symbol table */
491 /* mark it as undefined assume it is */
492 /* an integer in data space */
493 if (!csym && !tree->opval.val->sym->implicit)
496 /* if this is a function name then */
497 /* mark it as returning an int */
500 tree->opval.val->sym->type = newLink (DECLARATOR);
501 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
502 tree->opval.val->sym->type->next =
503 tree->opval.val->sym->etype = newIntLink ();
504 tree->opval.val->etype = tree->opval.val->etype;
505 tree->opval.val->type = tree->opval.val->sym->type;
506 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
507 tree->opval.val->sym->name);
508 //tree->opval.val->sym->undefined = 1;
509 allocVariables (tree->opval.val->sym);
513 tree->opval.val->sym->undefined = 1;
514 tree->opval.val->type =
515 tree->opval.val->etype = newIntLink ();
516 tree->opval.val->sym->type =
517 tree->opval.val->sym->etype = newIntLink ();
523 resolveSymbols (tree->left);
524 resolveSymbols (tree->right);
529 /*-----------------------------------------------------------------*/
530 /* setAstLineno - walks a ast tree & sets the line number */
531 /*-----------------------------------------------------------------*/
532 int setAstLineno (ast * tree, int lineno)
537 tree->lineno = lineno;
538 setAstLineno (tree->left, lineno);
539 setAstLineno (tree->right, lineno);
543 /*-----------------------------------------------------------------*/
544 /* funcOfType :- function of type with name */
545 /*-----------------------------------------------------------------*/
547 funcOfType (char *name, sym_link * type, sym_link * argType,
551 /* create the symbol */
552 sym = newSymbol (name, 0);
554 /* setup return value */
555 sym->type = newLink (DECLARATOR);
556 DCL_TYPE (sym->type) = FUNCTION;
557 sym->type->next = copyLinkChain (type);
558 sym->etype = getSpec (sym->type);
559 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
561 /* if arguments required */
565 args = FUNC_ARGS(sym->type) = newValue ();
569 args->type = copyLinkChain (argType);
570 args->etype = getSpec (args->type);
571 SPEC_EXTR(args->etype)=1;
574 args = args->next = newValue ();
581 allocVariables (sym);
586 /*-----------------------------------------------------------------*/
587 /* funcOfTypeVarg :- function of type with name and argtype */
588 /*-----------------------------------------------------------------*/
590 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
595 /* create the symbol */
596 sym = newSymbol (name, 0);
598 /* setup return value */
599 sym->type = newLink (DECLARATOR);
600 DCL_TYPE (sym->type) = FUNCTION;
601 sym->type->next = typeFromStr(rtype);
602 sym->etype = getSpec (sym->type);
604 /* if arguments required */
607 args = FUNC_ARGS(sym->type) = newValue ();
609 for ( i = 0 ; i < nArgs ; i++ ) {
610 args->type = typeFromStr(atypes[i]);
611 args->etype = getSpec (args->type);
612 SPEC_EXTR(args->etype)=1;
613 if ((i + 1) == nArgs) break;
614 args = args->next = newValue ();
621 allocVariables (sym);
626 /*-----------------------------------------------------------------*/
627 /* reverseParms - will reverse a parameter tree */
628 /*-----------------------------------------------------------------*/
630 reverseParms (ast * ptree)
636 /* top down if we find a nonParm tree then quit */
637 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
639 /* The various functions expect the parameter tree to be right heavy. */
640 /* Rotate the tree to be left heavy so that after reversal it is */
641 /* right heavy again. */
642 while ((ttree = ptree->right) && ttree->type == EX_OP &&
643 ttree->opval.op == PARAM)
645 ptree->right = ttree->right;
646 ttree->right = ttree->left;
647 ttree->left = ptree->left;
653 ptree->left = ptree->right;
654 ptree->right = ttree;
656 reverseParms (ptree->left);
657 reverseParms (ptree->right);
663 /*-----------------------------------------------------------------*/
664 /* processParms - makes sure the parameters are okay and do some */
665 /* processing with them */
666 /*-----------------------------------------------------------------*/
668 processParms (ast *func,
671 int *parmNumber, /* unused, although updated */
674 RESULT_TYPE resultType;
677 /* if none of them exist */
678 if (!defParm && !*actParm)
683 if (getenv("DEBUG_SANITY"))
685 fprintf (stderr, "processParms: %s ", defParm->name);
687 /* make sure the type is complete and sane */
688 checkTypeSanity(defParm->etype, defParm->name);
691 if (IS_CODEPTR (func->ftype))
692 functype = func->ftype->next;
694 functype = func->ftype;
696 /* if the function is being called via a pointer & */
697 /* it has not been defined a reentrant then we cannot */
698 /* have parameters */
699 /* PIC16 port can... */
700 if (!TARGET_IS_PIC16)
702 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
704 werror (W_NONRENT_ARGS);
710 /* if defined parameters ended but actual parameters */
711 /* exist and this is not defined as a variable arg */
712 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
714 werror (E_TOO_MANY_PARMS);
718 /* if defined parameters present but no actual parameters */
719 if (defParm && !*actParm)
721 werror (E_TOO_FEW_PARMS);
725 /* if this is a PARAM node then match left & right */
726 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
728 (*actParm)->decorated = 1;
729 return (processParms (func, defParm,
730 &(*actParm)->left, parmNumber, FALSE) ||
731 processParms (func, defParm ? defParm->next : NULL,
732 &(*actParm)->right, parmNumber, rightmost));
734 else if (defParm) /* not vararg */
736 /* If we have found a value node by following only right-hand links,
737 * then we know that there are no more values after us.
739 * Therefore, if there are more defined parameters, the caller didn't
742 if (rightmost && defParm->next)
744 werror (E_TOO_FEW_PARMS);
749 /* decorate parameter */
750 resultType = defParm ? getResultTypeFromType (defParm->etype) :
752 *actParm = decorateType (*actParm, resultType);
754 if (IS_VOID((*actParm)->ftype))
756 werror (E_VOID_VALUE_USED);
760 /* If this is a varargs function... */
761 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
766 if (IS_CAST_OP (*actParm)
767 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
769 /* Parameter was explicitly typecast; don't touch it. */
773 ftype = (*actParm)->ftype;
775 /* If it's a char, upcast to int. */
776 if (IS_INTEGRAL (ftype)
777 && (getSize (ftype) < (unsigned) INTSIZE))
779 newType = newAst_LINK(INTTYPE);
782 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
784 newType = newAst_LINK (copyLinkChain(ftype));
785 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
788 if (IS_AGGREGATE (ftype))
790 newType = newAst_LINK (copyLinkChain (ftype));
791 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
796 /* cast required; change this op to a cast. */
797 (*actParm)->decorated = 0;
798 *actParm = newNode (CAST, newType, *actParm);
799 (*actParm)->lineno = (*actParm)->right->lineno;
801 decorateType (*actParm, RESULT_TYPE_NONE);
806 /* if defined parameters ended but actual has not & */
808 if (!defParm && *actParm &&
809 (options.stackAuto || IFFUNC_ISREENT (functype)))
812 resolveSymbols (*actParm);
814 /* the parameter type must be at least castable */
815 if (compareType (defParm->type, (*actParm)->ftype) == 0)
817 werror (E_INCOMPAT_TYPES);
818 printFromToType ((*actParm)->ftype, defParm->type);
822 /* if the parameter is castable then add the cast */
823 if (compareType (defParm->type, (*actParm)->ftype) < 0)
827 resultType = getResultTypeFromType (defParm->etype);
828 pTree = resolveSymbols (copyAst (*actParm));
830 /* now change the current one to a cast */
831 (*actParm)->type = EX_OP;
832 (*actParm)->opval.op = CAST;
833 (*actParm)->left = newAst_LINK (defParm->type);
834 (*actParm)->right = pTree;
835 (*actParm)->decorated = 0; /* force typechecking */
836 decorateType (*actParm, resultType);
839 /* make a copy and change the regparm type to the defined parm */
840 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
841 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
842 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
847 /*-----------------------------------------------------------------*/
848 /* createIvalType - generates ival for basic types */
849 /*-----------------------------------------------------------------*/
851 createIvalType (ast * sym, sym_link * type, initList * ilist)
855 /* if initList is deep */
856 if (ilist->type == INIT_DEEP)
857 ilist = ilist->init.deep;
859 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
860 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
863 /*-----------------------------------------------------------------*/
864 /* createIvalStruct - generates initial value for structures */
865 /*-----------------------------------------------------------------*/
867 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
874 sflds = SPEC_STRUCT (type)->fields;
875 if (ilist->type != INIT_DEEP)
877 werror (E_INIT_STRUCT, "");
881 iloop = ilist->init.deep;
883 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
885 /* if we have come to end */
889 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
890 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
891 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
892 iloop, rast, rootValue)),
898 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
899 W_EXCESS_INITIALIZERS, "struct",
900 sym->opval.val->sym->name);
907 /*-----------------------------------------------------------------*/
908 /* createIvalArray - generates code for array initialization */
909 /*-----------------------------------------------------------------*/
911 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
915 int lcnt = 0, size = 0;
916 literalList *literalL;
918 /* take care of the special case */
919 /* array of characters can be init */
921 if (IS_CHAR (type->next))
922 if ((rast = createIvalCharPtr (sym,
924 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
927 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
929 /* not the special case */
930 if (ilist->type != INIT_DEEP)
932 werror (E_INIT_STRUCT, "");
936 iloop = ilist->init.deep;
937 lcnt = DCL_ELEM (type);
939 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
943 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
945 rast = newNode(ARRAYINIT, aSym, NULL);
946 rast->values.constlist = literalL;
948 // Make sure size is set to length of initializer list.
955 if (lcnt && size > lcnt)
957 // Array size was specified, and we have more initializers than needed.
958 char *name=sym->opval.val->sym->name;
959 int lineno=sym->opval.val->sym->lineDef;
960 char *filename=sym->opval.val->sym->fileDef;
962 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
971 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
972 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
973 rast = createIval (aSym, type->next, iloop, rast, rootValue);
974 iloop = (iloop ? iloop->next : NULL);
980 /* no of elements given and we */
981 /* have generated for all of them */
984 // is this a better way? at least it won't crash
985 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
986 int lineno = iloop->lineno;
987 char *filename = iloop->filename;
988 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
995 /* if we have not been given a size */
996 if (!DCL_ELEM (type))
998 /* check, if it's a flexible array */
999 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1000 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1002 DCL_ELEM (type) = size;
1005 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1009 /*-----------------------------------------------------------------*/
1010 /* createIvalCharPtr - generates initial values for char pointers */
1011 /*-----------------------------------------------------------------*/
1013 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1018 /* if this is a pointer & right is a literal array then */
1019 /* just assignment will do */
1020 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1021 SPEC_SCLS (iexpr->etype) == S_CODE)
1022 && IS_ARRAY (iexpr->ftype)))
1023 return newNode ('=', sym, iexpr);
1025 /* left side is an array so we have to assign each */
1027 if ((IS_LITERAL (iexpr->etype) ||
1028 SPEC_SCLS (iexpr->etype) == S_CODE)
1029 && IS_ARRAY (iexpr->ftype))
1031 /* for each character generate an assignment */
1032 /* to the array element */
1033 char *s = SPEC_CVAL (iexpr->etype).v_char;
1035 unsigned int symsize = getSize (type);
1037 size = getSize (iexpr->ftype);
1038 if (symsize && size>symsize)
1040 if (size>(symsize+1))
1042 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1044 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1050 for (i=0;i<size;i++)
1052 rast = newNode (NULLOP,
1056 newAst_VALUE (valueFromLit ((float) i))),
1057 newAst_VALUE (valueFromLit (*s))));
1061 // now WE don't need iexpr's symbol anymore
1062 freeStringSymbol(AST_SYMBOL(iexpr));
1064 /* if we have not been given a size */
1065 if (!DCL_ELEM (type))
1067 /* check, if it's a flexible array */
1068 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1069 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1071 DCL_ELEM (type) = size;
1074 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1080 /*-----------------------------------------------------------------*/
1081 /* createIvalPtr - generates initial value for pointers */
1082 /*-----------------------------------------------------------------*/
1084 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1090 if (ilist->type == INIT_DEEP)
1091 ilist = ilist->init.deep;
1093 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1095 /* if character pointer */
1096 if (IS_CHAR (type->next))
1097 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1100 return newNode ('=', sym, iexpr);
1103 /*-----------------------------------------------------------------*/
1104 /* createIval - generates code for initial value */
1105 /*-----------------------------------------------------------------*/
1107 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1114 /* if structure then */
1115 if (IS_STRUCT (type))
1116 rast = createIvalStruct (sym, type, ilist, rootValue);
1118 /* if this is a pointer */
1120 rast = createIvalPtr (sym, type, ilist, rootValue);
1122 /* if this is an array */
1123 if (IS_ARRAY (type))
1124 rast = createIvalArray (sym, type, ilist, rootValue);
1126 /* if type is SPECIFIER */
1128 rast = createIvalType (sym, type, ilist);
1131 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1133 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1136 /*-----------------------------------------------------------------*/
1137 /* initAggregates - initialises aggregate variables with initv */
1138 /*-----------------------------------------------------------------*/
1139 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1140 ast *newAst = newAst_VALUE (symbolVal (sym));
1141 return createIval (newAst, sym->type, ival, wid, newAst);
1144 /*-----------------------------------------------------------------*/
1145 /* gatherAutoInit - creates assignment expressions for initial */
1147 /*-----------------------------------------------------------------*/
1149 gatherAutoInit (symbol * autoChain)
1156 for (sym = autoChain; sym; sym = sym->next)
1159 /* resolve the symbols in the ival */
1161 resolveIvalSym (sym->ival, sym->type);
1164 /* if we are PIC16 port,
1165 * and this is a static,
1166 * and have initial value,
1167 * and not S_CODE, don't emit in gs segment,
1168 * but allow glue.c:pic16emitRegularMap to put symbol
1169 * in idata section */
1170 if(TARGET_IS_PIC16 &&
1171 IS_STATIC (sym->etype) && sym->ival
1172 && SPEC_SCLS(sym->etype) != S_CODE) {
1173 SPEC_SCLS (sym->etype) = S_DATA;
1178 /* if this is a static variable & has an */
1179 /* initial value the code needs to be lifted */
1180 /* here to the main portion since they can be */
1181 /* initialised only once at the start */
1182 if (IS_STATIC (sym->etype) && sym->ival &&
1183 SPEC_SCLS (sym->etype) != S_CODE)
1187 /* insert the symbol into the symbol table */
1188 /* with level = 0 & name = rname */
1189 newSym = copySymbol (sym);
1190 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1192 /* now lift the code to main */
1193 if (IS_AGGREGATE (sym->type)) {
1194 work = initAggregates (sym, sym->ival, NULL);
1196 if (getNelements(sym->type, sym->ival)>1) {
1197 werrorfl (sym->fileDef, sym->lineDef,
1198 W_EXCESS_INITIALIZERS, "scalar",
1201 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1202 list2expr (sym->ival));
1205 setAstLineno (work, sym->lineDef);
1209 staticAutos = newNode (NULLOP, staticAutos, work);
1216 /* if there is an initial value */
1217 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1219 initList *ilist=sym->ival;
1221 while (ilist->type == INIT_DEEP) {
1222 ilist = ilist->init.deep;
1225 /* update lineno for error msg */
1226 lineno=sym->lineDef;
1227 setAstLineno (ilist->init.node, lineno);
1229 if (IS_AGGREGATE (sym->type)) {
1230 work = initAggregates (sym, sym->ival, NULL);
1232 if (getNelements(sym->type, sym->ival)>1) {
1233 werrorfl (sym->fileDef, sym->lineDef,
1234 W_EXCESS_INITIALIZERS, "scalar",
1237 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1238 list2expr (sym->ival));
1242 setAstLineno (work, sym->lineDef);
1246 init = newNode (NULLOP, init, work);
1255 /*-----------------------------------------------------------------*/
1256 /* freeStringSymbol - delete a literal string if no more usage */
1257 /*-----------------------------------------------------------------*/
1258 void freeStringSymbol(symbol *sym) {
1259 /* make sure this is a literal string */
1260 assert (sym->isstrlit);
1261 if (--sym->isstrlit == 0) { // lower the usage count
1262 memmap *segment=SPEC_OCLS(sym->etype);
1264 deleteSetItem(&segment->syms, sym);
1269 /*-----------------------------------------------------------------*/
1270 /* stringToSymbol - creates a symbol from a literal string */
1271 /*-----------------------------------------------------------------*/
1273 stringToSymbol (value * val)
1275 char name[SDCC_NAME_MAX + 1];
1276 static int charLbl = 0;
1281 // have we heard this before?
1282 for (sp=statsg->syms; sp; sp=sp->next) {
1284 size = getSize (sym->type);
1285 if (sym->isstrlit && size == getSize (val->type) &&
1286 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1287 // yes, this is old news. Don't publish it again.
1288 sym->isstrlit++; // but raise the usage count
1289 return symbolVal(sym);
1293 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1294 sym = newSymbol (name, 0); /* make it @ level 0 */
1295 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1297 /* copy the type from the value passed */
1298 sym->type = copyLinkChain (val->type);
1299 sym->etype = getSpec (sym->type);
1300 /* change to storage class & output class */
1301 SPEC_SCLS (sym->etype) = S_CODE;
1302 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1303 SPEC_STAT (sym->etype) = 1;
1304 /* make the level & block = 0 */
1305 sym->block = sym->level = 0;
1307 /* create an ival */
1308 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1313 allocVariables (sym);
1316 return symbolVal (sym);
1320 /*-----------------------------------------------------------------*/
1321 /* processBlockVars - will go thru the ast looking for block if */
1322 /* a block is found then will allocate the syms */
1323 /* will also gather the auto inits present */
1324 /*-----------------------------------------------------------------*/
1326 processBlockVars (ast * tree, int *stack, int action)
1331 /* if this is a block */
1332 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1336 if (action == ALLOCATE)
1338 *stack += allocVariables (tree->values.sym);
1339 autoInit = gatherAutoInit (tree->values.sym);
1341 /* if there are auto inits then do them */
1343 tree->left = newNode (NULLOP, autoInit, tree->left);
1345 else /* action is deallocate */
1346 deallocLocal (tree->values.sym);
1349 processBlockVars (tree->left, stack, action);
1350 processBlockVars (tree->right, stack, action);
1355 /*-------------------------------------------------------------*/
1356 /* constExprTree - returns TRUE if this tree is a constant */
1358 /*-------------------------------------------------------------*/
1359 bool constExprTree (ast *cexpr) {
1365 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1367 switch (cexpr->type)
1370 if (IS_AST_LIT_VALUE(cexpr)) {
1371 // this is a literal
1374 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1375 // a function's address will never change
1378 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1379 // an array's address will never change
1382 if (IS_AST_SYM_VALUE(cexpr) &&
1383 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1384 // a symbol in code space will never change
1385 // This is only for the 'char *s="hallo"' case and will have to leave
1386 //printf(" code space symbol");
1391 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1392 "unexpected link in expression tree\n");
1395 if (cexpr->opval.op==ARRAYINIT) {
1396 // this is a list of literals
1399 if (cexpr->opval.op=='=') {
1400 return constExprTree(cexpr->right);
1402 if (cexpr->opval.op==CAST) {
1403 // cast ignored, maybe we should throw a warning here?
1404 return constExprTree(cexpr->right);
1406 if (cexpr->opval.op=='&') {
1409 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1412 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1417 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1422 /*-----------------------------------------------------------------*/
1423 /* constExprValue - returns the value of a constant expression */
1424 /* or NULL if it is not a constant expression */
1425 /*-----------------------------------------------------------------*/
1427 constExprValue (ast * cexpr, int check)
1429 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1431 /* if this is not a constant then */
1432 if (!IS_LITERAL (cexpr->ftype))
1434 /* then check if this is a literal array
1436 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1437 SPEC_CVAL (cexpr->etype).v_char &&
1438 IS_ARRAY (cexpr->ftype))
1440 value *val = valFromType (cexpr->ftype);
1441 SPEC_SCLS (val->etype) = S_LITERAL;
1442 val->sym = cexpr->opval.val->sym;
1443 val->sym->type = copyLinkChain (cexpr->ftype);
1444 val->sym->etype = getSpec (val->sym->type);
1445 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1449 /* if we are casting a literal value then */
1450 if (IS_AST_OP (cexpr) &&
1451 cexpr->opval.op == CAST &&
1452 IS_LITERAL (cexpr->right->ftype))
1454 return valCastLiteral (cexpr->ftype,
1455 floatFromVal (cexpr->right->opval.val));
1458 if (IS_AST_VALUE (cexpr))
1460 return cexpr->opval.val;
1464 werror (E_CONST_EXPECTED, "found expression");
1469 /* return the value */
1470 if (IS_AST_VALUE (cexpr))
1472 return cexpr->opval.val;
1477 /*-----------------------------------------------------------------*/
1478 /* isLabelInAst - will return true if a given label is found */
1479 /*-----------------------------------------------------------------*/
1481 isLabelInAst (symbol * label, ast * tree)
1483 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1486 if (IS_AST_OP (tree) &&
1487 tree->opval.op == LABEL &&
1488 isSymbolEqual (AST_SYMBOL (tree->left), label))
1491 return isLabelInAst (label, tree->right) &&
1492 isLabelInAst (label, tree->left);
1496 /*-----------------------------------------------------------------*/
1497 /* isLoopCountable - return true if the loop count can be determi- */
1498 /* -ned at compile time . */
1499 /*-----------------------------------------------------------------*/
1501 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1502 symbol ** sym, ast ** init, ast ** end)
1505 /* the loop is considered countable if the following
1506 conditions are true :-
1508 a) initExpr :- <sym> = <const>
1509 b) condExpr :- <sym> < <const1>
1510 c) loopExpr :- <sym> ++
1513 /* first check the initExpr */
1514 if (IS_AST_OP (initExpr) &&
1515 initExpr->opval.op == '=' && /* is assignment */
1516 IS_AST_SYM_VALUE (initExpr->left))
1517 { /* left is a symbol */
1519 *sym = AST_SYMBOL (initExpr->left);
1520 *init = initExpr->right;
1525 /* for now the symbol has to be of
1527 if (!IS_INTEGRAL ((*sym)->type))
1530 /* now check condExpr */
1531 if (IS_AST_OP (condExpr))
1534 switch (condExpr->opval.op)
1537 if (IS_AST_SYM_VALUE (condExpr->left) &&
1538 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1539 IS_AST_LIT_VALUE (condExpr->right))
1541 *end = condExpr->right;
1547 if (IS_AST_OP (condExpr->left) &&
1548 condExpr->left->opval.op == '>' &&
1549 IS_AST_LIT_VALUE (condExpr->left->right) &&
1550 IS_AST_SYM_VALUE (condExpr->left->left) &&
1551 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1554 *end = newNode ('+', condExpr->left->right,
1555 newAst_VALUE (constVal ("1")));
1568 /* check loop expression is of the form <sym>++ */
1569 if (!IS_AST_OP (loopExpr))
1572 /* check if <sym> ++ */
1573 if (loopExpr->opval.op == INC_OP)
1579 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1580 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1587 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1588 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1596 if (loopExpr->opval.op == ADD_ASSIGN)
1599 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1600 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1601 IS_AST_LIT_VALUE (loopExpr->right) &&
1602 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1610 /*-----------------------------------------------------------------*/
1611 /* astHasVolatile - returns true if ast contains any volatile */
1612 /*-----------------------------------------------------------------*/
1614 astHasVolatile (ast * tree)
1619 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1622 if (IS_AST_OP (tree))
1623 return astHasVolatile (tree->left) ||
1624 astHasVolatile (tree->right);
1629 /*-----------------------------------------------------------------*/
1630 /* astHasPointer - return true if the ast contains any ptr variable */
1631 /*-----------------------------------------------------------------*/
1633 astHasPointer (ast * tree)
1638 if (IS_AST_LINK (tree))
1641 /* if we hit an array expression then check
1642 only the left side */
1643 if (IS_AST_OP (tree) && tree->opval.op == '[')
1644 return astHasPointer (tree->left);
1646 if (IS_AST_VALUE (tree))
1647 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1649 return astHasPointer (tree->left) ||
1650 astHasPointer (tree->right);
1654 /*-----------------------------------------------------------------*/
1655 /* astHasSymbol - return true if the ast has the given symbol */
1656 /*-----------------------------------------------------------------*/
1658 astHasSymbol (ast * tree, symbol * sym)
1660 if (!tree || IS_AST_LINK (tree))
1663 if (IS_AST_VALUE (tree))
1665 if (IS_AST_SYM_VALUE (tree))
1666 return isSymbolEqual (AST_SYMBOL (tree), sym);
1671 return astHasSymbol (tree->left, sym) ||
1672 astHasSymbol (tree->right, sym);
1675 /*-----------------------------------------------------------------*/
1676 /* astHasDeref - return true if the ast has an indirect access */
1677 /*-----------------------------------------------------------------*/
1679 astHasDeref (ast * tree)
1681 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1684 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1686 return astHasDeref (tree->left) || astHasDeref (tree->right);
1689 /*-----------------------------------------------------------------*/
1690 /* isConformingBody - the loop body has to conform to a set of rules */
1691 /* for the loop to be considered reversible read on for rules */
1692 /*-----------------------------------------------------------------*/
1694 isConformingBody (ast * pbody, symbol * sym, ast * body)
1697 /* we are going to do a pre-order traversal of the
1698 tree && check for the following conditions. (essentially
1699 a set of very shallow tests )
1700 a) the sym passed does not participate in
1701 any arithmetic operation
1702 b) There are no function calls
1703 c) all jumps are within the body
1704 d) address of loop control variable not taken
1705 e) if an assignment has a pointer on the
1706 left hand side make sure right does not have
1707 loop control variable */
1709 /* if we reach the end or a leaf then true */
1710 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1713 /* if anything else is "volatile" */
1714 if (IS_VOLATILE (TETYPE (pbody)))
1717 /* we will walk the body in a pre-order traversal for
1719 switch (pbody->opval.op)
1721 /*------------------------------------------------------------------*/
1723 // if the loopvar is used as an index
1724 /* array op is commutative -- must check both left & right */
1725 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1728 return isConformingBody (pbody->right, sym, body)
1729 && isConformingBody (pbody->left, sym, body);
1731 /*------------------------------------------------------------------*/
1736 /*------------------------------------------------------------------*/
1740 /* sure we are not sym is not modified */
1742 IS_AST_SYM_VALUE (pbody->left) &&
1743 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1747 IS_AST_SYM_VALUE (pbody->right) &&
1748 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1753 /*------------------------------------------------------------------*/
1755 case '*': /* can be unary : if right is null then unary operation */
1760 /* if right is NULL then unary operation */
1761 /*------------------------------------------------------------------*/
1762 /*----------------------------*/
1764 /*----------------------------*/
1767 if (IS_AST_SYM_VALUE (pbody->left) &&
1768 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1771 return isConformingBody (pbody->left, sym, body);
1775 if (astHasSymbol (pbody->left, sym) ||
1776 astHasSymbol (pbody->right, sym))
1781 /*------------------------------------------------------------------*/
1792 if (IS_AST_SYM_VALUE (pbody->left) &&
1793 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1796 if (IS_AST_SYM_VALUE (pbody->right) &&
1797 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1800 return isConformingBody (pbody->left, sym, body) &&
1801 isConformingBody (pbody->right, sym, body);
1809 if (IS_AST_SYM_VALUE (pbody->left) &&
1810 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1812 return isConformingBody (pbody->left, sym, body);
1814 /*------------------------------------------------------------------*/
1826 case SIZEOF: /* evaluate wihout code generation */
1828 if (IS_AST_SYM_VALUE (pbody->left) &&
1829 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1832 if (IS_AST_SYM_VALUE (pbody->right) &&
1833 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1836 return isConformingBody (pbody->left, sym, body) &&
1837 isConformingBody (pbody->right, sym, body);
1839 /*------------------------------------------------------------------*/
1842 /* if left has a pointer & right has loop
1843 control variable then we cannot */
1844 if (astHasPointer (pbody->left) &&
1845 astHasSymbol (pbody->right, sym))
1847 if (astHasVolatile (pbody->left))
1850 if (IS_AST_SYM_VALUE (pbody->left)) {
1851 // if the loopvar has an assignment
1852 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1854 // if the loopvar is used in another (maybe conditional) block
1855 if (astHasSymbol (pbody->right, sym) &&
1856 (pbody->level >= body->level)) {
1861 if (astHasVolatile (pbody->left))
1864 if (astHasDeref(pbody->right)) return FALSE;
1866 return isConformingBody (pbody->left, sym, body) &&
1867 isConformingBody (pbody->right, sym, body);
1878 assert ("Parser should not have generated this\n");
1880 /*------------------------------------------------------------------*/
1881 /*----------------------------*/
1882 /* comma operator */
1883 /*----------------------------*/
1885 return isConformingBody (pbody->left, sym, body) &&
1886 isConformingBody (pbody->right, sym, body);
1888 /*------------------------------------------------------------------*/
1889 /*----------------------------*/
1891 /*----------------------------*/
1893 /* if local & not passed as paramater then ok */
1894 if (sym->level && !astHasSymbol(pbody->right,sym))
1898 /*------------------------------------------------------------------*/
1899 /*----------------------------*/
1900 /* return statement */
1901 /*----------------------------*/
1906 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1911 if (astHasSymbol (pbody->left, sym))
1918 return isConformingBody (pbody->left, sym, body) &&
1919 isConformingBody (pbody->right, sym, body);
1925 /*-----------------------------------------------------------------*/
1926 /* isLoopReversible - takes a for loop as input && returns true */
1927 /* if the for loop is reversible. If yes will set the value of */
1928 /* the loop control var & init value & termination value */
1929 /*-----------------------------------------------------------------*/
1931 isLoopReversible (ast * loop, symbol ** loopCntrl,
1932 ast ** init, ast ** end)
1934 /* if option says don't do it then don't */
1935 if (optimize.noLoopReverse)
1937 /* there are several tests to determine this */
1939 /* for loop has to be of the form
1940 for ( <sym> = <const1> ;
1941 [<sym> < <const2>] ;
1942 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1944 if (!isLoopCountable (AST_FOR (loop, initExpr),
1945 AST_FOR (loop, condExpr),
1946 AST_FOR (loop, loopExpr),
1947 loopCntrl, init, end))
1950 /* now do some serious checking on the body of the loop
1953 return isConformingBody (loop->left, *loopCntrl, loop->left);
1957 /*-----------------------------------------------------------------*/
1958 /* replLoopSym - replace the loop sym by loop sym -1 */
1959 /*-----------------------------------------------------------------*/
1961 replLoopSym (ast * body, symbol * sym)
1964 if (!body || IS_AST_LINK (body))
1967 if (IS_AST_SYM_VALUE (body))
1970 if (isSymbolEqual (AST_SYMBOL (body), sym))
1974 body->opval.op = '-';
1975 body->left = newAst_VALUE (symbolVal (sym));
1976 body->right = newAst_VALUE (constVal ("1"));
1984 replLoopSym (body->left, sym);
1985 replLoopSym (body->right, sym);
1989 /*-----------------------------------------------------------------*/
1990 /* reverseLoop - do the actual loop reversal */
1991 /*-----------------------------------------------------------------*/
1993 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1997 /* create the following tree
2002 if (sym) goto for_continue ;
2005 /* put it together piece by piece */
2006 rloop = newNode (NULLOP,
2007 createIf (newAst_VALUE (symbolVal (sym)),
2009 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2012 newAst_VALUE (symbolVal (sym)),
2015 replLoopSym (loop->left, sym);
2016 setAstLineno (rloop, init->lineno);
2018 rloop = newNode (NULLOP,
2020 newAst_VALUE (symbolVal (sym)),
2021 newNode ('-', end, init)),
2022 createLabel (AST_FOR (loop, continueLabel),
2026 newNode (SUB_ASSIGN,
2027 newAst_VALUE (symbolVal (sym)),
2028 newAst_VALUE (constVal ("1"))),
2031 rloop->lineno=init->lineno;
2032 return decorateType (rloop, RESULT_TYPE_NONE);
2036 /*-----------------------------------------------------------------*/
2037 /* searchLitOp - search tree (*ops only) for an ast with literal */
2038 /*-----------------------------------------------------------------*/
2040 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2044 if (tree && optimize.global_cse)
2046 /* is there a literal operand? */
2048 IS_AST_OP(tree->right) &&
2049 tree->right->right &&
2050 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2052 if (IS_LITERAL (RTYPE (tree->right)) !=
2053 IS_LITERAL (LTYPE (tree->right)))
2055 tree->right->decorated = 0;
2056 tree->decorated = 0;
2060 ret = searchLitOp (tree->right, parent, ops);
2065 IS_AST_OP(tree->left) &&
2066 tree->left->right &&
2067 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2069 if (IS_LITERAL (RTYPE (tree->left)) !=
2070 IS_LITERAL (LTYPE (tree->left)))
2072 tree->left->decorated = 0;
2073 tree->decorated = 0;
2077 ret = searchLitOp (tree->left, parent, ops);
2085 /*-----------------------------------------------------------------*/
2086 /* getResultFromType */
2087 /*-----------------------------------------------------------------*/
2089 getResultTypeFromType (sym_link *type)
2091 /* type = getSpec (type); */
2093 return RESULT_TYPE_BIT;
2094 if (IS_BITFIELD (type))
2096 int blen = SPEC_BLEN (type);
2099 return RESULT_TYPE_BIT;
2101 return RESULT_TYPE_CHAR;
2102 return RESULT_TYPE_INT;
2105 return RESULT_TYPE_CHAR;
2108 return RESULT_TYPE_INT;
2109 return RESULT_TYPE_OTHER;
2112 /*-----------------------------------------------------------------*/
2113 /* addCast - adds casts to a type specified by RESULT_TYPE */
2114 /*-----------------------------------------------------------------*/
2116 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2119 bool upCasted = FALSE;
2123 case RESULT_TYPE_NONE:
2124 /* if thing smaller than int must be promoted to int */
2126 getSize (tree->etype) >= INTSIZE)
2127 /* promotion not necessary or already an int */
2129 /* char and bits: promote to int */
2130 newLink = newIntLink();
2133 case RESULT_TYPE_BIT:
2135 /* already an int */
2136 bitsForType (tree->etype) >= 16 ||
2137 /* bit to bit operation: don't promote, the code generators
2138 hopefully know everything about promotion rules */
2139 bitsForType (tree->etype) == 1)
2141 newLink = newIntLink();
2144 case RESULT_TYPE_CHAR:
2145 if (IS_CHAR (tree->etype) ||
2146 IS_FLOAT(tree->etype) ||
2147 IS_FIXED(tree->etype))
2149 newLink = newCharLink();
2151 case RESULT_TYPE_INT:
2153 if (getSize (tree->etype) > INTSIZE)
2155 /* warn ("Loosing significant digits"); */
2159 /* char: promote to int */
2161 getSize (tree->etype) >= INTSIZE)
2163 newLink = newIntLink();
2166 case RESULT_TYPE_OTHER:
2169 /* return type is long, float: promote char to int */
2170 if (getSize (tree->etype) >= INTSIZE)
2172 newLink = newIntLink();
2178 tree->decorated = 0;
2179 tree = newNode (CAST, newAst_LINK (newLink), tree);
2180 tree->lineno = tree->right->lineno;
2181 /* keep unsigned type during cast to smaller type,
2182 but not when promoting from char to int */
2184 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2185 return decorateType (tree, resultType);
2188 /*-----------------------------------------------------------------*/
2189 /* resultTypePropagate - decides if resultType can be propagated */
2190 /*-----------------------------------------------------------------*/
2192 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2194 switch (tree->opval.op)
2213 return RESULT_TYPE_NONE;
2217 return RESULT_TYPE_IFX;
2219 return RESULT_TYPE_NONE;
2223 /*-----------------------------------------------------------------*/
2224 /* getLeftResultType - gets type from left branch for propagation */
2225 /*-----------------------------------------------------------------*/
2227 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2229 switch (tree->opval.op)
2233 if (IS_PTR (LTYPE (tree)))
2234 return RESULT_TYPE_NONE;
2236 return getResultTypeFromType (LETYPE (tree));
2238 if (IS_PTR (currFunc->type->next))
2239 return RESULT_TYPE_NONE;
2241 return getResultTypeFromType (currFunc->type->next);
2243 if (!IS_ARRAY (LTYPE (tree)))
2245 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2246 return RESULT_TYPE_CHAR;
2253 /*--------------------------------------------------------------------*/
2254 /* decorateType - compute type for this tree, also does type checking.*/
2255 /* This is done bottom up, since type has to flow upwards. */
2256 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2257 /* result is a char and the operand(s) are int's. */
2258 /* It also does constant folding, and parameter checking. */
2259 /*--------------------------------------------------------------------*/
2261 decorateType (ast * tree, RESULT_TYPE resultType)
2265 RESULT_TYPE resultTypeProp;
2270 /* if already has type then do nothing */
2271 if (tree->decorated)
2274 tree->decorated = 1;
2277 /* print the line */
2278 /* if not block & function */
2279 if (tree->type == EX_OP &&
2280 (tree->opval.op != FUNCTION &&
2281 tree->opval.op != BLOCK &&
2282 tree->opval.op != NULLOP))
2284 filename = tree->filename;
2285 lineno = tree->lineno;
2289 /* if any child is an error | this one is an error do nothing */
2290 if (tree->isError ||
2291 (tree->left && tree->left->isError) ||
2292 (tree->right && tree->right->isError))
2295 /*------------------------------------------------------------------*/
2296 /*----------------------------*/
2297 /* leaf has been reached */
2298 /*----------------------------*/
2299 lineno=tree->lineno;
2300 /* if this is of type value */
2301 /* just get the type */
2302 if (tree->type == EX_VALUE)
2305 if (IS_LITERAL (tree->opval.val->etype))
2308 /* if this is a character array then declare it */
2309 if (IS_ARRAY (tree->opval.val->type))
2310 tree->opval.val = stringToSymbol (tree->opval.val);
2312 /* otherwise just copy the type information */
2313 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2317 if (tree->opval.val->sym)
2319 /* if the undefined flag is set then give error message */
2320 if (tree->opval.val->sym->undefined)
2322 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2324 TTYPE (tree) = TETYPE (tree) =
2325 tree->opval.val->type = tree->opval.val->sym->type =
2326 tree->opval.val->etype = tree->opval.val->sym->etype =
2327 copyLinkChain (INTTYPE);
2332 /* if impilicit i.e. struct/union member then no type */
2333 if (tree->opval.val->sym->implicit)
2334 TTYPE (tree) = TETYPE (tree) = NULL;
2339 /* else copy the type */
2340 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2342 /* and mark it as referenced */
2343 tree->opval.val->sym->isref = 1;
2351 /* if type link for the case of cast */
2352 if (tree->type == EX_LINK)
2354 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2362 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2364 if (tree->left && tree->left->type == EX_OPERAND
2365 && (tree->left->opval.op == INC_OP
2366 || tree->left->opval.op == DEC_OP)
2367 && tree->left->left)
2369 tree->left->right = tree->left->left;
2370 tree->left->left = NULL;
2372 if (tree->right && tree->right->type == EX_OPERAND
2373 && (tree->right->opval.op == INC_OP
2374 || tree->right->opval.op == DEC_OP)
2375 && tree->right->left)
2377 tree->right->right = tree->right->left;
2378 tree->right->left = NULL;
2383 /* Before decorating the left branch we've to decide in dependence
2384 upon tree->opval.op, if resultType can be propagated */
2385 resultTypeProp = resultTypePropagate (tree, resultType);
2387 if (tree->opval.op == '?')
2388 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2390 dtl = decorateType (tree->left, resultTypeProp);
2392 /* if an array node, we may need to swap branches */
2393 if (tree->opval.op == '[')
2395 /* determine which is the array & which the index */
2396 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2397 IS_INTEGRAL (LTYPE (tree)))
2399 ast *tempTree = tree->left;
2400 tree->left = tree->right;
2401 tree->right = tempTree;
2405 /* After decorating the left branch there's type information available
2406 in tree->left->?type. If the op is e.g. '=' we extract the type
2407 information from there and propagate it to the right branch. */
2408 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2410 switch (tree->opval.op)
2413 /* delay right side for '?' operator since conditional macro
2414 expansions might rely on this */
2418 /* decorate right side for CALL (parameter list) in processParms();
2419 there is resultType available */
2423 dtr = decorateType (tree->right, resultTypeProp);
2427 /* this is to take care of situations
2428 when the tree gets rewritten */
2429 if (dtl != tree->left)
2431 if (dtr != tree->right)
2433 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2437 /* depending on type of operator do */
2439 switch (tree->opval.op)
2441 /*------------------------------------------------------------------*/
2442 /*----------------------------*/
2444 /*----------------------------*/
2447 /* first check if this is a array or a pointer */
2448 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2450 werror (E_NEED_ARRAY_PTR, "[]");
2451 goto errorTreeReturn;
2454 /* check if the type of the idx */
2455 if (!IS_INTEGRAL (RTYPE (tree)))
2457 werror (E_IDX_NOT_INT);
2458 goto errorTreeReturn;
2461 /* if the left is an rvalue then error */
2464 werror (E_LVALUE_REQUIRED, "array access");
2465 goto errorTreeReturn;
2468 if (IS_LITERAL (RTYPE (tree)))
2470 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2471 int arraySize = DCL_ELEM (LTYPE (tree));
2472 if (arraySize && arrayIndex >= arraySize)
2474 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2479 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2480 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2483 /*------------------------------------------------------------------*/
2484 /*----------------------------*/
2486 /*----------------------------*/
2488 /* if this is not a structure */
2489 if (!IS_STRUCT (LTYPE (tree)))
2491 werror (E_STRUCT_UNION, ".");
2492 goto errorTreeReturn;
2494 TTYPE (tree) = structElemType (LTYPE (tree),
2495 (tree->right->type == EX_VALUE ?
2496 tree->right->opval.val : NULL));
2497 TETYPE (tree) = getSpec (TTYPE (tree));
2500 /*------------------------------------------------------------------*/
2501 /*----------------------------*/
2502 /* struct/union pointer */
2503 /*----------------------------*/
2505 /* if not pointer to a structure */
2506 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2508 werror (E_PTR_REQD);
2509 goto errorTreeReturn;
2512 if (!IS_STRUCT (LTYPE (tree)->next))
2514 werror (E_STRUCT_UNION, "->");
2515 goto errorTreeReturn;
2518 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2519 (tree->right->type == EX_VALUE ?
2520 tree->right->opval.val : NULL));
2521 TETYPE (tree) = getSpec (TTYPE (tree));
2523 /* adjust the storage class */
2524 switch (DCL_TYPE(tree->left->ftype)) {
2526 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2529 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2532 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2535 SPEC_SCLS (TETYPE (tree)) = 0;
2538 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2541 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2544 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2547 SPEC_SCLS (TETYPE (tree)) = 0;
2554 /* This breaks with extern declarations, bitfields, and perhaps other */
2555 /* cases (gcse). Let's leave this optimization disabled for now and */
2556 /* ponder if there's a safe way to do this. -- EEP */
2558 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2559 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2561 /* If defined struct type at addr var
2562 then rewrite (&struct var)->member
2564 and define membertype at (addr+offsetof(struct var,member)) temp
2567 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2568 AST_SYMBOL(tree->right));
2570 sym = newSymbol(genSymName (0), 0);
2571 sym->type = TTYPE (tree);
2572 sym->etype = getSpec(sym->type);
2573 sym->lineDef = tree->lineno;
2576 SPEC_STAT (sym->etype) = 1;
2577 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2579 SPEC_ABSA(sym->etype) = 1;
2580 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2583 AST_VALUE (tree) = symbolVal(sym);
2586 tree->type = EX_VALUE;
2594 /*------------------------------------------------------------------*/
2595 /*----------------------------*/
2596 /* ++/-- operation */
2597 /*----------------------------*/
2601 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2602 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2603 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2604 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2613 /*------------------------------------------------------------------*/
2614 /*----------------------------*/
2616 /*----------------------------*/
2617 case '&': /* can be unary */
2618 /* if right is NULL then unary operation */
2619 if (tree->right) /* not an unary operation */
2622 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2624 werror (E_BITWISE_OP);
2625 werror (W_CONTINUE, "left & right types are ");
2626 printTypeChain (LTYPE (tree), stderr);
2627 fprintf (stderr, ",");
2628 printTypeChain (RTYPE (tree), stderr);
2629 fprintf (stderr, "\n");
2630 goto errorTreeReturn;
2633 /* if they are both literal */
2634 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2636 tree->type = EX_VALUE;
2637 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2638 valFromType (RETYPE (tree)), '&');
2640 tree->right = tree->left = NULL;
2641 TETYPE (tree) = tree->opval.val->etype;
2642 TTYPE (tree) = tree->opval.val->type;
2646 /* see if this is a GETHBIT operation if yes
2649 ast *otree = optimizeGetHbit (tree, resultType);
2652 return decorateType (otree, RESULT_TYPE_NONE);
2655 /* see if this is a GETABIT operation if yes
2658 ast *otree = optimizeGetAbit (tree, resultType);
2661 return decorateType (otree, RESULT_TYPE_NONE);
2664 /* see if this is a GETBYTE operation if yes
2667 ast *otree = optimizeGetByte (tree, resultType);
2670 return decorateType (otree, RESULT_TYPE_NONE);
2673 /* see if this is a GETWORD operation if yes
2676 ast *otree = optimizeGetWord (tree, resultType);
2679 return decorateType (otree, RESULT_TYPE_NONE);
2682 /* if left is a literal exchange left & right */
2683 if (IS_LITERAL (LTYPE (tree)))
2685 ast *tTree = tree->left;
2686 tree->left = tree->right;
2687 tree->right = tTree;
2690 /* if right is a literal and */
2691 /* we can find a 2nd literal in an and-tree then */
2692 /* rearrange the tree */
2693 if (IS_LITERAL (RTYPE (tree)))
2696 ast *litTree = searchLitOp (tree, &parent, "&");
2700 ast *tTree = litTree->left;
2701 litTree->left = tree->right;
2702 tree->right = tTree;
2703 /* both operands in litTree are literal now */
2704 decorateType (parent, resultType);
2708 LRVAL (tree) = RRVAL (tree) = 1;
2710 TTYPE (tree) = computeType (LTYPE (tree),
2714 TETYPE (tree) = getSpec (TTYPE (tree));
2719 /*------------------------------------------------------------------*/
2720 /*----------------------------*/
2722 /*----------------------------*/
2723 p = newLink (DECLARATOR);
2724 /* if bit field then error */
2725 if (IS_BITVAR (tree->left->etype))
2727 werror (E_ILLEGAL_ADDR, "address of bit variable");
2728 goto errorTreeReturn;
2731 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2733 werror (E_ILLEGAL_ADDR, "address of register variable");
2734 goto errorTreeReturn;
2737 if (IS_FUNC (LTYPE (tree)))
2739 // this ought to be ignored
2740 return (tree->left);
2743 if (IS_LITERAL(LTYPE(tree)))
2745 werror (E_ILLEGAL_ADDR, "address of literal");
2746 goto errorTreeReturn;
2751 werror (E_LVALUE_REQUIRED, "address of");
2752 goto errorTreeReturn;
2755 DCL_TYPE (p) = POINTER;
2756 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2757 DCL_TYPE (p) = CPOINTER;
2758 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2759 DCL_TYPE (p) = FPOINTER;
2760 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2761 DCL_TYPE (p) = PPOINTER;
2762 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2763 DCL_TYPE (p) = IPOINTER;
2764 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2765 DCL_TYPE (p) = EEPPOINTER;
2766 else if (SPEC_OCLS(tree->left->etype))
2767 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2769 DCL_TYPE (p) = POINTER;
2771 if (IS_AST_SYM_VALUE (tree->left))
2773 AST_SYMBOL (tree->left)->addrtaken = 1;
2774 AST_SYMBOL (tree->left)->allocreq = 1;
2777 p->next = LTYPE (tree);
2779 TETYPE (tree) = getSpec (TTYPE (tree));
2784 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2785 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2787 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2788 AST_SYMBOL(tree->left->right));
2789 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2790 valueFromLit(element->offset));
2793 tree->type = EX_VALUE;
2794 tree->values.literalFromCast = 1;
2800 /*------------------------------------------------------------------*/
2801 /*----------------------------*/
2803 /*----------------------------*/
2805 /* if the rewrite succeeds then don't go any further */
2807 ast *wtree = optimizeRRCRLC (tree);
2809 return decorateType (wtree, RESULT_TYPE_NONE);
2811 wtree = optimizeSWAP (tree);
2813 return decorateType (wtree, RESULT_TYPE_NONE);
2816 /* if left is a literal exchange left & right */
2817 if (IS_LITERAL (LTYPE (tree)))
2819 ast *tTree = tree->left;
2820 tree->left = tree->right;
2821 tree->right = tTree;
2824 /* if right is a literal and */
2825 /* we can find a 2nd literal in an or-tree then */
2826 /* rearrange the tree */
2827 if (IS_LITERAL (RTYPE (tree)))
2830 ast *litTree = searchLitOp (tree, &parent, "|");
2834 ast *tTree = litTree->left;
2835 litTree->left = tree->right;
2836 tree->right = tTree;
2837 /* both operands in tTree are literal now */
2838 decorateType (parent, resultType);
2843 /*------------------------------------------------------------------*/
2844 /*----------------------------*/
2846 /*----------------------------*/
2848 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2850 werror (E_BITWISE_OP);
2851 werror (W_CONTINUE, "left & right types are ");
2852 printTypeChain (LTYPE (tree), stderr);
2853 fprintf (stderr, ",");
2854 printTypeChain (RTYPE (tree), stderr);
2855 fprintf (stderr, "\n");
2856 goto errorTreeReturn;
2859 /* if they are both literal then rewrite the tree */
2860 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2862 tree->type = EX_VALUE;
2863 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2864 valFromType (RETYPE (tree)),
2866 tree->right = tree->left = NULL;
2867 TETYPE (tree) = tree->opval.val->etype;
2868 TTYPE (tree) = tree->opval.val->type;
2872 /* if left is a literal exchange left & right */
2873 if (IS_LITERAL (LTYPE (tree)))
2875 ast *tTree = tree->left;
2876 tree->left = tree->right;
2877 tree->right = tTree;
2880 /* if right is a literal and */
2881 /* we can find a 2nd literal in a xor-tree then */
2882 /* rearrange the tree */
2883 if (IS_LITERAL (RTYPE (tree)) &&
2884 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2887 ast *litTree = searchLitOp (tree, &parent, "^");
2891 ast *tTree = litTree->left;
2892 litTree->left = tree->right;
2893 tree->right = tTree;
2894 /* both operands in litTree are literal now */
2895 decorateType (parent, resultType);
2899 LRVAL (tree) = RRVAL (tree) = 1;
2901 TTYPE (tree) = computeType (LTYPE (tree),
2905 TETYPE (tree) = getSpec (TTYPE (tree));
2909 /*------------------------------------------------------------------*/
2910 /*----------------------------*/
2912 /*----------------------------*/
2914 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2916 werror (E_INVALID_OP, "divide");
2917 goto errorTreeReturn;
2919 /* if they are both literal then */
2920 /* rewrite the tree */
2921 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2923 tree->type = EX_VALUE;
2924 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2925 valFromType (RETYPE (tree)));
2926 tree->right = tree->left = NULL;
2927 TETYPE (tree) = getSpec (TTYPE (tree) =
2928 tree->opval.val->type);
2932 LRVAL (tree) = RRVAL (tree) = 1;
2934 TETYPE (tree) = getSpec (TTYPE (tree) =
2935 computeType (LTYPE (tree),
2940 /* if right is a literal and */
2941 /* left is also a division by a literal then */
2942 /* rearrange the tree */
2943 if (IS_LITERAL (RTYPE (tree))
2944 /* avoid infinite loop */
2945 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2948 ast *litTree = searchLitOp (tree, &parent, "/");
2951 if (IS_LITERAL (RTYPE (litTree)))
2955 litTree->right = newNode ('*',
2957 copyAst (tree->right));
2958 litTree->right->lineno = tree->lineno;
2960 tree->right->opval.val = constVal ("1");
2961 decorateType (parent, resultType);
2965 /* litTree->left is literal: no gcse possible.
2966 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2967 this would cause an infinit loop. */
2968 parent->decorated = 1;
2969 decorateType (litTree, resultType);
2976 /*------------------------------------------------------------------*/
2977 /*----------------------------*/
2979 /*----------------------------*/
2981 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2983 werror (E_BITWISE_OP);
2984 werror (W_CONTINUE, "left & right types are ");
2985 printTypeChain (LTYPE (tree), stderr);
2986 fprintf (stderr, ",");
2987 printTypeChain (RTYPE (tree), stderr);
2988 fprintf (stderr, "\n");
2989 goto errorTreeReturn;
2991 /* if they are both literal then */
2992 /* rewrite the tree */
2993 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2995 tree->type = EX_VALUE;
2996 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2997 valFromType (RETYPE (tree)));
2998 tree->right = tree->left = NULL;
2999 TETYPE (tree) = getSpec (TTYPE (tree) =
3000 tree->opval.val->type);
3003 LRVAL (tree) = RRVAL (tree) = 1;
3004 TETYPE (tree) = getSpec (TTYPE (tree) =
3005 computeType (LTYPE (tree),
3011 /*------------------------------------------------------------------*/
3012 /*----------------------------*/
3013 /* address dereference */
3014 /*----------------------------*/
3015 case '*': /* can be unary : if right is null then unary operation */
3018 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3020 werror (E_PTR_REQD);
3021 goto errorTreeReturn;
3026 werror (E_LVALUE_REQUIRED, "pointer deref");
3027 goto errorTreeReturn;
3029 if (IS_ADDRESS_OF_OP(tree->left))
3031 /* replace *&obj with obj */
3032 return tree->left->left;
3034 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3035 TETYPE (tree) = getSpec (TTYPE (tree));
3036 /* adjust the storage class */
3037 switch (DCL_TYPE(tree->left->ftype)) {
3039 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3042 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3045 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3048 SPEC_SCLS (TETYPE (tree)) = 0;
3051 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3054 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3057 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3060 SPEC_SCLS (TETYPE (tree)) = 0;
3069 /*------------------------------------------------------------------*/
3070 /*----------------------------*/
3071 /* multiplication */
3072 /*----------------------------*/
3073 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3075 werror (E_INVALID_OP, "multiplication");
3076 goto errorTreeReturn;
3079 /* if they are both literal then */
3080 /* rewrite the tree */
3081 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3083 tree->type = EX_VALUE;
3084 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3085 valFromType (RETYPE (tree)));
3086 tree->right = tree->left = NULL;
3087 TETYPE (tree) = getSpec (TTYPE (tree) =
3088 tree->opval.val->type);
3092 /* if left is a literal exchange left & right */
3093 if (IS_LITERAL (LTYPE (tree)))
3095 ast *tTree = tree->left;
3096 tree->left = tree->right;
3097 tree->right = tTree;
3100 /* if right is a literal and */
3101 /* we can find a 2nd literal in a mul-tree then */
3102 /* rearrange the tree */
3103 if (IS_LITERAL (RTYPE (tree)))
3106 ast *litTree = searchLitOp (tree, &parent, "*");
3110 ast *tTree = litTree->left;
3111 litTree->left = tree->right;
3112 tree->right = tTree;
3113 /* both operands in litTree are literal now */
3114 decorateType (parent, resultType);
3118 LRVAL (tree) = RRVAL (tree) = 1;
3119 tree->left = addCast (tree->left, resultType, FALSE);
3120 tree->right = addCast (tree->right, resultType, FALSE);
3121 TETYPE (tree) = getSpec (TTYPE (tree) =
3122 computeType (LTYPE (tree),
3129 /*------------------------------------------------------------------*/
3130 /*----------------------------*/
3131 /* unary '+' operator */
3132 /*----------------------------*/
3137 if (!IS_ARITHMETIC (LTYPE (tree)))
3139 werror (E_UNARY_OP, '+');
3140 goto errorTreeReturn;
3143 /* if left is a literal then do it */
3144 if (IS_LITERAL (LTYPE (tree)))
3146 tree->type = EX_VALUE;
3147 tree->opval.val = valFromType (LETYPE (tree));
3149 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3153 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3157 /*------------------------------------------------------------------*/
3158 /*----------------------------*/
3160 /*----------------------------*/
3162 /* this is not a unary operation */
3163 /* if both pointers then problem */
3164 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3165 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3167 werror (E_PTR_PLUS_PTR);
3168 goto errorTreeReturn;
3171 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3172 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3174 werror (E_PLUS_INVALID, "+");
3175 goto errorTreeReturn;
3178 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3179 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3181 werror (E_PLUS_INVALID, "+");
3182 goto errorTreeReturn;
3184 /* if they are both literal then */
3185 /* rewrite the tree */
3186 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3188 tree->type = EX_VALUE;
3189 tree->left = addCast (tree->left, resultType, TRUE);
3190 tree->right = addCast (tree->right, resultType, TRUE);
3191 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3192 valFromType (RETYPE (tree)));
3193 tree->right = tree->left = NULL;
3194 TETYPE (tree) = getSpec (TTYPE (tree) =
3195 tree->opval.val->type);
3199 /* if the right is a pointer or left is a literal
3200 xchange left & right */
3201 if (IS_ARRAY (RTYPE (tree)) ||
3202 IS_PTR (RTYPE (tree)) ||
3203 IS_LITERAL (LTYPE (tree)))
3205 ast *tTree = tree->left;
3206 tree->left = tree->right;
3207 tree->right = tTree;
3210 /* if right is a literal and */
3211 /* left is also an addition/subtraction with a literal then */
3212 /* rearrange the tree */
3213 if (IS_LITERAL (RTYPE (tree)))
3215 ast *litTree, *parent;
3216 litTree = searchLitOp (tree, &parent, "+-");
3219 if (litTree->opval.op == '+')
3223 ast *tTree = litTree->left;
3224 litTree->left = tree->right;
3225 tree->right = tree->left;
3228 else if (litTree->opval.op == '-')
3230 if (IS_LITERAL (RTYPE (litTree)))
3234 ast *tTree = litTree->left;
3235 litTree->left = tree->right;
3236 tree->right = tTree;
3242 ast *tTree = litTree->right;
3243 litTree->right = tree->right;
3244 tree->right = tTree;
3245 litTree->opval.op = '+';
3246 tree->opval.op = '-';
3249 decorateType (parent, resultType);
3253 LRVAL (tree) = RRVAL (tree) = 1;
3254 /* if the left is a pointer */
3255 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3256 TETYPE (tree) = getSpec (TTYPE (tree) =
3260 tree->left = addCast (tree->left, resultType, TRUE);
3261 tree->right = addCast (tree->right, resultType, TRUE);
3262 TETYPE (tree) = getSpec (TTYPE (tree) =
3263 computeType (LTYPE (tree),
3271 /*------------------------------------------------------------------*/
3272 /*----------------------------*/
3274 /*----------------------------*/
3275 case '-': /* can be unary */
3276 /* if right is null then unary */
3280 if (!IS_ARITHMETIC (LTYPE (tree)))
3282 werror (E_UNARY_OP, tree->opval.op);
3283 goto errorTreeReturn;
3286 /* if left is a literal then do it */
3287 if (IS_LITERAL (LTYPE (tree)))
3289 tree->type = EX_VALUE;
3290 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3292 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3295 tree->left = addCast (tree->left, resultType, TRUE);
3296 TETYPE (tree) = getSpec (TTYPE (tree) =
3297 computeType (LTYPE (tree),
3305 /*------------------------------------------------------------------*/
3306 /*----------------------------*/
3308 /*----------------------------*/
3310 if (!(IS_PTR (LTYPE (tree)) ||
3311 IS_ARRAY (LTYPE (tree)) ||
3312 IS_ARITHMETIC (LTYPE (tree))))
3314 werror (E_PLUS_INVALID, "-");
3315 goto errorTreeReturn;
3318 if (!(IS_PTR (RTYPE (tree)) ||
3319 IS_ARRAY (RTYPE (tree)) ||
3320 IS_ARITHMETIC (RTYPE (tree))))
3322 werror (E_PLUS_INVALID, "-");
3323 goto errorTreeReturn;
3326 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3327 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3328 IS_INTEGRAL (RTYPE (tree))))
3330 werror (E_PLUS_INVALID, "-");
3331 goto errorTreeReturn;
3334 /* if they are both literal then */
3335 /* rewrite the tree */
3336 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3338 tree->type = EX_VALUE;
3339 tree->left = addCast (tree->left, resultType, TRUE);
3340 tree->right = addCast (tree->right, resultType, TRUE);
3341 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3342 valFromType (RETYPE (tree)));
3343 tree->right = tree->left = NULL;
3344 TETYPE (tree) = getSpec (TTYPE (tree) =
3345 tree->opval.val->type);
3349 /* if the left & right are equal then zero */
3350 if (isAstEqual (tree->left, tree->right))
3352 tree->type = EX_VALUE;
3353 tree->left = tree->right = NULL;
3354 tree->opval.val = constVal ("0");
3355 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3359 /* if both of them are pointers or arrays then */
3360 /* the result is going to be an integer */
3361 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3362 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3363 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3365 /* if only the left is a pointer */
3366 /* then result is a pointer */
3367 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3368 TETYPE (tree) = getSpec (TTYPE (tree) =
3372 tree->left = addCast (tree->left, resultType, TRUE);
3373 tree->right = addCast (tree->right, resultType, TRUE);
3375 TETYPE (tree) = getSpec (TTYPE (tree) =
3376 computeType (LTYPE (tree),
3382 LRVAL (tree) = RRVAL (tree) = 1;
3384 /* if right is a literal and */
3385 /* left is also an addition/subtraction with a literal then */
3386 /* rearrange the tree */
3387 if (IS_LITERAL (RTYPE (tree))
3388 /* avoid infinite loop */
3389 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3391 ast *litTree, *litParent;
3392 litTree = searchLitOp (tree, &litParent, "+-");
3395 if (litTree->opval.op == '+')
3399 ast *tTree = litTree->left;
3400 litTree->left = litTree->right;
3401 litTree->right = tree->right;
3402 tree->right = tTree;
3403 tree->opval.op = '+';
3404 litTree->opval.op = '-';
3406 else if (litTree->opval.op == '-')
3408 if (IS_LITERAL (RTYPE (litTree)))
3412 ast *tTree = litTree->left;
3413 litTree->left = tree->right;
3414 tree->right = litParent->left;
3415 litParent->left = tTree;
3416 litTree->opval.op = '+';
3418 tree->decorated = 0;
3419 decorateType (tree, resultType);
3425 ast *tTree = litTree->right;
3426 litTree->right = tree->right;
3427 tree->right = tTree;
3430 decorateType (litParent, resultType);
3435 /*------------------------------------------------------------------*/
3436 /*----------------------------*/
3438 /*----------------------------*/
3440 /* can be only integral type */
3441 if (!IS_INTEGRAL (LTYPE (tree)))
3443 werror (E_UNARY_OP, tree->opval.op);
3444 goto errorTreeReturn;
3447 /* if left is a literal then do it */
3448 if (IS_LITERAL (LTYPE (tree)))
3450 tree->type = EX_VALUE;
3451 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3453 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3454 return addCast (tree, resultType, TRUE);
3457 if (resultType == RESULT_TYPE_BIT &&
3458 IS_UNSIGNED (tree->left->etype) &&
3459 getSize (tree->left->etype) < INTSIZE)
3461 /* promotion rules are responsible for this strange result:
3462 bit -> int -> ~int -> bit
3463 uchar -> int -> ~int -> bit
3465 werror(W_COMPLEMENT);
3467 /* optimize bit-result, even if we optimize a buggy source */
3468 tree->type = EX_VALUE;
3469 tree->opval.val = constVal ("1");
3472 tree->left = addCast (tree->left, resultType, TRUE);
3474 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3477 /*------------------------------------------------------------------*/
3478 /*----------------------------*/
3480 /*----------------------------*/
3482 /* can be pointer */
3483 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3484 !IS_PTR (LTYPE (tree)) &&
3485 !IS_ARRAY (LTYPE (tree)))
3487 werror (E_UNARY_OP, tree->opval.op);
3488 goto errorTreeReturn;
3491 /* if left is a literal then do it */
3492 if (IS_LITERAL (LTYPE (tree)))
3494 tree->type = EX_VALUE;
3495 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3497 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3501 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3504 /*------------------------------------------------------------------*/
3505 /*----------------------------*/
3507 /*----------------------------*/
3511 TTYPE (tree) = LTYPE (tree);
3512 TETYPE (tree) = LETYPE (tree);
3517 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3521 TTYPE (tree) = TETYPE (tree) = newCharLink();
3525 TTYPE (tree) = TETYPE (tree) = newIntLink();
3530 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3532 werror (E_SHIFT_OP_INVALID);
3533 werror (W_CONTINUE, "left & right types are ");
3534 printTypeChain (LTYPE (tree), stderr);
3535 fprintf (stderr, ",");
3536 printTypeChain (RTYPE (tree), stderr);
3537 fprintf (stderr, "\n");
3538 goto errorTreeReturn;
3541 /* make smaller type only if it's a LEFT_OP */
3542 if (tree->opval.op == LEFT_OP)
3543 tree->left = addCast (tree->left, resultType, TRUE);
3545 /* if they are both literal then */
3546 /* rewrite the tree */
3547 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3549 tree->type = EX_VALUE;
3550 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3551 valFromType (RETYPE (tree)),
3552 (tree->opval.op == LEFT_OP ? 1 : 0));
3553 tree->right = tree->left = NULL;
3554 TETYPE (tree) = getSpec (TTYPE (tree) =
3555 tree->opval.val->type);
3559 /* see if this is a GETBYTE operation if yes
3562 ast *otree = optimizeGetByte (tree, resultType);
3565 return decorateType (otree, RESULT_TYPE_NONE);
3568 /* see if this is a GETWORD operation if yes
3571 ast *otree = optimizeGetWord (tree, resultType);
3574 return decorateType (otree, RESULT_TYPE_NONE);
3577 LRVAL (tree) = RRVAL (tree) = 1;
3578 if (tree->opval.op == LEFT_OP)
3580 TETYPE (tree) = getSpec (TTYPE (tree) =
3581 computeType (LTYPE (tree),
3588 /* no promotion necessary */
3589 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3590 if (IS_LITERAL (TTYPE (tree)))
3591 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3594 /* if only the right side is a literal & we are
3595 shifting more than size of the left operand then zero */
3596 if (IS_LITERAL (RTYPE (tree)) &&
3597 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3598 (getSize (TETYPE (tree)) * 8))
3600 if (tree->opval.op==LEFT_OP ||
3601 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3603 lineno=tree->lineno;
3604 werror (W_SHIFT_CHANGED,
3605 (tree->opval.op == LEFT_OP ? "left" : "right"));
3606 tree->type = EX_VALUE;
3607 tree->left = tree->right = NULL;
3608 tree->opval.val = constVal ("0");
3609 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3616 /*------------------------------------------------------------------*/
3617 /*----------------------------*/
3619 /*----------------------------*/
3620 case CAST: /* change the type */
3621 /* cannot cast to an aggregate type */
3622 if (IS_AGGREGATE (LTYPE (tree)))
3624 werror (E_CAST_ILLEGAL);
3625 goto errorTreeReturn;
3628 /* make sure the type is complete and sane */
3629 changePointer(LTYPE(tree));
3630 checkTypeSanity(LETYPE(tree), "(cast)");
3632 /* if 'from' and 'to' are the same remove the superflous cast, */
3633 /* this helps other optimizations */
3634 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3639 /* If code memory is read only, then pointers to code memory */
3640 /* implicitly point to constants -- make this explicit */
3642 sym_link *t = LTYPE(tree);
3643 while (t && t->next)
3645 if (IS_CODEPTR(t) && port->mem.code_ro)
3647 if (IS_SPEC(t->next))
3648 SPEC_CONST (t->next) = 1;
3650 DCL_PTR_CONST (t->next) = 1;
3657 /* if the right is a literal replace the tree */
3658 if (IS_LITERAL (RETYPE (tree))) {
3659 if (!IS_PTR (LTYPE (tree))) {
3660 tree->type = EX_VALUE;
3662 valCastLiteral (LTYPE (tree),
3663 floatFromVal (valFromType (RETYPE (tree))));
3666 TTYPE (tree) = tree->opval.val->type;
3667 tree->values.literalFromCast = 1;
3668 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3669 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3670 sym_link *rest = LTYPE(tree)->next;
3671 werror(W_LITERAL_GENERIC);
3672 TTYPE(tree) = newLink(DECLARATOR);
3673 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3674 TTYPE(tree)->next = rest;
3675 tree->left->opval.lnk = TTYPE(tree);
3678 TTYPE (tree) = LTYPE (tree);
3682 TTYPE (tree) = LTYPE (tree);
3686 #if 0 // this is already checked, now this could be explicit
3687 /* if pointer to struct then check names */
3688 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3689 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3690 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3692 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3693 SPEC_STRUCT(LETYPE(tree))->tag);
3696 if (IS_ADDRESS_OF_OP(tree->right)
3697 && IS_AST_SYM_VALUE (tree->right->left)
3698 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3700 symbol * sym = AST_SYMBOL (tree->right->left);
3701 unsigned int gptype = 0;
3702 unsigned int addr = SPEC_ADDR (sym->etype);
3704 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3706 switch (SPEC_SCLS (sym->etype))
3709 gptype = GPTYPE_CODE;
3712 gptype = GPTYPE_FAR;
3716 gptype = GPTYPE_NEAR;
3719 gptype = GPTYPE_XSTACK;
3724 addr |= gptype << (8*(GPTRSIZE - 1));
3727 tree->type = EX_VALUE;
3729 valCastLiteral (LTYPE (tree), addr);
3730 TTYPE (tree) = tree->opval.val->type;
3731 TETYPE (tree) = getSpec (TTYPE (tree));
3734 tree->values.literalFromCast = 1;
3738 /* handle offsetof macro: */
3739 /* #define offsetof(TYPE, MEMBER) \ */
3740 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3741 if (IS_ADDRESS_OF_OP(tree->right)
3742 && IS_AST_OP (tree->right->left)
3743 && tree->right->left->opval.op == PTR_OP
3744 && IS_AST_OP (tree->right->left->left)
3745 && tree->right->left->left->opval.op == CAST
3746 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3748 symbol *element = getStructElement (
3749 SPEC_STRUCT (LETYPE(tree->right->left)),
3750 AST_SYMBOL(tree->right->left->right)
3754 tree->type = EX_VALUE;
3755 tree->opval.val = valCastLiteral (
3758 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3761 TTYPE (tree) = tree->opval.val->type;
3762 TETYPE (tree) = getSpec (TTYPE (tree));
3769 /* if the right is a literal replace the tree */
3770 if (IS_LITERAL (RETYPE (tree))) {
3772 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3773 /* rewrite (type *)litaddr
3775 and define type at litaddr temp
3776 (but only if type's storage class is not generic)
3778 ast *newTree = newNode ('&', NULL, NULL);
3781 TTYPE (newTree) = LTYPE (tree);
3782 TETYPE (newTree) = getSpec(LTYPE (tree));
3784 /* define a global symbol at the casted address*/
3785 sym = newSymbol(genSymName (0), 0);
3786 sym->type = LTYPE (tree)->next;
3788 sym->type = newLink (V_VOID);
3789 sym->etype = getSpec(sym->type);
3790 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3791 sym->lineDef = tree->lineno;
3794 SPEC_STAT (sym->etype) = 1;
3795 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3796 SPEC_ABSA(sym->etype) = 1;
3797 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3800 newTree->left = newAst_VALUE(symbolVal(sym));
3801 newTree->left->lineno = tree->lineno;
3802 LTYPE (newTree) = sym->type;
3803 LETYPE (newTree) = sym->etype;
3804 LLVAL (newTree) = 1;
3805 LRVAL (newTree) = 0;
3806 TLVAL (newTree) = 1;
3810 if (!IS_PTR (LTYPE (tree))) {
3811 tree->type = EX_VALUE;
3813 valCastLiteral (LTYPE (tree),
3814 floatFromVal (valFromType (RTYPE (tree))));
3815 TTYPE (tree) = tree->opval.val->type;
3818 tree->values.literalFromCast = 1;
3819 TETYPE (tree) = getSpec (TTYPE (tree));
3823 TTYPE (tree) = LTYPE (tree);
3827 TETYPE (tree) = getSpec (TTYPE (tree));
3831 /*------------------------------------------------------------------*/
3832 /*----------------------------*/
3833 /* logical &&, || */
3834 /*----------------------------*/
3837 /* each must be arithmetic type or be a pointer */
3838 if (!IS_PTR (LTYPE (tree)) &&
3839 !IS_ARRAY (LTYPE (tree)) &&
3840 !IS_INTEGRAL (LTYPE (tree)))
3842 werror (E_COMPARE_OP);
3843 goto errorTreeReturn;
3846 if (!IS_PTR (RTYPE (tree)) &&
3847 !IS_ARRAY (RTYPE (tree)) &&
3848 !IS_INTEGRAL (RTYPE (tree)))
3850 werror (E_COMPARE_OP);
3851 goto errorTreeReturn;
3853 /* if they are both literal then */
3854 /* rewrite the tree */
3855 if (IS_LITERAL (RTYPE (tree)) &&
3856 IS_LITERAL (LTYPE (tree)))
3858 tree->type = EX_VALUE;
3859 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3860 valFromType (RTYPE (tree)),
3862 tree->right = tree->left = NULL;
3863 TETYPE (tree) = getSpec (TTYPE (tree) =
3864 tree->opval.val->type);
3867 LRVAL (tree) = RRVAL (tree) = 1;
3868 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3871 /*------------------------------------------------------------------*/
3872 /*----------------------------*/
3873 /* comparison operators */
3874 /*----------------------------*/
3882 ast *lt = optimizeCompare (tree);
3888 /* if they are pointers they must be castable */
3889 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3891 if (tree->opval.op==EQ_OP &&
3892 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3893 // we cannot cast a gptr to a !gptr: switch the leaves
3894 struct ast *s=tree->left;
3895 tree->left=tree->right;
3898 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3900 werror (E_COMPARE_OP);
3901 fprintf (stderr, "comparing type ");
3902 printTypeChain (LTYPE (tree), stderr);
3903 fprintf (stderr, "to type ");
3904 printTypeChain (RTYPE (tree), stderr);
3905 fprintf (stderr, "\n");
3906 goto errorTreeReturn;
3909 /* else they should be promotable to one another */
3912 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3913 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3915 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3917 werror (E_COMPARE_OP);
3918 fprintf (stderr, "comparing type ");
3919 printTypeChain (LTYPE (tree), stderr);
3920 fprintf (stderr, "to type ");
3921 printTypeChain (RTYPE (tree), stderr);
3922 fprintf (stderr, "\n");
3923 goto errorTreeReturn;
3927 /* if unsigned value < 0 then always false */
3928 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3929 if (SPEC_USIGN(LETYPE(tree)) &&
3930 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3931 IS_LITERAL(RTYPE(tree)) &&
3932 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3934 if (tree->opval.op == '<')
3938 if (tree->opval.op == '>')
3940 if (resultType == RESULT_TYPE_IFX)
3942 /* the parent is an ifx: */
3943 /* if (unsigned value) */
3947 /* (unsigned value) ? 1 : 0 */
3948 tree->opval.op = '?';
3949 tree->right = newNode (':',
3950 newAst_VALUE (constVal ("1")),
3951 tree->right); /* val 0 */
3952 tree->right->lineno = tree->lineno;
3953 tree->right->left->lineno = tree->lineno;
3954 tree->decorated = 0;
3955 return decorateType (tree, resultType);
3959 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
3960 if (IS_LITERAL(RTYPE(tree)) &&
3961 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
3962 tree->opval.op == EQ_OP &&
3963 resultType == RESULT_TYPE_IFX)
3965 tree->opval.op = '!';
3967 tree->decorated = 0;
3968 return decorateType (tree, resultType);
3971 /* if they are both literal then */
3972 /* rewrite the tree */
3973 if (IS_LITERAL (RTYPE (tree)) &&
3974 IS_LITERAL (LTYPE (tree)))
3976 tree->type = EX_VALUE;
3977 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3978 valFromType (RETYPE (tree)),
3980 tree->right = tree->left = NULL;
3981 TETYPE (tree) = getSpec (TTYPE (tree) =
3982 tree->opval.val->type);
3985 /* if one is 'signed char ' and the other one is 'unsigned char' */
3986 /* it's necessary to promote to int */
3987 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
3988 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
3990 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
3991 if it's possible to use a 'signed char' */
3993 /* is left a 'unsigned char'? */
3994 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
3995 /* the value range of a 'unsigned char' is 0...255;
3996 if the actual value is < 128 it can be changed to signed */
3997 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
3999 /* now we've got 2 'signed char'! */
4000 SPEC_USIGN (RETYPE (tree)) = 0;
4002 /* same test for the left operand: */
4003 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4004 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4006 SPEC_USIGN (LETYPE (tree)) = 0;
4010 werror (W_CMP_SU_CHAR);
4011 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4012 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4016 LRVAL (tree) = RRVAL (tree) = 1;
4017 TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4020 /*------------------------------------------------------------------*/
4021 /*----------------------------*/
4023 /*----------------------------*/
4024 case SIZEOF: /* evaluate wihout code generation */
4025 /* change the type to a integer */
4027 int size = getSize (tree->right->ftype);
4028 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4029 if (!size && !IS_VOID(tree->right->ftype))
4030 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4032 tree->type = EX_VALUE;
4033 tree->opval.val = constVal (buffer);
4034 tree->right = tree->left = NULL;
4035 TETYPE (tree) = getSpec (TTYPE (tree) =
4036 tree->opval.val->type);
4039 /*------------------------------------------------------------------*/
4040 /*----------------------------*/
4042 /*----------------------------*/
4044 /* return typeof enum value */
4045 tree->type = EX_VALUE;
4048 if (IS_SPEC(tree->right->ftype)) {
4049 switch (SPEC_NOUN(tree->right->ftype)) {
4051 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4052 else typeofv = TYPEOF_INT;
4055 typeofv = TYPEOF_FLOAT;
4058 typeofv = TYPEOF_FIXED16X16;
4061 typeofv = TYPEOF_CHAR;
4064 typeofv = TYPEOF_VOID;
4067 typeofv = TYPEOF_STRUCT;
4070 typeofv = TYPEOF_BITFIELD;
4073 typeofv = TYPEOF_BIT;
4076 typeofv = TYPEOF_SBIT;
4082 switch (DCL_TYPE(tree->right->ftype)) {
4084 typeofv = TYPEOF_POINTER;
4087 typeofv = TYPEOF_FPOINTER;
4090 typeofv = TYPEOF_CPOINTER;
4093 typeofv = TYPEOF_GPOINTER;
4096 typeofv = TYPEOF_PPOINTER;
4099 typeofv = TYPEOF_IPOINTER;
4102 typeofv = TYPEOF_ARRAY;
4105 typeofv = TYPEOF_FUNCTION;
4111 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4112 tree->opval.val = constVal (buffer);
4113 tree->right = tree->left = NULL;
4114 TETYPE (tree) = getSpec (TTYPE (tree) =
4115 tree->opval.val->type);
4118 /*------------------------------------------------------------------*/
4119 /*----------------------------*/
4120 /* conditional operator '?' */
4121 /*----------------------------*/
4123 /* the type is value of the colon operator (on the right) */
4124 assert (IS_COLON_OP (tree->right));
4125 /* if already known then replace the tree : optimizer will do it
4126 but faster to do it here */
4127 if (IS_LITERAL (LTYPE (tree)))
4129 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4130 return decorateType (tree->right->left, resultTypeProp);
4132 return decorateType (tree->right->right, resultTypeProp);
4136 tree->right = decorateType (tree->right, resultTypeProp);
4137 TTYPE (tree) = RTYPE (tree);
4138 TETYPE (tree) = getSpec (TTYPE (tree));
4143 /* if they don't match we have a problem */
4144 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4145 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4147 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4148 goto errorTreeReturn;
4151 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4152 resultType, tree->opval.op);
4153 TETYPE (tree) = getSpec (TTYPE (tree));
4157 #if 0 // assignment operators are converted by the parser
4158 /*------------------------------------------------------------------*/
4159 /*----------------------------*/
4160 /* assignment operators */
4161 /*----------------------------*/
4164 /* for these it must be both must be integral */
4165 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4166 !IS_ARITHMETIC (RTYPE (tree)))
4168 werror (E_OPS_INTEGRAL);
4169 goto errorTreeReturn;
4172 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4174 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4175 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4179 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4180 goto errorTreeReturn;
4191 /* for these it must be both must be integral */
4192 if (!IS_INTEGRAL (LTYPE (tree)) ||
4193 !IS_INTEGRAL (RTYPE (tree)))
4195 werror (E_OPS_INTEGRAL);
4196 goto errorTreeReturn;
4199 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4201 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4202 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4206 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4207 goto errorTreeReturn;
4213 /*------------------------------------------------------------------*/
4214 /*----------------------------*/
4216 /*----------------------------*/
4218 if (!(IS_PTR (LTYPE (tree)) ||
4219 IS_ARITHMETIC (LTYPE (tree))))
4221 werror (E_PLUS_INVALID, "-=");
4222 goto errorTreeReturn;
4225 if (!(IS_PTR (RTYPE (tree)) ||
4226 IS_ARITHMETIC (RTYPE (tree))))
4228 werror (E_PLUS_INVALID, "-=");
4229 goto errorTreeReturn;
4232 TETYPE (tree) = getSpec (TTYPE (tree) =
4233 computeType (LTYPE (tree),
4238 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4239 werror (E_CODE_WRITE, "-=");
4243 werror (E_LVALUE_REQUIRED, "-=");
4244 goto errorTreeReturn;
4250 /*------------------------------------------------------------------*/
4251 /*----------------------------*/
4253 /*----------------------------*/
4255 /* this is not a unary operation */
4256 /* if both pointers then problem */
4257 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4259 werror (E_PTR_PLUS_PTR);
4260 goto errorTreeReturn;
4263 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4265 werror (E_PLUS_INVALID, "+=");
4266 goto errorTreeReturn;
4269 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4271 werror (E_PLUS_INVALID, "+=");
4272 goto errorTreeReturn;
4275 TETYPE (tree) = getSpec (TTYPE (tree) =
4276 computeType (LTYPE (tree),
4281 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4282 werror (E_CODE_WRITE, "+=");
4286 werror (E_LVALUE_REQUIRED, "+=");
4287 goto errorTreeReturn;
4290 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4291 tree->opval.op = '=';
4296 /*------------------------------------------------------------------*/
4297 /*----------------------------*/
4298 /* straight assignemnt */
4299 /*----------------------------*/
4301 /* cannot be an aggregate */
4302 if (IS_AGGREGATE (LTYPE (tree)))
4304 werror (E_AGGR_ASSIGN);
4305 goto errorTreeReturn;
4308 /* they should either match or be castable */
4309 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4311 werror (E_TYPE_MISMATCH, "assignment", " ");
4312 printFromToType(RTYPE(tree),LTYPE(tree));
4315 /* if the left side of the tree is of type void
4316 then report error */
4317 if (IS_VOID (LTYPE (tree)))
4319 werror (E_CAST_ZERO);
4320 printFromToType(RTYPE(tree), LTYPE(tree));
4323 TETYPE (tree) = getSpec (TTYPE (tree) =
4327 if (!tree->initMode ) {
4328 if (IS_CONSTANT(LTYPE(tree)))
4329 werror (E_CODE_WRITE, "=");
4333 werror (E_LVALUE_REQUIRED, "=");
4334 goto errorTreeReturn;
4339 /*------------------------------------------------------------------*/
4340 /*----------------------------*/
4341 /* comma operator */
4342 /*----------------------------*/
4344 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4347 /*------------------------------------------------------------------*/
4348 /*----------------------------*/
4350 /*----------------------------*/
4353 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4354 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4356 if (tree->left->opval.op == '*' && !tree->left->right)
4357 tree->left = tree->left->left;
4360 /* require a function or pointer to function */
4361 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4363 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4364 goto errorTreeReturn;
4367 /* if there are parms, make sure that
4368 parms are decorate / process / reverse only once */
4370 !tree->right->decorated)
4375 if (IS_FUNCPTR (LTYPE (tree)))
4377 functype = LTYPE (tree)->next;
4378 processFuncPtrArgs (functype);
4381 functype = LTYPE (tree);
4383 if (processParms (tree->left, FUNC_ARGS(functype),
4384 &tree->right, &parmNumber, TRUE))
4386 goto errorTreeReturn;
4389 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4390 !IFFUNC_ISBUILTIN(functype))
4392 reverseParms (tree->right);
4395 TTYPE (tree) = functype->next;
4396 TETYPE (tree) = getSpec (TTYPE (tree));
4400 /*------------------------------------------------------------------*/
4401 /*----------------------------*/
4402 /* return statement */
4403 /*----------------------------*/
4408 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4410 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4411 printFromToType (RTYPE(tree), currFunc->type->next);
4412 goto errorTreeReturn;
4415 if (IS_VOID (currFunc->type->next)
4417 !IS_VOID (RTYPE (tree)))
4419 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4420 goto errorTreeReturn;
4423 /* if there is going to be a casting required then add it */
4424 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4427 decorateType (newNode (CAST,
4428 newAst_LINK (copyLinkChain (currFunc->type->next)),
4438 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4440 werror (W_VOID_FUNC, currFunc->name);
4441 goto errorTreeReturn;
4444 TTYPE (tree) = TETYPE (tree) = NULL;
4447 /*------------------------------------------------------------------*/
4448 /*----------------------------*/
4449 /* switch statement */
4450 /*----------------------------*/
4452 /* the switch value must be an integer */
4453 if (!IS_INTEGRAL (LTYPE (tree)))
4455 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4456 goto errorTreeReturn;
4459 TTYPE (tree) = TETYPE (tree) = NULL;
4462 /*------------------------------------------------------------------*/
4463 /*----------------------------*/
4465 /*----------------------------*/
4467 tree->left = backPatchLabels (tree->left,
4470 TTYPE (tree) = TETYPE (tree) = NULL;
4473 /*------------------------------------------------------------------*/
4474 /*----------------------------*/
4476 /*----------------------------*/
4479 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4480 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4481 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4483 /* if the for loop is reversible then
4484 reverse it otherwise do what we normally
4490 if (isLoopReversible (tree, &sym, &init, &end))
4491 return reverseLoop (tree, sym, init, end);
4493 return decorateType (createFor (AST_FOR (tree, trueLabel),
4494 AST_FOR (tree, continueLabel),
4495 AST_FOR (tree, falseLabel),
4496 AST_FOR (tree, condLabel),
4497 AST_FOR (tree, initExpr),
4498 AST_FOR (tree, condExpr),
4499 AST_FOR (tree, loopExpr),
4500 tree->left), RESULT_TYPE_NONE);
4503 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4504 "node PARAM shouldn't be processed here");
4505 /* but in processParams() */
4508 TTYPE (tree) = TETYPE (tree) = NULL;
4512 /* some error found this tree will be killed */
4514 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4515 tree->opval.op = NULLOP;
4521 /*-----------------------------------------------------------------*/
4522 /* sizeofOp - processes size of operation */
4523 /*-----------------------------------------------------------------*/
4525 sizeofOp (sym_link * type)
4530 /* make sure the type is complete and sane */
4531 checkTypeSanity(type, "(sizeof)");
4533 /* get the size and convert it to character */
4534 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4535 if (!size && !IS_VOID(type))
4536 werror (E_SIZEOF_INCOMPLETE_TYPE);
4538 /* now convert into value */
4539 return constVal (buff);
4543 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4544 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4545 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4546 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4547 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4548 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4549 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4551 /*-----------------------------------------------------------------*/
4552 /* backPatchLabels - change and or not operators to flow control */
4553 /*-----------------------------------------------------------------*/
4555 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4561 if (!(IS_ANDORNOT (tree)))
4564 /* if this an and */
4567 static int localLbl = 0;
4570 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4571 localLabel = newSymbol (buffer, NestLevel);
4573 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4575 /* if left is already a IFX then just change the if true label in that */
4576 if (!IS_IFX (tree->left))
4577 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4579 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4580 /* right is a IFX then just join */
4581 if (IS_IFX (tree->right))
4582 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4584 tree->right = createLabel (localLabel, tree->right);
4585 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4587 return newNode (NULLOP, tree->left, tree->right);
4590 /* if this is an or operation */
4593 static int localLbl = 0;
4596 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4597 localLabel = newSymbol (buffer, NestLevel);
4599 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4601 /* if left is already a IFX then just change the if true label in that */
4602 if (!IS_IFX (tree->left))
4603 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4605 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4606 /* right is a IFX then just join */
4607 if (IS_IFX (tree->right))
4608 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4610 tree->right = createLabel (localLabel, tree->right);
4611 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4613 return newNode (NULLOP, tree->left, tree->right);
4619 /* call with exchanged labels */
4620 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4622 /* if left isn't already a IFX */
4623 if (!IS_IFX (tree->left))
4625 tree->left = newNode (IFX, tree->left, NULL);
4626 tree->left->trueLabel = falseLabel;
4627 tree->left->falseLabel = trueLabel;
4634 tree->trueLabel = trueLabel;
4635 tree->falseLabel = falseLabel;
4642 /*-----------------------------------------------------------------*/
4643 /* createBlock - create expression tree for block */
4644 /*-----------------------------------------------------------------*/
4646 createBlock (symbol * decl, ast * body)
4650 /* if the block has nothing */
4654 ex = newNode (BLOCK, NULL, body);
4655 ex->values.sym = decl;
4662 /*-----------------------------------------------------------------*/
4663 /* createLabel - creates the expression tree for labels */
4664 /*-----------------------------------------------------------------*/
4666 createLabel (symbol * label, ast * stmnt)
4669 char name[SDCC_NAME_MAX + 1];
4672 /* must create fresh symbol if the symbol name */
4673 /* exists in the symbol table, since there can */
4674 /* be a variable with the same name as the labl */
4675 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4676 (csym->level == label->level))
4677 label = newSymbol (label->name, label->level);
4679 /* change the name before putting it in add _ */
4680 SNPRINTF(name, sizeof(name), "%s", label->name);
4682 /* put the label in the LabelSymbol table */
4683 /* but first check if a label of the same */
4685 if ((csym = findSym (LabelTab, NULL, name)))
4686 werror (E_DUPLICATE_LABEL, label->name);
4688 addSym (LabelTab, label, name, label->level, 0, 0);
4692 label->key = labelKey++;
4693 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4699 /*-----------------------------------------------------------------*/
4700 /* createCase - generates the parsetree for a case statement */
4701 /*-----------------------------------------------------------------*/
4703 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4705 char caseLbl[SDCC_NAME_MAX + 1];
4709 /* if the switch statement does not exist */
4710 /* then case is out of context */
4713 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4717 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4718 /* if not a constant then error */
4719 if (!IS_LITERAL (caseVal->ftype))
4721 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4725 /* if not a integer than error */
4726 if (!IS_INTEGRAL (caseVal->ftype))
4728 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4732 /* find the end of the switch values chain */
4733 if (!(val = swStat->values.switchVals.swVals))
4734 swStat->values.switchVals.swVals = caseVal->opval.val;
4737 /* also order the cases according to value */
4739 int cVal = (int) floatFromVal (caseVal->opval.val);
4740 while (val && (int) floatFromVal (val) < cVal)
4746 /* if we reached the end then */
4749 pval->next = caseVal->opval.val;
4751 else if ((int) floatFromVal (val) == cVal)
4753 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4759 /* we found a value greater than */
4760 /* the current value we must add this */
4761 /* before the value */
4762 caseVal->opval.val->next = val;
4764 /* if this was the first in chain */
4765 if (swStat->values.switchVals.swVals == val)
4766 swStat->values.switchVals.swVals =
4769 pval->next = caseVal->opval.val;
4774 /* create the case label */
4775 SNPRINTF(caseLbl, sizeof(caseLbl),
4777 swStat->values.switchVals.swNum,
4778 (int) floatFromVal (caseVal->opval.val));
4780 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4785 /*-----------------------------------------------------------------*/
4786 /* createDefault - creates the parse tree for the default statement */
4787 /*-----------------------------------------------------------------*/
4789 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4791 char defLbl[SDCC_NAME_MAX + 1];
4793 /* if the switch statement does not exist */
4794 /* then case is out of context */
4797 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4801 if (swStat->values.switchVals.swDefault)
4803 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4808 /* turn on the default flag */
4809 swStat->values.switchVals.swDefault = 1;
4811 /* create the label */
4812 SNPRINTF (defLbl, sizeof(defLbl),
4813 "_default_%d", swStat->values.switchVals.swNum);
4814 return createLabel (newSymbol (defLbl, 0), stmnt);
4817 /*-----------------------------------------------------------------*/
4818 /* createIf - creates the parsetree for the if statement */
4819 /*-----------------------------------------------------------------*/
4821 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4823 static int Lblnum = 0;
4825 symbol *ifTrue, *ifFalse, *ifEnd;
4827 /* if neither exists */
4828 if (!elseBody && !ifBody) {
4829 // if there are no side effects (i++, j() etc)
4830 if (!hasSEFcalls(condAst)) {
4835 /* create the labels */
4836 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4837 ifFalse = newSymbol (buffer, NestLevel);
4838 /* if no else body then end == false */
4843 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4844 ifEnd = newSymbol (buffer, NestLevel);
4847 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4848 ifTrue = newSymbol (buffer, NestLevel);
4852 /* attach the ifTrue label to the top of it body */
4853 ifBody = createLabel (ifTrue, ifBody);
4854 /* attach a goto end to the ifBody if else is present */
4857 ifBody = newNode (NULLOP, ifBody,
4859 newAst_VALUE (symbolVal (ifEnd)),
4861 /* put the elseLabel on the else body */
4862 elseBody = createLabel (ifFalse, elseBody);
4863 /* out the end at the end of the body */
4864 elseBody = newNode (NULLOP,
4866 createLabel (ifEnd, NULL));
4870 ifBody = newNode (NULLOP, ifBody,
4871 createLabel (ifFalse, NULL));
4873 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4874 if (IS_IFX (condAst))
4877 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4879 return newNode (NULLOP, ifTree,
4880 newNode (NULLOP, ifBody, elseBody));
4884 /*-----------------------------------------------------------------*/
4885 /* createDo - creates parse tree for do */
4888 /* _docontinue_n: */
4889 /* condition_expression +-> trueLabel -> _dobody_n */
4891 /* +-> falseLabel-> _dobreak_n */
4893 /*-----------------------------------------------------------------*/
4895 createDo (symbol * trueLabel, symbol * continueLabel,
4896 symbol * falseLabel, ast * condAst, ast * doBody)
4901 /* if the body does not exist then it is simple */
4904 condAst = backPatchLabels (condAst, continueLabel, NULL);
4905 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4906 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4907 doTree->trueLabel = continueLabel;
4908 doTree->falseLabel = NULL;
4912 /* otherwise we have a body */
4913 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4915 /* attach the body label to the top */
4916 doBody = createLabel (trueLabel, doBody);
4917 /* attach the continue label to end of body */
4918 doBody = newNode (NULLOP, doBody,
4919 createLabel (continueLabel, NULL));
4921 /* now put the break label at the end */
4922 if (IS_IFX (condAst))
4925 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4927 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4929 /* putting it together */
4930 return newNode (NULLOP, doBody, doTree);
4933 /*-----------------------------------------------------------------*/
4934 /* createFor - creates parse tree for 'for' statement */
4937 /* condExpr +-> trueLabel -> _forbody_n */
4939 /* +-> falseLabel-> _forbreak_n */
4942 /* _forcontinue_n: */
4944 /* goto _forcond_n ; */
4946 /*-----------------------------------------------------------------*/
4948 createFor (symbol * trueLabel, symbol * continueLabel,
4949 symbol * falseLabel, symbol * condLabel,
4950 ast * initExpr, ast * condExpr, ast * loopExpr,
4955 /* if loopexpression not present then we can generate it */
4956 /* the same way as a while */
4958 return newNode (NULLOP, initExpr,
4959 createWhile (trueLabel, continueLabel,
4960 falseLabel, condExpr, forBody));
4961 /* vanilla for statement */
4962 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4964 if (condExpr && !IS_IFX (condExpr))
4965 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4968 /* attach condition label to condition */
4969 condExpr = createLabel (condLabel, condExpr);
4971 /* attach body label to body */
4972 forBody = createLabel (trueLabel, forBody);
4974 /* attach continue to forLoop expression & attach */
4975 /* goto the forcond @ and of loopExpression */
4976 loopExpr = createLabel (continueLabel,
4980 newAst_VALUE (symbolVal (condLabel)),
4982 /* now start putting them together */
4983 forTree = newNode (NULLOP, initExpr, condExpr);
4984 forTree = newNode (NULLOP, forTree, forBody);
4985 forTree = newNode (NULLOP, forTree, loopExpr);
4986 /* finally add the break label */
4987 forTree = newNode (NULLOP, forTree,
4988 createLabel (falseLabel, NULL));
4992 /*-----------------------------------------------------------------*/
4993 /* createWhile - creates parse tree for while statement */
4994 /* the while statement will be created as follows */
4996 /* _while_continue_n: */
4997 /* condition_expression +-> trueLabel -> _while_boby_n */
4999 /* +-> falseLabel -> _while_break_n */
5000 /* _while_body_n: */
5002 /* goto _while_continue_n */
5003 /* _while_break_n: */
5004 /*-----------------------------------------------------------------*/
5006 createWhile (symbol * trueLabel, symbol * continueLabel,
5007 symbol * falseLabel, ast * condExpr, ast * whileBody)
5011 /* put the continue label */
5012 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5013 condExpr = createLabel (continueLabel, condExpr);
5014 condExpr->lineno = 0;
5016 /* put the body label in front of the body */
5017 whileBody = createLabel (trueLabel, whileBody);
5018 whileBody->lineno = 0;
5019 /* put a jump to continue at the end of the body */
5020 /* and put break label at the end of the body */
5021 whileBody = newNode (NULLOP,
5024 newAst_VALUE (symbolVal (continueLabel)),
5025 createLabel (falseLabel, NULL)));
5027 /* put it all together */
5028 if (IS_IFX (condExpr))
5029 whileTree = condExpr;
5032 whileTree = newNode (IFX, condExpr, NULL);
5033 /* put the true & false labels in place */
5034 whileTree->trueLabel = trueLabel;
5035 whileTree->falseLabel = falseLabel;
5038 return newNode (NULLOP, whileTree, whileBody);
5041 /*-----------------------------------------------------------------*/
5042 /* isShiftRightLitVal _BitAndLitVal - helper function */
5043 /*-----------------------------------------------------------------*/
5045 isShiftRightLitVal_BitAndLitVal (ast * tree)
5047 /* if this is not a bit and */
5048 if (!IS_BITAND (tree))
5051 /* will look for tree of the form
5052 ( expr >> litval2) & litval1 */
5053 if (!IS_AST_LIT_VALUE (tree->right))
5056 if (!IS_RIGHT_OP (tree->left))
5059 if (!IS_AST_LIT_VALUE (tree->left->right))
5062 return tree->left->left;
5065 /*-----------------------------------------------------------------*/
5066 /* isBitAndPowOf2 - helper function */
5067 /*-----------------------------------------------------------------*/
5069 isBitAndPow2 (ast * tree)
5071 /* if this is not a bit and */
5072 if (!IS_BITAND (tree))
5075 /* will look for tree of the form
5076 ( expr & (1 << litval) */
5077 if (!IS_AST_LIT_VALUE (tree->right))
5080 return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5083 /*-----------------------------------------------------------------*/
5084 /* optimizeGetHbit - get highest order bit of the expression */
5085 /*-----------------------------------------------------------------*/
5087 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5092 expr = isShiftRightLitVal_BitAndLitVal(tree);
5095 if ((AST_LIT_VALUE (tree->right) != 1) ||
5096 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5097 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5100 if (!expr && (resultType == RESULT_TYPE_BIT))
5103 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5109 /* make sure the port supports GETHBIT */
5110 if (port->hasExtBitOp
5111 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5114 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5117 /*-----------------------------------------------------------------*/
5118 /* optimizeGetAbit - get a single bit of the expression */
5119 /*-----------------------------------------------------------------*/
5121 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5126 expr = isShiftRightLitVal_BitAndLitVal(tree);
5129 if (AST_LIT_VALUE (tree->right) != 1)
5131 count = tree->left->right;
5133 if (!expr && (resultType == RESULT_TYPE_BIT))
5135 int p2 = isBitAndPow2 (tree);
5139 count = newAst_VALUE (valueFromLit (p2));
5145 /* make sure the port supports GETABIT */
5146 if (port->hasExtBitOp
5147 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5150 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5154 /*-----------------------------------------------------------------*/
5155 /* optimizeGetByte - get a byte of the expression */
5156 /*-----------------------------------------------------------------*/
5158 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5164 expr = isShiftRightLitVal_BitAndLitVal(tree);
5167 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5168 count = tree->left->right;
5169 if (AST_LIT_VALUE (tree->right) != 0xFF)
5172 if (!expr && resultType == RESULT_TYPE_CHAR)
5174 /* if this is a right shift over a multiple of 8 */
5175 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5177 i = (unsigned int) AST_LIT_VALUE (tree->right);
5178 count = tree->right;
5182 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5185 /* make sure the port supports GETBYTE */
5186 if (port->hasExtBitOp
5187 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5190 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5193 /*-----------------------------------------------------------------*/
5194 /* optimizeGetWord - get two bytes of the expression */
5195 /*-----------------------------------------------------------------*/
5197 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5203 expr = isShiftRightLitVal_BitAndLitVal(tree);
5206 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5207 count = tree->left->right;
5208 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5211 if (!expr && resultType == RESULT_TYPE_INT)
5213 /* if this is a right shift over a multiple of 8 */
5214 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5216 i = (unsigned int) AST_LIT_VALUE (tree->right);
5217 count = tree->right;
5221 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5224 /* make sure the port supports GETWORD */
5225 if (port->hasExtBitOp
5226 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5229 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5232 /*-----------------------------------------------------------------*/
5233 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5234 /*-----------------------------------------------------------------*/
5236 optimizeRRCRLC (ast * root)
5238 /* will look for trees of the form
5239 (?expr << 1) | (?expr >> 7) or
5240 (?expr >> 7) | (?expr << 1) will make that
5241 into a RLC : operation ..
5243 (?expr >> 1) | (?expr << 7) or
5244 (?expr << 7) | (?expr >> 1) will make that
5245 into a RRC operation
5246 note : by 7 I mean (number of bits required to hold the
5248 /* if the root operation is not a | operation then not */
5249 if (!IS_BITOR (root))
5252 /* I have to think of a better way to match patterns this sucks */
5253 /* that aside let's start looking for the first case : I use a
5254 negative check a lot to improve the efficiency */
5255 /* (?expr << 1) | (?expr >> 7) */
5256 if (IS_LEFT_OP (root->left) &&
5257 IS_RIGHT_OP (root->right))
5260 if (!SPEC_USIGN (TETYPE (root->left->left)))
5263 if (!IS_AST_LIT_VALUE (root->left->right) ||
5264 !IS_AST_LIT_VALUE (root->right->right))
5267 /* make sure it is the same expression */
5268 if (!isAstEqual (root->left->left,
5272 if (AST_LIT_VALUE (root->left->right) != 1)
5275 if (AST_LIT_VALUE (root->right->right) !=
5276 (getSize (TTYPE (root->left->left)) * 8 - 1))
5279 /* make sure the port supports RLC */
5280 if (port->hasExtBitOp
5281 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5284 /* whew got the first case : create the AST */
5285 return newNode (RLC, root->left->left, NULL);
5289 /* check for second case */
5290 /* (?expr >> 7) | (?expr << 1) */
5291 if (IS_LEFT_OP (root->right) &&
5292 IS_RIGHT_OP (root->left))
5295 if (!SPEC_USIGN (TETYPE (root->left->left)))
5298 if (!IS_AST_LIT_VALUE (root->left->right) ||
5299 !IS_AST_LIT_VALUE (root->right->right))
5302 /* make sure it is the same symbol */
5303 if (!isAstEqual (root->left->left,
5307 if (AST_LIT_VALUE (root->right->right) != 1)
5310 if (AST_LIT_VALUE (root->left->right) !=
5311 (getSize (TTYPE (root->left->left)) * 8 - 1))
5314 /* make sure the port supports RLC */
5315 if (port->hasExtBitOp
5316 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5319 /* whew got the first case : create the AST */
5320 return newNode (RLC, root->left->left, NULL);
5325 /* third case for RRC */
5326 /* (?symbol >> 1) | (?symbol << 7) */
5327 if (IS_LEFT_OP (root->right) &&
5328 IS_RIGHT_OP (root->left))
5331 if (!SPEC_USIGN (TETYPE (root->left->left)))
5334 if (!IS_AST_LIT_VALUE (root->left->right) ||
5335 !IS_AST_LIT_VALUE (root->right->right))
5338 /* make sure it is the same symbol */
5339 if (!isAstEqual (root->left->left,
5343 if (AST_LIT_VALUE (root->left->right) != 1)
5346 if (AST_LIT_VALUE (root->right->right) !=
5347 (getSize (TTYPE (root->left->left)) * 8 - 1))
5350 /* make sure the port supports RRC */
5351 if (port->hasExtBitOp
5352 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5355 /* whew got the first case : create the AST */
5356 return newNode (RRC, root->left->left, NULL);
5360 /* fourth and last case for now */
5361 /* (?symbol << 7) | (?symbol >> 1) */
5362 if (IS_RIGHT_OP (root->right) &&
5363 IS_LEFT_OP (root->left))
5366 if (!SPEC_USIGN (TETYPE (root->left->left)))
5369 if (!IS_AST_LIT_VALUE (root->left->right) ||
5370 !IS_AST_LIT_VALUE (root->right->right))
5373 /* make sure it is the same symbol */
5374 if (!isAstEqual (root->left->left,
5378 if (AST_LIT_VALUE (root->right->right) != 1)
5381 if (AST_LIT_VALUE (root->left->right) !=
5382 (getSize (TTYPE (root->left->left)) * 8 - 1))
5385 /* make sure the port supports RRC */
5386 if (port->hasExtBitOp
5387 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5390 /* whew got the first case : create the AST */
5391 return newNode (RRC, root->left->left, NULL);
5395 /* not found return root */
5399 /*-----------------------------------------------------------------*/
5400 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5401 /*-----------------------------------------------------------------*/
5403 optimizeSWAP (ast * root)
5405 /* will look for trees of the form
5406 (?expr << 4) | (?expr >> 4) or
5407 (?expr >> 4) | (?expr << 4) will make that
5408 into a SWAP : operation ..
5409 note : by 4 I mean (number of bits required to hold the
5411 /* if the root operation is not a | operation then not */
5412 if (!IS_BITOR (root))
5415 /* (?expr << 4) | (?expr >> 4) */
5416 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5417 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5420 if (!SPEC_USIGN (TETYPE (root->left->left)))
5423 if (!IS_AST_LIT_VALUE (root->left->right) ||
5424 !IS_AST_LIT_VALUE (root->right->right))
5427 /* make sure it is the same expression */
5428 if (!isAstEqual (root->left->left,
5432 if (AST_LIT_VALUE (root->left->right) !=
5433 (getSize (TTYPE (root->left->left)) * 4))
5436 if (AST_LIT_VALUE (root->right->right) !=
5437 (getSize (TTYPE (root->left->left)) * 4))
5440 /* make sure the port supports SWAP */
5441 if (port->hasExtBitOp
5442 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5445 /* found it : create the AST */
5446 return newNode (SWAP, root->left->left, NULL);
5450 /* not found return root */
5454 /*-----------------------------------------------------------------*/
5455 /* optimizeCompare - optimizes compares for bit variables */
5456 /*-----------------------------------------------------------------*/
5458 optimizeCompare (ast * root)
5460 ast *optExpr = NULL;
5463 unsigned int litValue;
5465 /* if nothing then return nothing */
5469 /* if not a compare op then do leaves */
5470 if (!IS_COMPARE_OP (root))
5472 root->left = optimizeCompare (root->left);
5473 root->right = optimizeCompare (root->right);
5477 /* if left & right are the same then depending
5478 of the operation do */
5479 if (isAstEqual (root->left, root->right))
5481 switch (root->opval.op)
5486 optExpr = newAst_VALUE (constVal ("0"));
5491 optExpr = newAst_VALUE (constVal ("1"));
5495 return decorateType (optExpr, RESULT_TYPE_NONE);
5498 vleft = (root->left->type == EX_VALUE ?
5499 root->left->opval.val : NULL);
5501 vright = (root->right->type == EX_VALUE ?
5502 root->right->opval.val : NULL);
5504 /* if left is a BITVAR in BITSPACE */
5505 /* and right is a LITERAL then opt- */
5506 /* imize else do nothing */
5507 if (vleft && vright &&
5508 IS_BITVAR (vleft->etype) &&
5509 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5510 IS_LITERAL (vright->etype))
5513 /* if right side > 1 then comparison may never succeed */
5514 if ((litValue = (int) floatFromVal (vright)) > 1)
5516 werror (W_BAD_COMPARE);
5522 switch (root->opval.op)
5524 case '>': /* bit value greater than 1 cannot be */
5525 werror (W_BAD_COMPARE);
5529 case '<': /* bit value < 1 means 0 */
5531 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5534 case LE_OP: /* bit value <= 1 means no check */
5535 optExpr = newAst_VALUE (vright);
5538 case GE_OP: /* bit value >= 1 means only check for = */
5540 optExpr = newAst_VALUE (vleft);
5545 { /* literal is zero */
5546 switch (root->opval.op)
5548 case '<': /* bit value < 0 cannot be */
5549 werror (W_BAD_COMPARE);
5553 case '>': /* bit value > 0 means 1 */
5555 optExpr = newAst_VALUE (vleft);
5558 case LE_OP: /* bit value <= 0 means no check */
5559 case GE_OP: /* bit value >= 0 means no check */
5560 werror (W_BAD_COMPARE);
5564 case EQ_OP: /* bit == 0 means ! of bit */
5565 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5569 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5570 } /* end-of-if of BITVAR */
5575 /*-----------------------------------------------------------------*/
5576 /* addSymToBlock : adds the symbol to the first block we find */
5577 /*-----------------------------------------------------------------*/
5579 addSymToBlock (symbol * sym, ast * tree)
5581 /* reached end of tree or a leaf */
5582 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5586 if (IS_AST_OP (tree) &&
5587 tree->opval.op == BLOCK)
5590 symbol *lsym = copySymbol (sym);
5592 lsym->next = AST_VALUES (tree, sym);
5593 AST_VALUES (tree, sym) = lsym;
5597 addSymToBlock (sym, tree->left);
5598 addSymToBlock (sym, tree->right);
5601 /*-----------------------------------------------------------------*/
5602 /* processRegParms - do processing for register parameters */
5603 /*-----------------------------------------------------------------*/
5605 processRegParms (value * args, ast * body)
5609 if (IS_REGPARM (args->etype))
5610 addSymToBlock (args->sym, body);
5615 /*-----------------------------------------------------------------*/
5616 /* resetParmKey - resets the operandkeys for the symbols */
5617 /*-----------------------------------------------------------------*/
5618 DEFSETFUNC (resetParmKey)
5629 /*-----------------------------------------------------------------*/
5630 /* createFunction - This is the key node that calls the iCode for */
5631 /* generating the code for a function. Note code */
5632 /* is generated function by function, later when */
5633 /* add inter-procedural analysis this will change */
5634 /*-----------------------------------------------------------------*/
5636 createFunction (symbol * name, ast * body)
5642 iCode *piCode = NULL;
5644 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5645 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5647 /* if check function return 0 then some problem */
5648 if (checkFunction (name, NULL) == 0)
5651 /* create a dummy block if none exists */
5653 body = newNode (BLOCK, NULL, NULL);
5657 /* check if the function name already in the symbol table */
5658 if ((csym = findSym (SymbolTab, NULL, name->name)))
5661 /* special case for compiler defined functions
5662 we need to add the name to the publics list : this
5663 actually means we are now compiling the compiler
5667 addSet (&publics, name);
5672 addSymChain (&name);
5673 allocVariables (name);
5675 name->lastLine = mylineno;
5678 /* set the stack pointer */
5679 stackPtr = -port->stack.direction * port->stack.call_overhead;
5682 if (IFFUNC_ISISR (name->type))
5683 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5685 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5687 if (options.useXstack)
5688 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5690 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5693 fetype = getSpec (name->type); /* get the specifier for the function */
5694 /* if this is a reentrant function then */
5695 if (IFFUNC_ISREENT (name->type))
5698 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5700 /* do processing for parameters that are passed in registers */
5701 processRegParms (FUNC_ARGS(name->type), body);
5703 /* set the stack pointer */
5707 /* allocate & autoinit the block variables */
5708 processBlockVars (body, &stack, ALLOCATE);
5710 /* save the stack information */
5711 if (options.useXstack)
5712 name->xstack = SPEC_STAK (fetype) = stack;
5714 name->stack = SPEC_STAK (fetype) = stack;
5716 /* name needs to be mangled */
5717 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5719 body = resolveSymbols (body); /* resolve the symbols */
5720 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5722 ex = newAst_VALUE (symbolVal (name)); /* create name */
5723 ex = newNode (FUNCTION, ex, body);
5724 ex->values.args = FUNC_ARGS(name->type);
5726 if (options.dump_tree) PA(ex);
5729 werror (E_FUNC_NO_CODE, name->name);
5733 /* create the node & generate intermediate code */
5735 codeOutFile = code->oFile;
5736 piCode = iCodeFromAst (ex);
5740 werror (E_FUNC_NO_CODE, name->name);
5744 eBBlockFromiCode (piCode);
5746 /* if there are any statics then do them */
5749 GcurMemmap = statsg;
5750 codeOutFile = statsg->oFile;
5751 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5757 /* dealloc the block variables */
5758 processBlockVars (body, &stack, DEALLOCATE);
5759 outputDebugStackSymbols();
5760 /* deallocate paramaters */
5761 deallocParms (FUNC_ARGS(name->type));
5763 if (IFFUNC_ISREENT (name->type))
5766 /* we are done freeup memory & cleanup */
5768 if (port->reset_labelKey) labelKey = 1;
5770 FUNC_HASBODY(name->type) = 1;
5771 addSet (&operKeyReset, name);
5772 applyToSet (operKeyReset, resetParmKey);
5777 cleanUpLevel (LabelTab, 0);
5778 cleanUpBlock (StructTab, 1);
5779 cleanUpBlock (TypedefTab, 1);
5781 xstack->syms = NULL;
5782 istack->syms = NULL;
5787 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5788 /*-----------------------------------------------------------------*/
5789 /* ast_print : prints the ast (for debugging purposes) */
5790 /*-----------------------------------------------------------------*/
5792 void ast_print (ast * tree, FILE *outfile, int indent)
5797 /* can print only decorated trees */
5798 if (!tree->decorated) return;
5800 /* if any child is an error | this one is an error do nothing */
5801 if (tree->isError ||
5802 (tree->left && tree->left->isError) ||
5803 (tree->right && tree->right->isError)) {
5804 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5808 /* print the line */
5809 /* if not block & function */
5810 if (tree->type == EX_OP &&
5811 (tree->opval.op != FUNCTION &&
5812 tree->opval.op != BLOCK &&
5813 tree->opval.op != NULLOP)) {
5816 if (tree->opval.op == FUNCTION) {
5818 value *args=FUNC_ARGS(tree->left->opval.val->type);
5819 fprintf(outfile,"FUNCTION (%s=%p) type (",
5820 tree->left->opval.val->name, tree);
5821 printTypeChain (tree->left->opval.val->type->next,outfile);
5822 fprintf(outfile,") args (");
5825 fprintf (outfile, ", ");
5827 printTypeChain (args ? args->type : NULL, outfile);
5829 args= args ? args->next : NULL;
5831 fprintf(outfile,")\n");
5832 ast_print(tree->left,outfile,indent);
5833 ast_print(tree->right,outfile,indent);
5836 if (tree->opval.op == BLOCK) {
5837 symbol *decls = tree->values.sym;
5838 INDENT(indent,outfile);
5839 fprintf(outfile,"{\n");
5841 INDENT(indent+2,outfile);
5842 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5843 decls->name, decls);
5844 printTypeChain(decls->type,outfile);
5845 fprintf(outfile,")\n");
5847 decls = decls->next;
5849 ast_print(tree->right,outfile,indent+2);
5850 INDENT(indent,outfile);
5851 fprintf(outfile,"}\n");
5854 if (tree->opval.op == NULLOP) {
5855 ast_print(tree->left,outfile,indent);
5856 ast_print(tree->right,outfile,indent);
5859 INDENT(indent,outfile);
5861 /*------------------------------------------------------------------*/
5862 /*----------------------------*/
5863 /* leaf has been reached */
5864 /*----------------------------*/
5865 /* if this is of type value */
5866 /* just get the type */
5867 if (tree->type == EX_VALUE) {
5869 if (IS_LITERAL (tree->opval.val->etype)) {
5870 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5871 if (SPEC_USIGN (tree->opval.val->etype))
5872 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5874 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5875 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5876 floatFromVal(tree->opval.val));
5877 } else if (tree->opval.val->sym) {
5878 /* if the undefined flag is set then give error message */
5879 if (tree->opval.val->sym->undefined) {
5880 fprintf(outfile,"UNDEFINED SYMBOL ");
5882 fprintf(outfile,"SYMBOL ");
5884 fprintf(outfile,"(%s=%p)",
5885 tree->opval.val->sym->name,tree);
5888 fprintf(outfile," type (");
5889 printTypeChain(tree->ftype,outfile);
5890 fprintf(outfile,")\n");
5892 fprintf(outfile,"\n");
5897 /* if type link for the case of cast */
5898 if (tree->type == EX_LINK) {
5899 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5900 printTypeChain(tree->opval.lnk,outfile);
5901 fprintf(outfile,")\n");
5906 /* depending on type of operator do */
5908 switch (tree->opval.op) {
5909 /*------------------------------------------------------------------*/
5910 /*----------------------------*/
5912 /*----------------------------*/
5914 fprintf(outfile,"ARRAY_OP (%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 /*------------------------------------------------------------------*/
5922 /*----------------------------*/
5924 /*----------------------------*/
5926 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5927 printTypeChain(tree->ftype,outfile);
5928 fprintf(outfile,")\n");
5929 ast_print(tree->left,outfile,indent+2);
5930 ast_print(tree->right,outfile,indent+2);
5933 /*------------------------------------------------------------------*/
5934 /*----------------------------*/
5935 /* struct/union pointer */
5936 /*----------------------------*/
5938 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5939 printTypeChain(tree->ftype,outfile);
5940 fprintf(outfile,")\n");
5941 ast_print(tree->left,outfile,indent+2);
5942 ast_print(tree->right,outfile,indent+2);
5945 /*------------------------------------------------------------------*/
5946 /*----------------------------*/
5947 /* ++/-- operation */
5948 /*----------------------------*/
5951 fprintf(outfile,"post-");
5953 fprintf(outfile,"pre-");
5954 fprintf(outfile,"INC_OP (%p) type (",tree);
5955 printTypeChain(tree->ftype,outfile);
5956 fprintf(outfile,")\n");
5957 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5958 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5963 fprintf(outfile,"post-");
5965 fprintf(outfile,"pre-");
5966 fprintf(outfile,"DEC_OP (%p) type (",tree);
5967 printTypeChain(tree->ftype,outfile);
5968 fprintf(outfile,")\n");
5969 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5970 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5973 /*------------------------------------------------------------------*/
5974 /*----------------------------*/
5976 /*----------------------------*/
5979 fprintf(outfile,"& (%p) type (",tree);
5980 printTypeChain(tree->ftype,outfile);
5981 fprintf(outfile,")\n");
5982 ast_print(tree->left,outfile,indent+2);
5983 ast_print(tree->right,outfile,indent+2);
5985 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5986 printTypeChain(tree->ftype,outfile);
5987 fprintf(outfile,")\n");
5988 ast_print(tree->left,outfile,indent+2);
5989 ast_print(tree->right,outfile,indent+2);
5992 /*----------------------------*/
5994 /*----------------------------*/
5996 fprintf(outfile,"OR (%p) type (",tree);
5997 printTypeChain(tree->ftype,outfile);
5998 fprintf(outfile,")\n");
5999 ast_print(tree->left,outfile,indent+2);
6000 ast_print(tree->right,outfile,indent+2);
6002 /*------------------------------------------------------------------*/
6003 /*----------------------------*/
6005 /*----------------------------*/
6007 fprintf(outfile,"XOR (%p) type (",tree);
6008 printTypeChain(tree->ftype,outfile);
6009 fprintf(outfile,")\n");
6010 ast_print(tree->left,outfile,indent+2);
6011 ast_print(tree->right,outfile,indent+2);
6014 /*------------------------------------------------------------------*/
6015 /*----------------------------*/
6017 /*----------------------------*/
6019 fprintf(outfile,"DIV (%p) type (",tree);
6020 printTypeChain(tree->ftype,outfile);
6021 fprintf(outfile,")\n");
6022 ast_print(tree->left,outfile,indent+2);
6023 ast_print(tree->right,outfile,indent+2);
6025 /*------------------------------------------------------------------*/
6026 /*----------------------------*/
6028 /*----------------------------*/
6030 fprintf(outfile,"MOD (%p) type (",tree);
6031 printTypeChain(tree->ftype,outfile);
6032 fprintf(outfile,")\n");
6033 ast_print(tree->left,outfile,indent+2);
6034 ast_print(tree->right,outfile,indent+2);
6037 /*------------------------------------------------------------------*/
6038 /*----------------------------*/
6039 /* address dereference */
6040 /*----------------------------*/
6041 case '*': /* can be unary : if right is null then unary operation */
6043 fprintf(outfile,"DEREF (%p) type (",tree);
6044 printTypeChain(tree->ftype,outfile);
6045 fprintf(outfile,")\n");
6046 ast_print(tree->left,outfile,indent+2);
6049 /*------------------------------------------------------------------*/
6050 /*----------------------------*/
6051 /* multiplication */
6052 /*----------------------------*/
6053 fprintf(outfile,"MULT (%p) type (",tree);
6054 printTypeChain(tree->ftype,outfile);
6055 fprintf(outfile,")\n");
6056 ast_print(tree->left,outfile,indent+2);
6057 ast_print(tree->right,outfile,indent+2);
6061 /*------------------------------------------------------------------*/
6062 /*----------------------------*/
6063 /* unary '+' operator */
6064 /*----------------------------*/
6068 fprintf(outfile,"UPLUS (%p) type (",tree);
6069 printTypeChain(tree->ftype,outfile);
6070 fprintf(outfile,")\n");
6071 ast_print(tree->left,outfile,indent+2);
6073 /*------------------------------------------------------------------*/
6074 /*----------------------------*/
6076 /*----------------------------*/
6077 fprintf(outfile,"ADD (%p) type (",tree);
6078 printTypeChain(tree->ftype,outfile);
6079 fprintf(outfile,")\n");
6080 ast_print(tree->left,outfile,indent+2);
6081 ast_print(tree->right,outfile,indent+2);
6084 /*------------------------------------------------------------------*/
6085 /*----------------------------*/
6087 /*----------------------------*/
6088 case '-': /* can be unary */
6090 fprintf(outfile,"UMINUS (%p) type (",tree);
6091 printTypeChain(tree->ftype,outfile);
6092 fprintf(outfile,")\n");
6093 ast_print(tree->left,outfile,indent+2);
6095 /*------------------------------------------------------------------*/
6096 /*----------------------------*/
6098 /*----------------------------*/
6099 fprintf(outfile,"SUB (%p) type (",tree);
6100 printTypeChain(tree->ftype,outfile);
6101 fprintf(outfile,")\n");
6102 ast_print(tree->left,outfile,indent+2);
6103 ast_print(tree->right,outfile,indent+2);
6106 /*------------------------------------------------------------------*/
6107 /*----------------------------*/
6109 /*----------------------------*/
6111 fprintf(outfile,"COMPL (%p) type (",tree);
6112 printTypeChain(tree->ftype,outfile);
6113 fprintf(outfile,")\n");
6114 ast_print(tree->left,outfile,indent+2);
6116 /*------------------------------------------------------------------*/
6117 /*----------------------------*/
6119 /*----------------------------*/
6121 fprintf(outfile,"NOT (%p) type (",tree);
6122 printTypeChain(tree->ftype,outfile);
6123 fprintf(outfile,")\n");
6124 ast_print(tree->left,outfile,indent+2);
6126 /*------------------------------------------------------------------*/
6127 /*----------------------------*/
6129 /*----------------------------*/
6131 fprintf(outfile,"RRC (%p) type (",tree);
6132 printTypeChain(tree->ftype,outfile);
6133 fprintf(outfile,")\n");
6134 ast_print(tree->left,outfile,indent+2);
6138 fprintf(outfile,"RLC (%p) type (",tree);
6139 printTypeChain(tree->ftype,outfile);
6140 fprintf(outfile,")\n");
6141 ast_print(tree->left,outfile,indent+2);
6144 fprintf(outfile,"SWAP (%p) type (",tree);
6145 printTypeChain(tree->ftype,outfile);
6146 fprintf(outfile,")\n");
6147 ast_print(tree->left,outfile,indent+2);
6150 fprintf(outfile,"GETHBIT (%p) type (",tree);
6151 printTypeChain(tree->ftype,outfile);
6152 fprintf(outfile,")\n");
6153 ast_print(tree->left,outfile,indent+2);
6156 fprintf(outfile,"GETABIT (%p) type (",tree);
6157 printTypeChain(tree->ftype,outfile);
6158 fprintf(outfile,")\n");
6159 ast_print(tree->left,outfile,indent+2);
6160 ast_print(tree->right,outfile,indent+2);
6163 fprintf(outfile,"GETBYTE (%p) type (",tree);
6164 printTypeChain(tree->ftype,outfile);
6165 fprintf(outfile,")\n");
6166 ast_print(tree->left,outfile,indent+2);
6167 ast_print(tree->right,outfile,indent+2);
6170 fprintf(outfile,"GETWORD (%p) type (",tree);
6171 printTypeChain(tree->ftype,outfile);
6172 fprintf(outfile,")\n");
6173 ast_print(tree->left,outfile,indent+2);
6174 ast_print(tree->right,outfile,indent+2);
6177 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6178 printTypeChain(tree->ftype,outfile);
6179 fprintf(outfile,")\n");
6180 ast_print(tree->left,outfile,indent+2);
6181 ast_print(tree->right,outfile,indent+2);
6184 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6185 printTypeChain(tree->ftype,outfile);
6186 fprintf(outfile,")\n");
6187 ast_print(tree->left,outfile,indent+2);
6188 ast_print(tree->right,outfile,indent+2);
6190 /*------------------------------------------------------------------*/
6191 /*----------------------------*/
6193 /*----------------------------*/
6194 case CAST: /* change the type */
6195 fprintf(outfile,"CAST (%p) from type (",tree);
6196 printTypeChain(tree->right->ftype,outfile);
6197 fprintf(outfile,") to type (");
6198 printTypeChain(tree->ftype,outfile);
6199 fprintf(outfile,")\n");
6200 ast_print(tree->right,outfile,indent+2);
6204 fprintf(outfile,"ANDAND (%p) type (",tree);
6205 printTypeChain(tree->ftype,outfile);
6206 fprintf(outfile,")\n");
6207 ast_print(tree->left,outfile,indent+2);
6208 ast_print(tree->right,outfile,indent+2);
6211 fprintf(outfile,"OROR (%p) type (",tree);
6212 printTypeChain(tree->ftype,outfile);
6213 fprintf(outfile,")\n");
6214 ast_print(tree->left,outfile,indent+2);
6215 ast_print(tree->right,outfile,indent+2);
6218 /*------------------------------------------------------------------*/
6219 /*----------------------------*/
6220 /* comparison operators */
6221 /*----------------------------*/
6223 fprintf(outfile,"GT(>) (%p) type (",tree);
6224 printTypeChain(tree->ftype,outfile);
6225 fprintf(outfile,")\n");
6226 ast_print(tree->left,outfile,indent+2);
6227 ast_print(tree->right,outfile,indent+2);
6230 fprintf(outfile,"LT(<) (%p) type (",tree);
6231 printTypeChain(tree->ftype,outfile);
6232 fprintf(outfile,")\n");
6233 ast_print(tree->left,outfile,indent+2);
6234 ast_print(tree->right,outfile,indent+2);
6237 fprintf(outfile,"LE(<=) (%p) type (",tree);
6238 printTypeChain(tree->ftype,outfile);
6239 fprintf(outfile,")\n");
6240 ast_print(tree->left,outfile,indent+2);
6241 ast_print(tree->right,outfile,indent+2);
6244 fprintf(outfile,"GE(>=) (%p) type (",tree);
6245 printTypeChain(tree->ftype,outfile);
6246 fprintf(outfile,")\n");
6247 ast_print(tree->left,outfile,indent+2);
6248 ast_print(tree->right,outfile,indent+2);
6251 fprintf(outfile,"EQ(==) (%p) type (",tree);
6252 printTypeChain(tree->ftype,outfile);
6253 fprintf(outfile,")\n");
6254 ast_print(tree->left,outfile,indent+2);
6255 ast_print(tree->right,outfile,indent+2);
6258 fprintf(outfile,"NE(!=) (%p) type (",tree);
6259 printTypeChain(tree->ftype,outfile);
6260 fprintf(outfile,")\n");
6261 ast_print(tree->left,outfile,indent+2);
6262 ast_print(tree->right,outfile,indent+2);
6263 /*------------------------------------------------------------------*/
6264 /*----------------------------*/
6266 /*----------------------------*/
6267 case SIZEOF: /* evaluate wihout code generation */
6268 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6271 /*------------------------------------------------------------------*/
6272 /*----------------------------*/
6273 /* conditional operator '?' */
6274 /*----------------------------*/
6276 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6277 printTypeChain(tree->ftype,outfile);
6278 fprintf(outfile,")\n");
6279 ast_print(tree->left,outfile,indent+2);
6280 ast_print(tree->right,outfile,indent+2);
6284 fprintf(outfile,"COLON(:) (%p) type (",tree);
6285 printTypeChain(tree->ftype,outfile);
6286 fprintf(outfile,")\n");
6287 ast_print(tree->left,outfile,indent+2);
6288 ast_print(tree->right,outfile,indent+2);
6291 /*------------------------------------------------------------------*/
6292 /*----------------------------*/
6293 /* assignment operators */
6294 /*----------------------------*/
6296 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6297 printTypeChain(tree->ftype,outfile);
6298 fprintf(outfile,")\n");
6299 ast_print(tree->left,outfile,indent+2);
6300 ast_print(tree->right,outfile,indent+2);
6303 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6304 printTypeChain(tree->ftype,outfile);
6305 fprintf(outfile,")\n");
6306 ast_print(tree->left,outfile,indent+2);
6307 ast_print(tree->right,outfile,indent+2);
6310 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6311 printTypeChain(tree->ftype,outfile);
6312 fprintf(outfile,")\n");
6313 ast_print(tree->left,outfile,indent+2);
6314 ast_print(tree->right,outfile,indent+2);
6317 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6318 printTypeChain(tree->ftype,outfile);
6319 fprintf(outfile,")\n");
6320 ast_print(tree->left,outfile,indent+2);
6321 ast_print(tree->right,outfile,indent+2);
6324 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6325 printTypeChain(tree->ftype,outfile);
6326 fprintf(outfile,")\n");
6327 ast_print(tree->left,outfile,indent+2);
6328 ast_print(tree->right,outfile,indent+2);
6331 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6332 printTypeChain(tree->ftype,outfile);
6333 fprintf(outfile,")\n");
6334 ast_print(tree->left,outfile,indent+2);
6335 ast_print(tree->right,outfile,indent+2);
6338 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6339 printTypeChain(tree->ftype,outfile);
6340 fprintf(outfile,")\n");
6341 ast_print(tree->left,outfile,indent+2);
6342 ast_print(tree->right,outfile,indent+2);
6344 /*------------------------------------------------------------------*/
6345 /*----------------------------*/
6347 /*----------------------------*/
6349 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6350 printTypeChain(tree->ftype,outfile);
6351 fprintf(outfile,")\n");
6352 ast_print(tree->left,outfile,indent+2);
6353 ast_print(tree->right,outfile,indent+2);
6355 /*------------------------------------------------------------------*/
6356 /*----------------------------*/
6358 /*----------------------------*/
6360 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6361 printTypeChain(tree->ftype,outfile);
6362 fprintf(outfile,")\n");
6363 ast_print(tree->left,outfile,indent+2);
6364 ast_print(tree->right,outfile,indent+2);
6366 /*------------------------------------------------------------------*/
6367 /*----------------------------*/
6368 /* straight assignemnt */
6369 /*----------------------------*/
6371 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6372 printTypeChain(tree->ftype,outfile);
6373 fprintf(outfile,")\n");
6374 ast_print(tree->left,outfile,indent+2);
6375 ast_print(tree->right,outfile,indent+2);
6377 /*------------------------------------------------------------------*/
6378 /*----------------------------*/
6379 /* comma operator */
6380 /*----------------------------*/
6382 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6383 printTypeChain(tree->ftype,outfile);
6384 fprintf(outfile,")\n");
6385 ast_print(tree->left,outfile,indent+2);
6386 ast_print(tree->right,outfile,indent+2);
6388 /*------------------------------------------------------------------*/
6389 /*----------------------------*/
6391 /*----------------------------*/
6394 fprintf(outfile,"CALL (%p) type (",tree);
6395 printTypeChain(tree->ftype,outfile);
6396 fprintf(outfile,")\n");
6397 ast_print(tree->left,outfile,indent+2);
6398 ast_print(tree->right,outfile,indent+2);
6401 fprintf(outfile,"PARMS\n");
6402 ast_print(tree->left,outfile,indent+2);
6403 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6404 ast_print(tree->right,outfile,indent+2);
6407 /*------------------------------------------------------------------*/
6408 /*----------------------------*/
6409 /* return statement */
6410 /*----------------------------*/
6412 fprintf(outfile,"RETURN (%p) type (",tree);
6414 printTypeChain(tree->right->ftype,outfile);
6416 fprintf(outfile,")\n");
6417 ast_print(tree->right,outfile,indent+2);
6419 /*------------------------------------------------------------------*/
6420 /*----------------------------*/
6421 /* label statement */
6422 /*----------------------------*/
6424 fprintf(outfile,"LABEL (%p)\n",tree);
6425 ast_print(tree->left,outfile,indent+2);
6426 ast_print(tree->right,outfile,indent);
6428 /*------------------------------------------------------------------*/
6429 /*----------------------------*/
6430 /* switch statement */
6431 /*----------------------------*/
6435 fprintf(outfile,"SWITCH (%p) ",tree);
6436 ast_print(tree->left,outfile,0);
6437 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6438 INDENT(indent+2,outfile);
6439 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6440 (int) floatFromVal(val),
6441 tree->values.switchVals.swNum,
6442 (int) floatFromVal(val));
6444 ast_print(tree->right,outfile,indent);
6447 /*------------------------------------------------------------------*/
6448 /*----------------------------*/
6450 /*----------------------------*/
6452 fprintf(outfile,"IF (%p) \n",tree);
6453 ast_print(tree->left,outfile,indent+2);
6454 if (tree->trueLabel) {
6455 INDENT(indent+2,outfile);
6456 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6458 if (tree->falseLabel) {
6459 INDENT(indent+2,outfile);
6460 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6462 ast_print(tree->right,outfile,indent+2);
6464 /*----------------------------*/
6465 /* goto Statement */
6466 /*----------------------------*/
6468 fprintf(outfile,"GOTO (%p) \n",tree);
6469 ast_print(tree->left,outfile,indent+2);
6470 fprintf(outfile,"\n");
6472 /*------------------------------------------------------------------*/
6473 /*----------------------------*/
6475 /*----------------------------*/
6477 fprintf(outfile,"FOR (%p) \n",tree);
6478 if (AST_FOR( tree, initExpr)) {
6479 INDENT(indent+2,outfile);
6480 fprintf(outfile,"INIT EXPR ");
6481 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6483 if (AST_FOR( tree, condExpr)) {
6484 INDENT(indent+2,outfile);
6485 fprintf(outfile,"COND EXPR ");
6486 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6488 if (AST_FOR( tree, loopExpr)) {
6489 INDENT(indent+2,outfile);
6490 fprintf(outfile,"LOOP EXPR ");
6491 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6493 fprintf(outfile,"FOR LOOP BODY \n");
6494 ast_print(tree->left,outfile,indent+2);
6497 fprintf(outfile,"CRITICAL (%p) \n",tree);
6498 ast_print(tree->left,outfile,indent+2);
6506 ast_print(t,stdout,0);
6511 /*-----------------------------------------------------------------*/
6512 /* astErrors : returns non-zero if errors present in tree */
6513 /*-----------------------------------------------------------------*/
6514 int astErrors(ast *t)
6523 if (t->type == EX_VALUE
6524 && t->opval.val->sym
6525 && t->opval.val->sym->undefined)
6528 errors += astErrors(t->left);
6529 errors += astErrors(t->right);