1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *, RESULT_TYPE);
59 ast *optimizeGetAbit (ast *, RESULT_TYPE);
60 ast *optimizeGetByte (ast *, RESULT_TYPE);
61 ast *optimizeGetWord (ast *, RESULT_TYPE);
62 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)
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, iloop, rast)), RESULT_TYPE_NONE);
895 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
896 W_EXCESS_INITIALIZERS, "struct",
897 sym->opval.val->sym->name);
904 /*-----------------------------------------------------------------*/
905 /* createIvalArray - generates code for array initialization */
906 /*-----------------------------------------------------------------*/
908 createIvalArray (ast * sym, sym_link * type, initList * ilist)
912 int lcnt = 0, size = 0;
913 literalList *literalL;
915 /* take care of the special case */
916 /* array of characters can be init */
918 if (IS_CHAR (type->next))
919 if ((rast = createIvalCharPtr (sym,
921 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE))))
923 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
925 /* not the special case */
926 if (ilist->type != INIT_DEEP)
928 werror (E_INIT_STRUCT, "");
932 iloop = ilist->init.deep;
933 lcnt = DCL_ELEM (type);
935 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
939 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
941 rast = newNode(ARRAYINIT, aSym, NULL);
942 rast->values.constlist = literalL;
944 // Make sure size is set to length of initializer list.
951 if (lcnt && size > lcnt)
953 // Array size was specified, and we have more initializers than needed.
954 char *name=sym->opval.val->sym->name;
955 int lineno=sym->opval.val->sym->lineDef;
956 char *filename=sym->opval.val->sym->fileDef;
958 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
967 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
968 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
969 rast = createIval (aSym, type->next, iloop, rast);
970 iloop = (iloop ? iloop->next : NULL);
976 /* no of elements given and we */
977 /* have generated for all of them */
980 // is this a better way? at least it won't crash
981 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
982 int lineno = iloop->lineno;
983 char *filename = iloop->filename;
984 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
991 /* if we have not been given a size */
992 if (!DCL_ELEM (type))
994 /* but this still updates the typedef instead of the instance ! see bug 770487 */
995 DCL_ELEM (type) = size;
998 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1002 /*-----------------------------------------------------------------*/
1003 /* createIvalCharPtr - generates initial values for char pointers */
1004 /*-----------------------------------------------------------------*/
1006 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1010 /* if this is a pointer & right is a literal array then */
1011 /* just assignment will do */
1012 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1013 SPEC_SCLS (iexpr->etype) == S_CODE)
1014 && IS_ARRAY (iexpr->ftype)))
1015 return newNode ('=', sym, iexpr);
1017 /* left side is an array so we have to assign each */
1019 if ((IS_LITERAL (iexpr->etype) ||
1020 SPEC_SCLS (iexpr->etype) == S_CODE)
1021 && IS_ARRAY (iexpr->ftype))
1023 /* for each character generate an assignment */
1024 /* to the array element */
1025 char *s = SPEC_CVAL (iexpr->etype).v_char;
1027 int size = getSize (iexpr->ftype);
1028 int symsize = getSize (type);
1032 if (size>(symsize+1))
1034 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1036 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1042 for (i=0;i<size;i++)
1044 rast = newNode (NULLOP,
1048 newAst_VALUE (valueFromLit ((float) i))),
1049 newAst_VALUE (valueFromLit (*s))));
1053 // now WE don't need iexpr's symbol anymore
1054 freeStringSymbol(AST_SYMBOL(iexpr));
1056 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1062 /*-----------------------------------------------------------------*/
1063 /* createIvalPtr - generates initial value for pointers */
1064 /*-----------------------------------------------------------------*/
1066 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1072 if (ilist->type == INIT_DEEP)
1073 ilist = ilist->init.deep;
1075 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1077 /* if character pointer */
1078 if (IS_CHAR (type->next))
1079 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1082 return newNode ('=', sym, iexpr);
1085 /*-----------------------------------------------------------------*/
1086 /* createIval - generates code for initial value */
1087 /*-----------------------------------------------------------------*/
1089 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1096 /* if structure then */
1097 if (IS_STRUCT (type))
1098 rast = createIvalStruct (sym, type, ilist);
1100 /* if this is a pointer */
1102 rast = createIvalPtr (sym, type, ilist);
1104 /* if this is an array */
1105 if (IS_ARRAY (type))
1106 rast = createIvalArray (sym, type, ilist);
1108 /* if type is SPECIFIER */
1110 rast = createIvalType (sym, type, ilist);
1113 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1115 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1118 /*-----------------------------------------------------------------*/
1119 /* initAggregates - initialises aggregate variables with initv */
1120 /*-----------------------------------------------------------------*/
1121 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1122 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1125 /*-----------------------------------------------------------------*/
1126 /* gatherAutoInit - creates assignment expressions for initial */
1128 /*-----------------------------------------------------------------*/
1130 gatherAutoInit (symbol * autoChain)
1137 for (sym = autoChain; sym; sym = sym->next)
1140 /* resolve the symbols in the ival */
1142 resolveIvalSym (sym->ival, sym->type);
1145 /* if we are PIC16 port,
1146 * and this is a static,
1147 * and have initial value,
1148 * and not S_CODE, don't emit in gs segment,
1149 * but allow glue.c:pic16emitRegularMap to put symbol
1150 * in idata section */
1151 if(TARGET_IS_PIC16 &&
1152 IS_STATIC (sym->etype) && sym->ival
1153 && SPEC_SCLS(sym->etype) != S_CODE) {
1154 SPEC_SCLS (sym->etype) = S_DATA;
1159 /* if this is a static variable & has an */
1160 /* initial value the code needs to be lifted */
1161 /* here to the main portion since they can be */
1162 /* initialised only once at the start */
1163 if (IS_STATIC (sym->etype) && sym->ival &&
1164 SPEC_SCLS (sym->etype) != S_CODE)
1168 /* insert the symbol into the symbol table */
1169 /* with level = 0 & name = rname */
1170 newSym = copySymbol (sym);
1171 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1173 /* now lift the code to main */
1174 if (IS_AGGREGATE (sym->type)) {
1175 work = initAggregates (sym, sym->ival, NULL);
1177 if (getNelements(sym->type, sym->ival)>1) {
1178 werrorfl (sym->fileDef, sym->lineDef,
1179 W_EXCESS_INITIALIZERS, "scalar",
1182 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1183 list2expr (sym->ival));
1186 setAstLineno (work, sym->lineDef);
1190 staticAutos = newNode (NULLOP, staticAutos, work);
1197 /* if there is an initial value */
1198 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1200 initList *ilist=sym->ival;
1202 while (ilist->type == INIT_DEEP) {
1203 ilist = ilist->init.deep;
1206 /* update lineno for error msg */
1207 lineno=sym->lineDef;
1208 setAstLineno (ilist->init.node, lineno);
1210 if (IS_AGGREGATE (sym->type)) {
1211 work = initAggregates (sym, sym->ival, NULL);
1213 if (getNelements(sym->type, sym->ival)>1) {
1214 werrorfl (sym->fileDef, sym->lineDef,
1215 W_EXCESS_INITIALIZERS, "scalar",
1218 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1219 list2expr (sym->ival));
1223 setAstLineno (work, sym->lineDef);
1227 init = newNode (NULLOP, init, work);
1236 /*-----------------------------------------------------------------*/
1237 /* freeStringSymbol - delete a literal string if no more usage */
1238 /*-----------------------------------------------------------------*/
1239 void freeStringSymbol(symbol *sym) {
1240 /* make sure this is a literal string */
1241 assert (sym->isstrlit);
1242 if (--sym->isstrlit == 0) { // lower the usage count
1243 memmap *segment=SPEC_OCLS(sym->etype);
1245 deleteSetItem(&segment->syms, sym);
1250 /*-----------------------------------------------------------------*/
1251 /* stringToSymbol - creates a symbol from a literal string */
1252 /*-----------------------------------------------------------------*/
1254 stringToSymbol (value * val)
1256 char name[SDCC_NAME_MAX + 1];
1257 static int charLbl = 0;
1262 // have we heard this before?
1263 for (sp=statsg->syms; sp; sp=sp->next) {
1265 size = getSize (sym->type);
1266 if (sym->isstrlit && size == getSize (val->type) &&
1267 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1268 // yes, this is old news. Don't publish it again.
1269 sym->isstrlit++; // but raise the usage count
1270 return symbolVal(sym);
1274 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1275 sym = newSymbol (name, 0); /* make it @ level 0 */
1276 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1278 /* copy the type from the value passed */
1279 sym->type = copyLinkChain (val->type);
1280 sym->etype = getSpec (sym->type);
1281 /* change to storage class & output class */
1282 SPEC_SCLS (sym->etype) = S_CODE;
1283 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1284 SPEC_STAT (sym->etype) = 1;
1285 /* make the level & block = 0 */
1286 sym->block = sym->level = 0;
1288 /* create an ival */
1289 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1294 allocVariables (sym);
1297 return symbolVal (sym);
1301 /*-----------------------------------------------------------------*/
1302 /* processBlockVars - will go thru the ast looking for block if */
1303 /* a block is found then will allocate the syms */
1304 /* will also gather the auto inits present */
1305 /*-----------------------------------------------------------------*/
1307 processBlockVars (ast * tree, int *stack, int action)
1312 /* if this is a block */
1313 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1317 if (action == ALLOCATE)
1319 *stack += allocVariables (tree->values.sym);
1320 autoInit = gatherAutoInit (tree->values.sym);
1322 /* if there are auto inits then do them */
1324 tree->left = newNode (NULLOP, autoInit, tree->left);
1326 else /* action is deallocate */
1327 deallocLocal (tree->values.sym);
1330 processBlockVars (tree->left, stack, action);
1331 processBlockVars (tree->right, stack, action);
1336 /*-------------------------------------------------------------*/
1337 /* constExprTree - returns TRUE if this tree is a constant */
1339 /*-------------------------------------------------------------*/
1340 bool constExprTree (ast *cexpr) {
1346 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1348 switch (cexpr->type)
1351 if (IS_AST_LIT_VALUE(cexpr)) {
1352 // this is a literal
1355 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1356 // a function's address will never change
1359 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1360 // an array's address will never change
1363 if (IS_AST_SYM_VALUE(cexpr) &&
1364 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1365 // a symbol in code space will never change
1366 // This is only for the 'char *s="hallo"' case and will have to leave
1367 //printf(" code space symbol");
1372 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1373 "unexpected link in expression tree\n");
1376 if (cexpr->opval.op==ARRAYINIT) {
1377 // this is a list of literals
1380 if (cexpr->opval.op=='=') {
1381 return constExprTree(cexpr->right);
1383 if (cexpr->opval.op==CAST) {
1384 // cast ignored, maybe we should throw a warning here?
1385 return constExprTree(cexpr->right);
1387 if (cexpr->opval.op=='&') {
1390 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1393 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1398 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1403 /*-----------------------------------------------------------------*/
1404 /* constExprValue - returns the value of a constant expression */
1405 /* or NULL if it is not a constant expression */
1406 /*-----------------------------------------------------------------*/
1408 constExprValue (ast * cexpr, int check)
1410 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1412 /* if this is not a constant then */
1413 if (!IS_LITERAL (cexpr->ftype))
1415 /* then check if this is a literal array
1417 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1418 SPEC_CVAL (cexpr->etype).v_char &&
1419 IS_ARRAY (cexpr->ftype))
1421 value *val = valFromType (cexpr->ftype);
1422 SPEC_SCLS (val->etype) = S_LITERAL;
1423 val->sym = cexpr->opval.val->sym;
1424 val->sym->type = copyLinkChain (cexpr->ftype);
1425 val->sym->etype = getSpec (val->sym->type);
1426 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1430 /* if we are casting a literal value then */
1431 if (IS_AST_OP (cexpr) &&
1432 cexpr->opval.op == CAST &&
1433 IS_LITERAL (cexpr->right->ftype))
1435 return valCastLiteral (cexpr->ftype,
1436 floatFromVal (cexpr->right->opval.val));
1439 if (IS_AST_VALUE (cexpr))
1441 return cexpr->opval.val;
1445 werror (E_CONST_EXPECTED, "found expression");
1450 /* return the value */
1451 return cexpr->opval.val;
1455 /*-----------------------------------------------------------------*/
1456 /* isLabelInAst - will return true if a given label is found */
1457 /*-----------------------------------------------------------------*/
1459 isLabelInAst (symbol * label, ast * tree)
1461 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1464 if (IS_AST_OP (tree) &&
1465 tree->opval.op == LABEL &&
1466 isSymbolEqual (AST_SYMBOL (tree->left), label))
1469 return isLabelInAst (label, tree->right) &&
1470 isLabelInAst (label, tree->left);
1474 /*-----------------------------------------------------------------*/
1475 /* isLoopCountable - return true if the loop count can be determi- */
1476 /* -ned at compile time . */
1477 /*-----------------------------------------------------------------*/
1479 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1480 symbol ** sym, ast ** init, ast ** end)
1483 /* the loop is considered countable if the following
1484 conditions are true :-
1486 a) initExpr :- <sym> = <const>
1487 b) condExpr :- <sym> < <const1>
1488 c) loopExpr :- <sym> ++
1491 /* first check the initExpr */
1492 if (IS_AST_OP (initExpr) &&
1493 initExpr->opval.op == '=' && /* is assignment */
1494 IS_AST_SYM_VALUE (initExpr->left))
1495 { /* left is a symbol */
1497 *sym = AST_SYMBOL (initExpr->left);
1498 *init = initExpr->right;
1503 /* for now the symbol has to be of
1505 if (!IS_INTEGRAL ((*sym)->type))
1508 /* now check condExpr */
1509 if (IS_AST_OP (condExpr))
1512 switch (condExpr->opval.op)
1515 if (IS_AST_SYM_VALUE (condExpr->left) &&
1516 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1517 IS_AST_LIT_VALUE (condExpr->right))
1519 *end = condExpr->right;
1525 if (IS_AST_OP (condExpr->left) &&
1526 condExpr->left->opval.op == '>' &&
1527 IS_AST_LIT_VALUE (condExpr->left->right) &&
1528 IS_AST_SYM_VALUE (condExpr->left->left) &&
1529 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1532 *end = newNode ('+', condExpr->left->right,
1533 newAst_VALUE (constVal ("1")));
1546 /* check loop expression is of the form <sym>++ */
1547 if (!IS_AST_OP (loopExpr))
1550 /* check if <sym> ++ */
1551 if (loopExpr->opval.op == INC_OP)
1557 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1558 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1565 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1566 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1574 if (loopExpr->opval.op == ADD_ASSIGN)
1577 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1578 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1579 IS_AST_LIT_VALUE (loopExpr->right) &&
1580 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1588 /*-----------------------------------------------------------------*/
1589 /* astHasVolatile - returns true if ast contains any volatile */
1590 /*-----------------------------------------------------------------*/
1592 astHasVolatile (ast * tree)
1597 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1600 if (IS_AST_OP (tree))
1601 return astHasVolatile (tree->left) ||
1602 astHasVolatile (tree->right);
1607 /*-----------------------------------------------------------------*/
1608 /* astHasPointer - return true if the ast contains any ptr variable */
1609 /*-----------------------------------------------------------------*/
1611 astHasPointer (ast * tree)
1616 if (IS_AST_LINK (tree))
1619 /* if we hit an array expression then check
1620 only the left side */
1621 if (IS_AST_OP (tree) && tree->opval.op == '[')
1622 return astHasPointer (tree->left);
1624 if (IS_AST_VALUE (tree))
1625 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1627 return astHasPointer (tree->left) ||
1628 astHasPointer (tree->right);
1632 /*-----------------------------------------------------------------*/
1633 /* astHasSymbol - return true if the ast has the given symbol */
1634 /*-----------------------------------------------------------------*/
1636 astHasSymbol (ast * tree, symbol * sym)
1638 if (!tree || IS_AST_LINK (tree))
1641 if (IS_AST_VALUE (tree))
1643 if (IS_AST_SYM_VALUE (tree))
1644 return isSymbolEqual (AST_SYMBOL (tree), sym);
1649 return astHasSymbol (tree->left, sym) ||
1650 astHasSymbol (tree->right, sym);
1653 /*-----------------------------------------------------------------*/
1654 /* astHasDeref - return true if the ast has an indirect access */
1655 /*-----------------------------------------------------------------*/
1657 astHasDeref (ast * tree)
1659 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1662 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1664 return astHasDeref (tree->left) || astHasDeref (tree->right);
1667 /*-----------------------------------------------------------------*/
1668 /* isConformingBody - the loop body has to conform to a set of rules */
1669 /* for the loop to be considered reversible read on for rules */
1670 /*-----------------------------------------------------------------*/
1672 isConformingBody (ast * pbody, symbol * sym, ast * body)
1675 /* we are going to do a pre-order traversal of the
1676 tree && check for the following conditions. (essentially
1677 a set of very shallow tests )
1678 a) the sym passed does not participate in
1679 any arithmetic operation
1680 b) There are no function calls
1681 c) all jumps are within the body
1682 d) address of loop control variable not taken
1683 e) if an assignment has a pointer on the
1684 left hand side make sure right does not have
1685 loop control variable */
1687 /* if we reach the end or a leaf then true */
1688 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1691 /* if anything else is "volatile" */
1692 if (IS_VOLATILE (TETYPE (pbody)))
1695 /* we will walk the body in a pre-order traversal for
1697 switch (pbody->opval.op)
1699 /*------------------------------------------------------------------*/
1701 // if the loopvar is used as an index
1702 /* array op is commutative -- must check both left & right */
1703 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1706 return isConformingBody (pbody->right, sym, body)
1707 && isConformingBody (pbody->left, sym, body);
1709 /*------------------------------------------------------------------*/
1714 /*------------------------------------------------------------------*/
1718 /* sure we are not sym is not modified */
1720 IS_AST_SYM_VALUE (pbody->left) &&
1721 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1725 IS_AST_SYM_VALUE (pbody->right) &&
1726 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1731 /*------------------------------------------------------------------*/
1733 case '*': /* can be unary : if right is null then unary operation */
1738 /* if right is NULL then unary operation */
1739 /*------------------------------------------------------------------*/
1740 /*----------------------------*/
1742 /*----------------------------*/
1745 if (IS_AST_SYM_VALUE (pbody->left) &&
1746 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1749 return isConformingBody (pbody->left, sym, body);
1753 if (astHasSymbol (pbody->left, sym) ||
1754 astHasSymbol (pbody->right, sym))
1759 /*------------------------------------------------------------------*/
1770 if (IS_AST_SYM_VALUE (pbody->left) &&
1771 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1774 if (IS_AST_SYM_VALUE (pbody->right) &&
1775 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1778 return isConformingBody (pbody->left, sym, body) &&
1779 isConformingBody (pbody->right, sym, body);
1787 if (IS_AST_SYM_VALUE (pbody->left) &&
1788 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1790 return isConformingBody (pbody->left, sym, body);
1792 /*------------------------------------------------------------------*/
1804 case SIZEOF: /* evaluate wihout code generation */
1806 if (IS_AST_SYM_VALUE (pbody->left) &&
1807 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1810 if (IS_AST_SYM_VALUE (pbody->right) &&
1811 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1814 return isConformingBody (pbody->left, sym, body) &&
1815 isConformingBody (pbody->right, sym, body);
1817 /*------------------------------------------------------------------*/
1820 /* if left has a pointer & right has loop
1821 control variable then we cannot */
1822 if (astHasPointer (pbody->left) &&
1823 astHasSymbol (pbody->right, sym))
1825 if (astHasVolatile (pbody->left))
1828 if (IS_AST_SYM_VALUE (pbody->left)) {
1829 // if the loopvar has an assignment
1830 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1832 // if the loopvar is used in another (maybe conditional) block
1833 if (astHasSymbol (pbody->right, sym) &&
1834 (pbody->level >= body->level)) {
1839 if (astHasVolatile (pbody->left))
1842 if (astHasDeref(pbody->right)) return FALSE;
1844 return isConformingBody (pbody->left, sym, body) &&
1845 isConformingBody (pbody->right, sym, body);
1856 assert ("Parser should not have generated this\n");
1858 /*------------------------------------------------------------------*/
1859 /*----------------------------*/
1860 /* comma operator */
1861 /*----------------------------*/
1863 return isConformingBody (pbody->left, sym, body) &&
1864 isConformingBody (pbody->right, sym, body);
1866 /*------------------------------------------------------------------*/
1867 /*----------------------------*/
1869 /*----------------------------*/
1871 /* if local & not passed as paramater then ok */
1872 if (sym->level && !astHasSymbol(pbody->right,sym))
1876 /*------------------------------------------------------------------*/
1877 /*----------------------------*/
1878 /* return statement */
1879 /*----------------------------*/
1884 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1889 if (astHasSymbol (pbody->left, sym))
1896 return isConformingBody (pbody->left, sym, body) &&
1897 isConformingBody (pbody->right, sym, body);
1903 /*-----------------------------------------------------------------*/
1904 /* isLoopReversible - takes a for loop as input && returns true */
1905 /* if the for loop is reversible. If yes will set the value of */
1906 /* the loop control var & init value & termination value */
1907 /*-----------------------------------------------------------------*/
1909 isLoopReversible (ast * loop, symbol ** loopCntrl,
1910 ast ** init, ast ** end)
1912 /* if option says don't do it then don't */
1913 if (optimize.noLoopReverse)
1915 /* there are several tests to determine this */
1917 /* for loop has to be of the form
1918 for ( <sym> = <const1> ;
1919 [<sym> < <const2>] ;
1920 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1922 if (!isLoopCountable (AST_FOR (loop, initExpr),
1923 AST_FOR (loop, condExpr),
1924 AST_FOR (loop, loopExpr),
1925 loopCntrl, init, end))
1928 /* now do some serious checking on the body of the loop
1931 return isConformingBody (loop->left, *loopCntrl, loop->left);
1935 /*-----------------------------------------------------------------*/
1936 /* replLoopSym - replace the loop sym by loop sym -1 */
1937 /*-----------------------------------------------------------------*/
1939 replLoopSym (ast * body, symbol * sym)
1942 if (!body || IS_AST_LINK (body))
1945 if (IS_AST_SYM_VALUE (body))
1948 if (isSymbolEqual (AST_SYMBOL (body), sym))
1952 body->opval.op = '-';
1953 body->left = newAst_VALUE (symbolVal (sym));
1954 body->right = newAst_VALUE (constVal ("1"));
1962 replLoopSym (body->left, sym);
1963 replLoopSym (body->right, sym);
1967 /*-----------------------------------------------------------------*/
1968 /* reverseLoop - do the actual loop reversal */
1969 /*-----------------------------------------------------------------*/
1971 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1975 /* create the following tree
1980 if (sym) goto for_continue ;
1983 /* put it together piece by piece */
1984 rloop = newNode (NULLOP,
1985 createIf (newAst_VALUE (symbolVal (sym)),
1987 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1990 newAst_VALUE (symbolVal (sym)),
1993 replLoopSym (loop->left, sym);
1994 setAstLineno (rloop, init->lineno);
1996 rloop = newNode (NULLOP,
1998 newAst_VALUE (symbolVal (sym)),
1999 newNode ('-', end, init)),
2000 createLabel (AST_FOR (loop, continueLabel),
2004 newNode (SUB_ASSIGN,
2005 newAst_VALUE (symbolVal (sym)),
2006 newAst_VALUE (constVal ("1"))),
2009 rloop->lineno=init->lineno;
2010 return decorateType (rloop, RESULT_TYPE_NONE);
2014 /*-----------------------------------------------------------------*/
2015 /* searchLitOp - search tree (*ops only) for an ast with literal */
2016 /*-----------------------------------------------------------------*/
2018 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2022 if (tree && optimize.global_cse)
2024 /* is there a literal operand? */
2026 IS_AST_OP(tree->right) &&
2027 tree->right->right &&
2028 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2030 if (IS_LITERAL (RTYPE (tree->right)) !=
2031 IS_LITERAL (LTYPE (tree->right)))
2033 tree->right->decorated = 0;
2034 tree->decorated = 0;
2038 ret = searchLitOp (tree->right, parent, ops);
2043 IS_AST_OP(tree->left) &&
2044 tree->left->right &&
2045 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2047 if (IS_LITERAL (RTYPE (tree->left)) !=
2048 IS_LITERAL (LTYPE (tree->left)))
2050 tree->left->decorated = 0;
2051 tree->decorated = 0;
2055 ret = searchLitOp (tree->left, parent, ops);
2063 /*-----------------------------------------------------------------*/
2064 /* getResultFromType */
2065 /*-----------------------------------------------------------------*/
2067 getResultTypeFromType (sym_link *type)
2069 /* type = getSpec (type); */
2071 return RESULT_TYPE_BIT;
2072 if (IS_BITFIELD (type))
2074 int blen = SPEC_BLEN (type);
2077 return RESULT_TYPE_BIT;
2079 return RESULT_TYPE_CHAR;
2080 return RESULT_TYPE_INT;
2083 return RESULT_TYPE_CHAR;
2086 return RESULT_TYPE_INT;
2087 return RESULT_TYPE_OTHER;
2090 /*-----------------------------------------------------------------*/
2091 /* addCast - adds casts to a type specified by RESULT_TYPE */
2092 /*-----------------------------------------------------------------*/
2094 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2097 bool upCasted = FALSE;
2101 case RESULT_TYPE_NONE:
2102 /* if thing smaller than int must be promoted to int */
2104 getSize (tree->etype) >= INTSIZE)
2105 /* promotion not necessary or already an int */
2107 /* char and bits: promote to int */
2108 newLink = newIntLink();
2111 case RESULT_TYPE_BIT:
2113 /* already an int */
2114 bitsForType (tree->etype) >= 16 ||
2115 /* bit to bit operation: don't promote, the code generators
2116 hopefully know everything about promotion rules */
2117 bitsForType (tree->etype) == 1)
2119 newLink = newIntLink();
2122 case RESULT_TYPE_CHAR:
2123 if (IS_CHAR (tree->etype) ||
2124 IS_FLOAT(tree->etype) ||
2125 IS_FIXED(tree->etype))
2127 newLink = newCharLink();
2129 case RESULT_TYPE_INT:
2131 if (getSize (tree->etype) > INTSIZE)
2133 /* warn ("Loosing significant digits"); */
2137 /* char: promote to int */
2139 getSize (tree->etype) >= INTSIZE)
2141 newLink = newIntLink();
2144 case RESULT_TYPE_OTHER:
2147 /* return type is long, float: promote char to int */
2148 if (getSize (tree->etype) >= INTSIZE)
2150 newLink = newIntLink();
2156 tree->decorated = 0;
2157 tree = newNode (CAST, newAst_LINK (newLink), tree);
2158 tree->lineno = tree->right->lineno;
2159 /* keep unsigned type during cast to smaller type,
2160 but not when promoting from char to int */
2162 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2163 return decorateType (tree, resultType);
2166 /*-----------------------------------------------------------------*/
2167 /* resultTypePropagate - decides if resultType can be propagated */
2168 /*-----------------------------------------------------------------*/
2170 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2172 switch (tree->opval.op)
2191 return RESULT_TYPE_NONE;
2195 return RESULT_TYPE_IFX;
2197 return RESULT_TYPE_NONE;
2201 /*-----------------------------------------------------------------*/
2202 /* getLeftResultType - gets type from left branch for propagation */
2203 /*-----------------------------------------------------------------*/
2205 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2207 switch (tree->opval.op)
2211 if (IS_PTR (LTYPE (tree)))
2212 return RESULT_TYPE_NONE;
2214 return getResultTypeFromType (LETYPE (tree));
2216 if (IS_PTR (currFunc->type->next))
2217 return RESULT_TYPE_NONE;
2219 return getResultTypeFromType (currFunc->type->next);
2221 if (!IS_ARRAY (LTYPE (tree)))
2223 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2224 return RESULT_TYPE_CHAR;
2231 /*--------------------------------------------------------------------*/
2232 /* decorateType - compute type for this tree, also does type checking.*/
2233 /* This is done bottom up, since type has to flow upwards. */
2234 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2235 /* result is a char and the operand(s) are int's. */
2236 /* It also does constant folding, and parameter checking. */
2237 /*--------------------------------------------------------------------*/
2239 decorateType (ast * tree, RESULT_TYPE resultType)
2243 RESULT_TYPE resultTypeProp;
2248 /* if already has type then do nothing */
2249 if (tree->decorated)
2252 tree->decorated = 1;
2255 /* print the line */
2256 /* if not block & function */
2257 if (tree->type == EX_OP &&
2258 (tree->opval.op != FUNCTION &&
2259 tree->opval.op != BLOCK &&
2260 tree->opval.op != NULLOP))
2262 filename = tree->filename;
2263 lineno = tree->lineno;
2267 /* if any child is an error | this one is an error do nothing */
2268 if (tree->isError ||
2269 (tree->left && tree->left->isError) ||
2270 (tree->right && tree->right->isError))
2273 /*------------------------------------------------------------------*/
2274 /*----------------------------*/
2275 /* leaf has been reached */
2276 /*----------------------------*/
2277 lineno=tree->lineno;
2278 /* if this is of type value */
2279 /* just get the type */
2280 if (tree->type == EX_VALUE)
2283 if (IS_LITERAL (tree->opval.val->etype))
2286 /* if this is a character array then declare it */
2287 if (IS_ARRAY (tree->opval.val->type))
2288 tree->opval.val = stringToSymbol (tree->opval.val);
2290 /* otherwise just copy the type information */
2291 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2295 if (tree->opval.val->sym)
2297 /* if the undefined flag is set then give error message */
2298 if (tree->opval.val->sym->undefined)
2300 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2302 TTYPE (tree) = TETYPE (tree) =
2303 tree->opval.val->type = tree->opval.val->sym->type =
2304 tree->opval.val->etype = tree->opval.val->sym->etype =
2305 copyLinkChain (INTTYPE);
2310 /* if impilicit i.e. struct/union member then no type */
2311 if (tree->opval.val->sym->implicit)
2312 TTYPE (tree) = TETYPE (tree) = NULL;
2317 /* else copy the type */
2318 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2320 /* and mark it as referenced */
2321 tree->opval.val->sym->isref = 1;
2329 /* if type link for the case of cast */
2330 if (tree->type == EX_LINK)
2332 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2340 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2342 if (tree->left && tree->left->type == EX_OPERAND
2343 && (tree->left->opval.op == INC_OP
2344 || tree->left->opval.op == DEC_OP)
2345 && tree->left->left)
2347 tree->left->right = tree->left->left;
2348 tree->left->left = NULL;
2350 if (tree->right && tree->right->type == EX_OPERAND
2351 && (tree->right->opval.op == INC_OP
2352 || tree->right->opval.op == DEC_OP)
2353 && tree->right->left)
2355 tree->right->right = tree->right->left;
2356 tree->right->left = NULL;
2361 /* Before decorating the left branch we've to decide in dependence
2362 upon tree->opval.op, if resultType can be propagated */
2363 resultTypeProp = resultTypePropagate (tree, resultType);
2365 if (tree->opval.op == '?')
2366 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2368 dtl = decorateType (tree->left, resultTypeProp);
2370 /* if an array node, we may need to swap branches */
2371 if (tree->opval.op == '[')
2373 /* determine which is the array & which the index */
2374 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2375 IS_INTEGRAL (LTYPE (tree)))
2377 ast *tempTree = tree->left;
2378 tree->left = tree->right;
2379 tree->right = tempTree;
2383 /* After decorating the left branch there's type information available
2384 in tree->left->?type. If the op is e.g. '=' we extract the type
2385 information from there and propagate it to the right branch. */
2386 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2388 switch (tree->opval.op)
2391 /* delay right side for '?' operator since conditional macro
2392 expansions might rely on this */
2396 /* decorate right side for CALL (parameter list) in processParms();
2397 there is resultType available */
2401 dtr = decorateType (tree->right, resultTypeProp);
2405 /* this is to take care of situations
2406 when the tree gets rewritten */
2407 if (dtl != tree->left)
2409 if (dtr != tree->right)
2411 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2415 /* depending on type of operator do */
2417 switch (tree->opval.op)
2419 /*------------------------------------------------------------------*/
2420 /*----------------------------*/
2422 /*----------------------------*/
2425 /* first check if this is a array or a pointer */
2426 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2428 werror (E_NEED_ARRAY_PTR, "[]");
2429 goto errorTreeReturn;
2432 /* check if the type of the idx */
2433 if (!IS_INTEGRAL (RTYPE (tree)))
2435 werror (E_IDX_NOT_INT);
2436 goto errorTreeReturn;
2439 /* if the left is an rvalue then error */
2442 werror (E_LVALUE_REQUIRED, "array access");
2443 goto errorTreeReturn;
2446 if (IS_LITERAL (RTYPE (tree)))
2448 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2449 int arraySize = DCL_ELEM (LTYPE (tree));
2450 if (arraySize && arrayIndex >= arraySize)
2452 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2457 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2460 /*------------------------------------------------------------------*/
2461 /*----------------------------*/
2463 /*----------------------------*/
2465 /* if this is not a structure */
2466 if (!IS_STRUCT (LTYPE (tree)))
2468 werror (E_STRUCT_UNION, ".");
2469 goto errorTreeReturn;
2471 TTYPE (tree) = structElemType (LTYPE (tree),
2472 (tree->right->type == EX_VALUE ?
2473 tree->right->opval.val : NULL));
2474 TETYPE (tree) = getSpec (TTYPE (tree));
2477 /*------------------------------------------------------------------*/
2478 /*----------------------------*/
2479 /* struct/union pointer */
2480 /*----------------------------*/
2482 /* if not pointer to a structure */
2483 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2485 werror (E_PTR_REQD);
2486 goto errorTreeReturn;
2489 if (!IS_STRUCT (LTYPE (tree)->next))
2491 werror (E_STRUCT_UNION, "->");
2492 goto errorTreeReturn;
2495 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2496 (tree->right->type == EX_VALUE ?
2497 tree->right->opval.val : NULL));
2498 TETYPE (tree) = getSpec (TTYPE (tree));
2500 /* adjust the storage class */
2501 switch (DCL_TYPE(tree->left->ftype)) {
2503 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2506 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2509 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2512 SPEC_SCLS (TETYPE (tree)) = 0;
2515 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2518 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2521 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2524 SPEC_SCLS (TETYPE (tree)) = 0;
2531 /* This breaks with extern declarations, bitfields, and perhaps other */
2532 /* cases (gcse). Let's leave this optimization disabled for now and */
2533 /* ponder if there's a safe way to do this. -- EEP */
2535 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2536 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2538 /* If defined struct type at addr var
2539 then rewrite (&struct var)->member
2541 and define membertype at (addr+offsetof(struct var,member)) temp
2544 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2545 AST_SYMBOL(tree->right));
2547 sym = newSymbol(genSymName (0), 0);
2548 sym->type = TTYPE (tree);
2549 sym->etype = getSpec(sym->type);
2550 sym->lineDef = tree->lineno;
2553 SPEC_STAT (sym->etype) = 1;
2554 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2556 SPEC_ABSA(sym->etype) = 1;
2557 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2560 AST_VALUE (tree) = symbolVal(sym);
2563 tree->type = EX_VALUE;
2571 /*------------------------------------------------------------------*/
2572 /*----------------------------*/
2573 /* ++/-- operation */
2574 /*----------------------------*/
2578 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2579 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2580 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2581 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2590 /*------------------------------------------------------------------*/
2591 /*----------------------------*/
2593 /*----------------------------*/
2594 case '&': /* can be unary */
2595 /* if right is NULL then unary operation */
2596 if (tree->right) /* not an unary operation */
2599 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2601 werror (E_BITWISE_OP);
2602 werror (W_CONTINUE, "left & right types are ");
2603 printTypeChain (LTYPE (tree), stderr);
2604 fprintf (stderr, ",");
2605 printTypeChain (RTYPE (tree), stderr);
2606 fprintf (stderr, "\n");
2607 goto errorTreeReturn;
2610 /* if they are both literal */
2611 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2613 tree->type = EX_VALUE;
2614 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2615 valFromType (RETYPE (tree)), '&');
2617 tree->right = tree->left = NULL;
2618 TETYPE (tree) = tree->opval.val->etype;
2619 TTYPE (tree) = tree->opval.val->type;
2623 /* see if this is a GETHBIT operation if yes
2626 ast *otree = optimizeGetHbit (tree, resultType);
2629 return decorateType (otree, RESULT_TYPE_NONE);
2632 /* see if this is a GETABIT operation if yes
2635 ast *otree = optimizeGetAbit (tree, resultType);
2638 return decorateType (otree, RESULT_TYPE_NONE);
2641 /* see if this is a GETBYTE operation if yes
2644 ast *otree = optimizeGetByte (tree, resultType);
2647 return decorateType (otree, RESULT_TYPE_NONE);
2650 /* see if this is a GETWORD operation if yes
2653 ast *otree = optimizeGetWord (tree, resultType);
2656 return decorateType (otree, RESULT_TYPE_NONE);
2659 /* if left is a literal exchange left & right */
2660 if (IS_LITERAL (LTYPE (tree)))
2662 ast *tTree = tree->left;
2663 tree->left = tree->right;
2664 tree->right = tTree;
2667 /* if right is a literal and */
2668 /* we can find a 2nd literal in an and-tree then */
2669 /* rearrange the tree */
2670 if (IS_LITERAL (RTYPE (tree)))
2673 ast *litTree = searchLitOp (tree, &parent, "&");
2677 ast *tTree = litTree->left;
2678 litTree->left = tree->right;
2679 tree->right = tTree;
2680 /* both operands in litTree are literal now */
2681 decorateType (parent, resultType);
2685 LRVAL (tree) = RRVAL (tree) = 1;
2687 TTYPE (tree) = computeType (LTYPE (tree),
2691 TETYPE (tree) = getSpec (TTYPE (tree));
2696 /*------------------------------------------------------------------*/
2697 /*----------------------------*/
2699 /*----------------------------*/
2700 p = newLink (DECLARATOR);
2701 /* if bit field then error */
2702 if (IS_BITVAR (tree->left->etype))
2704 werror (E_ILLEGAL_ADDR, "address of bit variable");
2705 goto errorTreeReturn;
2708 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2710 werror (E_ILLEGAL_ADDR, "address of register variable");
2711 goto errorTreeReturn;
2714 if (IS_FUNC (LTYPE (tree)))
2716 // this ought to be ignored
2717 return (tree->left);
2720 if (IS_LITERAL(LTYPE(tree)))
2722 werror (E_ILLEGAL_ADDR, "address of literal");
2723 goto errorTreeReturn;
2728 werror (E_LVALUE_REQUIRED, "address of");
2729 goto errorTreeReturn;
2732 DCL_TYPE (p) = POINTER;
2733 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2734 DCL_TYPE (p) = CPOINTER;
2735 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2736 DCL_TYPE (p) = FPOINTER;
2737 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2738 DCL_TYPE (p) = PPOINTER;
2739 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2740 DCL_TYPE (p) = IPOINTER;
2741 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2742 DCL_TYPE (p) = EEPPOINTER;
2743 else if (SPEC_OCLS(tree->left->etype))
2744 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2746 DCL_TYPE (p) = POINTER;
2748 if (IS_AST_SYM_VALUE (tree->left))
2750 AST_SYMBOL (tree->left)->addrtaken = 1;
2751 AST_SYMBOL (tree->left)->allocreq = 1;
2754 p->next = LTYPE (tree);
2756 TETYPE (tree) = getSpec (TTYPE (tree));
2761 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2762 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2764 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2765 AST_SYMBOL(tree->left->right));
2766 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2767 valueFromLit(element->offset));
2770 tree->type = EX_VALUE;
2771 tree->values.literalFromCast = 1;
2777 /*------------------------------------------------------------------*/
2778 /*----------------------------*/
2780 /*----------------------------*/
2782 /* if the rewrite succeeds then don't go any further */
2784 ast *wtree = optimizeRRCRLC (tree);
2786 return decorateType (wtree, RESULT_TYPE_NONE);
2788 wtree = optimizeSWAP (tree);
2790 return decorateType (wtree, RESULT_TYPE_NONE);
2793 /* if left is a literal exchange left & right */
2794 if (IS_LITERAL (LTYPE (tree)))
2796 ast *tTree = tree->left;
2797 tree->left = tree->right;
2798 tree->right = tTree;
2801 /* if right is a literal and */
2802 /* we can find a 2nd literal in an or-tree then */
2803 /* rearrange the tree */
2804 if (IS_LITERAL (RTYPE (tree)))
2807 ast *litTree = searchLitOp (tree, &parent, "|");
2811 ast *tTree = litTree->left;
2812 litTree->left = tree->right;
2813 tree->right = tTree;
2814 /* both operands in tTree are literal now */
2815 decorateType (parent, resultType);
2820 /*------------------------------------------------------------------*/
2821 /*----------------------------*/
2823 /*----------------------------*/
2825 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2827 werror (E_BITWISE_OP);
2828 werror (W_CONTINUE, "left & right types are ");
2829 printTypeChain (LTYPE (tree), stderr);
2830 fprintf (stderr, ",");
2831 printTypeChain (RTYPE (tree), stderr);
2832 fprintf (stderr, "\n");
2833 goto errorTreeReturn;
2836 /* if they are both literal then rewrite the tree */
2837 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2839 tree->type = EX_VALUE;
2840 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2841 valFromType (RETYPE (tree)),
2843 tree->right = tree->left = NULL;
2844 TETYPE (tree) = tree->opval.val->etype;
2845 TTYPE (tree) = tree->opval.val->type;
2849 /* if left is a literal exchange left & right */
2850 if (IS_LITERAL (LTYPE (tree)))
2852 ast *tTree = tree->left;
2853 tree->left = tree->right;
2854 tree->right = tTree;
2857 /* if right is a literal and */
2858 /* we can find a 2nd literal in a xor-tree then */
2859 /* rearrange the tree */
2860 if (IS_LITERAL (RTYPE (tree)) &&
2861 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2864 ast *litTree = searchLitOp (tree, &parent, "^");
2868 ast *tTree = litTree->left;
2869 litTree->left = tree->right;
2870 tree->right = tTree;
2871 /* both operands in litTree are literal now */
2872 decorateType (parent, resultType);
2876 LRVAL (tree) = RRVAL (tree) = 1;
2878 TTYPE (tree) = computeType (LTYPE (tree),
2882 TETYPE (tree) = getSpec (TTYPE (tree));
2886 /*------------------------------------------------------------------*/
2887 /*----------------------------*/
2889 /*----------------------------*/
2891 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2893 werror (E_INVALID_OP, "divide");
2894 goto errorTreeReturn;
2896 /* if they are both literal then */
2897 /* rewrite the tree */
2898 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2900 tree->type = EX_VALUE;
2901 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2902 valFromType (RETYPE (tree)));
2903 tree->right = tree->left = NULL;
2904 TETYPE (tree) = getSpec (TTYPE (tree) =
2905 tree->opval.val->type);
2909 LRVAL (tree) = RRVAL (tree) = 1;
2911 TETYPE (tree) = getSpec (TTYPE (tree) =
2912 computeType (LTYPE (tree),
2917 /* if right is a literal and */
2918 /* left is also a division by a literal then */
2919 /* rearrange the tree */
2920 if (IS_LITERAL (RTYPE (tree))
2921 /* avoid infinite loop */
2922 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2925 ast *litTree = searchLitOp (tree, &parent, "/");
2928 if (IS_LITERAL (RTYPE (litTree)))
2932 litTree->right = newNode ('*',
2934 copyAst (tree->right));
2935 litTree->right->lineno = tree->lineno;
2937 tree->right->opval.val = constVal ("1");
2938 decorateType (parent, resultType);
2942 /* litTree->left is literal: no gcse possible.
2943 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2944 this would cause an infinit loop. */
2945 parent->decorated = 1;
2946 decorateType (litTree, resultType);
2953 /*------------------------------------------------------------------*/
2954 /*----------------------------*/
2956 /*----------------------------*/
2958 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2960 werror (E_BITWISE_OP);
2961 werror (W_CONTINUE, "left & right types are ");
2962 printTypeChain (LTYPE (tree), stderr);
2963 fprintf (stderr, ",");
2964 printTypeChain (RTYPE (tree), stderr);
2965 fprintf (stderr, "\n");
2966 goto errorTreeReturn;
2968 /* if they are both literal then */
2969 /* rewrite the tree */
2970 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2972 tree->type = EX_VALUE;
2973 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2974 valFromType (RETYPE (tree)));
2975 tree->right = tree->left = NULL;
2976 TETYPE (tree) = getSpec (TTYPE (tree) =
2977 tree->opval.val->type);
2980 LRVAL (tree) = RRVAL (tree) = 1;
2981 TETYPE (tree) = getSpec (TTYPE (tree) =
2982 computeType (LTYPE (tree),
2988 /*------------------------------------------------------------------*/
2989 /*----------------------------*/
2990 /* address dereference */
2991 /*----------------------------*/
2992 case '*': /* can be unary : if right is null then unary operation */
2995 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2997 werror (E_PTR_REQD);
2998 goto errorTreeReturn;
3003 werror (E_LVALUE_REQUIRED, "pointer deref");
3004 goto errorTreeReturn;
3006 if (IS_ADDRESS_OF_OP(tree->left))
3008 /* replace *&obj with obj */
3009 return tree->left->left;
3011 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3012 TETYPE (tree) = getSpec (TTYPE (tree));
3013 /* adjust the storage class */
3014 switch (DCL_TYPE(tree->left->ftype)) {
3016 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3019 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3022 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3025 SPEC_SCLS (TETYPE (tree)) = 0;
3028 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3031 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3034 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3037 SPEC_SCLS (TETYPE (tree)) = 0;
3046 /*------------------------------------------------------------------*/
3047 /*----------------------------*/
3048 /* multiplication */
3049 /*----------------------------*/
3050 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3052 werror (E_INVALID_OP, "multiplication");
3053 goto errorTreeReturn;
3056 /* if they are both literal then */
3057 /* rewrite the tree */
3058 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3060 tree->type = EX_VALUE;
3061 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3062 valFromType (RETYPE (tree)));
3063 tree->right = tree->left = NULL;
3064 TETYPE (tree) = getSpec (TTYPE (tree) =
3065 tree->opval.val->type);
3069 /* if left is a literal exchange left & right */
3070 if (IS_LITERAL (LTYPE (tree)))
3072 ast *tTree = tree->left;
3073 tree->left = tree->right;
3074 tree->right = tTree;
3077 /* if right is a literal and */
3078 /* we can find a 2nd literal in a mul-tree then */
3079 /* rearrange the tree */
3080 if (IS_LITERAL (RTYPE (tree)))
3083 ast *litTree = searchLitOp (tree, &parent, "*");
3087 ast *tTree = litTree->left;
3088 litTree->left = tree->right;
3089 tree->right = tTree;
3090 /* both operands in litTree are literal now */
3091 decorateType (parent, resultType);
3095 LRVAL (tree) = RRVAL (tree) = 1;
3096 tree->left = addCast (tree->left, resultType, FALSE);
3097 tree->right = addCast (tree->right, resultType, FALSE);
3098 TETYPE (tree) = getSpec (TTYPE (tree) =
3099 computeType (LTYPE (tree),
3106 /*------------------------------------------------------------------*/
3107 /*----------------------------*/
3108 /* unary '+' operator */
3109 /*----------------------------*/
3114 if (!IS_ARITHMETIC (LTYPE (tree)))
3116 werror (E_UNARY_OP, '+');
3117 goto errorTreeReturn;
3120 /* if left is a literal then do it */
3121 if (IS_LITERAL (LTYPE (tree)))
3123 tree->type = EX_VALUE;
3124 tree->opval.val = valFromType (LETYPE (tree));
3126 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3130 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3134 /*------------------------------------------------------------------*/
3135 /*----------------------------*/
3137 /*----------------------------*/
3139 /* this is not a unary operation */
3140 /* if both pointers then problem */
3141 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3142 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3144 werror (E_PTR_PLUS_PTR);
3145 goto errorTreeReturn;
3148 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3149 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3151 werror (E_PLUS_INVALID, "+");
3152 goto errorTreeReturn;
3155 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3156 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3158 werror (E_PLUS_INVALID, "+");
3159 goto errorTreeReturn;
3161 /* if they are both literal then */
3162 /* rewrite the tree */
3163 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3165 tree->type = EX_VALUE;
3166 tree->left = addCast (tree->left, resultType, TRUE);
3167 tree->right = addCast (tree->right, resultType, TRUE);
3168 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3169 valFromType (RETYPE (tree)));
3170 tree->right = tree->left = NULL;
3171 TETYPE (tree) = getSpec (TTYPE (tree) =
3172 tree->opval.val->type);
3176 /* if the right is a pointer or left is a literal
3177 xchange left & right */
3178 if (IS_ARRAY (RTYPE (tree)) ||
3179 IS_PTR (RTYPE (tree)) ||
3180 IS_LITERAL (LTYPE (tree)))
3182 ast *tTree = tree->left;
3183 tree->left = tree->right;
3184 tree->right = tTree;
3187 /* if right is a literal and */
3188 /* left is also an addition/subtraction with a literal then */
3189 /* rearrange the tree */
3190 if (IS_LITERAL (RTYPE (tree)))
3192 ast *litTree, *parent;
3193 litTree = searchLitOp (tree, &parent, "+-");
3196 if (litTree->opval.op == '+')
3200 ast *tTree = litTree->left;
3201 litTree->left = tree->right;
3202 tree->right = tree->left;
3205 else if (litTree->opval.op == '-')
3207 if (IS_LITERAL (RTYPE (litTree)))
3211 ast *tTree = litTree->left;
3212 litTree->left = tree->right;
3213 tree->right = tTree;
3219 ast *tTree = litTree->right;
3220 litTree->right = tree->right;
3221 tree->right = tTree;
3222 litTree->opval.op = '+';
3223 tree->opval.op = '-';
3226 decorateType (parent, resultType);
3230 LRVAL (tree) = RRVAL (tree) = 1;
3231 /* if the left is a pointer */
3232 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3233 TETYPE (tree) = getSpec (TTYPE (tree) =
3237 tree->left = addCast (tree->left, resultType, TRUE);
3238 tree->right = addCast (tree->right, resultType, TRUE);
3239 TETYPE (tree) = getSpec (TTYPE (tree) =
3240 computeType (LTYPE (tree),
3248 /*------------------------------------------------------------------*/
3249 /*----------------------------*/
3251 /*----------------------------*/
3252 case '-': /* can be unary */
3253 /* if right is null then unary */
3257 if (!IS_ARITHMETIC (LTYPE (tree)))
3259 werror (E_UNARY_OP, tree->opval.op);
3260 goto errorTreeReturn;
3263 /* if left is a literal then do it */
3264 if (IS_LITERAL (LTYPE (tree)))
3266 tree->type = EX_VALUE;
3267 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3269 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3270 SPEC_USIGN(TETYPE(tree)) = 0;
3274 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3278 /*------------------------------------------------------------------*/
3279 /*----------------------------*/
3281 /*----------------------------*/
3283 if (!(IS_PTR (LTYPE (tree)) ||
3284 IS_ARRAY (LTYPE (tree)) ||
3285 IS_ARITHMETIC (LTYPE (tree))))
3287 werror (E_PLUS_INVALID, "-");
3288 goto errorTreeReturn;
3291 if (!(IS_PTR (RTYPE (tree)) ||
3292 IS_ARRAY (RTYPE (tree)) ||
3293 IS_ARITHMETIC (RTYPE (tree))))
3295 werror (E_PLUS_INVALID, "-");
3296 goto errorTreeReturn;
3299 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3300 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3301 IS_INTEGRAL (RTYPE (tree))))
3303 werror (E_PLUS_INVALID, "-");
3304 goto errorTreeReturn;
3307 /* if they are both literal then */
3308 /* rewrite the tree */
3309 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3311 tree->type = EX_VALUE;
3312 tree->left = addCast (tree->left, resultType, TRUE);
3313 tree->right = addCast (tree->right, resultType, TRUE);
3314 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3315 valFromType (RETYPE (tree)));
3316 tree->right = tree->left = NULL;
3317 TETYPE (tree) = getSpec (TTYPE (tree) =
3318 tree->opval.val->type);
3322 /* if the left & right are equal then zero */
3323 if (isAstEqual (tree->left, tree->right))
3325 tree->type = EX_VALUE;
3326 tree->left = tree->right = NULL;
3327 tree->opval.val = constVal ("0");
3328 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3332 /* if both of them are pointers or arrays then */
3333 /* the result is going to be an integer */
3334 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3335 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3336 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3338 /* if only the left is a pointer */
3339 /* then result is a pointer */
3340 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3341 TETYPE (tree) = getSpec (TTYPE (tree) =
3345 tree->left = addCast (tree->left, resultType, TRUE);
3346 tree->right = addCast (tree->right, resultType, TRUE);
3348 TETYPE (tree) = getSpec (TTYPE (tree) =
3349 computeType (LTYPE (tree),
3355 LRVAL (tree) = RRVAL (tree) = 1;
3357 /* if right is a literal and */
3358 /* left is also an addition/subtraction with a literal then */
3359 /* rearrange the tree */
3360 if (IS_LITERAL (RTYPE (tree))
3361 /* avoid infinite loop */
3362 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3364 ast *litTree, *litParent;
3365 litTree = searchLitOp (tree, &litParent, "+-");
3368 if (litTree->opval.op == '+')
3372 ast *tTree = litTree->left;
3373 litTree->left = litTree->right;
3374 litTree->right = tree->right;
3375 tree->right = tTree;
3376 tree->opval.op = '+';
3377 litTree->opval.op = '-';
3379 else if (litTree->opval.op == '-')
3381 if (IS_LITERAL (RTYPE (litTree)))
3385 ast *tTree = litTree->left;
3386 litTree->left = tree->right;
3387 tree->right = litParent->left;
3388 litParent->left = tTree;
3389 litTree->opval.op = '+';
3391 tree->decorated = 0;
3392 decorateType (tree, resultType);
3398 ast *tTree = litTree->right;
3399 litTree->right = tree->right;
3400 tree->right = tTree;
3403 decorateType (litParent, resultType);
3408 /*------------------------------------------------------------------*/
3409 /*----------------------------*/
3411 /*----------------------------*/
3413 /* can be only integral type */
3414 if (!IS_INTEGRAL (LTYPE (tree)))
3416 werror (E_UNARY_OP, tree->opval.op);
3417 goto errorTreeReturn;
3420 /* if left is a literal then do it */
3421 if (IS_LITERAL (LTYPE (tree)))
3423 tree->type = EX_VALUE;
3424 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3426 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3427 return addCast (tree, resultType, TRUE);
3430 if (resultType == RESULT_TYPE_BIT &&
3431 IS_UNSIGNED (tree->left->etype) &&
3432 getSize (tree->left->etype) < INTSIZE)
3434 /* promotion rules are responsible for this strange result:
3435 bit -> int -> ~int -> bit
3436 uchar -> int -> ~int -> bit
3438 werror(W_COMPLEMENT);
3440 /* optimize bit-result, even if we optimize a buggy source */
3441 tree->type = EX_VALUE;
3442 tree->opval.val = constVal ("1");
3445 tree->left = addCast (tree->left, resultType, TRUE);
3447 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3450 /*------------------------------------------------------------------*/
3451 /*----------------------------*/
3453 /*----------------------------*/
3455 /* can be pointer */
3456 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3457 !IS_PTR (LTYPE (tree)) &&
3458 !IS_ARRAY (LTYPE (tree)))
3460 werror (E_UNARY_OP, tree->opval.op);
3461 goto errorTreeReturn;
3464 /* if left is a literal then do it */
3465 if (IS_LITERAL (LTYPE (tree)))
3467 tree->type = EX_VALUE;
3468 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3470 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3474 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3477 /*------------------------------------------------------------------*/
3478 /*----------------------------*/
3480 /*----------------------------*/
3484 TTYPE (tree) = LTYPE (tree);
3485 TETYPE (tree) = LETYPE (tree);
3490 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3494 TTYPE (tree) = TETYPE (tree) = newCharLink();
3498 TTYPE (tree) = TETYPE (tree) = newIntLink();
3503 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3505 werror (E_SHIFT_OP_INVALID);
3506 werror (W_CONTINUE, "left & right types are ");
3507 printTypeChain (LTYPE (tree), stderr);
3508 fprintf (stderr, ",");
3509 printTypeChain (RTYPE (tree), stderr);
3510 fprintf (stderr, "\n");
3511 goto errorTreeReturn;
3514 /* make smaller type only if it's a LEFT_OP */
3515 if (tree->opval.op == LEFT_OP)
3516 tree->left = addCast (tree->left, resultType, TRUE);
3518 /* if they are both literal then */
3519 /* rewrite the tree */
3520 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3522 tree->type = EX_VALUE;
3523 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3524 valFromType (RETYPE (tree)),
3525 (tree->opval.op == LEFT_OP ? 1 : 0));
3526 tree->right = tree->left = NULL;
3527 TETYPE (tree) = getSpec (TTYPE (tree) =
3528 tree->opval.val->type);
3532 /* see if this is a GETBYTE operation if yes
3535 ast *otree = optimizeGetByte (tree, resultType);
3538 return decorateType (otree, RESULT_TYPE_NONE);
3541 /* see if this is a GETWORD operation if yes
3544 ast *otree = optimizeGetWord (tree, resultType);
3547 return decorateType (otree, RESULT_TYPE_NONE);
3550 LRVAL (tree) = RRVAL (tree) = 1;
3551 if (tree->opval.op == LEFT_OP)
3553 TETYPE (tree) = getSpec (TTYPE (tree) =
3554 computeType (LTYPE (tree),
3561 /* no promotion necessary */
3562 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3563 if (IS_LITERAL (TTYPE (tree)))
3564 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3567 /* if only the right side is a literal & we are
3568 shifting more than size of the left operand then zero */
3569 if (IS_LITERAL (RTYPE (tree)) &&
3570 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3571 (getSize (TETYPE (tree)) * 8))
3573 if (tree->opval.op==LEFT_OP ||
3574 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3576 lineno=tree->lineno;
3577 werror (W_SHIFT_CHANGED,
3578 (tree->opval.op == LEFT_OP ? "left" : "right"));
3579 tree->type = EX_VALUE;
3580 tree->left = tree->right = NULL;
3581 tree->opval.val = constVal ("0");
3582 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3589 /*------------------------------------------------------------------*/
3590 /*----------------------------*/
3592 /*----------------------------*/
3593 case CAST: /* change the type */
3594 /* cannot cast to an aggregate type */
3595 if (IS_AGGREGATE (LTYPE (tree)))
3597 werror (E_CAST_ILLEGAL);
3598 goto errorTreeReturn;
3601 /* make sure the type is complete and sane */
3602 changePointer(LTYPE(tree));
3603 checkTypeSanity(LETYPE(tree), "(cast)");
3605 /* If code memory is read only, then pointers to code memory */
3606 /* implicitly point to constants -- make this explicit */
3608 sym_link *t = LTYPE(tree);
3609 while (t && t->next)
3611 if (IS_CODEPTR(t) && port->mem.code_ro)
3613 if (IS_SPEC(t->next))
3614 SPEC_CONST (t->next) = 1;
3616 DCL_PTR_CONST (t->next) = 1;
3623 /* if the right is a literal replace the tree */
3624 if (IS_LITERAL (RETYPE (tree))) {
3625 if (!IS_PTR (LTYPE (tree))) {
3626 tree->type = EX_VALUE;
3628 valCastLiteral (LTYPE (tree),
3629 floatFromVal (valFromType (RETYPE (tree))));
3632 TTYPE (tree) = tree->opval.val->type;
3633 tree->values.literalFromCast = 1;
3634 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3635 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3636 sym_link *rest = LTYPE(tree)->next;
3637 werror(W_LITERAL_GENERIC);
3638 TTYPE(tree) = newLink(DECLARATOR);
3639 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3640 TTYPE(tree)->next = rest;
3641 tree->left->opval.lnk = TTYPE(tree);
3644 TTYPE (tree) = LTYPE (tree);
3648 TTYPE (tree) = LTYPE (tree);
3652 #if 0 // this is already checked, now this could be explicit
3653 /* if pointer to struct then check names */
3654 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3655 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3656 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3658 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3659 SPEC_STRUCT(LETYPE(tree))->tag);
3662 if (IS_ADDRESS_OF_OP(tree->right)
3663 && IS_AST_SYM_VALUE (tree->right->left)
3664 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3666 symbol * sym = AST_SYMBOL (tree->right->left);
3667 unsigned int gptype = 0;
3668 unsigned int addr = SPEC_ADDR (sym->etype);
3670 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3672 switch (SPEC_SCLS (sym->etype))
3675 gptype = GPTYPE_CODE;
3678 gptype = GPTYPE_FAR;
3682 gptype = GPTYPE_NEAR;
3685 gptype = GPTYPE_XSTACK;
3690 addr |= gptype << (8*(GPTRSIZE - 1));
3693 tree->type = EX_VALUE;
3695 valCastLiteral (LTYPE (tree), addr);
3696 TTYPE (tree) = tree->opval.val->type;
3697 TETYPE (tree) = getSpec (TTYPE (tree));
3700 tree->values.literalFromCast = 1;
3704 /* handle offsetof macro: */
3705 /* #define offsetof(TYPE, MEMBER) \ */
3706 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3707 if (IS_ADDRESS_OF_OP(tree->right)
3708 && IS_AST_OP (tree->right->left)
3709 && tree->right->left->opval.op == PTR_OP
3710 && IS_AST_OP (tree->right->left->left)
3711 && tree->right->left->left->opval.op == CAST
3712 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3714 symbol *element = getStructElement (
3715 SPEC_STRUCT (LETYPE(tree->right->left)),
3716 AST_SYMBOL(tree->right->left->right)
3720 tree->type = EX_VALUE;
3721 tree->opval.val = valCastLiteral (
3724 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3727 TTYPE (tree) = tree->opval.val->type;
3728 TETYPE (tree) = getSpec (TTYPE (tree));
3735 /* if the right is a literal replace the tree */
3736 if (IS_LITERAL (RETYPE (tree))) {
3738 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3739 /* rewrite (type *)litaddr
3741 and define type at litaddr temp
3742 (but only if type's storage class is not generic)
3744 ast *newTree = newNode ('&', NULL, NULL);
3747 TTYPE (newTree) = LTYPE (tree);
3748 TETYPE (newTree) = getSpec(LTYPE (tree));
3750 /* define a global symbol at the casted address*/
3751 sym = newSymbol(genSymName (0), 0);
3752 sym->type = LTYPE (tree)->next;
3754 sym->type = newLink (V_VOID);
3755 sym->etype = getSpec(sym->type);
3756 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3757 sym->lineDef = tree->lineno;
3760 SPEC_STAT (sym->etype) = 1;
3761 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3762 SPEC_ABSA(sym->etype) = 1;
3763 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3766 newTree->left = newAst_VALUE(symbolVal(sym));
3767 newTree->left->lineno = tree->lineno;
3768 LTYPE (newTree) = sym->type;
3769 LETYPE (newTree) = sym->etype;
3770 LLVAL (newTree) = 1;
3771 LRVAL (newTree) = 0;
3772 TLVAL (newTree) = 1;
3776 if (!IS_PTR (LTYPE (tree))) {
3777 tree->type = EX_VALUE;
3779 valCastLiteral (LTYPE (tree),
3780 floatFromVal (valFromType (RTYPE (tree))));
3781 TTYPE (tree) = tree->opval.val->type;
3784 tree->values.literalFromCast = 1;
3785 TETYPE (tree) = getSpec (TTYPE (tree));
3789 TTYPE (tree) = LTYPE (tree);
3793 TETYPE (tree) = getSpec (TTYPE (tree));
3797 /*------------------------------------------------------------------*/
3798 /*----------------------------*/
3799 /* logical &&, || */
3800 /*----------------------------*/
3803 /* each must be arithmetic type or be a pointer */
3804 if (!IS_PTR (LTYPE (tree)) &&
3805 !IS_ARRAY (LTYPE (tree)) &&
3806 !IS_INTEGRAL (LTYPE (tree)))
3808 werror (E_COMPARE_OP);
3809 goto errorTreeReturn;
3812 if (!IS_PTR (RTYPE (tree)) &&
3813 !IS_ARRAY (RTYPE (tree)) &&
3814 !IS_INTEGRAL (RTYPE (tree)))
3816 werror (E_COMPARE_OP);
3817 goto errorTreeReturn;
3819 /* if they are both literal then */
3820 /* rewrite the tree */
3821 if (IS_LITERAL (RTYPE (tree)) &&
3822 IS_LITERAL (LTYPE (tree)))
3824 tree->type = EX_VALUE;
3825 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3826 valFromType (RTYPE (tree)),
3828 tree->right = tree->left = NULL;
3829 TETYPE (tree) = getSpec (TTYPE (tree) =
3830 tree->opval.val->type);
3833 LRVAL (tree) = RRVAL (tree) = 1;
3834 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3837 /*------------------------------------------------------------------*/
3838 /*----------------------------*/
3839 /* comparison operators */
3840 /*----------------------------*/
3848 ast *lt = optimizeCompare (tree);
3854 /* if they are pointers they must be castable */
3855 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3857 if (tree->opval.op==EQ_OP &&
3858 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3859 // we cannot cast a gptr to a !gptr: switch the leaves
3860 struct ast *s=tree->left;
3861 tree->left=tree->right;
3864 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3866 werror (E_COMPARE_OP);
3867 fprintf (stderr, "comparing type ");
3868 printTypeChain (LTYPE (tree), stderr);
3869 fprintf (stderr, "to type ");
3870 printTypeChain (RTYPE (tree), stderr);
3871 fprintf (stderr, "\n");
3872 goto errorTreeReturn;
3875 /* else they should be promotable to one another */
3878 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3879 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3881 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3883 werror (E_COMPARE_OP);
3884 fprintf (stderr, "comparing type ");
3885 printTypeChain (LTYPE (tree), stderr);
3886 fprintf (stderr, "to type ");
3887 printTypeChain (RTYPE (tree), stderr);
3888 fprintf (stderr, "\n");
3889 goto errorTreeReturn;
3892 /* if unsigned value < 0 then always false */
3893 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3894 if (SPEC_USIGN(LETYPE(tree)) &&
3895 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3896 IS_LITERAL(RTYPE(tree)) &&
3897 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3899 if (tree->opval.op == '<')
3903 if (tree->opval.op == '>')
3905 if (resultType == RESULT_TYPE_IFX)
3907 /* the parent is an ifx: */
3908 /* if (unsigned value) */
3912 /* (unsigned value) ? 1 : 0 */
3913 tree->opval.op = '?';
3914 tree->right = newNode (':',
3915 newAst_VALUE (constVal ("1")),
3916 tree->right); /* val 0 */
3917 tree->right->lineno = tree->lineno;
3918 tree->right->left->lineno = tree->lineno;
3919 decorateType (tree->right, RESULT_TYPE_NONE);
3922 /* if they are both literal then */
3923 /* rewrite the tree */
3924 if (IS_LITERAL (RTYPE (tree)) &&
3925 IS_LITERAL (LTYPE (tree)))
3927 tree->type = EX_VALUE;
3928 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3929 valFromType (RETYPE (tree)),
3931 tree->right = tree->left = NULL;
3932 TETYPE (tree) = getSpec (TTYPE (tree) =
3933 tree->opval.val->type);
3936 LRVAL (tree) = RRVAL (tree) = 1;
3937 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3940 /*------------------------------------------------------------------*/
3941 /*----------------------------*/
3943 /*----------------------------*/
3944 case SIZEOF: /* evaluate wihout code generation */
3945 /* change the type to a integer */
3947 int size = getSize (tree->right->ftype);
3948 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3949 if (!size && !IS_VOID(tree->right->ftype))
3950 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3952 tree->type = EX_VALUE;
3953 tree->opval.val = constVal (buffer);
3954 tree->right = tree->left = NULL;
3955 TETYPE (tree) = getSpec (TTYPE (tree) =
3956 tree->opval.val->type);
3959 /*------------------------------------------------------------------*/
3960 /*----------------------------*/
3962 /*----------------------------*/
3964 /* return typeof enum value */
3965 tree->type = EX_VALUE;
3968 if (IS_SPEC(tree->right->ftype)) {
3969 switch (SPEC_NOUN(tree->right->ftype)) {
3971 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3972 else typeofv = TYPEOF_INT;
3975 typeofv = TYPEOF_FLOAT;
3978 typeofv = TYPEOF_FIXED16X16;
3981 typeofv = TYPEOF_CHAR;
3984 typeofv = TYPEOF_VOID;
3987 typeofv = TYPEOF_STRUCT;
3990 typeofv = TYPEOF_BITFIELD;
3993 typeofv = TYPEOF_BIT;
3996 typeofv = TYPEOF_SBIT;
4002 switch (DCL_TYPE(tree->right->ftype)) {
4004 typeofv = TYPEOF_POINTER;
4007 typeofv = TYPEOF_FPOINTER;
4010 typeofv = TYPEOF_CPOINTER;
4013 typeofv = TYPEOF_GPOINTER;
4016 typeofv = TYPEOF_PPOINTER;
4019 typeofv = TYPEOF_IPOINTER;
4022 typeofv = TYPEOF_ARRAY;
4025 typeofv = TYPEOF_FUNCTION;
4031 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4032 tree->opval.val = constVal (buffer);
4033 tree->right = tree->left = NULL;
4034 TETYPE (tree) = getSpec (TTYPE (tree) =
4035 tree->opval.val->type);
4038 /*------------------------------------------------------------------*/
4039 /*----------------------------*/
4040 /* conditional operator '?' */
4041 /*----------------------------*/
4043 /* the type is value of the colon operator (on the right) */
4044 assert (IS_COLON_OP (tree->right));
4045 /* if already known then replace the tree : optimizer will do it
4046 but faster to do it here */
4047 if (IS_LITERAL (LTYPE (tree)))
4049 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4050 return decorateType (tree->right->left, resultTypeProp);
4052 return decorateType (tree->right->right, resultTypeProp);
4056 tree->right = decorateType (tree->right, resultTypeProp);
4057 TTYPE (tree) = RTYPE (tree);
4058 TETYPE (tree) = getSpec (TTYPE (tree));
4063 /* if they don't match we have a problem */
4064 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4065 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4067 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4068 goto errorTreeReturn;
4071 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4072 resultType, tree->opval.op);
4073 TETYPE (tree) = getSpec (TTYPE (tree));
4077 #if 0 // assignment operators are converted by the parser
4078 /*------------------------------------------------------------------*/
4079 /*----------------------------*/
4080 /* assignment operators */
4081 /*----------------------------*/
4084 /* for these it must be both must be integral */
4085 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4086 !IS_ARITHMETIC (RTYPE (tree)))
4088 werror (E_OPS_INTEGRAL);
4089 goto errorTreeReturn;
4092 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4094 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4095 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4099 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4100 goto errorTreeReturn;
4111 /* for these it must be both must be integral */
4112 if (!IS_INTEGRAL (LTYPE (tree)) ||
4113 !IS_INTEGRAL (RTYPE (tree)))
4115 werror (E_OPS_INTEGRAL);
4116 goto errorTreeReturn;
4119 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4121 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4122 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4126 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4127 goto errorTreeReturn;
4133 /*------------------------------------------------------------------*/
4134 /*----------------------------*/
4136 /*----------------------------*/
4138 if (!(IS_PTR (LTYPE (tree)) ||
4139 IS_ARITHMETIC (LTYPE (tree))))
4141 werror (E_PLUS_INVALID, "-=");
4142 goto errorTreeReturn;
4145 if (!(IS_PTR (RTYPE (tree)) ||
4146 IS_ARITHMETIC (RTYPE (tree))))
4148 werror (E_PLUS_INVALID, "-=");
4149 goto errorTreeReturn;
4152 TETYPE (tree) = getSpec (TTYPE (tree) =
4153 computeType (LTYPE (tree),
4158 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4159 werror (E_CODE_WRITE, "-=");
4163 werror (E_LVALUE_REQUIRED, "-=");
4164 goto errorTreeReturn;
4170 /*------------------------------------------------------------------*/
4171 /*----------------------------*/
4173 /*----------------------------*/
4175 /* this is not a unary operation */
4176 /* if both pointers then problem */
4177 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4179 werror (E_PTR_PLUS_PTR);
4180 goto errorTreeReturn;
4183 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4185 werror (E_PLUS_INVALID, "+=");
4186 goto errorTreeReturn;
4189 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4191 werror (E_PLUS_INVALID, "+=");
4192 goto errorTreeReturn;
4195 TETYPE (tree) = getSpec (TTYPE (tree) =
4196 computeType (LTYPE (tree),
4201 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4202 werror (E_CODE_WRITE, "+=");
4206 werror (E_LVALUE_REQUIRED, "+=");
4207 goto errorTreeReturn;
4210 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4211 tree->opval.op = '=';
4216 /*------------------------------------------------------------------*/
4217 /*----------------------------*/
4218 /* straight assignemnt */
4219 /*----------------------------*/
4221 /* cannot be an aggregate */
4222 if (IS_AGGREGATE (LTYPE (tree)))
4224 werror (E_AGGR_ASSIGN);
4225 goto errorTreeReturn;
4228 /* they should either match or be castable */
4229 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4231 werror (E_TYPE_MISMATCH, "assignment", " ");
4232 printFromToType(RTYPE(tree),LTYPE(tree));
4235 /* if the left side of the tree is of type void
4236 then report error */
4237 if (IS_VOID (LTYPE (tree)))
4239 werror (E_CAST_ZERO);
4240 printFromToType(RTYPE(tree), LTYPE(tree));
4243 TETYPE (tree) = getSpec (TTYPE (tree) =
4247 if (!tree->initMode ) {
4248 if (IS_CONSTANT(LTYPE(tree)))
4249 werror (E_CODE_WRITE, "=");
4253 werror (E_LVALUE_REQUIRED, "=");
4254 goto errorTreeReturn;
4259 /*------------------------------------------------------------------*/
4260 /*----------------------------*/
4261 /* comma operator */
4262 /*----------------------------*/
4264 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4267 /*------------------------------------------------------------------*/
4268 /*----------------------------*/
4270 /*----------------------------*/
4273 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4274 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4276 if (tree->left->opval.op == '*' && !tree->left->right)
4277 tree->left = tree->left->left;
4280 /* require a function or pointer to function */
4281 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4283 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4284 goto errorTreeReturn;
4287 /* if there are parms, make sure that
4288 parms are decorate / process / reverse only once */
4290 !tree->right->decorated)
4295 if (IS_FUNCPTR (LTYPE (tree)))
4296 functype = LTYPE (tree)->next;
4298 functype = LTYPE (tree);
4300 if (processParms (tree->left, FUNC_ARGS(functype),
4301 &tree->right, &parmNumber, TRUE))
4303 goto errorTreeReturn;
4306 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4307 !IFFUNC_ISBUILTIN(functype))
4309 reverseParms (tree->right);
4312 TTYPE (tree) = functype->next;
4313 TETYPE (tree) = getSpec (TTYPE (tree));
4317 /*------------------------------------------------------------------*/
4318 /*----------------------------*/
4319 /* return statement */
4320 /*----------------------------*/
4325 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4327 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4328 printFromToType (RTYPE(tree), currFunc->type->next);
4329 goto errorTreeReturn;
4332 if (IS_VOID (currFunc->type->next)
4334 !IS_VOID (RTYPE (tree)))
4336 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4337 goto errorTreeReturn;
4340 /* if there is going to be a casting required then add it */
4341 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4344 decorateType (newNode (CAST,
4345 newAst_LINK (copyLinkChain (currFunc->type->next)),
4355 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4357 werror (W_VOID_FUNC, currFunc->name);
4358 goto errorTreeReturn;
4361 TTYPE (tree) = TETYPE (tree) = NULL;
4364 /*------------------------------------------------------------------*/
4365 /*----------------------------*/
4366 /* switch statement */
4367 /*----------------------------*/
4369 /* the switch value must be an integer */
4370 if (!IS_INTEGRAL (LTYPE (tree)))
4372 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4373 goto errorTreeReturn;
4376 TTYPE (tree) = TETYPE (tree) = NULL;
4379 /*------------------------------------------------------------------*/
4380 /*----------------------------*/
4382 /*----------------------------*/
4384 tree->left = backPatchLabels (tree->left,
4387 TTYPE (tree) = TETYPE (tree) = NULL;
4390 /*------------------------------------------------------------------*/
4391 /*----------------------------*/
4393 /*----------------------------*/
4396 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4397 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4398 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4400 /* if the for loop is reversible then
4401 reverse it otherwise do what we normally
4407 if (isLoopReversible (tree, &sym, &init, &end))
4408 return reverseLoop (tree, sym, init, end);
4410 return decorateType (createFor (AST_FOR (tree, trueLabel),
4411 AST_FOR (tree, continueLabel),
4412 AST_FOR (tree, falseLabel),
4413 AST_FOR (tree, condLabel),
4414 AST_FOR (tree, initExpr),
4415 AST_FOR (tree, condExpr),
4416 AST_FOR (tree, loopExpr),
4417 tree->left), RESULT_TYPE_NONE);
4420 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4421 "node PARAM shouldn't be processed here");
4422 /* but in processParams() */
4425 TTYPE (tree) = TETYPE (tree) = NULL;
4429 /* some error found this tree will be killed */
4431 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4432 tree->opval.op = NULLOP;
4438 /*-----------------------------------------------------------------*/
4439 /* sizeofOp - processes size of operation */
4440 /*-----------------------------------------------------------------*/
4442 sizeofOp (sym_link * type)
4447 /* make sure the type is complete and sane */
4448 checkTypeSanity(type, "(sizeof)");
4450 /* get the size and convert it to character */
4451 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4452 if (!size && !IS_VOID(type))
4453 werror (E_SIZEOF_INCOMPLETE_TYPE);
4455 /* now convert into value */
4456 return constVal (buff);
4460 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4461 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4462 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4463 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4464 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4465 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4466 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4468 /*-----------------------------------------------------------------*/
4469 /* backPatchLabels - change and or not operators to flow control */
4470 /*-----------------------------------------------------------------*/
4472 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4478 if (!(IS_ANDORNOT (tree)))
4481 /* if this an and */
4484 static int localLbl = 0;
4487 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4488 localLabel = newSymbol (buffer, NestLevel);
4490 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4492 /* if left is already a IFX then just change the if true label in that */
4493 if (!IS_IFX (tree->left))
4494 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4496 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4497 /* right is a IFX then just join */
4498 if (IS_IFX (tree->right))
4499 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4501 tree->right = createLabel (localLabel, tree->right);
4502 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4504 return newNode (NULLOP, tree->left, tree->right);
4507 /* if this is an or operation */
4510 static int localLbl = 0;
4513 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4514 localLabel = newSymbol (buffer, NestLevel);
4516 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4518 /* if left is already a IFX then just change the if true label in that */
4519 if (!IS_IFX (tree->left))
4520 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4522 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4523 /* right is a IFX then just join */
4524 if (IS_IFX (tree->right))
4525 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4527 tree->right = createLabel (localLabel, tree->right);
4528 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4530 return newNode (NULLOP, tree->left, tree->right);
4536 int wasnot = IS_NOT (tree->left);
4537 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4539 /* if the left is already a IFX */
4540 if (!IS_IFX (tree->left))
4541 tree->left = newNode (IFX, tree->left, NULL);
4545 tree->left->trueLabel = trueLabel;
4546 tree->left->falseLabel = falseLabel;
4550 tree->left->trueLabel = falseLabel;
4551 tree->left->falseLabel = trueLabel;
4558 tree->trueLabel = trueLabel;
4559 tree->falseLabel = falseLabel;
4566 /*-----------------------------------------------------------------*/
4567 /* createBlock - create expression tree for block */
4568 /*-----------------------------------------------------------------*/
4570 createBlock (symbol * decl, ast * body)
4574 /* if the block has nothing */
4578 ex = newNode (BLOCK, NULL, body);
4579 ex->values.sym = decl;
4586 /*-----------------------------------------------------------------*/
4587 /* createLabel - creates the expression tree for labels */
4588 /*-----------------------------------------------------------------*/
4590 createLabel (symbol * label, ast * stmnt)
4593 char name[SDCC_NAME_MAX + 1];
4596 /* must create fresh symbol if the symbol name */
4597 /* exists in the symbol table, since there can */
4598 /* be a variable with the same name as the labl */
4599 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4600 (csym->level == label->level))
4601 label = newSymbol (label->name, label->level);
4603 /* change the name before putting it in add _ */
4604 SNPRINTF(name, sizeof(name), "%s", label->name);
4606 /* put the label in the LabelSymbol table */
4607 /* but first check if a label of the same */
4609 if ((csym = findSym (LabelTab, NULL, name)))
4610 werror (E_DUPLICATE_LABEL, label->name);
4612 addSym (LabelTab, label, name, label->level, 0, 0);
4616 label->key = labelKey++;
4617 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4623 /*-----------------------------------------------------------------*/
4624 /* createCase - generates the parsetree for a case statement */
4625 /*-----------------------------------------------------------------*/
4627 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4629 char caseLbl[SDCC_NAME_MAX + 1];
4633 /* if the switch statement does not exist */
4634 /* then case is out of context */
4637 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4641 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4642 /* if not a constant then error */
4643 if (!IS_LITERAL (caseVal->ftype))
4645 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4649 /* if not a integer than error */
4650 if (!IS_INTEGRAL (caseVal->ftype))
4652 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4656 /* find the end of the switch values chain */
4657 if (!(val = swStat->values.switchVals.swVals))
4658 swStat->values.switchVals.swVals = caseVal->opval.val;
4661 /* also order the cases according to value */
4663 int cVal = (int) floatFromVal (caseVal->opval.val);
4664 while (val && (int) floatFromVal (val) < cVal)
4670 /* if we reached the end then */
4673 pval->next = caseVal->opval.val;
4675 else if ((int) floatFromVal (val) == cVal)
4677 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4683 /* we found a value greater than */
4684 /* the current value we must add this */
4685 /* before the value */
4686 caseVal->opval.val->next = val;
4688 /* if this was the first in chain */
4689 if (swStat->values.switchVals.swVals == val)
4690 swStat->values.switchVals.swVals =
4693 pval->next = caseVal->opval.val;
4698 /* create the case label */
4699 SNPRINTF(caseLbl, sizeof(caseLbl),
4701 swStat->values.switchVals.swNum,
4702 (int) floatFromVal (caseVal->opval.val));
4704 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4709 /*-----------------------------------------------------------------*/
4710 /* createDefault - creates the parse tree for the default statement */
4711 /*-----------------------------------------------------------------*/
4713 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4715 char defLbl[SDCC_NAME_MAX + 1];
4717 /* if the switch statement does not exist */
4718 /* then case is out of context */
4721 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4725 if (swStat->values.switchVals.swDefault)
4727 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4732 /* turn on the default flag */
4733 swStat->values.switchVals.swDefault = 1;
4735 /* create the label */
4736 SNPRINTF (defLbl, sizeof(defLbl),
4737 "_default_%d", swStat->values.switchVals.swNum);
4738 return createLabel (newSymbol (defLbl, 0), stmnt);
4741 /*-----------------------------------------------------------------*/
4742 /* createIf - creates the parsetree for the if statement */
4743 /*-----------------------------------------------------------------*/
4745 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4747 static int Lblnum = 0;
4749 symbol *ifTrue, *ifFalse, *ifEnd;
4751 /* if neither exists */
4752 if (!elseBody && !ifBody) {
4753 // if there are no side effects (i++, j() etc)
4754 if (!hasSEFcalls(condAst)) {
4759 /* create the labels */
4760 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4761 ifFalse = newSymbol (buffer, NestLevel);
4762 /* if no else body then end == false */
4767 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4768 ifEnd = newSymbol (buffer, NestLevel);
4771 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4772 ifTrue = newSymbol (buffer, NestLevel);
4776 /* attach the ifTrue label to the top of it body */
4777 ifBody = createLabel (ifTrue, ifBody);
4778 /* attach a goto end to the ifBody if else is present */
4781 ifBody = newNode (NULLOP, ifBody,
4783 newAst_VALUE (symbolVal (ifEnd)),
4785 /* put the elseLabel on the else body */
4786 elseBody = createLabel (ifFalse, elseBody);
4787 /* out the end at the end of the body */
4788 elseBody = newNode (NULLOP,
4790 createLabel (ifEnd, NULL));
4794 ifBody = newNode (NULLOP, ifBody,
4795 createLabel (ifFalse, NULL));
4797 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4798 if (IS_IFX (condAst))
4801 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4803 return newNode (NULLOP, ifTree,
4804 newNode (NULLOP, ifBody, elseBody));
4808 /*-----------------------------------------------------------------*/
4809 /* createDo - creates parse tree for do */
4812 /* _docontinue_n: */
4813 /* condition_expression +-> trueLabel -> _dobody_n */
4815 /* +-> falseLabel-> _dobreak_n */
4817 /*-----------------------------------------------------------------*/
4819 createDo (symbol * trueLabel, symbol * continueLabel,
4820 symbol * falseLabel, ast * condAst, ast * doBody)
4825 /* if the body does not exist then it is simple */
4828 condAst = backPatchLabels (condAst, continueLabel, NULL);
4829 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4830 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4831 doTree->trueLabel = continueLabel;
4832 doTree->falseLabel = NULL;
4836 /* otherwise we have a body */
4837 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4839 /* attach the body label to the top */
4840 doBody = createLabel (trueLabel, doBody);
4841 /* attach the continue label to end of body */
4842 doBody = newNode (NULLOP, doBody,
4843 createLabel (continueLabel, NULL));
4845 /* now put the break label at the end */
4846 if (IS_IFX (condAst))
4849 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4851 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4853 /* putting it together */
4854 return newNode (NULLOP, doBody, doTree);
4857 /*-----------------------------------------------------------------*/
4858 /* createFor - creates parse tree for 'for' statement */
4861 /* condExpr +-> trueLabel -> _forbody_n */
4863 /* +-> falseLabel-> _forbreak_n */
4866 /* _forcontinue_n: */
4868 /* goto _forcond_n ; */
4870 /*-----------------------------------------------------------------*/
4872 createFor (symbol * trueLabel, symbol * continueLabel,
4873 symbol * falseLabel, symbol * condLabel,
4874 ast * initExpr, ast * condExpr, ast * loopExpr,
4879 /* if loopexpression not present then we can generate it */
4880 /* the same way as a while */
4882 return newNode (NULLOP, initExpr,
4883 createWhile (trueLabel, continueLabel,
4884 falseLabel, condExpr, forBody));
4885 /* vanilla for statement */
4886 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4888 if (condExpr && !IS_IFX (condExpr))
4889 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4892 /* attach condition label to condition */
4893 condExpr = createLabel (condLabel, condExpr);
4895 /* attach body label to body */
4896 forBody = createLabel (trueLabel, forBody);
4898 /* attach continue to forLoop expression & attach */
4899 /* goto the forcond @ and of loopExpression */
4900 loopExpr = createLabel (continueLabel,
4904 newAst_VALUE (symbolVal (condLabel)),
4906 /* now start putting them together */
4907 forTree = newNode (NULLOP, initExpr, condExpr);
4908 forTree = newNode (NULLOP, forTree, forBody);
4909 forTree = newNode (NULLOP, forTree, loopExpr);
4910 /* finally add the break label */
4911 forTree = newNode (NULLOP, forTree,
4912 createLabel (falseLabel, NULL));
4916 /*-----------------------------------------------------------------*/
4917 /* createWhile - creates parse tree for while statement */
4918 /* the while statement will be created as follows */
4920 /* _while_continue_n: */
4921 /* condition_expression +-> trueLabel -> _while_boby_n */
4923 /* +-> falseLabel -> _while_break_n */
4924 /* _while_body_n: */
4926 /* goto _while_continue_n */
4927 /* _while_break_n: */
4928 /*-----------------------------------------------------------------*/
4930 createWhile (symbol * trueLabel, symbol * continueLabel,
4931 symbol * falseLabel, ast * condExpr, ast * whileBody)
4935 /* put the continue label */
4936 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4937 condExpr = createLabel (continueLabel, condExpr);
4938 condExpr->lineno = 0;
4940 /* put the body label in front of the body */
4941 whileBody = createLabel (trueLabel, whileBody);
4942 whileBody->lineno = 0;
4943 /* put a jump to continue at the end of the body */
4944 /* and put break label at the end of the body */
4945 whileBody = newNode (NULLOP,
4948 newAst_VALUE (symbolVal (continueLabel)),
4949 createLabel (falseLabel, NULL)));
4951 /* put it all together */
4952 if (IS_IFX (condExpr))
4953 whileTree = condExpr;
4956 whileTree = newNode (IFX, condExpr, NULL);
4957 /* put the true & false labels in place */
4958 whileTree->trueLabel = trueLabel;
4959 whileTree->falseLabel = falseLabel;
4962 return newNode (NULLOP, whileTree, whileBody);
4965 /*-----------------------------------------------------------------*/
4966 /* isShiftRightLitVal _BitAndLitVal - helper function */
4967 /*-----------------------------------------------------------------*/
4969 isShiftRightLitVal_BitAndLitVal (ast * tree)
4971 /* if this is not a bit and */
4972 if (!IS_BITAND (tree))
4975 /* will look for tree of the form
4976 ( expr >> litval2) & litval1 */
4977 if (!IS_AST_LIT_VALUE (tree->right))
4980 if (!IS_RIGHT_OP (tree->left))
4983 if (!IS_AST_LIT_VALUE (tree->left->right))
4986 return tree->left->left;
4989 /*-----------------------------------------------------------------*/
4990 /* isBitAndPowOf2 - helper function */
4991 /*-----------------------------------------------------------------*/
4993 isBitAndPow2 (ast * tree)
4995 /* if this is not a bit and */
4996 if (!IS_BITAND (tree))
4999 /* will look for tree of the form
5000 ( expr & (1 << litval) */
5001 if (!IS_AST_LIT_VALUE (tree->right))
5004 return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5007 /*-----------------------------------------------------------------*/
5008 /* optimizeGetHbit - get highest order bit of the expression */
5009 /*-----------------------------------------------------------------*/
5011 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5016 expr = isShiftRightLitVal_BitAndLitVal(tree);
5019 if ((AST_LIT_VALUE (tree->right) != 1) ||
5020 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5021 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5024 if (!expr && (resultType == RESULT_TYPE_BIT))
5027 if (isBitAndPow2 (tree) != getSize (TTYPE (expr)) * 8 - 1)
5033 /* make sure the port supports GETHBIT */
5034 if (port->hasExtBitOp
5035 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5038 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5041 /*-----------------------------------------------------------------*/
5042 /* optimizeGetAbit - get a single bit of the expression */
5043 /*-----------------------------------------------------------------*/
5045 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5050 expr = isShiftRightLitVal_BitAndLitVal(tree);
5053 if (AST_LIT_VALUE (tree->right) != 1)
5055 count = tree->left->right;
5057 if (!expr && (resultType == RESULT_TYPE_BIT))
5059 int p2 = isBitAndPow2 (tree);
5063 count = newAst_VALUE (valueFromLit (p2));
5069 /* make sure the port supports GETABIT */
5070 if (port->hasExtBitOp
5071 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5074 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5078 /*-----------------------------------------------------------------*/
5079 /* optimizeGetByte - get a byte of the expression */
5080 /*-----------------------------------------------------------------*/
5082 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5088 expr = isShiftRightLitVal_BitAndLitVal(tree);
5091 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5092 count = tree->left->right;
5093 if (AST_LIT_VALUE (tree->right) != 0xFF)
5096 if (!expr && resultType == RESULT_TYPE_CHAR)
5098 /* if this is a right shift over a multiple of 8 */
5099 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5101 i = (unsigned int) AST_LIT_VALUE (tree->right);
5102 count = tree->right;
5106 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5109 /* make sure the port supports GETBYTE */
5110 if (port->hasExtBitOp
5111 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5114 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5117 /*-----------------------------------------------------------------*/
5118 /* optimizeGetWord - get two bytes of the expression */
5119 /*-----------------------------------------------------------------*/
5121 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5127 expr = isShiftRightLitVal_BitAndLitVal(tree);
5130 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5131 count = tree->left->right;
5132 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5135 if (!expr && resultType == RESULT_TYPE_INT)
5137 /* if this is a right shift over a multiple of 8 */
5138 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5140 i = (unsigned int) AST_LIT_VALUE (tree->right);
5141 count = tree->right;
5145 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5148 /* make sure the port supports GETWORD */
5149 if (port->hasExtBitOp
5150 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5153 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5156 /*-----------------------------------------------------------------*/
5157 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5158 /*-----------------------------------------------------------------*/
5160 optimizeRRCRLC (ast * root)
5162 /* will look for trees of the form
5163 (?expr << 1) | (?expr >> 7) or
5164 (?expr >> 7) | (?expr << 1) will make that
5165 into a RLC : operation ..
5167 (?expr >> 1) | (?expr << 7) or
5168 (?expr << 7) | (?expr >> 1) will make that
5169 into a RRC operation
5170 note : by 7 I mean (number of bits required to hold the
5172 /* if the root operations is not a | operation the not */
5173 if (!IS_BITOR (root))
5176 /* I have to think of a better way to match patterns this sucks */
5177 /* that aside let start looking for the first case : I use a the
5178 negative check a lot to improve the efficiency */
5179 /* (?expr << 1) | (?expr >> 7) */
5180 if (IS_LEFT_OP (root->left) &&
5181 IS_RIGHT_OP (root->right))
5184 if (!SPEC_USIGN (TETYPE (root->left->left)))
5187 if (!IS_AST_LIT_VALUE (root->left->right) ||
5188 !IS_AST_LIT_VALUE (root->right->right))
5191 /* make sure it is the same expression */
5192 if (!isAstEqual (root->left->left,
5196 if (AST_LIT_VALUE (root->left->right) != 1)
5199 if (AST_LIT_VALUE (root->right->right) !=
5200 (getSize (TTYPE (root->left->left)) * 8 - 1))
5203 /* make sure the port supports RLC */
5204 if (port->hasExtBitOp
5205 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5208 /* whew got the first case : create the AST */
5209 return newNode (RLC, root->left->left, NULL);
5213 /* check for second case */
5214 /* (?expr >> 7) | (?expr << 1) */
5215 if (IS_LEFT_OP (root->right) &&
5216 IS_RIGHT_OP (root->left))
5219 if (!SPEC_USIGN (TETYPE (root->left->left)))
5222 if (!IS_AST_LIT_VALUE (root->left->right) ||
5223 !IS_AST_LIT_VALUE (root->right->right))
5226 /* make sure it is the same symbol */
5227 if (!isAstEqual (root->left->left,
5231 if (AST_LIT_VALUE (root->right->right) != 1)
5234 if (AST_LIT_VALUE (root->left->right) !=
5235 (getSize (TTYPE (root->left->left)) * 8 - 1))
5238 /* make sure the port supports RLC */
5239 if (port->hasExtBitOp
5240 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5243 /* whew got the first case : create the AST */
5244 return newNode (RLC, root->left->left, NULL);
5249 /* third case for RRC */
5250 /* (?symbol >> 1) | (?symbol << 7) */
5251 if (IS_LEFT_OP (root->right) &&
5252 IS_RIGHT_OP (root->left))
5255 if (!SPEC_USIGN (TETYPE (root->left->left)))
5258 if (!IS_AST_LIT_VALUE (root->left->right) ||
5259 !IS_AST_LIT_VALUE (root->right->right))
5262 /* make sure it is the same symbol */
5263 if (!isAstEqual (root->left->left,
5267 if (AST_LIT_VALUE (root->left->right) != 1)
5270 if (AST_LIT_VALUE (root->right->right) !=
5271 (getSize (TTYPE (root->left->left)) * 8 - 1))
5274 /* make sure the port supports RRC */
5275 if (port->hasExtBitOp
5276 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5279 /* whew got the first case : create the AST */
5280 return newNode (RRC, root->left->left, NULL);
5284 /* fourth and last case for now */
5285 /* (?symbol << 7) | (?symbol >> 1) */
5286 if (IS_RIGHT_OP (root->right) &&
5287 IS_LEFT_OP (root->left))
5290 if (!SPEC_USIGN (TETYPE (root->left->left)))
5293 if (!IS_AST_LIT_VALUE (root->left->right) ||
5294 !IS_AST_LIT_VALUE (root->right->right))
5297 /* make sure it is the same symbol */
5298 if (!isAstEqual (root->left->left,
5302 if (AST_LIT_VALUE (root->right->right) != 1)
5305 if (AST_LIT_VALUE (root->left->right) !=
5306 (getSize (TTYPE (root->left->left)) * 8 - 1))
5309 /* make sure the port supports RRC */
5310 if (port->hasExtBitOp
5311 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5314 /* whew got the first case : create the AST */
5315 return newNode (RRC, root->left->left, NULL);
5319 /* not found return root */
5323 /*-----------------------------------------------------------------*/
5324 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5325 /*-----------------------------------------------------------------*/
5327 optimizeSWAP (ast * root)
5329 /* will look for trees of the form
5330 (?expr << 4) | (?expr >> 4) or
5331 (?expr >> 4) | (?expr << 4) will make that
5332 into a SWAP : operation ..
5333 note : by 4 I mean (number of bits required to hold the
5335 /* if the root operations is not a | operation the not */
5336 if (!IS_BITOR (root))
5339 /* (?expr << 4) | (?expr >> 4) */
5340 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5341 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5344 if (!SPEC_USIGN (TETYPE (root->left->left)))
5347 if (!IS_AST_LIT_VALUE (root->left->right) ||
5348 !IS_AST_LIT_VALUE (root->right->right))
5351 /* make sure it is the same expression */
5352 if (!isAstEqual (root->left->left,
5356 if (AST_LIT_VALUE (root->left->right) !=
5357 (getSize (TTYPE (root->left->left)) * 4))
5360 if (AST_LIT_VALUE (root->right->right) !=
5361 (getSize (TTYPE (root->left->left)) * 4))
5364 /* make sure the port supports SWAP */
5365 if (port->hasExtBitOp
5366 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5369 /* found it : create the AST */
5370 return newNode (SWAP, root->left->left, NULL);
5374 /* not found return root */
5378 /*-----------------------------------------------------------------*/
5379 /* optimizeCompare - optimizes compares for bit variables */
5380 /*-----------------------------------------------------------------*/
5382 optimizeCompare (ast * root)
5384 ast *optExpr = NULL;
5387 unsigned int litValue;
5389 /* if nothing then return nothing */
5393 /* if not a compare op then do leaves */
5394 if (!IS_COMPARE_OP (root))
5396 root->left = optimizeCompare (root->left);
5397 root->right = optimizeCompare (root->right);
5401 /* if left & right are the same then depending
5402 of the operation do */
5403 if (isAstEqual (root->left, root->right))
5405 switch (root->opval.op)
5410 optExpr = newAst_VALUE (constVal ("0"));
5415 optExpr = newAst_VALUE (constVal ("1"));
5419 return decorateType (optExpr, RESULT_TYPE_NONE);
5422 vleft = (root->left->type == EX_VALUE ?
5423 root->left->opval.val : NULL);
5425 vright = (root->right->type == EX_VALUE ?
5426 root->right->opval.val : NULL);
5428 /* if left is a BITVAR in BITSPACE */
5429 /* and right is a LITERAL then opt- */
5430 /* imize else do nothing */
5431 if (vleft && vright &&
5432 IS_BITVAR (vleft->etype) &&
5433 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5434 IS_LITERAL (vright->etype))
5437 /* if right side > 1 then comparison may never succeed */
5438 if ((litValue = (int) floatFromVal (vright)) > 1)
5440 werror (W_BAD_COMPARE);
5446 switch (root->opval.op)
5448 case '>': /* bit value greater than 1 cannot be */
5449 werror (W_BAD_COMPARE);
5453 case '<': /* bit value < 1 means 0 */
5455 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5458 case LE_OP: /* bit value <= 1 means no check */
5459 optExpr = newAst_VALUE (vright);
5462 case GE_OP: /* bit value >= 1 means only check for = */
5464 optExpr = newAst_VALUE (vleft);
5469 { /* literal is zero */
5470 switch (root->opval.op)
5472 case '<': /* bit value < 0 cannot be */
5473 werror (W_BAD_COMPARE);
5477 case '>': /* bit value > 0 means 1 */
5479 optExpr = newAst_VALUE (vleft);
5482 case LE_OP: /* bit value <= 0 means no check */
5483 case GE_OP: /* bit value >= 0 means no check */
5484 werror (W_BAD_COMPARE);
5488 case EQ_OP: /* bit == 0 means ! of bit */
5489 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5493 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5494 } /* end-of-if of BITVAR */
5499 /*-----------------------------------------------------------------*/
5500 /* addSymToBlock : adds the symbol to the first block we find */
5501 /*-----------------------------------------------------------------*/
5503 addSymToBlock (symbol * sym, ast * tree)
5505 /* reached end of tree or a leaf */
5506 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5510 if (IS_AST_OP (tree) &&
5511 tree->opval.op == BLOCK)
5514 symbol *lsym = copySymbol (sym);
5516 lsym->next = AST_VALUES (tree, sym);
5517 AST_VALUES (tree, sym) = lsym;
5521 addSymToBlock (sym, tree->left);
5522 addSymToBlock (sym, tree->right);
5525 /*-----------------------------------------------------------------*/
5526 /* processRegParms - do processing for register parameters */
5527 /*-----------------------------------------------------------------*/
5529 processRegParms (value * args, ast * body)
5533 if (IS_REGPARM (args->etype))
5534 addSymToBlock (args->sym, body);
5539 /*-----------------------------------------------------------------*/
5540 /* resetParmKey - resets the operandkeys for the symbols */
5541 /*-----------------------------------------------------------------*/
5542 DEFSETFUNC (resetParmKey)
5553 /*-----------------------------------------------------------------*/
5554 /* createFunction - This is the key node that calls the iCode for */
5555 /* generating the code for a function. Note code */
5556 /* is generated function by function, later when */
5557 /* add inter-procedural analysis this will change */
5558 /*-----------------------------------------------------------------*/
5560 createFunction (symbol * name, ast * body)
5566 iCode *piCode = NULL;
5568 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5569 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5571 /* if check function return 0 then some problem */
5572 if (checkFunction (name, NULL) == 0)
5575 /* create a dummy block if none exists */
5577 body = newNode (BLOCK, NULL, NULL);
5581 /* check if the function name already in the symbol table */
5582 if ((csym = findSym (SymbolTab, NULL, name->name)))
5585 /* special case for compiler defined functions
5586 we need to add the name to the publics list : this
5587 actually means we are now compiling the compiler
5591 addSet (&publics, name);
5596 addSymChain (&name);
5597 allocVariables (name);
5599 name->lastLine = mylineno;
5602 /* set the stack pointer */
5603 stackPtr = -port->stack.direction * port->stack.call_overhead;
5606 if (IFFUNC_ISISR (name->type))
5607 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5609 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5611 if (options.useXstack)
5612 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5614 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5617 fetype = getSpec (name->type); /* get the specifier for the function */
5618 /* if this is a reentrant function then */
5619 if (IFFUNC_ISREENT (name->type))
5622 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5624 /* do processing for parameters that are passed in registers */
5625 processRegParms (FUNC_ARGS(name->type), body);
5627 /* set the stack pointer */
5631 /* allocate & autoinit the block variables */
5632 processBlockVars (body, &stack, ALLOCATE);
5634 /* save the stack information */
5635 if (options.useXstack)
5636 name->xstack = SPEC_STAK (fetype) = stack;
5638 name->stack = SPEC_STAK (fetype) = stack;
5640 /* name needs to be mangled */
5641 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5643 body = resolveSymbols (body); /* resolve the symbols */
5644 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5647 ex = newAst_VALUE (symbolVal (name)); /* create name */
5648 ex = newNode (FUNCTION, ex, body);
5649 ex->values.args = FUNC_ARGS(name->type);
5651 if (options.dump_tree) PA(ex);
5654 werror (E_FUNC_NO_CODE, name->name);
5658 /* create the node & generate intermediate code */
5660 codeOutFile = code->oFile;
5661 piCode = iCodeFromAst (ex);
5665 werror (E_FUNC_NO_CODE, name->name);
5669 eBBlockFromiCode (piCode);
5671 /* if there are any statics then do them */
5674 GcurMemmap = statsg;
5675 codeOutFile = statsg->oFile;
5676 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5682 /* dealloc the block variables */
5683 processBlockVars (body, &stack, DEALLOCATE);
5684 outputDebugStackSymbols();
5685 /* deallocate paramaters */
5686 deallocParms (FUNC_ARGS(name->type));
5688 if (IFFUNC_ISREENT (name->type))
5691 /* we are done freeup memory & cleanup */
5693 if (port->reset_labelKey) labelKey = 1;
5695 FUNC_HASBODY(name->type) = 1;
5696 addSet (&operKeyReset, name);
5697 applyToSet (operKeyReset, resetParmKey);
5702 cleanUpLevel (LabelTab, 0);
5703 cleanUpBlock (StructTab, 1);
5704 cleanUpBlock (TypedefTab, 1);
5706 xstack->syms = NULL;
5707 istack->syms = NULL;
5712 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5713 /*-----------------------------------------------------------------*/
5714 /* ast_print : prints the ast (for debugging purposes) */
5715 /*-----------------------------------------------------------------*/
5717 void ast_print (ast * tree, FILE *outfile, int indent)
5722 /* can print only decorated trees */
5723 if (!tree->decorated) return;
5725 /* if any child is an error | this one is an error do nothing */
5726 if (tree->isError ||
5727 (tree->left && tree->left->isError) ||
5728 (tree->right && tree->right->isError)) {
5729 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5733 /* print the line */
5734 /* if not block & function */
5735 if (tree->type == EX_OP &&
5736 (tree->opval.op != FUNCTION &&
5737 tree->opval.op != BLOCK &&
5738 tree->opval.op != NULLOP)) {
5741 if (tree->opval.op == FUNCTION) {
5743 value *args=FUNC_ARGS(tree->left->opval.val->type);
5744 fprintf(outfile,"FUNCTION (%s=%p) type (",
5745 tree->left->opval.val->name, tree);
5746 printTypeChain (tree->left->opval.val->type->next,outfile);
5747 fprintf(outfile,") args (");
5750 fprintf (outfile, ", ");
5752 printTypeChain (args ? args->type : NULL, outfile);
5754 args= args ? args->next : NULL;
5756 fprintf(outfile,")\n");
5757 ast_print(tree->left,outfile,indent);
5758 ast_print(tree->right,outfile,indent);
5761 if (tree->opval.op == BLOCK) {
5762 symbol *decls = tree->values.sym;
5763 INDENT(indent,outfile);
5764 fprintf(outfile,"{\n");
5766 INDENT(indent+2,outfile);
5767 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5768 decls->name, decls);
5769 printTypeChain(decls->type,outfile);
5770 fprintf(outfile,")\n");
5772 decls = decls->next;
5774 ast_print(tree->right,outfile,indent+2);
5775 INDENT(indent,outfile);
5776 fprintf(outfile,"}\n");
5779 if (tree->opval.op == NULLOP) {
5780 ast_print(tree->left,outfile,indent);
5781 ast_print(tree->right,outfile,indent);
5784 INDENT(indent,outfile);
5786 /*------------------------------------------------------------------*/
5787 /*----------------------------*/
5788 /* leaf has been reached */
5789 /*----------------------------*/
5790 /* if this is of type value */
5791 /* just get the type */
5792 if (tree->type == EX_VALUE) {
5794 if (IS_LITERAL (tree->opval.val->etype)) {
5795 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5796 if (SPEC_USIGN (tree->opval.val->etype))
5797 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5799 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5800 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5801 floatFromVal(tree->opval.val));
5802 } else if (tree->opval.val->sym) {
5803 /* if the undefined flag is set then give error message */
5804 if (tree->opval.val->sym->undefined) {
5805 fprintf(outfile,"UNDEFINED SYMBOL ");
5807 fprintf(outfile,"SYMBOL ");
5809 fprintf(outfile,"(%s=%p)",
5810 tree->opval.val->sym->name,tree);
5813 fprintf(outfile," type (");
5814 printTypeChain(tree->ftype,outfile);
5815 fprintf(outfile,")\n");
5817 fprintf(outfile,"\n");
5822 /* if type link for the case of cast */
5823 if (tree->type == EX_LINK) {
5824 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5825 printTypeChain(tree->opval.lnk,outfile);
5826 fprintf(outfile,")\n");
5831 /* depending on type of operator do */
5833 switch (tree->opval.op) {
5834 /*------------------------------------------------------------------*/
5835 /*----------------------------*/
5837 /*----------------------------*/
5839 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5840 printTypeChain(tree->ftype,outfile);
5841 fprintf(outfile,")\n");
5842 ast_print(tree->left,outfile,indent+2);
5843 ast_print(tree->right,outfile,indent+2);
5846 /*------------------------------------------------------------------*/
5847 /*----------------------------*/
5849 /*----------------------------*/
5851 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5852 printTypeChain(tree->ftype,outfile);
5853 fprintf(outfile,")\n");
5854 ast_print(tree->left,outfile,indent+2);
5855 ast_print(tree->right,outfile,indent+2);
5858 /*------------------------------------------------------------------*/
5859 /*----------------------------*/
5860 /* struct/union pointer */
5861 /*----------------------------*/
5863 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5864 printTypeChain(tree->ftype,outfile);
5865 fprintf(outfile,")\n");
5866 ast_print(tree->left,outfile,indent+2);
5867 ast_print(tree->right,outfile,indent+2);
5870 /*------------------------------------------------------------------*/
5871 /*----------------------------*/
5872 /* ++/-- operation */
5873 /*----------------------------*/
5876 fprintf(outfile,"post-");
5878 fprintf(outfile,"pre-");
5879 fprintf(outfile,"INC_OP (%p) type (",tree);
5880 printTypeChain(tree->ftype,outfile);
5881 fprintf(outfile,")\n");
5882 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5883 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5888 fprintf(outfile,"post-");
5890 fprintf(outfile,"pre-");
5891 fprintf(outfile,"DEC_OP (%p) type (",tree);
5892 printTypeChain(tree->ftype,outfile);
5893 fprintf(outfile,")\n");
5894 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5895 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5898 /*------------------------------------------------------------------*/
5899 /*----------------------------*/
5901 /*----------------------------*/
5904 fprintf(outfile,"& (%p) type (",tree);
5905 printTypeChain(tree->ftype,outfile);
5906 fprintf(outfile,")\n");
5907 ast_print(tree->left,outfile,indent+2);
5908 ast_print(tree->right,outfile,indent+2);
5910 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5911 printTypeChain(tree->ftype,outfile);
5912 fprintf(outfile,")\n");
5913 ast_print(tree->left,outfile,indent+2);
5914 ast_print(tree->right,outfile,indent+2);
5917 /*----------------------------*/
5919 /*----------------------------*/
5921 fprintf(outfile,"OR (%p) type (",tree);
5922 printTypeChain(tree->ftype,outfile);
5923 fprintf(outfile,")\n");
5924 ast_print(tree->left,outfile,indent+2);
5925 ast_print(tree->right,outfile,indent+2);
5927 /*------------------------------------------------------------------*/
5928 /*----------------------------*/
5930 /*----------------------------*/
5932 fprintf(outfile,"XOR (%p) type (",tree);
5933 printTypeChain(tree->ftype,outfile);
5934 fprintf(outfile,")\n");
5935 ast_print(tree->left,outfile,indent+2);
5936 ast_print(tree->right,outfile,indent+2);
5939 /*------------------------------------------------------------------*/
5940 /*----------------------------*/
5942 /*----------------------------*/
5944 fprintf(outfile,"DIV (%p) type (",tree);
5945 printTypeChain(tree->ftype,outfile);
5946 fprintf(outfile,")\n");
5947 ast_print(tree->left,outfile,indent+2);
5948 ast_print(tree->right,outfile,indent+2);
5950 /*------------------------------------------------------------------*/
5951 /*----------------------------*/
5953 /*----------------------------*/
5955 fprintf(outfile,"MOD (%p) type (",tree);
5956 printTypeChain(tree->ftype,outfile);
5957 fprintf(outfile,")\n");
5958 ast_print(tree->left,outfile,indent+2);
5959 ast_print(tree->right,outfile,indent+2);
5962 /*------------------------------------------------------------------*/
5963 /*----------------------------*/
5964 /* address dereference */
5965 /*----------------------------*/
5966 case '*': /* can be unary : if right is null then unary operation */
5968 fprintf(outfile,"DEREF (%p) type (",tree);
5969 printTypeChain(tree->ftype,outfile);
5970 fprintf(outfile,")\n");
5971 ast_print(tree->left,outfile,indent+2);
5974 /*------------------------------------------------------------------*/
5975 /*----------------------------*/
5976 /* multiplication */
5977 /*----------------------------*/
5978 fprintf(outfile,"MULT (%p) type (",tree);
5979 printTypeChain(tree->ftype,outfile);
5980 fprintf(outfile,")\n");
5981 ast_print(tree->left,outfile,indent+2);
5982 ast_print(tree->right,outfile,indent+2);
5986 /*------------------------------------------------------------------*/
5987 /*----------------------------*/
5988 /* unary '+' operator */
5989 /*----------------------------*/
5993 fprintf(outfile,"UPLUS (%p) type (",tree);
5994 printTypeChain(tree->ftype,outfile);
5995 fprintf(outfile,")\n");
5996 ast_print(tree->left,outfile,indent+2);
5998 /*------------------------------------------------------------------*/
5999 /*----------------------------*/
6001 /*----------------------------*/
6002 fprintf(outfile,"ADD (%p) type (",tree);
6003 printTypeChain(tree->ftype,outfile);
6004 fprintf(outfile,")\n");
6005 ast_print(tree->left,outfile,indent+2);
6006 ast_print(tree->right,outfile,indent+2);
6009 /*------------------------------------------------------------------*/
6010 /*----------------------------*/
6012 /*----------------------------*/
6013 case '-': /* can be unary */
6015 fprintf(outfile,"UMINUS (%p) type (",tree);
6016 printTypeChain(tree->ftype,outfile);
6017 fprintf(outfile,")\n");
6018 ast_print(tree->left,outfile,indent+2);
6020 /*------------------------------------------------------------------*/
6021 /*----------------------------*/
6023 /*----------------------------*/
6024 fprintf(outfile,"SUB (%p) type (",tree);
6025 printTypeChain(tree->ftype,outfile);
6026 fprintf(outfile,")\n");
6027 ast_print(tree->left,outfile,indent+2);
6028 ast_print(tree->right,outfile,indent+2);
6031 /*------------------------------------------------------------------*/
6032 /*----------------------------*/
6034 /*----------------------------*/
6036 fprintf(outfile,"COMPL (%p) type (",tree);
6037 printTypeChain(tree->ftype,outfile);
6038 fprintf(outfile,")\n");
6039 ast_print(tree->left,outfile,indent+2);
6041 /*------------------------------------------------------------------*/
6042 /*----------------------------*/
6044 /*----------------------------*/
6046 fprintf(outfile,"NOT (%p) type (",tree);
6047 printTypeChain(tree->ftype,outfile);
6048 fprintf(outfile,")\n");
6049 ast_print(tree->left,outfile,indent+2);
6051 /*------------------------------------------------------------------*/
6052 /*----------------------------*/
6054 /*----------------------------*/
6056 fprintf(outfile,"RRC (%p) type (",tree);
6057 printTypeChain(tree->ftype,outfile);
6058 fprintf(outfile,")\n");
6059 ast_print(tree->left,outfile,indent+2);
6063 fprintf(outfile,"RLC (%p) type (",tree);
6064 printTypeChain(tree->ftype,outfile);
6065 fprintf(outfile,")\n");
6066 ast_print(tree->left,outfile,indent+2);
6069 fprintf(outfile,"SWAP (%p) type (",tree);
6070 printTypeChain(tree->ftype,outfile);
6071 fprintf(outfile,")\n");
6072 ast_print(tree->left,outfile,indent+2);
6075 fprintf(outfile,"GETHBIT (%p) type (",tree);
6076 printTypeChain(tree->ftype,outfile);
6077 fprintf(outfile,")\n");
6078 ast_print(tree->left,outfile,indent+2);
6081 fprintf(outfile,"GETABIT (%p) type (",tree);
6082 printTypeChain(tree->ftype,outfile);
6083 fprintf(outfile,")\n");
6084 ast_print(tree->left,outfile,indent+2);
6085 ast_print(tree->right,outfile,indent+2);
6088 fprintf(outfile,"GETBYTE (%p) type (",tree);
6089 printTypeChain(tree->ftype,outfile);
6090 fprintf(outfile,")\n");
6091 ast_print(tree->left,outfile,indent+2);
6092 ast_print(tree->right,outfile,indent+2);
6095 fprintf(outfile,"GETWORD (%p) type (",tree);
6096 printTypeChain(tree->ftype,outfile);
6097 fprintf(outfile,")\n");
6098 ast_print(tree->left,outfile,indent+2);
6099 ast_print(tree->right,outfile,indent+2);
6102 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6103 printTypeChain(tree->ftype,outfile);
6104 fprintf(outfile,")\n");
6105 ast_print(tree->left,outfile,indent+2);
6106 ast_print(tree->right,outfile,indent+2);
6109 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6110 printTypeChain(tree->ftype,outfile);
6111 fprintf(outfile,")\n");
6112 ast_print(tree->left,outfile,indent+2);
6113 ast_print(tree->right,outfile,indent+2);
6115 /*------------------------------------------------------------------*/
6116 /*----------------------------*/
6118 /*----------------------------*/
6119 case CAST: /* change the type */
6120 fprintf(outfile,"CAST (%p) from type (",tree);
6121 printTypeChain(tree->right->ftype,outfile);
6122 fprintf(outfile,") to type (");
6123 printTypeChain(tree->ftype,outfile);
6124 fprintf(outfile,")\n");
6125 ast_print(tree->right,outfile,indent+2);
6129 fprintf(outfile,"ANDAND (%p) type (",tree);
6130 printTypeChain(tree->ftype,outfile);
6131 fprintf(outfile,")\n");
6132 ast_print(tree->left,outfile,indent+2);
6133 ast_print(tree->right,outfile,indent+2);
6136 fprintf(outfile,"OROR (%p) type (",tree);
6137 printTypeChain(tree->ftype,outfile);
6138 fprintf(outfile,")\n");
6139 ast_print(tree->left,outfile,indent+2);
6140 ast_print(tree->right,outfile,indent+2);
6143 /*------------------------------------------------------------------*/
6144 /*----------------------------*/
6145 /* comparison operators */
6146 /*----------------------------*/
6148 fprintf(outfile,"GT(>) (%p) type (",tree);
6149 printTypeChain(tree->ftype,outfile);
6150 fprintf(outfile,")\n");
6151 ast_print(tree->left,outfile,indent+2);
6152 ast_print(tree->right,outfile,indent+2);
6155 fprintf(outfile,"LT(<) (%p) type (",tree);
6156 printTypeChain(tree->ftype,outfile);
6157 fprintf(outfile,")\n");
6158 ast_print(tree->left,outfile,indent+2);
6159 ast_print(tree->right,outfile,indent+2);
6162 fprintf(outfile,"LE(<=) (%p) type (",tree);
6163 printTypeChain(tree->ftype,outfile);
6164 fprintf(outfile,")\n");
6165 ast_print(tree->left,outfile,indent+2);
6166 ast_print(tree->right,outfile,indent+2);
6169 fprintf(outfile,"GE(>=) (%p) type (",tree);
6170 printTypeChain(tree->ftype,outfile);
6171 fprintf(outfile,")\n");
6172 ast_print(tree->left,outfile,indent+2);
6173 ast_print(tree->right,outfile,indent+2);
6176 fprintf(outfile,"EQ(==) (%p) type (",tree);
6177 printTypeChain(tree->ftype,outfile);
6178 fprintf(outfile,")\n");
6179 ast_print(tree->left,outfile,indent+2);
6180 ast_print(tree->right,outfile,indent+2);
6183 fprintf(outfile,"NE(!=) (%p) type (",tree);
6184 printTypeChain(tree->ftype,outfile);
6185 fprintf(outfile,")\n");
6186 ast_print(tree->left,outfile,indent+2);
6187 ast_print(tree->right,outfile,indent+2);
6188 /*------------------------------------------------------------------*/
6189 /*----------------------------*/
6191 /*----------------------------*/
6192 case SIZEOF: /* evaluate wihout code generation */
6193 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6196 /*------------------------------------------------------------------*/
6197 /*----------------------------*/
6198 /* conditional operator '?' */
6199 /*----------------------------*/
6201 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6202 printTypeChain(tree->ftype,outfile);
6203 fprintf(outfile,")\n");
6204 ast_print(tree->left,outfile,indent+2);
6205 ast_print(tree->right,outfile,indent+2);
6209 fprintf(outfile,"COLON(:) (%p) type (",tree);
6210 printTypeChain(tree->ftype,outfile);
6211 fprintf(outfile,")\n");
6212 ast_print(tree->left,outfile,indent+2);
6213 ast_print(tree->right,outfile,indent+2);
6216 /*------------------------------------------------------------------*/
6217 /*----------------------------*/
6218 /* assignment operators */
6219 /*----------------------------*/
6221 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6222 printTypeChain(tree->ftype,outfile);
6223 fprintf(outfile,")\n");
6224 ast_print(tree->left,outfile,indent+2);
6225 ast_print(tree->right,outfile,indent+2);
6228 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6229 printTypeChain(tree->ftype,outfile);
6230 fprintf(outfile,")\n");
6231 ast_print(tree->left,outfile,indent+2);
6232 ast_print(tree->right,outfile,indent+2);
6235 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6236 printTypeChain(tree->ftype,outfile);
6237 fprintf(outfile,")\n");
6238 ast_print(tree->left,outfile,indent+2);
6239 ast_print(tree->right,outfile,indent+2);
6242 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6243 printTypeChain(tree->ftype,outfile);
6244 fprintf(outfile,")\n");
6245 ast_print(tree->left,outfile,indent+2);
6246 ast_print(tree->right,outfile,indent+2);
6249 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6250 printTypeChain(tree->ftype,outfile);
6251 fprintf(outfile,")\n");
6252 ast_print(tree->left,outfile,indent+2);
6253 ast_print(tree->right,outfile,indent+2);
6256 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6257 printTypeChain(tree->ftype,outfile);
6258 fprintf(outfile,")\n");
6259 ast_print(tree->left,outfile,indent+2);
6260 ast_print(tree->right,outfile,indent+2);
6263 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6264 printTypeChain(tree->ftype,outfile);
6265 fprintf(outfile,")\n");
6266 ast_print(tree->left,outfile,indent+2);
6267 ast_print(tree->right,outfile,indent+2);
6269 /*------------------------------------------------------------------*/
6270 /*----------------------------*/
6272 /*----------------------------*/
6274 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6275 printTypeChain(tree->ftype,outfile);
6276 fprintf(outfile,")\n");
6277 ast_print(tree->left,outfile,indent+2);
6278 ast_print(tree->right,outfile,indent+2);
6280 /*------------------------------------------------------------------*/
6281 /*----------------------------*/
6283 /*----------------------------*/
6285 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6286 printTypeChain(tree->ftype,outfile);
6287 fprintf(outfile,")\n");
6288 ast_print(tree->left,outfile,indent+2);
6289 ast_print(tree->right,outfile,indent+2);
6291 /*------------------------------------------------------------------*/
6292 /*----------------------------*/
6293 /* straight assignemnt */
6294 /*----------------------------*/
6296 fprintf(outfile,"ASSIGN(=) (%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);
6302 /*------------------------------------------------------------------*/
6303 /*----------------------------*/
6304 /* comma operator */
6305 /*----------------------------*/
6307 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6308 printTypeChain(tree->ftype,outfile);
6309 fprintf(outfile,")\n");
6310 ast_print(tree->left,outfile,indent+2);
6311 ast_print(tree->right,outfile,indent+2);
6313 /*------------------------------------------------------------------*/
6314 /*----------------------------*/
6316 /*----------------------------*/
6319 fprintf(outfile,"CALL (%p) type (",tree);
6320 printTypeChain(tree->ftype,outfile);
6321 fprintf(outfile,")\n");
6322 ast_print(tree->left,outfile,indent+2);
6323 ast_print(tree->right,outfile,indent+2);
6326 fprintf(outfile,"PARMS\n");
6327 ast_print(tree->left,outfile,indent+2);
6328 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6329 ast_print(tree->right,outfile,indent+2);
6332 /*------------------------------------------------------------------*/
6333 /*----------------------------*/
6334 /* return statement */
6335 /*----------------------------*/
6337 fprintf(outfile,"RETURN (%p) type (",tree);
6339 printTypeChain(tree->right->ftype,outfile);
6341 fprintf(outfile,")\n");
6342 ast_print(tree->right,outfile,indent+2);
6344 /*------------------------------------------------------------------*/
6345 /*----------------------------*/
6346 /* label statement */
6347 /*----------------------------*/
6349 fprintf(outfile,"LABEL (%p)\n",tree);
6350 ast_print(tree->left,outfile,indent+2);
6351 ast_print(tree->right,outfile,indent);
6353 /*------------------------------------------------------------------*/
6354 /*----------------------------*/
6355 /* switch statement */
6356 /*----------------------------*/
6360 fprintf(outfile,"SWITCH (%p) ",tree);
6361 ast_print(tree->left,outfile,0);
6362 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6363 INDENT(indent+2,outfile);
6364 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6365 (int) floatFromVal(val),
6366 tree->values.switchVals.swNum,
6367 (int) floatFromVal(val));
6369 ast_print(tree->right,outfile,indent);
6372 /*------------------------------------------------------------------*/
6373 /*----------------------------*/
6375 /*----------------------------*/
6377 fprintf(outfile,"IF (%p) \n",tree);
6378 ast_print(tree->left,outfile,indent+2);
6379 if (tree->trueLabel) {
6380 INDENT(indent+2,outfile);
6381 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6383 if (tree->falseLabel) {
6384 INDENT(indent+2,outfile);
6385 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6387 ast_print(tree->right,outfile,indent+2);
6389 /*----------------------------*/
6390 /* goto Statement */
6391 /*----------------------------*/
6393 fprintf(outfile,"GOTO (%p) \n",tree);
6394 ast_print(tree->left,outfile,indent+2);
6395 fprintf(outfile,"\n");
6397 /*------------------------------------------------------------------*/
6398 /*----------------------------*/
6400 /*----------------------------*/
6402 fprintf(outfile,"FOR (%p) \n",tree);
6403 if (AST_FOR( tree, initExpr)) {
6404 INDENT(indent+2,outfile);
6405 fprintf(outfile,"INIT EXPR ");
6406 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6408 if (AST_FOR( tree, condExpr)) {
6409 INDENT(indent+2,outfile);
6410 fprintf(outfile,"COND EXPR ");
6411 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6413 if (AST_FOR( tree, loopExpr)) {
6414 INDENT(indent+2,outfile);
6415 fprintf(outfile,"LOOP EXPR ");
6416 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6418 fprintf(outfile,"FOR LOOP BODY \n");
6419 ast_print(tree->left,outfile,indent+2);
6422 fprintf(outfile,"CRITICAL (%p) \n",tree);
6423 ast_print(tree->left,outfile,indent+2);
6431 ast_print(t,stdout,0);
6436 /*-----------------------------------------------------------------*/
6437 /* astErrors : returns non-zero if errors present in tree */
6438 /*-----------------------------------------------------------------*/
6439 int astErrors(ast *t)
6448 if (t->type == EX_VALUE
6449 && t->opval.val->sym
6450 && t->opval.val->sym->undefined)
6453 errors += astErrors(t->left);
6454 errors += astErrors(t->right);