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))
1033 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1034 "string", sym->opval.val->sym->name);
1038 for (i=0;i<size;i++)
1040 rast = newNode (NULLOP,
1044 newAst_VALUE (valueFromLit ((float) i))),
1045 newAst_VALUE (valueFromLit (*s))));
1049 // now WE don't need iexpr's symbol anymore
1050 freeStringSymbol(AST_SYMBOL(iexpr));
1052 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1058 /*-----------------------------------------------------------------*/
1059 /* createIvalPtr - generates initial value for pointers */
1060 /*-----------------------------------------------------------------*/
1062 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1068 if (ilist->type == INIT_DEEP)
1069 ilist = ilist->init.deep;
1071 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1073 /* if character pointer */
1074 if (IS_CHAR (type->next))
1075 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1078 return newNode ('=', sym, iexpr);
1081 /*-----------------------------------------------------------------*/
1082 /* createIval - generates code for initial value */
1083 /*-----------------------------------------------------------------*/
1085 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1092 /* if structure then */
1093 if (IS_STRUCT (type))
1094 rast = createIvalStruct (sym, type, ilist);
1096 /* if this is a pointer */
1098 rast = createIvalPtr (sym, type, ilist);
1100 /* if this is an array */
1101 if (IS_ARRAY (type))
1102 rast = createIvalArray (sym, type, ilist);
1104 /* if type is SPECIFIER */
1106 rast = createIvalType (sym, type, ilist);
1109 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1111 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1114 /*-----------------------------------------------------------------*/
1115 /* initAggregates - initialises aggregate variables with initv */
1116 /*-----------------------------------------------------------------*/
1117 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1118 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1121 /*-----------------------------------------------------------------*/
1122 /* gatherAutoInit - creates assignment expressions for initial */
1124 /*-----------------------------------------------------------------*/
1126 gatherAutoInit (symbol * autoChain)
1133 for (sym = autoChain; sym; sym = sym->next)
1136 /* resolve the symbols in the ival */
1138 resolveIvalSym (sym->ival, sym->type);
1141 /* if we are PIC16 port,
1142 * and this is a static,
1143 * and have initial value,
1144 * and not S_CODE, don't emit in gs segment,
1145 * but allow glue.c:pic16emitRegularMap to put symbol
1146 * in idata section */
1147 if(TARGET_IS_PIC16 &&
1148 IS_STATIC (sym->etype) && sym->ival
1149 && SPEC_SCLS(sym->etype) != S_CODE) {
1150 SPEC_SCLS (sym->etype) = S_DATA;
1155 /* if this is a static variable & has an */
1156 /* initial value the code needs to be lifted */
1157 /* here to the main portion since they can be */
1158 /* initialised only once at the start */
1159 if (IS_STATIC (sym->etype) && sym->ival &&
1160 SPEC_SCLS (sym->etype) != S_CODE)
1164 /* insert the symbol into the symbol table */
1165 /* with level = 0 & name = rname */
1166 newSym = copySymbol (sym);
1167 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1169 /* now lift the code to main */
1170 if (IS_AGGREGATE (sym->type)) {
1171 work = initAggregates (sym, sym->ival, NULL);
1173 if (getNelements(sym->type, sym->ival)>1) {
1174 werrorfl (sym->fileDef, sym->lineDef,
1175 W_EXCESS_INITIALIZERS, "scalar",
1178 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1179 list2expr (sym->ival));
1182 setAstLineno (work, sym->lineDef);
1186 staticAutos = newNode (NULLOP, staticAutos, work);
1193 /* if there is an initial value */
1194 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1196 initList *ilist=sym->ival;
1198 while (ilist->type == INIT_DEEP) {
1199 ilist = ilist->init.deep;
1202 /* update lineno for error msg */
1203 lineno=sym->lineDef;
1204 setAstLineno (ilist->init.node, lineno);
1206 if (IS_AGGREGATE (sym->type)) {
1207 work = initAggregates (sym, sym->ival, NULL);
1209 if (getNelements(sym->type, sym->ival)>1) {
1210 werrorfl (sym->fileDef, sym->lineDef,
1211 W_EXCESS_INITIALIZERS, "scalar",
1214 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1215 list2expr (sym->ival));
1219 setAstLineno (work, sym->lineDef);
1223 init = newNode (NULLOP, init, work);
1232 /*-----------------------------------------------------------------*/
1233 /* freeStringSymbol - delete a literal string if no more usage */
1234 /*-----------------------------------------------------------------*/
1235 void freeStringSymbol(symbol *sym) {
1236 /* make sure this is a literal string */
1237 assert (sym->isstrlit);
1238 if (--sym->isstrlit == 0) { // lower the usage count
1239 memmap *segment=SPEC_OCLS(sym->etype);
1241 deleteSetItem(&segment->syms, sym);
1246 /*-----------------------------------------------------------------*/
1247 /* stringToSymbol - creates a symbol from a literal string */
1248 /*-----------------------------------------------------------------*/
1250 stringToSymbol (value * val)
1252 char name[SDCC_NAME_MAX + 1];
1253 static int charLbl = 0;
1258 // have we heard this before?
1259 for (sp=statsg->syms; sp; sp=sp->next) {
1261 size = getSize (sym->type);
1262 if (sym->isstrlit && size == getSize (val->type) &&
1263 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1264 // yes, this is old news. Don't publish it again.
1265 sym->isstrlit++; // but raise the usage count
1266 return symbolVal(sym);
1270 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1271 sym = newSymbol (name, 0); /* make it @ level 0 */
1272 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1274 /* copy the type from the value passed */
1275 sym->type = copyLinkChain (val->type);
1276 sym->etype = getSpec (sym->type);
1277 /* change to storage class & output class */
1278 SPEC_SCLS (sym->etype) = S_CODE;
1279 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1280 SPEC_STAT (sym->etype) = 1;
1281 /* make the level & block = 0 */
1282 sym->block = sym->level = 0;
1284 /* create an ival */
1285 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1290 allocVariables (sym);
1293 return symbolVal (sym);
1297 /*-----------------------------------------------------------------*/
1298 /* processBlockVars - will go thru the ast looking for block if */
1299 /* a block is found then will allocate the syms */
1300 /* will also gather the auto inits present */
1301 /*-----------------------------------------------------------------*/
1303 processBlockVars (ast * tree, int *stack, int action)
1308 /* if this is a block */
1309 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1313 if (action == ALLOCATE)
1315 *stack += allocVariables (tree->values.sym);
1316 autoInit = gatherAutoInit (tree->values.sym);
1318 /* if there are auto inits then do them */
1320 tree->left = newNode (NULLOP, autoInit, tree->left);
1322 else /* action is deallocate */
1323 deallocLocal (tree->values.sym);
1326 processBlockVars (tree->left, stack, action);
1327 processBlockVars (tree->right, stack, action);
1332 /*-------------------------------------------------------------*/
1333 /* constExprTree - returns TRUE if this tree is a constant */
1335 /*-------------------------------------------------------------*/
1336 bool constExprTree (ast *cexpr) {
1342 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1344 switch (cexpr->type)
1347 if (IS_AST_LIT_VALUE(cexpr)) {
1348 // this is a literal
1351 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1352 // a function's address will never change
1355 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1356 // an array's address will never change
1359 if (IS_AST_SYM_VALUE(cexpr) &&
1360 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1361 // a symbol in code space will never change
1362 // This is only for the 'char *s="hallo"' case and will have to leave
1363 //printf(" code space symbol");
1368 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1369 "unexpected link in expression tree\n");
1372 if (cexpr->opval.op==ARRAYINIT) {
1373 // this is a list of literals
1376 if (cexpr->opval.op=='=') {
1377 return constExprTree(cexpr->right);
1379 if (cexpr->opval.op==CAST) {
1380 // cast ignored, maybe we should throw a warning here?
1381 return constExprTree(cexpr->right);
1383 if (cexpr->opval.op=='&') {
1386 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1389 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1394 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1399 /*-----------------------------------------------------------------*/
1400 /* constExprValue - returns the value of a constant expression */
1401 /* or NULL if it is not a constant expression */
1402 /*-----------------------------------------------------------------*/
1404 constExprValue (ast * cexpr, int check)
1406 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1408 /* if this is not a constant then */
1409 if (!IS_LITERAL (cexpr->ftype))
1411 /* then check if this is a literal array
1413 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1414 SPEC_CVAL (cexpr->etype).v_char &&
1415 IS_ARRAY (cexpr->ftype))
1417 value *val = valFromType (cexpr->ftype);
1418 SPEC_SCLS (val->etype) = S_LITERAL;
1419 val->sym = cexpr->opval.val->sym;
1420 val->sym->type = copyLinkChain (cexpr->ftype);
1421 val->sym->etype = getSpec (val->sym->type);
1422 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1426 /* if we are casting a literal value then */
1427 if (IS_AST_OP (cexpr) &&
1428 cexpr->opval.op == CAST &&
1429 IS_LITERAL (cexpr->right->ftype))
1431 return valCastLiteral (cexpr->ftype,
1432 floatFromVal (cexpr->right->opval.val));
1435 if (IS_AST_VALUE (cexpr))
1437 return cexpr->opval.val;
1441 werror (E_CONST_EXPECTED, "found expression");
1446 /* return the value */
1447 return cexpr->opval.val;
1451 /*-----------------------------------------------------------------*/
1452 /* isLabelInAst - will return true if a given label is found */
1453 /*-----------------------------------------------------------------*/
1455 isLabelInAst (symbol * label, ast * tree)
1457 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1460 if (IS_AST_OP (tree) &&
1461 tree->opval.op == LABEL &&
1462 isSymbolEqual (AST_SYMBOL (tree->left), label))
1465 return isLabelInAst (label, tree->right) &&
1466 isLabelInAst (label, tree->left);
1470 /*-----------------------------------------------------------------*/
1471 /* isLoopCountable - return true if the loop count can be determi- */
1472 /* -ned at compile time . */
1473 /*-----------------------------------------------------------------*/
1475 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1476 symbol ** sym, ast ** init, ast ** end)
1479 /* the loop is considered countable if the following
1480 conditions are true :-
1482 a) initExpr :- <sym> = <const>
1483 b) condExpr :- <sym> < <const1>
1484 c) loopExpr :- <sym> ++
1487 /* first check the initExpr */
1488 if (IS_AST_OP (initExpr) &&
1489 initExpr->opval.op == '=' && /* is assignment */
1490 IS_AST_SYM_VALUE (initExpr->left))
1491 { /* left is a symbol */
1493 *sym = AST_SYMBOL (initExpr->left);
1494 *init = initExpr->right;
1499 /* for now the symbol has to be of
1501 if (!IS_INTEGRAL ((*sym)->type))
1504 /* now check condExpr */
1505 if (IS_AST_OP (condExpr))
1508 switch (condExpr->opval.op)
1511 if (IS_AST_SYM_VALUE (condExpr->left) &&
1512 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1513 IS_AST_LIT_VALUE (condExpr->right))
1515 *end = condExpr->right;
1521 if (IS_AST_OP (condExpr->left) &&
1522 condExpr->left->opval.op == '>' &&
1523 IS_AST_LIT_VALUE (condExpr->left->right) &&
1524 IS_AST_SYM_VALUE (condExpr->left->left) &&
1525 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1528 *end = newNode ('+', condExpr->left->right,
1529 newAst_VALUE (constVal ("1")));
1542 /* check loop expression is of the form <sym>++ */
1543 if (!IS_AST_OP (loopExpr))
1546 /* check if <sym> ++ */
1547 if (loopExpr->opval.op == INC_OP)
1553 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1554 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1561 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1562 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1570 if (loopExpr->opval.op == ADD_ASSIGN)
1573 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1574 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1575 IS_AST_LIT_VALUE (loopExpr->right) &&
1576 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1584 /*-----------------------------------------------------------------*/
1585 /* astHasVolatile - returns true if ast contains any volatile */
1586 /*-----------------------------------------------------------------*/
1588 astHasVolatile (ast * tree)
1593 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1596 if (IS_AST_OP (tree))
1597 return astHasVolatile (tree->left) ||
1598 astHasVolatile (tree->right);
1603 /*-----------------------------------------------------------------*/
1604 /* astHasPointer - return true if the ast contains any ptr variable */
1605 /*-----------------------------------------------------------------*/
1607 astHasPointer (ast * tree)
1612 if (IS_AST_LINK (tree))
1615 /* if we hit an array expression then check
1616 only the left side */
1617 if (IS_AST_OP (tree) && tree->opval.op == '[')
1618 return astHasPointer (tree->left);
1620 if (IS_AST_VALUE (tree))
1621 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1623 return astHasPointer (tree->left) ||
1624 astHasPointer (tree->right);
1628 /*-----------------------------------------------------------------*/
1629 /* astHasSymbol - return true if the ast has the given symbol */
1630 /*-----------------------------------------------------------------*/
1632 astHasSymbol (ast * tree, symbol * sym)
1634 if (!tree || IS_AST_LINK (tree))
1637 if (IS_AST_VALUE (tree))
1639 if (IS_AST_SYM_VALUE (tree))
1640 return isSymbolEqual (AST_SYMBOL (tree), sym);
1645 return astHasSymbol (tree->left, sym) ||
1646 astHasSymbol (tree->right, sym);
1649 /*-----------------------------------------------------------------*/
1650 /* astHasDeref - return true if the ast has an indirect access */
1651 /*-----------------------------------------------------------------*/
1653 astHasDeref (ast * tree)
1655 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1658 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1660 return astHasDeref (tree->left) || astHasDeref (tree->right);
1663 /*-----------------------------------------------------------------*/
1664 /* isConformingBody - the loop body has to conform to a set of rules */
1665 /* for the loop to be considered reversible read on for rules */
1666 /*-----------------------------------------------------------------*/
1668 isConformingBody (ast * pbody, symbol * sym, ast * body)
1671 /* we are going to do a pre-order traversal of the
1672 tree && check for the following conditions. (essentially
1673 a set of very shallow tests )
1674 a) the sym passed does not participate in
1675 any arithmetic operation
1676 b) There are no function calls
1677 c) all jumps are within the body
1678 d) address of loop control variable not taken
1679 e) if an assignment has a pointer on the
1680 left hand side make sure right does not have
1681 loop control variable */
1683 /* if we reach the end or a leaf then true */
1684 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1687 /* if anything else is "volatile" */
1688 if (IS_VOLATILE (TETYPE (pbody)))
1691 /* we will walk the body in a pre-order traversal for
1693 switch (pbody->opval.op)
1695 /*------------------------------------------------------------------*/
1697 // if the loopvar is used as an index
1698 /* array op is commutative -- must check both left & right */
1699 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1702 return isConformingBody (pbody->right, sym, body)
1703 && isConformingBody (pbody->left, sym, body);
1705 /*------------------------------------------------------------------*/
1710 /*------------------------------------------------------------------*/
1714 /* sure we are not sym is not modified */
1716 IS_AST_SYM_VALUE (pbody->left) &&
1717 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1721 IS_AST_SYM_VALUE (pbody->right) &&
1722 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1727 /*------------------------------------------------------------------*/
1729 case '*': /* can be unary : if right is null then unary operation */
1734 /* if right is NULL then unary operation */
1735 /*------------------------------------------------------------------*/
1736 /*----------------------------*/
1738 /*----------------------------*/
1741 if (IS_AST_SYM_VALUE (pbody->left) &&
1742 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1745 return isConformingBody (pbody->left, sym, body);
1749 if (astHasSymbol (pbody->left, sym) ||
1750 astHasSymbol (pbody->right, sym))
1755 /*------------------------------------------------------------------*/
1766 if (IS_AST_SYM_VALUE (pbody->left) &&
1767 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1770 if (IS_AST_SYM_VALUE (pbody->right) &&
1771 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1774 return isConformingBody (pbody->left, sym, body) &&
1775 isConformingBody (pbody->right, sym, body);
1783 if (IS_AST_SYM_VALUE (pbody->left) &&
1784 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1786 return isConformingBody (pbody->left, sym, body);
1788 /*------------------------------------------------------------------*/
1800 case SIZEOF: /* evaluate wihout code generation */
1802 if (IS_AST_SYM_VALUE (pbody->left) &&
1803 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1806 if (IS_AST_SYM_VALUE (pbody->right) &&
1807 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1810 return isConformingBody (pbody->left, sym, body) &&
1811 isConformingBody (pbody->right, sym, body);
1813 /*------------------------------------------------------------------*/
1816 /* if left has a pointer & right has loop
1817 control variable then we cannot */
1818 if (astHasPointer (pbody->left) &&
1819 astHasSymbol (pbody->right, sym))
1821 if (astHasVolatile (pbody->left))
1824 if (IS_AST_SYM_VALUE (pbody->left)) {
1825 // if the loopvar has an assignment
1826 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1828 // if the loopvar is used in another (maybe conditional) block
1829 if (astHasSymbol (pbody->right, sym) &&
1830 (pbody->level >= body->level)) {
1835 if (astHasVolatile (pbody->left))
1838 if (astHasDeref(pbody->right)) return FALSE;
1840 return isConformingBody (pbody->left, sym, body) &&
1841 isConformingBody (pbody->right, sym, body);
1852 assert ("Parser should not have generated this\n");
1854 /*------------------------------------------------------------------*/
1855 /*----------------------------*/
1856 /* comma operator */
1857 /*----------------------------*/
1859 return isConformingBody (pbody->left, sym, body) &&
1860 isConformingBody (pbody->right, sym, body);
1862 /*------------------------------------------------------------------*/
1863 /*----------------------------*/
1865 /*----------------------------*/
1867 /* if local & not passed as paramater then ok */
1868 if (sym->level && !astHasSymbol(pbody->right,sym))
1872 /*------------------------------------------------------------------*/
1873 /*----------------------------*/
1874 /* return statement */
1875 /*----------------------------*/
1880 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1885 if (astHasSymbol (pbody->left, sym))
1892 return isConformingBody (pbody->left, sym, body) &&
1893 isConformingBody (pbody->right, sym, body);
1899 /*-----------------------------------------------------------------*/
1900 /* isLoopReversible - takes a for loop as input && returns true */
1901 /* if the for loop is reversible. If yes will set the value of */
1902 /* the loop control var & init value & termination value */
1903 /*-----------------------------------------------------------------*/
1905 isLoopReversible (ast * loop, symbol ** loopCntrl,
1906 ast ** init, ast ** end)
1908 /* if option says don't do it then don't */
1909 if (optimize.noLoopReverse)
1911 /* there are several tests to determine this */
1913 /* for loop has to be of the form
1914 for ( <sym> = <const1> ;
1915 [<sym> < <const2>] ;
1916 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1918 if (!isLoopCountable (AST_FOR (loop, initExpr),
1919 AST_FOR (loop, condExpr),
1920 AST_FOR (loop, loopExpr),
1921 loopCntrl, init, end))
1924 /* now do some serious checking on the body of the loop
1927 return isConformingBody (loop->left, *loopCntrl, loop->left);
1931 /*-----------------------------------------------------------------*/
1932 /* replLoopSym - replace the loop sym by loop sym -1 */
1933 /*-----------------------------------------------------------------*/
1935 replLoopSym (ast * body, symbol * sym)
1938 if (!body || IS_AST_LINK (body))
1941 if (IS_AST_SYM_VALUE (body))
1944 if (isSymbolEqual (AST_SYMBOL (body), sym))
1948 body->opval.op = '-';
1949 body->left = newAst_VALUE (symbolVal (sym));
1950 body->right = newAst_VALUE (constVal ("1"));
1958 replLoopSym (body->left, sym);
1959 replLoopSym (body->right, sym);
1963 /*-----------------------------------------------------------------*/
1964 /* reverseLoop - do the actual loop reversal */
1965 /*-----------------------------------------------------------------*/
1967 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1971 /* create the following tree
1976 if (sym) goto for_continue ;
1979 /* put it together piece by piece */
1980 rloop = newNode (NULLOP,
1981 createIf (newAst_VALUE (symbolVal (sym)),
1983 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1986 newAst_VALUE (symbolVal (sym)),
1989 replLoopSym (loop->left, sym);
1990 setAstLineno (rloop, init->lineno);
1992 rloop = newNode (NULLOP,
1994 newAst_VALUE (symbolVal (sym)),
1995 newNode ('-', end, init)),
1996 createLabel (AST_FOR (loop, continueLabel),
2000 newNode (SUB_ASSIGN,
2001 newAst_VALUE (symbolVal (sym)),
2002 newAst_VALUE (constVal ("1"))),
2005 rloop->lineno=init->lineno;
2006 return decorateType (rloop, RESULT_TYPE_NONE);
2010 /*-----------------------------------------------------------------*/
2011 /* searchLitOp - search tree (*ops only) for an ast with literal */
2012 /*-----------------------------------------------------------------*/
2014 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2018 if (tree && optimize.global_cse)
2020 /* is there a literal operand? */
2022 IS_AST_OP(tree->right) &&
2023 tree->right->right &&
2024 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2026 if (IS_LITERAL (RTYPE (tree->right)) !=
2027 IS_LITERAL (LTYPE (tree->right)))
2029 tree->right->decorated = 0;
2030 tree->decorated = 0;
2034 ret = searchLitOp (tree->right, parent, ops);
2039 IS_AST_OP(tree->left) &&
2040 tree->left->right &&
2041 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2043 if (IS_LITERAL (RTYPE (tree->left)) !=
2044 IS_LITERAL (LTYPE (tree->left)))
2046 tree->left->decorated = 0;
2047 tree->decorated = 0;
2051 ret = searchLitOp (tree->left, parent, ops);
2059 /*-----------------------------------------------------------------*/
2060 /* getResultFromType */
2061 /*-----------------------------------------------------------------*/
2063 getResultTypeFromType (sym_link *type)
2065 /* type = getSpec (type); */
2067 return RESULT_TYPE_BIT;
2068 if (IS_BITFIELD (type))
2070 int blen = SPEC_BLEN (type);
2073 return RESULT_TYPE_BIT;
2075 return RESULT_TYPE_CHAR;
2076 return RESULT_TYPE_INT;
2079 return RESULT_TYPE_CHAR;
2082 return RESULT_TYPE_INT;
2083 return RESULT_TYPE_OTHER;
2086 /*-----------------------------------------------------------------*/
2087 /* addCast - adds casts to a type specified by RESULT_TYPE */
2088 /*-----------------------------------------------------------------*/
2090 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2093 bool upCasted = FALSE;
2097 case RESULT_TYPE_NONE:
2098 /* if thing smaller than int must be promoted to int */
2100 getSize (tree->etype) >= INTSIZE)
2101 /* promotion not necessary or already an int */
2103 /* char and bits: promote to int */
2104 newLink = newIntLink();
2107 case RESULT_TYPE_BIT:
2109 /* already an int */
2110 bitsForType (tree->etype) >= 16 ||
2111 /* bit to bit operation: don't promote, the code generators
2112 hopefully know everything about promotion rules */
2113 bitsForType (tree->etype) == 1)
2115 newLink = newIntLink();
2118 case RESULT_TYPE_CHAR:
2119 if (IS_CHAR (tree->etype) ||
2120 IS_FLOAT(tree->etype) ||
2121 IS_FIXED(tree->etype))
2123 newLink = newCharLink();
2125 case RESULT_TYPE_INT:
2127 if (getSize (tree->etype) > INTSIZE)
2129 /* warn ("Loosing significant digits"); */
2133 /* char: promote to int */
2135 getSize (tree->etype) >= INTSIZE)
2137 newLink = newIntLink();
2140 case RESULT_TYPE_OTHER:
2143 /* return type is long, float: promote char to int */
2144 if (getSize (tree->etype) >= INTSIZE)
2146 newLink = newIntLink();
2152 tree->decorated = 0;
2153 tree = newNode (CAST, newAst_LINK (newLink), tree);
2154 tree->lineno = tree->right->lineno;
2155 /* keep unsigned type during cast to smaller type,
2156 but not when promoting from char to int */
2158 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2159 return decorateType (tree, resultType);
2162 /*-----------------------------------------------------------------*/
2163 /* resultTypePropagate - decides if resultType can be propagated */
2164 /*-----------------------------------------------------------------*/
2166 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2168 switch (tree->opval.op)
2187 return RESULT_TYPE_NONE;
2191 return RESULT_TYPE_IFX;
2193 return RESULT_TYPE_NONE;
2197 /*-----------------------------------------------------------------*/
2198 /* getLeftResultType - gets type from left branch for propagation */
2199 /*-----------------------------------------------------------------*/
2201 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2203 switch (tree->opval.op)
2207 if (IS_PTR (LTYPE (tree)))
2208 return RESULT_TYPE_NONE;
2210 return getResultTypeFromType (LETYPE (tree));
2212 if (IS_PTR (currFunc->type->next))
2213 return RESULT_TYPE_NONE;
2215 return getResultTypeFromType (currFunc->type->next);
2217 if (!IS_ARRAY (LTYPE (tree)))
2219 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2220 return RESULT_TYPE_CHAR;
2227 /*--------------------------------------------------------------------*/
2228 /* decorateType - compute type for this tree, also does type checking.*/
2229 /* This is done bottom up, since type has to flow upwards. */
2230 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2231 /* result is a char and the operand(s) are int's. */
2232 /* It also does constant folding, and parameter checking. */
2233 /*--------------------------------------------------------------------*/
2235 decorateType (ast * tree, RESULT_TYPE resultType)
2239 RESULT_TYPE resultTypeProp;
2244 /* if already has type then do nothing */
2245 if (tree->decorated)
2248 tree->decorated = 1;
2251 /* print the line */
2252 /* if not block & function */
2253 if (tree->type == EX_OP &&
2254 (tree->opval.op != FUNCTION &&
2255 tree->opval.op != BLOCK &&
2256 tree->opval.op != NULLOP))
2258 filename = tree->filename;
2259 lineno = tree->lineno;
2263 /* if any child is an error | this one is an error do nothing */
2264 if (tree->isError ||
2265 (tree->left && tree->left->isError) ||
2266 (tree->right && tree->right->isError))
2269 /*------------------------------------------------------------------*/
2270 /*----------------------------*/
2271 /* leaf has been reached */
2272 /*----------------------------*/
2273 lineno=tree->lineno;
2274 /* if this is of type value */
2275 /* just get the type */
2276 if (tree->type == EX_VALUE)
2279 if (IS_LITERAL (tree->opval.val->etype))
2282 /* if this is a character array then declare it */
2283 if (IS_ARRAY (tree->opval.val->type))
2284 tree->opval.val = stringToSymbol (tree->opval.val);
2286 /* otherwise just copy the type information */
2287 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2291 if (tree->opval.val->sym)
2293 /* if the undefined flag is set then give error message */
2294 if (tree->opval.val->sym->undefined)
2296 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2298 TTYPE (tree) = TETYPE (tree) =
2299 tree->opval.val->type = tree->opval.val->sym->type =
2300 tree->opval.val->etype = tree->opval.val->sym->etype =
2301 copyLinkChain (INTTYPE);
2306 /* if impilicit i.e. struct/union member then no type */
2307 if (tree->opval.val->sym->implicit)
2308 TTYPE (tree) = TETYPE (tree) = NULL;
2313 /* else copy the type */
2314 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2316 /* and mark it as referenced */
2317 tree->opval.val->sym->isref = 1;
2325 /* if type link for the case of cast */
2326 if (tree->type == EX_LINK)
2328 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2336 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2338 if (tree->left && tree->left->type == EX_OPERAND
2339 && (tree->left->opval.op == INC_OP
2340 || tree->left->opval.op == DEC_OP)
2341 && tree->left->left)
2343 tree->left->right = tree->left->left;
2344 tree->left->left = NULL;
2346 if (tree->right && tree->right->type == EX_OPERAND
2347 && (tree->right->opval.op == INC_OP
2348 || tree->right->opval.op == DEC_OP)
2349 && tree->right->left)
2351 tree->right->right = tree->right->left;
2352 tree->right->left = NULL;
2357 /* Before decorating the left branch we've to decide in dependence
2358 upon tree->opval.op, if resultType can be propagated */
2359 resultTypeProp = resultTypePropagate (tree, resultType);
2361 if (tree->opval.op == '?')
2362 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2364 dtl = decorateType (tree->left, resultTypeProp);
2366 /* if an array node, we may need to swap branches */
2367 if (tree->opval.op == '[')
2369 /* determine which is the array & which the index */
2370 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2371 IS_INTEGRAL (LTYPE (tree)))
2373 ast *tempTree = tree->left;
2374 tree->left = tree->right;
2375 tree->right = tempTree;
2379 /* After decorating the left branch there's type information available
2380 in tree->left->?type. If the op is e.g. '=' we extract the type
2381 information from there and propagate it to the right branch. */
2382 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2384 switch (tree->opval.op)
2387 /* delay right side for '?' operator since conditional macro
2388 expansions might rely on this */
2392 /* decorate right side for CALL (parameter list) in processParms();
2393 there is resultType available */
2397 dtr = decorateType (tree->right, resultTypeProp);
2401 /* this is to take care of situations
2402 when the tree gets rewritten */
2403 if (dtl != tree->left)
2405 if (dtr != tree->right)
2407 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2411 /* depending on type of operator do */
2413 switch (tree->opval.op)
2415 /*------------------------------------------------------------------*/
2416 /*----------------------------*/
2418 /*----------------------------*/
2421 /* first check if this is a array or a pointer */
2422 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2424 werror (E_NEED_ARRAY_PTR, "[]");
2425 goto errorTreeReturn;
2428 /* check if the type of the idx */
2429 if (!IS_INTEGRAL (RTYPE (tree)))
2431 werror (E_IDX_NOT_INT);
2432 goto errorTreeReturn;
2435 /* if the left is an rvalue then error */
2438 werror (E_LVALUE_REQUIRED, "array access");
2439 goto errorTreeReturn;
2442 if (IS_LITERAL (RTYPE (tree)))
2444 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2445 int arraySize = DCL_ELEM (LTYPE (tree));
2446 if (arraySize && arrayIndex >= arraySize)
2448 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2453 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2456 /*------------------------------------------------------------------*/
2457 /*----------------------------*/
2459 /*----------------------------*/
2461 /* if this is not a structure */
2462 if (!IS_STRUCT (LTYPE (tree)))
2464 werror (E_STRUCT_UNION, ".");
2465 goto errorTreeReturn;
2467 TTYPE (tree) = structElemType (LTYPE (tree),
2468 (tree->right->type == EX_VALUE ?
2469 tree->right->opval.val : NULL));
2470 TETYPE (tree) = getSpec (TTYPE (tree));
2473 /*------------------------------------------------------------------*/
2474 /*----------------------------*/
2475 /* struct/union pointer */
2476 /*----------------------------*/
2478 /* if not pointer to a structure */
2479 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2481 werror (E_PTR_REQD);
2482 goto errorTreeReturn;
2485 if (!IS_STRUCT (LTYPE (tree)->next))
2487 werror (E_STRUCT_UNION, "->");
2488 goto errorTreeReturn;
2491 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2492 (tree->right->type == EX_VALUE ?
2493 tree->right->opval.val : NULL));
2494 TETYPE (tree) = getSpec (TTYPE (tree));
2496 /* adjust the storage class */
2497 switch (DCL_TYPE(tree->left->ftype)) {
2499 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2502 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2505 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2508 SPEC_SCLS (TETYPE (tree)) = 0;
2511 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2514 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2517 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2520 SPEC_SCLS (TETYPE (tree)) = 0;
2527 /* This breaks with extern declarations, bitfields, and perhaps other */
2528 /* cases (gcse). Let's leave this optimization disabled for now and */
2529 /* ponder if there's a safe way to do this. -- EEP */
2531 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2532 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2534 /* If defined struct type at addr var
2535 then rewrite (&struct var)->member
2537 and define membertype at (addr+offsetof(struct var,member)) temp
2540 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2541 AST_SYMBOL(tree->right));
2543 sym = newSymbol(genSymName (0), 0);
2544 sym->type = TTYPE (tree);
2545 sym->etype = getSpec(sym->type);
2546 sym->lineDef = tree->lineno;
2549 SPEC_STAT (sym->etype) = 1;
2550 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2552 SPEC_ABSA(sym->etype) = 1;
2553 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2556 AST_VALUE (tree) = symbolVal(sym);
2559 tree->type = EX_VALUE;
2567 /*------------------------------------------------------------------*/
2568 /*----------------------------*/
2569 /* ++/-- operation */
2570 /*----------------------------*/
2574 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2575 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2576 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2577 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2586 /*------------------------------------------------------------------*/
2587 /*----------------------------*/
2589 /*----------------------------*/
2590 case '&': /* can be unary */
2591 /* if right is NULL then unary operation */
2592 if (tree->right) /* not an unary operation */
2595 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2597 werror (E_BITWISE_OP);
2598 werror (W_CONTINUE, "left & right types are ");
2599 printTypeChain (LTYPE (tree), stderr);
2600 fprintf (stderr, ",");
2601 printTypeChain (RTYPE (tree), stderr);
2602 fprintf (stderr, "\n");
2603 goto errorTreeReturn;
2606 /* if they are both literal */
2607 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2609 tree->type = EX_VALUE;
2610 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2611 valFromType (RETYPE (tree)), '&');
2613 tree->right = tree->left = NULL;
2614 TETYPE (tree) = tree->opval.val->etype;
2615 TTYPE (tree) = tree->opval.val->type;
2619 /* see if this is a GETHBIT operation if yes
2622 ast *otree = optimizeGetHbit (tree, resultType);
2625 return decorateType (otree, RESULT_TYPE_NONE);
2628 /* see if this is a GETABIT operation if yes
2631 ast *otree = optimizeGetAbit (tree, resultType);
2634 return decorateType (otree, RESULT_TYPE_NONE);
2637 /* see if this is a GETBYTE operation if yes
2640 ast *otree = optimizeGetByte (tree, resultType);
2643 return decorateType (otree, RESULT_TYPE_NONE);
2646 /* see if this is a GETWORD operation if yes
2649 ast *otree = optimizeGetWord (tree, resultType);
2652 return decorateType (otree, RESULT_TYPE_NONE);
2655 /* if left is a literal exchange left & right */
2656 if (IS_LITERAL (LTYPE (tree)))
2658 ast *tTree = tree->left;
2659 tree->left = tree->right;
2660 tree->right = tTree;
2663 /* if right is a literal and */
2664 /* we can find a 2nd literal in an and-tree then */
2665 /* rearrange the tree */
2666 if (IS_LITERAL (RTYPE (tree)))
2669 ast *litTree = searchLitOp (tree, &parent, "&");
2673 ast *tTree = litTree->left;
2674 litTree->left = tree->right;
2675 tree->right = tTree;
2676 /* both operands in litTree are literal now */
2677 decorateType (parent, resultType);
2681 LRVAL (tree) = RRVAL (tree) = 1;
2683 TTYPE (tree) = computeType (LTYPE (tree),
2687 TETYPE (tree) = getSpec (TTYPE (tree));
2692 /*------------------------------------------------------------------*/
2693 /*----------------------------*/
2695 /*----------------------------*/
2696 p = newLink (DECLARATOR);
2697 /* if bit field then error */
2698 if (IS_BITVAR (tree->left->etype))
2700 werror (E_ILLEGAL_ADDR, "address of bit variable");
2701 goto errorTreeReturn;
2704 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2706 werror (E_ILLEGAL_ADDR, "address of register variable");
2707 goto errorTreeReturn;
2710 if (IS_FUNC (LTYPE (tree)))
2712 // this ought to be ignored
2713 return (tree->left);
2716 if (IS_LITERAL(LTYPE(tree)))
2718 werror (E_ILLEGAL_ADDR, "address of literal");
2719 goto errorTreeReturn;
2724 werror (E_LVALUE_REQUIRED, "address of");
2725 goto errorTreeReturn;
2728 DCL_TYPE (p) = POINTER;
2729 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2730 DCL_TYPE (p) = CPOINTER;
2731 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2732 DCL_TYPE (p) = FPOINTER;
2733 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2734 DCL_TYPE (p) = PPOINTER;
2735 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2736 DCL_TYPE (p) = IPOINTER;
2737 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2738 DCL_TYPE (p) = EEPPOINTER;
2739 else if (SPEC_OCLS(tree->left->etype))
2740 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2742 DCL_TYPE (p) = POINTER;
2744 if (IS_AST_SYM_VALUE (tree->left))
2746 AST_SYMBOL (tree->left)->addrtaken = 1;
2747 AST_SYMBOL (tree->left)->allocreq = 1;
2750 p->next = LTYPE (tree);
2752 TETYPE (tree) = getSpec (TTYPE (tree));
2757 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2758 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2760 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2761 AST_SYMBOL(tree->left->right));
2762 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2763 valueFromLit(element->offset));
2766 tree->type = EX_VALUE;
2767 tree->values.literalFromCast = 1;
2773 /*------------------------------------------------------------------*/
2774 /*----------------------------*/
2776 /*----------------------------*/
2778 /* if the rewrite succeeds then don't go any furthur */
2780 ast *wtree = optimizeRRCRLC (tree);
2782 return decorateType (wtree, RESULT_TYPE_NONE);
2784 wtree = optimizeSWAP (tree);
2786 return decorateType (wtree, RESULT_TYPE_NONE);
2789 /* if left is a literal exchange left & right */
2790 if (IS_LITERAL (LTYPE (tree)))
2792 ast *tTree = tree->left;
2793 tree->left = tree->right;
2794 tree->right = tTree;
2797 /* if right is a literal and */
2798 /* we can find a 2nd literal in an or-tree then */
2799 /* rearrange the tree */
2800 if (IS_LITERAL (RTYPE (tree)))
2803 ast *litTree = searchLitOp (tree, &parent, "|");
2807 ast *tTree = litTree->left;
2808 litTree->left = tree->right;
2809 tree->right = tTree;
2810 /* both operands in tTree are literal now */
2811 decorateType (parent, resultType);
2816 /*------------------------------------------------------------------*/
2817 /*----------------------------*/
2819 /*----------------------------*/
2821 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2823 werror (E_BITWISE_OP);
2824 werror (W_CONTINUE, "left & right types are ");
2825 printTypeChain (LTYPE (tree), stderr);
2826 fprintf (stderr, ",");
2827 printTypeChain (RTYPE (tree), stderr);
2828 fprintf (stderr, "\n");
2829 goto errorTreeReturn;
2832 /* if they are both literal then rewrite the tree */
2833 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2835 tree->type = EX_VALUE;
2836 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2837 valFromType (RETYPE (tree)),
2839 tree->right = tree->left = NULL;
2840 TETYPE (tree) = tree->opval.val->etype;
2841 TTYPE (tree) = tree->opval.val->type;
2845 /* if left is a literal exchange left & right */
2846 if (IS_LITERAL (LTYPE (tree)))
2848 ast *tTree = tree->left;
2849 tree->left = tree->right;
2850 tree->right = tTree;
2853 /* if right is a literal and */
2854 /* we can find a 2nd literal in a xor-tree then */
2855 /* rearrange the tree */
2856 if (IS_LITERAL (RTYPE (tree)) &&
2857 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2860 ast *litTree = searchLitOp (tree, &parent, "^");
2864 ast *tTree = litTree->left;
2865 litTree->left = tree->right;
2866 tree->right = tTree;
2867 /* both operands in litTree are literal now */
2868 decorateType (parent, resultType);
2872 LRVAL (tree) = RRVAL (tree) = 1;
2874 TTYPE (tree) = computeType (LTYPE (tree),
2878 TETYPE (tree) = getSpec (TTYPE (tree));
2882 /*------------------------------------------------------------------*/
2883 /*----------------------------*/
2885 /*----------------------------*/
2887 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2889 werror (E_INVALID_OP, "divide");
2890 goto errorTreeReturn;
2892 /* if they are both literal then */
2893 /* rewrite the tree */
2894 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2896 tree->type = EX_VALUE;
2897 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2898 valFromType (RETYPE (tree)));
2899 tree->right = tree->left = NULL;
2900 TETYPE (tree) = getSpec (TTYPE (tree) =
2901 tree->opval.val->type);
2905 LRVAL (tree) = RRVAL (tree) = 1;
2907 TETYPE (tree) = getSpec (TTYPE (tree) =
2908 computeType (LTYPE (tree),
2913 /* if right is a literal and */
2914 /* left is also a division by a literal then */
2915 /* rearrange the tree */
2916 if (IS_LITERAL (RTYPE (tree))
2917 /* avoid infinite loop */
2918 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2921 ast *litTree = searchLitOp (tree, &parent, "/");
2924 if (IS_LITERAL (RTYPE (litTree)))
2928 litTree->right = newNode ('*',
2930 copyAst (tree->right));
2931 litTree->right->lineno = tree->lineno;
2933 tree->right->opval.val = constVal ("1");
2934 decorateType (parent, resultType);
2938 /* litTree->left is literal: no gcse possible.
2939 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2940 this would cause an infinit loop. */
2941 parent->decorated = 1;
2942 decorateType (litTree, resultType);
2949 /*------------------------------------------------------------------*/
2950 /*----------------------------*/
2952 /*----------------------------*/
2954 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2956 werror (E_BITWISE_OP);
2957 werror (W_CONTINUE, "left & right types are ");
2958 printTypeChain (LTYPE (tree), stderr);
2959 fprintf (stderr, ",");
2960 printTypeChain (RTYPE (tree), stderr);
2961 fprintf (stderr, "\n");
2962 goto errorTreeReturn;
2964 /* if they are both literal then */
2965 /* rewrite the tree */
2966 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2968 tree->type = EX_VALUE;
2969 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2970 valFromType (RETYPE (tree)));
2971 tree->right = tree->left = NULL;
2972 TETYPE (tree) = getSpec (TTYPE (tree) =
2973 tree->opval.val->type);
2976 LRVAL (tree) = RRVAL (tree) = 1;
2977 TETYPE (tree) = getSpec (TTYPE (tree) =
2978 computeType (LTYPE (tree),
2984 /*------------------------------------------------------------------*/
2985 /*----------------------------*/
2986 /* address dereference */
2987 /*----------------------------*/
2988 case '*': /* can be unary : if right is null then unary operation */
2991 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2993 werror (E_PTR_REQD);
2994 goto errorTreeReturn;
2999 werror (E_LVALUE_REQUIRED, "pointer deref");
3000 goto errorTreeReturn;
3002 if (IS_ADDRESS_OF_OP(tree->left))
3004 /* replace *&obj with obj */
3005 return tree->left->left;
3007 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3008 TETYPE (tree) = getSpec (TTYPE (tree));
3009 /* adjust the storage class */
3010 switch (DCL_TYPE(tree->left->ftype)) {
3012 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3015 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3018 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3021 SPEC_SCLS (TETYPE (tree)) = 0;
3024 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3027 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3030 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3033 SPEC_SCLS (TETYPE (tree)) = 0;
3042 /*------------------------------------------------------------------*/
3043 /*----------------------------*/
3044 /* multiplication */
3045 /*----------------------------*/
3046 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3048 werror (E_INVALID_OP, "multiplication");
3049 goto errorTreeReturn;
3052 /* if they are both literal then */
3053 /* rewrite the tree */
3054 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3056 tree->type = EX_VALUE;
3057 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3058 valFromType (RETYPE (tree)));
3059 tree->right = tree->left = NULL;
3060 TETYPE (tree) = getSpec (TTYPE (tree) =
3061 tree->opval.val->type);
3065 /* if left is a literal exchange left & right */
3066 if (IS_LITERAL (LTYPE (tree)))
3068 ast *tTree = tree->left;
3069 tree->left = tree->right;
3070 tree->right = tTree;
3073 /* if right is a literal and */
3074 /* we can find a 2nd literal in a mul-tree then */
3075 /* rearrange the tree */
3076 if (IS_LITERAL (RTYPE (tree)))
3079 ast *litTree = searchLitOp (tree, &parent, "*");
3083 ast *tTree = litTree->left;
3084 litTree->left = tree->right;
3085 tree->right = tTree;
3086 /* both operands in litTree are literal now */
3087 decorateType (parent, resultType);
3091 LRVAL (tree) = RRVAL (tree) = 1;
3092 tree->left = addCast (tree->left, resultType, FALSE);
3093 tree->right = addCast (tree->right, resultType, FALSE);
3094 TETYPE (tree) = getSpec (TTYPE (tree) =
3095 computeType (LTYPE (tree),
3102 /*------------------------------------------------------------------*/
3103 /*----------------------------*/
3104 /* unary '+' operator */
3105 /*----------------------------*/
3110 if (!IS_ARITHMETIC (LTYPE (tree)))
3112 werror (E_UNARY_OP, '+');
3113 goto errorTreeReturn;
3116 /* if left is a literal then do it */
3117 if (IS_LITERAL (LTYPE (tree)))
3119 tree->type = EX_VALUE;
3120 tree->opval.val = valFromType (LETYPE (tree));
3122 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3126 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3130 /*------------------------------------------------------------------*/
3131 /*----------------------------*/
3133 /*----------------------------*/
3135 /* this is not a unary operation */
3136 /* if both pointers then problem */
3137 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3138 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3140 werror (E_PTR_PLUS_PTR);
3141 goto errorTreeReturn;
3144 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3145 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3147 werror (E_PLUS_INVALID, "+");
3148 goto errorTreeReturn;
3151 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3152 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3154 werror (E_PLUS_INVALID, "+");
3155 goto errorTreeReturn;
3157 /* if they are both literal then */
3158 /* rewrite the tree */
3159 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3161 tree->type = EX_VALUE;
3162 tree->left = addCast (tree->left, resultType, TRUE);
3163 tree->right = addCast (tree->right, resultType, TRUE);
3164 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3165 valFromType (RETYPE (tree)));
3166 tree->right = tree->left = NULL;
3167 TETYPE (tree) = getSpec (TTYPE (tree) =
3168 tree->opval.val->type);
3172 /* if the right is a pointer or left is a literal
3173 xchange left & right */
3174 if (IS_ARRAY (RTYPE (tree)) ||
3175 IS_PTR (RTYPE (tree)) ||
3176 IS_LITERAL (LTYPE (tree)))
3178 ast *tTree = tree->left;
3179 tree->left = tree->right;
3180 tree->right = tTree;
3183 /* if right is a literal and */
3184 /* left is also an addition/subtraction with a literal then */
3185 /* rearrange the tree */
3186 if (IS_LITERAL (RTYPE (tree)))
3188 ast *litTree, *parent;
3189 litTree = searchLitOp (tree, &parent, "+-");
3192 if (litTree->opval.op == '+')
3196 ast *tTree = litTree->left;
3197 litTree->left = tree->right;
3198 tree->right = tree->left;
3201 else if (litTree->opval.op == '-')
3203 if (IS_LITERAL (RTYPE (litTree)))
3207 ast *tTree = litTree->left;
3208 litTree->left = tree->right;
3209 tree->right = tTree;
3215 ast *tTree = litTree->right;
3216 litTree->right = tree->right;
3217 tree->right = tTree;
3218 litTree->opval.op = '+';
3219 tree->opval.op = '-';
3222 decorateType (parent, resultType);
3226 LRVAL (tree) = RRVAL (tree) = 1;
3227 /* if the left is a pointer */
3228 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3229 TETYPE (tree) = getSpec (TTYPE (tree) =
3233 tree->left = addCast (tree->left, resultType, TRUE);
3234 tree->right = addCast (tree->right, resultType, TRUE);
3235 TETYPE (tree) = getSpec (TTYPE (tree) =
3236 computeType (LTYPE (tree),
3244 /*------------------------------------------------------------------*/
3245 /*----------------------------*/
3247 /*----------------------------*/
3248 case '-': /* can be unary */
3249 /* if right is null then unary */
3253 if (!IS_ARITHMETIC (LTYPE (tree)))
3255 werror (E_UNARY_OP, tree->opval.op);
3256 goto errorTreeReturn;
3259 /* if left is a literal then do it */
3260 if (IS_LITERAL (LTYPE (tree)))
3262 tree->type = EX_VALUE;
3263 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3265 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3266 SPEC_USIGN(TETYPE(tree)) = 0;
3270 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3274 /*------------------------------------------------------------------*/
3275 /*----------------------------*/
3277 /*----------------------------*/
3279 if (!(IS_PTR (LTYPE (tree)) ||
3280 IS_ARRAY (LTYPE (tree)) ||
3281 IS_ARITHMETIC (LTYPE (tree))))
3283 werror (E_PLUS_INVALID, "-");
3284 goto errorTreeReturn;
3287 if (!(IS_PTR (RTYPE (tree)) ||
3288 IS_ARRAY (RTYPE (tree)) ||
3289 IS_ARITHMETIC (RTYPE (tree))))
3291 werror (E_PLUS_INVALID, "-");
3292 goto errorTreeReturn;
3295 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3296 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3297 IS_INTEGRAL (RTYPE (tree))))
3299 werror (E_PLUS_INVALID, "-");
3300 goto errorTreeReturn;
3303 /* if they are both literal then */
3304 /* rewrite the tree */
3305 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3307 tree->type = EX_VALUE;
3308 tree->left = addCast (tree->left, resultType, TRUE);
3309 tree->right = addCast (tree->right, resultType, TRUE);
3310 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3311 valFromType (RETYPE (tree)));
3312 tree->right = tree->left = NULL;
3313 TETYPE (tree) = getSpec (TTYPE (tree) =
3314 tree->opval.val->type);
3318 /* if the left & right are equal then zero */
3319 if (isAstEqual (tree->left, tree->right))
3321 tree->type = EX_VALUE;
3322 tree->left = tree->right = NULL;
3323 tree->opval.val = constVal ("0");
3324 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3328 /* if both of them are pointers or arrays then */
3329 /* the result is going to be an integer */
3330 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3331 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3332 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3334 /* if only the left is a pointer */
3335 /* then result is a pointer */
3336 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3337 TETYPE (tree) = getSpec (TTYPE (tree) =
3341 tree->left = addCast (tree->left, resultType, TRUE);
3342 tree->right = addCast (tree->right, resultType, TRUE);
3344 TETYPE (tree) = getSpec (TTYPE (tree) =
3345 computeType (LTYPE (tree),
3351 LRVAL (tree) = RRVAL (tree) = 1;
3353 /* if right is a literal and */
3354 /* left is also an addition/subtraction with a literal then */
3355 /* rearrange the tree */
3356 if (IS_LITERAL (RTYPE (tree))
3357 /* avoid infinite loop */
3358 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3360 ast *litTree, *litParent;
3361 litTree = searchLitOp (tree, &litParent, "+-");
3364 if (litTree->opval.op == '+')
3368 ast *tTree = litTree->left;
3369 litTree->left = litTree->right;
3370 litTree->right = tree->right;
3371 tree->right = tTree;
3372 tree->opval.op = '+';
3373 litTree->opval.op = '-';
3375 else if (litTree->opval.op == '-')
3377 if (IS_LITERAL (RTYPE (litTree)))
3381 ast *tTree = litTree->left;
3382 litTree->left = tree->right;
3383 tree->right = litParent->left;
3384 litParent->left = tTree;
3385 litTree->opval.op = '+';
3387 tree->decorated = 0;
3388 decorateType (tree, resultType);
3394 ast *tTree = litTree->right;
3395 litTree->right = tree->right;
3396 tree->right = tTree;
3399 decorateType (litParent, resultType);
3404 /*------------------------------------------------------------------*/
3405 /*----------------------------*/
3407 /*----------------------------*/
3409 /* can be only integral type */
3410 if (!IS_INTEGRAL (LTYPE (tree)))
3412 werror (E_UNARY_OP, tree->opval.op);
3413 goto errorTreeReturn;
3416 /* if left is a literal then do it */
3417 if (IS_LITERAL (LTYPE (tree)))
3419 tree->type = EX_VALUE;
3420 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3422 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3423 return addCast (tree, resultType, TRUE);
3426 if (resultType == RESULT_TYPE_BIT &&
3427 IS_UNSIGNED (tree->left->etype) &&
3428 getSize (tree->left->etype) < INTSIZE)
3430 /* promotion rules are responsible for this strange result:
3431 bit -> int -> ~int -> bit
3432 uchar -> int -> ~int -> bit
3434 werror(W_COMPLEMENT);
3436 /* optimize bit-result, even if we optimize a buggy source */
3437 tree->type = EX_VALUE;
3438 tree->opval.val = constVal ("1");
3441 tree->left = addCast (tree->left, resultType, TRUE);
3443 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3446 /*------------------------------------------------------------------*/
3447 /*----------------------------*/
3449 /*----------------------------*/
3451 /* can be pointer */
3452 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3453 !IS_PTR (LTYPE (tree)) &&
3454 !IS_ARRAY (LTYPE (tree)))
3456 werror (E_UNARY_OP, tree->opval.op);
3457 goto errorTreeReturn;
3460 /* if left is a literal then do it */
3461 if (IS_LITERAL (LTYPE (tree)))
3463 tree->type = EX_VALUE;
3464 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3466 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3470 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3473 /*------------------------------------------------------------------*/
3474 /*----------------------------*/
3476 /*----------------------------*/
3480 TTYPE (tree) = LTYPE (tree);
3481 TETYPE (tree) = LETYPE (tree);
3486 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3490 TTYPE (tree) = TETYPE (tree) = newCharLink();
3494 TTYPE (tree) = TETYPE (tree) = newIntLink();
3499 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3501 werror (E_SHIFT_OP_INVALID);
3502 werror (W_CONTINUE, "left & right types are ");
3503 printTypeChain (LTYPE (tree), stderr);
3504 fprintf (stderr, ",");
3505 printTypeChain (RTYPE (tree), stderr);
3506 fprintf (stderr, "\n");
3507 goto errorTreeReturn;
3510 /* make smaller type only if it's a LEFT_OP */
3511 if (tree->opval.op == LEFT_OP)
3512 tree->left = addCast (tree->left, resultType, TRUE);
3514 /* if they are both literal then */
3515 /* rewrite the tree */
3516 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3518 tree->type = EX_VALUE;
3519 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3520 valFromType (RETYPE (tree)),
3521 (tree->opval.op == LEFT_OP ? 1 : 0));
3522 tree->right = tree->left = NULL;
3523 TETYPE (tree) = getSpec (TTYPE (tree) =
3524 tree->opval.val->type);
3528 /* see if this is a GETBYTE operation if yes
3531 ast *otree = optimizeGetByte (tree, resultType);
3534 return decorateType (otree, RESULT_TYPE_NONE);
3537 /* see if this is a GETWORD operation if yes
3540 ast *otree = optimizeGetWord (tree, resultType);
3543 return decorateType (otree, RESULT_TYPE_NONE);
3546 LRVAL (tree) = RRVAL (tree) = 1;
3547 if (tree->opval.op == LEFT_OP)
3549 TETYPE (tree) = getSpec (TTYPE (tree) =
3550 computeType (LTYPE (tree),
3557 /* no promotion necessary */
3558 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3559 if (IS_LITERAL (TTYPE (tree)))
3560 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3563 /* if only the right side is a literal & we are
3564 shifting more than size of the left operand then zero */
3565 if (IS_LITERAL (RTYPE (tree)) &&
3566 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3567 (getSize (TETYPE (tree)) * 8))
3569 if (tree->opval.op==LEFT_OP ||
3570 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3572 lineno=tree->lineno;
3573 werror (W_SHIFT_CHANGED,
3574 (tree->opval.op == LEFT_OP ? "left" : "right"));
3575 tree->type = EX_VALUE;
3576 tree->left = tree->right = NULL;
3577 tree->opval.val = constVal ("0");
3578 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3585 /*------------------------------------------------------------------*/
3586 /*----------------------------*/
3588 /*----------------------------*/
3589 case CAST: /* change the type */
3590 /* cannot cast to an aggregate type */
3591 if (IS_AGGREGATE (LTYPE (tree)))
3593 werror (E_CAST_ILLEGAL);
3594 goto errorTreeReturn;
3597 /* make sure the type is complete and sane */
3598 changePointer(LTYPE(tree));
3599 checkTypeSanity(LETYPE(tree), "(cast)");
3601 /* If code memory is read only, then pointers to code memory */
3602 /* implicitly point to constants -- make this explicit */
3604 sym_link *t = LTYPE(tree);
3605 while (t && t->next)
3607 if (IS_CODEPTR(t) && port->mem.code_ro)
3609 if (IS_SPEC(t->next))
3610 SPEC_CONST (t->next) = 1;
3612 DCL_PTR_CONST (t->next) = 1;
3619 /* if the right is a literal replace the tree */
3620 if (IS_LITERAL (RETYPE (tree))) {
3621 if (!IS_PTR (LTYPE (tree))) {
3622 tree->type = EX_VALUE;
3624 valCastLiteral (LTYPE (tree),
3625 floatFromVal (valFromType (RETYPE (tree))));
3628 TTYPE (tree) = tree->opval.val->type;
3629 tree->values.literalFromCast = 1;
3630 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3631 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3632 sym_link *rest = LTYPE(tree)->next;
3633 werror(W_LITERAL_GENERIC);
3634 TTYPE(tree) = newLink(DECLARATOR);
3635 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3636 TTYPE(tree)->next = rest;
3637 tree->left->opval.lnk = TTYPE(tree);
3640 TTYPE (tree) = LTYPE (tree);
3644 TTYPE (tree) = LTYPE (tree);
3648 #if 0 // this is already checked, now this could be explicit
3649 /* if pointer to struct then check names */
3650 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3651 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3652 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3654 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3655 SPEC_STRUCT(LETYPE(tree))->tag);
3658 if (IS_ADDRESS_OF_OP(tree->right)
3659 && IS_AST_SYM_VALUE (tree->right->left)
3660 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3662 symbol * sym = AST_SYMBOL (tree->right->left);
3663 unsigned int gptype = 0;
3664 unsigned int addr = SPEC_ADDR (sym->etype);
3666 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3668 switch (SPEC_SCLS (sym->etype))
3671 gptype = GPTYPE_CODE;
3674 gptype = GPTYPE_FAR;
3678 gptype = GPTYPE_NEAR;
3681 gptype = GPTYPE_XSTACK;
3686 addr |= gptype << (8*(GPTRSIZE - 1));
3689 tree->type = EX_VALUE;
3691 valCastLiteral (LTYPE (tree), addr);
3692 TTYPE (tree) = tree->opval.val->type;
3693 TETYPE (tree) = getSpec (TTYPE (tree));
3696 tree->values.literalFromCast = 1;
3700 /* handle offsetof macro: */
3701 /* #define offsetof(TYPE, MEMBER) \ */
3702 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3703 if (IS_ADDRESS_OF_OP(tree->right)
3704 && IS_AST_OP (tree->right->left)
3705 && tree->right->left->opval.op == PTR_OP
3706 && IS_AST_OP (tree->right->left->left)
3707 && tree->right->left->left->opval.op == CAST
3708 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3710 symbol *element = getStructElement (
3711 SPEC_STRUCT (LETYPE(tree->right->left)),
3712 AST_SYMBOL(tree->right->left->right)
3716 tree->type = EX_VALUE;
3717 tree->opval.val = valCastLiteral (
3720 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3723 TTYPE (tree) = tree->opval.val->type;
3724 TETYPE (tree) = getSpec (TTYPE (tree));
3731 /* if the right is a literal replace the tree */
3732 if (IS_LITERAL (RETYPE (tree))) {
3734 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3735 /* rewrite (type *)litaddr
3737 and define type at litaddr temp
3738 (but only if type's storage class is not generic)
3740 ast *newTree = newNode ('&', NULL, NULL);
3743 TTYPE (newTree) = LTYPE (tree);
3744 TETYPE (newTree) = getSpec(LTYPE (tree));
3746 /* define a global symbol at the casted address*/
3747 sym = newSymbol(genSymName (0), 0);
3748 sym->type = LTYPE (tree)->next;
3750 sym->type = newLink (V_VOID);
3751 sym->etype = getSpec(sym->type);
3752 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3753 sym->lineDef = tree->lineno;
3756 SPEC_STAT (sym->etype) = 1;
3757 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3758 SPEC_ABSA(sym->etype) = 1;
3759 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3762 newTree->left = newAst_VALUE(symbolVal(sym));
3763 newTree->left->lineno = tree->lineno;
3764 LTYPE (newTree) = sym->type;
3765 LETYPE (newTree) = sym->etype;
3766 LLVAL (newTree) = 1;
3767 LRVAL (newTree) = 0;
3768 TLVAL (newTree) = 1;
3772 if (!IS_PTR (LTYPE (tree))) {
3773 tree->type = EX_VALUE;
3775 valCastLiteral (LTYPE (tree),
3776 floatFromVal (valFromType (RTYPE (tree))));
3777 TTYPE (tree) = tree->opval.val->type;
3780 tree->values.literalFromCast = 1;
3781 TETYPE (tree) = getSpec (TTYPE (tree));
3785 TTYPE (tree) = LTYPE (tree);
3789 TETYPE (tree) = getSpec (TTYPE (tree));
3793 /*------------------------------------------------------------------*/
3794 /*----------------------------*/
3795 /* logical &&, || */
3796 /*----------------------------*/
3799 /* each must be arithmetic type or be a pointer */
3800 if (!IS_PTR (LTYPE (tree)) &&
3801 !IS_ARRAY (LTYPE (tree)) &&
3802 !IS_INTEGRAL (LTYPE (tree)))
3804 werror (E_COMPARE_OP);
3805 goto errorTreeReturn;
3808 if (!IS_PTR (RTYPE (tree)) &&
3809 !IS_ARRAY (RTYPE (tree)) &&
3810 !IS_INTEGRAL (RTYPE (tree)))
3812 werror (E_COMPARE_OP);
3813 goto errorTreeReturn;
3815 /* if they are both literal then */
3816 /* rewrite the tree */
3817 if (IS_LITERAL (RTYPE (tree)) &&
3818 IS_LITERAL (LTYPE (tree)))
3820 tree->type = EX_VALUE;
3821 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3822 valFromType (RTYPE (tree)),
3824 tree->right = tree->left = NULL;
3825 TETYPE (tree) = getSpec (TTYPE (tree) =
3826 tree->opval.val->type);
3829 LRVAL (tree) = RRVAL (tree) = 1;
3830 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3833 /*------------------------------------------------------------------*/
3834 /*----------------------------*/
3835 /* comparison operators */
3836 /*----------------------------*/
3844 ast *lt = optimizeCompare (tree);
3850 /* if they are pointers they must be castable */
3851 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3853 if (tree->opval.op==EQ_OP &&
3854 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3855 // we cannot cast a gptr to a !gptr: switch the leaves
3856 struct ast *s=tree->left;
3857 tree->left=tree->right;
3860 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3862 werror (E_COMPARE_OP);
3863 fprintf (stderr, "comparing type ");
3864 printTypeChain (LTYPE (tree), stderr);
3865 fprintf (stderr, "to type ");
3866 printTypeChain (RTYPE (tree), stderr);
3867 fprintf (stderr, "\n");
3868 goto errorTreeReturn;
3871 /* else they should be promotable to one another */
3874 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3875 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3877 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3879 werror (E_COMPARE_OP);
3880 fprintf (stderr, "comparing type ");
3881 printTypeChain (LTYPE (tree), stderr);
3882 fprintf (stderr, "to type ");
3883 printTypeChain (RTYPE (tree), stderr);
3884 fprintf (stderr, "\n");
3885 goto errorTreeReturn;
3888 /* if unsigned value < 0 then always false */
3889 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3890 if (SPEC_USIGN(LETYPE(tree)) &&
3891 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3892 IS_LITERAL(RTYPE(tree)) &&
3893 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3895 if (tree->opval.op == '<')
3899 if (tree->opval.op == '>')
3901 if (resultType == RESULT_TYPE_IFX)
3903 /* the parent is an ifx: */
3904 /* if (unsigned value) */
3908 /* (unsigned value) ? 1 : 0 */
3909 tree->opval.op = '?';
3910 tree->right = newNode (':',
3911 newAst_VALUE (constVal ("1")),
3912 tree->right); /* val 0 */
3913 tree->right->lineno = tree->lineno;
3914 tree->right->left->lineno = tree->lineno;
3915 decorateType (tree->right, RESULT_TYPE_NONE);
3918 /* if they are both literal then */
3919 /* rewrite the tree */
3920 if (IS_LITERAL (RTYPE (tree)) &&
3921 IS_LITERAL (LTYPE (tree)))
3923 tree->type = EX_VALUE;
3924 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3925 valFromType (RETYPE (tree)),
3927 tree->right = tree->left = NULL;
3928 TETYPE (tree) = getSpec (TTYPE (tree) =
3929 tree->opval.val->type);
3932 LRVAL (tree) = RRVAL (tree) = 1;
3933 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3936 /*------------------------------------------------------------------*/
3937 /*----------------------------*/
3939 /*----------------------------*/
3940 case SIZEOF: /* evaluate wihout code generation */
3941 /* change the type to a integer */
3943 int size = getSize (tree->right->ftype);
3944 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3945 if (!size && !IS_VOID(tree->right->ftype))
3946 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3948 tree->type = EX_VALUE;
3949 tree->opval.val = constVal (buffer);
3950 tree->right = tree->left = NULL;
3951 TETYPE (tree) = getSpec (TTYPE (tree) =
3952 tree->opval.val->type);
3955 /*------------------------------------------------------------------*/
3956 /*----------------------------*/
3958 /*----------------------------*/
3960 /* return typeof enum value */
3961 tree->type = EX_VALUE;
3964 if (IS_SPEC(tree->right->ftype)) {
3965 switch (SPEC_NOUN(tree->right->ftype)) {
3967 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3968 else typeofv = TYPEOF_INT;
3971 typeofv = TYPEOF_FLOAT;
3974 typeofv = TYPEOF_FIXED16X16;
3977 typeofv = TYPEOF_CHAR;
3980 typeofv = TYPEOF_VOID;
3983 typeofv = TYPEOF_STRUCT;
3986 typeofv = TYPEOF_BITFIELD;
3989 typeofv = TYPEOF_BIT;
3992 typeofv = TYPEOF_SBIT;
3998 switch (DCL_TYPE(tree->right->ftype)) {
4000 typeofv = TYPEOF_POINTER;
4003 typeofv = TYPEOF_FPOINTER;
4006 typeofv = TYPEOF_CPOINTER;
4009 typeofv = TYPEOF_GPOINTER;
4012 typeofv = TYPEOF_PPOINTER;
4015 typeofv = TYPEOF_IPOINTER;
4018 typeofv = TYPEOF_ARRAY;
4021 typeofv = TYPEOF_FUNCTION;
4027 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4028 tree->opval.val = constVal (buffer);
4029 tree->right = tree->left = NULL;
4030 TETYPE (tree) = getSpec (TTYPE (tree) =
4031 tree->opval.val->type);
4034 /*------------------------------------------------------------------*/
4035 /*----------------------------*/
4036 /* conditional operator '?' */
4037 /*----------------------------*/
4039 /* the type is value of the colon operator (on the right) */
4040 assert (IS_COLON_OP (tree->right));
4041 /* if already known then replace the tree : optimizer will do it
4042 but faster to do it here */
4043 if (IS_LITERAL (LTYPE (tree)))
4045 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4046 return decorateType (tree->right->left, resultTypeProp);
4048 return decorateType (tree->right->right, resultTypeProp);
4052 tree->right = decorateType (tree->right, resultTypeProp);
4053 TTYPE (tree) = RTYPE (tree);
4054 TETYPE (tree) = getSpec (TTYPE (tree));
4059 /* if they don't match we have a problem */
4060 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4061 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4063 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4064 goto errorTreeReturn;
4067 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4068 resultType, tree->opval.op);
4069 TETYPE (tree) = getSpec (TTYPE (tree));
4073 #if 0 // assignment operators are converted by the parser
4074 /*------------------------------------------------------------------*/
4075 /*----------------------------*/
4076 /* assignment operators */
4077 /*----------------------------*/
4080 /* for these it must be both must be integral */
4081 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4082 !IS_ARITHMETIC (RTYPE (tree)))
4084 werror (E_OPS_INTEGRAL);
4085 goto errorTreeReturn;
4088 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4090 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4091 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4095 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4096 goto errorTreeReturn;
4107 /* for these it must be both must be integral */
4108 if (!IS_INTEGRAL (LTYPE (tree)) ||
4109 !IS_INTEGRAL (RTYPE (tree)))
4111 werror (E_OPS_INTEGRAL);
4112 goto errorTreeReturn;
4115 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4117 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4118 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4122 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4123 goto errorTreeReturn;
4129 /*------------------------------------------------------------------*/
4130 /*----------------------------*/
4132 /*----------------------------*/
4134 if (!(IS_PTR (LTYPE (tree)) ||
4135 IS_ARITHMETIC (LTYPE (tree))))
4137 werror (E_PLUS_INVALID, "-=");
4138 goto errorTreeReturn;
4141 if (!(IS_PTR (RTYPE (tree)) ||
4142 IS_ARITHMETIC (RTYPE (tree))))
4144 werror (E_PLUS_INVALID, "-=");
4145 goto errorTreeReturn;
4148 TETYPE (tree) = getSpec (TTYPE (tree) =
4149 computeType (LTYPE (tree),
4154 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4155 werror (E_CODE_WRITE, "-=");
4159 werror (E_LVALUE_REQUIRED, "-=");
4160 goto errorTreeReturn;
4166 /*------------------------------------------------------------------*/
4167 /*----------------------------*/
4169 /*----------------------------*/
4171 /* this is not a unary operation */
4172 /* if both pointers then problem */
4173 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4175 werror (E_PTR_PLUS_PTR);
4176 goto errorTreeReturn;
4179 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4181 werror (E_PLUS_INVALID, "+=");
4182 goto errorTreeReturn;
4185 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4187 werror (E_PLUS_INVALID, "+=");
4188 goto errorTreeReturn;
4191 TETYPE (tree) = getSpec (TTYPE (tree) =
4192 computeType (LTYPE (tree),
4197 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4198 werror (E_CODE_WRITE, "+=");
4202 werror (E_LVALUE_REQUIRED, "+=");
4203 goto errorTreeReturn;
4206 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4207 tree->opval.op = '=';
4212 /*------------------------------------------------------------------*/
4213 /*----------------------------*/
4214 /* straight assignemnt */
4215 /*----------------------------*/
4217 /* cannot be an aggregate */
4218 if (IS_AGGREGATE (LTYPE (tree)))
4220 werror (E_AGGR_ASSIGN);
4221 goto errorTreeReturn;
4224 /* they should either match or be castable */
4225 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4227 werror (E_TYPE_MISMATCH, "assignment", " ");
4228 printFromToType(RTYPE(tree),LTYPE(tree));
4231 /* if the left side of the tree is of type void
4232 then report error */
4233 if (IS_VOID (LTYPE (tree)))
4235 werror (E_CAST_ZERO);
4236 printFromToType(RTYPE(tree), LTYPE(tree));
4239 TETYPE (tree) = getSpec (TTYPE (tree) =
4243 if (!tree->initMode ) {
4244 if (IS_CONSTANT(LTYPE(tree)))
4245 werror (E_CODE_WRITE, "=");
4249 werror (E_LVALUE_REQUIRED, "=");
4250 goto errorTreeReturn;
4255 /*------------------------------------------------------------------*/
4256 /*----------------------------*/
4257 /* comma operator */
4258 /*----------------------------*/
4260 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4263 /*------------------------------------------------------------------*/
4264 /*----------------------------*/
4266 /*----------------------------*/
4269 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4270 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4272 if (tree->left->opval.op == '*' && !tree->left->right)
4273 tree->left = tree->left->left;
4276 /* require a function or pointer to function */
4277 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4279 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4280 goto errorTreeReturn;
4283 /* if there are parms, make sure that
4284 parms are decorate / process / reverse only once */
4286 !tree->right->decorated)
4291 if (IS_FUNCPTR (LTYPE (tree)))
4292 functype = LTYPE (tree)->next;
4294 functype = LTYPE (tree);
4296 if (processParms (tree->left, FUNC_ARGS(functype),
4297 &tree->right, &parmNumber, TRUE))
4299 goto errorTreeReturn;
4302 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4303 !IFFUNC_ISBUILTIN(functype))
4305 reverseParms (tree->right);
4308 TTYPE (tree) = functype->next;
4309 TETYPE (tree) = getSpec (TTYPE (tree));
4313 /*------------------------------------------------------------------*/
4314 /*----------------------------*/
4315 /* return statement */
4316 /*----------------------------*/
4321 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4323 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4324 printFromToType (RTYPE(tree), currFunc->type->next);
4325 goto errorTreeReturn;
4328 if (IS_VOID (currFunc->type->next)
4330 !IS_VOID (RTYPE (tree)))
4332 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4333 goto errorTreeReturn;
4336 /* if there is going to be a casting required then add it */
4337 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4340 decorateType (newNode (CAST,
4341 newAst_LINK (copyLinkChain (currFunc->type->next)),
4351 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4353 werror (W_VOID_FUNC, currFunc->name);
4354 goto errorTreeReturn;
4357 TTYPE (tree) = TETYPE (tree) = NULL;
4360 /*------------------------------------------------------------------*/
4361 /*----------------------------*/
4362 /* switch statement */
4363 /*----------------------------*/
4365 /* the switch value must be an integer */
4366 if (!IS_INTEGRAL (LTYPE (tree)))
4368 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4369 goto errorTreeReturn;
4372 TTYPE (tree) = TETYPE (tree) = NULL;
4375 /*------------------------------------------------------------------*/
4376 /*----------------------------*/
4378 /*----------------------------*/
4380 tree->left = backPatchLabels (tree->left,
4383 TTYPE (tree) = TETYPE (tree) = NULL;
4386 /*------------------------------------------------------------------*/
4387 /*----------------------------*/
4389 /*----------------------------*/
4392 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4393 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4394 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4396 /* if the for loop is reversible then
4397 reverse it otherwise do what we normally
4403 if (isLoopReversible (tree, &sym, &init, &end))
4404 return reverseLoop (tree, sym, init, end);
4406 return decorateType (createFor (AST_FOR (tree, trueLabel),
4407 AST_FOR (tree, continueLabel),
4408 AST_FOR (tree, falseLabel),
4409 AST_FOR (tree, condLabel),
4410 AST_FOR (tree, initExpr),
4411 AST_FOR (tree, condExpr),
4412 AST_FOR (tree, loopExpr),
4413 tree->left), RESULT_TYPE_NONE);
4416 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4417 "node PARAM shouldn't be processed here");
4418 /* but in processParams() */
4421 TTYPE (tree) = TETYPE (tree) = NULL;
4425 /* some error found this tree will be killed */
4427 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4428 tree->opval.op = NULLOP;
4434 /*-----------------------------------------------------------------*/
4435 /* sizeofOp - processes size of operation */
4436 /*-----------------------------------------------------------------*/
4438 sizeofOp (sym_link * type)
4443 /* make sure the type is complete and sane */
4444 checkTypeSanity(type, "(sizeof)");
4446 /* get the size and convert it to character */
4447 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4448 if (!size && !IS_VOID(type))
4449 werror (E_SIZEOF_INCOMPLETE_TYPE);
4451 /* now convert into value */
4452 return constVal (buff);
4456 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4457 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4458 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4459 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4460 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4461 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4462 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4464 /*-----------------------------------------------------------------*/
4465 /* backPatchLabels - change and or not operators to flow control */
4466 /*-----------------------------------------------------------------*/
4468 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4474 if (!(IS_ANDORNOT (tree)))
4477 /* if this an and */
4480 static int localLbl = 0;
4483 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4484 localLabel = newSymbol (buffer, NestLevel);
4486 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4488 /* if left is already a IFX then just change the if true label in that */
4489 if (!IS_IFX (tree->left))
4490 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4492 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4493 /* right is a IFX then just join */
4494 if (IS_IFX (tree->right))
4495 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4497 tree->right = createLabel (localLabel, tree->right);
4498 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4500 return newNode (NULLOP, tree->left, tree->right);
4503 /* if this is an or operation */
4506 static int localLbl = 0;
4509 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4510 localLabel = newSymbol (buffer, NestLevel);
4512 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4514 /* if left is already a IFX then just change the if true label in that */
4515 if (!IS_IFX (tree->left))
4516 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4518 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4519 /* right is a IFX then just join */
4520 if (IS_IFX (tree->right))
4521 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4523 tree->right = createLabel (localLabel, tree->right);
4524 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4526 return newNode (NULLOP, tree->left, tree->right);
4532 int wasnot = IS_NOT (tree->left);
4533 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4535 /* if the left is already a IFX */
4536 if (!IS_IFX (tree->left))
4537 tree->left = newNode (IFX, tree->left, NULL);
4541 tree->left->trueLabel = trueLabel;
4542 tree->left->falseLabel = falseLabel;
4546 tree->left->trueLabel = falseLabel;
4547 tree->left->falseLabel = trueLabel;
4554 tree->trueLabel = trueLabel;
4555 tree->falseLabel = falseLabel;
4562 /*-----------------------------------------------------------------*/
4563 /* createBlock - create expression tree for block */
4564 /*-----------------------------------------------------------------*/
4566 createBlock (symbol * decl, ast * body)
4570 /* if the block has nothing */
4574 ex = newNode (BLOCK, NULL, body);
4575 ex->values.sym = decl;
4582 /*-----------------------------------------------------------------*/
4583 /* createLabel - creates the expression tree for labels */
4584 /*-----------------------------------------------------------------*/
4586 createLabel (symbol * label, ast * stmnt)
4589 char name[SDCC_NAME_MAX + 1];
4592 /* must create fresh symbol if the symbol name */
4593 /* exists in the symbol table, since there can */
4594 /* be a variable with the same name as the labl */
4595 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4596 (csym->level == label->level))
4597 label = newSymbol (label->name, label->level);
4599 /* change the name before putting it in add _ */
4600 SNPRINTF(name, sizeof(name), "%s", label->name);
4602 /* put the label in the LabelSymbol table */
4603 /* but first check if a label of the same */
4605 if ((csym = findSym (LabelTab, NULL, name)))
4606 werror (E_DUPLICATE_LABEL, label->name);
4608 addSym (LabelTab, label, name, label->level, 0, 0);
4612 label->key = labelKey++;
4613 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4619 /*-----------------------------------------------------------------*/
4620 /* createCase - generates the parsetree for a case statement */
4621 /*-----------------------------------------------------------------*/
4623 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4625 char caseLbl[SDCC_NAME_MAX + 1];
4629 /* if the switch statement does not exist */
4630 /* then case is out of context */
4633 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4637 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4638 /* if not a constant then error */
4639 if (!IS_LITERAL (caseVal->ftype))
4641 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4645 /* if not a integer than error */
4646 if (!IS_INTEGRAL (caseVal->ftype))
4648 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4652 /* find the end of the switch values chain */
4653 if (!(val = swStat->values.switchVals.swVals))
4654 swStat->values.switchVals.swVals = caseVal->opval.val;
4657 /* also order the cases according to value */
4659 int cVal = (int) floatFromVal (caseVal->opval.val);
4660 while (val && (int) floatFromVal (val) < cVal)
4666 /* if we reached the end then */
4669 pval->next = caseVal->opval.val;
4671 else if ((int) floatFromVal (val) == cVal)
4673 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4679 /* we found a value greater than */
4680 /* the current value we must add this */
4681 /* before the value */
4682 caseVal->opval.val->next = val;
4684 /* if this was the first in chain */
4685 if (swStat->values.switchVals.swVals == val)
4686 swStat->values.switchVals.swVals =
4689 pval->next = caseVal->opval.val;
4694 /* create the case label */
4695 SNPRINTF(caseLbl, sizeof(caseLbl),
4697 swStat->values.switchVals.swNum,
4698 (int) floatFromVal (caseVal->opval.val));
4700 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4705 /*-----------------------------------------------------------------*/
4706 /* createDefault - creates the parse tree for the default statement */
4707 /*-----------------------------------------------------------------*/
4709 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4711 char defLbl[SDCC_NAME_MAX + 1];
4713 /* if the switch statement does not exist */
4714 /* then case is out of context */
4717 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4721 if (swStat->values.switchVals.swDefault)
4723 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4728 /* turn on the default flag */
4729 swStat->values.switchVals.swDefault = 1;
4731 /* create the label */
4732 SNPRINTF (defLbl, sizeof(defLbl),
4733 "_default_%d", swStat->values.switchVals.swNum);
4734 return createLabel (newSymbol (defLbl, 0), stmnt);
4737 /*-----------------------------------------------------------------*/
4738 /* createIf - creates the parsetree for the if statement */
4739 /*-----------------------------------------------------------------*/
4741 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4743 static int Lblnum = 0;
4745 symbol *ifTrue, *ifFalse, *ifEnd;
4747 /* if neither exists */
4748 if (!elseBody && !ifBody) {
4749 // if there are no side effects (i++, j() etc)
4750 if (!hasSEFcalls(condAst)) {
4755 /* create the labels */
4756 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4757 ifFalse = newSymbol (buffer, NestLevel);
4758 /* if no else body then end == false */
4763 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4764 ifEnd = newSymbol (buffer, NestLevel);
4767 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4768 ifTrue = newSymbol (buffer, NestLevel);
4772 /* attach the ifTrue label to the top of it body */
4773 ifBody = createLabel (ifTrue, ifBody);
4774 /* attach a goto end to the ifBody if else is present */
4777 ifBody = newNode (NULLOP, ifBody,
4779 newAst_VALUE (symbolVal (ifEnd)),
4781 /* put the elseLabel on the else body */
4782 elseBody = createLabel (ifFalse, elseBody);
4783 /* out the end at the end of the body */
4784 elseBody = newNode (NULLOP,
4786 createLabel (ifEnd, NULL));
4790 ifBody = newNode (NULLOP, ifBody,
4791 createLabel (ifFalse, NULL));
4793 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4794 if (IS_IFX (condAst))
4797 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4799 return newNode (NULLOP, ifTree,
4800 newNode (NULLOP, ifBody, elseBody));
4804 /*-----------------------------------------------------------------*/
4805 /* createDo - creates parse tree for do */
4808 /* _docontinue_n: */
4809 /* condition_expression +-> trueLabel -> _dobody_n */
4811 /* +-> falseLabel-> _dobreak_n */
4813 /*-----------------------------------------------------------------*/
4815 createDo (symbol * trueLabel, symbol * continueLabel,
4816 symbol * falseLabel, ast * condAst, ast * doBody)
4821 /* if the body does not exist then it is simple */
4824 condAst = backPatchLabels (condAst, continueLabel, NULL);
4825 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4826 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4827 doTree->trueLabel = continueLabel;
4828 doTree->falseLabel = NULL;
4832 /* otherwise we have a body */
4833 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4835 /* attach the body label to the top */
4836 doBody = createLabel (trueLabel, doBody);
4837 /* attach the continue label to end of body */
4838 doBody = newNode (NULLOP, doBody,
4839 createLabel (continueLabel, NULL));
4841 /* now put the break label at the end */
4842 if (IS_IFX (condAst))
4845 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4847 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4849 /* putting it together */
4850 return newNode (NULLOP, doBody, doTree);
4853 /*-----------------------------------------------------------------*/
4854 /* createFor - creates parse tree for 'for' statement */
4857 /* condExpr +-> trueLabel -> _forbody_n */
4859 /* +-> falseLabel-> _forbreak_n */
4862 /* _forcontinue_n: */
4864 /* goto _forcond_n ; */
4866 /*-----------------------------------------------------------------*/
4868 createFor (symbol * trueLabel, symbol * continueLabel,
4869 symbol * falseLabel, symbol * condLabel,
4870 ast * initExpr, ast * condExpr, ast * loopExpr,
4875 /* if loopexpression not present then we can generate it */
4876 /* the same way as a while */
4878 return newNode (NULLOP, initExpr,
4879 createWhile (trueLabel, continueLabel,
4880 falseLabel, condExpr, forBody));
4881 /* vanilla for statement */
4882 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4884 if (condExpr && !IS_IFX (condExpr))
4885 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4888 /* attach condition label to condition */
4889 condExpr = createLabel (condLabel, condExpr);
4891 /* attach body label to body */
4892 forBody = createLabel (trueLabel, forBody);
4894 /* attach continue to forLoop expression & attach */
4895 /* goto the forcond @ and of loopExpression */
4896 loopExpr = createLabel (continueLabel,
4900 newAst_VALUE (symbolVal (condLabel)),
4902 /* now start putting them together */
4903 forTree = newNode (NULLOP, initExpr, condExpr);
4904 forTree = newNode (NULLOP, forTree, forBody);
4905 forTree = newNode (NULLOP, forTree, loopExpr);
4906 /* finally add the break label */
4907 forTree = newNode (NULLOP, forTree,
4908 createLabel (falseLabel, NULL));
4912 /*-----------------------------------------------------------------*/
4913 /* createWhile - creates parse tree for while statement */
4914 /* the while statement will be created as follows */
4916 /* _while_continue_n: */
4917 /* condition_expression +-> trueLabel -> _while_boby_n */
4919 /* +-> falseLabel -> _while_break_n */
4920 /* _while_body_n: */
4922 /* goto _while_continue_n */
4923 /* _while_break_n: */
4924 /*-----------------------------------------------------------------*/
4926 createWhile (symbol * trueLabel, symbol * continueLabel,
4927 symbol * falseLabel, ast * condExpr, ast * whileBody)
4931 /* put the continue label */
4932 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4933 condExpr = createLabel (continueLabel, condExpr);
4934 condExpr->lineno = 0;
4936 /* put the body label in front of the body */
4937 whileBody = createLabel (trueLabel, whileBody);
4938 whileBody->lineno = 0;
4939 /* put a jump to continue at the end of the body */
4940 /* and put break label at the end of the body */
4941 whileBody = newNode (NULLOP,
4944 newAst_VALUE (symbolVal (continueLabel)),
4945 createLabel (falseLabel, NULL)));
4947 /* put it all together */
4948 if (IS_IFX (condExpr))
4949 whileTree = condExpr;
4952 whileTree = newNode (IFX, condExpr, NULL);
4953 /* put the true & false labels in place */
4954 whileTree->trueLabel = trueLabel;
4955 whileTree->falseLabel = falseLabel;
4958 return newNode (NULLOP, whileTree, whileBody);
4961 /*-----------------------------------------------------------------*/
4962 /* isShiftRightLitVal _BitAndLitVal - helper function */
4963 /*-----------------------------------------------------------------*/
4965 isShiftRightLitVal_BitAndLitVal (ast * tree)
4967 /* if this is not a bit and */
4968 if (!IS_BITAND (tree))
4971 /* will look for tree of the form
4972 ( expr >> litval2) & litval1 */
4973 if (!IS_AST_LIT_VALUE (tree->right))
4976 if (!IS_RIGHT_OP (tree->left))
4979 if (!IS_AST_LIT_VALUE (tree->left->right))
4982 return tree->left->left;
4985 /*-----------------------------------------------------------------*/
4986 /* isBitAndPowOf2 - helper function */
4987 /*-----------------------------------------------------------------*/
4989 isBitAndPow2 (ast * tree)
4993 /* if this is not a bit and */
4994 if (!IS_BITAND (tree))
4997 /* will look for tree of the form
4998 ( expr & (1 << litval) */
4999 if (!IS_AST_LIT_VALUE (tree->right))
5002 if (AST_LIT_VALUE (tree->right) == 1)
5004 p2 = powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5011 /*-----------------------------------------------------------------*/
5012 /* optimizeGetHbit - get highest order bit of the expression */
5013 /*-----------------------------------------------------------------*/
5015 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5020 expr = isShiftRightLitVal_BitAndLitVal(tree);
5023 if ((AST_LIT_VALUE (tree->right) != 1) ||
5024 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5025 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5028 if (!expr && (resultType == RESULT_TYPE_BIT))
5031 if (isBitAndPow2 (tree) != getSize (TTYPE (expr)) * 8 - 1)
5037 /* make sure the port supports GETHBIT */
5038 if (port->hasExtBitOp
5039 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5042 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5045 /*-----------------------------------------------------------------*/
5046 /* optimizeGetAbit - get a single bit of the expression */
5047 /*-----------------------------------------------------------------*/
5049 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5054 expr = isShiftRightLitVal_BitAndLitVal(tree);
5057 if (AST_LIT_VALUE (tree->right) != 1)
5059 count = tree->left->right;
5061 if (!expr && (resultType == RESULT_TYPE_BIT))
5063 int p2 = isBitAndPow2 (tree);
5067 count = newAst_VALUE (valueFromLit (p2));
5073 /* make sure the port supports GETABIT */
5074 if (port->hasExtBitOp
5075 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5078 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5082 /*-----------------------------------------------------------------*/
5083 /* optimizeGetByte - get a byte of the expression */
5084 /*-----------------------------------------------------------------*/
5086 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5092 expr = isShiftRightLitVal_BitAndLitVal(tree);
5095 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5096 count = tree->left->right;
5097 if (AST_LIT_VALUE (tree->right) != 0xFF)
5100 if (!expr && resultType == RESULT_TYPE_CHAR)
5102 /* if this is a right shift over a multiple of 8 */
5103 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5105 i = (unsigned int) AST_LIT_VALUE (tree->right);
5106 count = tree->right;
5110 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5113 /* make sure the port supports GETBYTE */
5114 if (port->hasExtBitOp
5115 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5118 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5121 /*-----------------------------------------------------------------*/
5122 /* optimizeGetWord - get two bytes of the expression */
5123 /*-----------------------------------------------------------------*/
5125 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5131 expr = isShiftRightLitVal_BitAndLitVal(tree);
5134 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5135 count = tree->left->right;
5136 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5139 if (!expr && resultType == RESULT_TYPE_INT)
5141 /* if this is a right shift over a multiple of 8 */
5142 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5144 i = (unsigned int) AST_LIT_VALUE (tree->right);
5145 count = tree->right;
5149 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5152 /* make sure the port supports GETWORD */
5153 if (port->hasExtBitOp
5154 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5157 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5160 /*-----------------------------------------------------------------*/
5161 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5162 /*-----------------------------------------------------------------*/
5164 optimizeRRCRLC (ast * root)
5166 /* will look for trees of the form
5167 (?expr << 1) | (?expr >> 7) or
5168 (?expr >> 7) | (?expr << 1) will make that
5169 into a RLC : operation ..
5171 (?expr >> 1) | (?expr << 7) or
5172 (?expr << 7) | (?expr >> 1) will make that
5173 into a RRC operation
5174 note : by 7 I mean (number of bits required to hold the
5176 /* if the root operations is not a | operation the not */
5177 if (!IS_BITOR (root))
5180 /* I have to think of a better way to match patterns this sucks */
5181 /* that aside let start looking for the first case : I use a the
5182 negative check a lot to improve the efficiency */
5183 /* (?expr << 1) | (?expr >> 7) */
5184 if (IS_LEFT_OP (root->left) &&
5185 IS_RIGHT_OP (root->right))
5188 if (!SPEC_USIGN (TETYPE (root->left->left)))
5191 if (!IS_AST_LIT_VALUE (root->left->right) ||
5192 !IS_AST_LIT_VALUE (root->right->right))
5195 /* make sure it is the same expression */
5196 if (!isAstEqual (root->left->left,
5200 if (AST_LIT_VALUE (root->left->right) != 1)
5203 if (AST_LIT_VALUE (root->right->right) !=
5204 (getSize (TTYPE (root->left->left)) * 8 - 1))
5207 /* make sure the port supports RLC */
5208 if (port->hasExtBitOp
5209 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5212 /* whew got the first case : create the AST */
5213 return newNode (RLC, root->left->left, NULL);
5217 /* check for second case */
5218 /* (?expr >> 7) | (?expr << 1) */
5219 if (IS_LEFT_OP (root->right) &&
5220 IS_RIGHT_OP (root->left))
5223 if (!SPEC_USIGN (TETYPE (root->left->left)))
5226 if (!IS_AST_LIT_VALUE (root->left->right) ||
5227 !IS_AST_LIT_VALUE (root->right->right))
5230 /* make sure it is the same symbol */
5231 if (!isAstEqual (root->left->left,
5235 if (AST_LIT_VALUE (root->right->right) != 1)
5238 if (AST_LIT_VALUE (root->left->right) !=
5239 (getSize (TTYPE (root->left->left)) * 8 - 1))
5242 /* make sure the port supports RLC */
5243 if (port->hasExtBitOp
5244 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5247 /* whew got the first case : create the AST */
5248 return newNode (RLC, root->left->left, NULL);
5253 /* third case for RRC */
5254 /* (?symbol >> 1) | (?symbol << 7) */
5255 if (IS_LEFT_OP (root->right) &&
5256 IS_RIGHT_OP (root->left))
5259 if (!SPEC_USIGN (TETYPE (root->left->left)))
5262 if (!IS_AST_LIT_VALUE (root->left->right) ||
5263 !IS_AST_LIT_VALUE (root->right->right))
5266 /* make sure it is the same symbol */
5267 if (!isAstEqual (root->left->left,
5271 if (AST_LIT_VALUE (root->left->right) != 1)
5274 if (AST_LIT_VALUE (root->right->right) !=
5275 (getSize (TTYPE (root->left->left)) * 8 - 1))
5278 /* make sure the port supports RRC */
5279 if (port->hasExtBitOp
5280 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5283 /* whew got the first case : create the AST */
5284 return newNode (RRC, root->left->left, NULL);
5288 /* fourth and last case for now */
5289 /* (?symbol << 7) | (?symbol >> 1) */
5290 if (IS_RIGHT_OP (root->right) &&
5291 IS_LEFT_OP (root->left))
5294 if (!SPEC_USIGN (TETYPE (root->left->left)))
5297 if (!IS_AST_LIT_VALUE (root->left->right) ||
5298 !IS_AST_LIT_VALUE (root->right->right))
5301 /* make sure it is the same symbol */
5302 if (!isAstEqual (root->left->left,
5306 if (AST_LIT_VALUE (root->right->right) != 1)
5309 if (AST_LIT_VALUE (root->left->right) !=
5310 (getSize (TTYPE (root->left->left)) * 8 - 1))
5313 /* make sure the port supports RRC */
5314 if (port->hasExtBitOp
5315 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5318 /* whew got the first case : create the AST */
5319 return newNode (RRC, root->left->left, NULL);
5323 /* not found return root */
5327 /*-----------------------------------------------------------------*/
5328 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5329 /*-----------------------------------------------------------------*/
5331 optimizeSWAP (ast * root)
5333 /* will look for trees of the form
5334 (?expr << 4) | (?expr >> 4) or
5335 (?expr >> 4) | (?expr << 4) will make that
5336 into a SWAP : operation ..
5337 note : by 4 I mean (number of bits required to hold the
5339 /* if the root operations is not a | operation the not */
5340 if (!IS_BITOR (root))
5343 /* (?expr << 4) | (?expr >> 4) */
5344 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5345 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5348 if (!SPEC_USIGN (TETYPE (root->left->left)))
5351 if (!IS_AST_LIT_VALUE (root->left->right) ||
5352 !IS_AST_LIT_VALUE (root->right->right))
5355 /* make sure it is the same expression */
5356 if (!isAstEqual (root->left->left,
5360 if (AST_LIT_VALUE (root->left->right) !=
5361 (getSize (TTYPE (root->left->left)) * 4))
5364 if (AST_LIT_VALUE (root->right->right) !=
5365 (getSize (TTYPE (root->left->left)) * 4))
5368 /* make sure the port supports SWAP */
5369 if (port->hasExtBitOp
5370 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5373 /* found it : create the AST */
5374 return newNode (SWAP, root->left->left, NULL);
5378 /* not found return root */
5382 /*-----------------------------------------------------------------*/
5383 /* optimizeCompare - optimizes compares for bit variables */
5384 /*-----------------------------------------------------------------*/
5386 optimizeCompare (ast * root)
5388 ast *optExpr = NULL;
5391 unsigned int litValue;
5393 /* if nothing then return nothing */
5397 /* if not a compare op then do leaves */
5398 if (!IS_COMPARE_OP (root))
5400 root->left = optimizeCompare (root->left);
5401 root->right = optimizeCompare (root->right);
5405 /* if left & right are the same then depending
5406 of the operation do */
5407 if (isAstEqual (root->left, root->right))
5409 switch (root->opval.op)
5414 optExpr = newAst_VALUE (constVal ("0"));
5419 optExpr = newAst_VALUE (constVal ("1"));
5423 return decorateType (optExpr, RESULT_TYPE_NONE);
5426 vleft = (root->left->type == EX_VALUE ?
5427 root->left->opval.val : NULL);
5429 vright = (root->right->type == EX_VALUE ?
5430 root->right->opval.val : NULL);
5432 /* if left is a BITVAR in BITSPACE */
5433 /* and right is a LITERAL then opt- */
5434 /* imize else do nothing */
5435 if (vleft && vright &&
5436 IS_BITVAR (vleft->etype) &&
5437 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5438 IS_LITERAL (vright->etype))
5441 /* if right side > 1 then comparison may never succeed */
5442 if ((litValue = (int) floatFromVal (vright)) > 1)
5444 werror (W_BAD_COMPARE);
5450 switch (root->opval.op)
5452 case '>': /* bit value greater than 1 cannot be */
5453 werror (W_BAD_COMPARE);
5457 case '<': /* bit value < 1 means 0 */
5459 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5462 case LE_OP: /* bit value <= 1 means no check */
5463 optExpr = newAst_VALUE (vright);
5466 case GE_OP: /* bit value >= 1 means only check for = */
5468 optExpr = newAst_VALUE (vleft);
5473 { /* literal is zero */
5474 switch (root->opval.op)
5476 case '<': /* bit value < 0 cannot be */
5477 werror (W_BAD_COMPARE);
5481 case '>': /* bit value > 0 means 1 */
5483 optExpr = newAst_VALUE (vleft);
5486 case LE_OP: /* bit value <= 0 means no check */
5487 case GE_OP: /* bit value >= 0 means no check */
5488 werror (W_BAD_COMPARE);
5492 case EQ_OP: /* bit == 0 means ! of bit */
5493 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5497 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5498 } /* end-of-if of BITVAR */
5503 /*-----------------------------------------------------------------*/
5504 /* addSymToBlock : adds the symbol to the first block we find */
5505 /*-----------------------------------------------------------------*/
5507 addSymToBlock (symbol * sym, ast * tree)
5509 /* reached end of tree or a leaf */
5510 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5514 if (IS_AST_OP (tree) &&
5515 tree->opval.op == BLOCK)
5518 symbol *lsym = copySymbol (sym);
5520 lsym->next = AST_VALUES (tree, sym);
5521 AST_VALUES (tree, sym) = lsym;
5525 addSymToBlock (sym, tree->left);
5526 addSymToBlock (sym, tree->right);
5529 /*-----------------------------------------------------------------*/
5530 /* processRegParms - do processing for register parameters */
5531 /*-----------------------------------------------------------------*/
5533 processRegParms (value * args, ast * body)
5537 if (IS_REGPARM (args->etype))
5538 addSymToBlock (args->sym, body);
5543 /*-----------------------------------------------------------------*/
5544 /* resetParmKey - resets the operandkeys for the symbols */
5545 /*-----------------------------------------------------------------*/
5546 DEFSETFUNC (resetParmKey)
5557 /*-----------------------------------------------------------------*/
5558 /* createFunction - This is the key node that calls the iCode for */
5559 /* generating the code for a function. Note code */
5560 /* is generated function by function, later when */
5561 /* add inter-procedural analysis this will change */
5562 /*-----------------------------------------------------------------*/
5564 createFunction (symbol * name, ast * body)
5570 iCode *piCode = NULL;
5572 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5573 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5575 /* if check function return 0 then some problem */
5576 if (checkFunction (name, NULL) == 0)
5579 /* create a dummy block if none exists */
5581 body = newNode (BLOCK, NULL, NULL);
5585 /* check if the function name already in the symbol table */
5586 if ((csym = findSym (SymbolTab, NULL, name->name)))
5589 /* special case for compiler defined functions
5590 we need to add the name to the publics list : this
5591 actually means we are now compiling the compiler
5595 addSet (&publics, name);
5600 addSymChain (&name);
5601 allocVariables (name);
5603 name->lastLine = mylineno;
5606 /* set the stack pointer */
5607 stackPtr = -port->stack.direction * port->stack.call_overhead;
5610 if (IFFUNC_ISISR (name->type))
5611 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5613 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5615 if (options.useXstack)
5616 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5618 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5621 fetype = getSpec (name->type); /* get the specifier for the function */
5622 /* if this is a reentrant function then */
5623 if (IFFUNC_ISREENT (name->type))
5626 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5628 /* do processing for parameters that are passed in registers */
5629 processRegParms (FUNC_ARGS(name->type), body);
5631 /* set the stack pointer */
5635 /* allocate & autoinit the block variables */
5636 processBlockVars (body, &stack, ALLOCATE);
5638 /* save the stack information */
5639 if (options.useXstack)
5640 name->xstack = SPEC_STAK (fetype) = stack;
5642 name->stack = SPEC_STAK (fetype) = stack;
5644 /* name needs to be mangled */
5645 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5647 body = resolveSymbols (body); /* resolve the symbols */
5648 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5651 ex = newAst_VALUE (symbolVal (name)); /* create name */
5652 ex = newNode (FUNCTION, ex, body);
5653 ex->values.args = FUNC_ARGS(name->type);
5655 if (options.dump_tree) PA(ex);
5658 werror (E_FUNC_NO_CODE, name->name);
5662 /* create the node & generate intermediate code */
5664 codeOutFile = code->oFile;
5665 piCode = iCodeFromAst (ex);
5669 werror (E_FUNC_NO_CODE, name->name);
5673 eBBlockFromiCode (piCode);
5675 /* if there are any statics then do them */
5678 GcurMemmap = statsg;
5679 codeOutFile = statsg->oFile;
5680 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5686 /* dealloc the block variables */
5687 processBlockVars (body, &stack, DEALLOCATE);
5688 outputDebugStackSymbols();
5689 /* deallocate paramaters */
5690 deallocParms (FUNC_ARGS(name->type));
5692 if (IFFUNC_ISREENT (name->type))
5695 /* we are done freeup memory & cleanup */
5697 if (port->reset_labelKey) labelKey = 1;
5699 FUNC_HASBODY(name->type) = 1;
5700 addSet (&operKeyReset, name);
5701 applyToSet (operKeyReset, resetParmKey);
5706 cleanUpLevel (LabelTab, 0);
5707 cleanUpBlock (StructTab, 1);
5708 cleanUpBlock (TypedefTab, 1);
5710 xstack->syms = NULL;
5711 istack->syms = NULL;
5716 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5717 /*-----------------------------------------------------------------*/
5718 /* ast_print : prints the ast (for debugging purposes) */
5719 /*-----------------------------------------------------------------*/
5721 void ast_print (ast * tree, FILE *outfile, int indent)
5726 /* can print only decorated trees */
5727 if (!tree->decorated) return;
5729 /* if any child is an error | this one is an error do nothing */
5730 if (tree->isError ||
5731 (tree->left && tree->left->isError) ||
5732 (tree->right && tree->right->isError)) {
5733 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5737 /* print the line */
5738 /* if not block & function */
5739 if (tree->type == EX_OP &&
5740 (tree->opval.op != FUNCTION &&
5741 tree->opval.op != BLOCK &&
5742 tree->opval.op != NULLOP)) {
5745 if (tree->opval.op == FUNCTION) {
5747 value *args=FUNC_ARGS(tree->left->opval.val->type);
5748 fprintf(outfile,"FUNCTION (%s=%p) type (",
5749 tree->left->opval.val->name, tree);
5750 printTypeChain (tree->left->opval.val->type->next,outfile);
5751 fprintf(outfile,") args (");
5754 fprintf (outfile, ", ");
5756 printTypeChain (args ? args->type : NULL, outfile);
5758 args= args ? args->next : NULL;
5760 fprintf(outfile,")\n");
5761 ast_print(tree->left,outfile,indent);
5762 ast_print(tree->right,outfile,indent);
5765 if (tree->opval.op == BLOCK) {
5766 symbol *decls = tree->values.sym;
5767 INDENT(indent,outfile);
5768 fprintf(outfile,"{\n");
5770 INDENT(indent+2,outfile);
5771 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5772 decls->name, decls);
5773 printTypeChain(decls->type,outfile);
5774 fprintf(outfile,")\n");
5776 decls = decls->next;
5778 ast_print(tree->right,outfile,indent+2);
5779 INDENT(indent,outfile);
5780 fprintf(outfile,"}\n");
5783 if (tree->opval.op == NULLOP) {
5784 ast_print(tree->left,outfile,indent);
5785 ast_print(tree->right,outfile,indent);
5788 INDENT(indent,outfile);
5790 /*------------------------------------------------------------------*/
5791 /*----------------------------*/
5792 /* leaf has been reached */
5793 /*----------------------------*/
5794 /* if this is of type value */
5795 /* just get the type */
5796 if (tree->type == EX_VALUE) {
5798 if (IS_LITERAL (tree->opval.val->etype)) {
5799 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5800 if (SPEC_USIGN (tree->opval.val->etype))
5801 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5803 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5804 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5805 floatFromVal(tree->opval.val));
5806 } else if (tree->opval.val->sym) {
5807 /* if the undefined flag is set then give error message */
5808 if (tree->opval.val->sym->undefined) {
5809 fprintf(outfile,"UNDEFINED SYMBOL ");
5811 fprintf(outfile,"SYMBOL ");
5813 fprintf(outfile,"(%s=%p)",
5814 tree->opval.val->sym->name,tree);
5817 fprintf(outfile," type (");
5818 printTypeChain(tree->ftype,outfile);
5819 fprintf(outfile,")\n");
5821 fprintf(outfile,"\n");
5826 /* if type link for the case of cast */
5827 if (tree->type == EX_LINK) {
5828 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5829 printTypeChain(tree->opval.lnk,outfile);
5830 fprintf(outfile,")\n");
5835 /* depending on type of operator do */
5837 switch (tree->opval.op) {
5838 /*------------------------------------------------------------------*/
5839 /*----------------------------*/
5841 /*----------------------------*/
5843 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5844 printTypeChain(tree->ftype,outfile);
5845 fprintf(outfile,")\n");
5846 ast_print(tree->left,outfile,indent+2);
5847 ast_print(tree->right,outfile,indent+2);
5850 /*------------------------------------------------------------------*/
5851 /*----------------------------*/
5853 /*----------------------------*/
5855 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5856 printTypeChain(tree->ftype,outfile);
5857 fprintf(outfile,")\n");
5858 ast_print(tree->left,outfile,indent+2);
5859 ast_print(tree->right,outfile,indent+2);
5862 /*------------------------------------------------------------------*/
5863 /*----------------------------*/
5864 /* struct/union pointer */
5865 /*----------------------------*/
5867 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5868 printTypeChain(tree->ftype,outfile);
5869 fprintf(outfile,")\n");
5870 ast_print(tree->left,outfile,indent+2);
5871 ast_print(tree->right,outfile,indent+2);
5874 /*------------------------------------------------------------------*/
5875 /*----------------------------*/
5876 /* ++/-- operation */
5877 /*----------------------------*/
5880 fprintf(outfile,"post-");
5882 fprintf(outfile,"pre-");
5883 fprintf(outfile,"INC_OP (%p) type (",tree);
5884 printTypeChain(tree->ftype,outfile);
5885 fprintf(outfile,")\n");
5886 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5887 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5892 fprintf(outfile,"post-");
5894 fprintf(outfile,"pre-");
5895 fprintf(outfile,"DEC_OP (%p) type (",tree);
5896 printTypeChain(tree->ftype,outfile);
5897 fprintf(outfile,")\n");
5898 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5899 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5902 /*------------------------------------------------------------------*/
5903 /*----------------------------*/
5905 /*----------------------------*/
5908 fprintf(outfile,"& (%p) type (",tree);
5909 printTypeChain(tree->ftype,outfile);
5910 fprintf(outfile,")\n");
5911 ast_print(tree->left,outfile,indent+2);
5912 ast_print(tree->right,outfile,indent+2);
5914 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5915 printTypeChain(tree->ftype,outfile);
5916 fprintf(outfile,")\n");
5917 ast_print(tree->left,outfile,indent+2);
5918 ast_print(tree->right,outfile,indent+2);
5921 /*----------------------------*/
5923 /*----------------------------*/
5925 fprintf(outfile,"OR (%p) type (",tree);
5926 printTypeChain(tree->ftype,outfile);
5927 fprintf(outfile,")\n");
5928 ast_print(tree->left,outfile,indent+2);
5929 ast_print(tree->right,outfile,indent+2);
5931 /*------------------------------------------------------------------*/
5932 /*----------------------------*/
5934 /*----------------------------*/
5936 fprintf(outfile,"XOR (%p) type (",tree);
5937 printTypeChain(tree->ftype,outfile);
5938 fprintf(outfile,")\n");
5939 ast_print(tree->left,outfile,indent+2);
5940 ast_print(tree->right,outfile,indent+2);
5943 /*------------------------------------------------------------------*/
5944 /*----------------------------*/
5946 /*----------------------------*/
5948 fprintf(outfile,"DIV (%p) type (",tree);
5949 printTypeChain(tree->ftype,outfile);
5950 fprintf(outfile,")\n");
5951 ast_print(tree->left,outfile,indent+2);
5952 ast_print(tree->right,outfile,indent+2);
5954 /*------------------------------------------------------------------*/
5955 /*----------------------------*/
5957 /*----------------------------*/
5959 fprintf(outfile,"MOD (%p) type (",tree);
5960 printTypeChain(tree->ftype,outfile);
5961 fprintf(outfile,")\n");
5962 ast_print(tree->left,outfile,indent+2);
5963 ast_print(tree->right,outfile,indent+2);
5966 /*------------------------------------------------------------------*/
5967 /*----------------------------*/
5968 /* address dereference */
5969 /*----------------------------*/
5970 case '*': /* can be unary : if right is null then unary operation */
5972 fprintf(outfile,"DEREF (%p) type (",tree);
5973 printTypeChain(tree->ftype,outfile);
5974 fprintf(outfile,")\n");
5975 ast_print(tree->left,outfile,indent+2);
5978 /*------------------------------------------------------------------*/
5979 /*----------------------------*/
5980 /* multiplication */
5981 /*----------------------------*/
5982 fprintf(outfile,"MULT (%p) type (",tree);
5983 printTypeChain(tree->ftype,outfile);
5984 fprintf(outfile,")\n");
5985 ast_print(tree->left,outfile,indent+2);
5986 ast_print(tree->right,outfile,indent+2);
5990 /*------------------------------------------------------------------*/
5991 /*----------------------------*/
5992 /* unary '+' operator */
5993 /*----------------------------*/
5997 fprintf(outfile,"UPLUS (%p) type (",tree);
5998 printTypeChain(tree->ftype,outfile);
5999 fprintf(outfile,")\n");
6000 ast_print(tree->left,outfile,indent+2);
6002 /*------------------------------------------------------------------*/
6003 /*----------------------------*/
6005 /*----------------------------*/
6006 fprintf(outfile,"ADD (%p) type (",tree);
6007 printTypeChain(tree->ftype,outfile);
6008 fprintf(outfile,")\n");
6009 ast_print(tree->left,outfile,indent+2);
6010 ast_print(tree->right,outfile,indent+2);
6013 /*------------------------------------------------------------------*/
6014 /*----------------------------*/
6016 /*----------------------------*/
6017 case '-': /* can be unary */
6019 fprintf(outfile,"UMINUS (%p) type (",tree);
6020 printTypeChain(tree->ftype,outfile);
6021 fprintf(outfile,")\n");
6022 ast_print(tree->left,outfile,indent+2);
6024 /*------------------------------------------------------------------*/
6025 /*----------------------------*/
6027 /*----------------------------*/
6028 fprintf(outfile,"SUB (%p) type (",tree);
6029 printTypeChain(tree->ftype,outfile);
6030 fprintf(outfile,")\n");
6031 ast_print(tree->left,outfile,indent+2);
6032 ast_print(tree->right,outfile,indent+2);
6035 /*------------------------------------------------------------------*/
6036 /*----------------------------*/
6038 /*----------------------------*/
6040 fprintf(outfile,"COMPL (%p) type (",tree);
6041 printTypeChain(tree->ftype,outfile);
6042 fprintf(outfile,")\n");
6043 ast_print(tree->left,outfile,indent+2);
6045 /*------------------------------------------------------------------*/
6046 /*----------------------------*/
6048 /*----------------------------*/
6050 fprintf(outfile,"NOT (%p) type (",tree);
6051 printTypeChain(tree->ftype,outfile);
6052 fprintf(outfile,")\n");
6053 ast_print(tree->left,outfile,indent+2);
6055 /*------------------------------------------------------------------*/
6056 /*----------------------------*/
6058 /*----------------------------*/
6060 fprintf(outfile,"RRC (%p) type (",tree);
6061 printTypeChain(tree->ftype,outfile);
6062 fprintf(outfile,")\n");
6063 ast_print(tree->left,outfile,indent+2);
6067 fprintf(outfile,"RLC (%p) type (",tree);
6068 printTypeChain(tree->ftype,outfile);
6069 fprintf(outfile,")\n");
6070 ast_print(tree->left,outfile,indent+2);
6073 fprintf(outfile,"SWAP (%p) type (",tree);
6074 printTypeChain(tree->ftype,outfile);
6075 fprintf(outfile,")\n");
6076 ast_print(tree->left,outfile,indent+2);
6079 fprintf(outfile,"GETHBIT (%p) type (",tree);
6080 printTypeChain(tree->ftype,outfile);
6081 fprintf(outfile,")\n");
6082 ast_print(tree->left,outfile,indent+2);
6085 fprintf(outfile,"GETABIT (%p) type (",tree);
6086 printTypeChain(tree->ftype,outfile);
6087 fprintf(outfile,")\n");
6088 ast_print(tree->left,outfile,indent+2);
6089 ast_print(tree->right,outfile,indent+2);
6092 fprintf(outfile,"GETBYTE (%p) type (",tree);
6093 printTypeChain(tree->ftype,outfile);
6094 fprintf(outfile,")\n");
6095 ast_print(tree->left,outfile,indent+2);
6096 ast_print(tree->right,outfile,indent+2);
6099 fprintf(outfile,"GETWORD (%p) type (",tree);
6100 printTypeChain(tree->ftype,outfile);
6101 fprintf(outfile,")\n");
6102 ast_print(tree->left,outfile,indent+2);
6103 ast_print(tree->right,outfile,indent+2);
6106 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6107 printTypeChain(tree->ftype,outfile);
6108 fprintf(outfile,")\n");
6109 ast_print(tree->left,outfile,indent+2);
6110 ast_print(tree->right,outfile,indent+2);
6113 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6114 printTypeChain(tree->ftype,outfile);
6115 fprintf(outfile,")\n");
6116 ast_print(tree->left,outfile,indent+2);
6117 ast_print(tree->right,outfile,indent+2);
6119 /*------------------------------------------------------------------*/
6120 /*----------------------------*/
6122 /*----------------------------*/
6123 case CAST: /* change the type */
6124 fprintf(outfile,"CAST (%p) from type (",tree);
6125 printTypeChain(tree->right->ftype,outfile);
6126 fprintf(outfile,") to type (");
6127 printTypeChain(tree->ftype,outfile);
6128 fprintf(outfile,")\n");
6129 ast_print(tree->right,outfile,indent+2);
6133 fprintf(outfile,"ANDAND (%p) type (",tree);
6134 printTypeChain(tree->ftype,outfile);
6135 fprintf(outfile,")\n");
6136 ast_print(tree->left,outfile,indent+2);
6137 ast_print(tree->right,outfile,indent+2);
6140 fprintf(outfile,"OROR (%p) type (",tree);
6141 printTypeChain(tree->ftype,outfile);
6142 fprintf(outfile,")\n");
6143 ast_print(tree->left,outfile,indent+2);
6144 ast_print(tree->right,outfile,indent+2);
6147 /*------------------------------------------------------------------*/
6148 /*----------------------------*/
6149 /* comparison operators */
6150 /*----------------------------*/
6152 fprintf(outfile,"GT(>) (%p) type (",tree);
6153 printTypeChain(tree->ftype,outfile);
6154 fprintf(outfile,")\n");
6155 ast_print(tree->left,outfile,indent+2);
6156 ast_print(tree->right,outfile,indent+2);
6159 fprintf(outfile,"LT(<) (%p) type (",tree);
6160 printTypeChain(tree->ftype,outfile);
6161 fprintf(outfile,")\n");
6162 ast_print(tree->left,outfile,indent+2);
6163 ast_print(tree->right,outfile,indent+2);
6166 fprintf(outfile,"LE(<=) (%p) type (",tree);
6167 printTypeChain(tree->ftype,outfile);
6168 fprintf(outfile,")\n");
6169 ast_print(tree->left,outfile,indent+2);
6170 ast_print(tree->right,outfile,indent+2);
6173 fprintf(outfile,"GE(>=) (%p) type (",tree);
6174 printTypeChain(tree->ftype,outfile);
6175 fprintf(outfile,")\n");
6176 ast_print(tree->left,outfile,indent+2);
6177 ast_print(tree->right,outfile,indent+2);
6180 fprintf(outfile,"EQ(==) (%p) type (",tree);
6181 printTypeChain(tree->ftype,outfile);
6182 fprintf(outfile,")\n");
6183 ast_print(tree->left,outfile,indent+2);
6184 ast_print(tree->right,outfile,indent+2);
6187 fprintf(outfile,"NE(!=) (%p) type (",tree);
6188 printTypeChain(tree->ftype,outfile);
6189 fprintf(outfile,")\n");
6190 ast_print(tree->left,outfile,indent+2);
6191 ast_print(tree->right,outfile,indent+2);
6192 /*------------------------------------------------------------------*/
6193 /*----------------------------*/
6195 /*----------------------------*/
6196 case SIZEOF: /* evaluate wihout code generation */
6197 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6200 /*------------------------------------------------------------------*/
6201 /*----------------------------*/
6202 /* conditional operator '?' */
6203 /*----------------------------*/
6205 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6206 printTypeChain(tree->ftype,outfile);
6207 fprintf(outfile,")\n");
6208 ast_print(tree->left,outfile,indent+2);
6209 ast_print(tree->right,outfile,indent+2);
6213 fprintf(outfile,"COLON(:) (%p) type (",tree);
6214 printTypeChain(tree->ftype,outfile);
6215 fprintf(outfile,")\n");
6216 ast_print(tree->left,outfile,indent+2);
6217 ast_print(tree->right,outfile,indent+2);
6220 /*------------------------------------------------------------------*/
6221 /*----------------------------*/
6222 /* assignment operators */
6223 /*----------------------------*/
6225 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6226 printTypeChain(tree->ftype,outfile);
6227 fprintf(outfile,")\n");
6228 ast_print(tree->left,outfile,indent+2);
6229 ast_print(tree->right,outfile,indent+2);
6232 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6233 printTypeChain(tree->ftype,outfile);
6234 fprintf(outfile,")\n");
6235 ast_print(tree->left,outfile,indent+2);
6236 ast_print(tree->right,outfile,indent+2);
6239 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6240 printTypeChain(tree->ftype,outfile);
6241 fprintf(outfile,")\n");
6242 ast_print(tree->left,outfile,indent+2);
6243 ast_print(tree->right,outfile,indent+2);
6246 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6247 printTypeChain(tree->ftype,outfile);
6248 fprintf(outfile,")\n");
6249 ast_print(tree->left,outfile,indent+2);
6250 ast_print(tree->right,outfile,indent+2);
6253 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6254 printTypeChain(tree->ftype,outfile);
6255 fprintf(outfile,")\n");
6256 ast_print(tree->left,outfile,indent+2);
6257 ast_print(tree->right,outfile,indent+2);
6260 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6261 printTypeChain(tree->ftype,outfile);
6262 fprintf(outfile,")\n");
6263 ast_print(tree->left,outfile,indent+2);
6264 ast_print(tree->right,outfile,indent+2);
6267 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6268 printTypeChain(tree->ftype,outfile);
6269 fprintf(outfile,")\n");
6270 ast_print(tree->left,outfile,indent+2);
6271 ast_print(tree->right,outfile,indent+2);
6273 /*------------------------------------------------------------------*/
6274 /*----------------------------*/
6276 /*----------------------------*/
6278 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6279 printTypeChain(tree->ftype,outfile);
6280 fprintf(outfile,")\n");
6281 ast_print(tree->left,outfile,indent+2);
6282 ast_print(tree->right,outfile,indent+2);
6284 /*------------------------------------------------------------------*/
6285 /*----------------------------*/
6287 /*----------------------------*/
6289 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6290 printTypeChain(tree->ftype,outfile);
6291 fprintf(outfile,")\n");
6292 ast_print(tree->left,outfile,indent+2);
6293 ast_print(tree->right,outfile,indent+2);
6295 /*------------------------------------------------------------------*/
6296 /*----------------------------*/
6297 /* straight assignemnt */
6298 /*----------------------------*/
6300 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6301 printTypeChain(tree->ftype,outfile);
6302 fprintf(outfile,")\n");
6303 ast_print(tree->left,outfile,indent+2);
6304 ast_print(tree->right,outfile,indent+2);
6306 /*------------------------------------------------------------------*/
6307 /*----------------------------*/
6308 /* comma operator */
6309 /*----------------------------*/
6311 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6312 printTypeChain(tree->ftype,outfile);
6313 fprintf(outfile,")\n");
6314 ast_print(tree->left,outfile,indent+2);
6315 ast_print(tree->right,outfile,indent+2);
6317 /*------------------------------------------------------------------*/
6318 /*----------------------------*/
6320 /*----------------------------*/
6323 fprintf(outfile,"CALL (%p) type (",tree);
6324 printTypeChain(tree->ftype,outfile);
6325 fprintf(outfile,")\n");
6326 ast_print(tree->left,outfile,indent+2);
6327 ast_print(tree->right,outfile,indent+2);
6330 fprintf(outfile,"PARMS\n");
6331 ast_print(tree->left,outfile,indent+2);
6332 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6333 ast_print(tree->right,outfile,indent+2);
6336 /*------------------------------------------------------------------*/
6337 /*----------------------------*/
6338 /* return statement */
6339 /*----------------------------*/
6341 fprintf(outfile,"RETURN (%p) type (",tree);
6343 printTypeChain(tree->right->ftype,outfile);
6345 fprintf(outfile,")\n");
6346 ast_print(tree->right,outfile,indent+2);
6348 /*------------------------------------------------------------------*/
6349 /*----------------------------*/
6350 /* label statement */
6351 /*----------------------------*/
6353 fprintf(outfile,"LABEL (%p)\n",tree);
6354 ast_print(tree->left,outfile,indent+2);
6355 ast_print(tree->right,outfile,indent);
6357 /*------------------------------------------------------------------*/
6358 /*----------------------------*/
6359 /* switch statement */
6360 /*----------------------------*/
6364 fprintf(outfile,"SWITCH (%p) ",tree);
6365 ast_print(tree->left,outfile,0);
6366 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6367 INDENT(indent+2,outfile);
6368 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6369 (int) floatFromVal(val),
6370 tree->values.switchVals.swNum,
6371 (int) floatFromVal(val));
6373 ast_print(tree->right,outfile,indent);
6376 /*------------------------------------------------------------------*/
6377 /*----------------------------*/
6379 /*----------------------------*/
6381 fprintf(outfile,"IF (%p) \n",tree);
6382 ast_print(tree->left,outfile,indent+2);
6383 if (tree->trueLabel) {
6384 INDENT(indent+2,outfile);
6385 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6387 if (tree->falseLabel) {
6388 INDENT(indent+2,outfile);
6389 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6391 ast_print(tree->right,outfile,indent+2);
6393 /*----------------------------*/
6394 /* goto Statement */
6395 /*----------------------------*/
6397 fprintf(outfile,"GOTO (%p) \n",tree);
6398 ast_print(tree->left,outfile,indent+2);
6399 fprintf(outfile,"\n");
6401 /*------------------------------------------------------------------*/
6402 /*----------------------------*/
6404 /*----------------------------*/
6406 fprintf(outfile,"FOR (%p) \n",tree);
6407 if (AST_FOR( tree, initExpr)) {
6408 INDENT(indent+2,outfile);
6409 fprintf(outfile,"INIT EXPR ");
6410 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6412 if (AST_FOR( tree, condExpr)) {
6413 INDENT(indent+2,outfile);
6414 fprintf(outfile,"COND EXPR ");
6415 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6417 if (AST_FOR( tree, loopExpr)) {
6418 INDENT(indent+2,outfile);
6419 fprintf(outfile,"LOOP EXPR ");
6420 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6422 fprintf(outfile,"FOR LOOP BODY \n");
6423 ast_print(tree->left,outfile,indent+2);
6426 fprintf(outfile,"CRITICAL (%p) \n",tree);
6427 ast_print(tree->left,outfile,indent+2);
6435 ast_print(t,stdout,0);
6440 /*-----------------------------------------------------------------*/
6441 /* astErrors : returns non-zero if errors present in tree */
6442 /*-----------------------------------------------------------------*/
6443 int astErrors(ast *t)
6452 if (t->type == EX_VALUE
6453 && t->opval.val->sym
6454 && t->opval.val->sym->undefined)
6457 errors += astErrors(t->left);
6458 errors += astErrors(t->right);