1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *, RESULT_TYPE);
59 ast *optimizeGetAbit (ast *, RESULT_TYPE);
60 ast *optimizeGetByte (ast *, RESULT_TYPE);
61 ast *optimizeGetWord (ast *, RESULT_TYPE);
62 ast *backPatchLabels (ast *, symbol *, symbol *);
65 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
70 printTypeChain (tree->ftype, stdout);
75 /*-----------------------------------------------------------------*/
76 /* newAst - creates a fresh node for an expression tree */
77 /*-----------------------------------------------------------------*/
79 newAst_ (unsigned type)
82 static int oldLineno = 0;
84 ex = Safe_alloc ( sizeof (ast));
87 ex->lineno = (noLineno ? oldLineno : mylineno);
88 ex->filename = currFname;
89 ex->level = NestLevel;
90 ex->block = currBlockno;
91 ex->initMode = inInitMode;
92 ex->seqPoint = seqPointNo;
97 newAst_VALUE (value * val)
99 ast *ex = newAst_ (EX_VALUE);
105 newAst_OP (unsigned op)
107 ast *ex = newAst_ (EX_OP);
113 newAst_LINK (sym_link * val)
115 ast *ex = newAst_ (EX_LINK);
120 /*-----------------------------------------------------------------*/
121 /* newNode - creates a new node */
122 /*-----------------------------------------------------------------*/
124 newNode (long op, ast * left, ast * right)
135 /*-----------------------------------------------------------------*/
136 /* newIfxNode - creates a new Ifx Node */
137 /*-----------------------------------------------------------------*/
139 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
143 /* if this is a literal then we already know the result */
144 if (condAst->etype && IS_LITERAL (condAst->etype))
146 /* then depending on the expression value */
147 if (floatFromVal (condAst->opval.val))
148 ifxNode = newNode (GOTO,
149 newAst_VALUE (symbolVal (trueLabel)),
152 ifxNode = newNode (GOTO,
153 newAst_VALUE (symbolVal (falseLabel)),
158 ifxNode = newNode (IFX, condAst, NULL);
159 ifxNode->trueLabel = trueLabel;
160 ifxNode->falseLabel = falseLabel;
166 /*-----------------------------------------------------------------*/
167 /* copyAstValues - copies value portion of ast if needed */
168 /*-----------------------------------------------------------------*/
170 copyAstValues (ast * dest, ast * src)
172 switch (src->opval.op)
175 dest->values.sym = copySymbolChain (src->values.sym);
179 dest->values.switchVals.swVals =
180 copyValue (src->values.switchVals.swVals);
181 dest->values.switchVals.swDefault =
182 src->values.switchVals.swDefault;
183 dest->values.switchVals.swNum =
184 src->values.switchVals.swNum;
188 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
192 dest->values.constlist = copyLiteralList(src->values.constlist);
196 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
197 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
198 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
199 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
200 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
201 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
202 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
207 /*-----------------------------------------------------------------*/
208 /* copyAst - makes a copy of a given astession */
209 /*-----------------------------------------------------------------*/
218 dest = Safe_alloc ( sizeof (ast));
220 dest->type = src->type;
221 dest->lineno = src->lineno;
222 dest->level = src->level;
223 dest->funcName = src->funcName;
224 dest->reversed = src->reversed;
227 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
229 /* if this is a leaf */
231 if (src->type == EX_VALUE)
233 dest->opval.val = copyValue (src->opval.val);
238 if (src->type == EX_LINK)
240 dest->opval.lnk = copyLinkChain (src->opval.lnk);
244 dest->opval.op = src->opval.op;
246 /* if this is a node that has special values */
247 copyAstValues (dest, src);
249 dest->trueLabel = copySymbol (src->trueLabel);
250 dest->falseLabel = copySymbol (src->falseLabel);
251 dest->left = copyAst (src->left);
252 dest->right = copyAst (src->right);
258 /*-----------------------------------------------------------------*/
259 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
260 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
261 /*-----------------------------------------------------------------*/
262 ast *removeIncDecOps (ast * tree) {
264 // traverse the tree and remove inc/dec ops
269 if (tree->type == EX_OP &&
270 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
277 tree->left=removeIncDecOps(tree->left);
278 tree->right=removeIncDecOps(tree->right);
283 /*-----------------------------------------------------------------*/
284 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
285 /* "*++s += 3" -> "*++s = *++s + 3" */
286 /*-----------------------------------------------------------------*/
287 ast *removePreIncDecOps (ast * tree) {
289 // traverse the tree and remove pre-inc/dec ops
294 if (tree->type == EX_OP &&
295 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
300 tree->left=removePreIncDecOps(tree->left);
301 tree->right=removePreIncDecOps(tree->right);
306 /*-----------------------------------------------------------------*/
307 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
308 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
309 /*-----------------------------------------------------------------*/
310 ast *removePostIncDecOps (ast * tree) {
312 // traverse the tree and remove pre-inc/dec ops
317 if (tree->type == EX_OP &&
318 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
323 tree->left=removePostIncDecOps(tree->left);
324 tree->right=removePostIncDecOps(tree->right);
329 /*-----------------------------------------------------------------*/
330 /* hasSEFcalls - returns TRUE if tree has a function call */
331 /*-----------------------------------------------------------------*/
333 hasSEFcalls (ast * tree)
338 if (tree->type == EX_OP &&
339 (tree->opval.op == CALL ||
340 tree->opval.op == PCALL ||
341 tree->opval.op == '=' ||
342 tree->opval.op == INC_OP ||
343 tree->opval.op == DEC_OP))
346 return (hasSEFcalls (tree->left) |
347 hasSEFcalls (tree->right));
350 /*-----------------------------------------------------------------*/
351 /* isAstEqual - compares two asts & returns 1 if they are equal */
352 /*-----------------------------------------------------------------*/
354 isAstEqual (ast * t1, ast * t2)
363 if (t1->type != t2->type)
369 if (t1->opval.op != t2->opval.op)
371 return (isAstEqual (t1->left, t2->left) &&
372 isAstEqual (t1->right, t2->right));
376 if (t1->opval.val->sym)
378 if (!t2->opval.val->sym)
381 return isSymbolEqual (t1->opval.val->sym,
386 if (t2->opval.val->sym)
389 return (floatFromVal (t1->opval.val) ==
390 floatFromVal (t2->opval.val));
394 /* only compare these two types */
402 /*-----------------------------------------------------------------*/
403 /* resolveSymbols - resolve symbols from the symbol table */
404 /*-----------------------------------------------------------------*/
406 resolveSymbols (ast * tree)
408 /* walk the entire tree and check for values */
409 /* with symbols if we find one then replace */
410 /* symbol with that from the symbol table */
417 /* if not block & function */
418 if (tree->type == EX_OP &&
419 (tree->opval.op != FUNCTION &&
420 tree->opval.op != BLOCK &&
421 tree->opval.op != NULLOP))
423 filename = tree->filename;
424 lineno = tree->lineno;
428 /* make sure we resolve the true & false labels for ifx */
429 if (tree->type == EX_OP && tree->opval.op == IFX)
435 if ((csym = findSym (LabelTab, tree->trueLabel,
436 tree->trueLabel->name)))
437 tree->trueLabel = csym;
439 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
440 tree->trueLabel->name);
443 if (tree->falseLabel)
445 if ((csym = findSym (LabelTab,
447 tree->falseLabel->name)))
448 tree->falseLabel = csym;
450 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
451 tree->falseLabel->name);
456 /* if this is a label resolve it from the labelTab */
457 if (IS_AST_VALUE (tree) &&
458 tree->opval.val->sym &&
459 tree->opval.val->sym->islbl)
462 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
463 tree->opval.val->sym->name);
466 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
467 tree->opval.val->sym->name);
469 tree->opval.val->sym = csym;
471 goto resolveChildren;
474 /* do only for leafs */
475 if (IS_AST_VALUE (tree) &&
476 tree->opval.val->sym &&
477 !tree->opval.val->sym->implicit)
480 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
482 /* if found in the symbol table & they r not the same */
483 if (csym && tree->opval.val->sym != csym)
485 tree->opval.val->sym = csym;
486 tree->opval.val->type = csym->type;
487 tree->opval.val->etype = csym->etype;
490 /* if not found in the symbol table */
491 /* mark it as undefined assume it is */
492 /* an integer in data space */
493 if (!csym && !tree->opval.val->sym->implicit)
496 /* if this is a function name then */
497 /* mark it as returning an int */
500 tree->opval.val->sym->type = newLink (DECLARATOR);
501 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
502 tree->opval.val->sym->type->next =
503 tree->opval.val->sym->etype = newIntLink ();
504 tree->opval.val->etype = tree->opval.val->etype;
505 tree->opval.val->type = tree->opval.val->sym->type;
506 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
507 tree->opval.val->sym->name);
508 //tree->opval.val->sym->undefined = 1;
509 allocVariables (tree->opval.val->sym);
513 tree->opval.val->sym->undefined = 1;
514 tree->opval.val->type =
515 tree->opval.val->etype = newIntLink ();
516 tree->opval.val->sym->type =
517 tree->opval.val->sym->etype = newIntLink ();
523 resolveSymbols (tree->left);
524 resolveSymbols (tree->right);
529 /*-----------------------------------------------------------------*/
530 /* setAstLineno - walks a ast tree & sets the line number */
531 /*-----------------------------------------------------------------*/
532 int setAstLineno (ast * tree, int lineno)
537 tree->lineno = lineno;
538 setAstLineno (tree->left, lineno);
539 setAstLineno (tree->right, lineno);
543 /*-----------------------------------------------------------------*/
544 /* funcOfType :- function of type with name */
545 /*-----------------------------------------------------------------*/
547 funcOfType (char *name, sym_link * type, sym_link * argType,
551 /* create the symbol */
552 sym = newSymbol (name, 0);
554 /* setup return value */
555 sym->type = newLink (DECLARATOR);
556 DCL_TYPE (sym->type) = FUNCTION;
557 sym->type->next = copyLinkChain (type);
558 sym->etype = getSpec (sym->type);
559 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
561 /* if arguments required */
565 args = FUNC_ARGS(sym->type) = newValue ();
569 args->type = copyLinkChain (argType);
570 args->etype = getSpec (args->type);
571 SPEC_EXTR(args->etype)=1;
574 args = args->next = newValue ();
581 allocVariables (sym);
586 /*-----------------------------------------------------------------*/
587 /* funcOfTypeVarg :- function of type with name and argtype */
588 /*-----------------------------------------------------------------*/
590 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
595 /* create the symbol */
596 sym = newSymbol (name, 0);
598 /* setup return value */
599 sym->type = newLink (DECLARATOR);
600 DCL_TYPE (sym->type) = FUNCTION;
601 sym->type->next = typeFromStr(rtype);
602 sym->etype = getSpec (sym->type);
604 /* if arguments required */
607 args = FUNC_ARGS(sym->type) = newValue ();
609 for ( i = 0 ; i < nArgs ; i++ ) {
610 args->type = typeFromStr(atypes[i]);
611 args->etype = getSpec (args->type);
612 SPEC_EXTR(args->etype)=1;
613 if ((i + 1) == nArgs) break;
614 args = args->next = newValue ();
621 allocVariables (sym);
626 /*-----------------------------------------------------------------*/
627 /* reverseParms - will reverse a parameter tree */
628 /*-----------------------------------------------------------------*/
630 reverseParms (ast * ptree)
636 /* top down if we find a nonParm tree then quit */
637 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
639 /* The various functions expect the parameter tree to be right heavy. */
640 /* Rotate the tree to be left heavy so that after reversal it is */
641 /* right heavy again. */
642 while ((ttree = ptree->right) && ttree->type == EX_OP &&
643 ttree->opval.op == PARAM)
645 ptree->right = ttree->right;
646 ttree->right = ttree->left;
647 ttree->left = ptree->left;
653 ptree->left = ptree->right;
654 ptree->right = ttree;
656 reverseParms (ptree->left);
657 reverseParms (ptree->right);
663 /*-----------------------------------------------------------------*/
664 /* processParms - makes sure the parameters are okay and do some */
665 /* processing with them */
666 /*-----------------------------------------------------------------*/
668 processParms (ast *func,
671 int *parmNumber, /* unused, although updated */
674 RESULT_TYPE resultType;
677 /* if none of them exist */
678 if (!defParm && !*actParm)
683 if (getenv("DEBUG_SANITY"))
685 fprintf (stderr, "processParms: %s ", defParm->name);
687 /* make sure the type is complete and sane */
688 checkTypeSanity(defParm->etype, defParm->name);
691 if (IS_CODEPTR (func->ftype))
692 functype = func->ftype->next;
694 functype = func->ftype;
696 /* if the function is being called via a pointer & */
697 /* it has not been defined a reentrant then we cannot */
698 /* have parameters */
699 /* PIC16 port can... */
700 if (!TARGET_IS_PIC16)
702 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
704 werror (W_NONRENT_ARGS);
710 /* if defined parameters ended but actual parameters */
711 /* exist and this is not defined as a variable arg */
712 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
714 werror (E_TOO_MANY_PARMS);
718 /* if defined parameters present but no actual parameters */
719 if (defParm && !*actParm)
721 werror (E_TOO_FEW_PARMS);
725 /* if this is a PARAM node then match left & right */
726 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
728 (*actParm)->decorated = 1;
729 return (processParms (func, defParm,
730 &(*actParm)->left, parmNumber, FALSE) ||
731 processParms (func, defParm ? defParm->next : NULL,
732 &(*actParm)->right, parmNumber, rightmost));
734 else if (defParm) /* not vararg */
736 /* If we have found a value node by following only right-hand links,
737 * then we know that there are no more values after us.
739 * Therefore, if there are more defined parameters, the caller didn't
742 if (rightmost && defParm->next)
744 werror (E_TOO_FEW_PARMS);
749 /* decorate parameter */
750 resultType = defParm ? getResultTypeFromType (defParm->etype) :
752 *actParm = decorateType (*actParm, resultType);
754 if (IS_VOID((*actParm)->ftype))
756 werror (E_VOID_VALUE_USED);
760 /* If this is a varargs function... */
761 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
766 if (IS_CAST_OP (*actParm)
767 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
769 /* Parameter was explicitly typecast; don't touch it. */
773 ftype = (*actParm)->ftype;
775 /* If it's a char, upcast to int. */
776 if (IS_INTEGRAL (ftype)
777 && (getSize (ftype) < (unsigned) INTSIZE))
779 newType = newAst_LINK(INTTYPE);
782 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
784 newType = newAst_LINK (copyLinkChain(ftype));
785 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
788 if (IS_AGGREGATE (ftype))
790 newType = newAst_LINK (copyLinkChain (ftype));
791 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
796 /* cast required; change this op to a cast. */
797 (*actParm)->decorated = 0;
798 *actParm = newNode (CAST, newType, *actParm);
799 (*actParm)->lineno = (*actParm)->right->lineno;
801 decorateType (*actParm, RESULT_TYPE_NONE);
806 /* if defined parameters ended but actual has not & */
808 if (!defParm && *actParm &&
809 (options.stackAuto || IFFUNC_ISREENT (functype)))
812 resolveSymbols (*actParm);
814 /* the parameter type must be at least castable */
815 if (compareType (defParm->type, (*actParm)->ftype) == 0)
817 werror (E_INCOMPAT_TYPES);
818 printFromToType ((*actParm)->ftype, defParm->type);
822 /* if the parameter is castable then add the cast */
823 if (compareType (defParm->type, (*actParm)->ftype) < 0)
827 resultType = getResultTypeFromType (defParm->etype);
828 pTree = resolveSymbols (copyAst (*actParm));
830 /* now change the current one to a cast */
831 (*actParm)->type = EX_OP;
832 (*actParm)->opval.op = CAST;
833 (*actParm)->left = newAst_LINK (defParm->type);
834 (*actParm)->right = pTree;
835 (*actParm)->decorated = 0; /* force typechecking */
836 decorateType (*actParm, resultType);
839 /* make a copy and change the regparm type to the defined parm */
840 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
841 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
842 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
847 /*-----------------------------------------------------------------*/
848 /* createIvalType - generates ival for basic types */
849 /*-----------------------------------------------------------------*/
851 createIvalType (ast * sym, sym_link * type, initList * ilist)
855 /* if initList is deep */
856 if (ilist->type == INIT_DEEP)
857 ilist = ilist->init.deep;
859 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
860 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
863 /*-----------------------------------------------------------------*/
864 /* createIvalStruct - generates initial value for structures */
865 /*-----------------------------------------------------------------*/
867 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
874 sflds = SPEC_STRUCT (type)->fields;
875 if (ilist->type != INIT_DEEP)
877 werror (E_INIT_STRUCT, "");
881 iloop = ilist->init.deep;
883 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
885 /* if we have come to end */
889 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
890 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
891 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
892 iloop, rast, rootValue)),
898 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
899 W_EXCESS_INITIALIZERS, "struct",
900 sym->opval.val->sym->name);
907 /*-----------------------------------------------------------------*/
908 /* createIvalArray - generates code for array initialization */
909 /*-----------------------------------------------------------------*/
911 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
915 int lcnt = 0, size = 0;
916 literalList *literalL;
918 /* take care of the special case */
919 /* array of characters can be init */
921 if (IS_CHAR (type->next))
922 if ((rast = createIvalCharPtr (sym,
924 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
927 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
929 /* not the special case */
930 if (ilist->type != INIT_DEEP)
932 werror (E_INIT_STRUCT, "");
936 iloop = ilist->init.deep;
937 lcnt = DCL_ELEM (type);
939 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
943 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
945 rast = newNode(ARRAYINIT, aSym, NULL);
946 rast->values.constlist = literalL;
948 // Make sure size is set to length of initializer list.
955 if (lcnt && size > lcnt)
957 // Array size was specified, and we have more initializers than needed.
958 char *name=sym->opval.val->sym->name;
959 int lineno=sym->opval.val->sym->lineDef;
960 char *filename=sym->opval.val->sym->fileDef;
962 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
971 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
972 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
973 rast = createIval (aSym, type->next, iloop, rast, rootValue);
974 iloop = (iloop ? iloop->next : NULL);
980 /* no of elements given and we */
981 /* have generated for all of them */
984 // is this a better way? at least it won't crash
985 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
986 int lineno = iloop->lineno;
987 char *filename = iloop->filename;
988 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
995 /* if we have not been given a size */
996 if (!DCL_ELEM (type))
998 /* check, if it's a flexible array */
999 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1000 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1002 DCL_ELEM (type) = size;
1005 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1009 /*-----------------------------------------------------------------*/
1010 /* createIvalCharPtr - generates initial values for char pointers */
1011 /*-----------------------------------------------------------------*/
1013 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1018 /* if this is a pointer & right is a literal array then */
1019 /* just assignment will do */
1020 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1021 SPEC_SCLS (iexpr->etype) == S_CODE)
1022 && IS_ARRAY (iexpr->ftype)))
1023 return newNode ('=', sym, iexpr);
1025 /* left side is an array so we have to assign each */
1027 if ((IS_LITERAL (iexpr->etype) ||
1028 SPEC_SCLS (iexpr->etype) == S_CODE)
1029 && IS_ARRAY (iexpr->ftype))
1031 /* for each character generate an assignment */
1032 /* to the array element */
1033 char *s = SPEC_CVAL (iexpr->etype).v_char;
1035 unsigned int symsize = getSize (type);
1037 size = getSize (iexpr->ftype);
1038 if (symsize && size>symsize)
1040 if (size>(symsize+1))
1042 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1044 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1050 for (i=0;i<size;i++)
1052 rast = newNode (NULLOP,
1056 newAst_VALUE (valueFromLit ((float) i))),
1057 newAst_VALUE (valueFromLit (*s))));
1061 // now WE don't need iexpr's symbol anymore
1062 freeStringSymbol(AST_SYMBOL(iexpr));
1064 /* if we have not been given a size */
1065 if (!DCL_ELEM (type))
1067 /* check, if it's a flexible array */
1068 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1069 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1071 DCL_ELEM (type) = size;
1074 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1080 /*-----------------------------------------------------------------*/
1081 /* createIvalPtr - generates initial value for pointers */
1082 /*-----------------------------------------------------------------*/
1084 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1090 if (ilist->type == INIT_DEEP)
1091 ilist = ilist->init.deep;
1093 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1095 /* if character pointer */
1096 if (IS_CHAR (type->next))
1097 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1100 return newNode ('=', sym, iexpr);
1103 /*-----------------------------------------------------------------*/
1104 /* createIval - generates code for initial value */
1105 /*-----------------------------------------------------------------*/
1107 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1114 /* if structure then */
1115 if (IS_STRUCT (type))
1116 rast = createIvalStruct (sym, type, ilist, rootValue);
1118 /* if this is a pointer */
1120 rast = createIvalPtr (sym, type, ilist, rootValue);
1122 /* if this is an array */
1123 if (IS_ARRAY (type))
1124 rast = createIvalArray (sym, type, ilist, rootValue);
1126 /* if type is SPECIFIER */
1128 rast = createIvalType (sym, type, ilist);
1131 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1133 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1136 /*-----------------------------------------------------------------*/
1137 /* initAggregates - initialises aggregate variables with initv */
1138 /*-----------------------------------------------------------------*/
1139 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1140 ast *newAst = newAst_VALUE (symbolVal (sym));
1141 return createIval (newAst, sym->type, ival, wid, newAst);
1144 /*-----------------------------------------------------------------*/
1145 /* gatherAutoInit - creates assignment expressions for initial */
1147 /*-----------------------------------------------------------------*/
1149 gatherAutoInit (symbol * autoChain)
1156 for (sym = autoChain; sym; sym = sym->next)
1159 /* resolve the symbols in the ival */
1161 resolveIvalSym (sym->ival, sym->type);
1164 /* if we are PIC16 port,
1165 * and this is a static,
1166 * and have initial value,
1167 * and not S_CODE, don't emit in gs segment,
1168 * but allow glue.c:pic16emitRegularMap to put symbol
1169 * in idata section */
1170 if(TARGET_IS_PIC16 &&
1171 IS_STATIC (sym->etype) && sym->ival
1172 && SPEC_SCLS(sym->etype) != S_CODE) {
1173 SPEC_SCLS (sym->etype) = S_DATA;
1178 /* if this is a static variable & has an */
1179 /* initial value the code needs to be lifted */
1180 /* here to the main portion since they can be */
1181 /* initialised only once at the start */
1182 if (IS_STATIC (sym->etype) && sym->ival &&
1183 SPEC_SCLS (sym->etype) != S_CODE)
1187 /* insert the symbol into the symbol table */
1188 /* with level = 0 & name = rname */
1189 newSym = copySymbol (sym);
1190 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1192 /* now lift the code to main */
1193 if (IS_AGGREGATE (sym->type)) {
1194 work = initAggregates (sym, sym->ival, NULL);
1196 if (getNelements(sym->type, sym->ival)>1) {
1197 werrorfl (sym->fileDef, sym->lineDef,
1198 W_EXCESS_INITIALIZERS, "scalar",
1201 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1202 list2expr (sym->ival));
1205 setAstLineno (work, sym->lineDef);
1209 staticAutos = newNode (NULLOP, staticAutos, work);
1216 /* if there is an initial value */
1217 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1219 initList *ilist=sym->ival;
1221 while (ilist->type == INIT_DEEP) {
1222 ilist = ilist->init.deep;
1225 /* update lineno for error msg */
1226 lineno=sym->lineDef;
1227 setAstLineno (ilist->init.node, lineno);
1229 if (IS_AGGREGATE (sym->type)) {
1230 work = initAggregates (sym, sym->ival, NULL);
1232 if (getNelements(sym->type, sym->ival)>1) {
1233 werrorfl (sym->fileDef, sym->lineDef,
1234 W_EXCESS_INITIALIZERS, "scalar",
1237 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1238 list2expr (sym->ival));
1242 setAstLineno (work, sym->lineDef);
1246 init = newNode (NULLOP, init, work);
1255 /*-----------------------------------------------------------------*/
1256 /* freeStringSymbol - delete a literal string if no more usage */
1257 /*-----------------------------------------------------------------*/
1258 void freeStringSymbol(symbol *sym) {
1259 /* make sure this is a literal string */
1260 assert (sym->isstrlit);
1261 if (--sym->isstrlit == 0) { // lower the usage count
1262 memmap *segment=SPEC_OCLS(sym->etype);
1264 deleteSetItem(&segment->syms, sym);
1269 /*-----------------------------------------------------------------*/
1270 /* stringToSymbol - creates a symbol from a literal string */
1271 /*-----------------------------------------------------------------*/
1273 stringToSymbol (value * val)
1275 char name[SDCC_NAME_MAX + 1];
1276 static int charLbl = 0;
1281 // have we heard this before?
1282 for (sp=statsg->syms; sp; sp=sp->next) {
1284 size = getSize (sym->type);
1285 if (sym->isstrlit && size == getSize (val->type) &&
1286 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1287 // yes, this is old news. Don't publish it again.
1288 sym->isstrlit++; // but raise the usage count
1289 return symbolVal(sym);
1293 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1294 sym = newSymbol (name, 0); /* make it @ level 0 */
1295 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1297 /* copy the type from the value passed */
1298 sym->type = copyLinkChain (val->type);
1299 sym->etype = getSpec (sym->type);
1300 /* change to storage class & output class */
1301 SPEC_SCLS (sym->etype) = S_CODE;
1302 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1303 SPEC_STAT (sym->etype) = 1;
1304 /* make the level & block = 0 */
1305 sym->block = sym->level = 0;
1307 /* create an ival */
1308 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1313 allocVariables (sym);
1316 return symbolVal (sym);
1320 /*-----------------------------------------------------------------*/
1321 /* processBlockVars - will go thru the ast looking for block if */
1322 /* a block is found then will allocate the syms */
1323 /* will also gather the auto inits present */
1324 /*-----------------------------------------------------------------*/
1326 processBlockVars (ast * tree, int *stack, int action)
1331 /* if this is a block */
1332 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1336 if (action == ALLOCATE)
1338 *stack += allocVariables (tree->values.sym);
1339 autoInit = gatherAutoInit (tree->values.sym);
1341 /* if there are auto inits then do them */
1343 tree->left = newNode (NULLOP, autoInit, tree->left);
1345 else /* action is deallocate */
1346 deallocLocal (tree->values.sym);
1349 processBlockVars (tree->left, stack, action);
1350 processBlockVars (tree->right, stack, action);
1355 /*-------------------------------------------------------------*/
1356 /* constExprTree - returns TRUE if this tree is a constant */
1358 /*-------------------------------------------------------------*/
1359 bool constExprTree (ast *cexpr) {
1365 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1367 switch (cexpr->type)
1370 if (IS_AST_LIT_VALUE(cexpr)) {
1371 // this is a literal
1374 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1375 // a function's address will never change
1378 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1379 // an array's address will never change
1382 if (IS_AST_SYM_VALUE(cexpr) &&
1383 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1384 // a symbol in code space will never change
1385 // This is only for the 'char *s="hallo"' case and will have to leave
1386 //printf(" code space symbol");
1391 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1392 "unexpected link in expression tree\n");
1395 if (cexpr->opval.op==ARRAYINIT) {
1396 // this is a list of literals
1399 if (cexpr->opval.op=='=') {
1400 return constExprTree(cexpr->right);
1402 if (cexpr->opval.op==CAST) {
1403 // cast ignored, maybe we should throw a warning here?
1404 return constExprTree(cexpr->right);
1406 if (cexpr->opval.op=='&') {
1409 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1412 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1417 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1422 /*-----------------------------------------------------------------*/
1423 /* constExprValue - returns the value of a constant expression */
1424 /* or NULL if it is not a constant expression */
1425 /*-----------------------------------------------------------------*/
1427 constExprValue (ast * cexpr, int check)
1429 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1431 /* if this is not a constant then */
1432 if (!IS_LITERAL (cexpr->ftype))
1434 /* then check if this is a literal array
1436 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1437 SPEC_CVAL (cexpr->etype).v_char &&
1438 IS_ARRAY (cexpr->ftype))
1440 value *val = valFromType (cexpr->ftype);
1441 SPEC_SCLS (val->etype) = S_LITERAL;
1442 val->sym = cexpr->opval.val->sym;
1443 val->sym->type = copyLinkChain (cexpr->ftype);
1444 val->sym->etype = getSpec (val->sym->type);
1445 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1449 /* if we are casting a literal value then */
1450 if (IS_AST_OP (cexpr) &&
1451 cexpr->opval.op == CAST &&
1452 IS_LITERAL (cexpr->right->ftype))
1454 return valCastLiteral (cexpr->ftype,
1455 floatFromVal (cexpr->right->opval.val));
1458 if (IS_AST_VALUE (cexpr))
1460 return cexpr->opval.val;
1464 werror (E_CONST_EXPECTED, "found expression");
1469 /* return the value */
1470 return cexpr->opval.val;
1474 /*-----------------------------------------------------------------*/
1475 /* isLabelInAst - will return true if a given label is found */
1476 /*-----------------------------------------------------------------*/
1478 isLabelInAst (symbol * label, ast * tree)
1480 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1483 if (IS_AST_OP (tree) &&
1484 tree->opval.op == LABEL &&
1485 isSymbolEqual (AST_SYMBOL (tree->left), label))
1488 return isLabelInAst (label, tree->right) &&
1489 isLabelInAst (label, tree->left);
1493 /*-----------------------------------------------------------------*/
1494 /* isLoopCountable - return true if the loop count can be determi- */
1495 /* -ned at compile time . */
1496 /*-----------------------------------------------------------------*/
1498 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1499 symbol ** sym, ast ** init, ast ** end)
1502 /* the loop is considered countable if the following
1503 conditions are true :-
1505 a) initExpr :- <sym> = <const>
1506 b) condExpr :- <sym> < <const1>
1507 c) loopExpr :- <sym> ++
1510 /* first check the initExpr */
1511 if (IS_AST_OP (initExpr) &&
1512 initExpr->opval.op == '=' && /* is assignment */
1513 IS_AST_SYM_VALUE (initExpr->left))
1514 { /* left is a symbol */
1516 *sym = AST_SYMBOL (initExpr->left);
1517 *init = initExpr->right;
1522 /* for now the symbol has to be of
1524 if (!IS_INTEGRAL ((*sym)->type))
1527 /* now check condExpr */
1528 if (IS_AST_OP (condExpr))
1531 switch (condExpr->opval.op)
1534 if (IS_AST_SYM_VALUE (condExpr->left) &&
1535 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1536 IS_AST_LIT_VALUE (condExpr->right))
1538 *end = condExpr->right;
1544 if (IS_AST_OP (condExpr->left) &&
1545 condExpr->left->opval.op == '>' &&
1546 IS_AST_LIT_VALUE (condExpr->left->right) &&
1547 IS_AST_SYM_VALUE (condExpr->left->left) &&
1548 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1551 *end = newNode ('+', condExpr->left->right,
1552 newAst_VALUE (constVal ("1")));
1565 /* check loop expression is of the form <sym>++ */
1566 if (!IS_AST_OP (loopExpr))
1569 /* check if <sym> ++ */
1570 if (loopExpr->opval.op == INC_OP)
1576 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1577 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1584 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1585 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1593 if (loopExpr->opval.op == ADD_ASSIGN)
1596 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1597 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1598 IS_AST_LIT_VALUE (loopExpr->right) &&
1599 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1607 /*-----------------------------------------------------------------*/
1608 /* astHasVolatile - returns true if ast contains any volatile */
1609 /*-----------------------------------------------------------------*/
1611 astHasVolatile (ast * tree)
1616 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1619 if (IS_AST_OP (tree))
1620 return astHasVolatile (tree->left) ||
1621 astHasVolatile (tree->right);
1626 /*-----------------------------------------------------------------*/
1627 /* astHasPointer - return true if the ast contains any ptr variable */
1628 /*-----------------------------------------------------------------*/
1630 astHasPointer (ast * tree)
1635 if (IS_AST_LINK (tree))
1638 /* if we hit an array expression then check
1639 only the left side */
1640 if (IS_AST_OP (tree) && tree->opval.op == '[')
1641 return astHasPointer (tree->left);
1643 if (IS_AST_VALUE (tree))
1644 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1646 return astHasPointer (tree->left) ||
1647 astHasPointer (tree->right);
1651 /*-----------------------------------------------------------------*/
1652 /* astHasSymbol - return true if the ast has the given symbol */
1653 /*-----------------------------------------------------------------*/
1655 astHasSymbol (ast * tree, symbol * sym)
1657 if (!tree || IS_AST_LINK (tree))
1660 if (IS_AST_VALUE (tree))
1662 if (IS_AST_SYM_VALUE (tree))
1663 return isSymbolEqual (AST_SYMBOL (tree), sym);
1668 return astHasSymbol (tree->left, sym) ||
1669 astHasSymbol (tree->right, sym);
1672 /*-----------------------------------------------------------------*/
1673 /* astHasDeref - return true if the ast has an indirect access */
1674 /*-----------------------------------------------------------------*/
1676 astHasDeref (ast * tree)
1678 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1681 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1683 return astHasDeref (tree->left) || astHasDeref (tree->right);
1686 /*-----------------------------------------------------------------*/
1687 /* isConformingBody - the loop body has to conform to a set of rules */
1688 /* for the loop to be considered reversible read on for rules */
1689 /*-----------------------------------------------------------------*/
1691 isConformingBody (ast * pbody, symbol * sym, ast * body)
1694 /* we are going to do a pre-order traversal of the
1695 tree && check for the following conditions. (essentially
1696 a set of very shallow tests )
1697 a) the sym passed does not participate in
1698 any arithmetic operation
1699 b) There are no function calls
1700 c) all jumps are within the body
1701 d) address of loop control variable not taken
1702 e) if an assignment has a pointer on the
1703 left hand side make sure right does not have
1704 loop control variable */
1706 /* if we reach the end or a leaf then true */
1707 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1710 /* if anything else is "volatile" */
1711 if (IS_VOLATILE (TETYPE (pbody)))
1714 /* we will walk the body in a pre-order traversal for
1716 switch (pbody->opval.op)
1718 /*------------------------------------------------------------------*/
1720 // if the loopvar is used as an index
1721 /* array op is commutative -- must check both left & right */
1722 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1725 return isConformingBody (pbody->right, sym, body)
1726 && isConformingBody (pbody->left, sym, body);
1728 /*------------------------------------------------------------------*/
1733 /*------------------------------------------------------------------*/
1737 /* sure we are not sym is not modified */
1739 IS_AST_SYM_VALUE (pbody->left) &&
1740 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1744 IS_AST_SYM_VALUE (pbody->right) &&
1745 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1750 /*------------------------------------------------------------------*/
1752 case '*': /* can be unary : if right is null then unary operation */
1757 /* if right is NULL then unary operation */
1758 /*------------------------------------------------------------------*/
1759 /*----------------------------*/
1761 /*----------------------------*/
1764 if (IS_AST_SYM_VALUE (pbody->left) &&
1765 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1768 return isConformingBody (pbody->left, sym, body);
1772 if (astHasSymbol (pbody->left, sym) ||
1773 astHasSymbol (pbody->right, sym))
1778 /*------------------------------------------------------------------*/
1789 if (IS_AST_SYM_VALUE (pbody->left) &&
1790 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1793 if (IS_AST_SYM_VALUE (pbody->right) &&
1794 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1797 return isConformingBody (pbody->left, sym, body) &&
1798 isConformingBody (pbody->right, sym, body);
1806 if (IS_AST_SYM_VALUE (pbody->left) &&
1807 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1809 return isConformingBody (pbody->left, sym, body);
1811 /*------------------------------------------------------------------*/
1823 case SIZEOF: /* evaluate wihout code generation */
1825 if (IS_AST_SYM_VALUE (pbody->left) &&
1826 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1829 if (IS_AST_SYM_VALUE (pbody->right) &&
1830 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1833 return isConformingBody (pbody->left, sym, body) &&
1834 isConformingBody (pbody->right, sym, body);
1836 /*------------------------------------------------------------------*/
1839 /* if left has a pointer & right has loop
1840 control variable then we cannot */
1841 if (astHasPointer (pbody->left) &&
1842 astHasSymbol (pbody->right, sym))
1844 if (astHasVolatile (pbody->left))
1847 if (IS_AST_SYM_VALUE (pbody->left)) {
1848 // if the loopvar has an assignment
1849 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1851 // if the loopvar is used in another (maybe conditional) block
1852 if (astHasSymbol (pbody->right, sym) &&
1853 (pbody->level >= body->level)) {
1858 if (astHasVolatile (pbody->left))
1861 if (astHasDeref(pbody->right)) return FALSE;
1863 return isConformingBody (pbody->left, sym, body) &&
1864 isConformingBody (pbody->right, sym, body);
1875 assert ("Parser should not have generated this\n");
1877 /*------------------------------------------------------------------*/
1878 /*----------------------------*/
1879 /* comma operator */
1880 /*----------------------------*/
1882 return isConformingBody (pbody->left, sym, body) &&
1883 isConformingBody (pbody->right, sym, body);
1885 /*------------------------------------------------------------------*/
1886 /*----------------------------*/
1888 /*----------------------------*/
1890 /* if local & not passed as paramater then ok */
1891 if (sym->level && !astHasSymbol(pbody->right,sym))
1895 /*------------------------------------------------------------------*/
1896 /*----------------------------*/
1897 /* return statement */
1898 /*----------------------------*/
1903 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1908 if (astHasSymbol (pbody->left, sym))
1915 return isConformingBody (pbody->left, sym, body) &&
1916 isConformingBody (pbody->right, sym, body);
1922 /*-----------------------------------------------------------------*/
1923 /* isLoopReversible - takes a for loop as input && returns true */
1924 /* if the for loop is reversible. If yes will set the value of */
1925 /* the loop control var & init value & termination value */
1926 /*-----------------------------------------------------------------*/
1928 isLoopReversible (ast * loop, symbol ** loopCntrl,
1929 ast ** init, ast ** end)
1931 /* if option says don't do it then don't */
1932 if (optimize.noLoopReverse)
1934 /* there are several tests to determine this */
1936 /* for loop has to be of the form
1937 for ( <sym> = <const1> ;
1938 [<sym> < <const2>] ;
1939 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1941 if (!isLoopCountable (AST_FOR (loop, initExpr),
1942 AST_FOR (loop, condExpr),
1943 AST_FOR (loop, loopExpr),
1944 loopCntrl, init, end))
1947 /* now do some serious checking on the body of the loop
1950 return isConformingBody (loop->left, *loopCntrl, loop->left);
1954 /*-----------------------------------------------------------------*/
1955 /* replLoopSym - replace the loop sym by loop sym -1 */
1956 /*-----------------------------------------------------------------*/
1958 replLoopSym (ast * body, symbol * sym)
1961 if (!body || IS_AST_LINK (body))
1964 if (IS_AST_SYM_VALUE (body))
1967 if (isSymbolEqual (AST_SYMBOL (body), sym))
1971 body->opval.op = '-';
1972 body->left = newAst_VALUE (symbolVal (sym));
1973 body->right = newAst_VALUE (constVal ("1"));
1981 replLoopSym (body->left, sym);
1982 replLoopSym (body->right, sym);
1986 /*-----------------------------------------------------------------*/
1987 /* reverseLoop - do the actual loop reversal */
1988 /*-----------------------------------------------------------------*/
1990 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1994 /* create the following tree
1999 if (sym) goto for_continue ;
2002 /* put it together piece by piece */
2003 rloop = newNode (NULLOP,
2004 createIf (newAst_VALUE (symbolVal (sym)),
2006 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2009 newAst_VALUE (symbolVal (sym)),
2012 replLoopSym (loop->left, sym);
2013 setAstLineno (rloop, init->lineno);
2015 rloop = newNode (NULLOP,
2017 newAst_VALUE (symbolVal (sym)),
2018 newNode ('-', end, init)),
2019 createLabel (AST_FOR (loop, continueLabel),
2023 newNode (SUB_ASSIGN,
2024 newAst_VALUE (symbolVal (sym)),
2025 newAst_VALUE (constVal ("1"))),
2028 rloop->lineno=init->lineno;
2029 return decorateType (rloop, RESULT_TYPE_NONE);
2033 /*-----------------------------------------------------------------*/
2034 /* searchLitOp - search tree (*ops only) for an ast with literal */
2035 /*-----------------------------------------------------------------*/
2037 searchLitOp (ast *tree, ast **parent, const unsigned char *ops)
2041 if (tree && optimize.global_cse)
2043 /* is there a literal operand? */
2045 IS_AST_OP(tree->right) &&
2046 tree->right->right &&
2047 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
2049 if (IS_LITERAL (RTYPE (tree->right)) !=
2050 IS_LITERAL (LTYPE (tree->right)))
2052 tree->right->decorated = 0;
2053 tree->decorated = 0;
2057 ret = searchLitOp (tree->right, parent, ops);
2062 IS_AST_OP(tree->left) &&
2063 tree->left->right &&
2064 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2066 if (IS_LITERAL (RTYPE (tree->left)) !=
2067 IS_LITERAL (LTYPE (tree->left)))
2069 tree->left->decorated = 0;
2070 tree->decorated = 0;
2074 ret = searchLitOp (tree->left, parent, ops);
2082 /*-----------------------------------------------------------------*/
2083 /* getResultFromType */
2084 /*-----------------------------------------------------------------*/
2086 getResultTypeFromType (sym_link *type)
2088 /* type = getSpec (type); */
2090 return RESULT_TYPE_BIT;
2091 if (IS_BITFIELD (type))
2093 int blen = SPEC_BLEN (type);
2096 return RESULT_TYPE_BIT;
2098 return RESULT_TYPE_CHAR;
2099 return RESULT_TYPE_INT;
2102 return RESULT_TYPE_CHAR;
2105 return RESULT_TYPE_INT;
2106 return RESULT_TYPE_OTHER;
2109 /*-----------------------------------------------------------------*/
2110 /* addCast - adds casts to a type specified by RESULT_TYPE */
2111 /*-----------------------------------------------------------------*/
2113 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2116 bool upCasted = FALSE;
2120 case RESULT_TYPE_NONE:
2121 /* if thing smaller than int must be promoted to int */
2123 getSize (tree->etype) >= INTSIZE)
2124 /* promotion not necessary or already an int */
2126 /* char and bits: promote to int */
2127 newLink = newIntLink();
2130 case RESULT_TYPE_BIT:
2132 /* already an int */
2133 bitsForType (tree->etype) >= 16 ||
2134 /* bit to bit operation: don't promote, the code generators
2135 hopefully know everything about promotion rules */
2136 bitsForType (tree->etype) == 1)
2138 newLink = newIntLink();
2141 case RESULT_TYPE_CHAR:
2142 if (IS_CHAR (tree->etype) ||
2143 IS_FLOAT(tree->etype) ||
2144 IS_FIXED(tree->etype))
2146 newLink = newCharLink();
2148 case RESULT_TYPE_INT:
2150 if (getSize (tree->etype) > INTSIZE)
2152 /* warn ("Loosing significant digits"); */
2156 /* char: promote to int */
2158 getSize (tree->etype) >= INTSIZE)
2160 newLink = newIntLink();
2163 case RESULT_TYPE_OTHER:
2166 /* return type is long, float: promote char to int */
2167 if (getSize (tree->etype) >= INTSIZE)
2169 newLink = newIntLink();
2175 tree->decorated = 0;
2176 tree = newNode (CAST, newAst_LINK (newLink), tree);
2177 tree->lineno = tree->right->lineno;
2178 /* keep unsigned type during cast to smaller type,
2179 but not when promoting from char to int */
2181 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2182 return decorateType (tree, resultType);
2185 /*-----------------------------------------------------------------*/
2186 /* resultTypePropagate - decides if resultType can be propagated */
2187 /*-----------------------------------------------------------------*/
2189 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2191 switch (tree->opval.op)
2210 return RESULT_TYPE_NONE;
2214 return RESULT_TYPE_IFX;
2216 return RESULT_TYPE_NONE;
2220 /*-----------------------------------------------------------------*/
2221 /* getLeftResultType - gets type from left branch for propagation */
2222 /*-----------------------------------------------------------------*/
2224 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2226 switch (tree->opval.op)
2230 if (IS_PTR (LTYPE (tree)))
2231 return RESULT_TYPE_NONE;
2233 return getResultTypeFromType (LETYPE (tree));
2235 if (IS_PTR (currFunc->type->next))
2236 return RESULT_TYPE_NONE;
2238 return getResultTypeFromType (currFunc->type->next);
2240 if (!IS_ARRAY (LTYPE (tree)))
2242 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2243 return RESULT_TYPE_CHAR;
2250 /*--------------------------------------------------------------------*/
2251 /* decorateType - compute type for this tree, also does type checking.*/
2252 /* This is done bottom up, since type has to flow upwards. */
2253 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2254 /* result is a char and the operand(s) are int's. */
2255 /* It also does constant folding, and parameter checking. */
2256 /*--------------------------------------------------------------------*/
2258 decorateType (ast * tree, RESULT_TYPE resultType)
2262 RESULT_TYPE resultTypeProp;
2267 /* if already has type then do nothing */
2268 if (tree->decorated)
2271 tree->decorated = 1;
2274 /* print the line */
2275 /* if not block & function */
2276 if (tree->type == EX_OP &&
2277 (tree->opval.op != FUNCTION &&
2278 tree->opval.op != BLOCK &&
2279 tree->opval.op != NULLOP))
2281 filename = tree->filename;
2282 lineno = tree->lineno;
2286 /* if any child is an error | this one is an error do nothing */
2287 if (tree->isError ||
2288 (tree->left && tree->left->isError) ||
2289 (tree->right && tree->right->isError))
2292 /*------------------------------------------------------------------*/
2293 /*----------------------------*/
2294 /* leaf has been reached */
2295 /*----------------------------*/
2296 lineno=tree->lineno;
2297 /* if this is of type value */
2298 /* just get the type */
2299 if (tree->type == EX_VALUE)
2302 if (IS_LITERAL (tree->opval.val->etype))
2305 /* if this is a character array then declare it */
2306 if (IS_ARRAY (tree->opval.val->type))
2307 tree->opval.val = stringToSymbol (tree->opval.val);
2309 /* otherwise just copy the type information */
2310 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2314 if (tree->opval.val->sym)
2316 /* if the undefined flag is set then give error message */
2317 if (tree->opval.val->sym->undefined)
2319 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2321 TTYPE (tree) = TETYPE (tree) =
2322 tree->opval.val->type = tree->opval.val->sym->type =
2323 tree->opval.val->etype = tree->opval.val->sym->etype =
2324 copyLinkChain (INTTYPE);
2329 /* if impilicit i.e. struct/union member then no type */
2330 if (tree->opval.val->sym->implicit)
2331 TTYPE (tree) = TETYPE (tree) = NULL;
2336 /* else copy the type */
2337 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2339 /* and mark it as referenced */
2340 tree->opval.val->sym->isref = 1;
2348 /* if type link for the case of cast */
2349 if (tree->type == EX_LINK)
2351 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2359 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2361 if (tree->left && tree->left->type == EX_OPERAND
2362 && (tree->left->opval.op == INC_OP
2363 || tree->left->opval.op == DEC_OP)
2364 && tree->left->left)
2366 tree->left->right = tree->left->left;
2367 tree->left->left = NULL;
2369 if (tree->right && tree->right->type == EX_OPERAND
2370 && (tree->right->opval.op == INC_OP
2371 || tree->right->opval.op == DEC_OP)
2372 && tree->right->left)
2374 tree->right->right = tree->right->left;
2375 tree->right->left = NULL;
2380 /* Before decorating the left branch we've to decide in dependence
2381 upon tree->opval.op, if resultType can be propagated */
2382 resultTypeProp = resultTypePropagate (tree, resultType);
2384 if (tree->opval.op == '?')
2385 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2387 dtl = decorateType (tree->left, resultTypeProp);
2389 /* if an array node, we may need to swap branches */
2390 if (tree->opval.op == '[')
2392 /* determine which is the array & which the index */
2393 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2394 IS_INTEGRAL (LTYPE (tree)))
2396 ast *tempTree = tree->left;
2397 tree->left = tree->right;
2398 tree->right = tempTree;
2402 /* After decorating the left branch there's type information available
2403 in tree->left->?type. If the op is e.g. '=' we extract the type
2404 information from there and propagate it to the right branch. */
2405 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2407 switch (tree->opval.op)
2410 /* delay right side for '?' operator since conditional macro
2411 expansions might rely on this */
2415 /* decorate right side for CALL (parameter list) in processParms();
2416 there is resultType available */
2420 dtr = decorateType (tree->right, resultTypeProp);
2424 /* this is to take care of situations
2425 when the tree gets rewritten */
2426 if (dtl != tree->left)
2428 if (dtr != tree->right)
2430 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2434 /* depending on type of operator do */
2436 switch (tree->opval.op)
2438 /*------------------------------------------------------------------*/
2439 /*----------------------------*/
2441 /*----------------------------*/
2444 /* first check if this is a array or a pointer */
2445 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2447 werror (E_NEED_ARRAY_PTR, "[]");
2448 goto errorTreeReturn;
2451 /* check if the type of the idx */
2452 if (!IS_INTEGRAL (RTYPE (tree)))
2454 werror (E_IDX_NOT_INT);
2455 goto errorTreeReturn;
2458 /* if the left is an rvalue then error */
2461 werror (E_LVALUE_REQUIRED, "array access");
2462 goto errorTreeReturn;
2465 if (IS_LITERAL (RTYPE (tree)))
2467 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2468 int arraySize = DCL_ELEM (LTYPE (tree));
2469 if (arraySize && arrayIndex >= arraySize)
2471 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2476 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2477 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2480 /*------------------------------------------------------------------*/
2481 /*----------------------------*/
2483 /*----------------------------*/
2485 /* if this is not a structure */
2486 if (!IS_STRUCT (LTYPE (tree)))
2488 werror (E_STRUCT_UNION, ".");
2489 goto errorTreeReturn;
2491 TTYPE (tree) = structElemType (LTYPE (tree),
2492 (tree->right->type == EX_VALUE ?
2493 tree->right->opval.val : NULL));
2494 TETYPE (tree) = getSpec (TTYPE (tree));
2497 /*------------------------------------------------------------------*/
2498 /*----------------------------*/
2499 /* struct/union pointer */
2500 /*----------------------------*/
2502 /* if not pointer to a structure */
2503 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2505 werror (E_PTR_REQD);
2506 goto errorTreeReturn;
2509 if (!IS_STRUCT (LTYPE (tree)->next))
2511 werror (E_STRUCT_UNION, "->");
2512 goto errorTreeReturn;
2515 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2516 (tree->right->type == EX_VALUE ?
2517 tree->right->opval.val : NULL));
2518 TETYPE (tree) = getSpec (TTYPE (tree));
2520 /* adjust the storage class */
2521 switch (DCL_TYPE(tree->left->ftype)) {
2523 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2526 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2529 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2532 SPEC_SCLS (TETYPE (tree)) = 0;
2535 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2538 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2541 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2544 SPEC_SCLS (TETYPE (tree)) = 0;
2551 /* This breaks with extern declarations, bitfields, and perhaps other */
2552 /* cases (gcse). Let's leave this optimization disabled for now and */
2553 /* ponder if there's a safe way to do this. -- EEP */
2555 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2556 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2558 /* If defined struct type at addr var
2559 then rewrite (&struct var)->member
2561 and define membertype at (addr+offsetof(struct var,member)) temp
2564 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2565 AST_SYMBOL(tree->right));
2567 sym = newSymbol(genSymName (0), 0);
2568 sym->type = TTYPE (tree);
2569 sym->etype = getSpec(sym->type);
2570 sym->lineDef = tree->lineno;
2573 SPEC_STAT (sym->etype) = 1;
2574 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2576 SPEC_ABSA(sym->etype) = 1;
2577 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2580 AST_VALUE (tree) = symbolVal(sym);
2583 tree->type = EX_VALUE;
2591 /*------------------------------------------------------------------*/
2592 /*----------------------------*/
2593 /* ++/-- operation */
2594 /*----------------------------*/
2598 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2599 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2600 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2601 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2610 /*------------------------------------------------------------------*/
2611 /*----------------------------*/
2613 /*----------------------------*/
2614 case '&': /* can be unary */
2615 /* if right is NULL then unary operation */
2616 if (tree->right) /* not an unary operation */
2619 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2621 werror (E_BITWISE_OP);
2622 werror (W_CONTINUE, "left & right types are ");
2623 printTypeChain (LTYPE (tree), stderr);
2624 fprintf (stderr, ",");
2625 printTypeChain (RTYPE (tree), stderr);
2626 fprintf (stderr, "\n");
2627 goto errorTreeReturn;
2630 /* if they are both literal */
2631 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2633 tree->type = EX_VALUE;
2634 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2635 valFromType (RETYPE (tree)), '&');
2637 tree->right = tree->left = NULL;
2638 TETYPE (tree) = tree->opval.val->etype;
2639 TTYPE (tree) = tree->opval.val->type;
2643 /* see if this is a GETHBIT operation if yes
2646 ast *otree = optimizeGetHbit (tree, resultType);
2649 return decorateType (otree, RESULT_TYPE_NONE);
2652 /* see if this is a GETABIT operation if yes
2655 ast *otree = optimizeGetAbit (tree, resultType);
2658 return decorateType (otree, RESULT_TYPE_NONE);
2661 /* see if this is a GETBYTE operation if yes
2664 ast *otree = optimizeGetByte (tree, resultType);
2667 return decorateType (otree, RESULT_TYPE_NONE);
2670 /* see if this is a GETWORD operation if yes
2673 ast *otree = optimizeGetWord (tree, resultType);
2676 return decorateType (otree, RESULT_TYPE_NONE);
2679 /* if left is a literal exchange left & right */
2680 if (IS_LITERAL (LTYPE (tree)))
2682 ast *tTree = tree->left;
2683 tree->left = tree->right;
2684 tree->right = tTree;
2687 /* if right is a literal and */
2688 /* we can find a 2nd literal in an and-tree then */
2689 /* rearrange the tree */
2690 if (IS_LITERAL (RTYPE (tree)))
2693 ast *litTree = searchLitOp (tree, &parent, "&");
2697 ast *tTree = litTree->left;
2698 litTree->left = tree->right;
2699 tree->right = tTree;
2700 /* both operands in litTree are literal now */
2701 decorateType (parent, resultType);
2705 LRVAL (tree) = RRVAL (tree) = 1;
2707 TTYPE (tree) = computeType (LTYPE (tree),
2711 TETYPE (tree) = getSpec (TTYPE (tree));
2716 /*------------------------------------------------------------------*/
2717 /*----------------------------*/
2719 /*----------------------------*/
2720 p = newLink (DECLARATOR);
2721 /* if bit field then error */
2722 if (IS_BITVAR (tree->left->etype))
2724 werror (E_ILLEGAL_ADDR, "address of bit variable");
2725 goto errorTreeReturn;
2728 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2730 werror (E_ILLEGAL_ADDR, "address of register variable");
2731 goto errorTreeReturn;
2734 if (IS_FUNC (LTYPE (tree)))
2736 // this ought to be ignored
2737 return (tree->left);
2740 if (IS_LITERAL(LTYPE(tree)))
2742 werror (E_ILLEGAL_ADDR, "address of literal");
2743 goto errorTreeReturn;
2748 werror (E_LVALUE_REQUIRED, "address of");
2749 goto errorTreeReturn;
2752 DCL_TYPE (p) = POINTER;
2753 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2754 DCL_TYPE (p) = CPOINTER;
2755 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2756 DCL_TYPE (p) = FPOINTER;
2757 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2758 DCL_TYPE (p) = PPOINTER;
2759 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2760 DCL_TYPE (p) = IPOINTER;
2761 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2762 DCL_TYPE (p) = EEPPOINTER;
2763 else if (SPEC_OCLS(tree->left->etype))
2764 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2766 DCL_TYPE (p) = POINTER;
2768 if (IS_AST_SYM_VALUE (tree->left))
2770 AST_SYMBOL (tree->left)->addrtaken = 1;
2771 AST_SYMBOL (tree->left)->allocreq = 1;
2774 p->next = LTYPE (tree);
2776 TETYPE (tree) = getSpec (TTYPE (tree));
2781 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2782 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2784 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2785 AST_SYMBOL(tree->left->right));
2786 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2787 valueFromLit(element->offset));
2790 tree->type = EX_VALUE;
2791 tree->values.literalFromCast = 1;
2797 /*------------------------------------------------------------------*/
2798 /*----------------------------*/
2800 /*----------------------------*/
2802 /* if the rewrite succeeds then don't go any further */
2804 ast *wtree = optimizeRRCRLC (tree);
2806 return decorateType (wtree, RESULT_TYPE_NONE);
2808 wtree = optimizeSWAP (tree);
2810 return decorateType (wtree, RESULT_TYPE_NONE);
2813 /* if left is a literal exchange left & right */
2814 if (IS_LITERAL (LTYPE (tree)))
2816 ast *tTree = tree->left;
2817 tree->left = tree->right;
2818 tree->right = tTree;
2821 /* if right is a literal and */
2822 /* we can find a 2nd literal in an or-tree then */
2823 /* rearrange the tree */
2824 if (IS_LITERAL (RTYPE (tree)))
2827 ast *litTree = searchLitOp (tree, &parent, "|");
2831 ast *tTree = litTree->left;
2832 litTree->left = tree->right;
2833 tree->right = tTree;
2834 /* both operands in tTree are literal now */
2835 decorateType (parent, resultType);
2840 /*------------------------------------------------------------------*/
2841 /*----------------------------*/
2843 /*----------------------------*/
2845 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2847 werror (E_BITWISE_OP);
2848 werror (W_CONTINUE, "left & right types are ");
2849 printTypeChain (LTYPE (tree), stderr);
2850 fprintf (stderr, ",");
2851 printTypeChain (RTYPE (tree), stderr);
2852 fprintf (stderr, "\n");
2853 goto errorTreeReturn;
2856 /* if they are both literal then rewrite the tree */
2857 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2859 tree->type = EX_VALUE;
2860 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2861 valFromType (RETYPE (tree)),
2863 tree->right = tree->left = NULL;
2864 TETYPE (tree) = tree->opval.val->etype;
2865 TTYPE (tree) = tree->opval.val->type;
2869 /* if left is a literal exchange left & right */
2870 if (IS_LITERAL (LTYPE (tree)))
2872 ast *tTree = tree->left;
2873 tree->left = tree->right;
2874 tree->right = tTree;
2877 /* if right is a literal and */
2878 /* we can find a 2nd literal in a xor-tree then */
2879 /* rearrange the tree */
2880 if (IS_LITERAL (RTYPE (tree)) &&
2881 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2884 ast *litTree = searchLitOp (tree, &parent, "^");
2888 ast *tTree = litTree->left;
2889 litTree->left = tree->right;
2890 tree->right = tTree;
2891 /* both operands in litTree are literal now */
2892 decorateType (parent, resultType);
2896 LRVAL (tree) = RRVAL (tree) = 1;
2898 TTYPE (tree) = computeType (LTYPE (tree),
2902 TETYPE (tree) = getSpec (TTYPE (tree));
2906 /*------------------------------------------------------------------*/
2907 /*----------------------------*/
2909 /*----------------------------*/
2911 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2913 werror (E_INVALID_OP, "divide");
2914 goto errorTreeReturn;
2916 /* if they are both literal then */
2917 /* rewrite the tree */
2918 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2920 tree->type = EX_VALUE;
2921 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2922 valFromType (RETYPE (tree)));
2923 tree->right = tree->left = NULL;
2924 TETYPE (tree) = getSpec (TTYPE (tree) =
2925 tree->opval.val->type);
2929 LRVAL (tree) = RRVAL (tree) = 1;
2931 TETYPE (tree) = getSpec (TTYPE (tree) =
2932 computeType (LTYPE (tree),
2937 /* if right is a literal and */
2938 /* left is also a division by a literal then */
2939 /* rearrange the tree */
2940 if (IS_LITERAL (RTYPE (tree))
2941 /* avoid infinite loop */
2942 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2945 ast *litTree = searchLitOp (tree, &parent, "/");
2948 if (IS_LITERAL (RTYPE (litTree)))
2952 litTree->right = newNode ('*',
2954 copyAst (tree->right));
2955 litTree->right->lineno = tree->lineno;
2957 tree->right->opval.val = constVal ("1");
2958 decorateType (parent, resultType);
2962 /* litTree->left is literal: no gcse possible.
2963 We can't call decorateType(parent, RESULT_TYPE_NONE), because
2964 this would cause an infinit loop. */
2965 parent->decorated = 1;
2966 decorateType (litTree, resultType);
2973 /*------------------------------------------------------------------*/
2974 /*----------------------------*/
2976 /*----------------------------*/
2978 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2980 werror (E_BITWISE_OP);
2981 werror (W_CONTINUE, "left & right types are ");
2982 printTypeChain (LTYPE (tree), stderr);
2983 fprintf (stderr, ",");
2984 printTypeChain (RTYPE (tree), stderr);
2985 fprintf (stderr, "\n");
2986 goto errorTreeReturn;
2988 /* if they are both literal then */
2989 /* rewrite the tree */
2990 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2992 tree->type = EX_VALUE;
2993 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2994 valFromType (RETYPE (tree)));
2995 tree->right = tree->left = NULL;
2996 TETYPE (tree) = getSpec (TTYPE (tree) =
2997 tree->opval.val->type);
3000 LRVAL (tree) = RRVAL (tree) = 1;
3001 TETYPE (tree) = getSpec (TTYPE (tree) =
3002 computeType (LTYPE (tree),
3008 /*------------------------------------------------------------------*/
3009 /*----------------------------*/
3010 /* address dereference */
3011 /*----------------------------*/
3012 case '*': /* can be unary : if right is null then unary operation */
3015 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3017 werror (E_PTR_REQD);
3018 goto errorTreeReturn;
3023 werror (E_LVALUE_REQUIRED, "pointer deref");
3024 goto errorTreeReturn;
3026 if (IS_ADDRESS_OF_OP(tree->left))
3028 /* replace *&obj with obj */
3029 return tree->left->left;
3031 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3032 TETYPE (tree) = getSpec (TTYPE (tree));
3033 /* adjust the storage class */
3034 switch (DCL_TYPE(tree->left->ftype)) {
3036 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3039 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3042 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3045 SPEC_SCLS (TETYPE (tree)) = 0;
3048 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3051 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3054 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3057 SPEC_SCLS (TETYPE (tree)) = 0;
3066 /*------------------------------------------------------------------*/
3067 /*----------------------------*/
3068 /* multiplication */
3069 /*----------------------------*/
3070 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3072 werror (E_INVALID_OP, "multiplication");
3073 goto errorTreeReturn;
3076 /* if they are both literal then */
3077 /* rewrite the tree */
3078 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3080 tree->type = EX_VALUE;
3081 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3082 valFromType (RETYPE (tree)));
3083 tree->right = tree->left = NULL;
3084 TETYPE (tree) = getSpec (TTYPE (tree) =
3085 tree->opval.val->type);
3089 /* if left is a literal exchange left & right */
3090 if (IS_LITERAL (LTYPE (tree)))
3092 ast *tTree = tree->left;
3093 tree->left = tree->right;
3094 tree->right = tTree;
3097 /* if right is a literal and */
3098 /* we can find a 2nd literal in a mul-tree then */
3099 /* rearrange the tree */
3100 if (IS_LITERAL (RTYPE (tree)))
3103 ast *litTree = searchLitOp (tree, &parent, "*");
3107 ast *tTree = litTree->left;
3108 litTree->left = tree->right;
3109 tree->right = tTree;
3110 /* both operands in litTree are literal now */
3111 decorateType (parent, resultType);
3115 LRVAL (tree) = RRVAL (tree) = 1;
3116 tree->left = addCast (tree->left, resultType, FALSE);
3117 tree->right = addCast (tree->right, resultType, FALSE);
3118 TETYPE (tree) = getSpec (TTYPE (tree) =
3119 computeType (LTYPE (tree),
3126 /*------------------------------------------------------------------*/
3127 /*----------------------------*/
3128 /* unary '+' operator */
3129 /*----------------------------*/
3134 if (!IS_ARITHMETIC (LTYPE (tree)))
3136 werror (E_UNARY_OP, '+');
3137 goto errorTreeReturn;
3140 /* if left is a literal then do it */
3141 if (IS_LITERAL (LTYPE (tree)))
3143 tree->type = EX_VALUE;
3144 tree->opval.val = valFromType (LETYPE (tree));
3146 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3150 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3154 /*------------------------------------------------------------------*/
3155 /*----------------------------*/
3157 /*----------------------------*/
3159 /* this is not a unary operation */
3160 /* if both pointers then problem */
3161 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3162 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3164 werror (E_PTR_PLUS_PTR);
3165 goto errorTreeReturn;
3168 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3169 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3171 werror (E_PLUS_INVALID, "+");
3172 goto errorTreeReturn;
3175 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3176 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3178 werror (E_PLUS_INVALID, "+");
3179 goto errorTreeReturn;
3181 /* if they are both literal then */
3182 /* rewrite the tree */
3183 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3185 tree->type = EX_VALUE;
3186 tree->left = addCast (tree->left, resultType, TRUE);
3187 tree->right = addCast (tree->right, resultType, TRUE);
3188 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3189 valFromType (RETYPE (tree)));
3190 tree->right = tree->left = NULL;
3191 TETYPE (tree) = getSpec (TTYPE (tree) =
3192 tree->opval.val->type);
3196 /* if the right is a pointer or left is a literal
3197 xchange left & right */
3198 if (IS_ARRAY (RTYPE (tree)) ||
3199 IS_PTR (RTYPE (tree)) ||
3200 IS_LITERAL (LTYPE (tree)))
3202 ast *tTree = tree->left;
3203 tree->left = tree->right;
3204 tree->right = tTree;
3207 /* if right is a literal and */
3208 /* left is also an addition/subtraction with a literal then */
3209 /* rearrange the tree */
3210 if (IS_LITERAL (RTYPE (tree)))
3212 ast *litTree, *parent;
3213 litTree = searchLitOp (tree, &parent, "+-");
3216 if (litTree->opval.op == '+')
3220 ast *tTree = litTree->left;
3221 litTree->left = tree->right;
3222 tree->right = tree->left;
3225 else if (litTree->opval.op == '-')
3227 if (IS_LITERAL (RTYPE (litTree)))
3231 ast *tTree = litTree->left;
3232 litTree->left = tree->right;
3233 tree->right = tTree;
3239 ast *tTree = litTree->right;
3240 litTree->right = tree->right;
3241 tree->right = tTree;
3242 litTree->opval.op = '+';
3243 tree->opval.op = '-';
3246 decorateType (parent, resultType);
3250 LRVAL (tree) = RRVAL (tree) = 1;
3251 /* if the left is a pointer */
3252 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3253 TETYPE (tree) = getSpec (TTYPE (tree) =
3257 tree->left = addCast (tree->left, resultType, TRUE);
3258 tree->right = addCast (tree->right, resultType, TRUE);
3259 TETYPE (tree) = getSpec (TTYPE (tree) =
3260 computeType (LTYPE (tree),
3268 /*------------------------------------------------------------------*/
3269 /*----------------------------*/
3271 /*----------------------------*/
3272 case '-': /* can be unary */
3273 /* if right is null then unary */
3277 if (!IS_ARITHMETIC (LTYPE (tree)))
3279 werror (E_UNARY_OP, tree->opval.op);
3280 goto errorTreeReturn;
3283 /* if left is a literal then do it */
3284 if (IS_LITERAL (LTYPE (tree)))
3286 tree->type = EX_VALUE;
3287 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3289 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3292 tree->left = addCast (tree->left, resultType, TRUE);
3293 TETYPE (tree) = getSpec (TTYPE (tree) =
3294 computeType (LTYPE (tree),
3302 /*------------------------------------------------------------------*/
3303 /*----------------------------*/
3305 /*----------------------------*/
3307 if (!(IS_PTR (LTYPE (tree)) ||
3308 IS_ARRAY (LTYPE (tree)) ||
3309 IS_ARITHMETIC (LTYPE (tree))))
3311 werror (E_PLUS_INVALID, "-");
3312 goto errorTreeReturn;
3315 if (!(IS_PTR (RTYPE (tree)) ||
3316 IS_ARRAY (RTYPE (tree)) ||
3317 IS_ARITHMETIC (RTYPE (tree))))
3319 werror (E_PLUS_INVALID, "-");
3320 goto errorTreeReturn;
3323 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3324 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3325 IS_INTEGRAL (RTYPE (tree))))
3327 werror (E_PLUS_INVALID, "-");
3328 goto errorTreeReturn;
3331 /* if they are both literal then */
3332 /* rewrite the tree */
3333 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3335 tree->type = EX_VALUE;
3336 tree->left = addCast (tree->left, resultType, TRUE);
3337 tree->right = addCast (tree->right, resultType, TRUE);
3338 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3339 valFromType (RETYPE (tree)));
3340 tree->right = tree->left = NULL;
3341 TETYPE (tree) = getSpec (TTYPE (tree) =
3342 tree->opval.val->type);
3346 /* if the left & right are equal then zero */
3347 if (isAstEqual (tree->left, tree->right))
3349 tree->type = EX_VALUE;
3350 tree->left = tree->right = NULL;
3351 tree->opval.val = constVal ("0");
3352 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3356 /* if both of them are pointers or arrays then */
3357 /* the result is going to be an integer */
3358 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3359 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3360 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3362 /* if only the left is a pointer */
3363 /* then result is a pointer */
3364 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3365 TETYPE (tree) = getSpec (TTYPE (tree) =
3369 tree->left = addCast (tree->left, resultType, TRUE);
3370 tree->right = addCast (tree->right, resultType, TRUE);
3372 TETYPE (tree) = getSpec (TTYPE (tree) =
3373 computeType (LTYPE (tree),
3379 LRVAL (tree) = RRVAL (tree) = 1;
3381 /* if right is a literal and */
3382 /* left is also an addition/subtraction with a literal then */
3383 /* rearrange the tree */
3384 if (IS_LITERAL (RTYPE (tree))
3385 /* avoid infinite loop */
3386 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3388 ast *litTree, *litParent;
3389 litTree = searchLitOp (tree, &litParent, "+-");
3392 if (litTree->opval.op == '+')
3396 ast *tTree = litTree->left;
3397 litTree->left = litTree->right;
3398 litTree->right = tree->right;
3399 tree->right = tTree;
3400 tree->opval.op = '+';
3401 litTree->opval.op = '-';
3403 else if (litTree->opval.op == '-')
3405 if (IS_LITERAL (RTYPE (litTree)))
3409 ast *tTree = litTree->left;
3410 litTree->left = tree->right;
3411 tree->right = litParent->left;
3412 litParent->left = tTree;
3413 litTree->opval.op = '+';
3415 tree->decorated = 0;
3416 decorateType (tree, resultType);
3422 ast *tTree = litTree->right;
3423 litTree->right = tree->right;
3424 tree->right = tTree;
3427 decorateType (litParent, resultType);
3432 /*------------------------------------------------------------------*/
3433 /*----------------------------*/
3435 /*----------------------------*/
3437 /* can be only integral type */
3438 if (!IS_INTEGRAL (LTYPE (tree)))
3440 werror (E_UNARY_OP, tree->opval.op);
3441 goto errorTreeReturn;
3444 /* if left is a literal then do it */
3445 if (IS_LITERAL (LTYPE (tree)))
3447 tree->type = EX_VALUE;
3448 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3450 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3451 return addCast (tree, resultType, TRUE);
3454 if (resultType == RESULT_TYPE_BIT &&
3455 IS_UNSIGNED (tree->left->etype) &&
3456 getSize (tree->left->etype) < INTSIZE)
3458 /* promotion rules are responsible for this strange result:
3459 bit -> int -> ~int -> bit
3460 uchar -> int -> ~int -> bit
3462 werror(W_COMPLEMENT);
3464 /* optimize bit-result, even if we optimize a buggy source */
3465 tree->type = EX_VALUE;
3466 tree->opval.val = constVal ("1");
3469 tree->left = addCast (tree->left, resultType, TRUE);
3471 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3474 /*------------------------------------------------------------------*/
3475 /*----------------------------*/
3477 /*----------------------------*/
3479 /* can be pointer */
3480 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3481 !IS_PTR (LTYPE (tree)) &&
3482 !IS_ARRAY (LTYPE (tree)))
3484 werror (E_UNARY_OP, tree->opval.op);
3485 goto errorTreeReturn;
3488 /* if left is a literal then do it */
3489 if (IS_LITERAL (LTYPE (tree)))
3491 tree->type = EX_VALUE;
3492 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3494 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3498 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3501 /*------------------------------------------------------------------*/
3502 /*----------------------------*/
3504 /*----------------------------*/
3508 TTYPE (tree) = LTYPE (tree);
3509 TETYPE (tree) = LETYPE (tree);
3514 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3518 TTYPE (tree) = TETYPE (tree) = newCharLink();
3522 TTYPE (tree) = TETYPE (tree) = newIntLink();
3527 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3529 werror (E_SHIFT_OP_INVALID);
3530 werror (W_CONTINUE, "left & right types are ");
3531 printTypeChain (LTYPE (tree), stderr);
3532 fprintf (stderr, ",");
3533 printTypeChain (RTYPE (tree), stderr);
3534 fprintf (stderr, "\n");
3535 goto errorTreeReturn;
3538 /* make smaller type only if it's a LEFT_OP */
3539 if (tree->opval.op == LEFT_OP)
3540 tree->left = addCast (tree->left, resultType, TRUE);
3542 /* if they are both literal then */
3543 /* rewrite the tree */
3544 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3546 tree->type = EX_VALUE;
3547 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3548 valFromType (RETYPE (tree)),
3549 (tree->opval.op == LEFT_OP ? 1 : 0));
3550 tree->right = tree->left = NULL;
3551 TETYPE (tree) = getSpec (TTYPE (tree) =
3552 tree->opval.val->type);
3556 /* see if this is a GETBYTE operation if yes
3559 ast *otree = optimizeGetByte (tree, resultType);
3562 return decorateType (otree, RESULT_TYPE_NONE);
3565 /* see if this is a GETWORD operation if yes
3568 ast *otree = optimizeGetWord (tree, resultType);
3571 return decorateType (otree, RESULT_TYPE_NONE);
3574 LRVAL (tree) = RRVAL (tree) = 1;
3575 if (tree->opval.op == LEFT_OP)
3577 TETYPE (tree) = getSpec (TTYPE (tree) =
3578 computeType (LTYPE (tree),
3585 /* no promotion necessary */
3586 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3587 if (IS_LITERAL (TTYPE (tree)))
3588 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3591 /* if only the right side is a literal & we are
3592 shifting more than size of the left operand then zero */
3593 if (IS_LITERAL (RTYPE (tree)) &&
3594 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3595 (getSize (TETYPE (tree)) * 8))
3597 if (tree->opval.op==LEFT_OP ||
3598 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3600 lineno=tree->lineno;
3601 werror (W_SHIFT_CHANGED,
3602 (tree->opval.op == LEFT_OP ? "left" : "right"));
3603 tree->type = EX_VALUE;
3604 tree->left = tree->right = NULL;
3605 tree->opval.val = constVal ("0");
3606 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3613 /*------------------------------------------------------------------*/
3614 /*----------------------------*/
3616 /*----------------------------*/
3617 case CAST: /* change the type */
3618 /* cannot cast to an aggregate type */
3619 if (IS_AGGREGATE (LTYPE (tree)))
3621 werror (E_CAST_ILLEGAL);
3622 goto errorTreeReturn;
3625 /* make sure the type is complete and sane */
3626 changePointer(LTYPE(tree));
3627 checkTypeSanity(LETYPE(tree), "(cast)");
3629 /* If code memory is read only, then pointers to code memory */
3630 /* implicitly point to constants -- make this explicit */
3632 sym_link *t = LTYPE(tree);
3633 while (t && t->next)
3635 if (IS_CODEPTR(t) && port->mem.code_ro)
3637 if (IS_SPEC(t->next))
3638 SPEC_CONST (t->next) = 1;
3640 DCL_PTR_CONST (t->next) = 1;
3647 /* if the right is a literal replace the tree */
3648 if (IS_LITERAL (RETYPE (tree))) {
3649 if (!IS_PTR (LTYPE (tree))) {
3650 tree->type = EX_VALUE;
3652 valCastLiteral (LTYPE (tree),
3653 floatFromVal (valFromType (RETYPE (tree))));
3656 TTYPE (tree) = tree->opval.val->type;
3657 tree->values.literalFromCast = 1;
3658 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3659 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3660 sym_link *rest = LTYPE(tree)->next;
3661 werror(W_LITERAL_GENERIC);
3662 TTYPE(tree) = newLink(DECLARATOR);
3663 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3664 TTYPE(tree)->next = rest;
3665 tree->left->opval.lnk = TTYPE(tree);
3668 TTYPE (tree) = LTYPE (tree);
3672 TTYPE (tree) = LTYPE (tree);
3676 #if 0 // this is already checked, now this could be explicit
3677 /* if pointer to struct then check names */
3678 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3679 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3680 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3682 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3683 SPEC_STRUCT(LETYPE(tree))->tag);
3686 if (IS_ADDRESS_OF_OP(tree->right)
3687 && IS_AST_SYM_VALUE (tree->right->left)
3688 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3690 symbol * sym = AST_SYMBOL (tree->right->left);
3691 unsigned int gptype = 0;
3692 unsigned int addr = SPEC_ADDR (sym->etype);
3694 if (IS_GENPTR (LTYPE (tree)) && GPTRSIZE > FPTRSIZE)
3696 switch (SPEC_SCLS (sym->etype))
3699 gptype = GPTYPE_CODE;
3702 gptype = GPTYPE_FAR;
3706 gptype = GPTYPE_NEAR;
3709 gptype = GPTYPE_XSTACK;
3714 addr |= gptype << (8*(GPTRSIZE - 1));
3717 tree->type = EX_VALUE;
3719 valCastLiteral (LTYPE (tree), addr);
3720 TTYPE (tree) = tree->opval.val->type;
3721 TETYPE (tree) = getSpec (TTYPE (tree));
3724 tree->values.literalFromCast = 1;
3728 /* handle offsetof macro: */
3729 /* #define offsetof(TYPE, MEMBER) \ */
3730 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3731 if (IS_ADDRESS_OF_OP(tree->right)
3732 && IS_AST_OP (tree->right->left)
3733 && tree->right->left->opval.op == PTR_OP
3734 && IS_AST_OP (tree->right->left->left)
3735 && tree->right->left->left->opval.op == CAST
3736 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3738 symbol *element = getStructElement (
3739 SPEC_STRUCT (LETYPE(tree->right->left)),
3740 AST_SYMBOL(tree->right->left->right)
3744 tree->type = EX_VALUE;
3745 tree->opval.val = valCastLiteral (
3748 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3751 TTYPE (tree) = tree->opval.val->type;
3752 TETYPE (tree) = getSpec (TTYPE (tree));
3759 /* if the right is a literal replace the tree */
3760 if (IS_LITERAL (RETYPE (tree))) {
3762 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3763 /* rewrite (type *)litaddr
3765 and define type at litaddr temp
3766 (but only if type's storage class is not generic)
3768 ast *newTree = newNode ('&', NULL, NULL);
3771 TTYPE (newTree) = LTYPE (tree);
3772 TETYPE (newTree) = getSpec(LTYPE (tree));
3774 /* define a global symbol at the casted address*/
3775 sym = newSymbol(genSymName (0), 0);
3776 sym->type = LTYPE (tree)->next;
3778 sym->type = newLink (V_VOID);
3779 sym->etype = getSpec(sym->type);
3780 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3781 sym->lineDef = tree->lineno;
3784 SPEC_STAT (sym->etype) = 1;
3785 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3786 SPEC_ABSA(sym->etype) = 1;
3787 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3790 newTree->left = newAst_VALUE(symbolVal(sym));
3791 newTree->left->lineno = tree->lineno;
3792 LTYPE (newTree) = sym->type;
3793 LETYPE (newTree) = sym->etype;
3794 LLVAL (newTree) = 1;
3795 LRVAL (newTree) = 0;
3796 TLVAL (newTree) = 1;
3800 if (!IS_PTR (LTYPE (tree))) {
3801 tree->type = EX_VALUE;
3803 valCastLiteral (LTYPE (tree),
3804 floatFromVal (valFromType (RTYPE (tree))));
3805 TTYPE (tree) = tree->opval.val->type;
3808 tree->values.literalFromCast = 1;
3809 TETYPE (tree) = getSpec (TTYPE (tree));
3813 TTYPE (tree) = LTYPE (tree);
3817 TETYPE (tree) = getSpec (TTYPE (tree));
3821 /*------------------------------------------------------------------*/
3822 /*----------------------------*/
3823 /* logical &&, || */
3824 /*----------------------------*/
3827 /* each must be arithmetic type or be a pointer */
3828 if (!IS_PTR (LTYPE (tree)) &&
3829 !IS_ARRAY (LTYPE (tree)) &&
3830 !IS_INTEGRAL (LTYPE (tree)))
3832 werror (E_COMPARE_OP);
3833 goto errorTreeReturn;
3836 if (!IS_PTR (RTYPE (tree)) &&
3837 !IS_ARRAY (RTYPE (tree)) &&
3838 !IS_INTEGRAL (RTYPE (tree)))
3840 werror (E_COMPARE_OP);
3841 goto errorTreeReturn;
3843 /* if they are both literal then */
3844 /* rewrite the tree */
3845 if (IS_LITERAL (RTYPE (tree)) &&
3846 IS_LITERAL (LTYPE (tree)))
3848 tree->type = EX_VALUE;
3849 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3850 valFromType (RTYPE (tree)),
3852 tree->right = tree->left = NULL;
3853 TETYPE (tree) = getSpec (TTYPE (tree) =
3854 tree->opval.val->type);
3857 LRVAL (tree) = RRVAL (tree) = 1;
3858 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3861 /*------------------------------------------------------------------*/
3862 /*----------------------------*/
3863 /* comparison operators */
3864 /*----------------------------*/
3872 ast *lt = optimizeCompare (tree);
3878 /* if they are pointers they must be castable */
3879 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3881 if (tree->opval.op==EQ_OP &&
3882 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3883 // we cannot cast a gptr to a !gptr: switch the leaves
3884 struct ast *s=tree->left;
3885 tree->left=tree->right;
3888 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3890 werror (E_COMPARE_OP);
3891 fprintf (stderr, "comparing type ");
3892 printTypeChain (LTYPE (tree), stderr);
3893 fprintf (stderr, "to type ");
3894 printTypeChain (RTYPE (tree), stderr);
3895 fprintf (stderr, "\n");
3896 goto errorTreeReturn;
3899 /* else they should be promotable to one another */
3902 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3903 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3905 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3907 werror (E_COMPARE_OP);
3908 fprintf (stderr, "comparing type ");
3909 printTypeChain (LTYPE (tree), stderr);
3910 fprintf (stderr, "to type ");
3911 printTypeChain (RTYPE (tree), stderr);
3912 fprintf (stderr, "\n");
3913 goto errorTreeReturn;
3916 /* if unsigned value < 0 then always false */
3917 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3918 if (SPEC_USIGN(LETYPE(tree)) &&
3919 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3920 IS_LITERAL(RTYPE(tree)) &&
3921 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3923 if (tree->opval.op == '<')
3927 if (tree->opval.op == '>')
3929 if (resultType == RESULT_TYPE_IFX)
3931 /* the parent is an ifx: */
3932 /* if (unsigned value) */
3936 /* (unsigned value) ? 1 : 0 */
3937 tree->opval.op = '?';
3938 tree->right = newNode (':',
3939 newAst_VALUE (constVal ("1")),
3940 tree->right); /* val 0 */
3941 tree->right->lineno = tree->lineno;
3942 tree->right->left->lineno = tree->lineno;
3943 decorateType (tree->right, RESULT_TYPE_NONE);
3946 /* if they are both literal then */
3947 /* rewrite the tree */
3948 if (IS_LITERAL (RTYPE (tree)) &&
3949 IS_LITERAL (LTYPE (tree)))
3951 tree->type = EX_VALUE;
3952 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3953 valFromType (RETYPE (tree)),
3955 tree->right = tree->left = NULL;
3956 TETYPE (tree) = getSpec (TTYPE (tree) =
3957 tree->opval.val->type);
3960 /* if one is 'signed char ' and the other one is 'unsigned char' */
3961 /* it's necessary to promote to int */
3962 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
3963 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
3965 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
3966 if it's possible to use a 'signed char' */
3968 /* is left a 'unsigned char'? */
3969 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
3970 /* the value range of a 'unsigned char' is 0...255;
3971 if the actual value is < 128 it can be changed to signed */
3972 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
3974 /* now we've got 2 'signed char'! */
3975 SPEC_USIGN (RETYPE (tree)) = 0;
3977 /* same test for the left operand: */
3978 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
3979 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
3981 SPEC_USIGN (LETYPE (tree)) = 0;
3985 werror (W_CMP_SU_CHAR);
3986 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
3987 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
3991 LRVAL (tree) = RRVAL (tree) = 1;
3992 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3995 /*------------------------------------------------------------------*/
3996 /*----------------------------*/
3998 /*----------------------------*/
3999 case SIZEOF: /* evaluate wihout code generation */
4000 /* change the type to a integer */
4002 int size = getSize (tree->right->ftype);
4003 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4004 if (!size && !IS_VOID(tree->right->ftype))
4005 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4007 tree->type = EX_VALUE;
4008 tree->opval.val = constVal (buffer);
4009 tree->right = tree->left = NULL;
4010 TETYPE (tree) = getSpec (TTYPE (tree) =
4011 tree->opval.val->type);
4014 /*------------------------------------------------------------------*/
4015 /*----------------------------*/
4017 /*----------------------------*/
4019 /* return typeof enum value */
4020 tree->type = EX_VALUE;
4023 if (IS_SPEC(tree->right->ftype)) {
4024 switch (SPEC_NOUN(tree->right->ftype)) {
4026 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4027 else typeofv = TYPEOF_INT;
4030 typeofv = TYPEOF_FLOAT;
4033 typeofv = TYPEOF_FIXED16X16;
4036 typeofv = TYPEOF_CHAR;
4039 typeofv = TYPEOF_VOID;
4042 typeofv = TYPEOF_STRUCT;
4045 typeofv = TYPEOF_BITFIELD;
4048 typeofv = TYPEOF_BIT;
4051 typeofv = TYPEOF_SBIT;
4057 switch (DCL_TYPE(tree->right->ftype)) {
4059 typeofv = TYPEOF_POINTER;
4062 typeofv = TYPEOF_FPOINTER;
4065 typeofv = TYPEOF_CPOINTER;
4068 typeofv = TYPEOF_GPOINTER;
4071 typeofv = TYPEOF_PPOINTER;
4074 typeofv = TYPEOF_IPOINTER;
4077 typeofv = TYPEOF_ARRAY;
4080 typeofv = TYPEOF_FUNCTION;
4086 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4087 tree->opval.val = constVal (buffer);
4088 tree->right = tree->left = NULL;
4089 TETYPE (tree) = getSpec (TTYPE (tree) =
4090 tree->opval.val->type);
4093 /*------------------------------------------------------------------*/
4094 /*----------------------------*/
4095 /* conditional operator '?' */
4096 /*----------------------------*/
4098 /* the type is value of the colon operator (on the right) */
4099 assert (IS_COLON_OP (tree->right));
4100 /* if already known then replace the tree : optimizer will do it
4101 but faster to do it here */
4102 if (IS_LITERAL (LTYPE (tree)))
4104 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4105 return decorateType (tree->right->left, resultTypeProp);
4107 return decorateType (tree->right->right, resultTypeProp);
4111 tree->right = decorateType (tree->right, resultTypeProp);
4112 TTYPE (tree) = RTYPE (tree);
4113 TETYPE (tree) = getSpec (TTYPE (tree));
4118 /* if they don't match we have a problem */
4119 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4120 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4122 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4123 goto errorTreeReturn;
4126 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4127 resultType, tree->opval.op);
4128 TETYPE (tree) = getSpec (TTYPE (tree));
4132 #if 0 // assignment operators are converted by the parser
4133 /*------------------------------------------------------------------*/
4134 /*----------------------------*/
4135 /* assignment operators */
4136 /*----------------------------*/
4139 /* for these it must be both must be integral */
4140 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4141 !IS_ARITHMETIC (RTYPE (tree)))
4143 werror (E_OPS_INTEGRAL);
4144 goto errorTreeReturn;
4147 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4149 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4150 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4154 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4155 goto errorTreeReturn;
4166 /* for these it must be both must be integral */
4167 if (!IS_INTEGRAL (LTYPE (tree)) ||
4168 !IS_INTEGRAL (RTYPE (tree)))
4170 werror (E_OPS_INTEGRAL);
4171 goto errorTreeReturn;
4174 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4176 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4177 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4181 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4182 goto errorTreeReturn;
4188 /*------------------------------------------------------------------*/
4189 /*----------------------------*/
4191 /*----------------------------*/
4193 if (!(IS_PTR (LTYPE (tree)) ||
4194 IS_ARITHMETIC (LTYPE (tree))))
4196 werror (E_PLUS_INVALID, "-=");
4197 goto errorTreeReturn;
4200 if (!(IS_PTR (RTYPE (tree)) ||
4201 IS_ARITHMETIC (RTYPE (tree))))
4203 werror (E_PLUS_INVALID, "-=");
4204 goto errorTreeReturn;
4207 TETYPE (tree) = getSpec (TTYPE (tree) =
4208 computeType (LTYPE (tree),
4213 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4214 werror (E_CODE_WRITE, "-=");
4218 werror (E_LVALUE_REQUIRED, "-=");
4219 goto errorTreeReturn;
4225 /*------------------------------------------------------------------*/
4226 /*----------------------------*/
4228 /*----------------------------*/
4230 /* this is not a unary operation */
4231 /* if both pointers then problem */
4232 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4234 werror (E_PTR_PLUS_PTR);
4235 goto errorTreeReturn;
4238 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4240 werror (E_PLUS_INVALID, "+=");
4241 goto errorTreeReturn;
4244 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4246 werror (E_PLUS_INVALID, "+=");
4247 goto errorTreeReturn;
4250 TETYPE (tree) = getSpec (TTYPE (tree) =
4251 computeType (LTYPE (tree),
4256 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4257 werror (E_CODE_WRITE, "+=");
4261 werror (E_LVALUE_REQUIRED, "+=");
4262 goto errorTreeReturn;
4265 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4266 tree->opval.op = '=';
4271 /*------------------------------------------------------------------*/
4272 /*----------------------------*/
4273 /* straight assignemnt */
4274 /*----------------------------*/
4276 /* cannot be an aggregate */
4277 if (IS_AGGREGATE (LTYPE (tree)))
4279 werror (E_AGGR_ASSIGN);
4280 goto errorTreeReturn;
4283 /* they should either match or be castable */
4284 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4286 werror (E_TYPE_MISMATCH, "assignment", " ");
4287 printFromToType(RTYPE(tree),LTYPE(tree));
4290 /* if the left side of the tree is of type void
4291 then report error */
4292 if (IS_VOID (LTYPE (tree)))
4294 werror (E_CAST_ZERO);
4295 printFromToType(RTYPE(tree), LTYPE(tree));
4298 TETYPE (tree) = getSpec (TTYPE (tree) =
4302 if (!tree->initMode ) {
4303 if (IS_CONSTANT(LTYPE(tree)))
4304 werror (E_CODE_WRITE, "=");
4308 werror (E_LVALUE_REQUIRED, "=");
4309 goto errorTreeReturn;
4314 /*------------------------------------------------------------------*/
4315 /*----------------------------*/
4316 /* comma operator */
4317 /*----------------------------*/
4319 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4322 /*------------------------------------------------------------------*/
4323 /*----------------------------*/
4325 /*----------------------------*/
4328 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4329 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4331 if (tree->left->opval.op == '*' && !tree->left->right)
4332 tree->left = tree->left->left;
4335 /* require a function or pointer to function */
4336 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4338 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4339 goto errorTreeReturn;
4342 /* if there are parms, make sure that
4343 parms are decorate / process / reverse only once */
4345 !tree->right->decorated)
4350 if (IS_FUNCPTR (LTYPE (tree)))
4351 functype = LTYPE (tree)->next;
4353 functype = LTYPE (tree);
4355 if (processParms (tree->left, FUNC_ARGS(functype),
4356 &tree->right, &parmNumber, TRUE))
4358 goto errorTreeReturn;
4361 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4362 !IFFUNC_ISBUILTIN(functype))
4364 reverseParms (tree->right);
4367 TTYPE (tree) = functype->next;
4368 TETYPE (tree) = getSpec (TTYPE (tree));
4372 /*------------------------------------------------------------------*/
4373 /*----------------------------*/
4374 /* return statement */
4375 /*----------------------------*/
4380 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4382 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4383 printFromToType (RTYPE(tree), currFunc->type->next);
4384 goto errorTreeReturn;
4387 if (IS_VOID (currFunc->type->next)
4389 !IS_VOID (RTYPE (tree)))
4391 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4392 goto errorTreeReturn;
4395 /* if there is going to be a casting required then add it */
4396 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4399 decorateType (newNode (CAST,
4400 newAst_LINK (copyLinkChain (currFunc->type->next)),
4410 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4412 werror (W_VOID_FUNC, currFunc->name);
4413 goto errorTreeReturn;
4416 TTYPE (tree) = TETYPE (tree) = NULL;
4419 /*------------------------------------------------------------------*/
4420 /*----------------------------*/
4421 /* switch statement */
4422 /*----------------------------*/
4424 /* the switch value must be an integer */
4425 if (!IS_INTEGRAL (LTYPE (tree)))
4427 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4428 goto errorTreeReturn;
4431 TTYPE (tree) = TETYPE (tree) = NULL;
4434 /*------------------------------------------------------------------*/
4435 /*----------------------------*/
4437 /*----------------------------*/
4439 tree->left = backPatchLabels (tree->left,
4442 TTYPE (tree) = TETYPE (tree) = NULL;
4445 /*------------------------------------------------------------------*/
4446 /*----------------------------*/
4448 /*----------------------------*/
4451 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4452 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4453 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4455 /* if the for loop is reversible then
4456 reverse it otherwise do what we normally
4462 if (isLoopReversible (tree, &sym, &init, &end))
4463 return reverseLoop (tree, sym, init, end);
4465 return decorateType (createFor (AST_FOR (tree, trueLabel),
4466 AST_FOR (tree, continueLabel),
4467 AST_FOR (tree, falseLabel),
4468 AST_FOR (tree, condLabel),
4469 AST_FOR (tree, initExpr),
4470 AST_FOR (tree, condExpr),
4471 AST_FOR (tree, loopExpr),
4472 tree->left), RESULT_TYPE_NONE);
4475 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4476 "node PARAM shouldn't be processed here");
4477 /* but in processParams() */
4480 TTYPE (tree) = TETYPE (tree) = NULL;
4484 /* some error found this tree will be killed */
4486 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4487 tree->opval.op = NULLOP;
4493 /*-----------------------------------------------------------------*/
4494 /* sizeofOp - processes size of operation */
4495 /*-----------------------------------------------------------------*/
4497 sizeofOp (sym_link * type)
4502 /* make sure the type is complete and sane */
4503 checkTypeSanity(type, "(sizeof)");
4505 /* get the size and convert it to character */
4506 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4507 if (!size && !IS_VOID(type))
4508 werror (E_SIZEOF_INCOMPLETE_TYPE);
4510 /* now convert into value */
4511 return constVal (buff);
4515 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4516 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4517 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4518 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4519 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4520 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4521 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4523 /*-----------------------------------------------------------------*/
4524 /* backPatchLabels - change and or not operators to flow control */
4525 /*-----------------------------------------------------------------*/
4527 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4533 if (!(IS_ANDORNOT (tree)))
4536 /* if this an and */
4539 static int localLbl = 0;
4542 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4543 localLabel = newSymbol (buffer, NestLevel);
4545 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4547 /* if left is already a IFX then just change the if true label in that */
4548 if (!IS_IFX (tree->left))
4549 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4551 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4552 /* right is a IFX then just join */
4553 if (IS_IFX (tree->right))
4554 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4556 tree->right = createLabel (localLabel, tree->right);
4557 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4559 return newNode (NULLOP, tree->left, tree->right);
4562 /* if this is an or operation */
4565 static int localLbl = 0;
4568 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4569 localLabel = newSymbol (buffer, NestLevel);
4571 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4573 /* if left is already a IFX then just change the if true label in that */
4574 if (!IS_IFX (tree->left))
4575 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4577 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4578 /* right is a IFX then just join */
4579 if (IS_IFX (tree->right))
4580 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4582 tree->right = createLabel (localLabel, tree->right);
4583 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4585 return newNode (NULLOP, tree->left, tree->right);
4591 int wasnot = IS_NOT (tree->left);
4592 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4594 /* if the left is already a IFX */
4595 if (!IS_IFX (tree->left))
4596 tree->left = newNode (IFX, tree->left, NULL);
4600 tree->left->trueLabel = trueLabel;
4601 tree->left->falseLabel = falseLabel;
4605 tree->left->trueLabel = falseLabel;
4606 tree->left->falseLabel = trueLabel;
4613 tree->trueLabel = trueLabel;
4614 tree->falseLabel = falseLabel;
4621 /*-----------------------------------------------------------------*/
4622 /* createBlock - create expression tree for block */
4623 /*-----------------------------------------------------------------*/
4625 createBlock (symbol * decl, ast * body)
4629 /* if the block has nothing */
4633 ex = newNode (BLOCK, NULL, body);
4634 ex->values.sym = decl;
4641 /*-----------------------------------------------------------------*/
4642 /* createLabel - creates the expression tree for labels */
4643 /*-----------------------------------------------------------------*/
4645 createLabel (symbol * label, ast * stmnt)
4648 char name[SDCC_NAME_MAX + 1];
4651 /* must create fresh symbol if the symbol name */
4652 /* exists in the symbol table, since there can */
4653 /* be a variable with the same name as the labl */
4654 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4655 (csym->level == label->level))
4656 label = newSymbol (label->name, label->level);
4658 /* change the name before putting it in add _ */
4659 SNPRINTF(name, sizeof(name), "%s", label->name);
4661 /* put the label in the LabelSymbol table */
4662 /* but first check if a label of the same */
4664 if ((csym = findSym (LabelTab, NULL, name)))
4665 werror (E_DUPLICATE_LABEL, label->name);
4667 addSym (LabelTab, label, name, label->level, 0, 0);
4671 label->key = labelKey++;
4672 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4678 /*-----------------------------------------------------------------*/
4679 /* createCase - generates the parsetree for a case statement */
4680 /*-----------------------------------------------------------------*/
4682 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4684 char caseLbl[SDCC_NAME_MAX + 1];
4688 /* if the switch statement does not exist */
4689 /* then case is out of context */
4692 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4696 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4697 /* if not a constant then error */
4698 if (!IS_LITERAL (caseVal->ftype))
4700 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4704 /* if not a integer than error */
4705 if (!IS_INTEGRAL (caseVal->ftype))
4707 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4711 /* find the end of the switch values chain */
4712 if (!(val = swStat->values.switchVals.swVals))
4713 swStat->values.switchVals.swVals = caseVal->opval.val;
4716 /* also order the cases according to value */
4718 int cVal = (int) floatFromVal (caseVal->opval.val);
4719 while (val && (int) floatFromVal (val) < cVal)
4725 /* if we reached the end then */
4728 pval->next = caseVal->opval.val;
4730 else if ((int) floatFromVal (val) == cVal)
4732 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4738 /* we found a value greater than */
4739 /* the current value we must add this */
4740 /* before the value */
4741 caseVal->opval.val->next = val;
4743 /* if this was the first in chain */
4744 if (swStat->values.switchVals.swVals == val)
4745 swStat->values.switchVals.swVals =
4748 pval->next = caseVal->opval.val;
4753 /* create the case label */
4754 SNPRINTF(caseLbl, sizeof(caseLbl),
4756 swStat->values.switchVals.swNum,
4757 (int) floatFromVal (caseVal->opval.val));
4759 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4764 /*-----------------------------------------------------------------*/
4765 /* createDefault - creates the parse tree for the default statement */
4766 /*-----------------------------------------------------------------*/
4768 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4770 char defLbl[SDCC_NAME_MAX + 1];
4772 /* if the switch statement does not exist */
4773 /* then case is out of context */
4776 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4780 if (swStat->values.switchVals.swDefault)
4782 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4787 /* turn on the default flag */
4788 swStat->values.switchVals.swDefault = 1;
4790 /* create the label */
4791 SNPRINTF (defLbl, sizeof(defLbl),
4792 "_default_%d", swStat->values.switchVals.swNum);
4793 return createLabel (newSymbol (defLbl, 0), stmnt);
4796 /*-----------------------------------------------------------------*/
4797 /* createIf - creates the parsetree for the if statement */
4798 /*-----------------------------------------------------------------*/
4800 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4802 static int Lblnum = 0;
4804 symbol *ifTrue, *ifFalse, *ifEnd;
4806 /* if neither exists */
4807 if (!elseBody && !ifBody) {
4808 // if there are no side effects (i++, j() etc)
4809 if (!hasSEFcalls(condAst)) {
4814 /* create the labels */
4815 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4816 ifFalse = newSymbol (buffer, NestLevel);
4817 /* if no else body then end == false */
4822 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4823 ifEnd = newSymbol (buffer, NestLevel);
4826 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4827 ifTrue = newSymbol (buffer, NestLevel);
4831 /* attach the ifTrue label to the top of it body */
4832 ifBody = createLabel (ifTrue, ifBody);
4833 /* attach a goto end to the ifBody if else is present */
4836 ifBody = newNode (NULLOP, ifBody,
4838 newAst_VALUE (symbolVal (ifEnd)),
4840 /* put the elseLabel on the else body */
4841 elseBody = createLabel (ifFalse, elseBody);
4842 /* out the end at the end of the body */
4843 elseBody = newNode (NULLOP,
4845 createLabel (ifEnd, NULL));
4849 ifBody = newNode (NULLOP, ifBody,
4850 createLabel (ifFalse, NULL));
4852 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4853 if (IS_IFX (condAst))
4856 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4858 return newNode (NULLOP, ifTree,
4859 newNode (NULLOP, ifBody, elseBody));
4863 /*-----------------------------------------------------------------*/
4864 /* createDo - creates parse tree for do */
4867 /* _docontinue_n: */
4868 /* condition_expression +-> trueLabel -> _dobody_n */
4870 /* +-> falseLabel-> _dobreak_n */
4872 /*-----------------------------------------------------------------*/
4874 createDo (symbol * trueLabel, symbol * continueLabel,
4875 symbol * falseLabel, ast * condAst, ast * doBody)
4880 /* if the body does not exist then it is simple */
4883 condAst = backPatchLabels (condAst, continueLabel, NULL);
4884 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4885 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4886 doTree->trueLabel = continueLabel;
4887 doTree->falseLabel = NULL;
4891 /* otherwise we have a body */
4892 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4894 /* attach the body label to the top */
4895 doBody = createLabel (trueLabel, doBody);
4896 /* attach the continue label to end of body */
4897 doBody = newNode (NULLOP, doBody,
4898 createLabel (continueLabel, NULL));
4900 /* now put the break label at the end */
4901 if (IS_IFX (condAst))
4904 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4906 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4908 /* putting it together */
4909 return newNode (NULLOP, doBody, doTree);
4912 /*-----------------------------------------------------------------*/
4913 /* createFor - creates parse tree for 'for' statement */
4916 /* condExpr +-> trueLabel -> _forbody_n */
4918 /* +-> falseLabel-> _forbreak_n */
4921 /* _forcontinue_n: */
4923 /* goto _forcond_n ; */
4925 /*-----------------------------------------------------------------*/
4927 createFor (symbol * trueLabel, symbol * continueLabel,
4928 symbol * falseLabel, symbol * condLabel,
4929 ast * initExpr, ast * condExpr, ast * loopExpr,
4934 /* if loopexpression not present then we can generate it */
4935 /* the same way as a while */
4937 return newNode (NULLOP, initExpr,
4938 createWhile (trueLabel, continueLabel,
4939 falseLabel, condExpr, forBody));
4940 /* vanilla for statement */
4941 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4943 if (condExpr && !IS_IFX (condExpr))
4944 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4947 /* attach condition label to condition */
4948 condExpr = createLabel (condLabel, condExpr);
4950 /* attach body label to body */
4951 forBody = createLabel (trueLabel, forBody);
4953 /* attach continue to forLoop expression & attach */
4954 /* goto the forcond @ and of loopExpression */
4955 loopExpr = createLabel (continueLabel,
4959 newAst_VALUE (symbolVal (condLabel)),
4961 /* now start putting them together */
4962 forTree = newNode (NULLOP, initExpr, condExpr);
4963 forTree = newNode (NULLOP, forTree, forBody);
4964 forTree = newNode (NULLOP, forTree, loopExpr);
4965 /* finally add the break label */
4966 forTree = newNode (NULLOP, forTree,
4967 createLabel (falseLabel, NULL));
4971 /*-----------------------------------------------------------------*/
4972 /* createWhile - creates parse tree for while statement */
4973 /* the while statement will be created as follows */
4975 /* _while_continue_n: */
4976 /* condition_expression +-> trueLabel -> _while_boby_n */
4978 /* +-> falseLabel -> _while_break_n */
4979 /* _while_body_n: */
4981 /* goto _while_continue_n */
4982 /* _while_break_n: */
4983 /*-----------------------------------------------------------------*/
4985 createWhile (symbol * trueLabel, symbol * continueLabel,
4986 symbol * falseLabel, ast * condExpr, ast * whileBody)
4990 /* put the continue label */
4991 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4992 condExpr = createLabel (continueLabel, condExpr);
4993 condExpr->lineno = 0;
4995 /* put the body label in front of the body */
4996 whileBody = createLabel (trueLabel, whileBody);
4997 whileBody->lineno = 0;
4998 /* put a jump to continue at the end of the body */
4999 /* and put break label at the end of the body */
5000 whileBody = newNode (NULLOP,
5003 newAst_VALUE (symbolVal (continueLabel)),
5004 createLabel (falseLabel, NULL)));
5006 /* put it all together */
5007 if (IS_IFX (condExpr))
5008 whileTree = condExpr;
5011 whileTree = newNode (IFX, condExpr, NULL);
5012 /* put the true & false labels in place */
5013 whileTree->trueLabel = trueLabel;
5014 whileTree->falseLabel = falseLabel;
5017 return newNode (NULLOP, whileTree, whileBody);
5020 /*-----------------------------------------------------------------*/
5021 /* isShiftRightLitVal _BitAndLitVal - helper function */
5022 /*-----------------------------------------------------------------*/
5024 isShiftRightLitVal_BitAndLitVal (ast * tree)
5026 /* if this is not a bit and */
5027 if (!IS_BITAND (tree))
5030 /* will look for tree of the form
5031 ( expr >> litval2) & litval1 */
5032 if (!IS_AST_LIT_VALUE (tree->right))
5035 if (!IS_RIGHT_OP (tree->left))
5038 if (!IS_AST_LIT_VALUE (tree->left->right))
5041 return tree->left->left;
5044 /*-----------------------------------------------------------------*/
5045 /* isBitAndPowOf2 - helper function */
5046 /*-----------------------------------------------------------------*/
5048 isBitAndPow2 (ast * tree)
5050 /* if this is not a bit and */
5051 if (!IS_BITAND (tree))
5054 /* will look for tree of the form
5055 ( expr & (1 << litval) */
5056 if (!IS_AST_LIT_VALUE (tree->right))
5059 return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5062 /*-----------------------------------------------------------------*/
5063 /* optimizeGetHbit - get highest order bit of the expression */
5064 /*-----------------------------------------------------------------*/
5066 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5071 expr = isShiftRightLitVal_BitAndLitVal(tree);
5074 if ((AST_LIT_VALUE (tree->right) != 1) ||
5075 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5076 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5079 if (!expr && (resultType == RESULT_TYPE_BIT))
5082 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5088 /* make sure the port supports GETHBIT */
5089 if (port->hasExtBitOp
5090 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5093 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5096 /*-----------------------------------------------------------------*/
5097 /* optimizeGetAbit - get a single bit of the expression */
5098 /*-----------------------------------------------------------------*/
5100 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5105 expr = isShiftRightLitVal_BitAndLitVal(tree);
5108 if (AST_LIT_VALUE (tree->right) != 1)
5110 count = tree->left->right;
5112 if (!expr && (resultType == RESULT_TYPE_BIT))
5114 int p2 = isBitAndPow2 (tree);
5118 count = newAst_VALUE (valueFromLit (p2));
5124 /* make sure the port supports GETABIT */
5125 if (port->hasExtBitOp
5126 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5129 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5133 /*-----------------------------------------------------------------*/
5134 /* optimizeGetByte - get a byte of the expression */
5135 /*-----------------------------------------------------------------*/
5137 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5143 expr = isShiftRightLitVal_BitAndLitVal(tree);
5146 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5147 count = tree->left->right;
5148 if (AST_LIT_VALUE (tree->right) != 0xFF)
5151 if (!expr && resultType == RESULT_TYPE_CHAR)
5153 /* if this is a right shift over a multiple of 8 */
5154 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5156 i = (unsigned int) AST_LIT_VALUE (tree->right);
5157 count = tree->right;
5161 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5164 /* make sure the port supports GETBYTE */
5165 if (port->hasExtBitOp
5166 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5169 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5172 /*-----------------------------------------------------------------*/
5173 /* optimizeGetWord - get two bytes of the expression */
5174 /*-----------------------------------------------------------------*/
5176 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5182 expr = isShiftRightLitVal_BitAndLitVal(tree);
5185 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5186 count = tree->left->right;
5187 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5190 if (!expr && resultType == RESULT_TYPE_INT)
5192 /* if this is a right shift over a multiple of 8 */
5193 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5195 i = (unsigned int) AST_LIT_VALUE (tree->right);
5196 count = tree->right;
5200 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5203 /* make sure the port supports GETWORD */
5204 if (port->hasExtBitOp
5205 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5208 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5211 /*-----------------------------------------------------------------*/
5212 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5213 /*-----------------------------------------------------------------*/
5215 optimizeRRCRLC (ast * root)
5217 /* will look for trees of the form
5218 (?expr << 1) | (?expr >> 7) or
5219 (?expr >> 7) | (?expr << 1) will make that
5220 into a RLC : operation ..
5222 (?expr >> 1) | (?expr << 7) or
5223 (?expr << 7) | (?expr >> 1) will make that
5224 into a RRC operation
5225 note : by 7 I mean (number of bits required to hold the
5227 /* if the root operations is not a | operation the not */
5228 if (!IS_BITOR (root))
5231 /* I have to think of a better way to match patterns this sucks */
5232 /* that aside let start looking for the first case : I use a the
5233 negative check a lot to improve the efficiency */
5234 /* (?expr << 1) | (?expr >> 7) */
5235 if (IS_LEFT_OP (root->left) &&
5236 IS_RIGHT_OP (root->right))
5239 if (!SPEC_USIGN (TETYPE (root->left->left)))
5242 if (!IS_AST_LIT_VALUE (root->left->right) ||
5243 !IS_AST_LIT_VALUE (root->right->right))
5246 /* make sure it is the same expression */
5247 if (!isAstEqual (root->left->left,
5251 if (AST_LIT_VALUE (root->left->right) != 1)
5254 if (AST_LIT_VALUE (root->right->right) !=
5255 (getSize (TTYPE (root->left->left)) * 8 - 1))
5258 /* make sure the port supports RLC */
5259 if (port->hasExtBitOp
5260 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5263 /* whew got the first case : create the AST */
5264 return newNode (RLC, root->left->left, NULL);
5268 /* check for second case */
5269 /* (?expr >> 7) | (?expr << 1) */
5270 if (IS_LEFT_OP (root->right) &&
5271 IS_RIGHT_OP (root->left))
5274 if (!SPEC_USIGN (TETYPE (root->left->left)))
5277 if (!IS_AST_LIT_VALUE (root->left->right) ||
5278 !IS_AST_LIT_VALUE (root->right->right))
5281 /* make sure it is the same symbol */
5282 if (!isAstEqual (root->left->left,
5286 if (AST_LIT_VALUE (root->right->right) != 1)
5289 if (AST_LIT_VALUE (root->left->right) !=
5290 (getSize (TTYPE (root->left->left)) * 8 - 1))
5293 /* make sure the port supports RLC */
5294 if (port->hasExtBitOp
5295 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5298 /* whew got the first case : create the AST */
5299 return newNode (RLC, root->left->left, NULL);
5304 /* third case for RRC */
5305 /* (?symbol >> 1) | (?symbol << 7) */
5306 if (IS_LEFT_OP (root->right) &&
5307 IS_RIGHT_OP (root->left))
5310 if (!SPEC_USIGN (TETYPE (root->left->left)))
5313 if (!IS_AST_LIT_VALUE (root->left->right) ||
5314 !IS_AST_LIT_VALUE (root->right->right))
5317 /* make sure it is the same symbol */
5318 if (!isAstEqual (root->left->left,
5322 if (AST_LIT_VALUE (root->left->right) != 1)
5325 if (AST_LIT_VALUE (root->right->right) !=
5326 (getSize (TTYPE (root->left->left)) * 8 - 1))
5329 /* make sure the port supports RRC */
5330 if (port->hasExtBitOp
5331 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5334 /* whew got the first case : create the AST */
5335 return newNode (RRC, root->left->left, NULL);
5339 /* fourth and last case for now */
5340 /* (?symbol << 7) | (?symbol >> 1) */
5341 if (IS_RIGHT_OP (root->right) &&
5342 IS_LEFT_OP (root->left))
5345 if (!SPEC_USIGN (TETYPE (root->left->left)))
5348 if (!IS_AST_LIT_VALUE (root->left->right) ||
5349 !IS_AST_LIT_VALUE (root->right->right))
5352 /* make sure it is the same symbol */
5353 if (!isAstEqual (root->left->left,
5357 if (AST_LIT_VALUE (root->right->right) != 1)
5360 if (AST_LIT_VALUE (root->left->right) !=
5361 (getSize (TTYPE (root->left->left)) * 8 - 1))
5364 /* make sure the port supports RRC */
5365 if (port->hasExtBitOp
5366 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5369 /* whew got the first case : create the AST */
5370 return newNode (RRC, root->left->left, NULL);
5374 /* not found return root */
5378 /*-----------------------------------------------------------------*/
5379 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5380 /*-----------------------------------------------------------------*/
5382 optimizeSWAP (ast * root)
5384 /* will look for trees of the form
5385 (?expr << 4) | (?expr >> 4) or
5386 (?expr >> 4) | (?expr << 4) will make that
5387 into a SWAP : operation ..
5388 note : by 4 I mean (number of bits required to hold the
5390 /* if the root operations is not a | operation the not */
5391 if (!IS_BITOR (root))
5394 /* (?expr << 4) | (?expr >> 4) */
5395 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5396 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5399 if (!SPEC_USIGN (TETYPE (root->left->left)))
5402 if (!IS_AST_LIT_VALUE (root->left->right) ||
5403 !IS_AST_LIT_VALUE (root->right->right))
5406 /* make sure it is the same expression */
5407 if (!isAstEqual (root->left->left,
5411 if (AST_LIT_VALUE (root->left->right) !=
5412 (getSize (TTYPE (root->left->left)) * 4))
5415 if (AST_LIT_VALUE (root->right->right) !=
5416 (getSize (TTYPE (root->left->left)) * 4))
5419 /* make sure the port supports SWAP */
5420 if (port->hasExtBitOp
5421 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5424 /* found it : create the AST */
5425 return newNode (SWAP, root->left->left, NULL);
5429 /* not found return root */
5433 /*-----------------------------------------------------------------*/
5434 /* optimizeCompare - optimizes compares for bit variables */
5435 /*-----------------------------------------------------------------*/
5437 optimizeCompare (ast * root)
5439 ast *optExpr = NULL;
5442 unsigned int litValue;
5444 /* if nothing then return nothing */
5448 /* if not a compare op then do leaves */
5449 if (!IS_COMPARE_OP (root))
5451 root->left = optimizeCompare (root->left);
5452 root->right = optimizeCompare (root->right);
5456 /* if left & right are the same then depending
5457 of the operation do */
5458 if (isAstEqual (root->left, root->right))
5460 switch (root->opval.op)
5465 optExpr = newAst_VALUE (constVal ("0"));
5470 optExpr = newAst_VALUE (constVal ("1"));
5474 return decorateType (optExpr, RESULT_TYPE_NONE);
5477 vleft = (root->left->type == EX_VALUE ?
5478 root->left->opval.val : NULL);
5480 vright = (root->right->type == EX_VALUE ?
5481 root->right->opval.val : NULL);
5483 /* if left is a BITVAR in BITSPACE */
5484 /* and right is a LITERAL then opt- */
5485 /* imize else do nothing */
5486 if (vleft && vright &&
5487 IS_BITVAR (vleft->etype) &&
5488 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5489 IS_LITERAL (vright->etype))
5492 /* if right side > 1 then comparison may never succeed */
5493 if ((litValue = (int) floatFromVal (vright)) > 1)
5495 werror (W_BAD_COMPARE);
5501 switch (root->opval.op)
5503 case '>': /* bit value greater than 1 cannot be */
5504 werror (W_BAD_COMPARE);
5508 case '<': /* bit value < 1 means 0 */
5510 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5513 case LE_OP: /* bit value <= 1 means no check */
5514 optExpr = newAst_VALUE (vright);
5517 case GE_OP: /* bit value >= 1 means only check for = */
5519 optExpr = newAst_VALUE (vleft);
5524 { /* literal is zero */
5525 switch (root->opval.op)
5527 case '<': /* bit value < 0 cannot be */
5528 werror (W_BAD_COMPARE);
5532 case '>': /* bit value > 0 means 1 */
5534 optExpr = newAst_VALUE (vleft);
5537 case LE_OP: /* bit value <= 0 means no check */
5538 case GE_OP: /* bit value >= 0 means no check */
5539 werror (W_BAD_COMPARE);
5543 case EQ_OP: /* bit == 0 means ! of bit */
5544 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5548 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5549 } /* end-of-if of BITVAR */
5554 /*-----------------------------------------------------------------*/
5555 /* addSymToBlock : adds the symbol to the first block we find */
5556 /*-----------------------------------------------------------------*/
5558 addSymToBlock (symbol * sym, ast * tree)
5560 /* reached end of tree or a leaf */
5561 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5565 if (IS_AST_OP (tree) &&
5566 tree->opval.op == BLOCK)
5569 symbol *lsym = copySymbol (sym);
5571 lsym->next = AST_VALUES (tree, sym);
5572 AST_VALUES (tree, sym) = lsym;
5576 addSymToBlock (sym, tree->left);
5577 addSymToBlock (sym, tree->right);
5580 /*-----------------------------------------------------------------*/
5581 /* processRegParms - do processing for register parameters */
5582 /*-----------------------------------------------------------------*/
5584 processRegParms (value * args, ast * body)
5588 if (IS_REGPARM (args->etype))
5589 addSymToBlock (args->sym, body);
5594 /*-----------------------------------------------------------------*/
5595 /* resetParmKey - resets the operandkeys for the symbols */
5596 /*-----------------------------------------------------------------*/
5597 DEFSETFUNC (resetParmKey)
5608 /*-----------------------------------------------------------------*/
5609 /* createFunction - This is the key node that calls the iCode for */
5610 /* generating the code for a function. Note code */
5611 /* is generated function by function, later when */
5612 /* add inter-procedural analysis this will change */
5613 /*-----------------------------------------------------------------*/
5615 createFunction (symbol * name, ast * body)
5621 iCode *piCode = NULL;
5623 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5624 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5626 /* if check function return 0 then some problem */
5627 if (checkFunction (name, NULL) == 0)
5630 /* create a dummy block if none exists */
5632 body = newNode (BLOCK, NULL, NULL);
5636 /* check if the function name already in the symbol table */
5637 if ((csym = findSym (SymbolTab, NULL, name->name)))
5640 /* special case for compiler defined functions
5641 we need to add the name to the publics list : this
5642 actually means we are now compiling the compiler
5646 addSet (&publics, name);
5651 addSymChain (&name);
5652 allocVariables (name);
5654 name->lastLine = mylineno;
5657 /* set the stack pointer */
5658 stackPtr = -port->stack.direction * port->stack.call_overhead;
5661 if (IFFUNC_ISISR (name->type))
5662 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5664 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5666 if (options.useXstack)
5667 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5669 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5672 fetype = getSpec (name->type); /* get the specifier for the function */
5673 /* if this is a reentrant function then */
5674 if (IFFUNC_ISREENT (name->type))
5677 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5679 /* do processing for parameters that are passed in registers */
5680 processRegParms (FUNC_ARGS(name->type), body);
5682 /* set the stack pointer */
5686 /* allocate & autoinit the block variables */
5687 processBlockVars (body, &stack, ALLOCATE);
5689 /* save the stack information */
5690 if (options.useXstack)
5691 name->xstack = SPEC_STAK (fetype) = stack;
5693 name->stack = SPEC_STAK (fetype) = stack;
5695 /* name needs to be mangled */
5696 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5698 body = resolveSymbols (body); /* resolve the symbols */
5699 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5701 ex = newAst_VALUE (symbolVal (name)); /* create name */
5702 ex = newNode (FUNCTION, ex, body);
5703 ex->values.args = FUNC_ARGS(name->type);
5705 if (options.dump_tree) PA(ex);
5708 werror (E_FUNC_NO_CODE, name->name);
5712 /* create the node & generate intermediate code */
5714 codeOutFile = code->oFile;
5715 piCode = iCodeFromAst (ex);
5719 werror (E_FUNC_NO_CODE, name->name);
5723 eBBlockFromiCode (piCode);
5725 /* if there are any statics then do them */
5728 GcurMemmap = statsg;
5729 codeOutFile = statsg->oFile;
5730 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5736 /* dealloc the block variables */
5737 processBlockVars (body, &stack, DEALLOCATE);
5738 outputDebugStackSymbols();
5739 /* deallocate paramaters */
5740 deallocParms (FUNC_ARGS(name->type));
5742 if (IFFUNC_ISREENT (name->type))
5745 /* we are done freeup memory & cleanup */
5747 if (port->reset_labelKey) labelKey = 1;
5749 FUNC_HASBODY(name->type) = 1;
5750 addSet (&operKeyReset, name);
5751 applyToSet (operKeyReset, resetParmKey);
5756 cleanUpLevel (LabelTab, 0);
5757 cleanUpBlock (StructTab, 1);
5758 cleanUpBlock (TypedefTab, 1);
5760 xstack->syms = NULL;
5761 istack->syms = NULL;
5766 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5767 /*-----------------------------------------------------------------*/
5768 /* ast_print : prints the ast (for debugging purposes) */
5769 /*-----------------------------------------------------------------*/
5771 void ast_print (ast * tree, FILE *outfile, int indent)
5776 /* can print only decorated trees */
5777 if (!tree->decorated) return;
5779 /* if any child is an error | this one is an error do nothing */
5780 if (tree->isError ||
5781 (tree->left && tree->left->isError) ||
5782 (tree->right && tree->right->isError)) {
5783 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5787 /* print the line */
5788 /* if not block & function */
5789 if (tree->type == EX_OP &&
5790 (tree->opval.op != FUNCTION &&
5791 tree->opval.op != BLOCK &&
5792 tree->opval.op != NULLOP)) {
5795 if (tree->opval.op == FUNCTION) {
5797 value *args=FUNC_ARGS(tree->left->opval.val->type);
5798 fprintf(outfile,"FUNCTION (%s=%p) type (",
5799 tree->left->opval.val->name, tree);
5800 printTypeChain (tree->left->opval.val->type->next,outfile);
5801 fprintf(outfile,") args (");
5804 fprintf (outfile, ", ");
5806 printTypeChain (args ? args->type : NULL, outfile);
5808 args= args ? args->next : NULL;
5810 fprintf(outfile,")\n");
5811 ast_print(tree->left,outfile,indent);
5812 ast_print(tree->right,outfile,indent);
5815 if (tree->opval.op == BLOCK) {
5816 symbol *decls = tree->values.sym;
5817 INDENT(indent,outfile);
5818 fprintf(outfile,"{\n");
5820 INDENT(indent+2,outfile);
5821 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5822 decls->name, decls);
5823 printTypeChain(decls->type,outfile);
5824 fprintf(outfile,")\n");
5826 decls = decls->next;
5828 ast_print(tree->right,outfile,indent+2);
5829 INDENT(indent,outfile);
5830 fprintf(outfile,"}\n");
5833 if (tree->opval.op == NULLOP) {
5834 ast_print(tree->left,outfile,indent);
5835 ast_print(tree->right,outfile,indent);
5838 INDENT(indent,outfile);
5840 /*------------------------------------------------------------------*/
5841 /*----------------------------*/
5842 /* leaf has been reached */
5843 /*----------------------------*/
5844 /* if this is of type value */
5845 /* just get the type */
5846 if (tree->type == EX_VALUE) {
5848 if (IS_LITERAL (tree->opval.val->etype)) {
5849 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5850 if (SPEC_USIGN (tree->opval.val->etype))
5851 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5853 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5854 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5855 floatFromVal(tree->opval.val));
5856 } else if (tree->opval.val->sym) {
5857 /* if the undefined flag is set then give error message */
5858 if (tree->opval.val->sym->undefined) {
5859 fprintf(outfile,"UNDEFINED SYMBOL ");
5861 fprintf(outfile,"SYMBOL ");
5863 fprintf(outfile,"(%s=%p)",
5864 tree->opval.val->sym->name,tree);
5867 fprintf(outfile," type (");
5868 printTypeChain(tree->ftype,outfile);
5869 fprintf(outfile,")\n");
5871 fprintf(outfile,"\n");
5876 /* if type link for the case of cast */
5877 if (tree->type == EX_LINK) {
5878 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5879 printTypeChain(tree->opval.lnk,outfile);
5880 fprintf(outfile,")\n");
5885 /* depending on type of operator do */
5887 switch (tree->opval.op) {
5888 /*------------------------------------------------------------------*/
5889 /*----------------------------*/
5891 /*----------------------------*/
5893 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5894 printTypeChain(tree->ftype,outfile);
5895 fprintf(outfile,")\n");
5896 ast_print(tree->left,outfile,indent+2);
5897 ast_print(tree->right,outfile,indent+2);
5900 /*------------------------------------------------------------------*/
5901 /*----------------------------*/
5903 /*----------------------------*/
5905 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5906 printTypeChain(tree->ftype,outfile);
5907 fprintf(outfile,")\n");
5908 ast_print(tree->left,outfile,indent+2);
5909 ast_print(tree->right,outfile,indent+2);
5912 /*------------------------------------------------------------------*/
5913 /*----------------------------*/
5914 /* struct/union pointer */
5915 /*----------------------------*/
5917 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5918 printTypeChain(tree->ftype,outfile);
5919 fprintf(outfile,")\n");
5920 ast_print(tree->left,outfile,indent+2);
5921 ast_print(tree->right,outfile,indent+2);
5924 /*------------------------------------------------------------------*/
5925 /*----------------------------*/
5926 /* ++/-- operation */
5927 /*----------------------------*/
5930 fprintf(outfile,"post-");
5932 fprintf(outfile,"pre-");
5933 fprintf(outfile,"INC_OP (%p) type (",tree);
5934 printTypeChain(tree->ftype,outfile);
5935 fprintf(outfile,")\n");
5936 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5937 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5942 fprintf(outfile,"post-");
5944 fprintf(outfile,"pre-");
5945 fprintf(outfile,"DEC_OP (%p) type (",tree);
5946 printTypeChain(tree->ftype,outfile);
5947 fprintf(outfile,")\n");
5948 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5949 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5952 /*------------------------------------------------------------------*/
5953 /*----------------------------*/
5955 /*----------------------------*/
5958 fprintf(outfile,"& (%p) type (",tree);
5959 printTypeChain(tree->ftype,outfile);
5960 fprintf(outfile,")\n");
5961 ast_print(tree->left,outfile,indent+2);
5962 ast_print(tree->right,outfile,indent+2);
5964 fprintf(outfile,"ADDRESS_OF (%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 /*----------------------------*/
5973 /*----------------------------*/
5975 fprintf(outfile,"OR (%p) type (",tree);
5976 printTypeChain(tree->ftype,outfile);
5977 fprintf(outfile,")\n");
5978 ast_print(tree->left,outfile,indent+2);
5979 ast_print(tree->right,outfile,indent+2);
5981 /*------------------------------------------------------------------*/
5982 /*----------------------------*/
5984 /*----------------------------*/
5986 fprintf(outfile,"XOR (%p) type (",tree);
5987 printTypeChain(tree->ftype,outfile);
5988 fprintf(outfile,")\n");
5989 ast_print(tree->left,outfile,indent+2);
5990 ast_print(tree->right,outfile,indent+2);
5993 /*------------------------------------------------------------------*/
5994 /*----------------------------*/
5996 /*----------------------------*/
5998 fprintf(outfile,"DIV (%p) type (",tree);
5999 printTypeChain(tree->ftype,outfile);
6000 fprintf(outfile,")\n");
6001 ast_print(tree->left,outfile,indent+2);
6002 ast_print(tree->right,outfile,indent+2);
6004 /*------------------------------------------------------------------*/
6005 /*----------------------------*/
6007 /*----------------------------*/
6009 fprintf(outfile,"MOD (%p) type (",tree);
6010 printTypeChain(tree->ftype,outfile);
6011 fprintf(outfile,")\n");
6012 ast_print(tree->left,outfile,indent+2);
6013 ast_print(tree->right,outfile,indent+2);
6016 /*------------------------------------------------------------------*/
6017 /*----------------------------*/
6018 /* address dereference */
6019 /*----------------------------*/
6020 case '*': /* can be unary : if right is null then unary operation */
6022 fprintf(outfile,"DEREF (%p) type (",tree);
6023 printTypeChain(tree->ftype,outfile);
6024 fprintf(outfile,")\n");
6025 ast_print(tree->left,outfile,indent+2);
6028 /*------------------------------------------------------------------*/
6029 /*----------------------------*/
6030 /* multiplication */
6031 /*----------------------------*/
6032 fprintf(outfile,"MULT (%p) type (",tree);
6033 printTypeChain(tree->ftype,outfile);
6034 fprintf(outfile,")\n");
6035 ast_print(tree->left,outfile,indent+2);
6036 ast_print(tree->right,outfile,indent+2);
6040 /*------------------------------------------------------------------*/
6041 /*----------------------------*/
6042 /* unary '+' operator */
6043 /*----------------------------*/
6047 fprintf(outfile,"UPLUS (%p) type (",tree);
6048 printTypeChain(tree->ftype,outfile);
6049 fprintf(outfile,")\n");
6050 ast_print(tree->left,outfile,indent+2);
6052 /*------------------------------------------------------------------*/
6053 /*----------------------------*/
6055 /*----------------------------*/
6056 fprintf(outfile,"ADD (%p) type (",tree);
6057 printTypeChain(tree->ftype,outfile);
6058 fprintf(outfile,")\n");
6059 ast_print(tree->left,outfile,indent+2);
6060 ast_print(tree->right,outfile,indent+2);
6063 /*------------------------------------------------------------------*/
6064 /*----------------------------*/
6066 /*----------------------------*/
6067 case '-': /* can be unary */
6069 fprintf(outfile,"UMINUS (%p) type (",tree);
6070 printTypeChain(tree->ftype,outfile);
6071 fprintf(outfile,")\n");
6072 ast_print(tree->left,outfile,indent+2);
6074 /*------------------------------------------------------------------*/
6075 /*----------------------------*/
6077 /*----------------------------*/
6078 fprintf(outfile,"SUB (%p) type (",tree);
6079 printTypeChain(tree->ftype,outfile);
6080 fprintf(outfile,")\n");
6081 ast_print(tree->left,outfile,indent+2);
6082 ast_print(tree->right,outfile,indent+2);
6085 /*------------------------------------------------------------------*/
6086 /*----------------------------*/
6088 /*----------------------------*/
6090 fprintf(outfile,"COMPL (%p) type (",tree);
6091 printTypeChain(tree->ftype,outfile);
6092 fprintf(outfile,")\n");
6093 ast_print(tree->left,outfile,indent+2);
6095 /*------------------------------------------------------------------*/
6096 /*----------------------------*/
6098 /*----------------------------*/
6100 fprintf(outfile,"NOT (%p) type (",tree);
6101 printTypeChain(tree->ftype,outfile);
6102 fprintf(outfile,")\n");
6103 ast_print(tree->left,outfile,indent+2);
6105 /*------------------------------------------------------------------*/
6106 /*----------------------------*/
6108 /*----------------------------*/
6110 fprintf(outfile,"RRC (%p) type (",tree);
6111 printTypeChain(tree->ftype,outfile);
6112 fprintf(outfile,")\n");
6113 ast_print(tree->left,outfile,indent+2);
6117 fprintf(outfile,"RLC (%p) type (",tree);
6118 printTypeChain(tree->ftype,outfile);
6119 fprintf(outfile,")\n");
6120 ast_print(tree->left,outfile,indent+2);
6123 fprintf(outfile,"SWAP (%p) type (",tree);
6124 printTypeChain(tree->ftype,outfile);
6125 fprintf(outfile,")\n");
6126 ast_print(tree->left,outfile,indent+2);
6129 fprintf(outfile,"GETHBIT (%p) type (",tree);
6130 printTypeChain(tree->ftype,outfile);
6131 fprintf(outfile,")\n");
6132 ast_print(tree->left,outfile,indent+2);
6135 fprintf(outfile,"GETABIT (%p) type (",tree);
6136 printTypeChain(tree->ftype,outfile);
6137 fprintf(outfile,")\n");
6138 ast_print(tree->left,outfile,indent+2);
6139 ast_print(tree->right,outfile,indent+2);
6142 fprintf(outfile,"GETBYTE (%p) type (",tree);
6143 printTypeChain(tree->ftype,outfile);
6144 fprintf(outfile,")\n");
6145 ast_print(tree->left,outfile,indent+2);
6146 ast_print(tree->right,outfile,indent+2);
6149 fprintf(outfile,"GETWORD (%p) type (",tree);
6150 printTypeChain(tree->ftype,outfile);
6151 fprintf(outfile,")\n");
6152 ast_print(tree->left,outfile,indent+2);
6153 ast_print(tree->right,outfile,indent+2);
6156 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6157 printTypeChain(tree->ftype,outfile);
6158 fprintf(outfile,")\n");
6159 ast_print(tree->left,outfile,indent+2);
6160 ast_print(tree->right,outfile,indent+2);
6163 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6164 printTypeChain(tree->ftype,outfile);
6165 fprintf(outfile,")\n");
6166 ast_print(tree->left,outfile,indent+2);
6167 ast_print(tree->right,outfile,indent+2);
6169 /*------------------------------------------------------------------*/
6170 /*----------------------------*/
6172 /*----------------------------*/
6173 case CAST: /* change the type */
6174 fprintf(outfile,"CAST (%p) from type (",tree);
6175 printTypeChain(tree->right->ftype,outfile);
6176 fprintf(outfile,") to type (");
6177 printTypeChain(tree->ftype,outfile);
6178 fprintf(outfile,")\n");
6179 ast_print(tree->right,outfile,indent+2);
6183 fprintf(outfile,"ANDAND (%p) type (",tree);
6184 printTypeChain(tree->ftype,outfile);
6185 fprintf(outfile,")\n");
6186 ast_print(tree->left,outfile,indent+2);
6187 ast_print(tree->right,outfile,indent+2);
6190 fprintf(outfile,"OROR (%p) type (",tree);
6191 printTypeChain(tree->ftype,outfile);
6192 fprintf(outfile,")\n");
6193 ast_print(tree->left,outfile,indent+2);
6194 ast_print(tree->right,outfile,indent+2);
6197 /*------------------------------------------------------------------*/
6198 /*----------------------------*/
6199 /* comparison operators */
6200 /*----------------------------*/
6202 fprintf(outfile,"GT(>) (%p) type (",tree);
6203 printTypeChain(tree->ftype,outfile);
6204 fprintf(outfile,")\n");
6205 ast_print(tree->left,outfile,indent+2);
6206 ast_print(tree->right,outfile,indent+2);
6209 fprintf(outfile,"LT(<) (%p) type (",tree);
6210 printTypeChain(tree->ftype,outfile);
6211 fprintf(outfile,")\n");
6212 ast_print(tree->left,outfile,indent+2);
6213 ast_print(tree->right,outfile,indent+2);
6216 fprintf(outfile,"LE(<=) (%p) type (",tree);
6217 printTypeChain(tree->ftype,outfile);
6218 fprintf(outfile,")\n");
6219 ast_print(tree->left,outfile,indent+2);
6220 ast_print(tree->right,outfile,indent+2);
6223 fprintf(outfile,"GE(>=) (%p) type (",tree);
6224 printTypeChain(tree->ftype,outfile);
6225 fprintf(outfile,")\n");
6226 ast_print(tree->left,outfile,indent+2);
6227 ast_print(tree->right,outfile,indent+2);
6230 fprintf(outfile,"EQ(==) (%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,"NE(!=) (%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);
6242 /*------------------------------------------------------------------*/
6243 /*----------------------------*/
6245 /*----------------------------*/
6246 case SIZEOF: /* evaluate wihout code generation */
6247 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6250 /*------------------------------------------------------------------*/
6251 /*----------------------------*/
6252 /* conditional operator '?' */
6253 /*----------------------------*/
6255 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6256 printTypeChain(tree->ftype,outfile);
6257 fprintf(outfile,")\n");
6258 ast_print(tree->left,outfile,indent+2);
6259 ast_print(tree->right,outfile,indent+2);
6263 fprintf(outfile,"COLON(:) (%p) type (",tree);
6264 printTypeChain(tree->ftype,outfile);
6265 fprintf(outfile,")\n");
6266 ast_print(tree->left,outfile,indent+2);
6267 ast_print(tree->right,outfile,indent+2);
6270 /*------------------------------------------------------------------*/
6271 /*----------------------------*/
6272 /* assignment operators */
6273 /*----------------------------*/
6275 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6276 printTypeChain(tree->ftype,outfile);
6277 fprintf(outfile,")\n");
6278 ast_print(tree->left,outfile,indent+2);
6279 ast_print(tree->right,outfile,indent+2);
6282 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6283 printTypeChain(tree->ftype,outfile);
6284 fprintf(outfile,")\n");
6285 ast_print(tree->left,outfile,indent+2);
6286 ast_print(tree->right,outfile,indent+2);
6289 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6290 printTypeChain(tree->ftype,outfile);
6291 fprintf(outfile,")\n");
6292 ast_print(tree->left,outfile,indent+2);
6293 ast_print(tree->right,outfile,indent+2);
6296 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6297 printTypeChain(tree->ftype,outfile);
6298 fprintf(outfile,")\n");
6299 ast_print(tree->left,outfile,indent+2);
6300 ast_print(tree->right,outfile,indent+2);
6303 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6304 printTypeChain(tree->ftype,outfile);
6305 fprintf(outfile,")\n");
6306 ast_print(tree->left,outfile,indent+2);
6307 ast_print(tree->right,outfile,indent+2);
6310 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6311 printTypeChain(tree->ftype,outfile);
6312 fprintf(outfile,")\n");
6313 ast_print(tree->left,outfile,indent+2);
6314 ast_print(tree->right,outfile,indent+2);
6317 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6318 printTypeChain(tree->ftype,outfile);
6319 fprintf(outfile,")\n");
6320 ast_print(tree->left,outfile,indent+2);
6321 ast_print(tree->right,outfile,indent+2);
6323 /*------------------------------------------------------------------*/
6324 /*----------------------------*/
6326 /*----------------------------*/
6328 fprintf(outfile,"SUBASS(-=) (%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);
6334 /*------------------------------------------------------------------*/
6335 /*----------------------------*/
6337 /*----------------------------*/
6339 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6340 printTypeChain(tree->ftype,outfile);
6341 fprintf(outfile,")\n");
6342 ast_print(tree->left,outfile,indent+2);
6343 ast_print(tree->right,outfile,indent+2);
6345 /*------------------------------------------------------------------*/
6346 /*----------------------------*/
6347 /* straight assignemnt */
6348 /*----------------------------*/
6350 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6351 printTypeChain(tree->ftype,outfile);
6352 fprintf(outfile,")\n");
6353 ast_print(tree->left,outfile,indent+2);
6354 ast_print(tree->right,outfile,indent+2);
6356 /*------------------------------------------------------------------*/
6357 /*----------------------------*/
6358 /* comma operator */
6359 /*----------------------------*/
6361 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6362 printTypeChain(tree->ftype,outfile);
6363 fprintf(outfile,")\n");
6364 ast_print(tree->left,outfile,indent+2);
6365 ast_print(tree->right,outfile,indent+2);
6367 /*------------------------------------------------------------------*/
6368 /*----------------------------*/
6370 /*----------------------------*/
6373 fprintf(outfile,"CALL (%p) type (",tree);
6374 printTypeChain(tree->ftype,outfile);
6375 fprintf(outfile,")\n");
6376 ast_print(tree->left,outfile,indent+2);
6377 ast_print(tree->right,outfile,indent+2);
6380 fprintf(outfile,"PARMS\n");
6381 ast_print(tree->left,outfile,indent+2);
6382 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6383 ast_print(tree->right,outfile,indent+2);
6386 /*------------------------------------------------------------------*/
6387 /*----------------------------*/
6388 /* return statement */
6389 /*----------------------------*/
6391 fprintf(outfile,"RETURN (%p) type (",tree);
6393 printTypeChain(tree->right->ftype,outfile);
6395 fprintf(outfile,")\n");
6396 ast_print(tree->right,outfile,indent+2);
6398 /*------------------------------------------------------------------*/
6399 /*----------------------------*/
6400 /* label statement */
6401 /*----------------------------*/
6403 fprintf(outfile,"LABEL (%p)\n",tree);
6404 ast_print(tree->left,outfile,indent+2);
6405 ast_print(tree->right,outfile,indent);
6407 /*------------------------------------------------------------------*/
6408 /*----------------------------*/
6409 /* switch statement */
6410 /*----------------------------*/
6414 fprintf(outfile,"SWITCH (%p) ",tree);
6415 ast_print(tree->left,outfile,0);
6416 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6417 INDENT(indent+2,outfile);
6418 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6419 (int) floatFromVal(val),
6420 tree->values.switchVals.swNum,
6421 (int) floatFromVal(val));
6423 ast_print(tree->right,outfile,indent);
6426 /*------------------------------------------------------------------*/
6427 /*----------------------------*/
6429 /*----------------------------*/
6431 fprintf(outfile,"IF (%p) \n",tree);
6432 ast_print(tree->left,outfile,indent+2);
6433 if (tree->trueLabel) {
6434 INDENT(indent+2,outfile);
6435 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6437 if (tree->falseLabel) {
6438 INDENT(indent+2,outfile);
6439 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6441 ast_print(tree->right,outfile,indent+2);
6443 /*----------------------------*/
6444 /* goto Statement */
6445 /*----------------------------*/
6447 fprintf(outfile,"GOTO (%p) \n",tree);
6448 ast_print(tree->left,outfile,indent+2);
6449 fprintf(outfile,"\n");
6451 /*------------------------------------------------------------------*/
6452 /*----------------------------*/
6454 /*----------------------------*/
6456 fprintf(outfile,"FOR (%p) \n",tree);
6457 if (AST_FOR( tree, initExpr)) {
6458 INDENT(indent+2,outfile);
6459 fprintf(outfile,"INIT EXPR ");
6460 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6462 if (AST_FOR( tree, condExpr)) {
6463 INDENT(indent+2,outfile);
6464 fprintf(outfile,"COND EXPR ");
6465 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6467 if (AST_FOR( tree, loopExpr)) {
6468 INDENT(indent+2,outfile);
6469 fprintf(outfile,"LOOP EXPR ");
6470 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6472 fprintf(outfile,"FOR LOOP BODY \n");
6473 ast_print(tree->left,outfile,indent+2);
6476 fprintf(outfile,"CRITICAL (%p) \n",tree);
6477 ast_print(tree->left,outfile,indent+2);
6485 ast_print(t,stdout,0);
6490 /*-----------------------------------------------------------------*/
6491 /* astErrors : returns non-zero if errors present in tree */
6492 /*-----------------------------------------------------------------*/
6493 int astErrors(ast *t)
6502 if (t->type == EX_VALUE
6503 && t->opval.val->sym
6504 && t->opval.val->sym->undefined)
6507 errors += astErrors(t->left);
6508 errors += astErrors(t->right);