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 DCL_ELEM (type) = size;
997 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1001 /*-----------------------------------------------------------------*/
1002 /* createIvalCharPtr - generates initial values for char pointers */
1003 /*-----------------------------------------------------------------*/
1005 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
1009 /* if this is a pointer & right is a literal array then */
1010 /* just assignment will do */
1011 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1012 SPEC_SCLS (iexpr->etype) == S_CODE)
1013 && IS_ARRAY (iexpr->ftype)))
1014 return newNode ('=', sym, iexpr);
1016 /* left side is an array so we have to assign each */
1018 if ((IS_LITERAL (iexpr->etype) ||
1019 SPEC_SCLS (iexpr->etype) == S_CODE)
1020 && IS_ARRAY (iexpr->ftype))
1022 /* for each character generate an assignment */
1023 /* to the array element */
1024 char *s = SPEC_CVAL (iexpr->etype).v_char;
1026 int size = getSize (iexpr->ftype);
1027 int symsize = getSize (type);
1031 if (size>(symsize+1))
1033 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1035 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1041 for (i=0;i<size;i++)
1043 rast = newNode (NULLOP,
1047 newAst_VALUE (valueFromLit ((float) i))),
1048 newAst_VALUE (valueFromLit (*s))));
1052 // now WE don't need iexpr's symbol anymore
1053 freeStringSymbol(AST_SYMBOL(iexpr));
1055 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1061 /*-----------------------------------------------------------------*/
1062 /* createIvalPtr - generates initial value for pointers */
1063 /*-----------------------------------------------------------------*/
1065 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1071 if (ilist->type == INIT_DEEP)
1072 ilist = ilist->init.deep;
1074 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1076 /* if character pointer */
1077 if (IS_CHAR (type->next))
1078 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1081 return newNode ('=', sym, iexpr);
1084 /*-----------------------------------------------------------------*/
1085 /* createIval - generates code for initial value */
1086 /*-----------------------------------------------------------------*/
1088 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1095 /* if structure then */
1096 if (IS_STRUCT (type))
1097 rast = createIvalStruct (sym, type, ilist);
1099 /* if this is a pointer */
1101 rast = createIvalPtr (sym, type, ilist);
1103 /* if this is an array */
1104 if (IS_ARRAY (type))
1105 rast = createIvalArray (sym, type, ilist);
1107 /* if type is SPECIFIER */
1109 rast = createIvalType (sym, type, ilist);
1112 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1114 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1117 /*-----------------------------------------------------------------*/
1118 /* initAggregates - initialises aggregate variables with initv */
1119 /*-----------------------------------------------------------------*/
1120 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1121 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1124 /*-----------------------------------------------------------------*/
1125 /* gatherAutoInit - creates assignment expressions for initial */
1127 /*-----------------------------------------------------------------*/
1129 gatherAutoInit (symbol * autoChain)
1136 for (sym = autoChain; sym; sym = sym->next)
1139 /* resolve the symbols in the ival */
1141 resolveIvalSym (sym->ival, sym->type);
1144 /* if we are PIC16 port,
1145 * and this is a static,
1146 * and have initial value,
1147 * and not S_CODE, don't emit in gs segment,
1148 * but allow glue.c:pic16emitRegularMap to put symbol
1149 * in idata section */
1150 if(TARGET_IS_PIC16 &&
1151 IS_STATIC (sym->etype) && sym->ival
1152 && SPEC_SCLS(sym->etype) != S_CODE) {
1153 SPEC_SCLS (sym->etype) = S_DATA;
1158 /* if this is a static variable & has an */
1159 /* initial value the code needs to be lifted */
1160 /* here to the main portion since they can be */
1161 /* initialised only once at the start */
1162 if (IS_STATIC (sym->etype) && sym->ival &&
1163 SPEC_SCLS (sym->etype) != S_CODE)
1167 /* insert the symbol into the symbol table */
1168 /* with level = 0 & name = rname */
1169 newSym = copySymbol (sym);
1170 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1172 /* now lift the code to main */
1173 if (IS_AGGREGATE (sym->type)) {
1174 work = initAggregates (sym, sym->ival, NULL);
1176 if (getNelements(sym->type, sym->ival)>1) {
1177 werrorfl (sym->fileDef, sym->lineDef,
1178 W_EXCESS_INITIALIZERS, "scalar",
1181 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1182 list2expr (sym->ival));
1185 setAstLineno (work, sym->lineDef);
1189 staticAutos = newNode (NULLOP, staticAutos, work);
1196 /* if there is an initial value */
1197 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1199 initList *ilist=sym->ival;
1201 while (ilist->type == INIT_DEEP) {
1202 ilist = ilist->init.deep;
1205 /* update lineno for error msg */
1206 lineno=sym->lineDef;
1207 setAstLineno (ilist->init.node, lineno);
1209 if (IS_AGGREGATE (sym->type)) {
1210 work = initAggregates (sym, sym->ival, NULL);
1212 if (getNelements(sym->type, sym->ival)>1) {
1213 werrorfl (sym->fileDef, sym->lineDef,
1214 W_EXCESS_INITIALIZERS, "scalar",
1217 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1218 list2expr (sym->ival));
1222 setAstLineno (work, sym->lineDef);
1226 init = newNode (NULLOP, init, work);
1235 /*-----------------------------------------------------------------*/
1236 /* freeStringSymbol - delete a literal string if no more usage */
1237 /*-----------------------------------------------------------------*/
1238 void freeStringSymbol(symbol *sym) {
1239 /* make sure this is a literal string */
1240 assert (sym->isstrlit);
1241 if (--sym->isstrlit == 0) { // lower the usage count
1242 memmap *segment=SPEC_OCLS(sym->etype);
1244 deleteSetItem(&segment->syms, sym);
1249 /*-----------------------------------------------------------------*/
1250 /* stringToSymbol - creates a symbol from a literal string */
1251 /*-----------------------------------------------------------------*/
1253 stringToSymbol (value * val)
1255 char name[SDCC_NAME_MAX + 1];
1256 static int charLbl = 0;
1261 // have we heard this before?
1262 for (sp=statsg->syms; sp; sp=sp->next) {
1264 size = getSize (sym->type);
1265 if (sym->isstrlit && size == getSize (val->type) &&
1266 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1267 // yes, this is old news. Don't publish it again.
1268 sym->isstrlit++; // but raise the usage count
1269 return symbolVal(sym);
1273 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1274 sym = newSymbol (name, 0); /* make it @ level 0 */
1275 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1277 /* copy the type from the value passed */
1278 sym->type = copyLinkChain (val->type);
1279 sym->etype = getSpec (sym->type);
1280 /* change to storage class & output class */
1281 SPEC_SCLS (sym->etype) = S_CODE;
1282 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1283 SPEC_STAT (sym->etype) = 1;
1284 /* make the level & block = 0 */
1285 sym->block = sym->level = 0;
1287 /* create an ival */
1288 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1293 allocVariables (sym);
1296 return symbolVal (sym);
1300 /*-----------------------------------------------------------------*/
1301 /* processBlockVars - will go thru the ast looking for block if */
1302 /* a block is found then will allocate the syms */
1303 /* will also gather the auto inits present */
1304 /*-----------------------------------------------------------------*/
1306 processBlockVars (ast * tree, int *stack, int action)
1311 /* if this is a block */
1312 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1316 if (action == ALLOCATE)
1318 *stack += allocVariables (tree->values.sym);
1319 autoInit = gatherAutoInit (tree->values.sym);
1321 /* if there are auto inits then do them */
1323 tree->left = newNode (NULLOP, autoInit, tree->left);
1325 else /* action is deallocate */
1326 deallocLocal (tree->values.sym);
1329 processBlockVars (tree->left, stack, action);
1330 processBlockVars (tree->right, stack, action);
1335 /*-------------------------------------------------------------*/
1336 /* constExprTree - returns TRUE if this tree is a constant */
1338 /*-------------------------------------------------------------*/
1339 bool constExprTree (ast *cexpr) {
1345 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1347 switch (cexpr->type)
1350 if (IS_AST_LIT_VALUE(cexpr)) {
1351 // this is a literal
1354 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1355 // a function's address will never change
1358 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1359 // an array's address will never change
1362 if (IS_AST_SYM_VALUE(cexpr) &&
1363 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1364 // a symbol in code space will never change
1365 // This is only for the 'char *s="hallo"' case and will have to leave
1366 //printf(" code space symbol");
1371 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1372 "unexpected link in expression tree\n");
1375 if (cexpr->opval.op==ARRAYINIT) {
1376 // this is a list of literals
1379 if (cexpr->opval.op=='=') {
1380 return constExprTree(cexpr->right);
1382 if (cexpr->opval.op==CAST) {
1383 // cast ignored, maybe we should throw a warning here?
1384 return constExprTree(cexpr->right);
1386 if (cexpr->opval.op=='&') {
1389 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1392 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1397 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1402 /*-----------------------------------------------------------------*/
1403 /* constExprValue - returns the value of a constant expression */
1404 /* or NULL if it is not a constant expression */
1405 /*-----------------------------------------------------------------*/
1407 constExprValue (ast * cexpr, int check)
1409 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1411 /* if this is not a constant then */
1412 if (!IS_LITERAL (cexpr->ftype))
1414 /* then check if this is a literal array
1416 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1417 SPEC_CVAL (cexpr->etype).v_char &&
1418 IS_ARRAY (cexpr->ftype))
1420 value *val = valFromType (cexpr->ftype);
1421 SPEC_SCLS (val->etype) = S_LITERAL;
1422 val->sym = cexpr->opval.val->sym;
1423 val->sym->type = copyLinkChain (cexpr->ftype);
1424 val->sym->etype = getSpec (val->sym->type);
1425 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1429 /* if we are casting a literal value then */
1430 if (IS_AST_OP (cexpr) &&
1431 cexpr->opval.op == CAST &&
1432 IS_LITERAL (cexpr->right->ftype))
1434 return valCastLiteral (cexpr->ftype,
1435 floatFromVal (cexpr->right->opval.val));
1438 if (IS_AST_VALUE (cexpr))
1440 return cexpr->opval.val;
1444 werror (E_CONST_EXPECTED, "found expression");
1449 /* return the value */
1450 return cexpr->opval.val;
1454 /*-----------------------------------------------------------------*/
1455 /* isLabelInAst - will return true if a given label is found */
1456 /*-----------------------------------------------------------------*/
1458 isLabelInAst (symbol * label, ast * tree)
1460 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1463 if (IS_AST_OP (tree) &&
1464 tree->opval.op == LABEL &&
1465 isSymbolEqual (AST_SYMBOL (tree->left), label))
1468 return isLabelInAst (label, tree->right) &&
1469 isLabelInAst (label, tree->left);
1473 /*-----------------------------------------------------------------*/
1474 /* isLoopCountable - return true if the loop count can be determi- */
1475 /* -ned at compile time . */
1476 /*-----------------------------------------------------------------*/
1478 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1479 symbol ** sym, ast ** init, ast ** end)
1482 /* the loop is considered countable if the following
1483 conditions are true :-
1485 a) initExpr :- <sym> = <const>
1486 b) condExpr :- <sym> < <const1>
1487 c) loopExpr :- <sym> ++
1490 /* first check the initExpr */
1491 if (IS_AST_OP (initExpr) &&
1492 initExpr->opval.op == '=' && /* is assignment */
1493 IS_AST_SYM_VALUE (initExpr->left))
1494 { /* left is a symbol */
1496 *sym = AST_SYMBOL (initExpr->left);
1497 *init = initExpr->right;
1502 /* for now the symbol has to be of
1504 if (!IS_INTEGRAL ((*sym)->type))
1507 /* now check condExpr */
1508 if (IS_AST_OP (condExpr))
1511 switch (condExpr->opval.op)
1514 if (IS_AST_SYM_VALUE (condExpr->left) &&
1515 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1516 IS_AST_LIT_VALUE (condExpr->right))
1518 *end = condExpr->right;
1524 if (IS_AST_OP (condExpr->left) &&
1525 condExpr->left->opval.op == '>' &&
1526 IS_AST_LIT_VALUE (condExpr->left->right) &&
1527 IS_AST_SYM_VALUE (condExpr->left->left) &&
1528 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1531 *end = newNode ('+', condExpr->left->right,
1532 newAst_VALUE (constVal ("1")));
1545 /* check loop expression is of the form <sym>++ */
1546 if (!IS_AST_OP (loopExpr))
1549 /* check if <sym> ++ */
1550 if (loopExpr->opval.op == INC_OP)
1556 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1557 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1564 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1565 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1573 if (loopExpr->opval.op == ADD_ASSIGN)
1576 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1577 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1578 IS_AST_LIT_VALUE (loopExpr->right) &&
1579 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1587 /*-----------------------------------------------------------------*/
1588 /* astHasVolatile - returns true if ast contains any volatile */
1589 /*-----------------------------------------------------------------*/
1591 astHasVolatile (ast * tree)
1596 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1599 if (IS_AST_OP (tree))
1600 return astHasVolatile (tree->left) ||
1601 astHasVolatile (tree->right);
1606 /*-----------------------------------------------------------------*/
1607 /* astHasPointer - return true if the ast contains any ptr variable */
1608 /*-----------------------------------------------------------------*/
1610 astHasPointer (ast * tree)
1615 if (IS_AST_LINK (tree))
1618 /* if we hit an array expression then check
1619 only the left side */
1620 if (IS_AST_OP (tree) && tree->opval.op == '[')
1621 return astHasPointer (tree->left);
1623 if (IS_AST_VALUE (tree))
1624 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1626 return astHasPointer (tree->left) ||
1627 astHasPointer (tree->right);
1631 /*-----------------------------------------------------------------*/
1632 /* astHasSymbol - return true if the ast has the given symbol */
1633 /*-----------------------------------------------------------------*/
1635 astHasSymbol (ast * tree, symbol * sym)
1637 if (!tree || IS_AST_LINK (tree))
1640 if (IS_AST_VALUE (tree))
1642 if (IS_AST_SYM_VALUE (tree))
1643 return isSymbolEqual (AST_SYMBOL (tree), sym);
1648 return astHasSymbol (tree->left, sym) ||
1649 astHasSymbol (tree->right, sym);
1652 /*-----------------------------------------------------------------*/
1653 /* astHasDeref - return true if the ast has an indirect access */
1654 /*-----------------------------------------------------------------*/
1656 astHasDeref (ast * tree)
1658 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1661 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1663 return astHasDeref (tree->left) || astHasDeref (tree->right);
1666 /*-----------------------------------------------------------------*/
1667 /* isConformingBody - the loop body has to conform to a set of rules */
1668 /* for the loop to be considered reversible read on for rules */
1669 /*-----------------------------------------------------------------*/
1671 isConformingBody (ast * pbody, symbol * sym, ast * body)
1674 /* we are going to do a pre-order traversal of the
1675 tree && check for the following conditions. (essentially
1676 a set of very shallow tests )
1677 a) the sym passed does not participate in
1678 any arithmetic operation
1679 b) There are no function calls
1680 c) all jumps are within the body
1681 d) address of loop control variable not taken
1682 e) if an assignment has a pointer on the
1683 left hand side make sure right does not have
1684 loop control variable */
1686 /* if we reach the end or a leaf then true */
1687 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1690 /* if anything else is "volatile" */
1691 if (IS_VOLATILE (TETYPE (pbody)))
1694 /* we will walk the body in a pre-order traversal for
1696 switch (pbody->opval.op)
1698 /*------------------------------------------------------------------*/
1700 // if the loopvar is used as an index
1701 /* array op is commutative -- must check both left & right */
1702 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1705 return isConformingBody (pbody->right, sym, body)
1706 && isConformingBody (pbody->left, sym, body);
1708 /*------------------------------------------------------------------*/
1713 /*------------------------------------------------------------------*/
1717 /* sure we are not sym is not modified */
1719 IS_AST_SYM_VALUE (pbody->left) &&
1720 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1724 IS_AST_SYM_VALUE (pbody->right) &&
1725 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1730 /*------------------------------------------------------------------*/
1732 case '*': /* can be unary : if right is null then unary operation */
1737 /* if right is NULL then unary operation */
1738 /*------------------------------------------------------------------*/
1739 /*----------------------------*/
1741 /*----------------------------*/
1744 if (IS_AST_SYM_VALUE (pbody->left) &&
1745 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1748 return isConformingBody (pbody->left, sym, body);
1752 if (astHasSymbol (pbody->left, sym) ||
1753 astHasSymbol (pbody->right, sym))
1758 /*------------------------------------------------------------------*/
1769 if (IS_AST_SYM_VALUE (pbody->left) &&
1770 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1773 if (IS_AST_SYM_VALUE (pbody->right) &&
1774 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1777 return isConformingBody (pbody->left, sym, body) &&
1778 isConformingBody (pbody->right, sym, body);
1786 if (IS_AST_SYM_VALUE (pbody->left) &&
1787 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1789 return isConformingBody (pbody->left, sym, body);
1791 /*------------------------------------------------------------------*/
1803 case SIZEOF: /* evaluate wihout code generation */
1805 if (IS_AST_SYM_VALUE (pbody->left) &&
1806 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1809 if (IS_AST_SYM_VALUE (pbody->right) &&
1810 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1813 return isConformingBody (pbody->left, sym, body) &&
1814 isConformingBody (pbody->right, sym, body);
1816 /*------------------------------------------------------------------*/
1819 /* if left has a pointer & right has loop
1820 control variable then we cannot */
1821 if (astHasPointer (pbody->left) &&
1822 astHasSymbol (pbody->right, sym))
1824 if (astHasVolatile (pbody->left))
1827 if (IS_AST_SYM_VALUE (pbody->left)) {
1828 // if the loopvar has an assignment
1829 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1831 // if the loopvar is used in another (maybe conditional) block
1832 if (astHasSymbol (pbody->right, sym) &&
1833 (pbody->level >= body->level)) {
1838 if (astHasVolatile (pbody->left))
1841 if (astHasDeref(pbody->right)) return FALSE;
1843 return isConformingBody (pbody->left, sym, body) &&
1844 isConformingBody (pbody->right, sym, body);
1855 assert ("Parser should not have generated this\n");
1857 /*------------------------------------------------------------------*/
1858 /*----------------------------*/
1859 /* comma operator */
1860 /*----------------------------*/
1862 return isConformingBody (pbody->left, sym, body) &&
1863 isConformingBody (pbody->right, sym, body);
1865 /*------------------------------------------------------------------*/
1866 /*----------------------------*/
1868 /*----------------------------*/
1870 /* if local & not passed as paramater then ok */
1871 if (sym->level && !astHasSymbol(pbody->right,sym))
1875 /*------------------------------------------------------------------*/
1876 /*----------------------------*/
1877 /* return statement */
1878 /*----------------------------*/
1883 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1888 if (astHasSymbol (pbody->left, sym))
1895 return isConformingBody (pbody->left, sym, body) &&
1896 isConformingBody (pbody->right, sym, body);
1902 /*-----------------------------------------------------------------*/
1903 /* isLoopReversible - takes a for loop as input && returns true */
1904 /* if the for loop is reversible. If yes will set the value of */
1905 /* the loop control var & init value & termination value */
1906 /*-----------------------------------------------------------------*/
1908 isLoopReversible (ast * loop, symbol ** loopCntrl,
1909 ast ** init, ast ** end)
1911 /* if option says don't do it then don't */
1912 if (optimize.noLoopReverse)
1914 /* there are several tests to determine this */
1916 /* for loop has to be of the form
1917 for ( <sym> = <const1> ;
1918 [<sym> < <const2>] ;
1919 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1921 if (!isLoopCountable (AST_FOR (loop, initExpr),
1922 AST_FOR (loop, condExpr),
1923 AST_FOR (loop, loopExpr),
1924 loopCntrl, init, end))
1927 /* now do some serious checking on the body of the loop
1930 return isConformingBody (loop->left, *loopCntrl, loop->left);
1934 /*-----------------------------------------------------------------*/
1935 /* replLoopSym - replace the loop sym by loop sym -1 */
1936 /*-----------------------------------------------------------------*/
1938 replLoopSym (ast * body, symbol * sym)
1941 if (!body || IS_AST_LINK (body))
1944 if (IS_AST_SYM_VALUE (body))
1947 if (isSymbolEqual (AST_SYMBOL (body), sym))
1951 body->opval.op = '-';
1952 body->left = newAst_VALUE (symbolVal (sym));
1953 body->right = newAst_VALUE (constVal ("1"));
1961 replLoopSym (body->left, sym);
1962 replLoopSym (body->right, sym);
1966 /*-----------------------------------------------------------------*/
1967 /* reverseLoop - do the actual loop reversal */
1968 /*-----------------------------------------------------------------*/
1970 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1974 /* create the following tree
1979 if (sym) goto for_continue ;
1982 /* put it together piece by piece */
1983 rloop = newNode (NULLOP,
1984 createIf (newAst_VALUE (symbolVal (sym)),
1986 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1989 newAst_VALUE (symbolVal (sym)),
1992 replLoopSym (loop->left, sym);
1993 setAstLineno (rloop, init->lineno);
1995 rloop = newNode (NULLOP,
1997 newAst_VALUE (symbolVal (sym)),
1998 newNode ('-', end, init)),
1999 createLabel (AST_FOR (loop, continueLabel),
2003 newNode (SUB_ASSIGN,
2004 newAst_VALUE (symbolVal (sym)),
2005 newAst_VALUE (constVal ("1"))),
2008 rloop->lineno=init->lineno;
2009 return decorateType (rloop, RESULT_TYPE_NONE);
2013 /*-----------------------------------------------------------------*/
2014 /* searchLitOp - search tree (*ops only) for an ast with literal */
2015 /*-----------------------------------------------------------------*/
2017 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2021 if (tree && optimize.global_cse)
2023 /* is there a literal operand? */
2025 IS_AST_OP(tree->right) &&
2026 tree->right->right &&
2027 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2029 if (IS_LITERAL (RTYPE (tree->right)) !=
2030 IS_LITERAL (LTYPE (tree->right)))
2032 tree->right->decorated = 0;
2033 tree->decorated = 0;
2037 ret = searchLitOp (tree->right, parent, ops);
2042 IS_AST_OP(tree->left) &&
2043 tree->left->right &&
2044 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2046 if (IS_LITERAL (RTYPE (tree->left)) !=
2047 IS_LITERAL (LTYPE (tree->left)))
2049 tree->left->decorated = 0;
2050 tree->decorated = 0;
2054 ret = searchLitOp (tree->left, parent, ops);
2062 /*-----------------------------------------------------------------*/
2063 /* getResultFromType */
2064 /*-----------------------------------------------------------------*/
2066 getResultTypeFromType (sym_link *type)
2068 /* type = getSpec (type); */
2070 return RESULT_TYPE_BIT;
2071 if (IS_BITFIELD (type))
2073 int blen = SPEC_BLEN (type);
2076 return RESULT_TYPE_BIT;
2078 return RESULT_TYPE_CHAR;
2079 return RESULT_TYPE_INT;
2082 return RESULT_TYPE_CHAR;
2085 return RESULT_TYPE_INT;
2086 return RESULT_TYPE_OTHER;
2089 /*-----------------------------------------------------------------*/
2090 /* addCast - adds casts to a type specified by RESULT_TYPE */
2091 /*-----------------------------------------------------------------*/
2093 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2096 bool upCasted = FALSE;
2100 case RESULT_TYPE_NONE:
2101 /* if thing smaller than int must be promoted to int */
2103 getSize (tree->etype) >= INTSIZE)
2104 /* promotion not necessary or already an int */
2106 /* char and bits: promote to int */
2107 newLink = newIntLink();
2110 case RESULT_TYPE_BIT:
2112 /* already an int */
2113 bitsForType (tree->etype) >= 16 ||
2114 /* bit to bit operation: don't promote, the code generators
2115 hopefully know everything about promotion rules */
2116 bitsForType (tree->etype) == 1)
2118 newLink = newIntLink();
2121 case RESULT_TYPE_CHAR:
2122 if (IS_CHAR (tree->etype) ||
2123 IS_FLOAT(tree->etype) ||
2124 IS_FIXED(tree->etype))
2126 newLink = newCharLink();
2128 case RESULT_TYPE_INT:
2130 if (getSize (tree->etype) > INTSIZE)
2132 /* warn ("Loosing significant digits"); */
2136 /* char: promote to int */
2138 getSize (tree->etype) >= INTSIZE)
2140 newLink = newIntLink();
2143 case RESULT_TYPE_OTHER:
2146 /* return type is long, float: promote char to int */
2147 if (getSize (tree->etype) >= INTSIZE)
2149 newLink = newIntLink();
2155 tree->decorated = 0;
2156 tree = newNode (CAST, newAst_LINK (newLink), tree);
2157 tree->lineno = tree->right->lineno;
2158 /* keep unsigned type during cast to smaller type,
2159 but not when promoting from char to int */
2161 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2162 return decorateType (tree, resultType);
2165 /*-----------------------------------------------------------------*/
2166 /* resultTypePropagate - decides if resultType can be propagated */
2167 /*-----------------------------------------------------------------*/
2169 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2171 switch (tree->opval.op)
2190 return RESULT_TYPE_NONE;
2194 return RESULT_TYPE_IFX;
2196 return RESULT_TYPE_NONE;
2200 /*-----------------------------------------------------------------*/
2201 /* getLeftResultType - gets type from left branch for propagation */
2202 /*-----------------------------------------------------------------*/
2204 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2206 switch (tree->opval.op)
2210 if (IS_PTR (LTYPE (tree)))
2211 return RESULT_TYPE_NONE;
2213 return getResultTypeFromType (LETYPE (tree));
2215 if (IS_PTR (currFunc->type->next))
2216 return RESULT_TYPE_NONE;
2218 return getResultTypeFromType (currFunc->type->next);
2220 if (!IS_ARRAY (LTYPE (tree)))
2222 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2223 return RESULT_TYPE_CHAR;
2230 /*--------------------------------------------------------------------*/
2231 /* decorateType - compute type for this tree, also does type checking.*/
2232 /* This is done bottom up, since type has to flow upwards. */
2233 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2234 /* result is a char and the operand(s) are int's. */
2235 /* It also does constant folding, and parameter checking. */
2236 /*--------------------------------------------------------------------*/
2238 decorateType (ast * tree, RESULT_TYPE resultType)
2242 RESULT_TYPE resultTypeProp;
2247 /* if already has type then do nothing */
2248 if (tree->decorated)
2251 tree->decorated = 1;
2254 /* print the line */
2255 /* if not block & function */
2256 if (tree->type == EX_OP &&
2257 (tree->opval.op != FUNCTION &&
2258 tree->opval.op != BLOCK &&
2259 tree->opval.op != NULLOP))
2261 filename = tree->filename;
2262 lineno = tree->lineno;
2266 /* if any child is an error | this one is an error do nothing */
2267 if (tree->isError ||
2268 (tree->left && tree->left->isError) ||
2269 (tree->right && tree->right->isError))
2272 /*------------------------------------------------------------------*/
2273 /*----------------------------*/
2274 /* leaf has been reached */
2275 /*----------------------------*/
2276 lineno=tree->lineno;
2277 /* if this is of type value */
2278 /* just get the type */
2279 if (tree->type == EX_VALUE)
2282 if (IS_LITERAL (tree->opval.val->etype))
2285 /* if this is a character array then declare it */
2286 if (IS_ARRAY (tree->opval.val->type))
2287 tree->opval.val = stringToSymbol (tree->opval.val);
2289 /* otherwise just copy the type information */
2290 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2294 if (tree->opval.val->sym)
2296 /* if the undefined flag is set then give error message */
2297 if (tree->opval.val->sym->undefined)
2299 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2301 TTYPE (tree) = TETYPE (tree) =
2302 tree->opval.val->type = tree->opval.val->sym->type =
2303 tree->opval.val->etype = tree->opval.val->sym->etype =
2304 copyLinkChain (INTTYPE);
2309 /* if impilicit i.e. struct/union member then no type */
2310 if (tree->opval.val->sym->implicit)
2311 TTYPE (tree) = TETYPE (tree) = NULL;
2316 /* else copy the type */
2317 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2319 /* and mark it as referenced */
2320 tree->opval.val->sym->isref = 1;
2328 /* if type link for the case of cast */
2329 if (tree->type == EX_LINK)
2331 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2339 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2341 if (tree->left && tree->left->type == EX_OPERAND
2342 && (tree->left->opval.op == INC_OP
2343 || tree->left->opval.op == DEC_OP)
2344 && tree->left->left)
2346 tree->left->right = tree->left->left;
2347 tree->left->left = NULL;
2349 if (tree->right && tree->right->type == EX_OPERAND
2350 && (tree->right->opval.op == INC_OP
2351 || tree->right->opval.op == DEC_OP)
2352 && tree->right->left)
2354 tree->right->right = tree->right->left;
2355 tree->right->left = NULL;
2360 /* Before decorating the left branch we've to decide in dependence
2361 upon tree->opval.op, if resultType can be propagated */
2362 resultTypeProp = resultTypePropagate (tree, resultType);
2364 if (tree->opval.op == '?')
2365 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2367 dtl = decorateType (tree->left, resultTypeProp);
2369 /* if an array node, we may need to swap branches */
2370 if (tree->opval.op == '[')
2372 /* determine which is the array & which the index */
2373 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2374 IS_INTEGRAL (LTYPE (tree)))
2376 ast *tempTree = tree->left;
2377 tree->left = tree->right;
2378 tree->right = tempTree;
2382 /* After decorating the left branch there's type information available
2383 in tree->left->?type. If the op is e.g. '=' we extract the type
2384 information from there and propagate it to the right branch. */
2385 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2387 switch (tree->opval.op)
2390 /* delay right side for '?' operator since conditional macro
2391 expansions might rely on this */
2395 /* decorate right side for CALL (parameter list) in processParms();
2396 there is resultType available */
2400 dtr = decorateType (tree->right, resultTypeProp);
2404 /* this is to take care of situations
2405 when the tree gets rewritten */
2406 if (dtl != tree->left)
2408 if (dtr != tree->right)
2410 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2414 /* depending on type of operator do */
2416 switch (tree->opval.op)
2418 /*------------------------------------------------------------------*/
2419 /*----------------------------*/
2421 /*----------------------------*/
2424 /* first check if this is a array or a pointer */
2425 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2427 werror (E_NEED_ARRAY_PTR, "[]");
2428 goto errorTreeReturn;
2431 /* check if the type of the idx */
2432 if (!IS_INTEGRAL (RTYPE (tree)))
2434 werror (E_IDX_NOT_INT);
2435 goto errorTreeReturn;
2438 /* if the left is an rvalue then error */
2441 werror (E_LVALUE_REQUIRED, "array access");
2442 goto errorTreeReturn;
2445 if (IS_LITERAL (RTYPE (tree)))
2447 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2448 int arraySize = DCL_ELEM (LTYPE (tree));
2449 if (arraySize && arrayIndex >= arraySize)
2451 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2456 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2459 /*------------------------------------------------------------------*/
2460 /*----------------------------*/
2462 /*----------------------------*/
2464 /* if this is not a structure */
2465 if (!IS_STRUCT (LTYPE (tree)))
2467 werror (E_STRUCT_UNION, ".");
2468 goto errorTreeReturn;
2470 TTYPE (tree) = structElemType (LTYPE (tree),
2471 (tree->right->type == EX_VALUE ?
2472 tree->right->opval.val : NULL));
2473 TETYPE (tree) = getSpec (TTYPE (tree));
2476 /*------------------------------------------------------------------*/
2477 /*----------------------------*/
2478 /* struct/union pointer */
2479 /*----------------------------*/
2481 /* if not pointer to a structure */
2482 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2484 werror (E_PTR_REQD);
2485 goto errorTreeReturn;
2488 if (!IS_STRUCT (LTYPE (tree)->next))
2490 werror (E_STRUCT_UNION, "->");
2491 goto errorTreeReturn;
2494 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2495 (tree->right->type == EX_VALUE ?
2496 tree->right->opval.val : NULL));
2497 TETYPE (tree) = getSpec (TTYPE (tree));
2499 /* adjust the storage class */
2500 switch (DCL_TYPE(tree->left->ftype)) {
2502 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2505 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2508 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2511 SPEC_SCLS (TETYPE (tree)) = 0;
2514 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2517 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2520 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2523 SPEC_SCLS (TETYPE (tree)) = 0;
2530 /* This breaks with extern declarations, bitfields, and perhaps other */
2531 /* cases (gcse). Let's leave this optimization disabled for now and */
2532 /* ponder if there's a safe way to do this. -- EEP */
2534 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2535 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2537 /* If defined struct type at addr var
2538 then rewrite (&struct var)->member
2540 and define membertype at (addr+offsetof(struct var,member)) temp
2543 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2544 AST_SYMBOL(tree->right));
2546 sym = newSymbol(genSymName (0), 0);
2547 sym->type = TTYPE (tree);
2548 sym->etype = getSpec(sym->type);
2549 sym->lineDef = tree->lineno;
2552 SPEC_STAT (sym->etype) = 1;
2553 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2555 SPEC_ABSA(sym->etype) = 1;
2556 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2559 AST_VALUE (tree) = symbolVal(sym);
2562 tree->type = EX_VALUE;
2570 /*------------------------------------------------------------------*/
2571 /*----------------------------*/
2572 /* ++/-- operation */
2573 /*----------------------------*/
2577 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2578 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2579 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2580 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2589 /*------------------------------------------------------------------*/
2590 /*----------------------------*/
2592 /*----------------------------*/
2593 case '&': /* can be unary */
2594 /* if right is NULL then unary operation */
2595 if (tree->right) /* not an unary operation */
2598 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2600 werror (E_BITWISE_OP);
2601 werror (W_CONTINUE, "left & right types are ");
2602 printTypeChain (LTYPE (tree), stderr);
2603 fprintf (stderr, ",");
2604 printTypeChain (RTYPE (tree), stderr);
2605 fprintf (stderr, "\n");
2606 goto errorTreeReturn;
2609 /* if they are both literal */
2610 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2612 tree->type = EX_VALUE;
2613 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2614 valFromType (RETYPE (tree)), '&');
2616 tree->right = tree->left = NULL;
2617 TETYPE (tree) = tree->opval.val->etype;
2618 TTYPE (tree) = tree->opval.val->type;
2622 /* see if this is a GETHBIT operation if yes
2625 ast *otree = optimizeGetHbit (tree, resultType);
2628 return decorateType (otree, RESULT_TYPE_NONE);
2631 /* see if this is a GETABIT operation if yes
2634 ast *otree = optimizeGetAbit (tree, resultType);
2637 return decorateType (otree, RESULT_TYPE_NONE);
2640 /* see if this is a GETBYTE operation if yes
2643 ast *otree = optimizeGetByte (tree, resultType);
2646 return decorateType (otree, RESULT_TYPE_NONE);
2649 /* see if this is a GETWORD operation if yes
2652 ast *otree = optimizeGetWord (tree, resultType);
2655 return decorateType (otree, RESULT_TYPE_NONE);
2658 /* if left is a literal exchange left & right */
2659 if (IS_LITERAL (LTYPE (tree)))
2661 ast *tTree = tree->left;
2662 tree->left = tree->right;
2663 tree->right = tTree;
2666 /* if right is a literal and */
2667 /* we can find a 2nd literal in an and-tree then */
2668 /* rearrange the tree */
2669 if (IS_LITERAL (RTYPE (tree)))
2672 ast *litTree = searchLitOp (tree, &parent, "&");
2676 ast *tTree = litTree->left;
2677 litTree->left = tree->right;
2678 tree->right = tTree;
2679 /* both operands in litTree are literal now */
2680 decorateType (parent, resultType);
2684 LRVAL (tree) = RRVAL (tree) = 1;
2686 TTYPE (tree) = computeType (LTYPE (tree),
2690 TETYPE (tree) = getSpec (TTYPE (tree));
2695 /*------------------------------------------------------------------*/
2696 /*----------------------------*/
2698 /*----------------------------*/
2699 p = newLink (DECLARATOR);
2700 /* if bit field then error */
2701 if (IS_BITVAR (tree->left->etype))
2703 werror (E_ILLEGAL_ADDR, "address of bit variable");
2704 goto errorTreeReturn;
2707 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2709 werror (E_ILLEGAL_ADDR, "address of register variable");
2710 goto errorTreeReturn;
2713 if (IS_FUNC (LTYPE (tree)))
2715 // this ought to be ignored
2716 return (tree->left);
2719 if (IS_LITERAL(LTYPE(tree)))
2721 werror (E_ILLEGAL_ADDR, "address of literal");
2722 goto errorTreeReturn;
2727 werror (E_LVALUE_REQUIRED, "address of");
2728 goto errorTreeReturn;
2731 DCL_TYPE (p) = POINTER;
2732 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2733 DCL_TYPE (p) = CPOINTER;
2734 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2735 DCL_TYPE (p) = FPOINTER;
2736 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2737 DCL_TYPE (p) = PPOINTER;
2738 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2739 DCL_TYPE (p) = IPOINTER;
2740 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2741 DCL_TYPE (p) = EEPPOINTER;
2742 else if (SPEC_OCLS(tree->left->etype))
2743 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2745 DCL_TYPE (p) = POINTER;
2747 if (IS_AST_SYM_VALUE (tree->left))
2749 AST_SYMBOL (tree->left)->addrtaken = 1;
2750 AST_SYMBOL (tree->left)->allocreq = 1;
2753 p->next = LTYPE (tree);
2755 TETYPE (tree) = getSpec (TTYPE (tree));
2760 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2761 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2763 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2764 AST_SYMBOL(tree->left->right));
2765 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2766 valueFromLit(element->offset));
2769 tree->type = EX_VALUE;
2770 tree->values.literalFromCast = 1;
2776 /*------------------------------------------------------------------*/
2777 /*----------------------------*/
2779 /*----------------------------*/
2781 /* if the rewrite succeeds then don't go any further */
2783 ast *wtree = optimizeRRCRLC (tree);
2785 return decorateType (wtree, RESULT_TYPE_NONE);
2787 wtree = optimizeSWAP (tree);
2789 return decorateType (wtree, RESULT_TYPE_NONE);
2792 /* if left is a literal exchange left & right */
2793 if (IS_LITERAL (LTYPE (tree)))
2795 ast *tTree = tree->left;
2796 tree->left = tree->right;
2797 tree->right = tTree;
2800 /* if right is a literal and */
2801 /* we can find a 2nd literal in an or-tree then */
2802 /* rearrange the tree */
2803 if (IS_LITERAL (RTYPE (tree)))
2806 ast *litTree = searchLitOp (tree, &parent, "|");
2810 ast *tTree = litTree->left;
2811 litTree->left = tree->right;
2812 tree->right = tTree;
2813 /* both operands in tTree are literal now */
2814 decorateType (parent, resultType);
2819 /*------------------------------------------------------------------*/
2820 /*----------------------------*/
2822 /*----------------------------*/
2824 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2826 werror (E_BITWISE_OP);
2827 werror (W_CONTINUE, "left & right types are ");
2828 printTypeChain (LTYPE (tree), stderr);
2829 fprintf (stderr, ",");
2830 printTypeChain (RTYPE (tree), stderr);
2831 fprintf (stderr, "\n");
2832 goto errorTreeReturn;
2835 /* if they are both literal then rewrite the tree */
2836 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2838 tree->type = EX_VALUE;
2839 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2840 valFromType (RETYPE (tree)),
2842 tree->right = tree->left = NULL;
2843 TETYPE (tree) = tree->opval.val->etype;
2844 TTYPE (tree) = tree->opval.val->type;
2848 /* if left is a literal exchange left & right */
2849 if (IS_LITERAL (LTYPE (tree)))
2851 ast *tTree = tree->left;
2852 tree->left = tree->right;
2853 tree->right = tTree;
2856 /* if right is a literal and */
2857 /* we can find a 2nd literal in a xor-tree then */
2858 /* rearrange the tree */
2859 if (IS_LITERAL (RTYPE (tree)) &&
2860 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2863 ast *litTree = searchLitOp (tree, &parent, "^");
2867 ast *tTree = litTree->left;
2868 litTree->left = tree->right;
2869 tree->right = tTree;
2870 /* both operands in litTree are literal now */
2871 decorateType (parent, resultType);
2875 LRVAL (tree) = RRVAL (tree) = 1;
2877 TTYPE (tree) = computeType (LTYPE (tree),
2881 TETYPE (tree) = getSpec (TTYPE (tree));
2885 /*------------------------------------------------------------------*/
2886 /*----------------------------*/
2888 /*----------------------------*/
2890 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2892 werror (E_INVALID_OP, "divide");
2893 goto errorTreeReturn;
2895 /* if they are both literal then */
2896 /* rewrite the tree */
2897 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2899 tree->type = EX_VALUE;
2900 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2901 valFromType (RETYPE (tree)));
2902 tree->right = tree->left = NULL;
2903 TETYPE (tree) = getSpec (TTYPE (tree) =
2904 tree->opval.val->type);
2908 LRVAL (tree) = RRVAL (tree) = 1;
2910 TETYPE (tree) = getSpec (TTYPE (tree) =
2911 computeType (LTYPE (tree),
2916 /* if right is a literal and */
2917 /* left is also a division by a literal then */
2918 /* rearrange the tree */
2919 if (IS_LITERAL (RTYPE (tree))
2920 /* avoid infinite loop */
2921 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2924 ast *litTree = searchLitOp (tree, &parent, "/");
2927 if (IS_LITERAL (RTYPE (litTree)))
2931 litTree->right = newNode ('*',
2933 copyAst (tree->right));
2934 litTree->right->lineno = tree->lineno;
2936 tree->right->opval.val = constVal ("1");
2937 decorateType (parent, resultType);
2941 /* litTree->left is literal: no gcse possible.
2942 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2943 this would cause an infinit loop. */
2944 parent->decorated = 1;
2945 decorateType (litTree, resultType);
2952 /*------------------------------------------------------------------*/
2953 /*----------------------------*/
2955 /*----------------------------*/
2957 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2959 werror (E_BITWISE_OP);
2960 werror (W_CONTINUE, "left & right types are ");
2961 printTypeChain (LTYPE (tree), stderr);
2962 fprintf (stderr, ",");
2963 printTypeChain (RTYPE (tree), stderr);
2964 fprintf (stderr, "\n");
2965 goto errorTreeReturn;
2967 /* if they are both literal then */
2968 /* rewrite the tree */
2969 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2971 tree->type = EX_VALUE;
2972 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2973 valFromType (RETYPE (tree)));
2974 tree->right = tree->left = NULL;
2975 TETYPE (tree) = getSpec (TTYPE (tree) =
2976 tree->opval.val->type);
2979 LRVAL (tree) = RRVAL (tree) = 1;
2980 TETYPE (tree) = getSpec (TTYPE (tree) =
2981 computeType (LTYPE (tree),
2987 /*------------------------------------------------------------------*/
2988 /*----------------------------*/
2989 /* address dereference */
2990 /*----------------------------*/
2991 case '*': /* can be unary : if right is null then unary operation */
2994 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2996 werror (E_PTR_REQD);
2997 goto errorTreeReturn;
3002 werror (E_LVALUE_REQUIRED, "pointer deref");
3003 goto errorTreeReturn;
3005 if (IS_ADDRESS_OF_OP(tree->left))
3007 /* replace *&obj with obj */
3008 return tree->left->left;
3010 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3011 TETYPE (tree) = getSpec (TTYPE (tree));
3012 /* adjust the storage class */
3013 switch (DCL_TYPE(tree->left->ftype)) {
3015 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3018 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3021 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3024 SPEC_SCLS (TETYPE (tree)) = 0;
3027 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3030 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3033 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3036 SPEC_SCLS (TETYPE (tree)) = 0;
3045 /*------------------------------------------------------------------*/
3046 /*----------------------------*/
3047 /* multiplication */
3048 /*----------------------------*/
3049 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3051 werror (E_INVALID_OP, "multiplication");
3052 goto errorTreeReturn;
3055 /* if they are both literal then */
3056 /* rewrite the tree */
3057 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3059 tree->type = EX_VALUE;
3060 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3061 valFromType (RETYPE (tree)));
3062 tree->right = tree->left = NULL;
3063 TETYPE (tree) = getSpec (TTYPE (tree) =
3064 tree->opval.val->type);
3068 /* if left is a literal exchange left & right */
3069 if (IS_LITERAL (LTYPE (tree)))
3071 ast *tTree = tree->left;
3072 tree->left = tree->right;
3073 tree->right = tTree;
3076 /* if right is a literal and */
3077 /* we can find a 2nd literal in a mul-tree then */
3078 /* rearrange the tree */
3079 if (IS_LITERAL (RTYPE (tree)))
3082 ast *litTree = searchLitOp (tree, &parent, "*");
3086 ast *tTree = litTree->left;
3087 litTree->left = tree->right;
3088 tree->right = tTree;
3089 /* both operands in litTree are literal now */
3090 decorateType (parent, resultType);
3094 LRVAL (tree) = RRVAL (tree) = 1;
3095 tree->left = addCast (tree->left, resultType, FALSE);
3096 tree->right = addCast (tree->right, resultType, FALSE);
3097 TETYPE (tree) = getSpec (TTYPE (tree) =
3098 computeType (LTYPE (tree),
3105 /*------------------------------------------------------------------*/
3106 /*----------------------------*/
3107 /* unary '+' operator */
3108 /*----------------------------*/
3113 if (!IS_ARITHMETIC (LTYPE (tree)))
3115 werror (E_UNARY_OP, '+');
3116 goto errorTreeReturn;
3119 /* if left is a literal then do it */
3120 if (IS_LITERAL (LTYPE (tree)))
3122 tree->type = EX_VALUE;
3123 tree->opval.val = valFromType (LETYPE (tree));
3125 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3129 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3133 /*------------------------------------------------------------------*/
3134 /*----------------------------*/
3136 /*----------------------------*/
3138 /* this is not a unary operation */
3139 /* if both pointers then problem */
3140 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3141 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3143 werror (E_PTR_PLUS_PTR);
3144 goto errorTreeReturn;
3147 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3148 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3150 werror (E_PLUS_INVALID, "+");
3151 goto errorTreeReturn;
3154 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3155 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3157 werror (E_PLUS_INVALID, "+");
3158 goto errorTreeReturn;
3160 /* if they are both literal then */
3161 /* rewrite the tree */
3162 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3164 tree->type = EX_VALUE;
3165 tree->left = addCast (tree->left, resultType, TRUE);
3166 tree->right = addCast (tree->right, resultType, TRUE);
3167 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3168 valFromType (RETYPE (tree)));
3169 tree->right = tree->left = NULL;
3170 TETYPE (tree) = getSpec (TTYPE (tree) =
3171 tree->opval.val->type);
3175 /* if the right is a pointer or left is a literal
3176 xchange left & right */
3177 if (IS_ARRAY (RTYPE (tree)) ||
3178 IS_PTR (RTYPE (tree)) ||
3179 IS_LITERAL (LTYPE (tree)))
3181 ast *tTree = tree->left;
3182 tree->left = tree->right;
3183 tree->right = tTree;
3186 /* if right is a literal and */
3187 /* left is also an addition/subtraction with a literal then */
3188 /* rearrange the tree */
3189 if (IS_LITERAL (RTYPE (tree)))
3191 ast *litTree, *parent;
3192 litTree = searchLitOp (tree, &parent, "+-");
3195 if (litTree->opval.op == '+')
3199 ast *tTree = litTree->left;
3200 litTree->left = tree->right;
3201 tree->right = tree->left;
3204 else if (litTree->opval.op == '-')
3206 if (IS_LITERAL (RTYPE (litTree)))
3210 ast *tTree = litTree->left;
3211 litTree->left = tree->right;
3212 tree->right = tTree;
3218 ast *tTree = litTree->right;
3219 litTree->right = tree->right;
3220 tree->right = tTree;
3221 litTree->opval.op = '+';
3222 tree->opval.op = '-';
3225 decorateType (parent, resultType);
3229 LRVAL (tree) = RRVAL (tree) = 1;
3230 /* if the left is a pointer */
3231 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3232 TETYPE (tree) = getSpec (TTYPE (tree) =
3236 tree->left = addCast (tree->left, resultType, TRUE);
3237 tree->right = addCast (tree->right, resultType, TRUE);
3238 TETYPE (tree) = getSpec (TTYPE (tree) =
3239 computeType (LTYPE (tree),
3247 /*------------------------------------------------------------------*/
3248 /*----------------------------*/
3250 /*----------------------------*/
3251 case '-': /* can be unary */
3252 /* if right is null then unary */
3256 if (!IS_ARITHMETIC (LTYPE (tree)))
3258 werror (E_UNARY_OP, tree->opval.op);
3259 goto errorTreeReturn;
3262 /* if left is a literal then do it */
3263 if (IS_LITERAL (LTYPE (tree)))
3265 tree->type = EX_VALUE;
3266 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3268 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3269 SPEC_USIGN(TETYPE(tree)) = 0;
3273 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3277 /*------------------------------------------------------------------*/
3278 /*----------------------------*/
3280 /*----------------------------*/
3282 if (!(IS_PTR (LTYPE (tree)) ||
3283 IS_ARRAY (LTYPE (tree)) ||
3284 IS_ARITHMETIC (LTYPE (tree))))
3286 werror (E_PLUS_INVALID, "-");
3287 goto errorTreeReturn;
3290 if (!(IS_PTR (RTYPE (tree)) ||
3291 IS_ARRAY (RTYPE (tree)) ||
3292 IS_ARITHMETIC (RTYPE (tree))))
3294 werror (E_PLUS_INVALID, "-");
3295 goto errorTreeReturn;
3298 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3299 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3300 IS_INTEGRAL (RTYPE (tree))))
3302 werror (E_PLUS_INVALID, "-");
3303 goto errorTreeReturn;
3306 /* if they are both literal then */
3307 /* rewrite the tree */
3308 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3310 tree->type = EX_VALUE;
3311 tree->left = addCast (tree->left, resultType, TRUE);
3312 tree->right = addCast (tree->right, resultType, TRUE);
3313 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3314 valFromType (RETYPE (tree)));
3315 tree->right = tree->left = NULL;
3316 TETYPE (tree) = getSpec (TTYPE (tree) =
3317 tree->opval.val->type);
3321 /* if the left & right are equal then zero */
3322 if (isAstEqual (tree->left, tree->right))
3324 tree->type = EX_VALUE;
3325 tree->left = tree->right = NULL;
3326 tree->opval.val = constVal ("0");
3327 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3331 /* if both of them are pointers or arrays then */
3332 /* the result is going to be an integer */
3333 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3334 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3335 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3337 /* if only the left is a pointer */
3338 /* then result is a pointer */
3339 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3340 TETYPE (tree) = getSpec (TTYPE (tree) =
3344 tree->left = addCast (tree->left, resultType, TRUE);
3345 tree->right = addCast (tree->right, resultType, TRUE);
3347 TETYPE (tree) = getSpec (TTYPE (tree) =
3348 computeType (LTYPE (tree),
3354 LRVAL (tree) = RRVAL (tree) = 1;
3356 /* if right is a literal and */
3357 /* left is also an addition/subtraction with a literal then */
3358 /* rearrange the tree */
3359 if (IS_LITERAL (RTYPE (tree))
3360 /* avoid infinite loop */
3361 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3363 ast *litTree, *litParent;
3364 litTree = searchLitOp (tree, &litParent, "+-");
3367 if (litTree->opval.op == '+')
3371 ast *tTree = litTree->left;
3372 litTree->left = litTree->right;
3373 litTree->right = tree->right;
3374 tree->right = tTree;
3375 tree->opval.op = '+';
3376 litTree->opval.op = '-';
3378 else if (litTree->opval.op == '-')
3380 if (IS_LITERAL (RTYPE (litTree)))
3384 ast *tTree = litTree->left;
3385 litTree->left = tree->right;
3386 tree->right = litParent->left;
3387 litParent->left = tTree;
3388 litTree->opval.op = '+';
3390 tree->decorated = 0;
3391 decorateType (tree, resultType);
3397 ast *tTree = litTree->right;
3398 litTree->right = tree->right;
3399 tree->right = tTree;
3402 decorateType (litParent, resultType);
3407 /*------------------------------------------------------------------*/
3408 /*----------------------------*/
3410 /*----------------------------*/
3412 /* can be only integral type */
3413 if (!IS_INTEGRAL (LTYPE (tree)))
3415 werror (E_UNARY_OP, tree->opval.op);
3416 goto errorTreeReturn;
3419 /* if left is a literal then do it */
3420 if (IS_LITERAL (LTYPE (tree)))
3422 tree->type = EX_VALUE;
3423 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3425 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3426 return addCast (tree, resultType, TRUE);
3429 if (resultType == RESULT_TYPE_BIT &&
3430 IS_UNSIGNED (tree->left->etype) &&
3431 getSize (tree->left->etype) < INTSIZE)
3433 /* promotion rules are responsible for this strange result:
3434 bit -> int -> ~int -> bit
3435 uchar -> int -> ~int -> bit
3437 werror(W_COMPLEMENT);
3439 /* optimize bit-result, even if we optimize a buggy source */
3440 tree->type = EX_VALUE;
3441 tree->opval.val = constVal ("1");
3444 tree->left = addCast (tree->left, resultType, TRUE);
3446 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3449 /*------------------------------------------------------------------*/
3450 /*----------------------------*/
3452 /*----------------------------*/
3454 /* can be pointer */
3455 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3456 !IS_PTR (LTYPE (tree)) &&
3457 !IS_ARRAY (LTYPE (tree)))
3459 werror (E_UNARY_OP, tree->opval.op);
3460 goto errorTreeReturn;
3463 /* if left is a literal then do it */
3464 if (IS_LITERAL (LTYPE (tree)))
3466 tree->type = EX_VALUE;
3467 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3469 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3473 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3476 /*------------------------------------------------------------------*/
3477 /*----------------------------*/
3479 /*----------------------------*/
3483 TTYPE (tree) = LTYPE (tree);
3484 TETYPE (tree) = LETYPE (tree);
3489 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3493 TTYPE (tree) = TETYPE (tree) = newCharLink();
3497 TTYPE (tree) = TETYPE (tree) = newIntLink();
3502 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3504 werror (E_SHIFT_OP_INVALID);
3505 werror (W_CONTINUE, "left & right types are ");
3506 printTypeChain (LTYPE (tree), stderr);
3507 fprintf (stderr, ",");
3508 printTypeChain (RTYPE (tree), stderr);
3509 fprintf (stderr, "\n");
3510 goto errorTreeReturn;
3513 /* make smaller type only if it's a LEFT_OP */
3514 if (tree->opval.op == LEFT_OP)
3515 tree->left = addCast (tree->left, resultType, TRUE);
3517 /* if they are both literal then */
3518 /* rewrite the tree */
3519 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3521 tree->type = EX_VALUE;
3522 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3523 valFromType (RETYPE (tree)),
3524 (tree->opval.op == LEFT_OP ? 1 : 0));
3525 tree->right = tree->left = NULL;
3526 TETYPE (tree) = getSpec (TTYPE (tree) =
3527 tree->opval.val->type);
3531 /* see if this is a GETBYTE operation if yes
3534 ast *otree = optimizeGetByte (tree, resultType);
3537 return decorateType (otree, RESULT_TYPE_NONE);
3540 /* see if this is a GETWORD operation if yes
3543 ast *otree = optimizeGetWord (tree, resultType);
3546 return decorateType (otree, RESULT_TYPE_NONE);
3549 LRVAL (tree) = RRVAL (tree) = 1;
3550 if (tree->opval.op == LEFT_OP)
3552 TETYPE (tree) = getSpec (TTYPE (tree) =
3553 computeType (LTYPE (tree),
3560 /* no promotion necessary */
3561 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3562 if (IS_LITERAL (TTYPE (tree)))
3563 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3566 /* if only the right side is a literal & we are
3567 shifting more than size of the left operand then zero */
3568 if (IS_LITERAL (RTYPE (tree)) &&
3569 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3570 (getSize (TETYPE (tree)) * 8))
3572 if (tree->opval.op==LEFT_OP ||
3573 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3575 lineno=tree->lineno;
3576 werror (W_SHIFT_CHANGED,
3577 (tree->opval.op == LEFT_OP ? "left" : "right"));
3578 tree->type = EX_VALUE;
3579 tree->left = tree->right = NULL;
3580 tree->opval.val = constVal ("0");
3581 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3588 /*------------------------------------------------------------------*/
3589 /*----------------------------*/
3591 /*----------------------------*/
3592 case CAST: /* change the type */
3593 /* cannot cast to an aggregate type */
3594 if (IS_AGGREGATE (LTYPE (tree)))
3596 werror (E_CAST_ILLEGAL);
3597 goto errorTreeReturn;
3600 /* make sure the type is complete and sane */
3601 changePointer(LTYPE(tree));
3602 checkTypeSanity(LETYPE(tree), "(cast)");
3604 /* If code memory is read only, then pointers to code memory */
3605 /* implicitly point to constants -- make this explicit */
3607 sym_link *t = LTYPE(tree);
3608 while (t && t->next)
3610 if (IS_CODEPTR(t) && port->mem.code_ro)
3612 if (IS_SPEC(t->next))
3613 SPEC_CONST (t->next) = 1;
3615 DCL_PTR_CONST (t->next) = 1;
3622 /* if the right is a literal replace the tree */
3623 if (IS_LITERAL (RETYPE (tree))) {
3624 if (!IS_PTR (LTYPE (tree))) {
3625 tree->type = EX_VALUE;
3627 valCastLiteral (LTYPE (tree),
3628 floatFromVal (valFromType (RETYPE (tree))));
3631 TTYPE (tree) = tree->opval.val->type;
3632 tree->values.literalFromCast = 1;
3633 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3634 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3635 sym_link *rest = LTYPE(tree)->next;
3636 werror(W_LITERAL_GENERIC);
3637 TTYPE(tree) = newLink(DECLARATOR);
3638 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3639 TTYPE(tree)->next = rest;
3640 tree->left->opval.lnk = TTYPE(tree);
3643 TTYPE (tree) = LTYPE (tree);
3647 TTYPE (tree) = LTYPE (tree);
3651 #if 0 // this is already checked, now this could be explicit
3652 /* if pointer to struct then check names */
3653 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3654 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3655 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3657 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3658 SPEC_STRUCT(LETYPE(tree))->tag);
3661 if (IS_ADDRESS_OF_OP(tree->right)
3662 && IS_AST_SYM_VALUE (tree->right->left)
3663 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3665 symbol * sym = AST_SYMBOL (tree->right->left);
3666 unsigned int gptype = 0;
3667 unsigned int addr = SPEC_ADDR (sym->etype);
3669 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3671 switch (SPEC_SCLS (sym->etype))
3674 gptype = GPTYPE_CODE;
3677 gptype = GPTYPE_FAR;
3681 gptype = GPTYPE_NEAR;
3684 gptype = GPTYPE_XSTACK;
3689 addr |= gptype << (8*(GPTRSIZE - 1));
3692 tree->type = EX_VALUE;
3694 valCastLiteral (LTYPE (tree), addr);
3695 TTYPE (tree) = tree->opval.val->type;
3696 TETYPE (tree) = getSpec (TTYPE (tree));
3699 tree->values.literalFromCast = 1;
3703 /* handle offsetof macro: */
3704 /* #define offsetof(TYPE, MEMBER) \ */
3705 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3706 if (IS_ADDRESS_OF_OP(tree->right)
3707 && IS_AST_OP (tree->right->left)
3708 && tree->right->left->opval.op == PTR_OP
3709 && IS_AST_OP (tree->right->left->left)
3710 && tree->right->left->left->opval.op == CAST
3711 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3713 symbol *element = getStructElement (
3714 SPEC_STRUCT (LETYPE(tree->right->left)),
3715 AST_SYMBOL(tree->right->left->right)
3719 tree->type = EX_VALUE;
3720 tree->opval.val = valCastLiteral (
3723 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3726 TTYPE (tree) = tree->opval.val->type;
3727 TETYPE (tree) = getSpec (TTYPE (tree));
3734 /* if the right is a literal replace the tree */
3735 if (IS_LITERAL (RETYPE (tree))) {
3737 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3738 /* rewrite (type *)litaddr
3740 and define type at litaddr temp
3741 (but only if type's storage class is not generic)
3743 ast *newTree = newNode ('&', NULL, NULL);
3746 TTYPE (newTree) = LTYPE (tree);
3747 TETYPE (newTree) = getSpec(LTYPE (tree));
3749 /* define a global symbol at the casted address*/
3750 sym = newSymbol(genSymName (0), 0);
3751 sym->type = LTYPE (tree)->next;
3753 sym->type = newLink (V_VOID);
3754 sym->etype = getSpec(sym->type);
3755 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3756 sym->lineDef = tree->lineno;
3759 SPEC_STAT (sym->etype) = 1;
3760 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3761 SPEC_ABSA(sym->etype) = 1;
3762 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3765 newTree->left = newAst_VALUE(symbolVal(sym));
3766 newTree->left->lineno = tree->lineno;
3767 LTYPE (newTree) = sym->type;
3768 LETYPE (newTree) = sym->etype;
3769 LLVAL (newTree) = 1;
3770 LRVAL (newTree) = 0;
3771 TLVAL (newTree) = 1;
3775 if (!IS_PTR (LTYPE (tree))) {
3776 tree->type = EX_VALUE;
3778 valCastLiteral (LTYPE (tree),
3779 floatFromVal (valFromType (RTYPE (tree))));
3780 TTYPE (tree) = tree->opval.val->type;
3783 tree->values.literalFromCast = 1;
3784 TETYPE (tree) = getSpec (TTYPE (tree));
3788 TTYPE (tree) = LTYPE (tree);
3792 TETYPE (tree) = getSpec (TTYPE (tree));
3796 /*------------------------------------------------------------------*/
3797 /*----------------------------*/
3798 /* logical &&, || */
3799 /*----------------------------*/
3802 /* each must be arithmetic type or be a pointer */
3803 if (!IS_PTR (LTYPE (tree)) &&
3804 !IS_ARRAY (LTYPE (tree)) &&
3805 !IS_INTEGRAL (LTYPE (tree)))
3807 werror (E_COMPARE_OP);
3808 goto errorTreeReturn;
3811 if (!IS_PTR (RTYPE (tree)) &&
3812 !IS_ARRAY (RTYPE (tree)) &&
3813 !IS_INTEGRAL (RTYPE (tree)))
3815 werror (E_COMPARE_OP);
3816 goto errorTreeReturn;
3818 /* if they are both literal then */
3819 /* rewrite the tree */
3820 if (IS_LITERAL (RTYPE (tree)) &&
3821 IS_LITERAL (LTYPE (tree)))
3823 tree->type = EX_VALUE;
3824 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3825 valFromType (RTYPE (tree)),
3827 tree->right = tree->left = NULL;
3828 TETYPE (tree) = getSpec (TTYPE (tree) =
3829 tree->opval.val->type);
3832 LRVAL (tree) = RRVAL (tree) = 1;
3833 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3836 /*------------------------------------------------------------------*/
3837 /*----------------------------*/
3838 /* comparison operators */
3839 /*----------------------------*/
3847 ast *lt = optimizeCompare (tree);
3853 /* if they are pointers they must be castable */
3854 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3856 if (tree->opval.op==EQ_OP &&
3857 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3858 // we cannot cast a gptr to a !gptr: switch the leaves
3859 struct ast *s=tree->left;
3860 tree->left=tree->right;
3863 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3865 werror (E_COMPARE_OP);
3866 fprintf (stderr, "comparing type ");
3867 printTypeChain (LTYPE (tree), stderr);
3868 fprintf (stderr, "to type ");
3869 printTypeChain (RTYPE (tree), stderr);
3870 fprintf (stderr, "\n");
3871 goto errorTreeReturn;
3874 /* else they should be promotable to one another */
3877 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3878 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3880 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3882 werror (E_COMPARE_OP);
3883 fprintf (stderr, "comparing type ");
3884 printTypeChain (LTYPE (tree), stderr);
3885 fprintf (stderr, "to type ");
3886 printTypeChain (RTYPE (tree), stderr);
3887 fprintf (stderr, "\n");
3888 goto errorTreeReturn;
3891 /* if unsigned value < 0 then always false */
3892 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3893 if (SPEC_USIGN(LETYPE(tree)) &&
3894 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3895 IS_LITERAL(RTYPE(tree)) &&
3896 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3898 if (tree->opval.op == '<')
3902 if (tree->opval.op == '>')
3904 if (resultType == RESULT_TYPE_IFX)
3906 /* the parent is an ifx: */
3907 /* if (unsigned value) */
3911 /* (unsigned value) ? 1 : 0 */
3912 tree->opval.op = '?';
3913 tree->right = newNode (':',
3914 newAst_VALUE (constVal ("1")),
3915 tree->right); /* val 0 */
3916 tree->right->lineno = tree->lineno;
3917 tree->right->left->lineno = tree->lineno;
3918 decorateType (tree->right, RESULT_TYPE_NONE);
3921 /* if they are both literal then */
3922 /* rewrite the tree */
3923 if (IS_LITERAL (RTYPE (tree)) &&
3924 IS_LITERAL (LTYPE (tree)))
3926 tree->type = EX_VALUE;
3927 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3928 valFromType (RETYPE (tree)),
3930 tree->right = tree->left = NULL;
3931 TETYPE (tree) = getSpec (TTYPE (tree) =
3932 tree->opval.val->type);
3935 /* if one is 'signed char ' and the other one is 'unsigned char' */
3936 /* it's necessary to promote to int */
3937 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
3938 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
3940 werror (W_CMP_SU_CHAR);
3941 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
3942 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
3945 LRVAL (tree) = RRVAL (tree) = 1;
3946 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3949 /*------------------------------------------------------------------*/
3950 /*----------------------------*/
3952 /*----------------------------*/
3953 case SIZEOF: /* evaluate wihout code generation */
3954 /* change the type to a integer */
3956 int size = getSize (tree->right->ftype);
3957 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3958 if (!size && !IS_VOID(tree->right->ftype))
3959 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3961 tree->type = EX_VALUE;
3962 tree->opval.val = constVal (buffer);
3963 tree->right = tree->left = NULL;
3964 TETYPE (tree) = getSpec (TTYPE (tree) =
3965 tree->opval.val->type);
3968 /*------------------------------------------------------------------*/
3969 /*----------------------------*/
3971 /*----------------------------*/
3973 /* return typeof enum value */
3974 tree->type = EX_VALUE;
3977 if (IS_SPEC(tree->right->ftype)) {
3978 switch (SPEC_NOUN(tree->right->ftype)) {
3980 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3981 else typeofv = TYPEOF_INT;
3984 typeofv = TYPEOF_FLOAT;
3987 typeofv = TYPEOF_FIXED16X16;
3990 typeofv = TYPEOF_CHAR;
3993 typeofv = TYPEOF_VOID;
3996 typeofv = TYPEOF_STRUCT;
3999 typeofv = TYPEOF_BITFIELD;
4002 typeofv = TYPEOF_BIT;
4005 typeofv = TYPEOF_SBIT;
4011 switch (DCL_TYPE(tree->right->ftype)) {
4013 typeofv = TYPEOF_POINTER;
4016 typeofv = TYPEOF_FPOINTER;
4019 typeofv = TYPEOF_CPOINTER;
4022 typeofv = TYPEOF_GPOINTER;
4025 typeofv = TYPEOF_PPOINTER;
4028 typeofv = TYPEOF_IPOINTER;
4031 typeofv = TYPEOF_ARRAY;
4034 typeofv = TYPEOF_FUNCTION;
4040 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4041 tree->opval.val = constVal (buffer);
4042 tree->right = tree->left = NULL;
4043 TETYPE (tree) = getSpec (TTYPE (tree) =
4044 tree->opval.val->type);
4047 /*------------------------------------------------------------------*/
4048 /*----------------------------*/
4049 /* conditional operator '?' */
4050 /*----------------------------*/
4052 /* the type is value of the colon operator (on the right) */
4053 assert (IS_COLON_OP (tree->right));
4054 /* if already known then replace the tree : optimizer will do it
4055 but faster to do it here */
4056 if (IS_LITERAL (LTYPE (tree)))
4058 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4059 return decorateType (tree->right->left, resultTypeProp);
4061 return decorateType (tree->right->right, resultTypeProp);
4065 tree->right = decorateType (tree->right, resultTypeProp);
4066 TTYPE (tree) = RTYPE (tree);
4067 TETYPE (tree) = getSpec (TTYPE (tree));
4072 /* if they don't match we have a problem */
4073 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4074 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4076 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4077 goto errorTreeReturn;
4080 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4081 resultType, tree->opval.op);
4082 TETYPE (tree) = getSpec (TTYPE (tree));
4086 #if 0 // assignment operators are converted by the parser
4087 /*------------------------------------------------------------------*/
4088 /*----------------------------*/
4089 /* assignment operators */
4090 /*----------------------------*/
4093 /* for these it must be both must be integral */
4094 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4095 !IS_ARITHMETIC (RTYPE (tree)))
4097 werror (E_OPS_INTEGRAL);
4098 goto errorTreeReturn;
4101 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4103 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4104 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4108 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4109 goto errorTreeReturn;
4120 /* for these it must be both must be integral */
4121 if (!IS_INTEGRAL (LTYPE (tree)) ||
4122 !IS_INTEGRAL (RTYPE (tree)))
4124 werror (E_OPS_INTEGRAL);
4125 goto errorTreeReturn;
4128 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4130 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4131 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4135 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4136 goto errorTreeReturn;
4142 /*------------------------------------------------------------------*/
4143 /*----------------------------*/
4145 /*----------------------------*/
4147 if (!(IS_PTR (LTYPE (tree)) ||
4148 IS_ARITHMETIC (LTYPE (tree))))
4150 werror (E_PLUS_INVALID, "-=");
4151 goto errorTreeReturn;
4154 if (!(IS_PTR (RTYPE (tree)) ||
4155 IS_ARITHMETIC (RTYPE (tree))))
4157 werror (E_PLUS_INVALID, "-=");
4158 goto errorTreeReturn;
4161 TETYPE (tree) = getSpec (TTYPE (tree) =
4162 computeType (LTYPE (tree),
4167 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4168 werror (E_CODE_WRITE, "-=");
4172 werror (E_LVALUE_REQUIRED, "-=");
4173 goto errorTreeReturn;
4179 /*------------------------------------------------------------------*/
4180 /*----------------------------*/
4182 /*----------------------------*/
4184 /* this is not a unary operation */
4185 /* if both pointers then problem */
4186 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4188 werror (E_PTR_PLUS_PTR);
4189 goto errorTreeReturn;
4192 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4194 werror (E_PLUS_INVALID, "+=");
4195 goto errorTreeReturn;
4198 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4200 werror (E_PLUS_INVALID, "+=");
4201 goto errorTreeReturn;
4204 TETYPE (tree) = getSpec (TTYPE (tree) =
4205 computeType (LTYPE (tree),
4210 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4211 werror (E_CODE_WRITE, "+=");
4215 werror (E_LVALUE_REQUIRED, "+=");
4216 goto errorTreeReturn;
4219 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4220 tree->opval.op = '=';
4225 /*------------------------------------------------------------------*/
4226 /*----------------------------*/
4227 /* straight assignemnt */
4228 /*----------------------------*/
4230 /* cannot be an aggregate */
4231 if (IS_AGGREGATE (LTYPE (tree)))
4233 werror (E_AGGR_ASSIGN);
4234 goto errorTreeReturn;
4237 /* they should either match or be castable */
4238 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4240 werror (E_TYPE_MISMATCH, "assignment", " ");
4241 printFromToType(RTYPE(tree),LTYPE(tree));
4244 /* if the left side of the tree is of type void
4245 then report error */
4246 if (IS_VOID (LTYPE (tree)))
4248 werror (E_CAST_ZERO);
4249 printFromToType(RTYPE(tree), LTYPE(tree));
4252 TETYPE (tree) = getSpec (TTYPE (tree) =
4256 if (!tree->initMode ) {
4257 if (IS_CONSTANT(LTYPE(tree)))
4258 werror (E_CODE_WRITE, "=");
4262 werror (E_LVALUE_REQUIRED, "=");
4263 goto errorTreeReturn;
4268 /*------------------------------------------------------------------*/
4269 /*----------------------------*/
4270 /* comma operator */
4271 /*----------------------------*/
4273 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4276 /*------------------------------------------------------------------*/
4277 /*----------------------------*/
4279 /*----------------------------*/
4282 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4283 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4285 if (tree->left->opval.op == '*' && !tree->left->right)
4286 tree->left = tree->left->left;
4289 /* require a function or pointer to function */
4290 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4292 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4293 goto errorTreeReturn;
4296 /* if there are parms, make sure that
4297 parms are decorate / process / reverse only once */
4299 !tree->right->decorated)
4304 if (IS_FUNCPTR (LTYPE (tree)))
4305 functype = LTYPE (tree)->next;
4307 functype = LTYPE (tree);
4309 if (processParms (tree->left, FUNC_ARGS(functype),
4310 &tree->right, &parmNumber, TRUE))
4312 goto errorTreeReturn;
4315 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4316 !IFFUNC_ISBUILTIN(functype))
4318 reverseParms (tree->right);
4321 TTYPE (tree) = functype->next;
4322 TETYPE (tree) = getSpec (TTYPE (tree));
4326 /*------------------------------------------------------------------*/
4327 /*----------------------------*/
4328 /* return statement */
4329 /*----------------------------*/
4334 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4336 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4337 printFromToType (RTYPE(tree), currFunc->type->next);
4338 goto errorTreeReturn;
4341 if (IS_VOID (currFunc->type->next)
4343 !IS_VOID (RTYPE (tree)))
4345 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4346 goto errorTreeReturn;
4349 /* if there is going to be a casting required then add it */
4350 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4353 decorateType (newNode (CAST,
4354 newAst_LINK (copyLinkChain (currFunc->type->next)),
4364 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4366 werror (W_VOID_FUNC, currFunc->name);
4367 goto errorTreeReturn;
4370 TTYPE (tree) = TETYPE (tree) = NULL;
4373 /*------------------------------------------------------------------*/
4374 /*----------------------------*/
4375 /* switch statement */
4376 /*----------------------------*/
4378 /* the switch value must be an integer */
4379 if (!IS_INTEGRAL (LTYPE (tree)))
4381 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4382 goto errorTreeReturn;
4385 TTYPE (tree) = TETYPE (tree) = NULL;
4388 /*------------------------------------------------------------------*/
4389 /*----------------------------*/
4391 /*----------------------------*/
4393 tree->left = backPatchLabels (tree->left,
4396 TTYPE (tree) = TETYPE (tree) = NULL;
4399 /*------------------------------------------------------------------*/
4400 /*----------------------------*/
4402 /*----------------------------*/
4405 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4406 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4407 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4409 /* if the for loop is reversible then
4410 reverse it otherwise do what we normally
4416 if (isLoopReversible (tree, &sym, &init, &end))
4417 return reverseLoop (tree, sym, init, end);
4419 return decorateType (createFor (AST_FOR (tree, trueLabel),
4420 AST_FOR (tree, continueLabel),
4421 AST_FOR (tree, falseLabel),
4422 AST_FOR (tree, condLabel),
4423 AST_FOR (tree, initExpr),
4424 AST_FOR (tree, condExpr),
4425 AST_FOR (tree, loopExpr),
4426 tree->left), RESULT_TYPE_NONE);
4429 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4430 "node PARAM shouldn't be processed here");
4431 /* but in processParams() */
4434 TTYPE (tree) = TETYPE (tree) = NULL;
4438 /* some error found this tree will be killed */
4440 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4441 tree->opval.op = NULLOP;
4447 /*-----------------------------------------------------------------*/
4448 /* sizeofOp - processes size of operation */
4449 /*-----------------------------------------------------------------*/
4451 sizeofOp (sym_link * type)
4456 /* make sure the type is complete and sane */
4457 checkTypeSanity(type, "(sizeof)");
4459 /* get the size and convert it to character */
4460 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4461 if (!size && !IS_VOID(type))
4462 werror (E_SIZEOF_INCOMPLETE_TYPE);
4464 /* now convert into value */
4465 return constVal (buff);
4469 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4470 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4471 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4472 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4473 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4474 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4475 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4477 /*-----------------------------------------------------------------*/
4478 /* backPatchLabels - change and or not operators to flow control */
4479 /*-----------------------------------------------------------------*/
4481 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4487 if (!(IS_ANDORNOT (tree)))
4490 /* if this an and */
4493 static int localLbl = 0;
4496 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4497 localLabel = newSymbol (buffer, NestLevel);
4499 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4501 /* if left is already a IFX then just change the if true label in that */
4502 if (!IS_IFX (tree->left))
4503 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4505 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4506 /* right is a IFX then just join */
4507 if (IS_IFX (tree->right))
4508 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4510 tree->right = createLabel (localLabel, tree->right);
4511 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4513 return newNode (NULLOP, tree->left, tree->right);
4516 /* if this is an or operation */
4519 static int localLbl = 0;
4522 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4523 localLabel = newSymbol (buffer, NestLevel);
4525 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4527 /* if left is already a IFX then just change the if true label in that */
4528 if (!IS_IFX (tree->left))
4529 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4531 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4532 /* right is a IFX then just join */
4533 if (IS_IFX (tree->right))
4534 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4536 tree->right = createLabel (localLabel, tree->right);
4537 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4539 return newNode (NULLOP, tree->left, tree->right);
4545 int wasnot = IS_NOT (tree->left);
4546 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4548 /* if the left is already a IFX */
4549 if (!IS_IFX (tree->left))
4550 tree->left = newNode (IFX, tree->left, NULL);
4554 tree->left->trueLabel = trueLabel;
4555 tree->left->falseLabel = falseLabel;
4559 tree->left->trueLabel = falseLabel;
4560 tree->left->falseLabel = trueLabel;
4567 tree->trueLabel = trueLabel;
4568 tree->falseLabel = falseLabel;
4575 /*-----------------------------------------------------------------*/
4576 /* createBlock - create expression tree for block */
4577 /*-----------------------------------------------------------------*/
4579 createBlock (symbol * decl, ast * body)
4583 /* if the block has nothing */
4587 ex = newNode (BLOCK, NULL, body);
4588 ex->values.sym = decl;
4595 /*-----------------------------------------------------------------*/
4596 /* createLabel - creates the expression tree for labels */
4597 /*-----------------------------------------------------------------*/
4599 createLabel (symbol * label, ast * stmnt)
4602 char name[SDCC_NAME_MAX + 1];
4605 /* must create fresh symbol if the symbol name */
4606 /* exists in the symbol table, since there can */
4607 /* be a variable with the same name as the labl */
4608 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4609 (csym->level == label->level))
4610 label = newSymbol (label->name, label->level);
4612 /* change the name before putting it in add _ */
4613 SNPRINTF(name, sizeof(name), "%s", label->name);
4615 /* put the label in the LabelSymbol table */
4616 /* but first check if a label of the same */
4618 if ((csym = findSym (LabelTab, NULL, name)))
4619 werror (E_DUPLICATE_LABEL, label->name);
4621 addSym (LabelTab, label, name, label->level, 0, 0);
4625 label->key = labelKey++;
4626 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4632 /*-----------------------------------------------------------------*/
4633 /* createCase - generates the parsetree for a case statement */
4634 /*-----------------------------------------------------------------*/
4636 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4638 char caseLbl[SDCC_NAME_MAX + 1];
4642 /* if the switch statement does not exist */
4643 /* then case is out of context */
4646 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4650 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4651 /* if not a constant then error */
4652 if (!IS_LITERAL (caseVal->ftype))
4654 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4658 /* if not a integer than error */
4659 if (!IS_INTEGRAL (caseVal->ftype))
4661 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4665 /* find the end of the switch values chain */
4666 if (!(val = swStat->values.switchVals.swVals))
4667 swStat->values.switchVals.swVals = caseVal->opval.val;
4670 /* also order the cases according to value */
4672 int cVal = (int) floatFromVal (caseVal->opval.val);
4673 while (val && (int) floatFromVal (val) < cVal)
4679 /* if we reached the end then */
4682 pval->next = caseVal->opval.val;
4684 else if ((int) floatFromVal (val) == cVal)
4686 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4692 /* we found a value greater than */
4693 /* the current value we must add this */
4694 /* before the value */
4695 caseVal->opval.val->next = val;
4697 /* if this was the first in chain */
4698 if (swStat->values.switchVals.swVals == val)
4699 swStat->values.switchVals.swVals =
4702 pval->next = caseVal->opval.val;
4707 /* create the case label */
4708 SNPRINTF(caseLbl, sizeof(caseLbl),
4710 swStat->values.switchVals.swNum,
4711 (int) floatFromVal (caseVal->opval.val));
4713 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4718 /*-----------------------------------------------------------------*/
4719 /* createDefault - creates the parse tree for the default statement */
4720 /*-----------------------------------------------------------------*/
4722 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4724 char defLbl[SDCC_NAME_MAX + 1];
4726 /* if the switch statement does not exist */
4727 /* then case is out of context */
4730 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4734 if (swStat->values.switchVals.swDefault)
4736 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4741 /* turn on the default flag */
4742 swStat->values.switchVals.swDefault = 1;
4744 /* create the label */
4745 SNPRINTF (defLbl, sizeof(defLbl),
4746 "_default_%d", swStat->values.switchVals.swNum);
4747 return createLabel (newSymbol (defLbl, 0), stmnt);
4750 /*-----------------------------------------------------------------*/
4751 /* createIf - creates the parsetree for the if statement */
4752 /*-----------------------------------------------------------------*/
4754 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4756 static int Lblnum = 0;
4758 symbol *ifTrue, *ifFalse, *ifEnd;
4760 /* if neither exists */
4761 if (!elseBody && !ifBody) {
4762 // if there are no side effects (i++, j() etc)
4763 if (!hasSEFcalls(condAst)) {
4768 /* create the labels */
4769 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4770 ifFalse = newSymbol (buffer, NestLevel);
4771 /* if no else body then end == false */
4776 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4777 ifEnd = newSymbol (buffer, NestLevel);
4780 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4781 ifTrue = newSymbol (buffer, NestLevel);
4785 /* attach the ifTrue label to the top of it body */
4786 ifBody = createLabel (ifTrue, ifBody);
4787 /* attach a goto end to the ifBody if else is present */
4790 ifBody = newNode (NULLOP, ifBody,
4792 newAst_VALUE (symbolVal (ifEnd)),
4794 /* put the elseLabel on the else body */
4795 elseBody = createLabel (ifFalse, elseBody);
4796 /* out the end at the end of the body */
4797 elseBody = newNode (NULLOP,
4799 createLabel (ifEnd, NULL));
4803 ifBody = newNode (NULLOP, ifBody,
4804 createLabel (ifFalse, NULL));
4806 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4807 if (IS_IFX (condAst))
4810 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4812 return newNode (NULLOP, ifTree,
4813 newNode (NULLOP, ifBody, elseBody));
4817 /*-----------------------------------------------------------------*/
4818 /* createDo - creates parse tree for do */
4821 /* _docontinue_n: */
4822 /* condition_expression +-> trueLabel -> _dobody_n */
4824 /* +-> falseLabel-> _dobreak_n */
4826 /*-----------------------------------------------------------------*/
4828 createDo (symbol * trueLabel, symbol * continueLabel,
4829 symbol * falseLabel, ast * condAst, ast * doBody)
4834 /* if the body does not exist then it is simple */
4837 condAst = backPatchLabels (condAst, continueLabel, NULL);
4838 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4839 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4840 doTree->trueLabel = continueLabel;
4841 doTree->falseLabel = NULL;
4845 /* otherwise we have a body */
4846 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4848 /* attach the body label to the top */
4849 doBody = createLabel (trueLabel, doBody);
4850 /* attach the continue label to end of body */
4851 doBody = newNode (NULLOP, doBody,
4852 createLabel (continueLabel, NULL));
4854 /* now put the break label at the end */
4855 if (IS_IFX (condAst))
4858 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4860 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4862 /* putting it together */
4863 return newNode (NULLOP, doBody, doTree);
4866 /*-----------------------------------------------------------------*/
4867 /* createFor - creates parse tree for 'for' statement */
4870 /* condExpr +-> trueLabel -> _forbody_n */
4872 /* +-> falseLabel-> _forbreak_n */
4875 /* _forcontinue_n: */
4877 /* goto _forcond_n ; */
4879 /*-----------------------------------------------------------------*/
4881 createFor (symbol * trueLabel, symbol * continueLabel,
4882 symbol * falseLabel, symbol * condLabel,
4883 ast * initExpr, ast * condExpr, ast * loopExpr,
4888 /* if loopexpression not present then we can generate it */
4889 /* the same way as a while */
4891 return newNode (NULLOP, initExpr,
4892 createWhile (trueLabel, continueLabel,
4893 falseLabel, condExpr, forBody));
4894 /* vanilla for statement */
4895 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4897 if (condExpr && !IS_IFX (condExpr))
4898 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4901 /* attach condition label to condition */
4902 condExpr = createLabel (condLabel, condExpr);
4904 /* attach body label to body */
4905 forBody = createLabel (trueLabel, forBody);
4907 /* attach continue to forLoop expression & attach */
4908 /* goto the forcond @ and of loopExpression */
4909 loopExpr = createLabel (continueLabel,
4913 newAst_VALUE (symbolVal (condLabel)),
4915 /* now start putting them together */
4916 forTree = newNode (NULLOP, initExpr, condExpr);
4917 forTree = newNode (NULLOP, forTree, forBody);
4918 forTree = newNode (NULLOP, forTree, loopExpr);
4919 /* finally add the break label */
4920 forTree = newNode (NULLOP, forTree,
4921 createLabel (falseLabel, NULL));
4925 /*-----------------------------------------------------------------*/
4926 /* createWhile - creates parse tree for while statement */
4927 /* the while statement will be created as follows */
4929 /* _while_continue_n: */
4930 /* condition_expression +-> trueLabel -> _while_boby_n */
4932 /* +-> falseLabel -> _while_break_n */
4933 /* _while_body_n: */
4935 /* goto _while_continue_n */
4936 /* _while_break_n: */
4937 /*-----------------------------------------------------------------*/
4939 createWhile (symbol * trueLabel, symbol * continueLabel,
4940 symbol * falseLabel, ast * condExpr, ast * whileBody)
4944 /* put the continue label */
4945 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4946 condExpr = createLabel (continueLabel, condExpr);
4947 condExpr->lineno = 0;
4949 /* put the body label in front of the body */
4950 whileBody = createLabel (trueLabel, whileBody);
4951 whileBody->lineno = 0;
4952 /* put a jump to continue at the end of the body */
4953 /* and put break label at the end of the body */
4954 whileBody = newNode (NULLOP,
4957 newAst_VALUE (symbolVal (continueLabel)),
4958 createLabel (falseLabel, NULL)));
4960 /* put it all together */
4961 if (IS_IFX (condExpr))
4962 whileTree = condExpr;
4965 whileTree = newNode (IFX, condExpr, NULL);
4966 /* put the true & false labels in place */
4967 whileTree->trueLabel = trueLabel;
4968 whileTree->falseLabel = falseLabel;
4971 return newNode (NULLOP, whileTree, whileBody);
4974 /*-----------------------------------------------------------------*/
4975 /* isShiftRightLitVal _BitAndLitVal - helper function */
4976 /*-----------------------------------------------------------------*/
4978 isShiftRightLitVal_BitAndLitVal (ast * tree)
4980 /* if this is not a bit and */
4981 if (!IS_BITAND (tree))
4984 /* will look for tree of the form
4985 ( expr >> litval2) & litval1 */
4986 if (!IS_AST_LIT_VALUE (tree->right))
4989 if (!IS_RIGHT_OP (tree->left))
4992 if (!IS_AST_LIT_VALUE (tree->left->right))
4995 return tree->left->left;
4998 /*-----------------------------------------------------------------*/
4999 /* isBitAndPowOf2 - helper function */
5000 /*-----------------------------------------------------------------*/
5002 isBitAndPow2 (ast * tree)
5004 /* if this is not a bit and */
5005 if (!IS_BITAND (tree))
5008 /* will look for tree of the form
5009 ( expr & (1 << litval) */
5010 if (!IS_AST_LIT_VALUE (tree->right))
5013 return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5016 /*-----------------------------------------------------------------*/
5017 /* optimizeGetHbit - get highest order bit of the expression */
5018 /*-----------------------------------------------------------------*/
5020 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5025 expr = isShiftRightLitVal_BitAndLitVal(tree);
5028 if ((AST_LIT_VALUE (tree->right) != 1) ||
5029 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5030 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5033 if (!expr && (resultType == RESULT_TYPE_BIT))
5036 if (isBitAndPow2 (tree) != getSize (TTYPE (expr)) * 8 - 1)
5042 /* make sure the port supports GETHBIT */
5043 if (port->hasExtBitOp
5044 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5047 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5050 /*-----------------------------------------------------------------*/
5051 /* optimizeGetAbit - get a single bit of the expression */
5052 /*-----------------------------------------------------------------*/
5054 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5059 expr = isShiftRightLitVal_BitAndLitVal(tree);
5062 if (AST_LIT_VALUE (tree->right) != 1)
5064 count = tree->left->right;
5066 if (!expr && (resultType == RESULT_TYPE_BIT))
5068 int p2 = isBitAndPow2 (tree);
5072 count = newAst_VALUE (valueFromLit (p2));
5078 /* make sure the port supports GETABIT */
5079 if (port->hasExtBitOp
5080 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5083 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5087 /*-----------------------------------------------------------------*/
5088 /* optimizeGetByte - get a byte of the expression */
5089 /*-----------------------------------------------------------------*/
5091 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5097 expr = isShiftRightLitVal_BitAndLitVal(tree);
5100 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5101 count = tree->left->right;
5102 if (AST_LIT_VALUE (tree->right) != 0xFF)
5105 if (!expr && resultType == RESULT_TYPE_CHAR)
5107 /* if this is a right shift over a multiple of 8 */
5108 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5110 i = (unsigned int) AST_LIT_VALUE (tree->right);
5111 count = tree->right;
5115 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5118 /* make sure the port supports GETBYTE */
5119 if (port->hasExtBitOp
5120 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5123 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5126 /*-----------------------------------------------------------------*/
5127 /* optimizeGetWord - get two bytes of the expression */
5128 /*-----------------------------------------------------------------*/
5130 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5136 expr = isShiftRightLitVal_BitAndLitVal(tree);
5139 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5140 count = tree->left->right;
5141 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5144 if (!expr && resultType == RESULT_TYPE_INT)
5146 /* if this is a right shift over a multiple of 8 */
5147 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5149 i = (unsigned int) AST_LIT_VALUE (tree->right);
5150 count = tree->right;
5154 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5157 /* make sure the port supports GETWORD */
5158 if (port->hasExtBitOp
5159 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5162 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5165 /*-----------------------------------------------------------------*/
5166 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5167 /*-----------------------------------------------------------------*/
5169 optimizeRRCRLC (ast * root)
5171 /* will look for trees of the form
5172 (?expr << 1) | (?expr >> 7) or
5173 (?expr >> 7) | (?expr << 1) will make that
5174 into a RLC : operation ..
5176 (?expr >> 1) | (?expr << 7) or
5177 (?expr << 7) | (?expr >> 1) will make that
5178 into a RRC operation
5179 note : by 7 I mean (number of bits required to hold the
5181 /* if the root operations is not a | operation the not */
5182 if (!IS_BITOR (root))
5185 /* I have to think of a better way to match patterns this sucks */
5186 /* that aside let start looking for the first case : I use a the
5187 negative check a lot to improve the efficiency */
5188 /* (?expr << 1) | (?expr >> 7) */
5189 if (IS_LEFT_OP (root->left) &&
5190 IS_RIGHT_OP (root->right))
5193 if (!SPEC_USIGN (TETYPE (root->left->left)))
5196 if (!IS_AST_LIT_VALUE (root->left->right) ||
5197 !IS_AST_LIT_VALUE (root->right->right))
5200 /* make sure it is the same expression */
5201 if (!isAstEqual (root->left->left,
5205 if (AST_LIT_VALUE (root->left->right) != 1)
5208 if (AST_LIT_VALUE (root->right->right) !=
5209 (getSize (TTYPE (root->left->left)) * 8 - 1))
5212 /* make sure the port supports RLC */
5213 if (port->hasExtBitOp
5214 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5217 /* whew got the first case : create the AST */
5218 return newNode (RLC, root->left->left, NULL);
5222 /* check for second case */
5223 /* (?expr >> 7) | (?expr << 1) */
5224 if (IS_LEFT_OP (root->right) &&
5225 IS_RIGHT_OP (root->left))
5228 if (!SPEC_USIGN (TETYPE (root->left->left)))
5231 if (!IS_AST_LIT_VALUE (root->left->right) ||
5232 !IS_AST_LIT_VALUE (root->right->right))
5235 /* make sure it is the same symbol */
5236 if (!isAstEqual (root->left->left,
5240 if (AST_LIT_VALUE (root->right->right) != 1)
5243 if (AST_LIT_VALUE (root->left->right) !=
5244 (getSize (TTYPE (root->left->left)) * 8 - 1))
5247 /* make sure the port supports RLC */
5248 if (port->hasExtBitOp
5249 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5252 /* whew got the first case : create the AST */
5253 return newNode (RLC, root->left->left, NULL);
5258 /* third case for RRC */
5259 /* (?symbol >> 1) | (?symbol << 7) */
5260 if (IS_LEFT_OP (root->right) &&
5261 IS_RIGHT_OP (root->left))
5264 if (!SPEC_USIGN (TETYPE (root->left->left)))
5267 if (!IS_AST_LIT_VALUE (root->left->right) ||
5268 !IS_AST_LIT_VALUE (root->right->right))
5271 /* make sure it is the same symbol */
5272 if (!isAstEqual (root->left->left,
5276 if (AST_LIT_VALUE (root->left->right) != 1)
5279 if (AST_LIT_VALUE (root->right->right) !=
5280 (getSize (TTYPE (root->left->left)) * 8 - 1))
5283 /* make sure the port supports RRC */
5284 if (port->hasExtBitOp
5285 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5288 /* whew got the first case : create the AST */
5289 return newNode (RRC, root->left->left, NULL);
5293 /* fourth and last case for now */
5294 /* (?symbol << 7) | (?symbol >> 1) */
5295 if (IS_RIGHT_OP (root->right) &&
5296 IS_LEFT_OP (root->left))
5299 if (!SPEC_USIGN (TETYPE (root->left->left)))
5302 if (!IS_AST_LIT_VALUE (root->left->right) ||
5303 !IS_AST_LIT_VALUE (root->right->right))
5306 /* make sure it is the same symbol */
5307 if (!isAstEqual (root->left->left,
5311 if (AST_LIT_VALUE (root->right->right) != 1)
5314 if (AST_LIT_VALUE (root->left->right) !=
5315 (getSize (TTYPE (root->left->left)) * 8 - 1))
5318 /* make sure the port supports RRC */
5319 if (port->hasExtBitOp
5320 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5323 /* whew got the first case : create the AST */
5324 return newNode (RRC, root->left->left, NULL);
5328 /* not found return root */
5332 /*-----------------------------------------------------------------*/
5333 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5334 /*-----------------------------------------------------------------*/
5336 optimizeSWAP (ast * root)
5338 /* will look for trees of the form
5339 (?expr << 4) | (?expr >> 4) or
5340 (?expr >> 4) | (?expr << 4) will make that
5341 into a SWAP : operation ..
5342 note : by 4 I mean (number of bits required to hold the
5344 /* if the root operations is not a | operation the not */
5345 if (!IS_BITOR (root))
5348 /* (?expr << 4) | (?expr >> 4) */
5349 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5350 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5353 if (!SPEC_USIGN (TETYPE (root->left->left)))
5356 if (!IS_AST_LIT_VALUE (root->left->right) ||
5357 !IS_AST_LIT_VALUE (root->right->right))
5360 /* make sure it is the same expression */
5361 if (!isAstEqual (root->left->left,
5365 if (AST_LIT_VALUE (root->left->right) !=
5366 (getSize (TTYPE (root->left->left)) * 4))
5369 if (AST_LIT_VALUE (root->right->right) !=
5370 (getSize (TTYPE (root->left->left)) * 4))
5373 /* make sure the port supports SWAP */
5374 if (port->hasExtBitOp
5375 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5378 /* found it : create the AST */
5379 return newNode (SWAP, root->left->left, NULL);
5383 /* not found return root */
5387 /*-----------------------------------------------------------------*/
5388 /* optimizeCompare - optimizes compares for bit variables */
5389 /*-----------------------------------------------------------------*/
5391 optimizeCompare (ast * root)
5393 ast *optExpr = NULL;
5396 unsigned int litValue;
5398 /* if nothing then return nothing */
5402 /* if not a compare op then do leaves */
5403 if (!IS_COMPARE_OP (root))
5405 root->left = optimizeCompare (root->left);
5406 root->right = optimizeCompare (root->right);
5410 /* if left & right are the same then depending
5411 of the operation do */
5412 if (isAstEqual (root->left, root->right))
5414 switch (root->opval.op)
5419 optExpr = newAst_VALUE (constVal ("0"));
5424 optExpr = newAst_VALUE (constVal ("1"));
5428 return decorateType (optExpr, RESULT_TYPE_NONE);
5431 vleft = (root->left->type == EX_VALUE ?
5432 root->left->opval.val : NULL);
5434 vright = (root->right->type == EX_VALUE ?
5435 root->right->opval.val : NULL);
5437 /* if left is a BITVAR in BITSPACE */
5438 /* and right is a LITERAL then opt- */
5439 /* imize else do nothing */
5440 if (vleft && vright &&
5441 IS_BITVAR (vleft->etype) &&
5442 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5443 IS_LITERAL (vright->etype))
5446 /* if right side > 1 then comparison may never succeed */
5447 if ((litValue = (int) floatFromVal (vright)) > 1)
5449 werror (W_BAD_COMPARE);
5455 switch (root->opval.op)
5457 case '>': /* bit value greater than 1 cannot be */
5458 werror (W_BAD_COMPARE);
5462 case '<': /* bit value < 1 means 0 */
5464 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5467 case LE_OP: /* bit value <= 1 means no check */
5468 optExpr = newAst_VALUE (vright);
5471 case GE_OP: /* bit value >= 1 means only check for = */
5473 optExpr = newAst_VALUE (vleft);
5478 { /* literal is zero */
5479 switch (root->opval.op)
5481 case '<': /* bit value < 0 cannot be */
5482 werror (W_BAD_COMPARE);
5486 case '>': /* bit value > 0 means 1 */
5488 optExpr = newAst_VALUE (vleft);
5491 case LE_OP: /* bit value <= 0 means no check */
5492 case GE_OP: /* bit value >= 0 means no check */
5493 werror (W_BAD_COMPARE);
5497 case EQ_OP: /* bit == 0 means ! of bit */
5498 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5502 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5503 } /* end-of-if of BITVAR */
5508 /*-----------------------------------------------------------------*/
5509 /* addSymToBlock : adds the symbol to the first block we find */
5510 /*-----------------------------------------------------------------*/
5512 addSymToBlock (symbol * sym, ast * tree)
5514 /* reached end of tree or a leaf */
5515 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5519 if (IS_AST_OP (tree) &&
5520 tree->opval.op == BLOCK)
5523 symbol *lsym = copySymbol (sym);
5525 lsym->next = AST_VALUES (tree, sym);
5526 AST_VALUES (tree, sym) = lsym;
5530 addSymToBlock (sym, tree->left);
5531 addSymToBlock (sym, tree->right);
5534 /*-----------------------------------------------------------------*/
5535 /* processRegParms - do processing for register parameters */
5536 /*-----------------------------------------------------------------*/
5538 processRegParms (value * args, ast * body)
5542 if (IS_REGPARM (args->etype))
5543 addSymToBlock (args->sym, body);
5548 /*-----------------------------------------------------------------*/
5549 /* resetParmKey - resets the operandkeys for the symbols */
5550 /*-----------------------------------------------------------------*/
5551 DEFSETFUNC (resetParmKey)
5562 /*-----------------------------------------------------------------*/
5563 /* createFunction - This is the key node that calls the iCode for */
5564 /* generating the code for a function. Note code */
5565 /* is generated function by function, later when */
5566 /* add inter-procedural analysis this will change */
5567 /*-----------------------------------------------------------------*/
5569 createFunction (symbol * name, ast * body)
5575 iCode *piCode = NULL;
5577 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5578 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5580 /* if check function return 0 then some problem */
5581 if (checkFunction (name, NULL) == 0)
5584 /* create a dummy block if none exists */
5586 body = newNode (BLOCK, NULL, NULL);
5590 /* check if the function name already in the symbol table */
5591 if ((csym = findSym (SymbolTab, NULL, name->name)))
5594 /* special case for compiler defined functions
5595 we need to add the name to the publics list : this
5596 actually means we are now compiling the compiler
5600 addSet (&publics, name);
5605 addSymChain (&name);
5606 allocVariables (name);
5608 name->lastLine = mylineno;
5611 /* set the stack pointer */
5612 stackPtr = -port->stack.direction * port->stack.call_overhead;
5615 if (IFFUNC_ISISR (name->type))
5616 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5618 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5620 if (options.useXstack)
5621 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5623 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5626 fetype = getSpec (name->type); /* get the specifier for the function */
5627 /* if this is a reentrant function then */
5628 if (IFFUNC_ISREENT (name->type))
5631 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5633 /* do processing for parameters that are passed in registers */
5634 processRegParms (FUNC_ARGS(name->type), body);
5636 /* set the stack pointer */
5640 /* allocate & autoinit the block variables */
5641 processBlockVars (body, &stack, ALLOCATE);
5643 /* save the stack information */
5644 if (options.useXstack)
5645 name->xstack = SPEC_STAK (fetype) = stack;
5647 name->stack = SPEC_STAK (fetype) = stack;
5649 /* name needs to be mangled */
5650 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5652 body = resolveSymbols (body); /* resolve the symbols */
5653 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5656 ex = newAst_VALUE (symbolVal (name)); /* create name */
5657 ex = newNode (FUNCTION, ex, body);
5658 ex->values.args = FUNC_ARGS(name->type);
5660 if (options.dump_tree) PA(ex);
5663 werror (E_FUNC_NO_CODE, name->name);
5667 /* create the node & generate intermediate code */
5669 codeOutFile = code->oFile;
5670 piCode = iCodeFromAst (ex);
5674 werror (E_FUNC_NO_CODE, name->name);
5678 eBBlockFromiCode (piCode);
5680 /* if there are any statics then do them */
5683 GcurMemmap = statsg;
5684 codeOutFile = statsg->oFile;
5685 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5691 /* dealloc the block variables */
5692 processBlockVars (body, &stack, DEALLOCATE);
5693 outputDebugStackSymbols();
5694 /* deallocate paramaters */
5695 deallocParms (FUNC_ARGS(name->type));
5697 if (IFFUNC_ISREENT (name->type))
5700 /* we are done freeup memory & cleanup */
5702 if (port->reset_labelKey) labelKey = 1;
5704 FUNC_HASBODY(name->type) = 1;
5705 addSet (&operKeyReset, name);
5706 applyToSet (operKeyReset, resetParmKey);
5711 cleanUpLevel (LabelTab, 0);
5712 cleanUpBlock (StructTab, 1);
5713 cleanUpBlock (TypedefTab, 1);
5715 xstack->syms = NULL;
5716 istack->syms = NULL;
5721 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5722 /*-----------------------------------------------------------------*/
5723 /* ast_print : prints the ast (for debugging purposes) */
5724 /*-----------------------------------------------------------------*/
5726 void ast_print (ast * tree, FILE *outfile, int indent)
5731 /* can print only decorated trees */
5732 if (!tree->decorated) return;
5734 /* if any child is an error | this one is an error do nothing */
5735 if (tree->isError ||
5736 (tree->left && tree->left->isError) ||
5737 (tree->right && tree->right->isError)) {
5738 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5742 /* print the line */
5743 /* if not block & function */
5744 if (tree->type == EX_OP &&
5745 (tree->opval.op != FUNCTION &&
5746 tree->opval.op != BLOCK &&
5747 tree->opval.op != NULLOP)) {
5750 if (tree->opval.op == FUNCTION) {
5752 value *args=FUNC_ARGS(tree->left->opval.val->type);
5753 fprintf(outfile,"FUNCTION (%s=%p) type (",
5754 tree->left->opval.val->name, tree);
5755 printTypeChain (tree->left->opval.val->type->next,outfile);
5756 fprintf(outfile,") args (");
5759 fprintf (outfile, ", ");
5761 printTypeChain (args ? args->type : NULL, outfile);
5763 args= args ? args->next : NULL;
5765 fprintf(outfile,")\n");
5766 ast_print(tree->left,outfile,indent);
5767 ast_print(tree->right,outfile,indent);
5770 if (tree->opval.op == BLOCK) {
5771 symbol *decls = tree->values.sym;
5772 INDENT(indent,outfile);
5773 fprintf(outfile,"{\n");
5775 INDENT(indent+2,outfile);
5776 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5777 decls->name, decls);
5778 printTypeChain(decls->type,outfile);
5779 fprintf(outfile,")\n");
5781 decls = decls->next;
5783 ast_print(tree->right,outfile,indent+2);
5784 INDENT(indent,outfile);
5785 fprintf(outfile,"}\n");
5788 if (tree->opval.op == NULLOP) {
5789 ast_print(tree->left,outfile,indent);
5790 ast_print(tree->right,outfile,indent);
5793 INDENT(indent,outfile);
5795 /*------------------------------------------------------------------*/
5796 /*----------------------------*/
5797 /* leaf has been reached */
5798 /*----------------------------*/
5799 /* if this is of type value */
5800 /* just get the type */
5801 if (tree->type == EX_VALUE) {
5803 if (IS_LITERAL (tree->opval.val->etype)) {
5804 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5805 if (SPEC_USIGN (tree->opval.val->etype))
5806 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5808 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5809 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5810 floatFromVal(tree->opval.val));
5811 } else if (tree->opval.val->sym) {
5812 /* if the undefined flag is set then give error message */
5813 if (tree->opval.val->sym->undefined) {
5814 fprintf(outfile,"UNDEFINED SYMBOL ");
5816 fprintf(outfile,"SYMBOL ");
5818 fprintf(outfile,"(%s=%p)",
5819 tree->opval.val->sym->name,tree);
5822 fprintf(outfile," type (");
5823 printTypeChain(tree->ftype,outfile);
5824 fprintf(outfile,")\n");
5826 fprintf(outfile,"\n");
5831 /* if type link for the case of cast */
5832 if (tree->type == EX_LINK) {
5833 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5834 printTypeChain(tree->opval.lnk,outfile);
5835 fprintf(outfile,")\n");
5840 /* depending on type of operator do */
5842 switch (tree->opval.op) {
5843 /*------------------------------------------------------------------*/
5844 /*----------------------------*/
5846 /*----------------------------*/
5848 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5849 printTypeChain(tree->ftype,outfile);
5850 fprintf(outfile,")\n");
5851 ast_print(tree->left,outfile,indent+2);
5852 ast_print(tree->right,outfile,indent+2);
5855 /*------------------------------------------------------------------*/
5856 /*----------------------------*/
5858 /*----------------------------*/
5860 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5861 printTypeChain(tree->ftype,outfile);
5862 fprintf(outfile,")\n");
5863 ast_print(tree->left,outfile,indent+2);
5864 ast_print(tree->right,outfile,indent+2);
5867 /*------------------------------------------------------------------*/
5868 /*----------------------------*/
5869 /* struct/union pointer */
5870 /*----------------------------*/
5872 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5873 printTypeChain(tree->ftype,outfile);
5874 fprintf(outfile,")\n");
5875 ast_print(tree->left,outfile,indent+2);
5876 ast_print(tree->right,outfile,indent+2);
5879 /*------------------------------------------------------------------*/
5880 /*----------------------------*/
5881 /* ++/-- operation */
5882 /*----------------------------*/
5885 fprintf(outfile,"post-");
5887 fprintf(outfile,"pre-");
5888 fprintf(outfile,"INC_OP (%p) type (",tree);
5889 printTypeChain(tree->ftype,outfile);
5890 fprintf(outfile,")\n");
5891 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5892 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5897 fprintf(outfile,"post-");
5899 fprintf(outfile,"pre-");
5900 fprintf(outfile,"DEC_OP (%p) type (",tree);
5901 printTypeChain(tree->ftype,outfile);
5902 fprintf(outfile,")\n");
5903 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5904 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5907 /*------------------------------------------------------------------*/
5908 /*----------------------------*/
5910 /*----------------------------*/
5913 fprintf(outfile,"& (%p) type (",tree);
5914 printTypeChain(tree->ftype,outfile);
5915 fprintf(outfile,")\n");
5916 ast_print(tree->left,outfile,indent+2);
5917 ast_print(tree->right,outfile,indent+2);
5919 fprintf(outfile,"ADDRESS_OF (%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);
5926 /*----------------------------*/
5928 /*----------------------------*/
5930 fprintf(outfile,"OR (%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);
5936 /*------------------------------------------------------------------*/
5937 /*----------------------------*/
5939 /*----------------------------*/
5941 fprintf(outfile,"XOR (%p) type (",tree);
5942 printTypeChain(tree->ftype,outfile);
5943 fprintf(outfile,")\n");
5944 ast_print(tree->left,outfile,indent+2);
5945 ast_print(tree->right,outfile,indent+2);
5948 /*------------------------------------------------------------------*/
5949 /*----------------------------*/
5951 /*----------------------------*/
5953 fprintf(outfile,"DIV (%p) type (",tree);
5954 printTypeChain(tree->ftype,outfile);
5955 fprintf(outfile,")\n");
5956 ast_print(tree->left,outfile,indent+2);
5957 ast_print(tree->right,outfile,indent+2);
5959 /*------------------------------------------------------------------*/
5960 /*----------------------------*/
5962 /*----------------------------*/
5964 fprintf(outfile,"MOD (%p) type (",tree);
5965 printTypeChain(tree->ftype,outfile);
5966 fprintf(outfile,")\n");
5967 ast_print(tree->left,outfile,indent+2);
5968 ast_print(tree->right,outfile,indent+2);
5971 /*------------------------------------------------------------------*/
5972 /*----------------------------*/
5973 /* address dereference */
5974 /*----------------------------*/
5975 case '*': /* can be unary : if right is null then unary operation */
5977 fprintf(outfile,"DEREF (%p) type (",tree);
5978 printTypeChain(tree->ftype,outfile);
5979 fprintf(outfile,")\n");
5980 ast_print(tree->left,outfile,indent+2);
5983 /*------------------------------------------------------------------*/
5984 /*----------------------------*/
5985 /* multiplication */
5986 /*----------------------------*/
5987 fprintf(outfile,"MULT (%p) type (",tree);
5988 printTypeChain(tree->ftype,outfile);
5989 fprintf(outfile,")\n");
5990 ast_print(tree->left,outfile,indent+2);
5991 ast_print(tree->right,outfile,indent+2);
5995 /*------------------------------------------------------------------*/
5996 /*----------------------------*/
5997 /* unary '+' operator */
5998 /*----------------------------*/
6002 fprintf(outfile,"UPLUS (%p) type (",tree);
6003 printTypeChain(tree->ftype,outfile);
6004 fprintf(outfile,")\n");
6005 ast_print(tree->left,outfile,indent+2);
6007 /*------------------------------------------------------------------*/
6008 /*----------------------------*/
6010 /*----------------------------*/
6011 fprintf(outfile,"ADD (%p) type (",tree);
6012 printTypeChain(tree->ftype,outfile);
6013 fprintf(outfile,")\n");
6014 ast_print(tree->left,outfile,indent+2);
6015 ast_print(tree->right,outfile,indent+2);
6018 /*------------------------------------------------------------------*/
6019 /*----------------------------*/
6021 /*----------------------------*/
6022 case '-': /* can be unary */
6024 fprintf(outfile,"UMINUS (%p) type (",tree);
6025 printTypeChain(tree->ftype,outfile);
6026 fprintf(outfile,")\n");
6027 ast_print(tree->left,outfile,indent+2);
6029 /*------------------------------------------------------------------*/
6030 /*----------------------------*/
6032 /*----------------------------*/
6033 fprintf(outfile,"SUB (%p) type (",tree);
6034 printTypeChain(tree->ftype,outfile);
6035 fprintf(outfile,")\n");
6036 ast_print(tree->left,outfile,indent+2);
6037 ast_print(tree->right,outfile,indent+2);
6040 /*------------------------------------------------------------------*/
6041 /*----------------------------*/
6043 /*----------------------------*/
6045 fprintf(outfile,"COMPL (%p) type (",tree);
6046 printTypeChain(tree->ftype,outfile);
6047 fprintf(outfile,")\n");
6048 ast_print(tree->left,outfile,indent+2);
6050 /*------------------------------------------------------------------*/
6051 /*----------------------------*/
6053 /*----------------------------*/
6055 fprintf(outfile,"NOT (%p) type (",tree);
6056 printTypeChain(tree->ftype,outfile);
6057 fprintf(outfile,")\n");
6058 ast_print(tree->left,outfile,indent+2);
6060 /*------------------------------------------------------------------*/
6061 /*----------------------------*/
6063 /*----------------------------*/
6065 fprintf(outfile,"RRC (%p) type (",tree);
6066 printTypeChain(tree->ftype,outfile);
6067 fprintf(outfile,")\n");
6068 ast_print(tree->left,outfile,indent+2);
6072 fprintf(outfile,"RLC (%p) type (",tree);
6073 printTypeChain(tree->ftype,outfile);
6074 fprintf(outfile,")\n");
6075 ast_print(tree->left,outfile,indent+2);
6078 fprintf(outfile,"SWAP (%p) type (",tree);
6079 printTypeChain(tree->ftype,outfile);
6080 fprintf(outfile,")\n");
6081 ast_print(tree->left,outfile,indent+2);
6084 fprintf(outfile,"GETHBIT (%p) type (",tree);
6085 printTypeChain(tree->ftype,outfile);
6086 fprintf(outfile,")\n");
6087 ast_print(tree->left,outfile,indent+2);
6090 fprintf(outfile,"GETABIT (%p) type (",tree);
6091 printTypeChain(tree->ftype,outfile);
6092 fprintf(outfile,")\n");
6093 ast_print(tree->left,outfile,indent+2);
6094 ast_print(tree->right,outfile,indent+2);
6097 fprintf(outfile,"GETBYTE (%p) type (",tree);
6098 printTypeChain(tree->ftype,outfile);
6099 fprintf(outfile,")\n");
6100 ast_print(tree->left,outfile,indent+2);
6101 ast_print(tree->right,outfile,indent+2);
6104 fprintf(outfile,"GETWORD (%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,"LEFT_SHIFT (%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 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6119 printTypeChain(tree->ftype,outfile);
6120 fprintf(outfile,")\n");
6121 ast_print(tree->left,outfile,indent+2);
6122 ast_print(tree->right,outfile,indent+2);
6124 /*------------------------------------------------------------------*/
6125 /*----------------------------*/
6127 /*----------------------------*/
6128 case CAST: /* change the type */
6129 fprintf(outfile,"CAST (%p) from type (",tree);
6130 printTypeChain(tree->right->ftype,outfile);
6131 fprintf(outfile,") to type (");
6132 printTypeChain(tree->ftype,outfile);
6133 fprintf(outfile,")\n");
6134 ast_print(tree->right,outfile,indent+2);
6138 fprintf(outfile,"ANDAND (%p) type (",tree);
6139 printTypeChain(tree->ftype,outfile);
6140 fprintf(outfile,")\n");
6141 ast_print(tree->left,outfile,indent+2);
6142 ast_print(tree->right,outfile,indent+2);
6145 fprintf(outfile,"OROR (%p) type (",tree);
6146 printTypeChain(tree->ftype,outfile);
6147 fprintf(outfile,")\n");
6148 ast_print(tree->left,outfile,indent+2);
6149 ast_print(tree->right,outfile,indent+2);
6152 /*------------------------------------------------------------------*/
6153 /*----------------------------*/
6154 /* comparison operators */
6155 /*----------------------------*/
6157 fprintf(outfile,"GT(>) (%p) type (",tree);
6158 printTypeChain(tree->ftype,outfile);
6159 fprintf(outfile,")\n");
6160 ast_print(tree->left,outfile,indent+2);
6161 ast_print(tree->right,outfile,indent+2);
6164 fprintf(outfile,"LT(<) (%p) type (",tree);
6165 printTypeChain(tree->ftype,outfile);
6166 fprintf(outfile,")\n");
6167 ast_print(tree->left,outfile,indent+2);
6168 ast_print(tree->right,outfile,indent+2);
6171 fprintf(outfile,"LE(<=) (%p) type (",tree);
6172 printTypeChain(tree->ftype,outfile);
6173 fprintf(outfile,")\n");
6174 ast_print(tree->left,outfile,indent+2);
6175 ast_print(tree->right,outfile,indent+2);
6178 fprintf(outfile,"GE(>=) (%p) type (",tree);
6179 printTypeChain(tree->ftype,outfile);
6180 fprintf(outfile,")\n");
6181 ast_print(tree->left,outfile,indent+2);
6182 ast_print(tree->right,outfile,indent+2);
6185 fprintf(outfile,"EQ(==) (%p) type (",tree);
6186 printTypeChain(tree->ftype,outfile);
6187 fprintf(outfile,")\n");
6188 ast_print(tree->left,outfile,indent+2);
6189 ast_print(tree->right,outfile,indent+2);
6192 fprintf(outfile,"NE(!=) (%p) type (",tree);
6193 printTypeChain(tree->ftype,outfile);
6194 fprintf(outfile,")\n");
6195 ast_print(tree->left,outfile,indent+2);
6196 ast_print(tree->right,outfile,indent+2);
6197 /*------------------------------------------------------------------*/
6198 /*----------------------------*/
6200 /*----------------------------*/
6201 case SIZEOF: /* evaluate wihout code generation */
6202 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6205 /*------------------------------------------------------------------*/
6206 /*----------------------------*/
6207 /* conditional operator '?' */
6208 /*----------------------------*/
6210 fprintf(outfile,"QUEST(?) (%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);
6218 fprintf(outfile,"COLON(:) (%p) type (",tree);
6219 printTypeChain(tree->ftype,outfile);
6220 fprintf(outfile,")\n");
6221 ast_print(tree->left,outfile,indent+2);
6222 ast_print(tree->right,outfile,indent+2);
6225 /*------------------------------------------------------------------*/
6226 /*----------------------------*/
6227 /* assignment operators */
6228 /*----------------------------*/
6230 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6231 printTypeChain(tree->ftype,outfile);
6232 fprintf(outfile,")\n");
6233 ast_print(tree->left,outfile,indent+2);
6234 ast_print(tree->right,outfile,indent+2);
6237 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6238 printTypeChain(tree->ftype,outfile);
6239 fprintf(outfile,")\n");
6240 ast_print(tree->left,outfile,indent+2);
6241 ast_print(tree->right,outfile,indent+2);
6244 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6245 printTypeChain(tree->ftype,outfile);
6246 fprintf(outfile,")\n");
6247 ast_print(tree->left,outfile,indent+2);
6248 ast_print(tree->right,outfile,indent+2);
6251 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6252 printTypeChain(tree->ftype,outfile);
6253 fprintf(outfile,")\n");
6254 ast_print(tree->left,outfile,indent+2);
6255 ast_print(tree->right,outfile,indent+2);
6258 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6259 printTypeChain(tree->ftype,outfile);
6260 fprintf(outfile,")\n");
6261 ast_print(tree->left,outfile,indent+2);
6262 ast_print(tree->right,outfile,indent+2);
6265 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6266 printTypeChain(tree->ftype,outfile);
6267 fprintf(outfile,")\n");
6268 ast_print(tree->left,outfile,indent+2);
6269 ast_print(tree->right,outfile,indent+2);
6272 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6273 printTypeChain(tree->ftype,outfile);
6274 fprintf(outfile,")\n");
6275 ast_print(tree->left,outfile,indent+2);
6276 ast_print(tree->right,outfile,indent+2);
6278 /*------------------------------------------------------------------*/
6279 /*----------------------------*/
6281 /*----------------------------*/
6283 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6284 printTypeChain(tree->ftype,outfile);
6285 fprintf(outfile,")\n");
6286 ast_print(tree->left,outfile,indent+2);
6287 ast_print(tree->right,outfile,indent+2);
6289 /*------------------------------------------------------------------*/
6290 /*----------------------------*/
6292 /*----------------------------*/
6294 fprintf(outfile,"ADDASS(+=) (%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);
6300 /*------------------------------------------------------------------*/
6301 /*----------------------------*/
6302 /* straight assignemnt */
6303 /*----------------------------*/
6305 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6306 printTypeChain(tree->ftype,outfile);
6307 fprintf(outfile,")\n");
6308 ast_print(tree->left,outfile,indent+2);
6309 ast_print(tree->right,outfile,indent+2);
6311 /*------------------------------------------------------------------*/
6312 /*----------------------------*/
6313 /* comma operator */
6314 /*----------------------------*/
6316 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6317 printTypeChain(tree->ftype,outfile);
6318 fprintf(outfile,")\n");
6319 ast_print(tree->left,outfile,indent+2);
6320 ast_print(tree->right,outfile,indent+2);
6322 /*------------------------------------------------------------------*/
6323 /*----------------------------*/
6325 /*----------------------------*/
6328 fprintf(outfile,"CALL (%p) type (",tree);
6329 printTypeChain(tree->ftype,outfile);
6330 fprintf(outfile,")\n");
6331 ast_print(tree->left,outfile,indent+2);
6332 ast_print(tree->right,outfile,indent+2);
6335 fprintf(outfile,"PARMS\n");
6336 ast_print(tree->left,outfile,indent+2);
6337 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6338 ast_print(tree->right,outfile,indent+2);
6341 /*------------------------------------------------------------------*/
6342 /*----------------------------*/
6343 /* return statement */
6344 /*----------------------------*/
6346 fprintf(outfile,"RETURN (%p) type (",tree);
6348 printTypeChain(tree->right->ftype,outfile);
6350 fprintf(outfile,")\n");
6351 ast_print(tree->right,outfile,indent+2);
6353 /*------------------------------------------------------------------*/
6354 /*----------------------------*/
6355 /* label statement */
6356 /*----------------------------*/
6358 fprintf(outfile,"LABEL (%p)\n",tree);
6359 ast_print(tree->left,outfile,indent+2);
6360 ast_print(tree->right,outfile,indent);
6362 /*------------------------------------------------------------------*/
6363 /*----------------------------*/
6364 /* switch statement */
6365 /*----------------------------*/
6369 fprintf(outfile,"SWITCH (%p) ",tree);
6370 ast_print(tree->left,outfile,0);
6371 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6372 INDENT(indent+2,outfile);
6373 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6374 (int) floatFromVal(val),
6375 tree->values.switchVals.swNum,
6376 (int) floatFromVal(val));
6378 ast_print(tree->right,outfile,indent);
6381 /*------------------------------------------------------------------*/
6382 /*----------------------------*/
6384 /*----------------------------*/
6386 fprintf(outfile,"IF (%p) \n",tree);
6387 ast_print(tree->left,outfile,indent+2);
6388 if (tree->trueLabel) {
6389 INDENT(indent+2,outfile);
6390 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6392 if (tree->falseLabel) {
6393 INDENT(indent+2,outfile);
6394 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6396 ast_print(tree->right,outfile,indent+2);
6398 /*----------------------------*/
6399 /* goto Statement */
6400 /*----------------------------*/
6402 fprintf(outfile,"GOTO (%p) \n",tree);
6403 ast_print(tree->left,outfile,indent+2);
6404 fprintf(outfile,"\n");
6406 /*------------------------------------------------------------------*/
6407 /*----------------------------*/
6409 /*----------------------------*/
6411 fprintf(outfile,"FOR (%p) \n",tree);
6412 if (AST_FOR( tree, initExpr)) {
6413 INDENT(indent+2,outfile);
6414 fprintf(outfile,"INIT EXPR ");
6415 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6417 if (AST_FOR( tree, condExpr)) {
6418 INDENT(indent+2,outfile);
6419 fprintf(outfile,"COND EXPR ");
6420 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6422 if (AST_FOR( tree, loopExpr)) {
6423 INDENT(indent+2,outfile);
6424 fprintf(outfile,"LOOP EXPR ");
6425 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6427 fprintf(outfile,"FOR LOOP BODY \n");
6428 ast_print(tree->left,outfile,indent+2);
6431 fprintf(outfile,"CRITICAL (%p) \n",tree);
6432 ast_print(tree->left,outfile,indent+2);
6440 ast_print(t,stdout,0);
6445 /*-----------------------------------------------------------------*/
6446 /* astErrors : returns non-zero if errors present in tree */
6447 /*-----------------------------------------------------------------*/
6448 int astErrors(ast *t)
6457 if (t->type == EX_VALUE
6458 && t->opval.val->sym
6459 && t->opval.val->sym->undefined)
6462 errors += astErrors(t->left);
6463 errors += astErrors(t->right);