1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *);
59 ast *backPatchLabels (ast *, symbol *, symbol *);
62 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
67 printTypeChain (tree->ftype, stdout);
72 /*-----------------------------------------------------------------*/
73 /* newAst - creates a fresh node for an expression tree */
74 /*-----------------------------------------------------------------*/
76 newAst_ (unsigned type)
79 static int oldLineno = 0;
81 ex = Safe_alloc ( sizeof (ast));
84 ex->lineno = (noLineno ? oldLineno : mylineno);
85 ex->filename = currFname;
86 ex->level = NestLevel;
87 ex->block = currBlockno;
88 ex->initMode = inInitMode;
89 ex->seqPoint = seqPointNo;
94 newAst_VALUE (value * val)
96 ast *ex = newAst_ (EX_VALUE);
102 newAst_OP (unsigned op)
104 ast *ex = newAst_ (EX_OP);
110 newAst_LINK (sym_link * val)
112 ast *ex = newAst_ (EX_LINK);
117 /*-----------------------------------------------------------------*/
118 /* newNode - creates a new node */
119 /*-----------------------------------------------------------------*/
121 newNode (long op, ast * left, ast * right)
132 /*-----------------------------------------------------------------*/
133 /* newIfxNode - creates a new Ifx Node */
134 /*-----------------------------------------------------------------*/
136 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
140 /* if this is a literal then we already know the result */
141 if (condAst->etype && IS_LITERAL (condAst->etype))
143 /* then depending on the expression value */
144 if (floatFromVal (condAst->opval.val))
145 ifxNode = newNode (GOTO,
146 newAst_VALUE (symbolVal (trueLabel)),
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (falseLabel)),
155 ifxNode = newNode (IFX, condAst, NULL);
156 ifxNode->trueLabel = trueLabel;
157 ifxNode->falseLabel = falseLabel;
163 /*-----------------------------------------------------------------*/
164 /* copyAstValues - copies value portion of ast if needed */
165 /*-----------------------------------------------------------------*/
167 copyAstValues (ast * dest, ast * src)
169 switch (src->opval.op)
172 dest->values.sym = copySymbolChain (src->values.sym);
176 dest->values.switchVals.swVals =
177 copyValue (src->values.switchVals.swVals);
178 dest->values.switchVals.swDefault =
179 src->values.switchVals.swDefault;
180 dest->values.switchVals.swNum =
181 src->values.switchVals.swNum;
185 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
189 dest->values.constlist = copyLiteralList(src->values.constlist);
193 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
194 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
195 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
196 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
197 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
198 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
199 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
204 /*-----------------------------------------------------------------*/
205 /* copyAst - makes a copy of a given astession */
206 /*-----------------------------------------------------------------*/
215 dest = Safe_alloc ( sizeof (ast));
217 dest->type = src->type;
218 dest->lineno = src->lineno;
219 dest->level = src->level;
220 dest->funcName = src->funcName;
223 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
225 /* if this is a leaf */
227 if (src->type == EX_VALUE)
229 dest->opval.val = copyValue (src->opval.val);
234 if (src->type == EX_LINK)
236 dest->opval.lnk = copyLinkChain (src->opval.lnk);
240 dest->opval.op = src->opval.op;
242 /* if this is a node that has special values */
243 copyAstValues (dest, src);
245 dest->trueLabel = copySymbol (src->trueLabel);
246 dest->falseLabel = copySymbol (src->falseLabel);
247 dest->left = copyAst (src->left);
248 dest->right = copyAst (src->right);
254 /*-----------------------------------------------------------------*/
255 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
256 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
257 /*-----------------------------------------------------------------*/
258 ast *removeIncDecOps (ast * tree) {
260 // traverse the tree and remove inc/dec ops
265 if (tree->type == EX_OP &&
266 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
273 tree->left=removeIncDecOps(tree->left);
274 tree->right=removeIncDecOps(tree->right);
279 /*-----------------------------------------------------------------*/
280 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
281 /* "*++s += 3" -> "*++s = *++s + 3" */
282 /*-----------------------------------------------------------------*/
283 ast *removePreIncDecOps (ast * tree) {
285 // traverse the tree and remove pre-inc/dec ops
290 if (tree->type == EX_OP &&
291 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
296 tree->left=removePreIncDecOps(tree->left);
297 tree->right=removePreIncDecOps(tree->right);
302 /*-----------------------------------------------------------------*/
303 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
304 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
305 /*-----------------------------------------------------------------*/
306 ast *removePostIncDecOps (ast * tree) {
308 // traverse the tree and remove pre-inc/dec ops
313 if (tree->type == EX_OP &&
314 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
319 tree->left=removePostIncDecOps(tree->left);
320 tree->right=removePostIncDecOps(tree->right);
325 /*-----------------------------------------------------------------*/
326 /* hasSEFcalls - returns TRUE if tree has a function call */
327 /*-----------------------------------------------------------------*/
329 hasSEFcalls (ast * tree)
334 if (tree->type == EX_OP &&
335 (tree->opval.op == CALL ||
336 tree->opval.op == PCALL ||
337 tree->opval.op == '=' ||
338 tree->opval.op == INC_OP ||
339 tree->opval.op == DEC_OP))
342 return (hasSEFcalls (tree->left) |
343 hasSEFcalls (tree->right));
346 /*-----------------------------------------------------------------*/
347 /* isAstEqual - compares two asts & returns 1 if they are equal */
348 /*-----------------------------------------------------------------*/
350 isAstEqual (ast * t1, ast * t2)
359 if (t1->type != t2->type)
365 if (t1->opval.op != t2->opval.op)
367 return (isAstEqual (t1->left, t2->left) &&
368 isAstEqual (t1->right, t2->right));
372 if (t1->opval.val->sym)
374 if (!t2->opval.val->sym)
377 return isSymbolEqual (t1->opval.val->sym,
382 if (t2->opval.val->sym)
385 return (floatFromVal (t1->opval.val) ==
386 floatFromVal (t2->opval.val));
390 /* only compare these two types */
398 /*-----------------------------------------------------------------*/
399 /* resolveSymbols - resolve symbols from the symbol table */
400 /*-----------------------------------------------------------------*/
402 resolveSymbols (ast * tree)
404 /* walk the entire tree and check for values */
405 /* with symbols if we find one then replace */
406 /* symbol with that from the symbol table */
413 /* if not block & function */
414 if (tree->type == EX_OP &&
415 (tree->opval.op != FUNCTION &&
416 tree->opval.op != BLOCK &&
417 tree->opval.op != NULLOP))
419 filename = tree->filename;
420 lineno = tree->lineno;
424 /* make sure we resolve the true & false labels for ifx */
425 if (tree->type == EX_OP && tree->opval.op == IFX)
431 if ((csym = findSym (LabelTab, tree->trueLabel,
432 tree->trueLabel->name)))
433 tree->trueLabel = csym;
435 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
436 tree->trueLabel->name);
439 if (tree->falseLabel)
441 if ((csym = findSym (LabelTab,
443 tree->falseLabel->name)))
444 tree->falseLabel = csym;
446 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
447 tree->falseLabel->name);
452 /* if this is a label resolve it from the labelTab */
453 if (IS_AST_VALUE (tree) &&
454 tree->opval.val->sym &&
455 tree->opval.val->sym->islbl)
458 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
459 tree->opval.val->sym->name);
462 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
463 tree->opval.val->sym->name);
465 tree->opval.val->sym = csym;
467 goto resolveChildren;
470 /* do only for leafs */
471 if (IS_AST_VALUE (tree) &&
472 tree->opval.val->sym &&
473 !tree->opval.val->sym->implicit)
476 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
478 /* if found in the symbol table & they r not the same */
479 if (csym && tree->opval.val->sym != csym)
481 tree->opval.val->sym = csym;
482 tree->opval.val->type = csym->type;
483 tree->opval.val->etype = csym->etype;
486 /* if not found in the symbol table */
487 /* mark it as undefined assume it is */
488 /* an integer in data space */
489 if (!csym && !tree->opval.val->sym->implicit)
492 /* if this is a function name then */
493 /* mark it as returning an int */
496 tree->opval.val->sym->type = newLink (DECLARATOR);
497 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
498 tree->opval.val->sym->type->next =
499 tree->opval.val->sym->etype = newIntLink ();
500 tree->opval.val->etype = tree->opval.val->etype;
501 tree->opval.val->type = tree->opval.val->sym->type;
502 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
503 tree->opval.val->sym->name);
504 //tree->opval.val->sym->undefined = 1;
505 allocVariables (tree->opval.val->sym);
509 tree->opval.val->sym->undefined = 1;
510 tree->opval.val->type =
511 tree->opval.val->etype = newIntLink ();
512 tree->opval.val->sym->type =
513 tree->opval.val->sym->etype = newIntLink ();
519 resolveSymbols (tree->left);
520 resolveSymbols (tree->right);
525 /*-----------------------------------------------------------------*/
526 /* setAstLineno - walks a ast tree & sets the line number */
527 /*-----------------------------------------------------------------*/
528 int setAstLineno (ast * tree, int lineno)
533 tree->lineno = lineno;
534 setAstLineno (tree->left, lineno);
535 setAstLineno (tree->right, lineno);
539 /*-----------------------------------------------------------------*/
540 /* funcOfType :- function of type with name */
541 /*-----------------------------------------------------------------*/
543 funcOfType (char *name, sym_link * type, sym_link * argType,
547 /* create the symbol */
548 sym = newSymbol (name, 0);
550 /* setup return value */
551 sym->type = newLink (DECLARATOR);
552 DCL_TYPE (sym->type) = FUNCTION;
553 sym->type->next = copyLinkChain (type);
554 sym->etype = getSpec (sym->type);
555 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
557 /* if arguments required */
561 args = FUNC_ARGS(sym->type) = newValue ();
565 args->type = copyLinkChain (argType);
566 args->etype = getSpec (args->type);
567 SPEC_EXTR(args->etype)=1;
570 args = args->next = newValue ();
577 allocVariables (sym);
582 /*-----------------------------------------------------------------*/
583 /* funcOfTypeVarg :- function of type with name and argtype */
584 /*-----------------------------------------------------------------*/
586 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
591 /* create the symbol */
592 sym = newSymbol (name, 0);
594 /* setup return value */
595 sym->type = newLink (DECLARATOR);
596 DCL_TYPE (sym->type) = FUNCTION;
597 sym->type->next = typeFromStr(rtype);
598 sym->etype = getSpec (sym->type);
600 /* if arguments required */
603 args = FUNC_ARGS(sym->type) = newValue ();
605 for ( i = 0 ; i < nArgs ; i++ ) {
606 args->type = typeFromStr(atypes[i]);
607 args->etype = getSpec (args->type);
608 SPEC_EXTR(args->etype)=1;
609 if ((i + 1) == nArgs) break;
610 args = args->next = newValue ();
617 allocVariables (sym);
622 /*-----------------------------------------------------------------*/
623 /* reverseParms - will reverse a parameter tree */
624 /*-----------------------------------------------------------------*/
626 reverseParms (ast * ptree)
632 /* top down if we find a nonParm tree then quit */
633 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
636 ptree->left = ptree->right;
637 ptree->right = ttree;
638 reverseParms (ptree->left);
639 reverseParms (ptree->right);
645 /*-----------------------------------------------------------------*/
646 /* processParms - makes sure the parameters are okay and do some */
647 /* processing with them */
648 /*-----------------------------------------------------------------*/
650 processParms (ast *func,
653 int *parmNumber, /* unused, although updated */
656 RESULT_TYPE resultType;
659 /* if none of them exist */
660 if (!defParm && !actParm)
665 if (getenv("DEBUG_SANITY"))
667 fprintf (stderr, "processParms: %s ", defParm->name);
669 /* make sure the type is complete and sane */
670 checkTypeSanity(defParm->etype, defParm->name);
673 if (IS_CODEPTR (func->ftype))
674 functype = func->ftype->next;
676 functype = func->ftype;
678 /* if the function is being called via a pointer & */
679 /* it has not been defined a reentrant then we cannot */
680 /* have parameters */
681 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
683 werror (W_NONRENT_ARGS);
688 /* if defined parameters ended but actual parameters */
689 /* exist and this is not defined as a variable arg */
690 if (!defParm && actParm && !IFFUNC_HASVARARGS(functype))
692 werror (E_TOO_MANY_PARMS);
696 /* if defined parameters present but no actual parameters */
697 if (defParm && !actParm)
699 werror (E_TOO_FEW_PARMS);
703 /* if this is a PARAM node then match left & right */
704 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
706 actParm->decorated = 1;
707 return (processParms (func, defParm,
708 actParm->left, parmNumber, FALSE) ||
709 processParms (func, defParm ? defParm->next : NULL,
710 actParm->right, parmNumber, rightmost));
712 else if (defParm) /* not vararg */
714 /* If we have found a value node by following only right-hand links,
715 * then we know that there are no more values after us.
717 * Therefore, if there are more defined parameters, the caller didn't
720 if (rightmost && defParm->next)
722 werror (E_TOO_FEW_PARMS);
727 /* decorate parameter */
728 resultType = defParm ? getResultTypeFromType (defParm->etype) :
730 actParm = decorateType (actParm, resultType);
732 if (IS_VOID(actParm->ftype))
734 werror (E_VOID_VALUE_USED);
738 /* If this is a varargs function... */
739 if (!defParm && actParm && IFFUNC_HASVARARGS(functype))
744 if (IS_CAST_OP (actParm)
745 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
747 /* Parameter was explicitly typecast; don't touch it. */
751 ftype = actParm->ftype;
753 /* If it's a char, upcast to int. */
754 if (IS_INTEGRAL (ftype)
755 && (getSize (ftype) < (unsigned) INTSIZE))
757 newType = newAst_LINK(INTTYPE);
760 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
762 newType = newAst_LINK (copyLinkChain(ftype));
763 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
766 if (IS_AGGREGATE (ftype))
768 newType = newAst_LINK (copyLinkChain (ftype));
769 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
774 /* cast required; change this op to a cast. */
775 ast *parmCopy = resolveSymbols (copyAst (actParm));
777 actParm->type = EX_OP;
778 actParm->opval.op = CAST;
779 actParm->left = newType;
780 actParm->right = parmCopy;
781 actParm->decorated = 0; /* force typechecking */
782 decorateType (actParm, RESULT_TYPE_NONE);
787 /* if defined parameters ended but actual has not & */
789 if (!defParm && actParm &&
790 (options.stackAuto || IFFUNC_ISREENT (functype)))
793 resolveSymbols (actParm);
795 /* the parameter type must be at least castable */
796 if (compareType (defParm->type, actParm->ftype) == 0)
798 werror (E_INCOMPAT_TYPES);
799 printFromToType (actParm->ftype, defParm->type);
803 /* if the parameter is castable then add the cast */
804 if (compareType (defParm->type, actParm->ftype) < 0)
808 resultType = getResultTypeFromType (defParm->etype);
809 pTree = resolveSymbols (copyAst (actParm));
811 /* now change the current one to a cast */
812 actParm->type = EX_OP;
813 actParm->opval.op = CAST;
814 actParm->left = newAst_LINK (defParm->type);
815 actParm->right = pTree;
816 actParm->decorated = 0; /* force typechecking */
817 decorateType (actParm, resultType);
820 /* make a copy and change the regparm type to the defined parm */
821 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
822 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
823 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
828 /*-----------------------------------------------------------------*/
829 /* createIvalType - generates ival for basic types */
830 /*-----------------------------------------------------------------*/
832 createIvalType (ast * sym, sym_link * type, initList * ilist)
836 /* if initList is deep */
837 if (ilist->type == INIT_DEEP)
838 ilist = ilist->init.deep;
840 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
841 return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
844 /*-----------------------------------------------------------------*/
845 /* createIvalStruct - generates initial value for structures */
846 /*-----------------------------------------------------------------*/
848 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
855 sflds = SPEC_STRUCT (type)->fields;
856 if (ilist->type != INIT_DEEP)
858 werror (E_INIT_STRUCT, "");
862 iloop = ilist->init.deep;
864 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
866 /* if we have come to end */
870 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
871 lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
872 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
876 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
877 W_EXCESS_INITIALIZERS, "struct",
878 sym->opval.val->sym->name);
885 /*-----------------------------------------------------------------*/
886 /* createIvalArray - generates code for array initialization */
887 /*-----------------------------------------------------------------*/
889 createIvalArray (ast * sym, sym_link * type, initList * ilist)
893 int lcnt = 0, size = 0;
894 literalList *literalL;
896 /* take care of the special case */
897 /* array of characters can be init */
899 if (IS_CHAR (type->next))
900 if ((rast = createIvalCharPtr (sym,
902 decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
904 return decorateType (resolveSymbols (rast), RESULT_CHECK);
906 /* not the special case */
907 if (ilist->type != INIT_DEEP)
909 werror (E_INIT_STRUCT, "");
913 iloop = ilist->init.deep;
914 lcnt = DCL_ELEM (type);
916 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
920 aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
922 rast = newNode(ARRAYINIT, aSym, NULL);
923 rast->values.constlist = literalL;
925 // Make sure size is set to length of initializer list.
932 if (lcnt && size > lcnt)
934 // Array size was specified, and we have more initializers than needed.
935 char *name=sym->opval.val->sym->name;
936 int lineno=sym->opval.val->sym->lineDef;
937 char *filename=sym->opval.val->sym->fileDef;
939 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
948 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
949 aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
950 rast = createIval (aSym, type->next, iloop, rast);
951 iloop = (iloop ? iloop->next : NULL);
957 /* no of elements given and we */
958 /* have generated for all of them */
961 // there has to be a better way
962 char *name=sym->opval.val->sym->name;
963 int lineno=sym->opval.val->sym->lineDef;
964 char *filename=sym->opval.val->sym->fileDef;
965 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
972 /* if we have not been given a size */
973 if (!DCL_ELEM (type))
975 DCL_ELEM (type) = size;
978 return decorateType (resolveSymbols (rast), RESULT_CHECK);
982 /*-----------------------------------------------------------------*/
983 /* createIvalCharPtr - generates initial values for char pointers */
984 /*-----------------------------------------------------------------*/
986 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
990 /* if this is a pointer & right is a literal array then */
991 /* just assignment will do */
992 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
993 SPEC_SCLS (iexpr->etype) == S_CODE)
994 && IS_ARRAY (iexpr->ftype)))
995 return newNode ('=', sym, iexpr);
997 /* left side is an array so we have to assign each */
999 if ((IS_LITERAL (iexpr->etype) ||
1000 SPEC_SCLS (iexpr->etype) == S_CODE)
1001 && IS_ARRAY (iexpr->ftype))
1003 /* for each character generate an assignment */
1004 /* to the array element */
1005 char *s = SPEC_CVAL (iexpr->etype).v_char;
1007 int size = getSize (iexpr->ftype);
1008 int symsize = getSize (type);
1012 if (size>(symsize+1))
1013 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1014 "string", sym->opval.val->sym->name);
1018 for (i=0;i<size;i++)
1020 rast = newNode (NULLOP,
1024 newAst_VALUE (valueFromLit ((float) i))),
1025 newAst_VALUE (valueFromLit (*s))));
1029 // now WE don't need iexpr's symbol anymore
1030 freeStringSymbol(AST_SYMBOL(iexpr));
1032 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1038 /*-----------------------------------------------------------------*/
1039 /* createIvalPtr - generates initial value for pointers */
1040 /*-----------------------------------------------------------------*/
1042 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1048 if (ilist->type == INIT_DEEP)
1049 ilist = ilist->init.deep;
1051 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1053 /* if character pointer */
1054 if (IS_CHAR (type->next))
1055 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1058 return newNode ('=', sym, iexpr);
1061 /*-----------------------------------------------------------------*/
1062 /* createIval - generates code for initial value */
1063 /*-----------------------------------------------------------------*/
1065 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1072 /* if structure then */
1073 if (IS_STRUCT (type))
1074 rast = createIvalStruct (sym, type, ilist);
1076 /* if this is a pointer */
1078 rast = createIvalPtr (sym, type, ilist);
1080 /* if this is an array */
1081 if (IS_ARRAY (type))
1082 rast = createIvalArray (sym, type, ilist);
1084 /* if type is SPECIFIER */
1086 rast = createIvalType (sym, type, ilist);
1089 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1091 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1094 /*-----------------------------------------------------------------*/
1095 /* initAggregates - initialises aggregate variables with initv */
1096 /*-----------------------------------------------------------------*/
1097 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1098 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1101 /*-----------------------------------------------------------------*/
1102 /* gatherAutoInit - creates assignment expressions for initial */
1104 /*-----------------------------------------------------------------*/
1106 gatherAutoInit (symbol * autoChain)
1113 for (sym = autoChain; sym; sym = sym->next)
1116 /* resolve the symbols in the ival */
1118 resolveIvalSym (sym->ival, sym->type);
1120 /* if this is a static variable & has an */
1121 /* initial value the code needs to be lifted */
1122 /* here to the main portion since they can be */
1123 /* initialised only once at the start */
1124 if (IS_STATIC (sym->etype) && sym->ival &&
1125 SPEC_SCLS (sym->etype) != S_CODE)
1129 /* insert the symbol into the symbol table */
1130 /* with level = 0 & name = rname */
1131 newSym = copySymbol (sym);
1132 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1134 /* now lift the code to main */
1135 if (IS_AGGREGATE (sym->type)) {
1136 work = initAggregates (sym, sym->ival, NULL);
1138 if (getNelements(sym->type, sym->ival)>1) {
1139 werrorfl (sym->fileDef, sym->lineDef,
1140 W_EXCESS_INITIALIZERS, "scalar",
1143 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1144 list2expr (sym->ival));
1147 setAstLineno (work, sym->lineDef);
1151 staticAutos = newNode (NULLOP, staticAutos, work);
1158 /* if there is an initial value */
1159 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1161 initList *ilist=sym->ival;
1163 while (ilist->type == INIT_DEEP) {
1164 ilist = ilist->init.deep;
1167 /* update lineno for error msg */
1168 lineno=sym->lineDef;
1169 setAstLineno (ilist->init.node, lineno);
1171 if (IS_AGGREGATE (sym->type)) {
1172 work = initAggregates (sym, sym->ival, NULL);
1174 if (getNelements(sym->type, sym->ival)>1) {
1175 werrorfl (sym->fileDef, sym->lineDef,
1176 W_EXCESS_INITIALIZERS, "scalar",
1179 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1180 list2expr (sym->ival));
1184 setAstLineno (work, sym->lineDef);
1188 init = newNode (NULLOP, init, work);
1197 /*-----------------------------------------------------------------*/
1198 /* freeStringSymbol - delete a literal string if no more usage */
1199 /*-----------------------------------------------------------------*/
1200 void freeStringSymbol(symbol *sym) {
1201 /* make sure this is a literal string */
1202 assert (sym->isstrlit);
1203 if (--sym->isstrlit == 0) { // lower the usage count
1204 memmap *segment=SPEC_OCLS(sym->etype);
1206 deleteSetItem(&segment->syms, sym);
1211 /*-----------------------------------------------------------------*/
1212 /* stringToSymbol - creates a symbol from a literal string */
1213 /*-----------------------------------------------------------------*/
1215 stringToSymbol (value * val)
1217 char name[SDCC_NAME_MAX + 1];
1218 static int charLbl = 0;
1223 // have we heard this before?
1224 for (sp=statsg->syms; sp; sp=sp->next) {
1226 size = getSize (sym->type);
1227 if (sym->isstrlit && size == getSize (val->type) &&
1228 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1229 // yes, this is old news. Don't publish it again.
1230 sym->isstrlit++; // but raise the usage count
1231 return symbolVal(sym);
1235 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1236 sym = newSymbol (name, 0); /* make it @ level 0 */
1237 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1239 /* copy the type from the value passed */
1240 sym->type = copyLinkChain (val->type);
1241 sym->etype = getSpec (sym->type);
1242 /* change to storage class & output class */
1243 SPEC_SCLS (sym->etype) = S_CODE;
1244 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1245 SPEC_STAT (sym->etype) = 1;
1246 /* make the level & block = 0 */
1247 sym->block = sym->level = 0;
1249 /* create an ival */
1250 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1255 allocVariables (sym);
1258 return symbolVal (sym);
1262 /*-----------------------------------------------------------------*/
1263 /* processBlockVars - will go thru the ast looking for block if */
1264 /* a block is found then will allocate the syms */
1265 /* will also gather the auto inits present */
1266 /*-----------------------------------------------------------------*/
1268 processBlockVars (ast * tree, int *stack, int action)
1273 /* if this is a block */
1274 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1278 if (action == ALLOCATE)
1280 *stack += allocVariables (tree->values.sym);
1281 autoInit = gatherAutoInit (tree->values.sym);
1283 /* if there are auto inits then do them */
1285 tree->left = newNode (NULLOP, autoInit, tree->left);
1287 else /* action is deallocate */
1288 deallocLocal (tree->values.sym);
1291 processBlockVars (tree->left, stack, action);
1292 processBlockVars (tree->right, stack, action);
1297 /*-------------------------------------------------------------*/
1298 /* constExprTree - returns TRUE if this tree is a constant */
1300 /*-------------------------------------------------------------*/
1301 bool constExprTree (ast *cexpr) {
1307 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1309 switch (cexpr->type)
1312 if (IS_AST_LIT_VALUE(cexpr)) {
1313 // this is a literal
1316 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1317 // a function's address will never change
1320 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1321 // an array's address will never change
1324 if (IS_AST_SYM_VALUE(cexpr) &&
1325 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1326 // a symbol in code space will never change
1327 // This is only for the 'char *s="hallo"' case and will have to leave
1328 //printf(" code space symbol");
1333 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1334 "unexpected link in expression tree\n");
1337 if (cexpr->opval.op==ARRAYINIT) {
1338 // this is a list of literals
1341 if (cexpr->opval.op=='=') {
1342 return constExprTree(cexpr->right);
1344 if (cexpr->opval.op==CAST) {
1345 // cast ignored, maybe we should throw a warning here?
1346 return constExprTree(cexpr->right);
1348 if (cexpr->opval.op=='&') {
1351 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1354 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1359 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1364 /*-----------------------------------------------------------------*/
1365 /* constExprValue - returns the value of a constant expression */
1366 /* or NULL if it is not a constant expression */
1367 /*-----------------------------------------------------------------*/
1369 constExprValue (ast * cexpr, int check)
1371 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1373 /* if this is not a constant then */
1374 if (!IS_LITERAL (cexpr->ftype))
1376 /* then check if this is a literal array
1378 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1379 SPEC_CVAL (cexpr->etype).v_char &&
1380 IS_ARRAY (cexpr->ftype))
1382 value *val = valFromType (cexpr->ftype);
1383 SPEC_SCLS (val->etype) = S_LITERAL;
1384 val->sym = cexpr->opval.val->sym;
1385 val->sym->type = copyLinkChain (cexpr->ftype);
1386 val->sym->etype = getSpec (val->sym->type);
1387 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1391 /* if we are casting a literal value then */
1392 if (IS_AST_OP (cexpr) &&
1393 cexpr->opval.op == CAST &&
1394 IS_LITERAL (cexpr->right->ftype))
1396 return valCastLiteral (cexpr->ftype,
1397 floatFromVal (cexpr->right->opval.val));
1400 if (IS_AST_VALUE (cexpr))
1402 return cexpr->opval.val;
1406 werror (E_CONST_EXPECTED, "found expression");
1411 /* return the value */
1412 return cexpr->opval.val;
1416 /*-----------------------------------------------------------------*/
1417 /* isLabelInAst - will return true if a given label is found */
1418 /*-----------------------------------------------------------------*/
1420 isLabelInAst (symbol * label, ast * tree)
1422 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1425 if (IS_AST_OP (tree) &&
1426 tree->opval.op == LABEL &&
1427 isSymbolEqual (AST_SYMBOL (tree->left), label))
1430 return isLabelInAst (label, tree->right) &&
1431 isLabelInAst (label, tree->left);
1435 /*-----------------------------------------------------------------*/
1436 /* isLoopCountable - return true if the loop count can be determi- */
1437 /* -ned at compile time . */
1438 /*-----------------------------------------------------------------*/
1440 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1441 symbol ** sym, ast ** init, ast ** end)
1444 /* the loop is considered countable if the following
1445 conditions are true :-
1447 a) initExpr :- <sym> = <const>
1448 b) condExpr :- <sym> < <const1>
1449 c) loopExpr :- <sym> ++
1452 /* first check the initExpr */
1453 if (IS_AST_OP (initExpr) &&
1454 initExpr->opval.op == '=' && /* is assignment */
1455 IS_AST_SYM_VALUE (initExpr->left))
1456 { /* left is a symbol */
1458 *sym = AST_SYMBOL (initExpr->left);
1459 *init = initExpr->right;
1464 /* for now the symbol has to be of
1466 if (!IS_INTEGRAL ((*sym)->type))
1469 /* now check condExpr */
1470 if (IS_AST_OP (condExpr))
1473 switch (condExpr->opval.op)
1476 if (IS_AST_SYM_VALUE (condExpr->left) &&
1477 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1478 IS_AST_LIT_VALUE (condExpr->right))
1480 *end = condExpr->right;
1486 if (IS_AST_OP (condExpr->left) &&
1487 condExpr->left->opval.op == '>' &&
1488 IS_AST_LIT_VALUE (condExpr->left->right) &&
1489 IS_AST_SYM_VALUE (condExpr->left->left) &&
1490 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1493 *end = newNode ('+', condExpr->left->right,
1494 newAst_VALUE (constVal ("1")));
1505 /* check loop expression is of the form <sym>++ */
1506 if (!IS_AST_OP (loopExpr))
1509 /* check if <sym> ++ */
1510 if (loopExpr->opval.op == INC_OP)
1516 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1517 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1524 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1525 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1533 if (loopExpr->opval.op == ADD_ASSIGN)
1536 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1537 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1538 IS_AST_LIT_VALUE (loopExpr->right) &&
1539 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1547 /*-----------------------------------------------------------------*/
1548 /* astHasVolatile - returns true if ast contains any volatile */
1549 /*-----------------------------------------------------------------*/
1551 astHasVolatile (ast * tree)
1556 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1559 if (IS_AST_OP (tree))
1560 return astHasVolatile (tree->left) ||
1561 astHasVolatile (tree->right);
1566 /*-----------------------------------------------------------------*/
1567 /* astHasPointer - return true if the ast contains any ptr variable */
1568 /*-----------------------------------------------------------------*/
1570 astHasPointer (ast * tree)
1575 if (IS_AST_LINK (tree))
1578 /* if we hit an array expression then check
1579 only the left side */
1580 if (IS_AST_OP (tree) && tree->opval.op == '[')
1581 return astHasPointer (tree->left);
1583 if (IS_AST_VALUE (tree))
1584 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1586 return astHasPointer (tree->left) ||
1587 astHasPointer (tree->right);
1591 /*-----------------------------------------------------------------*/
1592 /* astHasSymbol - return true if the ast has the given symbol */
1593 /*-----------------------------------------------------------------*/
1595 astHasSymbol (ast * tree, symbol * sym)
1597 if (!tree || IS_AST_LINK (tree))
1600 if (IS_AST_VALUE (tree))
1602 if (IS_AST_SYM_VALUE (tree))
1603 return isSymbolEqual (AST_SYMBOL (tree), sym);
1608 return astHasSymbol (tree->left, sym) ||
1609 astHasSymbol (tree->right, sym);
1612 /*-----------------------------------------------------------------*/
1613 /* astHasDeref - return true if the ast has an indirect access */
1614 /*-----------------------------------------------------------------*/
1616 astHasDeref (ast * tree)
1618 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1621 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1623 return astHasDeref (tree->left) || astHasDeref (tree->right);
1626 /*-----------------------------------------------------------------*/
1627 /* isConformingBody - the loop body has to conform to a set of rules */
1628 /* for the loop to be considered reversible read on for rules */
1629 /*-----------------------------------------------------------------*/
1631 isConformingBody (ast * pbody, symbol * sym, ast * body)
1634 /* we are going to do a pre-order traversal of the
1635 tree && check for the following conditions. (essentially
1636 a set of very shallow tests )
1637 a) the sym passed does not participate in
1638 any arithmetic operation
1639 b) There are no function calls
1640 c) all jumps are within the body
1641 d) address of loop control variable not taken
1642 e) if an assignment has a pointer on the
1643 left hand side make sure right does not have
1644 loop control variable */
1646 /* if we reach the end or a leaf then true */
1647 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1650 /* if anything else is "volatile" */
1651 if (IS_VOLATILE (TETYPE (pbody)))
1654 /* we will walk the body in a pre-order traversal for
1656 switch (pbody->opval.op)
1658 /*------------------------------------------------------------------*/
1660 // if the loopvar is used as an index
1661 if (astHasSymbol(pbody->right, sym)) {
1664 return isConformingBody (pbody->right, sym, body);
1666 /*------------------------------------------------------------------*/
1671 /*------------------------------------------------------------------*/
1675 /* sure we are not sym is not modified */
1677 IS_AST_SYM_VALUE (pbody->left) &&
1678 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1682 IS_AST_SYM_VALUE (pbody->right) &&
1683 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1688 /*------------------------------------------------------------------*/
1690 case '*': /* can be unary : if right is null then unary operation */
1695 /* if right is NULL then unary operation */
1696 /*------------------------------------------------------------------*/
1697 /*----------------------------*/
1699 /*----------------------------*/
1702 if (IS_AST_SYM_VALUE (pbody->left) &&
1703 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1706 return isConformingBody (pbody->left, sym, body);
1710 if (astHasSymbol (pbody->left, sym) ||
1711 astHasSymbol (pbody->right, sym))
1716 /*------------------------------------------------------------------*/
1724 if (IS_AST_SYM_VALUE (pbody->left) &&
1725 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1728 if (IS_AST_SYM_VALUE (pbody->right) &&
1729 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1732 return isConformingBody (pbody->left, sym, body) &&
1733 isConformingBody (pbody->right, sym, body);
1741 if (IS_AST_SYM_VALUE (pbody->left) &&
1742 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1744 return isConformingBody (pbody->left, sym, body);
1746 /*------------------------------------------------------------------*/
1758 case SIZEOF: /* evaluate wihout code generation */
1760 if (IS_AST_SYM_VALUE (pbody->left) &&
1761 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1764 if (IS_AST_SYM_VALUE (pbody->right) &&
1765 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1768 return isConformingBody (pbody->left, sym, body) &&
1769 isConformingBody (pbody->right, sym, body);
1771 /*------------------------------------------------------------------*/
1774 /* if left has a pointer & right has loop
1775 control variable then we cannot */
1776 if (astHasPointer (pbody->left) &&
1777 astHasSymbol (pbody->right, sym))
1779 if (astHasVolatile (pbody->left))
1782 if (IS_AST_SYM_VALUE (pbody->left)) {
1783 // if the loopvar has an assignment
1784 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1786 // if the loopvar is used in another (maybe conditional) block
1787 if (astHasSymbol (pbody->right, sym) &&
1788 (pbody->level >= body->level)) {
1793 if (astHasVolatile (pbody->left))
1796 if (astHasDeref(pbody->right)) return FALSE;
1798 return isConformingBody (pbody->left, sym, body) &&
1799 isConformingBody (pbody->right, sym, body);
1810 assert ("Parser should not have generated this\n");
1812 /*------------------------------------------------------------------*/
1813 /*----------------------------*/
1814 /* comma operator */
1815 /*----------------------------*/
1817 return isConformingBody (pbody->left, sym, body) &&
1818 isConformingBody (pbody->right, sym, body);
1820 /*------------------------------------------------------------------*/
1821 /*----------------------------*/
1823 /*----------------------------*/
1825 /* if local & not passed as paramater then ok */
1826 if (sym->level && !astHasSymbol(pbody->right,sym))
1830 /*------------------------------------------------------------------*/
1831 /*----------------------------*/
1832 /* return statement */
1833 /*----------------------------*/
1838 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1843 if (astHasSymbol (pbody->left, sym))
1850 return isConformingBody (pbody->left, sym, body) &&
1851 isConformingBody (pbody->right, sym, body);
1857 /*-----------------------------------------------------------------*/
1858 /* isLoopReversible - takes a for loop as input && returns true */
1859 /* if the for loop is reversible. If yes will set the value of */
1860 /* the loop control var & init value & termination value */
1861 /*-----------------------------------------------------------------*/
1863 isLoopReversible (ast * loop, symbol ** loopCntrl,
1864 ast ** init, ast ** end)
1866 /* if option says don't do it then don't */
1867 if (optimize.noLoopReverse)
1869 /* there are several tests to determine this */
1871 /* for loop has to be of the form
1872 for ( <sym> = <const1> ;
1873 [<sym> < <const2>] ;
1874 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1876 if (!isLoopCountable (AST_FOR (loop, initExpr),
1877 AST_FOR (loop, condExpr),
1878 AST_FOR (loop, loopExpr),
1879 loopCntrl, init, end))
1882 /* now do some serious checking on the body of the loop
1885 return isConformingBody (loop->left, *loopCntrl, loop->left);
1889 /*-----------------------------------------------------------------*/
1890 /* replLoopSym - replace the loop sym by loop sym -1 */
1891 /*-----------------------------------------------------------------*/
1893 replLoopSym (ast * body, symbol * sym)
1896 if (!body || IS_AST_LINK (body))
1899 if (IS_AST_SYM_VALUE (body))
1902 if (isSymbolEqual (AST_SYMBOL (body), sym))
1906 body->opval.op = '-';
1907 body->left = newAst_VALUE (symbolVal (sym));
1908 body->right = newAst_VALUE (constVal ("1"));
1916 replLoopSym (body->left, sym);
1917 replLoopSym (body->right, sym);
1921 /*-----------------------------------------------------------------*/
1922 /* reverseLoop - do the actual loop reversal */
1923 /*-----------------------------------------------------------------*/
1925 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1929 /* create the following tree
1934 if (sym) goto for_continue ;
1937 /* put it together piece by piece */
1938 rloop = newNode (NULLOP,
1939 createIf (newAst_VALUE (symbolVal (sym)),
1941 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1944 newAst_VALUE (symbolVal (sym)),
1947 replLoopSym (loop->left, sym);
1948 setAstLineno (rloop, init->lineno);
1950 rloop = newNode (NULLOP,
1952 newAst_VALUE (symbolVal (sym)),
1953 newNode ('-', end, init)),
1954 createLabel (AST_FOR (loop, continueLabel),
1958 newNode (SUB_ASSIGN,
1959 newAst_VALUE (symbolVal (sym)),
1960 newAst_VALUE (constVal ("1"))),
1963 rloop->lineno=init->lineno;
1964 return decorateType (rloop, RESULT_CHECK);
1968 /*-----------------------------------------------------------------*/
1969 /* searchLitOp - search tree (*ops only) for an ast with literal */
1970 /*-----------------------------------------------------------------*/
1972 searchLitOp (ast *tree, ast **parent, const char *ops)
1976 if (tree && optimize.global_cse)
1978 /* is there a literal operand? */
1980 IS_AST_OP(tree->right) &&
1981 tree->right->right &&
1982 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1984 if (IS_LITERAL (RTYPE (tree->right)) !=
1985 IS_LITERAL (LTYPE (tree->right)))
1987 tree->right->decorated = 0;
1988 tree->decorated = 0;
1992 ret = searchLitOp (tree->right, parent, ops);
1997 IS_AST_OP(tree->left) &&
1998 tree->left->right &&
1999 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
2001 if (IS_LITERAL (RTYPE (tree->left)) !=
2002 IS_LITERAL (LTYPE (tree->left)))
2004 tree->left->decorated = 0;
2005 tree->decorated = 0;
2009 ret = searchLitOp (tree->left, parent, ops);
2017 /*-----------------------------------------------------------------*/
2018 /* getResultFromType */
2019 /*-----------------------------------------------------------------*/
2021 getResultTypeFromType (sym_link *type)
2023 /* type = getSpec (type); */
2025 return RESULT_TYPE_BIT;
2026 if (IS_BITFIELD (type))
2028 int blen = SPEC_BLEN (type);
2031 return RESULT_TYPE_BIT;
2033 return RESULT_TYPE_CHAR;
2034 return RESULT_TYPE_INT;
2037 return RESULT_TYPE_CHAR;
2040 return RESULT_TYPE_INT;
2041 return RESULT_TYPE_OTHER;
2044 /*-----------------------------------------------------------------*/
2045 /* addCast - adds casts to a type specified by RESULT_TYPE */
2046 /*-----------------------------------------------------------------*/
2048 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2051 bool upCasted = FALSE;
2055 case RESULT_TYPE_NONE:
2056 /* char: promote to int */
2058 getSize (tree->etype) >= INTSIZE)
2060 newLink = newIntLink();
2063 case RESULT_TYPE_CHAR:
2064 if (IS_CHAR (tree->etype))
2066 newLink = newCharLink();
2068 case RESULT_TYPE_INT:
2070 if (getSize (tree->etype) > INTSIZE)
2072 /* warn ("Loosing significant digits"); */
2076 /* char: promote to int */
2078 getSize (tree->etype) >= INTSIZE)
2080 newLink = newIntLink();
2083 case RESULT_TYPE_OTHER:
2086 /* return type is long, float: promote char to int */
2087 if (getSize (tree->etype) >= INTSIZE)
2089 newLink = newIntLink();
2095 tree->decorated = 0;
2096 tree = newNode (CAST, newAst_LINK (newLink), tree);
2097 tree->lineno = tree->right->lineno;
2098 /* keep unsigned type during cast to smaller type,
2099 but not when promoting from char to int */
2101 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2102 return decorateType (tree, resultType);
2105 /*-----------------------------------------------------------------*/
2106 /* resultTypePropagate - decides if resultType can be propagated */
2107 /*-----------------------------------------------------------------*/
2109 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2111 switch (tree->opval.op)
2126 return RESULT_TYPE_NONE;
2130 return RESULT_TYPE_IFX;
2132 return RESULT_TYPE_NONE;
2136 /*-----------------------------------------------------------------*/
2137 /* getLeftResultType - gets type from left branch for propagation */
2138 /*-----------------------------------------------------------------*/
2140 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2142 switch (tree->opval.op)
2146 if (IS_PTR (LTYPE (tree)))
2147 return RESULT_TYPE_NONE;
2149 return getResultTypeFromType (LETYPE (tree));
2151 if (IS_PTR (currFunc->type->next))
2152 return RESULT_TYPE_NONE;
2154 return getResultTypeFromType (currFunc->type->next);
2156 if (!IS_ARRAY (LTYPE (tree)))
2158 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2159 return RESULT_TYPE_CHAR;
2166 /*--------------------------------------------------------------------*/
2167 /* decorateType - compute type for this tree, also does type checking.*/
2168 /* This is done bottom up, since type has to flow upwards. */
2169 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2170 /* result is a char and the operand(s) are int's. */
2171 /* It also does constant folding, and parameter checking. */
2172 /*--------------------------------------------------------------------*/
2174 decorateType (ast * tree, RESULT_TYPE resultType)
2178 RESULT_TYPE resultTypeProp;
2183 /* if already has type then do nothing */
2184 if (tree->decorated)
2187 tree->decorated = 1;
2190 /* print the line */
2191 /* if not block & function */
2192 if (tree->type == EX_OP &&
2193 (tree->opval.op != FUNCTION &&
2194 tree->opval.op != BLOCK &&
2195 tree->opval.op != NULLOP))
2197 filename = tree->filename;
2198 lineno = tree->lineno;
2202 /* if any child is an error | this one is an error do nothing */
2203 if (tree->isError ||
2204 (tree->left && tree->left->isError) ||
2205 (tree->right && tree->right->isError))
2208 /*------------------------------------------------------------------*/
2209 /*----------------------------*/
2210 /* leaf has been reached */
2211 /*----------------------------*/
2212 lineno=tree->lineno;
2213 /* if this is of type value */
2214 /* just get the type */
2215 if (tree->type == EX_VALUE)
2218 if (IS_LITERAL (tree->opval.val->etype))
2221 /* if this is a character array then declare it */
2222 if (IS_ARRAY (tree->opval.val->type))
2223 tree->opval.val = stringToSymbol (tree->opval.val);
2225 /* otherwise just copy the type information */
2226 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2230 if (tree->opval.val->sym)
2232 /* if the undefined flag is set then give error message */
2233 if (tree->opval.val->sym->undefined)
2235 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2237 TTYPE (tree) = TETYPE (tree) =
2238 tree->opval.val->type = tree->opval.val->sym->type =
2239 tree->opval.val->etype = tree->opval.val->sym->etype =
2240 copyLinkChain (INTTYPE);
2245 /* if impilicit i.e. struct/union member then no type */
2246 if (tree->opval.val->sym->implicit)
2247 TTYPE (tree) = TETYPE (tree) = NULL;
2252 /* else copy the type */
2253 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2255 /* and mark it as referenced */
2256 tree->opval.val->sym->isref = 1;
2264 /* if type link for the case of cast */
2265 if (tree->type == EX_LINK)
2267 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2275 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2277 if (tree->left && tree->left->type == EX_OPERAND
2278 && (tree->left->opval.op == INC_OP
2279 || tree->left->opval.op == DEC_OP)
2280 && tree->left->left)
2282 tree->left->right = tree->left->left;
2283 tree->left->left = NULL;
2285 if (tree->right && tree->right->type == EX_OPERAND
2286 && (tree->right->opval.op == INC_OP
2287 || tree->right->opval.op == DEC_OP)
2288 && tree->right->left)
2290 tree->right->right = tree->right->left;
2291 tree->right->left = NULL;
2296 /* Before decorating the left branch we've to decide in dependence
2297 upon tree->opval.op, if resultType can be propagated */
2298 resultTypeProp = resultTypePropagate (tree, resultType);
2300 if (tree->opval.op == '?')
2301 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2303 dtl = decorateType (tree->left, resultTypeProp);
2305 /* if an array node, we may need to swap branches */
2306 if (tree->opval.op == '[')
2308 /* determine which is the array & which the index */
2309 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2310 IS_INTEGRAL (LTYPE (tree)))
2312 ast *tempTree = tree->left;
2313 tree->left = tree->right;
2314 tree->right = tempTree;
2318 /* After decorating the left branch there's type information available
2319 in tree->left->?type. If the op is e.g. '=' we extract the type
2320 information from there and propagate it to the right branch. */
2321 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2323 switch (tree->opval.op)
2326 /* delay right side for '?' operator since conditional macro
2327 expansions might rely on this */
2331 /* decorate right side for CALL (parameter list) in processParms();
2332 there is resultType available */
2336 dtr = decorateType (tree->right, resultTypeProp);
2340 /* this is to take care of situations
2341 when the tree gets rewritten */
2342 if (dtl != tree->left)
2344 if (dtr != tree->right)
2346 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2350 /* depending on type of operator do */
2352 switch (tree->opval.op)
2354 /*------------------------------------------------------------------*/
2355 /*----------------------------*/
2357 /*----------------------------*/
2360 /* first check if this is a array or a pointer */
2361 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2363 werror (E_NEED_ARRAY_PTR, "[]");
2364 goto errorTreeReturn;
2367 /* check if the type of the idx */
2368 if (!IS_INTEGRAL (RTYPE (tree)))
2370 werror (E_IDX_NOT_INT);
2371 goto errorTreeReturn;
2374 /* if the left is an rvalue then error */
2377 werror (E_LVALUE_REQUIRED, "array access");
2378 goto errorTreeReturn;
2381 if (IS_LITERAL (RTYPE (tree)))
2383 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2384 int arraySize = DCL_ELEM (LTYPE (tree));
2385 if (arraySize && arrayIndex >= arraySize)
2387 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2392 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2395 /*------------------------------------------------------------------*/
2396 /*----------------------------*/
2398 /*----------------------------*/
2400 /* if this is not a structure */
2401 if (!IS_STRUCT (LTYPE (tree)))
2403 werror (E_STRUCT_UNION, ".");
2404 goto errorTreeReturn;
2406 TTYPE (tree) = structElemType (LTYPE (tree),
2407 (tree->right->type == EX_VALUE ?
2408 tree->right->opval.val : NULL));
2409 TETYPE (tree) = getSpec (TTYPE (tree));
2412 /*------------------------------------------------------------------*/
2413 /*----------------------------*/
2414 /* struct/union pointer */
2415 /*----------------------------*/
2417 /* if not pointer to a structure */
2418 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2420 werror (E_PTR_REQD);
2421 goto errorTreeReturn;
2424 if (!IS_STRUCT (LTYPE (tree)->next))
2426 werror (E_STRUCT_UNION, "->");
2427 goto errorTreeReturn;
2430 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2431 (tree->right->type == EX_VALUE ?
2432 tree->right->opval.val : NULL));
2433 TETYPE (tree) = getSpec (TTYPE (tree));
2435 /* adjust the storage class */
2436 switch (DCL_TYPE(tree->left->ftype)) {
2438 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2441 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2444 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2447 SPEC_SCLS (TETYPE (tree)) = 0;
2450 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2453 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2456 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2459 SPEC_SCLS (TETYPE (tree)) = 0;
2466 /* This breaks with extern declarations, bitfields, and perhaps other */
2467 /* cases (gcse). Let's leave this optimization disabled for now and */
2468 /* ponder if there's a safe way to do this. -- EEP */
2470 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2471 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2473 /* If defined struct type at addr var
2474 then rewrite (&struct var)->member
2476 and define membertype at (addr+offsetof(struct var,member)) temp
2479 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2480 AST_SYMBOL(tree->right));
2482 sym = newSymbol(genSymName (0), 0);
2483 sym->type = TTYPE (tree);
2484 sym->etype = getSpec(sym->type);
2485 sym->lineDef = tree->lineno;
2488 SPEC_STAT (sym->etype) = 1;
2489 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2491 SPEC_ABSA(sym->etype) = 1;
2492 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2495 AST_VALUE (tree) = symbolVal(sym);
2498 tree->type = EX_VALUE;
2506 /*------------------------------------------------------------------*/
2507 /*----------------------------*/
2508 /* ++/-- operation */
2509 /*----------------------------*/
2513 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2514 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2515 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2516 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2525 /*------------------------------------------------------------------*/
2526 /*----------------------------*/
2528 /*----------------------------*/
2529 case '&': /* can be unary */
2530 /* if right is NULL then unary operation */
2531 if (tree->right) /* not an unary operation */
2534 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2536 werror (E_BITWISE_OP);
2537 werror (W_CONTINUE, "left & right types are ");
2538 printTypeChain (LTYPE (tree), stderr);
2539 fprintf (stderr, ",");
2540 printTypeChain (RTYPE (tree), stderr);
2541 fprintf (stderr, "\n");
2542 goto errorTreeReturn;
2545 /* if they are both literal */
2546 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2548 tree->type = EX_VALUE;
2549 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2550 valFromType (RETYPE (tree)), '&');
2552 tree->right = tree->left = NULL;
2553 TETYPE (tree) = tree->opval.val->etype;
2554 TTYPE (tree) = tree->opval.val->type;
2558 /* see if this is a GETHBIT operation if yes
2561 ast *otree = optimizeGetHbit (tree);
2564 return decorateType (otree, RESULT_CHECK);
2567 TTYPE (tree) = computeType (LTYPE (tree),
2571 TETYPE (tree) = getSpec (TTYPE (tree));
2573 /* if left is a literal exchange left & right */
2574 if (IS_LITERAL (LTYPE (tree)))
2576 ast *tTree = tree->left;
2577 tree->left = tree->right;
2578 tree->right = tTree;
2581 /* if right is a literal and */
2582 /* we can find a 2nd literal in a and-tree then */
2583 /* rearrange the tree */
2584 if (IS_LITERAL (RTYPE (tree)))
2587 ast *litTree = searchLitOp (tree, &parent, "&");
2591 ast *tTree = litTree->left;
2592 litTree->left = tree->right;
2593 tree->right = tTree;
2594 /* both operands in tTree are literal now */
2595 decorateType (parent, resultType);
2599 LRVAL (tree) = RRVAL (tree) = 1;
2604 /*------------------------------------------------------------------*/
2605 /*----------------------------*/
2607 /*----------------------------*/
2608 p = newLink (DECLARATOR);
2609 /* if bit field then error */
2610 if (IS_BITVAR (tree->left->etype))
2612 werror (E_ILLEGAL_ADDR, "address of bit variable");
2613 goto errorTreeReturn;
2616 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2618 werror (E_ILLEGAL_ADDR, "address of register variable");
2619 goto errorTreeReturn;
2622 if (IS_FUNC (LTYPE (tree)))
2624 // this ought to be ignored
2625 return (tree->left);
2628 if (IS_LITERAL(LTYPE(tree)))
2630 werror (E_ILLEGAL_ADDR, "address of literal");
2631 goto errorTreeReturn;
2636 werror (E_LVALUE_REQUIRED, "address of");
2637 goto errorTreeReturn;
2640 DCL_TYPE (p) = POINTER;
2641 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2642 DCL_TYPE (p) = CPOINTER;
2643 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2644 DCL_TYPE (p) = FPOINTER;
2645 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2646 DCL_TYPE (p) = PPOINTER;
2647 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2648 DCL_TYPE (p) = IPOINTER;
2649 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2650 DCL_TYPE (p) = EEPPOINTER;
2651 else if (SPEC_OCLS(tree->left->etype))
2652 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2654 DCL_TYPE (p) = POINTER;
2656 if (IS_AST_SYM_VALUE (tree->left))
2658 AST_SYMBOL (tree->left)->addrtaken = 1;
2659 AST_SYMBOL (tree->left)->allocreq = 1;
2662 p->next = LTYPE (tree);
2664 TETYPE (tree) = getSpec (TTYPE (tree));
2669 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2670 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2672 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2673 AST_SYMBOL(tree->left->right));
2674 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2675 valueFromLit(element->offset));
2678 tree->type = EX_VALUE;
2679 tree->values.literalFromCast = 1;
2685 /*------------------------------------------------------------------*/
2686 /*----------------------------*/
2688 /*----------------------------*/
2690 /* if the rewrite succeeds then don't go any furthur */
2692 ast *wtree = optimizeRRCRLC (tree);
2694 return decorateType (wtree, RESULT_CHECK);
2696 wtree = optimizeSWAP (tree);
2698 return decorateType (wtree, RESULT_CHECK);
2701 /* if left is a literal exchange left & right */
2702 if (IS_LITERAL (LTYPE (tree)))
2704 ast *tTree = tree->left;
2705 tree->left = tree->right;
2706 tree->right = tTree;
2709 /* if right is a literal and */
2710 /* we can find a 2nd literal in a or-tree then */
2711 /* rearrange the tree */
2712 if (IS_LITERAL (RTYPE (tree)))
2715 ast *litTree = searchLitOp (tree, &parent, "|");
2719 ast *tTree = litTree->left;
2720 litTree->left = tree->right;
2721 tree->right = tTree;
2722 /* both operands in tTree are literal now */
2723 decorateType (parent, resultType);
2728 /*------------------------------------------------------------------*/
2729 /*----------------------------*/
2731 /*----------------------------*/
2733 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2735 werror (E_BITWISE_OP);
2736 werror (W_CONTINUE, "left & right types are ");
2737 printTypeChain (LTYPE (tree), stderr);
2738 fprintf (stderr, ",");
2739 printTypeChain (RTYPE (tree), stderr);
2740 fprintf (stderr, "\n");
2741 goto errorTreeReturn;
2744 /* if they are both literal then */
2745 /* rewrite the tree */
2746 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2748 tree->type = EX_VALUE;
2749 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2750 valFromType (RETYPE (tree)),
2752 tree->right = tree->left = NULL;
2753 TETYPE (tree) = tree->opval.val->etype;
2754 TTYPE (tree) = tree->opval.val->type;
2758 /* if left is a literal exchange left & right */
2759 if (IS_LITERAL (LTYPE (tree)))
2761 ast *tTree = tree->left;
2762 tree->left = tree->right;
2763 tree->right = tTree;
2766 /* if right is a literal and */
2767 /* we can find a 2nd literal in a xor-tree then */
2768 /* rearrange the tree */
2769 if (IS_LITERAL (RTYPE (tree)) &&
2770 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2773 ast *litTree = searchLitOp (tree, &parent, "^");
2777 ast *tTree = litTree->left;
2778 litTree->left = tree->right;
2779 tree->right = tTree;
2780 /* both operands in litTree are literal now */
2781 decorateType (parent, resultType);
2785 LRVAL (tree) = RRVAL (tree) = 1;
2786 TETYPE (tree) = getSpec (TTYPE (tree) =
2787 computeType (LTYPE (tree),
2794 /*------------------------------------------------------------------*/
2795 /*----------------------------*/
2797 /*----------------------------*/
2799 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2801 werror (E_INVALID_OP, "divide");
2802 goto errorTreeReturn;
2804 /* if they are both literal then */
2805 /* rewrite the tree */
2806 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2808 tree->type = EX_VALUE;
2809 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2810 valFromType (RETYPE (tree)));
2811 tree->right = tree->left = NULL;
2812 TETYPE (tree) = getSpec (TTYPE (tree) =
2813 tree->opval.val->type);
2817 LRVAL (tree) = RRVAL (tree) = 1;
2819 TETYPE (tree) = getSpec (TTYPE (tree) =
2820 computeType (LTYPE (tree),
2825 /* if right is a literal and */
2826 /* left is also a division by a literal then */
2827 /* rearrange the tree */
2828 if (IS_LITERAL (RTYPE (tree))
2829 /* avoid infinite loop */
2830 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2833 ast *litTree = searchLitOp (tree, &parent, "/");
2836 if (IS_LITERAL (RTYPE (litTree)))
2840 litTree->right = newNode ('*',
2842 copyAst (tree->right));
2843 litTree->right->lineno = tree->lineno;
2845 tree->right->opval.val = constVal ("1");
2846 decorateType (parent, resultType);
2850 /* litTree->left is literal: no gcse possible.
2851 We can't call decorateType(parent, RESULT_CHECK), because
2852 this would cause an infinit loop. */
2853 parent->decorated = 1;
2854 decorateType (litTree, resultType);
2861 /*------------------------------------------------------------------*/
2862 /*----------------------------*/
2864 /*----------------------------*/
2866 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2868 werror (E_BITWISE_OP);
2869 werror (W_CONTINUE, "left & right types are ");
2870 printTypeChain (LTYPE (tree), stderr);
2871 fprintf (stderr, ",");
2872 printTypeChain (RTYPE (tree), stderr);
2873 fprintf (stderr, "\n");
2874 goto errorTreeReturn;
2876 /* if they are both literal then */
2877 /* rewrite the tree */
2878 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2880 tree->type = EX_VALUE;
2881 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2882 valFromType (RETYPE (tree)));
2883 tree->right = tree->left = NULL;
2884 TETYPE (tree) = getSpec (TTYPE (tree) =
2885 tree->opval.val->type);
2888 LRVAL (tree) = RRVAL (tree) = 1;
2889 TETYPE (tree) = getSpec (TTYPE (tree) =
2890 computeType (LTYPE (tree),
2896 /*------------------------------------------------------------------*/
2897 /*----------------------------*/
2898 /* address dereference */
2899 /*----------------------------*/
2900 case '*': /* can be unary : if right is null then unary operation */
2903 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2905 werror (E_PTR_REQD);
2906 goto errorTreeReturn;
2911 werror (E_LVALUE_REQUIRED, "pointer deref");
2912 goto errorTreeReturn;
2914 if (IS_ADDRESS_OF_OP(tree->left))
2916 /* replace *&obj with obj */
2917 return tree->left->left;
2919 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2920 TETYPE (tree) = getSpec (TTYPE (tree));
2921 /* adjust the storage class */
2922 switch (DCL_TYPE(tree->left->ftype)) {
2924 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2927 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2930 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2933 SPEC_SCLS (TETYPE (tree)) = 0;
2936 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2939 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2942 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2945 SPEC_SCLS (TETYPE (tree)) = 0;
2954 /*------------------------------------------------------------------*/
2955 /*----------------------------*/
2956 /* multiplication */
2957 /*----------------------------*/
2958 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2960 werror (E_INVALID_OP, "multiplication");
2961 goto errorTreeReturn;
2964 /* if they are both literal then */
2965 /* rewrite the tree */
2966 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2968 tree->type = EX_VALUE;
2969 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2970 valFromType (RETYPE (tree)));
2971 tree->right = tree->left = NULL;
2972 TETYPE (tree) = getSpec (TTYPE (tree) =
2973 tree->opval.val->type);
2977 /* if left is a literal exchange left & right */
2978 if (IS_LITERAL (LTYPE (tree)))
2980 ast *tTree = tree->left;
2981 tree->left = tree->right;
2982 tree->right = tTree;
2985 /* if right is a literal and */
2986 /* we can find a 2nd literal in a mul-tree then */
2987 /* rearrange the tree */
2988 if (IS_LITERAL (RTYPE (tree)))
2991 ast *litTree = searchLitOp (tree, &parent, "*");
2995 ast *tTree = litTree->left;
2996 litTree->left = tree->right;
2997 tree->right = tTree;
2998 /* both operands in litTree are literal now */
2999 decorateType (parent, resultType);
3003 LRVAL (tree) = RRVAL (tree) = 1;
3004 tree->left = addCast (tree->left, resultType, FALSE);
3005 tree->right = addCast (tree->right, resultType, FALSE);
3006 TETYPE (tree) = getSpec (TTYPE (tree) =
3007 computeType (LTYPE (tree),
3014 /*------------------------------------------------------------------*/
3015 /*----------------------------*/
3016 /* unary '+' operator */
3017 /*----------------------------*/
3022 if (!IS_ARITHMETIC (LTYPE (tree)))
3024 werror (E_UNARY_OP, '+');
3025 goto errorTreeReturn;
3028 /* if left is a literal then do it */
3029 if (IS_LITERAL (LTYPE (tree)))
3031 tree->type = EX_VALUE;
3032 tree->opval.val = valFromType (LETYPE (tree));
3034 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3038 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3042 /*------------------------------------------------------------------*/
3043 /*----------------------------*/
3045 /*----------------------------*/
3047 /* this is not a unary operation */
3048 /* if both pointers then problem */
3049 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3050 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3052 werror (E_PTR_PLUS_PTR);
3053 goto errorTreeReturn;
3056 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3057 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3059 werror (E_PLUS_INVALID, "+");
3060 goto errorTreeReturn;
3063 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3064 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3066 werror (E_PLUS_INVALID, "+");
3067 goto errorTreeReturn;
3069 /* if they are both literal then */
3070 /* rewrite the tree */
3071 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3073 tree->type = EX_VALUE;
3074 tree->left = addCast (tree->left, resultType, TRUE);
3075 tree->right = addCast (tree->right, resultType, TRUE);
3076 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3077 valFromType (RETYPE (tree)));
3078 tree->right = tree->left = NULL;
3079 TETYPE (tree) = getSpec (TTYPE (tree) =
3080 tree->opval.val->type);
3084 /* if the right is a pointer or left is a literal
3085 xchange left & right */
3086 if (IS_ARRAY (RTYPE (tree)) ||
3087 IS_PTR (RTYPE (tree)) ||
3088 IS_LITERAL (LTYPE (tree)))
3090 ast *tTree = tree->left;
3091 tree->left = tree->right;
3092 tree->right = tTree;
3095 /* if right is a literal and */
3096 /* left is also an addition/subtraction with a literal then */
3097 /* rearrange the tree */
3098 if (IS_LITERAL (RTYPE (tree)))
3100 ast *litTree, *parent;
3101 litTree = searchLitOp (tree, &parent, "+-");
3104 if (litTree->opval.op == '+')
3108 ast *tTree = litTree->left;
3109 litTree->left = tree->right;
3110 tree->right = tree->left;
3113 else if (litTree->opval.op == '-')
3115 if (IS_LITERAL (RTYPE (litTree)))
3119 ast *tTree = litTree->left;
3120 litTree->left = tree->right;
3121 tree->right = tTree;
3127 ast *tTree = litTree->right;
3128 litTree->right = tree->right;
3129 tree->right = tTree;
3130 litTree->opval.op = '+';
3131 tree->opval.op = '-';
3134 decorateType (parent, resultType);
3138 LRVAL (tree) = RRVAL (tree) = 1;
3139 /* if the left is a pointer */
3140 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3141 TETYPE (tree) = getSpec (TTYPE (tree) =
3145 tree->left = addCast (tree->left, resultType, TRUE);
3146 tree->right = addCast (tree->right, resultType, TRUE);
3147 TETYPE (tree) = getSpec (TTYPE (tree) =
3148 computeType (LTYPE (tree),
3156 /*------------------------------------------------------------------*/
3157 /*----------------------------*/
3159 /*----------------------------*/
3160 case '-': /* can be unary */
3161 /* if right is null then unary */
3165 if (!IS_ARITHMETIC (LTYPE (tree)))
3167 werror (E_UNARY_OP, tree->opval.op);
3168 goto errorTreeReturn;
3171 /* if left is a literal then do it */
3172 if (IS_LITERAL (LTYPE (tree)))
3174 tree->type = EX_VALUE;
3175 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3177 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3178 SPEC_USIGN(TETYPE(tree)) = 0;
3182 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3186 /*------------------------------------------------------------------*/
3187 /*----------------------------*/
3189 /*----------------------------*/
3191 if (!(IS_PTR (LTYPE (tree)) ||
3192 IS_ARRAY (LTYPE (tree)) ||
3193 IS_ARITHMETIC (LTYPE (tree))))
3195 werror (E_PLUS_INVALID, "-");
3196 goto errorTreeReturn;
3199 if (!(IS_PTR (RTYPE (tree)) ||
3200 IS_ARRAY (RTYPE (tree)) ||
3201 IS_ARITHMETIC (RTYPE (tree))))
3203 werror (E_PLUS_INVALID, "-");
3204 goto errorTreeReturn;
3207 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3208 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3209 IS_INTEGRAL (RTYPE (tree))))
3211 werror (E_PLUS_INVALID, "-");
3212 goto errorTreeReturn;
3215 /* if they are both literal then */
3216 /* rewrite the tree */
3217 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3219 tree->type = EX_VALUE;
3220 tree->left = addCast (tree->left, resultType, TRUE);
3221 tree->right = addCast (tree->right, resultType, TRUE);
3222 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3223 valFromType (RETYPE (tree)));
3224 tree->right = tree->left = NULL;
3225 TETYPE (tree) = getSpec (TTYPE (tree) =
3226 tree->opval.val->type);
3230 /* if the left & right are equal then zero */
3231 if (isAstEqual (tree->left, tree->right))
3233 tree->type = EX_VALUE;
3234 tree->left = tree->right = NULL;
3235 tree->opval.val = constVal ("0");
3236 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3240 /* if both of them are pointers or arrays then */
3241 /* the result is going to be an integer */
3242 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3243 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3244 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3246 /* if only the left is a pointer */
3247 /* then result is a pointer */
3248 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3249 TETYPE (tree) = getSpec (TTYPE (tree) =
3253 tree->left = addCast (tree->left, resultType, TRUE);
3254 tree->right = addCast (tree->right, resultType, TRUE);
3256 TETYPE (tree) = getSpec (TTYPE (tree) =
3257 computeType (LTYPE (tree),
3263 LRVAL (tree) = RRVAL (tree) = 1;
3265 /* if right is a literal and */
3266 /* left is also an addition/subtraction with a literal then */
3267 /* rearrange the tree */
3268 if (IS_LITERAL (RTYPE (tree))
3269 /* avoid infinite loop */
3270 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3272 ast *litTree, *litParent;
3273 litTree = searchLitOp (tree, &litParent, "+-");
3276 if (litTree->opval.op == '+')
3280 ast *tTree = litTree->left;
3281 litTree->left = litTree->right;
3282 litTree->right = tree->right;
3283 tree->right = tTree;
3284 tree->opval.op = '+';
3285 litTree->opval.op = '-';
3287 else if (litTree->opval.op == '-')
3289 if (IS_LITERAL (RTYPE (litTree)))
3293 ast *tTree = litTree->left;
3294 litTree->left = tree->right;
3295 tree->right = litParent->left;
3296 litParent->left = tTree;
3297 litTree->opval.op = '+';
3299 tree->decorated = 0;
3300 decorateType (tree, resultType);
3306 ast *tTree = litTree->right;
3307 litTree->right = tree->right;
3308 tree->right = tTree;
3311 decorateType (litParent, resultType);
3316 /*------------------------------------------------------------------*/
3317 /*----------------------------*/
3319 /*----------------------------*/
3321 /* can be only integral type */
3322 if (!IS_INTEGRAL (LTYPE (tree)))
3324 werror (E_UNARY_OP, tree->opval.op);
3325 goto errorTreeReturn;
3328 /* if left is a literal then do it */
3329 if (IS_LITERAL (LTYPE (tree)))
3331 tree->type = EX_VALUE;
3332 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3334 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3338 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3341 /*------------------------------------------------------------------*/
3342 /*----------------------------*/
3344 /*----------------------------*/
3346 /* can be pointer */
3347 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3348 !IS_PTR (LTYPE (tree)) &&
3349 !IS_ARRAY (LTYPE (tree)))
3351 werror (E_UNARY_OP, tree->opval.op);
3352 goto errorTreeReturn;
3355 /* if left is a literal then do it */
3356 if (IS_LITERAL (LTYPE (tree)))
3358 tree->type = EX_VALUE;
3359 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3361 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3365 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3368 /*------------------------------------------------------------------*/
3369 /*----------------------------*/
3371 /*----------------------------*/
3375 TTYPE (tree) = LTYPE (tree);
3376 TETYPE (tree) = LETYPE (tree);
3380 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3385 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3387 werror (E_SHIFT_OP_INVALID);
3388 werror (W_CONTINUE, "left & right types are ");
3389 printTypeChain (LTYPE (tree), stderr);
3390 fprintf (stderr, ",");
3391 printTypeChain (RTYPE (tree), stderr);
3392 fprintf (stderr, "\n");
3393 goto errorTreeReturn;
3396 /* make smaller type only if it's a LEFT_OP */
3397 if (tree->opval.op == LEFT_OP)
3398 tree->left = addCast (tree->left, resultType, TRUE);
3400 /* if they are both literal then */
3401 /* rewrite the tree */
3402 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3404 tree->type = EX_VALUE;
3405 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3406 valFromType (RETYPE (tree)),
3407 (tree->opval.op == LEFT_OP ? 1 : 0));
3408 tree->right = tree->left = NULL;
3409 TETYPE (tree) = getSpec (TTYPE (tree) =
3410 tree->opval.val->type);
3414 LRVAL (tree) = RRVAL (tree) = 1;
3415 if (tree->opval.op == LEFT_OP)
3417 TETYPE (tree) = getSpec (TTYPE (tree) =
3418 computeType (LTYPE (tree),
3425 /* no promotion necessary */
3426 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3427 if (IS_LITERAL (TTYPE (tree)))
3428 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3431 /* if only the right side is a literal & we are
3432 shifting more than size of the left operand then zero */
3433 if (IS_LITERAL (RTYPE (tree)) &&
3434 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3435 (getSize (TETYPE (tree)) * 8))
3437 if (tree->opval.op==LEFT_OP ||
3438 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3440 lineno=tree->lineno;
3441 werror (W_SHIFT_CHANGED,
3442 (tree->opval.op == LEFT_OP ? "left" : "right"));
3443 tree->type = EX_VALUE;
3444 tree->left = tree->right = NULL;
3445 tree->opval.val = constVal ("0");
3446 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3453 /*------------------------------------------------------------------*/
3454 /*----------------------------*/
3456 /*----------------------------*/
3457 case CAST: /* change the type */
3458 /* cannot cast to an aggregate type */
3459 if (IS_AGGREGATE (LTYPE (tree)))
3461 werror (E_CAST_ILLEGAL);
3462 goto errorTreeReturn;
3465 /* make sure the type is complete and sane */
3466 checkTypeSanity(LETYPE(tree), "(cast)");
3468 /* If code memory is read only, then pointers to code memory */
3469 /* implicitly point to constants -- make this explicit */
3471 sym_link *t = LTYPE(tree);
3472 while (t && t->next)
3474 if (IS_CODEPTR(t) && port->mem.code_ro)
3476 if (IS_SPEC(t->next))
3477 SPEC_CONST (t->next) = 1;
3479 DCL_PTR_CONST (t->next) = 1;
3486 /* if the right is a literal replace the tree */
3487 if (IS_LITERAL (RETYPE (tree))) {
3488 if (!IS_PTR (LTYPE (tree))) {
3489 tree->type = EX_VALUE;
3491 valCastLiteral (LTYPE (tree),
3492 floatFromVal (valFromType (RETYPE (tree))));
3495 TTYPE (tree) = tree->opval.val->type;
3496 tree->values.literalFromCast = 1;
3497 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3498 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3499 sym_link *rest = LTYPE(tree)->next;
3500 werror(W_LITERAL_GENERIC);
3501 TTYPE(tree) = newLink(DECLARATOR);
3502 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3503 TTYPE(tree)->next = rest;
3504 tree->left->opval.lnk = TTYPE(tree);
3507 TTYPE (tree) = LTYPE (tree);
3511 TTYPE (tree) = LTYPE (tree);
3515 #if 0 // this is already checked, now this could be explicit
3516 /* if pointer to struct then check names */
3517 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3518 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3519 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3521 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3522 SPEC_STRUCT(LETYPE(tree))->tag);
3525 if (IS_ADDRESS_OF_OP(tree->right)
3526 && IS_AST_SYM_VALUE (tree->right->left)
3527 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3529 tree->type = EX_VALUE;
3531 valCastLiteral (LTYPE (tree),
3532 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3533 TTYPE (tree) = tree->opval.val->type;
3534 TETYPE (tree) = getSpec (TTYPE (tree));
3537 tree->values.literalFromCast = 1;
3541 /* handle offsetof macro: */
3542 /* #define offsetof(TYPE, MEMBER) \ */
3543 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3544 if (IS_ADDRESS_OF_OP(tree->right)
3545 && IS_AST_OP (tree->right->left)
3546 && tree->right->left->opval.op == PTR_OP
3547 && IS_AST_OP (tree->right->left->left)
3548 && tree->right->left->left->opval.op == CAST
3549 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3551 symbol *element = getStructElement (
3552 SPEC_STRUCT (LETYPE(tree->right->left)),
3553 AST_SYMBOL(tree->right->left->right)
3557 tree->type = EX_VALUE;
3558 tree->opval.val = valCastLiteral (
3561 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3564 TTYPE (tree) = tree->opval.val->type;
3565 TETYPE (tree) = getSpec (TTYPE (tree));
3572 /* if the right is a literal replace the tree */
3573 if (IS_LITERAL (RETYPE (tree))) {
3575 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3576 /* rewrite (type *)litaddr
3578 and define type at litaddr temp
3579 (but only if type's storage class is not generic)
3581 ast *newTree = newNode ('&', NULL, NULL);
3584 TTYPE (newTree) = LTYPE (tree);
3585 TETYPE (newTree) = getSpec(LTYPE (tree));
3587 /* define a global symbol at the casted address*/
3588 sym = newSymbol(genSymName (0), 0);
3589 sym->type = LTYPE (tree)->next;
3591 sym->type = newLink (V_VOID);
3592 sym->etype = getSpec(sym->type);
3593 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3594 sym->lineDef = tree->lineno;
3597 SPEC_STAT (sym->etype) = 1;
3598 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3599 SPEC_ABSA(sym->etype) = 1;
3600 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3603 newTree->left = newAst_VALUE(symbolVal(sym));
3604 newTree->left->lineno = tree->lineno;
3605 LTYPE (newTree) = sym->type;
3606 LETYPE (newTree) = sym->etype;
3607 LLVAL (newTree) = 1;
3608 LRVAL (newTree) = 0;
3609 TLVAL (newTree) = 1;
3613 if (!IS_PTR (LTYPE (tree))) {
3614 tree->type = EX_VALUE;
3616 valCastLiteral (LTYPE (tree),
3617 floatFromVal (valFromType (RTYPE (tree))));
3618 TTYPE (tree) = tree->opval.val->type;
3621 tree->values.literalFromCast = 1;
3622 TETYPE (tree) = getSpec (TTYPE (tree));
3626 TTYPE (tree) = LTYPE (tree);
3630 TETYPE (tree) = getSpec (TTYPE (tree));
3634 /*------------------------------------------------------------------*/
3635 /*----------------------------*/
3636 /* logical &&, || */
3637 /*----------------------------*/
3640 /* each must be arithmetic type or be a pointer */
3641 if (!IS_PTR (LTYPE (tree)) &&
3642 !IS_ARRAY (LTYPE (tree)) &&
3643 !IS_INTEGRAL (LTYPE (tree)))
3645 werror (E_COMPARE_OP);
3646 goto errorTreeReturn;
3649 if (!IS_PTR (RTYPE (tree)) &&
3650 !IS_ARRAY (RTYPE (tree)) &&
3651 !IS_INTEGRAL (RTYPE (tree)))
3653 werror (E_COMPARE_OP);
3654 goto errorTreeReturn;
3656 /* if they are both literal then */
3657 /* rewrite the tree */
3658 if (IS_LITERAL (RTYPE (tree)) &&
3659 IS_LITERAL (LTYPE (tree)))
3661 tree->type = EX_VALUE;
3662 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3663 valFromType (RTYPE (tree)),
3665 tree->right = tree->left = NULL;
3666 TETYPE (tree) = getSpec (TTYPE (tree) =
3667 tree->opval.val->type);
3670 LRVAL (tree) = RRVAL (tree) = 1;
3671 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3674 /*------------------------------------------------------------------*/
3675 /*----------------------------*/
3676 /* comparison operators */
3677 /*----------------------------*/
3685 ast *lt = optimizeCompare (tree);
3691 /* if they are pointers they must be castable */
3692 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3694 if (tree->opval.op==EQ_OP &&
3695 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3696 // we cannot cast a gptr to a !gptr: switch the leaves
3697 struct ast *s=tree->left;
3698 tree->left=tree->right;
3701 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3703 werror (E_COMPARE_OP);
3704 fprintf (stderr, "comparing type ");
3705 printTypeChain (LTYPE (tree), stderr);
3706 fprintf (stderr, "to type ");
3707 printTypeChain (RTYPE (tree), stderr);
3708 fprintf (stderr, "\n");
3709 goto errorTreeReturn;
3712 /* else they should be promotable to one another */
3715 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3716 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3718 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3720 werror (E_COMPARE_OP);
3721 fprintf (stderr, "comparing type ");
3722 printTypeChain (LTYPE (tree), stderr);
3723 fprintf (stderr, "to type ");
3724 printTypeChain (RTYPE (tree), stderr);
3725 fprintf (stderr, "\n");
3726 goto errorTreeReturn;
3729 /* if unsigned value < 0 then always false */
3730 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3731 if (SPEC_USIGN(LETYPE(tree)) &&
3732 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3733 IS_LITERAL(RTYPE(tree)) &&
3734 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3736 if (tree->opval.op == '<')
3740 if (tree->opval.op == '>')
3742 if (resultType == RESULT_TYPE_IFX)
3744 /* the parent is an ifx: */
3745 /* if (unsigned value) */
3749 /* (unsigned value) ? 1 : 0 */
3750 tree->opval.op = '?';
3751 tree->right = newNode (':',
3752 newAst_VALUE (constVal ("1")),
3753 tree->right); /* val 0 */
3754 tree->right->lineno = tree->lineno;
3755 tree->right->left->lineno = tree->lineno;
3756 decorateType (tree->right, RESULT_CHECK);
3759 /* if they are both literal then */
3760 /* rewrite the tree */
3761 if (IS_LITERAL (RTYPE (tree)) &&
3762 IS_LITERAL (LTYPE (tree)))
3764 tree->type = EX_VALUE;
3765 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3766 valFromType (RETYPE (tree)),
3768 tree->right = tree->left = NULL;
3769 TETYPE (tree) = getSpec (TTYPE (tree) =
3770 tree->opval.val->type);
3773 LRVAL (tree) = RRVAL (tree) = 1;
3774 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3777 /*------------------------------------------------------------------*/
3778 /*----------------------------*/
3780 /*----------------------------*/
3781 case SIZEOF: /* evaluate wihout code generation */
3782 /* change the type to a integer */
3784 int size = getSize (tree->right->ftype);
3785 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3786 if (!size && !IS_VOID(tree->right->ftype))
3787 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3789 tree->type = EX_VALUE;
3790 tree->opval.val = constVal (buffer);
3791 tree->right = tree->left = NULL;
3792 TETYPE (tree) = getSpec (TTYPE (tree) =
3793 tree->opval.val->type);
3796 /*------------------------------------------------------------------*/
3797 /*----------------------------*/
3799 /*----------------------------*/
3801 /* return typeof enum value */
3802 tree->type = EX_VALUE;
3805 if (IS_SPEC(tree->right->ftype)) {
3806 switch (SPEC_NOUN(tree->right->ftype)) {
3808 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3809 else typeofv = TYPEOF_INT;
3812 typeofv = TYPEOF_FLOAT;
3815 typeofv = TYPEOF_CHAR;
3818 typeofv = TYPEOF_VOID;
3821 typeofv = TYPEOF_STRUCT;
3824 typeofv = TYPEOF_BITFIELD;
3827 typeofv = TYPEOF_BIT;
3830 typeofv = TYPEOF_SBIT;
3836 switch (DCL_TYPE(tree->right->ftype)) {
3838 typeofv = TYPEOF_POINTER;
3841 typeofv = TYPEOF_FPOINTER;
3844 typeofv = TYPEOF_CPOINTER;
3847 typeofv = TYPEOF_GPOINTER;
3850 typeofv = TYPEOF_PPOINTER;
3853 typeofv = TYPEOF_IPOINTER;
3856 typeofv = TYPEOF_ARRAY;
3859 typeofv = TYPEOF_FUNCTION;
3865 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3866 tree->opval.val = constVal (buffer);
3867 tree->right = tree->left = NULL;
3868 TETYPE (tree) = getSpec (TTYPE (tree) =
3869 tree->opval.val->type);
3872 /*------------------------------------------------------------------*/
3873 /*----------------------------*/
3874 /* conditional operator '?' */
3875 /*----------------------------*/
3877 /* the type is value of the colon operator (on the right) */
3878 assert (IS_COLON_OP (tree->right));
3879 /* if already known then replace the tree : optimizer will do it
3880 but faster to do it here */
3881 if (IS_LITERAL (LTYPE (tree)))
3883 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3884 return decorateType (tree->right->left, resultTypeProp);
3886 return decorateType (tree->right->right, resultTypeProp);
3890 tree->right = decorateType (tree->right, resultTypeProp);
3891 TTYPE (tree) = RTYPE (tree);
3892 TETYPE (tree) = getSpec (TTYPE (tree));
3897 /* if they don't match we have a problem */
3898 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3900 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3901 goto errorTreeReturn;
3904 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
3905 resultType, tree->opval.op);
3906 TETYPE (tree) = getSpec (TTYPE (tree));
3910 #if 0 // assignment operators are converted by the parser
3911 /*------------------------------------------------------------------*/
3912 /*----------------------------*/
3913 /* assignment operators */
3914 /*----------------------------*/
3917 /* for these it must be both must be integral */
3918 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3919 !IS_ARITHMETIC (RTYPE (tree)))
3921 werror (E_OPS_INTEGRAL);
3922 goto errorTreeReturn;
3925 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3927 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3928 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3932 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3933 goto errorTreeReturn;
3944 /* for these it must be both must be integral */
3945 if (!IS_INTEGRAL (LTYPE (tree)) ||
3946 !IS_INTEGRAL (RTYPE (tree)))
3948 werror (E_OPS_INTEGRAL);
3949 goto errorTreeReturn;
3952 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3954 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3955 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3959 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3960 goto errorTreeReturn;
3966 /*------------------------------------------------------------------*/
3967 /*----------------------------*/
3969 /*----------------------------*/
3971 if (!(IS_PTR (LTYPE (tree)) ||
3972 IS_ARITHMETIC (LTYPE (tree))))
3974 werror (E_PLUS_INVALID, "-=");
3975 goto errorTreeReturn;
3978 if (!(IS_PTR (RTYPE (tree)) ||
3979 IS_ARITHMETIC (RTYPE (tree))))
3981 werror (E_PLUS_INVALID, "-=");
3982 goto errorTreeReturn;
3985 TETYPE (tree) = getSpec (TTYPE (tree) =
3986 computeType (LTYPE (tree),
3991 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3992 werror (E_CODE_WRITE, "-=");
3996 werror (E_LVALUE_REQUIRED, "-=");
3997 goto errorTreeReturn;
4003 /*------------------------------------------------------------------*/
4004 /*----------------------------*/
4006 /*----------------------------*/
4008 /* this is not a unary operation */
4009 /* if both pointers then problem */
4010 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4012 werror (E_PTR_PLUS_PTR);
4013 goto errorTreeReturn;
4016 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4018 werror (E_PLUS_INVALID, "+=");
4019 goto errorTreeReturn;
4022 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4024 werror (E_PLUS_INVALID, "+=");
4025 goto errorTreeReturn;
4028 TETYPE (tree) = getSpec (TTYPE (tree) =
4029 computeType (LTYPE (tree),
4034 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4035 werror (E_CODE_WRITE, "+=");
4039 werror (E_LVALUE_REQUIRED, "+=");
4040 goto errorTreeReturn;
4043 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
4044 tree->opval.op = '=';
4049 /*------------------------------------------------------------------*/
4050 /*----------------------------*/
4051 /* straight assignemnt */
4052 /*----------------------------*/
4054 /* cannot be an aggregate */
4055 if (IS_AGGREGATE (LTYPE (tree)))
4057 werror (E_AGGR_ASSIGN);
4058 goto errorTreeReturn;
4061 /* they should either match or be castable */
4062 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4064 werror (E_TYPE_MISMATCH, "assignment", " ");
4065 printFromToType(RTYPE(tree),LTYPE(tree));
4068 /* if the left side of the tree is of type void
4069 then report error */
4070 if (IS_VOID (LTYPE (tree)))
4072 werror (E_CAST_ZERO);
4073 printFromToType(RTYPE(tree), LTYPE(tree));
4076 TETYPE (tree) = getSpec (TTYPE (tree) =
4080 if (!tree->initMode ) {
4081 if (IS_CONSTANT(LTYPE(tree)))
4082 werror (E_CODE_WRITE, "=");
4086 werror (E_LVALUE_REQUIRED, "=");
4087 goto errorTreeReturn;
4092 /*------------------------------------------------------------------*/
4093 /*----------------------------*/
4094 /* comma operator */
4095 /*----------------------------*/
4097 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4100 /*------------------------------------------------------------------*/
4101 /*----------------------------*/
4103 /*----------------------------*/
4106 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4107 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4109 if (tree->left->opval.op == '*' && !tree->left->right)
4110 tree->left = tree->left->left;
4113 /* require a function or pointer to function */
4114 if (!IS_FUNC (LTYPE (tree))
4115 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4117 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4118 goto errorTreeReturn;
4125 if (IS_CODEPTR(LTYPE(tree)))
4126 functype = LTYPE (tree)->next;
4128 functype = LTYPE (tree);
4130 if (processParms (tree->left, FUNC_ARGS(functype),
4131 tree->right, &parmNumber, TRUE)) {
4132 goto errorTreeReturn;
4135 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4136 !IFFUNC_ISBUILTIN(functype))
4138 reverseParms (tree->right);
4141 TTYPE (tree) = functype->next;
4142 TETYPE (tree) = getSpec (TTYPE (tree));
4146 /*------------------------------------------------------------------*/
4147 /*----------------------------*/
4148 /* return statement */
4149 /*----------------------------*/
4154 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4156 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4157 printFromToType (RTYPE(tree), currFunc->type->next);
4158 goto errorTreeReturn;
4161 if (IS_VOID (currFunc->type->next)
4163 !IS_VOID (RTYPE (tree)))
4165 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4166 goto errorTreeReturn;
4169 /* if there is going to be a casting required then add it */
4170 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4173 decorateType (newNode (CAST,
4174 newAst_LINK (copyLinkChain (currFunc->type->next)),
4184 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4186 werror (W_VOID_FUNC, currFunc->name);
4187 goto errorTreeReturn;
4190 TTYPE (tree) = TETYPE (tree) = NULL;
4193 /*------------------------------------------------------------------*/
4194 /*----------------------------*/
4195 /* switch statement */
4196 /*----------------------------*/
4198 /* the switch value must be an integer */
4199 if (!IS_INTEGRAL (LTYPE (tree)))
4201 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4202 goto errorTreeReturn;
4205 TTYPE (tree) = TETYPE (tree) = NULL;
4208 /*------------------------------------------------------------------*/
4209 /*----------------------------*/
4211 /*----------------------------*/
4213 tree->left = backPatchLabels (tree->left,
4216 TTYPE (tree) = TETYPE (tree) = NULL;
4219 /*------------------------------------------------------------------*/
4220 /*----------------------------*/
4222 /*----------------------------*/
4225 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4226 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4227 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4229 /* if the for loop is reversible then
4230 reverse it otherwise do what we normally
4236 if (isLoopReversible (tree, &sym, &init, &end))
4237 return reverseLoop (tree, sym, init, end);
4239 return decorateType (createFor (AST_FOR (tree, trueLabel),
4240 AST_FOR (tree, continueLabel),
4241 AST_FOR (tree, falseLabel),
4242 AST_FOR (tree, condLabel),
4243 AST_FOR (tree, initExpr),
4244 AST_FOR (tree, condExpr),
4245 AST_FOR (tree, loopExpr),
4246 tree->left), RESULT_CHECK);
4249 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4250 "node PARAM shouldn't be processed here");
4251 /* but in processParams() */
4254 TTYPE (tree) = TETYPE (tree) = NULL;
4258 /* some error found this tree will be killed */
4260 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4261 tree->opval.op = NULLOP;
4267 /*-----------------------------------------------------------------*/
4268 /* sizeofOp - processes size of operation */
4269 /*-----------------------------------------------------------------*/
4271 sizeofOp (sym_link * type)
4276 /* make sure the type is complete and sane */
4277 checkTypeSanity(type, "(sizeof)");
4279 /* get the size and convert it to character */
4280 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4281 if (!size && !IS_VOID(type))
4282 werror (E_SIZEOF_INCOMPLETE_TYPE);
4284 /* now convert into value */
4285 return constVal (buff);
4289 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4290 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4291 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4292 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4293 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4294 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4295 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4297 /*-----------------------------------------------------------------*/
4298 /* backPatchLabels - change and or not operators to flow control */
4299 /*-----------------------------------------------------------------*/
4301 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4307 if (!(IS_ANDORNOT (tree)))
4310 /* if this an and */
4313 static int localLbl = 0;
4316 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4317 localLabel = newSymbol (buffer, NestLevel);
4319 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4321 /* if left is already a IFX then just change the if true label in that */
4322 if (!IS_IFX (tree->left))
4323 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4325 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4326 /* right is a IFX then just join */
4327 if (IS_IFX (tree->right))
4328 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4330 tree->right = createLabel (localLabel, tree->right);
4331 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4333 return newNode (NULLOP, tree->left, tree->right);
4336 /* if this is an or operation */
4339 static int localLbl = 0;
4342 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4343 localLabel = newSymbol (buffer, NestLevel);
4345 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4347 /* if left is already a IFX then just change the if true label in that */
4348 if (!IS_IFX (tree->left))
4349 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4351 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4352 /* right is a IFX then just join */
4353 if (IS_IFX (tree->right))
4354 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4356 tree->right = createLabel (localLabel, tree->right);
4357 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4359 return newNode (NULLOP, tree->left, tree->right);
4365 int wasnot = IS_NOT (tree->left);
4366 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4368 /* if the left is already a IFX */
4369 if (!IS_IFX (tree->left))
4370 tree->left = newNode (IFX, tree->left, NULL);
4374 tree->left->trueLabel = trueLabel;
4375 tree->left->falseLabel = falseLabel;
4379 tree->left->trueLabel = falseLabel;
4380 tree->left->falseLabel = trueLabel;
4387 tree->trueLabel = trueLabel;
4388 tree->falseLabel = falseLabel;
4395 /*-----------------------------------------------------------------*/
4396 /* createBlock - create expression tree for block */
4397 /*-----------------------------------------------------------------*/
4399 createBlock (symbol * decl, ast * body)
4403 /* if the block has nothing */
4407 ex = newNode (BLOCK, NULL, body);
4408 ex->values.sym = decl;
4410 ex->right = ex->right;
4416 /*-----------------------------------------------------------------*/
4417 /* createLabel - creates the expression tree for labels */
4418 /*-----------------------------------------------------------------*/
4420 createLabel (symbol * label, ast * stmnt)
4423 char name[SDCC_NAME_MAX + 1];
4426 /* must create fresh symbol if the symbol name */
4427 /* exists in the symbol table, since there can */
4428 /* be a variable with the same name as the labl */
4429 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4430 (csym->level == label->level))
4431 label = newSymbol (label->name, label->level);
4433 /* change the name before putting it in add _ */
4434 SNPRINTF(name, sizeof(name), "%s", label->name);
4436 /* put the label in the LabelSymbol table */
4437 /* but first check if a label of the same */
4439 if ((csym = findSym (LabelTab, NULL, name)))
4440 werror (E_DUPLICATE_LABEL, label->name);
4442 addSym (LabelTab, label, name, label->level, 0, 0);
4445 label->key = labelKey++;
4446 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4452 /*-----------------------------------------------------------------*/
4453 /* createCase - generates the parsetree for a case statement */
4454 /*-----------------------------------------------------------------*/
4456 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4458 char caseLbl[SDCC_NAME_MAX + 1];
4462 /* if the switch statement does not exist */
4463 /* then case is out of context */
4466 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4470 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4471 /* if not a constant then error */
4472 if (!IS_LITERAL (caseVal->ftype))
4474 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4478 /* if not a integer than error */
4479 if (!IS_INTEGRAL (caseVal->ftype))
4481 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4485 /* find the end of the switch values chain */
4486 if (!(val = swStat->values.switchVals.swVals))
4487 swStat->values.switchVals.swVals = caseVal->opval.val;
4490 /* also order the cases according to value */
4492 int cVal = (int) floatFromVal (caseVal->opval.val);
4493 while (val && (int) floatFromVal (val) < cVal)
4499 /* if we reached the end then */
4502 pval->next = caseVal->opval.val;
4504 else if ((int) floatFromVal (val) == cVal)
4506 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4512 /* we found a value greater than */
4513 /* the current value we must add this */
4514 /* before the value */
4515 caseVal->opval.val->next = val;
4517 /* if this was the first in chain */
4518 if (swStat->values.switchVals.swVals == val)
4519 swStat->values.switchVals.swVals =
4522 pval->next = caseVal->opval.val;
4527 /* create the case label */
4528 SNPRINTF(caseLbl, sizeof(caseLbl),
4530 swStat->values.switchVals.swNum,
4531 (int) floatFromVal (caseVal->opval.val));
4533 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4538 /*-----------------------------------------------------------------*/
4539 /* createDefault - creates the parse tree for the default statement */
4540 /*-----------------------------------------------------------------*/
4542 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4544 char defLbl[SDCC_NAME_MAX + 1];
4546 /* if the switch statement does not exist */
4547 /* then case is out of context */
4550 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4554 if (swStat->values.switchVals.swDefault)
4556 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4561 /* turn on the default flag */
4562 swStat->values.switchVals.swDefault = 1;
4564 /* create the label */
4565 SNPRINTF (defLbl, sizeof(defLbl),
4566 "_default_%d", swStat->values.switchVals.swNum);
4567 return createLabel (newSymbol (defLbl, 0), stmnt);
4570 /*-----------------------------------------------------------------*/
4571 /* createIf - creates the parsetree for the if statement */
4572 /*-----------------------------------------------------------------*/
4574 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4576 static int Lblnum = 0;
4578 symbol *ifTrue, *ifFalse, *ifEnd;
4580 /* if neither exists */
4581 if (!elseBody && !ifBody) {
4582 // if there are no side effects (i++, j() etc)
4583 if (!hasSEFcalls(condAst)) {
4588 /* create the labels */
4589 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4590 ifFalse = newSymbol (buffer, NestLevel);
4591 /* if no else body then end == false */
4596 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4597 ifEnd = newSymbol (buffer, NestLevel);
4600 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4601 ifTrue = newSymbol (buffer, NestLevel);
4605 /* attach the ifTrue label to the top of it body */
4606 ifBody = createLabel (ifTrue, ifBody);
4607 /* attach a goto end to the ifBody if else is present */
4610 ifBody = newNode (NULLOP, ifBody,
4612 newAst_VALUE (symbolVal (ifEnd)),
4614 /* put the elseLabel on the else body */
4615 elseBody = createLabel (ifFalse, elseBody);
4616 /* out the end at the end of the body */
4617 elseBody = newNode (NULLOP,
4619 createLabel (ifEnd, NULL));
4623 ifBody = newNode (NULLOP, ifBody,
4624 createLabel (ifFalse, NULL));
4626 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4627 if (IS_IFX (condAst))
4630 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4632 return newNode (NULLOP, ifTree,
4633 newNode (NULLOP, ifBody, elseBody));
4637 /*-----------------------------------------------------------------*/
4638 /* createDo - creates parse tree for do */
4641 /* _docontinue_n: */
4642 /* condition_expression +-> trueLabel -> _dobody_n */
4644 /* +-> falseLabel-> _dobreak_n */
4646 /*-----------------------------------------------------------------*/
4648 createDo (symbol * trueLabel, symbol * continueLabel,
4649 symbol * falseLabel, ast * condAst, ast * doBody)
4654 /* if the body does not exist then it is simple */
4657 condAst = backPatchLabels (condAst, continueLabel, NULL);
4658 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4659 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4660 doTree->trueLabel = continueLabel;
4661 doTree->falseLabel = NULL;
4665 /* otherwise we have a body */
4666 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4668 /* attach the body label to the top */
4669 doBody = createLabel (trueLabel, doBody);
4670 /* attach the continue label to end of body */
4671 doBody = newNode (NULLOP, doBody,
4672 createLabel (continueLabel, NULL));
4674 /* now put the break label at the end */
4675 if (IS_IFX (condAst))
4678 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4680 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4682 /* putting it together */
4683 return newNode (NULLOP, doBody, doTree);
4686 /*-----------------------------------------------------------------*/
4687 /* createFor - creates parse tree for 'for' statement */
4690 /* condExpr +-> trueLabel -> _forbody_n */
4692 /* +-> falseLabel-> _forbreak_n */
4695 /* _forcontinue_n: */
4697 /* goto _forcond_n ; */
4699 /*-----------------------------------------------------------------*/
4701 createFor (symbol * trueLabel, symbol * continueLabel,
4702 symbol * falseLabel, symbol * condLabel,
4703 ast * initExpr, ast * condExpr, ast * loopExpr,
4708 /* if loopexpression not present then we can generate it */
4709 /* the same way as a while */
4711 return newNode (NULLOP, initExpr,
4712 createWhile (trueLabel, continueLabel,
4713 falseLabel, condExpr, forBody));
4714 /* vanilla for statement */
4715 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4717 if (condExpr && !IS_IFX (condExpr))
4718 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4721 /* attach condition label to condition */
4722 condExpr = createLabel (condLabel, condExpr);
4724 /* attach body label to body */
4725 forBody = createLabel (trueLabel, forBody);
4727 /* attach continue to forLoop expression & attach */
4728 /* goto the forcond @ and of loopExpression */
4729 loopExpr = createLabel (continueLabel,
4733 newAst_VALUE (symbolVal (condLabel)),
4735 /* now start putting them together */
4736 forTree = newNode (NULLOP, initExpr, condExpr);
4737 forTree = newNode (NULLOP, forTree, forBody);
4738 forTree = newNode (NULLOP, forTree, loopExpr);
4739 /* finally add the break label */
4740 forTree = newNode (NULLOP, forTree,
4741 createLabel (falseLabel, NULL));
4745 /*-----------------------------------------------------------------*/
4746 /* createWhile - creates parse tree for while statement */
4747 /* the while statement will be created as follows */
4749 /* _while_continue_n: */
4750 /* condition_expression +-> trueLabel -> _while_boby_n */
4752 /* +-> falseLabel -> _while_break_n */
4753 /* _while_body_n: */
4755 /* goto _while_continue_n */
4756 /* _while_break_n: */
4757 /*-----------------------------------------------------------------*/
4759 createWhile (symbol * trueLabel, symbol * continueLabel,
4760 symbol * falseLabel, ast * condExpr, ast * whileBody)
4764 /* put the continue label */
4765 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4766 condExpr = createLabel (continueLabel, condExpr);
4767 condExpr->lineno = 0;
4769 /* put the body label in front of the body */
4770 whileBody = createLabel (trueLabel, whileBody);
4771 whileBody->lineno = 0;
4772 /* put a jump to continue at the end of the body */
4773 /* and put break label at the end of the body */
4774 whileBody = newNode (NULLOP,
4777 newAst_VALUE (symbolVal (continueLabel)),
4778 createLabel (falseLabel, NULL)));
4780 /* put it all together */
4781 if (IS_IFX (condExpr))
4782 whileTree = condExpr;
4785 whileTree = newNode (IFX, condExpr, NULL);
4786 /* put the true & false labels in place */
4787 whileTree->trueLabel = trueLabel;
4788 whileTree->falseLabel = falseLabel;
4791 return newNode (NULLOP, whileTree, whileBody);
4794 /*-----------------------------------------------------------------*/
4795 /* optimizeGetHbit - get highest order bit of the expression */
4796 /*-----------------------------------------------------------------*/
4798 optimizeGetHbit (ast * tree)
4801 /* if this is not a bit and */
4802 if (!IS_BITAND (tree))
4805 /* will look for tree of the form
4806 ( expr >> ((sizeof expr) -1) ) & 1 */
4807 if (!IS_AST_LIT_VALUE (tree->right))
4810 if (AST_LIT_VALUE (tree->right) != 1)
4813 if (!IS_RIGHT_OP (tree->left))
4816 if (!IS_AST_LIT_VALUE (tree->left->right))
4819 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4820 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4823 /* make sure the port supports GETHBIT */
4824 if (port->hasExtBitOp
4825 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4828 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4832 /*-----------------------------------------------------------------*/
4833 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4834 /*-----------------------------------------------------------------*/
4836 optimizeRRCRLC (ast * root)
4838 /* will look for trees of the form
4839 (?expr << 1) | (?expr >> 7) or
4840 (?expr >> 7) | (?expr << 1) will make that
4841 into a RLC : operation ..
4843 (?expr >> 1) | (?expr << 7) or
4844 (?expr << 7) | (?expr >> 1) will make that
4845 into a RRC operation
4846 note : by 7 I mean (number of bits required to hold the
4848 /* if the root operations is not a | operation the not */
4849 if (!IS_BITOR (root))
4852 /* I have to think of a better way to match patterns this sucks */
4853 /* that aside let start looking for the first case : I use a the
4854 negative check a lot to improve the efficiency */
4855 /* (?expr << 1) | (?expr >> 7) */
4856 if (IS_LEFT_OP (root->left) &&
4857 IS_RIGHT_OP (root->right))
4860 if (!SPEC_USIGN (TETYPE (root->left->left)))
4863 if (!IS_AST_LIT_VALUE (root->left->right) ||
4864 !IS_AST_LIT_VALUE (root->right->right))
4867 /* make sure it is the same expression */
4868 if (!isAstEqual (root->left->left,
4872 if (AST_LIT_VALUE (root->left->right) != 1)
4875 if (AST_LIT_VALUE (root->right->right) !=
4876 (getSize (TTYPE (root->left->left)) * 8 - 1))
4879 /* make sure the port supports RLC */
4880 if (port->hasExtBitOp
4881 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4884 /* whew got the first case : create the AST */
4885 return newNode (RLC, root->left->left, NULL);
4889 /* check for second case */
4890 /* (?expr >> 7) | (?expr << 1) */
4891 if (IS_LEFT_OP (root->right) &&
4892 IS_RIGHT_OP (root->left))
4895 if (!SPEC_USIGN (TETYPE (root->left->left)))
4898 if (!IS_AST_LIT_VALUE (root->left->right) ||
4899 !IS_AST_LIT_VALUE (root->right->right))
4902 /* make sure it is the same symbol */
4903 if (!isAstEqual (root->left->left,
4907 if (AST_LIT_VALUE (root->right->right) != 1)
4910 if (AST_LIT_VALUE (root->left->right) !=
4911 (getSize (TTYPE (root->left->left)) * 8 - 1))
4914 /* make sure the port supports RLC */
4915 if (port->hasExtBitOp
4916 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4919 /* whew got the first case : create the AST */
4920 return newNode (RLC, root->left->left, NULL);
4925 /* third case for RRC */
4926 /* (?symbol >> 1) | (?symbol << 7) */
4927 if (IS_LEFT_OP (root->right) &&
4928 IS_RIGHT_OP (root->left))
4931 if (!SPEC_USIGN (TETYPE (root->left->left)))
4934 if (!IS_AST_LIT_VALUE (root->left->right) ||
4935 !IS_AST_LIT_VALUE (root->right->right))
4938 /* make sure it is the same symbol */
4939 if (!isAstEqual (root->left->left,
4943 if (AST_LIT_VALUE (root->left->right) != 1)
4946 if (AST_LIT_VALUE (root->right->right) !=
4947 (getSize (TTYPE (root->left->left)) * 8 - 1))
4950 /* make sure the port supports RRC */
4951 if (port->hasExtBitOp
4952 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4955 /* whew got the first case : create the AST */
4956 return newNode (RRC, root->left->left, NULL);
4960 /* fourth and last case for now */
4961 /* (?symbol << 7) | (?symbol >> 1) */
4962 if (IS_RIGHT_OP (root->right) &&
4963 IS_LEFT_OP (root->left))
4966 if (!SPEC_USIGN (TETYPE (root->left->left)))
4969 if (!IS_AST_LIT_VALUE (root->left->right) ||
4970 !IS_AST_LIT_VALUE (root->right->right))
4973 /* make sure it is the same symbol */
4974 if (!isAstEqual (root->left->left,
4978 if (AST_LIT_VALUE (root->right->right) != 1)
4981 if (AST_LIT_VALUE (root->left->right) !=
4982 (getSize (TTYPE (root->left->left)) * 8 - 1))
4985 /* make sure the port supports RRC */
4986 if (port->hasExtBitOp
4987 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4990 /* whew got the first case : create the AST */
4991 return newNode (RRC, root->left->left, NULL);
4995 /* not found return root */
4999 /*-----------------------------------------------------------------*/
5000 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5001 /*-----------------------------------------------------------------*/
5003 optimizeSWAP (ast * root)
5005 /* will look for trees of the form
5006 (?expr << 4) | (?expr >> 4) or
5007 (?expr >> 4) | (?expr << 4) will make that
5008 into a SWAP : operation ..
5009 note : by 4 I mean (number of bits required to hold the
5011 /* if the root operations is not a | operation the not */
5012 if (!IS_BITOR (root))
5015 /* (?expr << 4) | (?expr >> 4) */
5016 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5017 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5020 if (!SPEC_USIGN (TETYPE (root->left->left)))
5023 if (!IS_AST_LIT_VALUE (root->left->right) ||
5024 !IS_AST_LIT_VALUE (root->right->right))
5027 /* make sure it is the same expression */
5028 if (!isAstEqual (root->left->left,
5032 if (AST_LIT_VALUE (root->left->right) !=
5033 (getSize (TTYPE (root->left->left)) * 4))
5036 if (AST_LIT_VALUE (root->right->right) !=
5037 (getSize (TTYPE (root->left->left)) * 4))
5040 /* make sure the port supports SWAP */
5041 if (port->hasExtBitOp
5042 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5045 /* found it : create the AST */
5046 return newNode (SWAP, root->left->left, NULL);
5050 /* not found return root */
5054 /*-----------------------------------------------------------------*/
5055 /* optimizeCompare - otimizes compares for bit variables */
5056 /*-----------------------------------------------------------------*/
5058 optimizeCompare (ast * root)
5060 ast *optExpr = NULL;
5063 unsigned int litValue;
5065 /* if nothing then return nothing */
5069 /* if not a compare op then do leaves */
5070 if (!IS_COMPARE_OP (root))
5072 root->left = optimizeCompare (root->left);
5073 root->right = optimizeCompare (root->right);
5077 /* if left & right are the same then depending
5078 of the operation do */
5079 if (isAstEqual (root->left, root->right))
5081 switch (root->opval.op)
5086 optExpr = newAst_VALUE (constVal ("0"));
5091 optExpr = newAst_VALUE (constVal ("1"));
5095 return decorateType (optExpr, RESULT_CHECK);
5098 vleft = (root->left->type == EX_VALUE ?
5099 root->left->opval.val : NULL);
5101 vright = (root->right->type == EX_VALUE ?
5102 root->right->opval.val : NULL);
5104 /* if left is a BITVAR in BITSPACE */
5105 /* and right is a LITERAL then opt- */
5106 /* imize else do nothing */
5107 if (vleft && vright &&
5108 IS_BITVAR (vleft->etype) &&
5109 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5110 IS_LITERAL (vright->etype))
5113 /* if right side > 1 then comparison may never succeed */
5114 if ((litValue = (int) floatFromVal (vright)) > 1)
5116 werror (W_BAD_COMPARE);
5122 switch (root->opval.op)
5124 case '>': /* bit value greater than 1 cannot be */
5125 werror (W_BAD_COMPARE);
5129 case '<': /* bit value < 1 means 0 */
5131 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5134 case LE_OP: /* bit value <= 1 means no check */
5135 optExpr = newAst_VALUE (vright);
5138 case GE_OP: /* bit value >= 1 means only check for = */
5140 optExpr = newAst_VALUE (vleft);
5145 { /* literal is zero */
5146 switch (root->opval.op)
5148 case '<': /* bit value < 0 cannot be */
5149 werror (W_BAD_COMPARE);
5153 case '>': /* bit value > 0 means 1 */
5155 optExpr = newAst_VALUE (vleft);
5158 case LE_OP: /* bit value <= 0 means no check */
5159 case GE_OP: /* bit value >= 0 means no check */
5160 werror (W_BAD_COMPARE);
5164 case EQ_OP: /* bit == 0 means ! of bit */
5165 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5169 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5170 } /* end-of-if of BITVAR */
5175 /*-----------------------------------------------------------------*/
5176 /* addSymToBlock : adds the symbol to the first block we find */
5177 /*-----------------------------------------------------------------*/
5179 addSymToBlock (symbol * sym, ast * tree)
5181 /* reached end of tree or a leaf */
5182 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5186 if (IS_AST_OP (tree) &&
5187 tree->opval.op == BLOCK)
5190 symbol *lsym = copySymbol (sym);
5192 lsym->next = AST_VALUES (tree, sym);
5193 AST_VALUES (tree, sym) = lsym;
5197 addSymToBlock (sym, tree->left);
5198 addSymToBlock (sym, tree->right);
5201 /*-----------------------------------------------------------------*/
5202 /* processRegParms - do processing for register parameters */
5203 /*-----------------------------------------------------------------*/
5205 processRegParms (value * args, ast * body)
5209 if (IS_REGPARM (args->etype))
5210 addSymToBlock (args->sym, body);
5215 /*-----------------------------------------------------------------*/
5216 /* resetParmKey - resets the operandkeys for the symbols */
5217 /*-----------------------------------------------------------------*/
5218 DEFSETFUNC (resetParmKey)
5229 /*-----------------------------------------------------------------*/
5230 /* createFunction - This is the key node that calls the iCode for */
5231 /* generating the code for a function. Note code */
5232 /* is generated function by function, later when */
5233 /* add inter-procedural analysis this will change */
5234 /*-----------------------------------------------------------------*/
5236 createFunction (symbol * name, ast * body)
5242 iCode *piCode = NULL;
5244 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5245 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5247 /* if check function return 0 then some problem */
5248 if (checkFunction (name, NULL) == 0)
5251 /* create a dummy block if none exists */
5253 body = newNode (BLOCK, NULL, NULL);
5257 /* check if the function name already in the symbol table */
5258 if ((csym = findSym (SymbolTab, NULL, name->name)))
5261 /* special case for compiler defined functions
5262 we need to add the name to the publics list : this
5263 actually means we are now compiling the compiler
5267 addSet (&publics, name);
5273 allocVariables (name);
5275 name->lastLine = mylineno;
5278 /* set the stack pointer */
5279 /* PENDING: check this for the mcs51 */
5280 stackPtr = -port->stack.direction * port->stack.call_overhead;
5281 if (IFFUNC_ISISR (name->type))
5282 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5283 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5284 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5286 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5288 fetype = getSpec (name->type); /* get the specifier for the function */
5289 /* if this is a reentrant function then */
5290 if (IFFUNC_ISREENT (name->type))
5293 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5295 /* do processing for parameters that are passed in registers */
5296 processRegParms (FUNC_ARGS(name->type), body);
5298 /* set the stack pointer */
5302 /* allocate & autoinit the block variables */
5303 processBlockVars (body, &stack, ALLOCATE);
5305 /* save the stack information */
5306 if (options.useXstack)
5307 name->xstack = SPEC_STAK (fetype) = stack;
5309 name->stack = SPEC_STAK (fetype) = stack;
5311 /* name needs to be mangled */
5312 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5314 body = resolveSymbols (body); /* resolve the symbols */
5315 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5318 ex = newAst_VALUE (symbolVal (name)); /* create name */
5319 ex = newNode (FUNCTION, ex, body);
5320 ex->values.args = FUNC_ARGS(name->type);
5322 if (options.dump_tree) PA(ex);
5325 werror (E_FUNC_NO_CODE, name->name);
5329 /* create the node & generate intermediate code */
5331 codeOutFile = code->oFile;
5332 piCode = iCodeFromAst (ex);
5336 werror (E_FUNC_NO_CODE, name->name);
5340 eBBlockFromiCode (piCode);
5342 /* if there are any statics then do them */
5345 GcurMemmap = statsg;
5346 codeOutFile = statsg->oFile;
5347 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5353 /* dealloc the block variables */
5354 processBlockVars (body, &stack, DEALLOCATE);
5355 outputDebugStackSymbols();
5356 /* deallocate paramaters */
5357 deallocParms (FUNC_ARGS(name->type));
5359 if (IFFUNC_ISREENT (name->type))
5362 /* we are done freeup memory & cleanup */
5364 if (port->reset_labelKey) labelKey = 1;
5366 FUNC_HASBODY(name->type) = 1;
5367 addSet (&operKeyReset, name);
5368 applyToSet (operKeyReset, resetParmKey);
5373 cleanUpLevel (LabelTab, 0);
5374 cleanUpBlock (StructTab, 1);
5375 cleanUpBlock (TypedefTab, 1);
5377 xstack->syms = NULL;
5378 istack->syms = NULL;
5383 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5384 /*-----------------------------------------------------------------*/
5385 /* ast_print : prints the ast (for debugging purposes) */
5386 /*-----------------------------------------------------------------*/
5388 void ast_print (ast * tree, FILE *outfile, int indent)
5393 /* can print only decorated trees */
5394 if (!tree->decorated) return;
5396 /* if any child is an error | this one is an error do nothing */
5397 if (tree->isError ||
5398 (tree->left && tree->left->isError) ||
5399 (tree->right && tree->right->isError)) {
5400 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5404 /* print the line */
5405 /* if not block & function */
5406 if (tree->type == EX_OP &&
5407 (tree->opval.op != FUNCTION &&
5408 tree->opval.op != BLOCK &&
5409 tree->opval.op != NULLOP)) {
5412 if (tree->opval.op == FUNCTION) {
5414 value *args=FUNC_ARGS(tree->left->opval.val->type);
5415 fprintf(outfile,"FUNCTION (%s=%p) type (",
5416 tree->left->opval.val->name, tree);
5417 printTypeChain (tree->left->opval.val->type->next,outfile);
5418 fprintf(outfile,") args (");
5421 fprintf (outfile, ", ");
5423 printTypeChain (args ? args->type : NULL, outfile);
5425 args= args ? args->next : NULL;
5427 fprintf(outfile,")\n");
5428 ast_print(tree->left,outfile,indent);
5429 ast_print(tree->right,outfile,indent);
5432 if (tree->opval.op == BLOCK) {
5433 symbol *decls = tree->values.sym;
5434 INDENT(indent,outfile);
5435 fprintf(outfile,"{\n");
5437 INDENT(indent+2,outfile);
5438 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5439 decls->name, decls);
5440 printTypeChain(decls->type,outfile);
5441 fprintf(outfile,")\n");
5443 decls = decls->next;
5445 ast_print(tree->right,outfile,indent+2);
5446 INDENT(indent,outfile);
5447 fprintf(outfile,"}\n");
5450 if (tree->opval.op == NULLOP) {
5451 ast_print(tree->left,outfile,indent);
5452 ast_print(tree->right,outfile,indent);
5455 INDENT(indent,outfile);
5457 /*------------------------------------------------------------------*/
5458 /*----------------------------*/
5459 /* leaf has been reached */
5460 /*----------------------------*/
5461 /* if this is of type value */
5462 /* just get the type */
5463 if (tree->type == EX_VALUE) {
5465 if (IS_LITERAL (tree->opval.val->etype)) {
5466 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5467 if (SPEC_USIGN (tree->opval.val->etype))
5468 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5470 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5471 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5472 floatFromVal(tree->opval.val));
5473 } else if (tree->opval.val->sym) {
5474 /* if the undefined flag is set then give error message */
5475 if (tree->opval.val->sym->undefined) {
5476 fprintf(outfile,"UNDEFINED SYMBOL ");
5478 fprintf(outfile,"SYMBOL ");
5480 fprintf(outfile,"(%s=%p)",
5481 tree->opval.val->sym->name,tree);
5484 fprintf(outfile," type (");
5485 printTypeChain(tree->ftype,outfile);
5486 fprintf(outfile,")\n");
5488 fprintf(outfile,"\n");
5493 /* if type link for the case of cast */
5494 if (tree->type == EX_LINK) {
5495 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5496 printTypeChain(tree->opval.lnk,outfile);
5497 fprintf(outfile,")\n");
5502 /* depending on type of operator do */
5504 switch (tree->opval.op) {
5505 /*------------------------------------------------------------------*/
5506 /*----------------------------*/
5508 /*----------------------------*/
5510 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5511 printTypeChain(tree->ftype,outfile);
5512 fprintf(outfile,")\n");
5513 ast_print(tree->left,outfile,indent+2);
5514 ast_print(tree->right,outfile,indent+2);
5517 /*------------------------------------------------------------------*/
5518 /*----------------------------*/
5520 /*----------------------------*/
5522 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5523 printTypeChain(tree->ftype,outfile);
5524 fprintf(outfile,")\n");
5525 ast_print(tree->left,outfile,indent+2);
5526 ast_print(tree->right,outfile,indent+2);
5529 /*------------------------------------------------------------------*/
5530 /*----------------------------*/
5531 /* struct/union pointer */
5532 /*----------------------------*/
5534 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5535 printTypeChain(tree->ftype,outfile);
5536 fprintf(outfile,")\n");
5537 ast_print(tree->left,outfile,indent+2);
5538 ast_print(tree->right,outfile,indent+2);
5541 /*------------------------------------------------------------------*/
5542 /*----------------------------*/
5543 /* ++/-- operation */
5544 /*----------------------------*/
5547 fprintf(outfile,"post-");
5549 fprintf(outfile,"pre-");
5550 fprintf(outfile,"INC_OP (%p) type (",tree);
5551 printTypeChain(tree->ftype,outfile);
5552 fprintf(outfile,")\n");
5553 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5554 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5559 fprintf(outfile,"post-");
5561 fprintf(outfile,"pre-");
5562 fprintf(outfile,"DEC_OP (%p) type (",tree);
5563 printTypeChain(tree->ftype,outfile);
5564 fprintf(outfile,")\n");
5565 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5566 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5569 /*------------------------------------------------------------------*/
5570 /*----------------------------*/
5572 /*----------------------------*/
5575 fprintf(outfile,"& (%p) type (",tree);
5576 printTypeChain(tree->ftype,outfile);
5577 fprintf(outfile,")\n");
5578 ast_print(tree->left,outfile,indent+2);
5579 ast_print(tree->right,outfile,indent+2);
5581 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5582 printTypeChain(tree->ftype,outfile);
5583 fprintf(outfile,")\n");
5584 ast_print(tree->left,outfile,indent+2);
5585 ast_print(tree->right,outfile,indent+2);
5588 /*----------------------------*/
5590 /*----------------------------*/
5592 fprintf(outfile,"OR (%p) type (",tree);
5593 printTypeChain(tree->ftype,outfile);
5594 fprintf(outfile,")\n");
5595 ast_print(tree->left,outfile,indent+2);
5596 ast_print(tree->right,outfile,indent+2);
5598 /*------------------------------------------------------------------*/
5599 /*----------------------------*/
5601 /*----------------------------*/
5603 fprintf(outfile,"XOR (%p) type (",tree);
5604 printTypeChain(tree->ftype,outfile);
5605 fprintf(outfile,")\n");
5606 ast_print(tree->left,outfile,indent+2);
5607 ast_print(tree->right,outfile,indent+2);
5610 /*------------------------------------------------------------------*/
5611 /*----------------------------*/
5613 /*----------------------------*/
5615 fprintf(outfile,"DIV (%p) type (",tree);
5616 printTypeChain(tree->ftype,outfile);
5617 fprintf(outfile,")\n");
5618 ast_print(tree->left,outfile,indent+2);
5619 ast_print(tree->right,outfile,indent+2);
5621 /*------------------------------------------------------------------*/
5622 /*----------------------------*/
5624 /*----------------------------*/
5626 fprintf(outfile,"MOD (%p) type (",tree);
5627 printTypeChain(tree->ftype,outfile);
5628 fprintf(outfile,")\n");
5629 ast_print(tree->left,outfile,indent+2);
5630 ast_print(tree->right,outfile,indent+2);
5633 /*------------------------------------------------------------------*/
5634 /*----------------------------*/
5635 /* address dereference */
5636 /*----------------------------*/
5637 case '*': /* can be unary : if right is null then unary operation */
5639 fprintf(outfile,"DEREF (%p) type (",tree);
5640 printTypeChain(tree->ftype,outfile);
5641 fprintf(outfile,")\n");
5642 ast_print(tree->left,outfile,indent+2);
5645 /*------------------------------------------------------------------*/
5646 /*----------------------------*/
5647 /* multiplication */
5648 /*----------------------------*/
5649 fprintf(outfile,"MULT (%p) type (",tree);
5650 printTypeChain(tree->ftype,outfile);
5651 fprintf(outfile,")\n");
5652 ast_print(tree->left,outfile,indent+2);
5653 ast_print(tree->right,outfile,indent+2);
5657 /*------------------------------------------------------------------*/
5658 /*----------------------------*/
5659 /* unary '+' operator */
5660 /*----------------------------*/
5664 fprintf(outfile,"UPLUS (%p) type (",tree);
5665 printTypeChain(tree->ftype,outfile);
5666 fprintf(outfile,")\n");
5667 ast_print(tree->left,outfile,indent+2);
5669 /*------------------------------------------------------------------*/
5670 /*----------------------------*/
5672 /*----------------------------*/
5673 fprintf(outfile,"ADD (%p) type (",tree);
5674 printTypeChain(tree->ftype,outfile);
5675 fprintf(outfile,")\n");
5676 ast_print(tree->left,outfile,indent+2);
5677 ast_print(tree->right,outfile,indent+2);
5680 /*------------------------------------------------------------------*/
5681 /*----------------------------*/
5683 /*----------------------------*/
5684 case '-': /* can be unary */
5686 fprintf(outfile,"UMINUS (%p) type (",tree);
5687 printTypeChain(tree->ftype,outfile);
5688 fprintf(outfile,")\n");
5689 ast_print(tree->left,outfile,indent+2);
5691 /*------------------------------------------------------------------*/
5692 /*----------------------------*/
5694 /*----------------------------*/
5695 fprintf(outfile,"SUB (%p) type (",tree);
5696 printTypeChain(tree->ftype,outfile);
5697 fprintf(outfile,")\n");
5698 ast_print(tree->left,outfile,indent+2);
5699 ast_print(tree->right,outfile,indent+2);
5702 /*------------------------------------------------------------------*/
5703 /*----------------------------*/
5705 /*----------------------------*/
5707 fprintf(outfile,"COMPL (%p) type (",tree);
5708 printTypeChain(tree->ftype,outfile);
5709 fprintf(outfile,")\n");
5710 ast_print(tree->left,outfile,indent+2);
5712 /*------------------------------------------------------------------*/
5713 /*----------------------------*/
5715 /*----------------------------*/
5717 fprintf(outfile,"NOT (%p) type (",tree);
5718 printTypeChain(tree->ftype,outfile);
5719 fprintf(outfile,")\n");
5720 ast_print(tree->left,outfile,indent+2);
5722 /*------------------------------------------------------------------*/
5723 /*----------------------------*/
5725 /*----------------------------*/
5727 fprintf(outfile,"RRC (%p) type (",tree);
5728 printTypeChain(tree->ftype,outfile);
5729 fprintf(outfile,")\n");
5730 ast_print(tree->left,outfile,indent+2);
5734 fprintf(outfile,"RLC (%p) type (",tree);
5735 printTypeChain(tree->ftype,outfile);
5736 fprintf(outfile,")\n");
5737 ast_print(tree->left,outfile,indent+2);
5740 fprintf(outfile,"SWAP (%p) type (",tree);
5741 printTypeChain(tree->ftype,outfile);
5742 fprintf(outfile,")\n");
5743 ast_print(tree->left,outfile,indent+2);
5746 fprintf(outfile,"GETHBIT (%p) type (",tree);
5747 printTypeChain(tree->ftype,outfile);
5748 fprintf(outfile,")\n");
5749 ast_print(tree->left,outfile,indent+2);
5752 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5753 printTypeChain(tree->ftype,outfile);
5754 fprintf(outfile,")\n");
5755 ast_print(tree->left,outfile,indent+2);
5756 ast_print(tree->right,outfile,indent+2);
5759 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5760 printTypeChain(tree->ftype,outfile);
5761 fprintf(outfile,")\n");
5762 ast_print(tree->left,outfile,indent+2);
5763 ast_print(tree->right,outfile,indent+2);
5765 /*------------------------------------------------------------------*/
5766 /*----------------------------*/
5768 /*----------------------------*/
5769 case CAST: /* change the type */
5770 fprintf(outfile,"CAST (%p) from type (",tree);
5771 printTypeChain(tree->right->ftype,outfile);
5772 fprintf(outfile,") to type (");
5773 printTypeChain(tree->ftype,outfile);
5774 fprintf(outfile,")\n");
5775 ast_print(tree->right,outfile,indent+2);
5779 fprintf(outfile,"ANDAND (%p) type (",tree);
5780 printTypeChain(tree->ftype,outfile);
5781 fprintf(outfile,")\n");
5782 ast_print(tree->left,outfile,indent+2);
5783 ast_print(tree->right,outfile,indent+2);
5786 fprintf(outfile,"OROR (%p) type (",tree);
5787 printTypeChain(tree->ftype,outfile);
5788 fprintf(outfile,")\n");
5789 ast_print(tree->left,outfile,indent+2);
5790 ast_print(tree->right,outfile,indent+2);
5793 /*------------------------------------------------------------------*/
5794 /*----------------------------*/
5795 /* comparison operators */
5796 /*----------------------------*/
5798 fprintf(outfile,"GT(>) (%p) type (",tree);
5799 printTypeChain(tree->ftype,outfile);
5800 fprintf(outfile,")\n");
5801 ast_print(tree->left,outfile,indent+2);
5802 ast_print(tree->right,outfile,indent+2);
5805 fprintf(outfile,"LT(<) (%p) type (",tree);
5806 printTypeChain(tree->ftype,outfile);
5807 fprintf(outfile,")\n");
5808 ast_print(tree->left,outfile,indent+2);
5809 ast_print(tree->right,outfile,indent+2);
5812 fprintf(outfile,"LE(<=) (%p) type (",tree);
5813 printTypeChain(tree->ftype,outfile);
5814 fprintf(outfile,")\n");
5815 ast_print(tree->left,outfile,indent+2);
5816 ast_print(tree->right,outfile,indent+2);
5819 fprintf(outfile,"GE(>=) (%p) type (",tree);
5820 printTypeChain(tree->ftype,outfile);
5821 fprintf(outfile,")\n");
5822 ast_print(tree->left,outfile,indent+2);
5823 ast_print(tree->right,outfile,indent+2);
5826 fprintf(outfile,"EQ(==) (%p) type (",tree);
5827 printTypeChain(tree->ftype,outfile);
5828 fprintf(outfile,")\n");
5829 ast_print(tree->left,outfile,indent+2);
5830 ast_print(tree->right,outfile,indent+2);
5833 fprintf(outfile,"NE(!=) (%p) type (",tree);
5834 printTypeChain(tree->ftype,outfile);
5835 fprintf(outfile,")\n");
5836 ast_print(tree->left,outfile,indent+2);
5837 ast_print(tree->right,outfile,indent+2);
5838 /*------------------------------------------------------------------*/
5839 /*----------------------------*/
5841 /*----------------------------*/
5842 case SIZEOF: /* evaluate wihout code generation */
5843 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5846 /*------------------------------------------------------------------*/
5847 /*----------------------------*/
5848 /* conditional operator '?' */
5849 /*----------------------------*/
5851 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5852 printTypeChain(tree->ftype,outfile);
5853 fprintf(outfile,")\n");
5854 ast_print(tree->left,outfile,indent+2);
5855 ast_print(tree->right,outfile,indent+2);
5859 fprintf(outfile,"COLON(:) (%p) type (",tree);
5860 printTypeChain(tree->ftype,outfile);
5861 fprintf(outfile,")\n");
5862 ast_print(tree->left,outfile,indent+2);
5863 ast_print(tree->right,outfile,indent+2);
5866 /*------------------------------------------------------------------*/
5867 /*----------------------------*/
5868 /* assignment operators */
5869 /*----------------------------*/
5871 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5872 printTypeChain(tree->ftype,outfile);
5873 fprintf(outfile,")\n");
5874 ast_print(tree->left,outfile,indent+2);
5875 ast_print(tree->right,outfile,indent+2);
5878 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5879 printTypeChain(tree->ftype,outfile);
5880 fprintf(outfile,")\n");
5881 ast_print(tree->left,outfile,indent+2);
5882 ast_print(tree->right,outfile,indent+2);
5885 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5886 printTypeChain(tree->ftype,outfile);
5887 fprintf(outfile,")\n");
5888 ast_print(tree->left,outfile,indent+2);
5889 ast_print(tree->right,outfile,indent+2);
5892 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5893 printTypeChain(tree->ftype,outfile);
5894 fprintf(outfile,")\n");
5895 ast_print(tree->left,outfile,indent+2);
5896 ast_print(tree->right,outfile,indent+2);
5899 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5900 printTypeChain(tree->ftype,outfile);
5901 fprintf(outfile,")\n");
5902 ast_print(tree->left,outfile,indent+2);
5903 ast_print(tree->right,outfile,indent+2);
5906 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5907 printTypeChain(tree->ftype,outfile);
5908 fprintf(outfile,")\n");
5909 ast_print(tree->left,outfile,indent+2);
5910 ast_print(tree->right,outfile,indent+2);
5913 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5914 printTypeChain(tree->ftype,outfile);
5915 fprintf(outfile,")\n");
5916 ast_print(tree->left,outfile,indent+2);
5917 ast_print(tree->right,outfile,indent+2);
5919 /*------------------------------------------------------------------*/
5920 /*----------------------------*/
5922 /*----------------------------*/
5924 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5925 printTypeChain(tree->ftype,outfile);
5926 fprintf(outfile,")\n");
5927 ast_print(tree->left,outfile,indent+2);
5928 ast_print(tree->right,outfile,indent+2);
5930 /*------------------------------------------------------------------*/
5931 /*----------------------------*/
5933 /*----------------------------*/
5935 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5936 printTypeChain(tree->ftype,outfile);
5937 fprintf(outfile,")\n");
5938 ast_print(tree->left,outfile,indent+2);
5939 ast_print(tree->right,outfile,indent+2);
5941 /*------------------------------------------------------------------*/
5942 /*----------------------------*/
5943 /* straight assignemnt */
5944 /*----------------------------*/
5946 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5947 printTypeChain(tree->ftype,outfile);
5948 fprintf(outfile,")\n");
5949 ast_print(tree->left,outfile,indent+2);
5950 ast_print(tree->right,outfile,indent+2);
5952 /*------------------------------------------------------------------*/
5953 /*----------------------------*/
5954 /* comma operator */
5955 /*----------------------------*/
5957 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5958 printTypeChain(tree->ftype,outfile);
5959 fprintf(outfile,")\n");
5960 ast_print(tree->left,outfile,indent+2);
5961 ast_print(tree->right,outfile,indent+2);
5963 /*------------------------------------------------------------------*/
5964 /*----------------------------*/
5966 /*----------------------------*/
5969 fprintf(outfile,"CALL (%p) type (",tree);
5970 printTypeChain(tree->ftype,outfile);
5971 fprintf(outfile,")\n");
5972 ast_print(tree->left,outfile,indent+2);
5973 ast_print(tree->right,outfile,indent+2);
5976 fprintf(outfile,"PARMS\n");
5977 ast_print(tree->left,outfile,indent+2);
5978 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5979 ast_print(tree->right,outfile,indent+2);
5982 /*------------------------------------------------------------------*/
5983 /*----------------------------*/
5984 /* return statement */
5985 /*----------------------------*/
5987 fprintf(outfile,"RETURN (%p) type (",tree);
5989 printTypeChain(tree->right->ftype,outfile);
5991 fprintf(outfile,")\n");
5992 ast_print(tree->right,outfile,indent+2);
5994 /*------------------------------------------------------------------*/
5995 /*----------------------------*/
5996 /* label statement */
5997 /*----------------------------*/
5999 fprintf(outfile,"LABEL (%p)\n",tree);
6000 ast_print(tree->left,outfile,indent+2);
6001 ast_print(tree->right,outfile,indent);
6003 /*------------------------------------------------------------------*/
6004 /*----------------------------*/
6005 /* switch statement */
6006 /*----------------------------*/
6010 fprintf(outfile,"SWITCH (%p) ",tree);
6011 ast_print(tree->left,outfile,0);
6012 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6013 INDENT(indent+2,outfile);
6014 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6015 (int) floatFromVal(val),
6016 tree->values.switchVals.swNum,
6017 (int) floatFromVal(val));
6019 ast_print(tree->right,outfile,indent);
6022 /*------------------------------------------------------------------*/
6023 /*----------------------------*/
6025 /*----------------------------*/
6027 fprintf(outfile,"IF (%p) \n",tree);
6028 ast_print(tree->left,outfile,indent+2);
6029 if (tree->trueLabel) {
6030 INDENT(indent+2,outfile);
6031 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6033 if (tree->falseLabel) {
6034 INDENT(indent+2,outfile);
6035 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6037 ast_print(tree->right,outfile,indent+2);
6039 /*----------------------------*/
6040 /* goto Statement */
6041 /*----------------------------*/
6043 fprintf(outfile,"GOTO (%p) \n",tree);
6044 ast_print(tree->left,outfile,indent+2);
6045 fprintf(outfile,"\n");
6047 /*------------------------------------------------------------------*/
6048 /*----------------------------*/
6050 /*----------------------------*/
6052 fprintf(outfile,"FOR (%p) \n",tree);
6053 if (AST_FOR( tree, initExpr)) {
6054 INDENT(indent+2,outfile);
6055 fprintf(outfile,"INIT EXPR ");
6056 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6058 if (AST_FOR( tree, condExpr)) {
6059 INDENT(indent+2,outfile);
6060 fprintf(outfile,"COND EXPR ");
6061 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6063 if (AST_FOR( tree, loopExpr)) {
6064 INDENT(indent+2,outfile);
6065 fprintf(outfile,"LOOP EXPR ");
6066 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6068 fprintf(outfile,"FOR LOOP BODY \n");
6069 ast_print(tree->left,outfile,indent+2);
6072 fprintf(outfile,"CRITICAL (%p) \n",tree);
6073 ast_print(tree->left,outfile,indent+2);
6081 ast_print(t,stdout,0);
6086 /*-----------------------------------------------------------------*/
6087 /* astErrors : returns non-zero if errors present in tree */
6088 /*-----------------------------------------------------------------*/
6089 int astErrors(ast *t)
6098 if (t->type == EX_VALUE
6099 && t->opval.val->sym
6100 && t->opval.val->sym->undefined)
6103 errors += astErrors(t->left);
6104 errors += astErrors(t->right);