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 upcast)
2093 bool upCasted = FALSE;
2097 case RESULT_TYPE_NONE:
2098 /* char: promote to int */
2100 getSize (tree->etype) >= INTSIZE)
2102 newLink = newIntLink();
2105 case RESULT_TYPE_CHAR:
2106 if (IS_CHAR (tree->etype) ||
2107 IS_FLOAT(tree->etype) ||
2108 IS_FIXED(tree->etype))
2110 newLink = newCharLink();
2112 case RESULT_TYPE_INT:
2114 if (getSize (tree->etype) > INTSIZE)
2116 /* warn ("Loosing significant digits"); */
2120 /* char: promote to int */
2122 getSize (tree->etype) >= INTSIZE)
2124 newLink = newIntLink();
2127 case RESULT_TYPE_OTHER:
2130 /* return type is long, float: promote char to int */
2131 if (getSize (tree->etype) >= INTSIZE)
2133 newLink = newIntLink();
2139 tree->decorated = 0;
2140 tree = newNode (CAST, newAst_LINK (newLink), tree);
2141 tree->lineno = tree->right->lineno;
2142 /* keep unsigned type during cast to smaller type,
2143 but not when promoting from char to int */
2145 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2146 return decorateType (tree, resultType);
2149 /*-----------------------------------------------------------------*/
2150 /* resultTypePropagate - decides if resultType can be propagated */
2151 /*-----------------------------------------------------------------*/
2153 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2155 switch (tree->opval.op)
2174 return RESULT_TYPE_NONE;
2178 return RESULT_TYPE_IFX;
2180 return RESULT_TYPE_NONE;
2184 /*-----------------------------------------------------------------*/
2185 /* getLeftResultType - gets type from left branch for propagation */
2186 /*-----------------------------------------------------------------*/
2188 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2190 switch (tree->opval.op)
2194 if (IS_PTR (LTYPE (tree)))
2195 return RESULT_TYPE_NONE;
2197 return getResultTypeFromType (LETYPE (tree));
2199 if (IS_PTR (currFunc->type->next))
2200 return RESULT_TYPE_NONE;
2202 return getResultTypeFromType (currFunc->type->next);
2204 if (!IS_ARRAY (LTYPE (tree)))
2206 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2207 return RESULT_TYPE_CHAR;
2214 /*--------------------------------------------------------------------*/
2215 /* decorateType - compute type for this tree, also does type checking.*/
2216 /* This is done bottom up, since type has to flow upwards. */
2217 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2218 /* result is a char and the operand(s) are int's. */
2219 /* It also does constant folding, and parameter checking. */
2220 /*--------------------------------------------------------------------*/
2222 decorateType (ast * tree, RESULT_TYPE resultType)
2226 RESULT_TYPE resultTypeProp;
2231 /* if already has type then do nothing */
2232 if (tree->decorated)
2235 tree->decorated = 1;
2238 /* print the line */
2239 /* if not block & function */
2240 if (tree->type == EX_OP &&
2241 (tree->opval.op != FUNCTION &&
2242 tree->opval.op != BLOCK &&
2243 tree->opval.op != NULLOP))
2245 filename = tree->filename;
2246 lineno = tree->lineno;
2250 /* if any child is an error | this one is an error do nothing */
2251 if (tree->isError ||
2252 (tree->left && tree->left->isError) ||
2253 (tree->right && tree->right->isError))
2256 /*------------------------------------------------------------------*/
2257 /*----------------------------*/
2258 /* leaf has been reached */
2259 /*----------------------------*/
2260 lineno=tree->lineno;
2261 /* if this is of type value */
2262 /* just get the type */
2263 if (tree->type == EX_VALUE)
2266 if (IS_LITERAL (tree->opval.val->etype))
2269 /* if this is a character array then declare it */
2270 if (IS_ARRAY (tree->opval.val->type))
2271 tree->opval.val = stringToSymbol (tree->opval.val);
2273 /* otherwise just copy the type information */
2274 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2278 if (tree->opval.val->sym)
2280 /* if the undefined flag is set then give error message */
2281 if (tree->opval.val->sym->undefined)
2283 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2285 TTYPE (tree) = TETYPE (tree) =
2286 tree->opval.val->type = tree->opval.val->sym->type =
2287 tree->opval.val->etype = tree->opval.val->sym->etype =
2288 copyLinkChain (INTTYPE);
2293 /* if impilicit i.e. struct/union member then no type */
2294 if (tree->opval.val->sym->implicit)
2295 TTYPE (tree) = TETYPE (tree) = NULL;
2300 /* else copy the type */
2301 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2303 /* and mark it as referenced */
2304 tree->opval.val->sym->isref = 1;
2312 /* if type link for the case of cast */
2313 if (tree->type == EX_LINK)
2315 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2323 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2325 if (tree->left && tree->left->type == EX_OPERAND
2326 && (tree->left->opval.op == INC_OP
2327 || tree->left->opval.op == DEC_OP)
2328 && tree->left->left)
2330 tree->left->right = tree->left->left;
2331 tree->left->left = NULL;
2333 if (tree->right && tree->right->type == EX_OPERAND
2334 && (tree->right->opval.op == INC_OP
2335 || tree->right->opval.op == DEC_OP)
2336 && tree->right->left)
2338 tree->right->right = tree->right->left;
2339 tree->right->left = NULL;
2344 /* Before decorating the left branch we've to decide in dependence
2345 upon tree->opval.op, if resultType can be propagated */
2346 resultTypeProp = resultTypePropagate (tree, resultType);
2348 if (tree->opval.op == '?')
2349 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2351 dtl = decorateType (tree->left, resultTypeProp);
2353 /* if an array node, we may need to swap branches */
2354 if (tree->opval.op == '[')
2356 /* determine which is the array & which the index */
2357 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2358 IS_INTEGRAL (LTYPE (tree)))
2360 ast *tempTree = tree->left;
2361 tree->left = tree->right;
2362 tree->right = tempTree;
2366 /* After decorating the left branch there's type information available
2367 in tree->left->?type. If the op is e.g. '=' we extract the type
2368 information from there and propagate it to the right branch. */
2369 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2371 switch (tree->opval.op)
2374 /* delay right side for '?' operator since conditional macro
2375 expansions might rely on this */
2379 /* decorate right side for CALL (parameter list) in processParms();
2380 there is resultType available */
2384 dtr = decorateType (tree->right, resultTypeProp);
2388 /* this is to take care of situations
2389 when the tree gets rewritten */
2390 if (dtl != tree->left)
2392 if (dtr != tree->right)
2394 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2398 /* depending on type of operator do */
2400 switch (tree->opval.op)
2402 /*------------------------------------------------------------------*/
2403 /*----------------------------*/
2405 /*----------------------------*/
2408 /* first check if this is a array or a pointer */
2409 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2411 werror (E_NEED_ARRAY_PTR, "[]");
2412 goto errorTreeReturn;
2415 /* check if the type of the idx */
2416 if (!IS_INTEGRAL (RTYPE (tree)))
2418 werror (E_IDX_NOT_INT);
2419 goto errorTreeReturn;
2422 /* if the left is an rvalue then error */
2425 werror (E_LVALUE_REQUIRED, "array access");
2426 goto errorTreeReturn;
2429 if (IS_LITERAL (RTYPE (tree)))
2431 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2432 int arraySize = DCL_ELEM (LTYPE (tree));
2433 if (arraySize && arrayIndex >= arraySize)
2435 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2440 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2443 /*------------------------------------------------------------------*/
2444 /*----------------------------*/
2446 /*----------------------------*/
2448 /* if this is not a structure */
2449 if (!IS_STRUCT (LTYPE (tree)))
2451 werror (E_STRUCT_UNION, ".");
2452 goto errorTreeReturn;
2454 TTYPE (tree) = structElemType (LTYPE (tree),
2455 (tree->right->type == EX_VALUE ?
2456 tree->right->opval.val : NULL));
2457 TETYPE (tree) = getSpec (TTYPE (tree));
2460 /*------------------------------------------------------------------*/
2461 /*----------------------------*/
2462 /* struct/union pointer */
2463 /*----------------------------*/
2465 /* if not pointer to a structure */
2466 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2468 werror (E_PTR_REQD);
2469 goto errorTreeReturn;
2472 if (!IS_STRUCT (LTYPE (tree)->next))
2474 werror (E_STRUCT_UNION, "->");
2475 goto errorTreeReturn;
2478 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2479 (tree->right->type == EX_VALUE ?
2480 tree->right->opval.val : NULL));
2481 TETYPE (tree) = getSpec (TTYPE (tree));
2483 /* adjust the storage class */
2484 switch (DCL_TYPE(tree->left->ftype)) {
2486 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2489 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2492 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2495 SPEC_SCLS (TETYPE (tree)) = 0;
2498 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2501 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2504 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2507 SPEC_SCLS (TETYPE (tree)) = 0;
2514 /* This breaks with extern declarations, bitfields, and perhaps other */
2515 /* cases (gcse). Let's leave this optimization disabled for now and */
2516 /* ponder if there's a safe way to do this. -- EEP */
2518 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2519 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2521 /* If defined struct type at addr var
2522 then rewrite (&struct var)->member
2524 and define membertype at (addr+offsetof(struct var,member)) temp
2527 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2528 AST_SYMBOL(tree->right));
2530 sym = newSymbol(genSymName (0), 0);
2531 sym->type = TTYPE (tree);
2532 sym->etype = getSpec(sym->type);
2533 sym->lineDef = tree->lineno;
2536 SPEC_STAT (sym->etype) = 1;
2537 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2539 SPEC_ABSA(sym->etype) = 1;
2540 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2543 AST_VALUE (tree) = symbolVal(sym);
2546 tree->type = EX_VALUE;
2554 /*------------------------------------------------------------------*/
2555 /*----------------------------*/
2556 /* ++/-- operation */
2557 /*----------------------------*/
2561 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2562 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2563 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2564 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2573 /*------------------------------------------------------------------*/
2574 /*----------------------------*/
2576 /*----------------------------*/
2577 case '&': /* can be unary */
2578 /* if right is NULL then unary operation */
2579 if (tree->right) /* not an unary operation */
2582 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2584 werror (E_BITWISE_OP);
2585 werror (W_CONTINUE, "left & right types are ");
2586 printTypeChain (LTYPE (tree), stderr);
2587 fprintf (stderr, ",");
2588 printTypeChain (RTYPE (tree), stderr);
2589 fprintf (stderr, "\n");
2590 goto errorTreeReturn;
2593 /* if they are both literal */
2594 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2596 tree->type = EX_VALUE;
2597 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2598 valFromType (RETYPE (tree)), '&');
2600 tree->right = tree->left = NULL;
2601 TETYPE (tree) = tree->opval.val->etype;
2602 TTYPE (tree) = tree->opval.val->type;
2606 /* see if this is a GETHBIT operation if yes
2609 ast *otree = optimizeGetHbit (tree, resultType);
2612 return decorateType (otree, RESULT_TYPE_NONE);
2615 /* see if this is a GETABIT operation if yes
2618 ast *otree = optimizeGetAbit (tree, resultType);
2621 return decorateType (otree, RESULT_TYPE_NONE);
2624 /* see if this is a GETBYTE operation if yes
2627 ast *otree = optimizeGetByte (tree, resultType);
2630 return decorateType (otree, RESULT_TYPE_NONE);
2633 /* see if this is a GETWORD operation if yes
2636 ast *otree = optimizeGetWord (tree, resultType);
2639 return decorateType (otree, RESULT_TYPE_NONE);
2642 /* if left is a literal exchange left & right */
2643 if (IS_LITERAL (LTYPE (tree)))
2645 ast *tTree = tree->left;
2646 tree->left = tree->right;
2647 tree->right = tTree;
2650 /* if right is a literal and */
2651 /* we can find a 2nd literal in an and-tree then */
2652 /* rearrange the tree */
2653 if (IS_LITERAL (RTYPE (tree)))
2656 ast *litTree = searchLitOp (tree, &parent, "&");
2660 ast *tTree = litTree->left;
2661 litTree->left = tree->right;
2662 tree->right = tTree;
2663 /* both operands in litTree are literal now */
2664 decorateType (parent, resultType);
2668 LRVAL (tree) = RRVAL (tree) = 1;
2670 TTYPE (tree) = computeType (LTYPE (tree),
2674 TETYPE (tree) = getSpec (TTYPE (tree));
2679 /*------------------------------------------------------------------*/
2680 /*----------------------------*/
2682 /*----------------------------*/
2683 p = newLink (DECLARATOR);
2684 /* if bit field then error */
2685 if (IS_BITVAR (tree->left->etype))
2687 werror (E_ILLEGAL_ADDR, "address of bit variable");
2688 goto errorTreeReturn;
2691 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2693 werror (E_ILLEGAL_ADDR, "address of register variable");
2694 goto errorTreeReturn;
2697 if (IS_FUNC (LTYPE (tree)))
2699 // this ought to be ignored
2700 return (tree->left);
2703 if (IS_LITERAL(LTYPE(tree)))
2705 werror (E_ILLEGAL_ADDR, "address of literal");
2706 goto errorTreeReturn;
2711 werror (E_LVALUE_REQUIRED, "address of");
2712 goto errorTreeReturn;
2715 DCL_TYPE (p) = POINTER;
2716 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2717 DCL_TYPE (p) = CPOINTER;
2718 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2719 DCL_TYPE (p) = FPOINTER;
2720 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2721 DCL_TYPE (p) = PPOINTER;
2722 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2723 DCL_TYPE (p) = IPOINTER;
2724 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2725 DCL_TYPE (p) = EEPPOINTER;
2726 else if (SPEC_OCLS(tree->left->etype))
2727 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2729 DCL_TYPE (p) = POINTER;
2731 if (IS_AST_SYM_VALUE (tree->left))
2733 AST_SYMBOL (tree->left)->addrtaken = 1;
2734 AST_SYMBOL (tree->left)->allocreq = 1;
2737 p->next = LTYPE (tree);
2739 TETYPE (tree) = getSpec (TTYPE (tree));
2744 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2745 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2747 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2748 AST_SYMBOL(tree->left->right));
2749 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2750 valueFromLit(element->offset));
2753 tree->type = EX_VALUE;
2754 tree->values.literalFromCast = 1;
2760 /*------------------------------------------------------------------*/
2761 /*----------------------------*/
2763 /*----------------------------*/
2765 /* if the rewrite succeeds then don't go any furthur */
2767 ast *wtree = optimizeRRCRLC (tree);
2769 return decorateType (wtree, RESULT_TYPE_NONE);
2771 wtree = optimizeSWAP (tree);
2773 return decorateType (wtree, RESULT_TYPE_NONE);
2776 /* if left is a literal exchange left & right */
2777 if (IS_LITERAL (LTYPE (tree)))
2779 ast *tTree = tree->left;
2780 tree->left = tree->right;
2781 tree->right = tTree;
2784 /* if right is a literal and */
2785 /* we can find a 2nd literal in an or-tree then */
2786 /* rearrange the tree */
2787 if (IS_LITERAL (RTYPE (tree)))
2790 ast *litTree = searchLitOp (tree, &parent, "|");
2794 ast *tTree = litTree->left;
2795 litTree->left = tree->right;
2796 tree->right = tTree;
2797 /* both operands in tTree are literal now */
2798 decorateType (parent, resultType);
2803 /*------------------------------------------------------------------*/
2804 /*----------------------------*/
2806 /*----------------------------*/
2808 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2810 werror (E_BITWISE_OP);
2811 werror (W_CONTINUE, "left & right types are ");
2812 printTypeChain (LTYPE (tree), stderr);
2813 fprintf (stderr, ",");
2814 printTypeChain (RTYPE (tree), stderr);
2815 fprintf (stderr, "\n");
2816 goto errorTreeReturn;
2819 /* if they are both literal then rewrite the tree */
2820 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2822 tree->type = EX_VALUE;
2823 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2824 valFromType (RETYPE (tree)),
2826 tree->right = tree->left = NULL;
2827 TETYPE (tree) = tree->opval.val->etype;
2828 TTYPE (tree) = tree->opval.val->type;
2832 /* if left is a literal exchange left & right */
2833 if (IS_LITERAL (LTYPE (tree)))
2835 ast *tTree = tree->left;
2836 tree->left = tree->right;
2837 tree->right = tTree;
2840 /* if right is a literal and */
2841 /* we can find a 2nd literal in a xor-tree then */
2842 /* rearrange the tree */
2843 if (IS_LITERAL (RTYPE (tree)) &&
2844 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2847 ast *litTree = searchLitOp (tree, &parent, "^");
2851 ast *tTree = litTree->left;
2852 litTree->left = tree->right;
2853 tree->right = tTree;
2854 /* both operands in litTree are literal now */
2855 decorateType (parent, resultType);
2859 LRVAL (tree) = RRVAL (tree) = 1;
2861 TTYPE (tree) = computeType (LTYPE (tree),
2865 TETYPE (tree) = getSpec (TTYPE (tree));
2869 /*------------------------------------------------------------------*/
2870 /*----------------------------*/
2872 /*----------------------------*/
2874 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2876 werror (E_INVALID_OP, "divide");
2877 goto errorTreeReturn;
2879 /* if they are both literal then */
2880 /* rewrite the tree */
2881 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2883 tree->type = EX_VALUE;
2884 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2885 valFromType (RETYPE (tree)));
2886 tree->right = tree->left = NULL;
2887 TETYPE (tree) = getSpec (TTYPE (tree) =
2888 tree->opval.val->type);
2892 LRVAL (tree) = RRVAL (tree) = 1;
2894 TETYPE (tree) = getSpec (TTYPE (tree) =
2895 computeType (LTYPE (tree),
2900 /* if right is a literal and */
2901 /* left is also a division by a literal then */
2902 /* rearrange the tree */
2903 if (IS_LITERAL (RTYPE (tree))
2904 /* avoid infinite loop */
2905 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2908 ast *litTree = searchLitOp (tree, &parent, "/");
2911 if (IS_LITERAL (RTYPE (litTree)))
2915 litTree->right = newNode ('*',
2917 copyAst (tree->right));
2918 litTree->right->lineno = tree->lineno;
2920 tree->right->opval.val = constVal ("1");
2921 decorateType (parent, resultType);
2925 /* litTree->left is literal: no gcse possible.
2926 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2927 this would cause an infinit loop. */
2928 parent->decorated = 1;
2929 decorateType (litTree, resultType);
2936 /*------------------------------------------------------------------*/
2937 /*----------------------------*/
2939 /*----------------------------*/
2941 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2943 werror (E_BITWISE_OP);
2944 werror (W_CONTINUE, "left & right types are ");
2945 printTypeChain (LTYPE (tree), stderr);
2946 fprintf (stderr, ",");
2947 printTypeChain (RTYPE (tree), stderr);
2948 fprintf (stderr, "\n");
2949 goto errorTreeReturn;
2951 /* if they are both literal then */
2952 /* rewrite the tree */
2953 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2955 tree->type = EX_VALUE;
2956 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2957 valFromType (RETYPE (tree)));
2958 tree->right = tree->left = NULL;
2959 TETYPE (tree) = getSpec (TTYPE (tree) =
2960 tree->opval.val->type);
2963 LRVAL (tree) = RRVAL (tree) = 1;
2964 TETYPE (tree) = getSpec (TTYPE (tree) =
2965 computeType (LTYPE (tree),
2971 /*------------------------------------------------------------------*/
2972 /*----------------------------*/
2973 /* address dereference */
2974 /*----------------------------*/
2975 case '*': /* can be unary : if right is null then unary operation */
2978 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2980 werror (E_PTR_REQD);
2981 goto errorTreeReturn;
2986 werror (E_LVALUE_REQUIRED, "pointer deref");
2987 goto errorTreeReturn;
2989 if (IS_ADDRESS_OF_OP(tree->left))
2991 /* replace *&obj with obj */
2992 return tree->left->left;
2994 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2995 TETYPE (tree) = getSpec (TTYPE (tree));
2996 /* adjust the storage class */
2997 switch (DCL_TYPE(tree->left->ftype)) {
2999 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3002 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3005 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3008 SPEC_SCLS (TETYPE (tree)) = 0;
3011 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3014 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3017 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3020 SPEC_SCLS (TETYPE (tree)) = 0;
3029 /*------------------------------------------------------------------*/
3030 /*----------------------------*/
3031 /* multiplication */
3032 /*----------------------------*/
3033 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3035 werror (E_INVALID_OP, "multiplication");
3036 goto errorTreeReturn;
3039 /* if they are both literal then */
3040 /* rewrite the tree */
3041 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3043 tree->type = EX_VALUE;
3044 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3045 valFromType (RETYPE (tree)));
3046 tree->right = tree->left = NULL;
3047 TETYPE (tree) = getSpec (TTYPE (tree) =
3048 tree->opval.val->type);
3052 /* if left is a literal exchange left & right */
3053 if (IS_LITERAL (LTYPE (tree)))
3055 ast *tTree = tree->left;
3056 tree->left = tree->right;
3057 tree->right = tTree;
3060 /* if right is a literal and */
3061 /* we can find a 2nd literal in a mul-tree then */
3062 /* rearrange the tree */
3063 if (IS_LITERAL (RTYPE (tree)))
3066 ast *litTree = searchLitOp (tree, &parent, "*");
3070 ast *tTree = litTree->left;
3071 litTree->left = tree->right;
3072 tree->right = tTree;
3073 /* both operands in litTree are literal now */
3074 decorateType (parent, resultType);
3078 LRVAL (tree) = RRVAL (tree) = 1;
3079 tree->left = addCast (tree->left, resultType, FALSE);
3080 tree->right = addCast (tree->right, resultType, FALSE);
3081 TETYPE (tree) = getSpec (TTYPE (tree) =
3082 computeType (LTYPE (tree),
3089 /*------------------------------------------------------------------*/
3090 /*----------------------------*/
3091 /* unary '+' operator */
3092 /*----------------------------*/
3097 if (!IS_ARITHMETIC (LTYPE (tree)))
3099 werror (E_UNARY_OP, '+');
3100 goto errorTreeReturn;
3103 /* if left is a literal then do it */
3104 if (IS_LITERAL (LTYPE (tree)))
3106 tree->type = EX_VALUE;
3107 tree->opval.val = valFromType (LETYPE (tree));
3109 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3113 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3117 /*------------------------------------------------------------------*/
3118 /*----------------------------*/
3120 /*----------------------------*/
3122 /* this is not a unary operation */
3123 /* if both pointers then problem */
3124 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3125 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3127 werror (E_PTR_PLUS_PTR);
3128 goto errorTreeReturn;
3131 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3132 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3134 werror (E_PLUS_INVALID, "+");
3135 goto errorTreeReturn;
3138 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3139 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3141 werror (E_PLUS_INVALID, "+");
3142 goto errorTreeReturn;
3144 /* if they are both literal then */
3145 /* rewrite the tree */
3146 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3148 tree->type = EX_VALUE;
3149 tree->left = addCast (tree->left, resultType, TRUE);
3150 tree->right = addCast (tree->right, resultType, TRUE);
3151 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3152 valFromType (RETYPE (tree)));
3153 tree->right = tree->left = NULL;
3154 TETYPE (tree) = getSpec (TTYPE (tree) =
3155 tree->opval.val->type);
3159 /* if the right is a pointer or left is a literal
3160 xchange left & right */
3161 if (IS_ARRAY (RTYPE (tree)) ||
3162 IS_PTR (RTYPE (tree)) ||
3163 IS_LITERAL (LTYPE (tree)))
3165 ast *tTree = tree->left;
3166 tree->left = tree->right;
3167 tree->right = tTree;
3170 /* if right is a literal and */
3171 /* left is also an addition/subtraction with a literal then */
3172 /* rearrange the tree */
3173 if (IS_LITERAL (RTYPE (tree)))
3175 ast *litTree, *parent;
3176 litTree = searchLitOp (tree, &parent, "+-");
3179 if (litTree->opval.op == '+')
3183 ast *tTree = litTree->left;
3184 litTree->left = tree->right;
3185 tree->right = tree->left;
3188 else if (litTree->opval.op == '-')
3190 if (IS_LITERAL (RTYPE (litTree)))
3194 ast *tTree = litTree->left;
3195 litTree->left = tree->right;
3196 tree->right = tTree;
3202 ast *tTree = litTree->right;
3203 litTree->right = tree->right;
3204 tree->right = tTree;
3205 litTree->opval.op = '+';
3206 tree->opval.op = '-';
3209 decorateType (parent, resultType);
3213 LRVAL (tree) = RRVAL (tree) = 1;
3214 /* if the left is a pointer */
3215 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3216 TETYPE (tree) = getSpec (TTYPE (tree) =
3220 tree->left = addCast (tree->left, resultType, TRUE);
3221 tree->right = addCast (tree->right, resultType, TRUE);
3222 TETYPE (tree) = getSpec (TTYPE (tree) =
3223 computeType (LTYPE (tree),
3231 /*------------------------------------------------------------------*/
3232 /*----------------------------*/
3234 /*----------------------------*/
3235 case '-': /* can be unary */
3236 /* if right is null then unary */
3240 if (!IS_ARITHMETIC (LTYPE (tree)))
3242 werror (E_UNARY_OP, tree->opval.op);
3243 goto errorTreeReturn;
3246 /* if left is a literal then do it */
3247 if (IS_LITERAL (LTYPE (tree)))
3249 tree->type = EX_VALUE;
3250 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3252 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3253 SPEC_USIGN(TETYPE(tree)) = 0;
3257 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3261 /*------------------------------------------------------------------*/
3262 /*----------------------------*/
3264 /*----------------------------*/
3266 if (!(IS_PTR (LTYPE (tree)) ||
3267 IS_ARRAY (LTYPE (tree)) ||
3268 IS_ARITHMETIC (LTYPE (tree))))
3270 werror (E_PLUS_INVALID, "-");
3271 goto errorTreeReturn;
3274 if (!(IS_PTR (RTYPE (tree)) ||
3275 IS_ARRAY (RTYPE (tree)) ||
3276 IS_ARITHMETIC (RTYPE (tree))))
3278 werror (E_PLUS_INVALID, "-");
3279 goto errorTreeReturn;
3282 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3283 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3284 IS_INTEGRAL (RTYPE (tree))))
3286 werror (E_PLUS_INVALID, "-");
3287 goto errorTreeReturn;
3290 /* if they are both literal then */
3291 /* rewrite the tree */
3292 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3294 tree->type = EX_VALUE;
3295 tree->left = addCast (tree->left, resultType, TRUE);
3296 tree->right = addCast (tree->right, resultType, TRUE);
3297 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3298 valFromType (RETYPE (tree)));
3299 tree->right = tree->left = NULL;
3300 TETYPE (tree) = getSpec (TTYPE (tree) =
3301 tree->opval.val->type);
3305 /* if the left & right are equal then zero */
3306 if (isAstEqual (tree->left, tree->right))
3308 tree->type = EX_VALUE;
3309 tree->left = tree->right = NULL;
3310 tree->opval.val = constVal ("0");
3311 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3315 /* if both of them are pointers or arrays then */
3316 /* the result is going to be an integer */
3317 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3318 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3319 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3321 /* if only the left is a pointer */
3322 /* then result is a pointer */
3323 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3324 TETYPE (tree) = getSpec (TTYPE (tree) =
3328 tree->left = addCast (tree->left, resultType, TRUE);
3329 tree->right = addCast (tree->right, resultType, TRUE);
3331 TETYPE (tree) = getSpec (TTYPE (tree) =
3332 computeType (LTYPE (tree),
3338 LRVAL (tree) = RRVAL (tree) = 1;
3340 /* if right is a literal and */
3341 /* left is also an addition/subtraction with a literal then */
3342 /* rearrange the tree */
3343 if (IS_LITERAL (RTYPE (tree))
3344 /* avoid infinite loop */
3345 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3347 ast *litTree, *litParent;
3348 litTree = searchLitOp (tree, &litParent, "+-");
3351 if (litTree->opval.op == '+')
3355 ast *tTree = litTree->left;
3356 litTree->left = litTree->right;
3357 litTree->right = tree->right;
3358 tree->right = tTree;
3359 tree->opval.op = '+';
3360 litTree->opval.op = '-';
3362 else if (litTree->opval.op == '-')
3364 if (IS_LITERAL (RTYPE (litTree)))
3368 ast *tTree = litTree->left;
3369 litTree->left = tree->right;
3370 tree->right = litParent->left;
3371 litParent->left = tTree;
3372 litTree->opval.op = '+';
3374 tree->decorated = 0;
3375 decorateType (tree, resultType);
3381 ast *tTree = litTree->right;
3382 litTree->right = tree->right;
3383 tree->right = tTree;
3386 decorateType (litParent, resultType);
3391 /*------------------------------------------------------------------*/
3392 /*----------------------------*/
3394 /*----------------------------*/
3396 /* can be only integral type */
3397 if (!IS_INTEGRAL (LTYPE (tree)))
3399 werror (E_UNARY_OP, tree->opval.op);
3400 goto errorTreeReturn;
3403 /* if left is a literal then do it */
3404 if (IS_LITERAL (LTYPE (tree)))
3406 tree->type = EX_VALUE;
3407 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3409 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3410 return addCast (tree, resultType, TRUE);
3412 tree->left = addCast (tree->left, resultType, TRUE);
3414 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3417 /*------------------------------------------------------------------*/
3418 /*----------------------------*/
3420 /*----------------------------*/
3422 /* can be pointer */
3423 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3424 !IS_PTR (LTYPE (tree)) &&
3425 !IS_ARRAY (LTYPE (tree)))
3427 werror (E_UNARY_OP, tree->opval.op);
3428 goto errorTreeReturn;
3431 /* if left is a literal then do it */
3432 if (IS_LITERAL (LTYPE (tree)))
3434 tree->type = EX_VALUE;
3435 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3437 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3441 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3444 /*------------------------------------------------------------------*/
3445 /*----------------------------*/
3447 /*----------------------------*/
3451 TTYPE (tree) = LTYPE (tree);
3452 TETYPE (tree) = LETYPE (tree);
3457 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3461 TTYPE (tree) = TETYPE (tree) = newCharLink();
3465 TTYPE (tree) = TETYPE (tree) = newIntLink();
3470 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3472 werror (E_SHIFT_OP_INVALID);
3473 werror (W_CONTINUE, "left & right types are ");
3474 printTypeChain (LTYPE (tree), stderr);
3475 fprintf (stderr, ",");
3476 printTypeChain (RTYPE (tree), stderr);
3477 fprintf (stderr, "\n");
3478 goto errorTreeReturn;
3481 /* make smaller type only if it's a LEFT_OP */
3482 if (tree->opval.op == LEFT_OP)
3483 tree->left = addCast (tree->left, resultType, TRUE);
3485 /* if they are both literal then */
3486 /* rewrite the tree */
3487 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3489 tree->type = EX_VALUE;
3490 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3491 valFromType (RETYPE (tree)),
3492 (tree->opval.op == LEFT_OP ? 1 : 0));
3493 tree->right = tree->left = NULL;
3494 TETYPE (tree) = getSpec (TTYPE (tree) =
3495 tree->opval.val->type);
3499 /* see if this is a GETBYTE operation if yes
3502 ast *otree = optimizeGetByte (tree, resultType);
3505 return decorateType (otree, RESULT_TYPE_NONE);
3508 /* see if this is a GETWORD operation if yes
3511 ast *otree = optimizeGetWord (tree, resultType);
3514 return decorateType (otree, RESULT_TYPE_NONE);
3517 LRVAL (tree) = RRVAL (tree) = 1;
3518 if (tree->opval.op == LEFT_OP)
3520 TETYPE (tree) = getSpec (TTYPE (tree) =
3521 computeType (LTYPE (tree),
3528 /* no promotion necessary */
3529 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3530 if (IS_LITERAL (TTYPE (tree)))
3531 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3534 /* if only the right side is a literal & we are
3535 shifting more than size of the left operand then zero */
3536 if (IS_LITERAL (RTYPE (tree)) &&
3537 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3538 (getSize (TETYPE (tree)) * 8))
3540 if (tree->opval.op==LEFT_OP ||
3541 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3543 lineno=tree->lineno;
3544 werror (W_SHIFT_CHANGED,
3545 (tree->opval.op == LEFT_OP ? "left" : "right"));
3546 tree->type = EX_VALUE;
3547 tree->left = tree->right = NULL;
3548 tree->opval.val = constVal ("0");
3549 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3556 /*------------------------------------------------------------------*/
3557 /*----------------------------*/
3559 /*----------------------------*/
3560 case CAST: /* change the type */
3561 /* cannot cast to an aggregate type */
3562 if (IS_AGGREGATE (LTYPE (tree)))
3564 werror (E_CAST_ILLEGAL);
3565 goto errorTreeReturn;
3568 /* make sure the type is complete and sane */
3569 changePointer(LTYPE(tree));
3570 checkTypeSanity(LETYPE(tree), "(cast)");
3572 /* If code memory is read only, then pointers to code memory */
3573 /* implicitly point to constants -- make this explicit */
3575 sym_link *t = LTYPE(tree);
3576 while (t && t->next)
3578 if (IS_CODEPTR(t) && port->mem.code_ro)
3580 if (IS_SPEC(t->next))
3581 SPEC_CONST (t->next) = 1;
3583 DCL_PTR_CONST (t->next) = 1;
3590 /* if the right is a literal replace the tree */
3591 if (IS_LITERAL (RETYPE (tree))) {
3592 if (!IS_PTR (LTYPE (tree))) {
3593 tree->type = EX_VALUE;
3595 valCastLiteral (LTYPE (tree),
3596 floatFromVal (valFromType (RETYPE (tree))));
3599 TTYPE (tree) = tree->opval.val->type;
3600 tree->values.literalFromCast = 1;
3601 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3602 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3603 sym_link *rest = LTYPE(tree)->next;
3604 werror(W_LITERAL_GENERIC);
3605 TTYPE(tree) = newLink(DECLARATOR);
3606 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3607 TTYPE(tree)->next = rest;
3608 tree->left->opval.lnk = TTYPE(tree);
3611 TTYPE (tree) = LTYPE (tree);
3615 TTYPE (tree) = LTYPE (tree);
3619 #if 0 // this is already checked, now this could be explicit
3620 /* if pointer to struct then check names */
3621 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3622 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3623 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3625 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3626 SPEC_STRUCT(LETYPE(tree))->tag);
3629 if (IS_ADDRESS_OF_OP(tree->right)
3630 && IS_AST_SYM_VALUE (tree->right->left)
3631 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3633 symbol * sym = AST_SYMBOL (tree->right->left);
3634 unsigned int gptype = 0;
3635 unsigned int addr = SPEC_ADDR (sym->etype);
3637 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3639 switch (SPEC_SCLS (sym->etype))
3642 gptype = GPTYPE_CODE;
3645 gptype = GPTYPE_FAR;
3649 gptype = GPTYPE_NEAR;
3652 gptype = GPTYPE_XSTACK;
3657 addr |= gptype << (8*(GPTRSIZE - 1));
3660 tree->type = EX_VALUE;
3662 valCastLiteral (LTYPE (tree), addr);
3663 TTYPE (tree) = tree->opval.val->type;
3664 TETYPE (tree) = getSpec (TTYPE (tree));
3667 tree->values.literalFromCast = 1;
3671 /* handle offsetof macro: */
3672 /* #define offsetof(TYPE, MEMBER) \ */
3673 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3674 if (IS_ADDRESS_OF_OP(tree->right)
3675 && IS_AST_OP (tree->right->left)
3676 && tree->right->left->opval.op == PTR_OP
3677 && IS_AST_OP (tree->right->left->left)
3678 && tree->right->left->left->opval.op == CAST
3679 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3681 symbol *element = getStructElement (
3682 SPEC_STRUCT (LETYPE(tree->right->left)),
3683 AST_SYMBOL(tree->right->left->right)
3687 tree->type = EX_VALUE;
3688 tree->opval.val = valCastLiteral (
3691 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3694 TTYPE (tree) = tree->opval.val->type;
3695 TETYPE (tree) = getSpec (TTYPE (tree));
3702 /* if the right is a literal replace the tree */
3703 if (IS_LITERAL (RETYPE (tree))) {
3705 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3706 /* rewrite (type *)litaddr
3708 and define type at litaddr temp
3709 (but only if type's storage class is not generic)
3711 ast *newTree = newNode ('&', NULL, NULL);
3714 TTYPE (newTree) = LTYPE (tree);
3715 TETYPE (newTree) = getSpec(LTYPE (tree));
3717 /* define a global symbol at the casted address*/
3718 sym = newSymbol(genSymName (0), 0);
3719 sym->type = LTYPE (tree)->next;
3721 sym->type = newLink (V_VOID);
3722 sym->etype = getSpec(sym->type);
3723 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3724 sym->lineDef = tree->lineno;
3727 SPEC_STAT (sym->etype) = 1;
3728 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3729 SPEC_ABSA(sym->etype) = 1;
3730 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3733 newTree->left = newAst_VALUE(symbolVal(sym));
3734 newTree->left->lineno = tree->lineno;
3735 LTYPE (newTree) = sym->type;
3736 LETYPE (newTree) = sym->etype;
3737 LLVAL (newTree) = 1;
3738 LRVAL (newTree) = 0;
3739 TLVAL (newTree) = 1;
3743 if (!IS_PTR (LTYPE (tree))) {
3744 tree->type = EX_VALUE;
3746 valCastLiteral (LTYPE (tree),
3747 floatFromVal (valFromType (RTYPE (tree))));
3748 TTYPE (tree) = tree->opval.val->type;
3751 tree->values.literalFromCast = 1;
3752 TETYPE (tree) = getSpec (TTYPE (tree));
3756 TTYPE (tree) = LTYPE (tree);
3760 TETYPE (tree) = getSpec (TTYPE (tree));
3764 /*------------------------------------------------------------------*/
3765 /*----------------------------*/
3766 /* logical &&, || */
3767 /*----------------------------*/
3770 /* each must be arithmetic type or be a pointer */
3771 if (!IS_PTR (LTYPE (tree)) &&
3772 !IS_ARRAY (LTYPE (tree)) &&
3773 !IS_INTEGRAL (LTYPE (tree)))
3775 werror (E_COMPARE_OP);
3776 goto errorTreeReturn;
3779 if (!IS_PTR (RTYPE (tree)) &&
3780 !IS_ARRAY (RTYPE (tree)) &&
3781 !IS_INTEGRAL (RTYPE (tree)))
3783 werror (E_COMPARE_OP);
3784 goto errorTreeReturn;
3786 /* if they are both literal then */
3787 /* rewrite the tree */
3788 if (IS_LITERAL (RTYPE (tree)) &&
3789 IS_LITERAL (LTYPE (tree)))
3791 tree->type = EX_VALUE;
3792 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3793 valFromType (RTYPE (tree)),
3795 tree->right = tree->left = NULL;
3796 TETYPE (tree) = getSpec (TTYPE (tree) =
3797 tree->opval.val->type);
3800 LRVAL (tree) = RRVAL (tree) = 1;
3801 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3804 /*------------------------------------------------------------------*/
3805 /*----------------------------*/
3806 /* comparison operators */
3807 /*----------------------------*/
3815 ast *lt = optimizeCompare (tree);
3821 /* if they are pointers they must be castable */
3822 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3824 if (tree->opval.op==EQ_OP &&
3825 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3826 // we cannot cast a gptr to a !gptr: switch the leaves
3827 struct ast *s=tree->left;
3828 tree->left=tree->right;
3831 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3833 werror (E_COMPARE_OP);
3834 fprintf (stderr, "comparing type ");
3835 printTypeChain (LTYPE (tree), stderr);
3836 fprintf (stderr, "to type ");
3837 printTypeChain (RTYPE (tree), stderr);
3838 fprintf (stderr, "\n");
3839 goto errorTreeReturn;
3842 /* else they should be promotable to one another */
3845 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3846 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3848 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3850 werror (E_COMPARE_OP);
3851 fprintf (stderr, "comparing type ");
3852 printTypeChain (LTYPE (tree), stderr);
3853 fprintf (stderr, "to type ");
3854 printTypeChain (RTYPE (tree), stderr);
3855 fprintf (stderr, "\n");
3856 goto errorTreeReturn;
3859 /* if unsigned value < 0 then always false */
3860 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3861 if (SPEC_USIGN(LETYPE(tree)) &&
3862 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3863 IS_LITERAL(RTYPE(tree)) &&
3864 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3866 if (tree->opval.op == '<')
3870 if (tree->opval.op == '>')
3872 if (resultType == RESULT_TYPE_IFX)
3874 /* the parent is an ifx: */
3875 /* if (unsigned value) */
3879 /* (unsigned value) ? 1 : 0 */
3880 tree->opval.op = '?';
3881 tree->right = newNode (':',
3882 newAst_VALUE (constVal ("1")),
3883 tree->right); /* val 0 */
3884 tree->right->lineno = tree->lineno;
3885 tree->right->left->lineno = tree->lineno;
3886 decorateType (tree->right, RESULT_TYPE_NONE);
3889 /* if they are both literal then */
3890 /* rewrite the tree */
3891 if (IS_LITERAL (RTYPE (tree)) &&
3892 IS_LITERAL (LTYPE (tree)))
3894 tree->type = EX_VALUE;
3895 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3896 valFromType (RETYPE (tree)),
3898 tree->right = tree->left = NULL;
3899 TETYPE (tree) = getSpec (TTYPE (tree) =
3900 tree->opval.val->type);
3903 LRVAL (tree) = RRVAL (tree) = 1;
3904 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3907 /*------------------------------------------------------------------*/
3908 /*----------------------------*/
3910 /*----------------------------*/
3911 case SIZEOF: /* evaluate wihout code generation */
3912 /* change the type to a integer */
3914 int size = getSize (tree->right->ftype);
3915 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3916 if (!size && !IS_VOID(tree->right->ftype))
3917 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3919 tree->type = EX_VALUE;
3920 tree->opval.val = constVal (buffer);
3921 tree->right = tree->left = NULL;
3922 TETYPE (tree) = getSpec (TTYPE (tree) =
3923 tree->opval.val->type);
3926 /*------------------------------------------------------------------*/
3927 /*----------------------------*/
3929 /*----------------------------*/
3931 /* return typeof enum value */
3932 tree->type = EX_VALUE;
3935 if (IS_SPEC(tree->right->ftype)) {
3936 switch (SPEC_NOUN(tree->right->ftype)) {
3938 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3939 else typeofv = TYPEOF_INT;
3942 typeofv = TYPEOF_FLOAT;
3945 typeofv = TYPEOF_FIXED16X16;
3948 typeofv = TYPEOF_CHAR;
3951 typeofv = TYPEOF_VOID;
3954 typeofv = TYPEOF_STRUCT;
3957 typeofv = TYPEOF_BITFIELD;
3960 typeofv = TYPEOF_BIT;
3963 typeofv = TYPEOF_SBIT;
3969 switch (DCL_TYPE(tree->right->ftype)) {
3971 typeofv = TYPEOF_POINTER;
3974 typeofv = TYPEOF_FPOINTER;
3977 typeofv = TYPEOF_CPOINTER;
3980 typeofv = TYPEOF_GPOINTER;
3983 typeofv = TYPEOF_PPOINTER;
3986 typeofv = TYPEOF_IPOINTER;
3989 typeofv = TYPEOF_ARRAY;
3992 typeofv = TYPEOF_FUNCTION;
3998 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3999 tree->opval.val = constVal (buffer);
4000 tree->right = tree->left = NULL;
4001 TETYPE (tree) = getSpec (TTYPE (tree) =
4002 tree->opval.val->type);
4005 /*------------------------------------------------------------------*/
4006 /*----------------------------*/
4007 /* conditional operator '?' */
4008 /*----------------------------*/
4010 /* the type is value of the colon operator (on the right) */
4011 assert (IS_COLON_OP (tree->right));
4012 /* if already known then replace the tree : optimizer will do it
4013 but faster to do it here */
4014 if (IS_LITERAL (LTYPE (tree)))
4016 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4017 return decorateType (tree->right->left, resultTypeProp);
4019 return decorateType (tree->right->right, resultTypeProp);
4023 tree->right = decorateType (tree->right, resultTypeProp);
4024 TTYPE (tree) = RTYPE (tree);
4025 TETYPE (tree) = getSpec (TTYPE (tree));
4030 /* if they don't match we have a problem */
4031 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4032 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4034 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4035 goto errorTreeReturn;
4038 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4039 resultType, tree->opval.op);
4040 TETYPE (tree) = getSpec (TTYPE (tree));
4044 #if 0 // assignment operators are converted by the parser
4045 /*------------------------------------------------------------------*/
4046 /*----------------------------*/
4047 /* assignment operators */
4048 /*----------------------------*/
4051 /* for these it must be both must be integral */
4052 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4053 !IS_ARITHMETIC (RTYPE (tree)))
4055 werror (E_OPS_INTEGRAL);
4056 goto errorTreeReturn;
4059 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4061 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4062 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4066 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4067 goto errorTreeReturn;
4078 /* for these it must be both must be integral */
4079 if (!IS_INTEGRAL (LTYPE (tree)) ||
4080 !IS_INTEGRAL (RTYPE (tree)))
4082 werror (E_OPS_INTEGRAL);
4083 goto errorTreeReturn;
4086 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4088 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4089 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4093 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4094 goto errorTreeReturn;
4100 /*------------------------------------------------------------------*/
4101 /*----------------------------*/
4103 /*----------------------------*/
4105 if (!(IS_PTR (LTYPE (tree)) ||
4106 IS_ARITHMETIC (LTYPE (tree))))
4108 werror (E_PLUS_INVALID, "-=");
4109 goto errorTreeReturn;
4112 if (!(IS_PTR (RTYPE (tree)) ||
4113 IS_ARITHMETIC (RTYPE (tree))))
4115 werror (E_PLUS_INVALID, "-=");
4116 goto errorTreeReturn;
4119 TETYPE (tree) = getSpec (TTYPE (tree) =
4120 computeType (LTYPE (tree),
4125 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4126 werror (E_CODE_WRITE, "-=");
4130 werror (E_LVALUE_REQUIRED, "-=");
4131 goto errorTreeReturn;
4137 /*------------------------------------------------------------------*/
4138 /*----------------------------*/
4140 /*----------------------------*/
4142 /* this is not a unary operation */
4143 /* if both pointers then problem */
4144 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4146 werror (E_PTR_PLUS_PTR);
4147 goto errorTreeReturn;
4150 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4152 werror (E_PLUS_INVALID, "+=");
4153 goto errorTreeReturn;
4156 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4158 werror (E_PLUS_INVALID, "+=");
4159 goto errorTreeReturn;
4162 TETYPE (tree) = getSpec (TTYPE (tree) =
4163 computeType (LTYPE (tree),
4168 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4169 werror (E_CODE_WRITE, "+=");
4173 werror (E_LVALUE_REQUIRED, "+=");
4174 goto errorTreeReturn;
4177 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4178 tree->opval.op = '=';
4183 /*------------------------------------------------------------------*/
4184 /*----------------------------*/
4185 /* straight assignemnt */
4186 /*----------------------------*/
4188 /* cannot be an aggregate */
4189 if (IS_AGGREGATE (LTYPE (tree)))
4191 werror (E_AGGR_ASSIGN);
4192 goto errorTreeReturn;
4195 /* they should either match or be castable */
4196 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4198 werror (E_TYPE_MISMATCH, "assignment", " ");
4199 printFromToType(RTYPE(tree),LTYPE(tree));
4202 /* if the left side of the tree is of type void
4203 then report error */
4204 if (IS_VOID (LTYPE (tree)))
4206 werror (E_CAST_ZERO);
4207 printFromToType(RTYPE(tree), LTYPE(tree));
4210 TETYPE (tree) = getSpec (TTYPE (tree) =
4214 if (!tree->initMode ) {
4215 if (IS_CONSTANT(LTYPE(tree)))
4216 werror (E_CODE_WRITE, "=");
4220 werror (E_LVALUE_REQUIRED, "=");
4221 goto errorTreeReturn;
4226 /*------------------------------------------------------------------*/
4227 /*----------------------------*/
4228 /* comma operator */
4229 /*----------------------------*/
4231 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4234 /*------------------------------------------------------------------*/
4235 /*----------------------------*/
4237 /*----------------------------*/
4240 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4241 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4243 if (tree->left->opval.op == '*' && !tree->left->right)
4244 tree->left = tree->left->left;
4247 /* require a function or pointer to function */
4248 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4250 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4251 goto errorTreeReturn;
4254 /* if there are parms, make sure that
4255 parms are decorate / process / reverse only once */
4257 !tree->right->decorated)
4262 if (IS_FUNCPTR (LTYPE (tree)))
4263 functype = LTYPE (tree)->next;
4265 functype = LTYPE (tree);
4267 if (processParms (tree->left, FUNC_ARGS(functype),
4268 &tree->right, &parmNumber, TRUE))
4270 goto errorTreeReturn;
4273 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4274 !IFFUNC_ISBUILTIN(functype))
4276 reverseParms (tree->right);
4279 TTYPE (tree) = functype->next;
4280 TETYPE (tree) = getSpec (TTYPE (tree));
4284 /*------------------------------------------------------------------*/
4285 /*----------------------------*/
4286 /* return statement */
4287 /*----------------------------*/
4292 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4294 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4295 printFromToType (RTYPE(tree), currFunc->type->next);
4296 goto errorTreeReturn;
4299 if (IS_VOID (currFunc->type->next)
4301 !IS_VOID (RTYPE (tree)))
4303 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4304 goto errorTreeReturn;
4307 /* if there is going to be a casting required then add it */
4308 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4311 decorateType (newNode (CAST,
4312 newAst_LINK (copyLinkChain (currFunc->type->next)),
4322 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4324 werror (W_VOID_FUNC, currFunc->name);
4325 goto errorTreeReturn;
4328 TTYPE (tree) = TETYPE (tree) = NULL;
4331 /*------------------------------------------------------------------*/
4332 /*----------------------------*/
4333 /* switch statement */
4334 /*----------------------------*/
4336 /* the switch value must be an integer */
4337 if (!IS_INTEGRAL (LTYPE (tree)))
4339 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4340 goto errorTreeReturn;
4343 TTYPE (tree) = TETYPE (tree) = NULL;
4346 /*------------------------------------------------------------------*/
4347 /*----------------------------*/
4349 /*----------------------------*/
4351 tree->left = backPatchLabels (tree->left,
4354 TTYPE (tree) = TETYPE (tree) = NULL;
4357 /*------------------------------------------------------------------*/
4358 /*----------------------------*/
4360 /*----------------------------*/
4363 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4364 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4365 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4367 /* if the for loop is reversible then
4368 reverse it otherwise do what we normally
4374 if (isLoopReversible (tree, &sym, &init, &end))
4375 return reverseLoop (tree, sym, init, end);
4377 return decorateType (createFor (AST_FOR (tree, trueLabel),
4378 AST_FOR (tree, continueLabel),
4379 AST_FOR (tree, falseLabel),
4380 AST_FOR (tree, condLabel),
4381 AST_FOR (tree, initExpr),
4382 AST_FOR (tree, condExpr),
4383 AST_FOR (tree, loopExpr),
4384 tree->left), RESULT_TYPE_NONE);
4387 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4388 "node PARAM shouldn't be processed here");
4389 /* but in processParams() */
4392 TTYPE (tree) = TETYPE (tree) = NULL;
4396 /* some error found this tree will be killed */
4398 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4399 tree->opval.op = NULLOP;
4405 /*-----------------------------------------------------------------*/
4406 /* sizeofOp - processes size of operation */
4407 /*-----------------------------------------------------------------*/
4409 sizeofOp (sym_link * type)
4414 /* make sure the type is complete and sane */
4415 checkTypeSanity(type, "(sizeof)");
4417 /* get the size and convert it to character */
4418 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4419 if (!size && !IS_VOID(type))
4420 werror (E_SIZEOF_INCOMPLETE_TYPE);
4422 /* now convert into value */
4423 return constVal (buff);
4427 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4428 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4429 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4430 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4431 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4432 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4433 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4435 /*-----------------------------------------------------------------*/
4436 /* backPatchLabels - change and or not operators to flow control */
4437 /*-----------------------------------------------------------------*/
4439 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4445 if (!(IS_ANDORNOT (tree)))
4448 /* if this an and */
4451 static int localLbl = 0;
4454 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4455 localLabel = newSymbol (buffer, NestLevel);
4457 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4459 /* if left is already a IFX then just change the if true label in that */
4460 if (!IS_IFX (tree->left))
4461 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4463 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4464 /* right is a IFX then just join */
4465 if (IS_IFX (tree->right))
4466 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4468 tree->right = createLabel (localLabel, tree->right);
4469 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4471 return newNode (NULLOP, tree->left, tree->right);
4474 /* if this is an or operation */
4477 static int localLbl = 0;
4480 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4481 localLabel = newSymbol (buffer, NestLevel);
4483 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4485 /* if left is already a IFX then just change the if true label in that */
4486 if (!IS_IFX (tree->left))
4487 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4489 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4490 /* right is a IFX then just join */
4491 if (IS_IFX (tree->right))
4492 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4494 tree->right = createLabel (localLabel, tree->right);
4495 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4497 return newNode (NULLOP, tree->left, tree->right);
4503 int wasnot = IS_NOT (tree->left);
4504 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4506 /* if the left is already a IFX */
4507 if (!IS_IFX (tree->left))
4508 tree->left = newNode (IFX, tree->left, NULL);
4512 tree->left->trueLabel = trueLabel;
4513 tree->left->falseLabel = falseLabel;
4517 tree->left->trueLabel = falseLabel;
4518 tree->left->falseLabel = trueLabel;
4525 tree->trueLabel = trueLabel;
4526 tree->falseLabel = falseLabel;
4533 /*-----------------------------------------------------------------*/
4534 /* createBlock - create expression tree for block */
4535 /*-----------------------------------------------------------------*/
4537 createBlock (symbol * decl, ast * body)
4541 /* if the block has nothing */
4545 ex = newNode (BLOCK, NULL, body);
4546 ex->values.sym = decl;
4553 /*-----------------------------------------------------------------*/
4554 /* createLabel - creates the expression tree for labels */
4555 /*-----------------------------------------------------------------*/
4557 createLabel (symbol * label, ast * stmnt)
4560 char name[SDCC_NAME_MAX + 1];
4563 /* must create fresh symbol if the symbol name */
4564 /* exists in the symbol table, since there can */
4565 /* be a variable with the same name as the labl */
4566 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4567 (csym->level == label->level))
4568 label = newSymbol (label->name, label->level);
4570 /* change the name before putting it in add _ */
4571 SNPRINTF(name, sizeof(name), "%s", label->name);
4573 /* put the label in the LabelSymbol table */
4574 /* but first check if a label of the same */
4576 if ((csym = findSym (LabelTab, NULL, name)))
4577 werror (E_DUPLICATE_LABEL, label->name);
4579 addSym (LabelTab, label, name, label->level, 0, 0);
4583 label->key = labelKey++;
4584 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4590 /*-----------------------------------------------------------------*/
4591 /* createCase - generates the parsetree for a case statement */
4592 /*-----------------------------------------------------------------*/
4594 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4596 char caseLbl[SDCC_NAME_MAX + 1];
4600 /* if the switch statement does not exist */
4601 /* then case is out of context */
4604 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4608 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4609 /* if not a constant then error */
4610 if (!IS_LITERAL (caseVal->ftype))
4612 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4616 /* if not a integer than error */
4617 if (!IS_INTEGRAL (caseVal->ftype))
4619 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4623 /* find the end of the switch values chain */
4624 if (!(val = swStat->values.switchVals.swVals))
4625 swStat->values.switchVals.swVals = caseVal->opval.val;
4628 /* also order the cases according to value */
4630 int cVal = (int) floatFromVal (caseVal->opval.val);
4631 while (val && (int) floatFromVal (val) < cVal)
4637 /* if we reached the end then */
4640 pval->next = caseVal->opval.val;
4642 else if ((int) floatFromVal (val) == cVal)
4644 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4650 /* we found a value greater than */
4651 /* the current value we must add this */
4652 /* before the value */
4653 caseVal->opval.val->next = val;
4655 /* if this was the first in chain */
4656 if (swStat->values.switchVals.swVals == val)
4657 swStat->values.switchVals.swVals =
4660 pval->next = caseVal->opval.val;
4665 /* create the case label */
4666 SNPRINTF(caseLbl, sizeof(caseLbl),
4668 swStat->values.switchVals.swNum,
4669 (int) floatFromVal (caseVal->opval.val));
4671 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4676 /*-----------------------------------------------------------------*/
4677 /* createDefault - creates the parse tree for the default statement */
4678 /*-----------------------------------------------------------------*/
4680 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4682 char defLbl[SDCC_NAME_MAX + 1];
4684 /* if the switch statement does not exist */
4685 /* then case is out of context */
4688 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4692 if (swStat->values.switchVals.swDefault)
4694 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4699 /* turn on the default flag */
4700 swStat->values.switchVals.swDefault = 1;
4702 /* create the label */
4703 SNPRINTF (defLbl, sizeof(defLbl),
4704 "_default_%d", swStat->values.switchVals.swNum);
4705 return createLabel (newSymbol (defLbl, 0), stmnt);
4708 /*-----------------------------------------------------------------*/
4709 /* createIf - creates the parsetree for the if statement */
4710 /*-----------------------------------------------------------------*/
4712 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4714 static int Lblnum = 0;
4716 symbol *ifTrue, *ifFalse, *ifEnd;
4718 /* if neither exists */
4719 if (!elseBody && !ifBody) {
4720 // if there are no side effects (i++, j() etc)
4721 if (!hasSEFcalls(condAst)) {
4726 /* create the labels */
4727 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4728 ifFalse = newSymbol (buffer, NestLevel);
4729 /* if no else body then end == false */
4734 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4735 ifEnd = newSymbol (buffer, NestLevel);
4738 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4739 ifTrue = newSymbol (buffer, NestLevel);
4743 /* attach the ifTrue label to the top of it body */
4744 ifBody = createLabel (ifTrue, ifBody);
4745 /* attach a goto end to the ifBody if else is present */
4748 ifBody = newNode (NULLOP, ifBody,
4750 newAst_VALUE (symbolVal (ifEnd)),
4752 /* put the elseLabel on the else body */
4753 elseBody = createLabel (ifFalse, elseBody);
4754 /* out the end at the end of the body */
4755 elseBody = newNode (NULLOP,
4757 createLabel (ifEnd, NULL));
4761 ifBody = newNode (NULLOP, ifBody,
4762 createLabel (ifFalse, NULL));
4764 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4765 if (IS_IFX (condAst))
4768 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4770 return newNode (NULLOP, ifTree,
4771 newNode (NULLOP, ifBody, elseBody));
4775 /*-----------------------------------------------------------------*/
4776 /* createDo - creates parse tree for do */
4779 /* _docontinue_n: */
4780 /* condition_expression +-> trueLabel -> _dobody_n */
4782 /* +-> falseLabel-> _dobreak_n */
4784 /*-----------------------------------------------------------------*/
4786 createDo (symbol * trueLabel, symbol * continueLabel,
4787 symbol * falseLabel, ast * condAst, ast * doBody)
4792 /* if the body does not exist then it is simple */
4795 condAst = backPatchLabels (condAst, continueLabel, NULL);
4796 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4797 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4798 doTree->trueLabel = continueLabel;
4799 doTree->falseLabel = NULL;
4803 /* otherwise we have a body */
4804 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4806 /* attach the body label to the top */
4807 doBody = createLabel (trueLabel, doBody);
4808 /* attach the continue label to end of body */
4809 doBody = newNode (NULLOP, doBody,
4810 createLabel (continueLabel, NULL));
4812 /* now put the break label at the end */
4813 if (IS_IFX (condAst))
4816 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4818 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4820 /* putting it together */
4821 return newNode (NULLOP, doBody, doTree);
4824 /*-----------------------------------------------------------------*/
4825 /* createFor - creates parse tree for 'for' statement */
4828 /* condExpr +-> trueLabel -> _forbody_n */
4830 /* +-> falseLabel-> _forbreak_n */
4833 /* _forcontinue_n: */
4835 /* goto _forcond_n ; */
4837 /*-----------------------------------------------------------------*/
4839 createFor (symbol * trueLabel, symbol * continueLabel,
4840 symbol * falseLabel, symbol * condLabel,
4841 ast * initExpr, ast * condExpr, ast * loopExpr,
4846 /* if loopexpression not present then we can generate it */
4847 /* the same way as a while */
4849 return newNode (NULLOP, initExpr,
4850 createWhile (trueLabel, continueLabel,
4851 falseLabel, condExpr, forBody));
4852 /* vanilla for statement */
4853 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4855 if (condExpr && !IS_IFX (condExpr))
4856 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4859 /* attach condition label to condition */
4860 condExpr = createLabel (condLabel, condExpr);
4862 /* attach body label to body */
4863 forBody = createLabel (trueLabel, forBody);
4865 /* attach continue to forLoop expression & attach */
4866 /* goto the forcond @ and of loopExpression */
4867 loopExpr = createLabel (continueLabel,
4871 newAst_VALUE (symbolVal (condLabel)),
4873 /* now start putting them together */
4874 forTree = newNode (NULLOP, initExpr, condExpr);
4875 forTree = newNode (NULLOP, forTree, forBody);
4876 forTree = newNode (NULLOP, forTree, loopExpr);
4877 /* finally add the break label */
4878 forTree = newNode (NULLOP, forTree,
4879 createLabel (falseLabel, NULL));
4883 /*-----------------------------------------------------------------*/
4884 /* createWhile - creates parse tree for while statement */
4885 /* the while statement will be created as follows */
4887 /* _while_continue_n: */
4888 /* condition_expression +-> trueLabel -> _while_boby_n */
4890 /* +-> falseLabel -> _while_break_n */
4891 /* _while_body_n: */
4893 /* goto _while_continue_n */
4894 /* _while_break_n: */
4895 /*-----------------------------------------------------------------*/
4897 createWhile (symbol * trueLabel, symbol * continueLabel,
4898 symbol * falseLabel, ast * condExpr, ast * whileBody)
4902 /* put the continue label */
4903 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4904 condExpr = createLabel (continueLabel, condExpr);
4905 condExpr->lineno = 0;
4907 /* put the body label in front of the body */
4908 whileBody = createLabel (trueLabel, whileBody);
4909 whileBody->lineno = 0;
4910 /* put a jump to continue at the end of the body */
4911 /* and put break label at the end of the body */
4912 whileBody = newNode (NULLOP,
4915 newAst_VALUE (symbolVal (continueLabel)),
4916 createLabel (falseLabel, NULL)));
4918 /* put it all together */
4919 if (IS_IFX (condExpr))
4920 whileTree = condExpr;
4923 whileTree = newNode (IFX, condExpr, NULL);
4924 /* put the true & false labels in place */
4925 whileTree->trueLabel = trueLabel;
4926 whileTree->falseLabel = falseLabel;
4929 return newNode (NULLOP, whileTree, whileBody);
4932 /*-----------------------------------------------------------------*/
4933 /* isShiftRightLitVal _BitAndLitVal - helper function */
4934 /*-----------------------------------------------------------------*/
4936 isShiftRightLitVal_BitAndLitVal (ast * tree)
4938 /* if this is not a bit and */
4939 if (!IS_BITAND (tree))
4942 /* will look for tree of the form
4943 ( expr >> litval2) & litval1 */
4944 if (!IS_AST_LIT_VALUE (tree->right))
4947 if (!IS_RIGHT_OP (tree->left))
4950 if (!IS_AST_LIT_VALUE (tree->left->right))
4953 return tree->left->left;
4956 /*-----------------------------------------------------------------*/
4957 /* isBitAndPowOf2 - helper function */
4958 /*-----------------------------------------------------------------*/
4960 isBitAndPow2 (ast * tree)
4964 /* if this is not a bit and */
4965 if (!IS_BITAND (tree))
4968 /* will look for tree of the form
4969 ( expr & (1 << litval) */
4970 if (!IS_AST_LIT_VALUE (tree->right))
4973 if (AST_LIT_VALUE (tree->right) == 1)
4975 p2 = powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
4982 /*-----------------------------------------------------------------*/
4983 /* optimizeGetHbit - get highest order bit of the expression */
4984 /*-----------------------------------------------------------------*/
4986 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
4991 expr = isShiftRightLitVal_BitAndLitVal(tree);
4994 if ((AST_LIT_VALUE (tree->right) != 1) ||
4995 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4996 (j = (getSize (TTYPE (expr)) * 8 - 1))))
4999 if (!expr && (resultType == RESULT_TYPE_BIT))
5002 if (isBitAndPow2 (tree) != getSize (TTYPE (expr)) * 8 - 1)
5008 /* make sure the port supports GETHBIT */
5009 if (port->hasExtBitOp
5010 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5013 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5016 /*-----------------------------------------------------------------*/
5017 /* optimizeGetAbit - get a single bit of the expression */
5018 /*-----------------------------------------------------------------*/
5020 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5025 expr = isShiftRightLitVal_BitAndLitVal(tree);
5028 if (AST_LIT_VALUE (tree->right) != 1)
5030 count = tree->left->right;
5032 if (!expr && (resultType == RESULT_TYPE_BIT))
5034 int p2 = isBitAndPow2 (tree);
5038 count = newAst_VALUE (valueFromLit (p2));
5044 /* make sure the port supports GETABIT */
5045 if (port->hasExtBitOp
5046 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5049 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5053 /*-----------------------------------------------------------------*/
5054 /* optimizeGetByte - get a byte of the expression */
5055 /*-----------------------------------------------------------------*/
5057 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5063 expr = isShiftRightLitVal_BitAndLitVal(tree);
5066 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5067 count = tree->left->right;
5068 if (AST_LIT_VALUE (tree->right) != 0xFF)
5071 if (!expr && resultType == RESULT_TYPE_CHAR)
5073 /* if this is a right shift over a multiple of 8 */
5074 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5076 i = (unsigned int) AST_LIT_VALUE (tree->right);
5077 count = tree->right;
5081 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5084 /* make sure the port supports GETBYTE */
5085 if (port->hasExtBitOp
5086 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5089 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5092 /*-----------------------------------------------------------------*/
5093 /* optimizeGetWord - get two bytes of the expression */
5094 /*-----------------------------------------------------------------*/
5096 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5102 expr = isShiftRightLitVal_BitAndLitVal(tree);
5105 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5106 count = tree->left->right;
5107 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5110 if (!expr && resultType == RESULT_TYPE_INT)
5112 /* if this is a right shift over a multiple of 8 */
5113 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5115 i = (unsigned int) AST_LIT_VALUE (tree->right);
5116 count = tree->right;
5120 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5123 /* make sure the port supports GETWORD */
5124 if (port->hasExtBitOp
5125 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5128 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5131 /*-----------------------------------------------------------------*/
5132 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5133 /*-----------------------------------------------------------------*/
5135 optimizeRRCRLC (ast * root)
5137 /* will look for trees of the form
5138 (?expr << 1) | (?expr >> 7) or
5139 (?expr >> 7) | (?expr << 1) will make that
5140 into a RLC : operation ..
5142 (?expr >> 1) | (?expr << 7) or
5143 (?expr << 7) | (?expr >> 1) will make that
5144 into a RRC operation
5145 note : by 7 I mean (number of bits required to hold the
5147 /* if the root operations is not a | operation the not */
5148 if (!IS_BITOR (root))
5151 /* I have to think of a better way to match patterns this sucks */
5152 /* that aside let start looking for the first case : I use a the
5153 negative check a lot to improve the efficiency */
5154 /* (?expr << 1) | (?expr >> 7) */
5155 if (IS_LEFT_OP (root->left) &&
5156 IS_RIGHT_OP (root->right))
5159 if (!SPEC_USIGN (TETYPE (root->left->left)))
5162 if (!IS_AST_LIT_VALUE (root->left->right) ||
5163 !IS_AST_LIT_VALUE (root->right->right))
5166 /* make sure it is the same expression */
5167 if (!isAstEqual (root->left->left,
5171 if (AST_LIT_VALUE (root->left->right) != 1)
5174 if (AST_LIT_VALUE (root->right->right) !=
5175 (getSize (TTYPE (root->left->left)) * 8 - 1))
5178 /* make sure the port supports RLC */
5179 if (port->hasExtBitOp
5180 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5183 /* whew got the first case : create the AST */
5184 return newNode (RLC, root->left->left, NULL);
5188 /* check for second case */
5189 /* (?expr >> 7) | (?expr << 1) */
5190 if (IS_LEFT_OP (root->right) &&
5191 IS_RIGHT_OP (root->left))
5194 if (!SPEC_USIGN (TETYPE (root->left->left)))
5197 if (!IS_AST_LIT_VALUE (root->left->right) ||
5198 !IS_AST_LIT_VALUE (root->right->right))
5201 /* make sure it is the same symbol */
5202 if (!isAstEqual (root->left->left,
5206 if (AST_LIT_VALUE (root->right->right) != 1)
5209 if (AST_LIT_VALUE (root->left->right) !=
5210 (getSize (TTYPE (root->left->left)) * 8 - 1))
5213 /* make sure the port supports RLC */
5214 if (port->hasExtBitOp
5215 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5218 /* whew got the first case : create the AST */
5219 return newNode (RLC, root->left->left, NULL);
5224 /* third case for RRC */
5225 /* (?symbol >> 1) | (?symbol << 7) */
5226 if (IS_LEFT_OP (root->right) &&
5227 IS_RIGHT_OP (root->left))
5230 if (!SPEC_USIGN (TETYPE (root->left->left)))
5233 if (!IS_AST_LIT_VALUE (root->left->right) ||
5234 !IS_AST_LIT_VALUE (root->right->right))
5237 /* make sure it is the same symbol */
5238 if (!isAstEqual (root->left->left,
5242 if (AST_LIT_VALUE (root->left->right) != 1)
5245 if (AST_LIT_VALUE (root->right->right) !=
5246 (getSize (TTYPE (root->left->left)) * 8 - 1))
5249 /* make sure the port supports RRC */
5250 if (port->hasExtBitOp
5251 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5254 /* whew got the first case : create the AST */
5255 return newNode (RRC, root->left->left, NULL);
5259 /* fourth and last case for now */
5260 /* (?symbol << 7) | (?symbol >> 1) */
5261 if (IS_RIGHT_OP (root->right) &&
5262 IS_LEFT_OP (root->left))
5265 if (!SPEC_USIGN (TETYPE (root->left->left)))
5268 if (!IS_AST_LIT_VALUE (root->left->right) ||
5269 !IS_AST_LIT_VALUE (root->right->right))
5272 /* make sure it is the same symbol */
5273 if (!isAstEqual (root->left->left,
5277 if (AST_LIT_VALUE (root->right->right) != 1)
5280 if (AST_LIT_VALUE (root->left->right) !=
5281 (getSize (TTYPE (root->left->left)) * 8 - 1))
5284 /* make sure the port supports RRC */
5285 if (port->hasExtBitOp
5286 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5289 /* whew got the first case : create the AST */
5290 return newNode (RRC, root->left->left, NULL);
5294 /* not found return root */
5298 /*-----------------------------------------------------------------*/
5299 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5300 /*-----------------------------------------------------------------*/
5302 optimizeSWAP (ast * root)
5304 /* will look for trees of the form
5305 (?expr << 4) | (?expr >> 4) or
5306 (?expr >> 4) | (?expr << 4) will make that
5307 into a SWAP : operation ..
5308 note : by 4 I mean (number of bits required to hold the
5310 /* if the root operations is not a | operation the not */
5311 if (!IS_BITOR (root))
5314 /* (?expr << 4) | (?expr >> 4) */
5315 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5316 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5319 if (!SPEC_USIGN (TETYPE (root->left->left)))
5322 if (!IS_AST_LIT_VALUE (root->left->right) ||
5323 !IS_AST_LIT_VALUE (root->right->right))
5326 /* make sure it is the same expression */
5327 if (!isAstEqual (root->left->left,
5331 if (AST_LIT_VALUE (root->left->right) !=
5332 (getSize (TTYPE (root->left->left)) * 4))
5335 if (AST_LIT_VALUE (root->right->right) !=
5336 (getSize (TTYPE (root->left->left)) * 4))
5339 /* make sure the port supports SWAP */
5340 if (port->hasExtBitOp
5341 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5344 /* found it : create the AST */
5345 return newNode (SWAP, root->left->left, NULL);
5349 /* not found return root */
5353 /*-----------------------------------------------------------------*/
5354 /* optimizeCompare - optimizes compares for bit variables */
5355 /*-----------------------------------------------------------------*/
5357 optimizeCompare (ast * root)
5359 ast *optExpr = NULL;
5362 unsigned int litValue;
5364 /* if nothing then return nothing */
5368 /* if not a compare op then do leaves */
5369 if (!IS_COMPARE_OP (root))
5371 root->left = optimizeCompare (root->left);
5372 root->right = optimizeCompare (root->right);
5376 /* if left & right are the same then depending
5377 of the operation do */
5378 if (isAstEqual (root->left, root->right))
5380 switch (root->opval.op)
5385 optExpr = newAst_VALUE (constVal ("0"));
5390 optExpr = newAst_VALUE (constVal ("1"));
5394 return decorateType (optExpr, RESULT_TYPE_NONE);
5397 vleft = (root->left->type == EX_VALUE ?
5398 root->left->opval.val : NULL);
5400 vright = (root->right->type == EX_VALUE ?
5401 root->right->opval.val : NULL);
5403 /* if left is a BITVAR in BITSPACE */
5404 /* and right is a LITERAL then opt- */
5405 /* imize else do nothing */
5406 if (vleft && vright &&
5407 IS_BITVAR (vleft->etype) &&
5408 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5409 IS_LITERAL (vright->etype))
5412 /* if right side > 1 then comparison may never succeed */
5413 if ((litValue = (int) floatFromVal (vright)) > 1)
5415 werror (W_BAD_COMPARE);
5421 switch (root->opval.op)
5423 case '>': /* bit value greater than 1 cannot be */
5424 werror (W_BAD_COMPARE);
5428 case '<': /* bit value < 1 means 0 */
5430 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5433 case LE_OP: /* bit value <= 1 means no check */
5434 optExpr = newAst_VALUE (vright);
5437 case GE_OP: /* bit value >= 1 means only check for = */
5439 optExpr = newAst_VALUE (vleft);
5444 { /* literal is zero */
5445 switch (root->opval.op)
5447 case '<': /* bit value < 0 cannot be */
5448 werror (W_BAD_COMPARE);
5452 case '>': /* bit value > 0 means 1 */
5454 optExpr = newAst_VALUE (vleft);
5457 case LE_OP: /* bit value <= 0 means no check */
5458 case GE_OP: /* bit value >= 0 means no check */
5459 werror (W_BAD_COMPARE);
5463 case EQ_OP: /* bit == 0 means ! of bit */
5464 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5468 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5469 } /* end-of-if of BITVAR */
5474 /*-----------------------------------------------------------------*/
5475 /* addSymToBlock : adds the symbol to the first block we find */
5476 /*-----------------------------------------------------------------*/
5478 addSymToBlock (symbol * sym, ast * tree)
5480 /* reached end of tree or a leaf */
5481 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5485 if (IS_AST_OP (tree) &&
5486 tree->opval.op == BLOCK)
5489 symbol *lsym = copySymbol (sym);
5491 lsym->next = AST_VALUES (tree, sym);
5492 AST_VALUES (tree, sym) = lsym;
5496 addSymToBlock (sym, tree->left);
5497 addSymToBlock (sym, tree->right);
5500 /*-----------------------------------------------------------------*/
5501 /* processRegParms - do processing for register parameters */
5502 /*-----------------------------------------------------------------*/
5504 processRegParms (value * args, ast * body)
5508 if (IS_REGPARM (args->etype))
5509 addSymToBlock (args->sym, body);
5514 /*-----------------------------------------------------------------*/
5515 /* resetParmKey - resets the operandkeys for the symbols */
5516 /*-----------------------------------------------------------------*/
5517 DEFSETFUNC (resetParmKey)
5528 /*-----------------------------------------------------------------*/
5529 /* createFunction - This is the key node that calls the iCode for */
5530 /* generating the code for a function. Note code */
5531 /* is generated function by function, later when */
5532 /* add inter-procedural analysis this will change */
5533 /*-----------------------------------------------------------------*/
5535 createFunction (symbol * name, ast * body)
5541 iCode *piCode = NULL;
5543 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5544 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5546 /* if check function return 0 then some problem */
5547 if (checkFunction (name, NULL) == 0)
5550 /* create a dummy block if none exists */
5552 body = newNode (BLOCK, NULL, NULL);
5556 /* check if the function name already in the symbol table */
5557 if ((csym = findSym (SymbolTab, NULL, name->name)))
5560 /* special case for compiler defined functions
5561 we need to add the name to the publics list : this
5562 actually means we are now compiling the compiler
5566 addSet (&publics, name);
5571 addSymChain (&name);
5572 allocVariables (name);
5574 name->lastLine = mylineno;
5577 /* set the stack pointer */
5578 stackPtr = -port->stack.direction * port->stack.call_overhead;
5581 if (IFFUNC_ISISR (name->type))
5582 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5584 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5586 if (options.useXstack)
5587 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5589 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5592 fetype = getSpec (name->type); /* get the specifier for the function */
5593 /* if this is a reentrant function then */
5594 if (IFFUNC_ISREENT (name->type))
5597 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5599 /* do processing for parameters that are passed in registers */
5600 processRegParms (FUNC_ARGS(name->type), body);
5602 /* set the stack pointer */
5606 /* allocate & autoinit the block variables */
5607 processBlockVars (body, &stack, ALLOCATE);
5609 /* save the stack information */
5610 if (options.useXstack)
5611 name->xstack = SPEC_STAK (fetype) = stack;
5613 name->stack = SPEC_STAK (fetype) = stack;
5615 /* name needs to be mangled */
5616 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5618 body = resolveSymbols (body); /* resolve the symbols */
5619 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5622 ex = newAst_VALUE (symbolVal (name)); /* create name */
5623 ex = newNode (FUNCTION, ex, body);
5624 ex->values.args = FUNC_ARGS(name->type);
5626 if (options.dump_tree) PA(ex);
5629 werror (E_FUNC_NO_CODE, name->name);
5633 /* create the node & generate intermediate code */
5635 codeOutFile = code->oFile;
5636 piCode = iCodeFromAst (ex);
5640 werror (E_FUNC_NO_CODE, name->name);
5644 eBBlockFromiCode (piCode);
5646 /* if there are any statics then do them */
5649 GcurMemmap = statsg;
5650 codeOutFile = statsg->oFile;
5651 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5657 /* dealloc the block variables */
5658 processBlockVars (body, &stack, DEALLOCATE);
5659 outputDebugStackSymbols();
5660 /* deallocate paramaters */
5661 deallocParms (FUNC_ARGS(name->type));
5663 if (IFFUNC_ISREENT (name->type))
5666 /* we are done freeup memory & cleanup */
5668 if (port->reset_labelKey) labelKey = 1;
5670 FUNC_HASBODY(name->type) = 1;
5671 addSet (&operKeyReset, name);
5672 applyToSet (operKeyReset, resetParmKey);
5677 cleanUpLevel (LabelTab, 0);
5678 cleanUpBlock (StructTab, 1);
5679 cleanUpBlock (TypedefTab, 1);
5681 xstack->syms = NULL;
5682 istack->syms = NULL;
5687 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5688 /*-----------------------------------------------------------------*/
5689 /* ast_print : prints the ast (for debugging purposes) */
5690 /*-----------------------------------------------------------------*/
5692 void ast_print (ast * tree, FILE *outfile, int indent)
5697 /* can print only decorated trees */
5698 if (!tree->decorated) return;
5700 /* if any child is an error | this one is an error do nothing */
5701 if (tree->isError ||
5702 (tree->left && tree->left->isError) ||
5703 (tree->right && tree->right->isError)) {
5704 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5708 /* print the line */
5709 /* if not block & function */
5710 if (tree->type == EX_OP &&
5711 (tree->opval.op != FUNCTION &&
5712 tree->opval.op != BLOCK &&
5713 tree->opval.op != NULLOP)) {
5716 if (tree->opval.op == FUNCTION) {
5718 value *args=FUNC_ARGS(tree->left->opval.val->type);
5719 fprintf(outfile,"FUNCTION (%s=%p) type (",
5720 tree->left->opval.val->name, tree);
5721 printTypeChain (tree->left->opval.val->type->next,outfile);
5722 fprintf(outfile,") args (");
5725 fprintf (outfile, ", ");
5727 printTypeChain (args ? args->type : NULL, outfile);
5729 args= args ? args->next : NULL;
5731 fprintf(outfile,")\n");
5732 ast_print(tree->left,outfile,indent);
5733 ast_print(tree->right,outfile,indent);
5736 if (tree->opval.op == BLOCK) {
5737 symbol *decls = tree->values.sym;
5738 INDENT(indent,outfile);
5739 fprintf(outfile,"{\n");
5741 INDENT(indent+2,outfile);
5742 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5743 decls->name, decls);
5744 printTypeChain(decls->type,outfile);
5745 fprintf(outfile,")\n");
5747 decls = decls->next;
5749 ast_print(tree->right,outfile,indent+2);
5750 INDENT(indent,outfile);
5751 fprintf(outfile,"}\n");
5754 if (tree->opval.op == NULLOP) {
5755 ast_print(tree->left,outfile,indent);
5756 ast_print(tree->right,outfile,indent);
5759 INDENT(indent,outfile);
5761 /*------------------------------------------------------------------*/
5762 /*----------------------------*/
5763 /* leaf has been reached */
5764 /*----------------------------*/
5765 /* if this is of type value */
5766 /* just get the type */
5767 if (tree->type == EX_VALUE) {
5769 if (IS_LITERAL (tree->opval.val->etype)) {
5770 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5771 if (SPEC_USIGN (tree->opval.val->etype))
5772 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5774 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5775 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5776 floatFromVal(tree->opval.val));
5777 } else if (tree->opval.val->sym) {
5778 /* if the undefined flag is set then give error message */
5779 if (tree->opval.val->sym->undefined) {
5780 fprintf(outfile,"UNDEFINED SYMBOL ");
5782 fprintf(outfile,"SYMBOL ");
5784 fprintf(outfile,"(%s=%p)",
5785 tree->opval.val->sym->name,tree);
5788 fprintf(outfile," type (");
5789 printTypeChain(tree->ftype,outfile);
5790 fprintf(outfile,")\n");
5792 fprintf(outfile,"\n");
5797 /* if type link for the case of cast */
5798 if (tree->type == EX_LINK) {
5799 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5800 printTypeChain(tree->opval.lnk,outfile);
5801 fprintf(outfile,")\n");
5806 /* depending on type of operator do */
5808 switch (tree->opval.op) {
5809 /*------------------------------------------------------------------*/
5810 /*----------------------------*/
5812 /*----------------------------*/
5814 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5815 printTypeChain(tree->ftype,outfile);
5816 fprintf(outfile,")\n");
5817 ast_print(tree->left,outfile,indent+2);
5818 ast_print(tree->right,outfile,indent+2);
5821 /*------------------------------------------------------------------*/
5822 /*----------------------------*/
5824 /*----------------------------*/
5826 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5827 printTypeChain(tree->ftype,outfile);
5828 fprintf(outfile,")\n");
5829 ast_print(tree->left,outfile,indent+2);
5830 ast_print(tree->right,outfile,indent+2);
5833 /*------------------------------------------------------------------*/
5834 /*----------------------------*/
5835 /* struct/union pointer */
5836 /*----------------------------*/
5838 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5839 printTypeChain(tree->ftype,outfile);
5840 fprintf(outfile,")\n");
5841 ast_print(tree->left,outfile,indent+2);
5842 ast_print(tree->right,outfile,indent+2);
5845 /*------------------------------------------------------------------*/
5846 /*----------------------------*/
5847 /* ++/-- operation */
5848 /*----------------------------*/
5851 fprintf(outfile,"post-");
5853 fprintf(outfile,"pre-");
5854 fprintf(outfile,"INC_OP (%p) type (",tree);
5855 printTypeChain(tree->ftype,outfile);
5856 fprintf(outfile,")\n");
5857 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5858 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5863 fprintf(outfile,"post-");
5865 fprintf(outfile,"pre-");
5866 fprintf(outfile,"DEC_OP (%p) type (",tree);
5867 printTypeChain(tree->ftype,outfile);
5868 fprintf(outfile,")\n");
5869 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5870 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5873 /*------------------------------------------------------------------*/
5874 /*----------------------------*/
5876 /*----------------------------*/
5879 fprintf(outfile,"& (%p) type (",tree);
5880 printTypeChain(tree->ftype,outfile);
5881 fprintf(outfile,")\n");
5882 ast_print(tree->left,outfile,indent+2);
5883 ast_print(tree->right,outfile,indent+2);
5885 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5886 printTypeChain(tree->ftype,outfile);
5887 fprintf(outfile,")\n");
5888 ast_print(tree->left,outfile,indent+2);
5889 ast_print(tree->right,outfile,indent+2);
5892 /*----------------------------*/
5894 /*----------------------------*/
5896 fprintf(outfile,"OR (%p) type (",tree);
5897 printTypeChain(tree->ftype,outfile);
5898 fprintf(outfile,")\n");
5899 ast_print(tree->left,outfile,indent+2);
5900 ast_print(tree->right,outfile,indent+2);
5902 /*------------------------------------------------------------------*/
5903 /*----------------------------*/
5905 /*----------------------------*/
5907 fprintf(outfile,"XOR (%p) type (",tree);
5908 printTypeChain(tree->ftype,outfile);
5909 fprintf(outfile,")\n");
5910 ast_print(tree->left,outfile,indent+2);
5911 ast_print(tree->right,outfile,indent+2);
5914 /*------------------------------------------------------------------*/
5915 /*----------------------------*/
5917 /*----------------------------*/
5919 fprintf(outfile,"DIV (%p) type (",tree);
5920 printTypeChain(tree->ftype,outfile);
5921 fprintf(outfile,")\n");
5922 ast_print(tree->left,outfile,indent+2);
5923 ast_print(tree->right,outfile,indent+2);
5925 /*------------------------------------------------------------------*/
5926 /*----------------------------*/
5928 /*----------------------------*/
5930 fprintf(outfile,"MOD (%p) type (",tree);
5931 printTypeChain(tree->ftype,outfile);
5932 fprintf(outfile,")\n");
5933 ast_print(tree->left,outfile,indent+2);
5934 ast_print(tree->right,outfile,indent+2);
5937 /*------------------------------------------------------------------*/
5938 /*----------------------------*/
5939 /* address dereference */
5940 /*----------------------------*/
5941 case '*': /* can be unary : if right is null then unary operation */
5943 fprintf(outfile,"DEREF (%p) type (",tree);
5944 printTypeChain(tree->ftype,outfile);
5945 fprintf(outfile,")\n");
5946 ast_print(tree->left,outfile,indent+2);
5949 /*------------------------------------------------------------------*/
5950 /*----------------------------*/
5951 /* multiplication */
5952 /*----------------------------*/
5953 fprintf(outfile,"MULT (%p) type (",tree);
5954 printTypeChain(tree->ftype,outfile);
5955 fprintf(outfile,")\n");
5956 ast_print(tree->left,outfile,indent+2);
5957 ast_print(tree->right,outfile,indent+2);
5961 /*------------------------------------------------------------------*/
5962 /*----------------------------*/
5963 /* unary '+' operator */
5964 /*----------------------------*/
5968 fprintf(outfile,"UPLUS (%p) type (",tree);
5969 printTypeChain(tree->ftype,outfile);
5970 fprintf(outfile,")\n");
5971 ast_print(tree->left,outfile,indent+2);
5973 /*------------------------------------------------------------------*/
5974 /*----------------------------*/
5976 /*----------------------------*/
5977 fprintf(outfile,"ADD (%p) type (",tree);
5978 printTypeChain(tree->ftype,outfile);
5979 fprintf(outfile,")\n");
5980 ast_print(tree->left,outfile,indent+2);
5981 ast_print(tree->right,outfile,indent+2);
5984 /*------------------------------------------------------------------*/
5985 /*----------------------------*/
5987 /*----------------------------*/
5988 case '-': /* can be unary */
5990 fprintf(outfile,"UMINUS (%p) type (",tree);
5991 printTypeChain(tree->ftype,outfile);
5992 fprintf(outfile,")\n");
5993 ast_print(tree->left,outfile,indent+2);
5995 /*------------------------------------------------------------------*/
5996 /*----------------------------*/
5998 /*----------------------------*/
5999 fprintf(outfile,"SUB (%p) type (",tree);
6000 printTypeChain(tree->ftype,outfile);
6001 fprintf(outfile,")\n");
6002 ast_print(tree->left,outfile,indent+2);
6003 ast_print(tree->right,outfile,indent+2);
6006 /*------------------------------------------------------------------*/
6007 /*----------------------------*/
6009 /*----------------------------*/
6011 fprintf(outfile,"COMPL (%p) type (",tree);
6012 printTypeChain(tree->ftype,outfile);
6013 fprintf(outfile,")\n");
6014 ast_print(tree->left,outfile,indent+2);
6016 /*------------------------------------------------------------------*/
6017 /*----------------------------*/
6019 /*----------------------------*/
6021 fprintf(outfile,"NOT (%p) type (",tree);
6022 printTypeChain(tree->ftype,outfile);
6023 fprintf(outfile,")\n");
6024 ast_print(tree->left,outfile,indent+2);
6026 /*------------------------------------------------------------------*/
6027 /*----------------------------*/
6029 /*----------------------------*/
6031 fprintf(outfile,"RRC (%p) type (",tree);
6032 printTypeChain(tree->ftype,outfile);
6033 fprintf(outfile,")\n");
6034 ast_print(tree->left,outfile,indent+2);
6038 fprintf(outfile,"RLC (%p) type (",tree);
6039 printTypeChain(tree->ftype,outfile);
6040 fprintf(outfile,")\n");
6041 ast_print(tree->left,outfile,indent+2);
6044 fprintf(outfile,"SWAP (%p) type (",tree);
6045 printTypeChain(tree->ftype,outfile);
6046 fprintf(outfile,")\n");
6047 ast_print(tree->left,outfile,indent+2);
6050 fprintf(outfile,"GETHBIT (%p) type (",tree);
6051 printTypeChain(tree->ftype,outfile);
6052 fprintf(outfile,")\n");
6053 ast_print(tree->left,outfile,indent+2);
6056 fprintf(outfile,"GETABIT (%p) type (",tree);
6057 printTypeChain(tree->ftype,outfile);
6058 fprintf(outfile,")\n");
6059 ast_print(tree->left,outfile,indent+2);
6060 ast_print(tree->right,outfile,indent+2);
6063 fprintf(outfile,"GETBYTE (%p) type (",tree);
6064 printTypeChain(tree->ftype,outfile);
6065 fprintf(outfile,")\n");
6066 ast_print(tree->left,outfile,indent+2);
6067 ast_print(tree->right,outfile,indent+2);
6070 fprintf(outfile,"GETWORD (%p) type (",tree);
6071 printTypeChain(tree->ftype,outfile);
6072 fprintf(outfile,")\n");
6073 ast_print(tree->left,outfile,indent+2);
6074 ast_print(tree->right,outfile,indent+2);
6077 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6078 printTypeChain(tree->ftype,outfile);
6079 fprintf(outfile,")\n");
6080 ast_print(tree->left,outfile,indent+2);
6081 ast_print(tree->right,outfile,indent+2);
6084 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6085 printTypeChain(tree->ftype,outfile);
6086 fprintf(outfile,")\n");
6087 ast_print(tree->left,outfile,indent+2);
6088 ast_print(tree->right,outfile,indent+2);
6090 /*------------------------------------------------------------------*/
6091 /*----------------------------*/
6093 /*----------------------------*/
6094 case CAST: /* change the type */
6095 fprintf(outfile,"CAST (%p) from type (",tree);
6096 printTypeChain(tree->right->ftype,outfile);
6097 fprintf(outfile,") to type (");
6098 printTypeChain(tree->ftype,outfile);
6099 fprintf(outfile,")\n");
6100 ast_print(tree->right,outfile,indent+2);
6104 fprintf(outfile,"ANDAND (%p) type (",tree);
6105 printTypeChain(tree->ftype,outfile);
6106 fprintf(outfile,")\n");
6107 ast_print(tree->left,outfile,indent+2);
6108 ast_print(tree->right,outfile,indent+2);
6111 fprintf(outfile,"OROR (%p) type (",tree);
6112 printTypeChain(tree->ftype,outfile);
6113 fprintf(outfile,")\n");
6114 ast_print(tree->left,outfile,indent+2);
6115 ast_print(tree->right,outfile,indent+2);
6118 /*------------------------------------------------------------------*/
6119 /*----------------------------*/
6120 /* comparison operators */
6121 /*----------------------------*/
6123 fprintf(outfile,"GT(>) (%p) type (",tree);
6124 printTypeChain(tree->ftype,outfile);
6125 fprintf(outfile,")\n");
6126 ast_print(tree->left,outfile,indent+2);
6127 ast_print(tree->right,outfile,indent+2);
6130 fprintf(outfile,"LT(<) (%p) type (",tree);
6131 printTypeChain(tree->ftype,outfile);
6132 fprintf(outfile,")\n");
6133 ast_print(tree->left,outfile,indent+2);
6134 ast_print(tree->right,outfile,indent+2);
6137 fprintf(outfile,"LE(<=) (%p) type (",tree);
6138 printTypeChain(tree->ftype,outfile);
6139 fprintf(outfile,")\n");
6140 ast_print(tree->left,outfile,indent+2);
6141 ast_print(tree->right,outfile,indent+2);
6144 fprintf(outfile,"GE(>=) (%p) type (",tree);
6145 printTypeChain(tree->ftype,outfile);
6146 fprintf(outfile,")\n");
6147 ast_print(tree->left,outfile,indent+2);
6148 ast_print(tree->right,outfile,indent+2);
6151 fprintf(outfile,"EQ(==) (%p) type (",tree);
6152 printTypeChain(tree->ftype,outfile);
6153 fprintf(outfile,")\n");
6154 ast_print(tree->left,outfile,indent+2);
6155 ast_print(tree->right,outfile,indent+2);
6158 fprintf(outfile,"NE(!=) (%p) type (",tree);
6159 printTypeChain(tree->ftype,outfile);
6160 fprintf(outfile,")\n");
6161 ast_print(tree->left,outfile,indent+2);
6162 ast_print(tree->right,outfile,indent+2);
6163 /*------------------------------------------------------------------*/
6164 /*----------------------------*/
6166 /*----------------------------*/
6167 case SIZEOF: /* evaluate wihout code generation */
6168 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6171 /*------------------------------------------------------------------*/
6172 /*----------------------------*/
6173 /* conditional operator '?' */
6174 /*----------------------------*/
6176 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6177 printTypeChain(tree->ftype,outfile);
6178 fprintf(outfile,")\n");
6179 ast_print(tree->left,outfile,indent+2);
6180 ast_print(tree->right,outfile,indent+2);
6184 fprintf(outfile,"COLON(:) (%p) type (",tree);
6185 printTypeChain(tree->ftype,outfile);
6186 fprintf(outfile,")\n");
6187 ast_print(tree->left,outfile,indent+2);
6188 ast_print(tree->right,outfile,indent+2);
6191 /*------------------------------------------------------------------*/
6192 /*----------------------------*/
6193 /* assignment operators */
6194 /*----------------------------*/
6196 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6197 printTypeChain(tree->ftype,outfile);
6198 fprintf(outfile,")\n");
6199 ast_print(tree->left,outfile,indent+2);
6200 ast_print(tree->right,outfile,indent+2);
6203 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6204 printTypeChain(tree->ftype,outfile);
6205 fprintf(outfile,")\n");
6206 ast_print(tree->left,outfile,indent+2);
6207 ast_print(tree->right,outfile,indent+2);
6210 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6211 printTypeChain(tree->ftype,outfile);
6212 fprintf(outfile,")\n");
6213 ast_print(tree->left,outfile,indent+2);
6214 ast_print(tree->right,outfile,indent+2);
6217 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6218 printTypeChain(tree->ftype,outfile);
6219 fprintf(outfile,")\n");
6220 ast_print(tree->left,outfile,indent+2);
6221 ast_print(tree->right,outfile,indent+2);
6224 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6225 printTypeChain(tree->ftype,outfile);
6226 fprintf(outfile,")\n");
6227 ast_print(tree->left,outfile,indent+2);
6228 ast_print(tree->right,outfile,indent+2);
6231 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6232 printTypeChain(tree->ftype,outfile);
6233 fprintf(outfile,")\n");
6234 ast_print(tree->left,outfile,indent+2);
6235 ast_print(tree->right,outfile,indent+2);
6238 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6239 printTypeChain(tree->ftype,outfile);
6240 fprintf(outfile,")\n");
6241 ast_print(tree->left,outfile,indent+2);
6242 ast_print(tree->right,outfile,indent+2);
6244 /*------------------------------------------------------------------*/
6245 /*----------------------------*/
6247 /*----------------------------*/
6249 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6250 printTypeChain(tree->ftype,outfile);
6251 fprintf(outfile,")\n");
6252 ast_print(tree->left,outfile,indent+2);
6253 ast_print(tree->right,outfile,indent+2);
6255 /*------------------------------------------------------------------*/
6256 /*----------------------------*/
6258 /*----------------------------*/
6260 fprintf(outfile,"ADDASS(+=) (%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);
6266 /*------------------------------------------------------------------*/
6267 /*----------------------------*/
6268 /* straight assignemnt */
6269 /*----------------------------*/
6271 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6272 printTypeChain(tree->ftype,outfile);
6273 fprintf(outfile,")\n");
6274 ast_print(tree->left,outfile,indent+2);
6275 ast_print(tree->right,outfile,indent+2);
6277 /*------------------------------------------------------------------*/
6278 /*----------------------------*/
6279 /* comma operator */
6280 /*----------------------------*/
6282 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6283 printTypeChain(tree->ftype,outfile);
6284 fprintf(outfile,")\n");
6285 ast_print(tree->left,outfile,indent+2);
6286 ast_print(tree->right,outfile,indent+2);
6288 /*------------------------------------------------------------------*/
6289 /*----------------------------*/
6291 /*----------------------------*/
6294 fprintf(outfile,"CALL (%p) type (",tree);
6295 printTypeChain(tree->ftype,outfile);
6296 fprintf(outfile,")\n");
6297 ast_print(tree->left,outfile,indent+2);
6298 ast_print(tree->right,outfile,indent+2);
6301 fprintf(outfile,"PARMS\n");
6302 ast_print(tree->left,outfile,indent+2);
6303 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6304 ast_print(tree->right,outfile,indent+2);
6307 /*------------------------------------------------------------------*/
6308 /*----------------------------*/
6309 /* return statement */
6310 /*----------------------------*/
6312 fprintf(outfile,"RETURN (%p) type (",tree);
6314 printTypeChain(tree->right->ftype,outfile);
6316 fprintf(outfile,")\n");
6317 ast_print(tree->right,outfile,indent+2);
6319 /*------------------------------------------------------------------*/
6320 /*----------------------------*/
6321 /* label statement */
6322 /*----------------------------*/
6324 fprintf(outfile,"LABEL (%p)\n",tree);
6325 ast_print(tree->left,outfile,indent+2);
6326 ast_print(tree->right,outfile,indent);
6328 /*------------------------------------------------------------------*/
6329 /*----------------------------*/
6330 /* switch statement */
6331 /*----------------------------*/
6335 fprintf(outfile,"SWITCH (%p) ",tree);
6336 ast_print(tree->left,outfile,0);
6337 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6338 INDENT(indent+2,outfile);
6339 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6340 (int) floatFromVal(val),
6341 tree->values.switchVals.swNum,
6342 (int) floatFromVal(val));
6344 ast_print(tree->right,outfile,indent);
6347 /*------------------------------------------------------------------*/
6348 /*----------------------------*/
6350 /*----------------------------*/
6352 fprintf(outfile,"IF (%p) \n",tree);
6353 ast_print(tree->left,outfile,indent+2);
6354 if (tree->trueLabel) {
6355 INDENT(indent+2,outfile);
6356 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6358 if (tree->falseLabel) {
6359 INDENT(indent+2,outfile);
6360 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6362 ast_print(tree->right,outfile,indent+2);
6364 /*----------------------------*/
6365 /* goto Statement */
6366 /*----------------------------*/
6368 fprintf(outfile,"GOTO (%p) \n",tree);
6369 ast_print(tree->left,outfile,indent+2);
6370 fprintf(outfile,"\n");
6372 /*------------------------------------------------------------------*/
6373 /*----------------------------*/
6375 /*----------------------------*/
6377 fprintf(outfile,"FOR (%p) \n",tree);
6378 if (AST_FOR( tree, initExpr)) {
6379 INDENT(indent+2,outfile);
6380 fprintf(outfile,"INIT EXPR ");
6381 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6383 if (AST_FOR( tree, condExpr)) {
6384 INDENT(indent+2,outfile);
6385 fprintf(outfile,"COND EXPR ");
6386 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6388 if (AST_FOR( tree, loopExpr)) {
6389 INDENT(indent+2,outfile);
6390 fprintf(outfile,"LOOP EXPR ");
6391 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6393 fprintf(outfile,"FOR LOOP BODY \n");
6394 ast_print(tree->left,outfile,indent+2);
6397 fprintf(outfile,"CRITICAL (%p) \n",tree);
6398 ast_print(tree->left,outfile,indent+2);
6406 ast_print(t,stdout,0);
6411 /*-----------------------------------------------------------------*/
6412 /* astErrors : returns non-zero if errors present in tree */
6413 /*-----------------------------------------------------------------*/
6414 int astErrors(ast *t)
6423 if (t->type == EX_VALUE
6424 && t->opval.val->sym
6425 && t->opval.val->sym->undefined)
6428 errors += astErrors(t->left);
6429 errors += astErrors(t->right);