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 int count; /* number of inline functions inserted */
36 symbol * retsym; /* variable for inlined function return value */
37 symbol * retlab; /* label ending inlined function (virtual return) */
40 #define LRVAL(x) x->left->rvalue
41 #define RRVAL(x) x->right->rvalue
42 #define TRVAL(x) x->rvalue
43 #define LLVAL(x) x->left->lvalue
44 #define RLVAL(x) x->right->lvalue
45 #define TLVAL(x) x->lvalue
46 #define RTYPE(x) x->right->ftype
47 #define RETYPE(x) x->right->etype
48 #define LTYPE(x) x->left->ftype
49 #define LETYPE(x) x->left->etype
50 #define TTYPE(x) x->ftype
51 #define TETYPE(x) x->etype
57 symbol *currFunc=NULL;
58 static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
59 static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
60 static ast *optimizeCompare (ast *);
61 ast *optimizeRRCRLC (ast *);
62 ast *optimizeSWAP (ast *);
63 ast *optimizeGetHbit (ast *, RESULT_TYPE);
64 ast *optimizeGetAbit (ast *, RESULT_TYPE);
65 ast *optimizeGetByte (ast *, RESULT_TYPE);
66 ast *optimizeGetWord (ast *, RESULT_TYPE);
67 static ast *backPatchLabels (ast *, symbol *, symbol *);
70 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
71 struct dbuf_s *codeOutBuf;
75 printTypeChain (tree->ftype, stdout);
80 /*-----------------------------------------------------------------*/
81 /* newAst - creates a fresh node for an expression tree */
82 /*-----------------------------------------------------------------*/
84 newAst_ (unsigned type)
87 static int oldLineno = 0;
89 ex = Safe_alloc ( sizeof (ast));
92 ex->lineno = (noLineno ? oldLineno : lexLineno);
93 ex->filename = lexFilename;
94 ex->level = NestLevel;
95 ex->block = currBlockno;
96 ex->initMode = inInitMode;
97 ex->seqPoint = seqPointNo;
102 newAst_VALUE (value * val)
104 ast *ex = newAst_ (EX_VALUE);
110 newAst_OP (unsigned op)
112 ast *ex = newAst_ (EX_OP);
118 newAst_LINK (sym_link * val)
120 ast *ex = newAst_ (EX_LINK);
125 /*-----------------------------------------------------------------*/
126 /* newNode - creates a new node */
127 /*-----------------------------------------------------------------*/
129 newNode (long op, ast * left, ast * right)
140 /*-----------------------------------------------------------------*/
141 /* newIfxNode - creates a new Ifx Node */
142 /*-----------------------------------------------------------------*/
144 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
148 /* if this is a literal then we already know the result */
149 if (condAst->etype && IS_LITERAL (condAst->etype))
151 /* then depending on the expression value */
152 if (floatFromVal (condAst->opval.val))
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (trueLabel)),
157 ifxNode = newNode (GOTO,
158 newAst_VALUE (symbolVal (falseLabel)),
163 ifxNode = newNode (IFX, condAst, NULL);
164 ifxNode->trueLabel = trueLabel;
165 ifxNode->falseLabel = falseLabel;
171 /*-----------------------------------------------------------------*/
172 /* copyAstValues - copies value portion of ast if needed */
173 /*-----------------------------------------------------------------*/
175 copyAstValues (ast * dest, ast * src)
177 switch (src->opval.op)
180 dest->values.sym = copySymbolChain (src->values.sym);
184 dest->values.switchVals.swVals =
185 copyValue (src->values.switchVals.swVals);
186 dest->values.switchVals.swDefault =
187 src->values.switchVals.swDefault;
188 dest->values.switchVals.swNum =
189 src->values.switchVals.swNum;
193 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
197 dest->values.constlist = copyLiteralList(src->values.constlist);
201 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
202 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
203 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
204 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
205 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
206 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
207 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
212 /*-----------------------------------------------------------------*/
213 /* copyAst - makes a copy of a given astession */
214 /*-----------------------------------------------------------------*/
223 dest = Safe_alloc ( sizeof (ast));
225 dest->type = src->type;
226 dest->lineno = src->lineno;
227 dest->level = src->level;
228 dest->funcName = src->funcName;
229 dest->reversed = src->reversed;
232 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
234 /* if this is a leaf */
236 if (src->type == EX_VALUE)
238 dest->opval.val = copyValue (src->opval.val);
243 if (src->type == EX_LINK)
245 dest->opval.lnk = copyLinkChain (src->opval.lnk);
249 dest->opval.op = src->opval.op;
251 /* if this is a node that has special values */
252 copyAstValues (dest, src);
254 dest->trueLabel = copySymbol (src->trueLabel);
255 dest->falseLabel = copySymbol (src->falseLabel);
256 dest->left = copyAst (src->left);
257 dest->right = copyAst (src->right);
263 /*-----------------------------------------------------------------*/
264 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
265 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
266 /*-----------------------------------------------------------------*/
267 ast *removeIncDecOps (ast * tree) {
269 // traverse the tree and remove inc/dec ops
274 if (tree->type == EX_OP &&
275 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
282 tree->left=removeIncDecOps(tree->left);
283 tree->right=removeIncDecOps(tree->right);
288 /*-----------------------------------------------------------------*/
289 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
290 /* "*++s += 3" -> "*++s = *++s + 3" */
291 /*-----------------------------------------------------------------*/
292 ast *removePreIncDecOps (ast * tree) {
294 // traverse the tree and remove pre-inc/dec ops
299 if (tree->type == EX_OP &&
300 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
305 tree->left=removePreIncDecOps(tree->left);
306 tree->right=removePreIncDecOps(tree->right);
311 /*-----------------------------------------------------------------*/
312 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
313 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
314 /*-----------------------------------------------------------------*/
315 ast *removePostIncDecOps (ast * tree) {
317 // traverse the tree and remove pre-inc/dec ops
322 if (tree->type == EX_OP &&
323 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
328 tree->left=removePostIncDecOps(tree->left);
329 tree->right=removePostIncDecOps(tree->right);
334 /*-----------------------------------------------------------------*/
335 /* replaceAstWithTemporary: Replace the AST pointed to by the arg */
336 /* with a reference to a new temporary variable. Returns*/
337 /* an AST which assigns the original value to the */
339 /*-----------------------------------------------------------------*/
340 static ast *replaceAstWithTemporary(ast **treeptr)
342 symbol *sym = newSymbol (genSymName(NestLevel), NestLevel );
345 /* Tell gatherImplicitVariables() to automatically give the
346 symbol the correct type */
351 tempvar = newNode('=', newAst_VALUE(symbolVal(sym)), *treeptr);
352 *treeptr = newAst_VALUE(symbolVal(sym));
359 /*-----------------------------------------------------------------*/
360 /* createRMW: Create a read-modify-write expression, using a */
361 /* temporary variable if necessary to avoid duplicating */
362 /* any side effects, for use in e.g. */
363 /* foo()->count += 5; becomes */
364 /* tmp = foo(); tmp->count = tmp->count + 5; */
365 /*-----------------------------------------------------------------*/
366 ast * createRMW (ast *target, unsigned op, ast *operand)
368 ast *readval, *writeval;
369 ast *tempvar1 = NULL;
370 ast *tempvar2 = NULL;
373 if (!target || !operand) {
377 /* we need to create two copies of target: one to read from and
378 one to write to. but we need to do this without duplicating
379 any side effects that may be contained in the tree. */
381 if (IS_AST_OP(target)) {
382 /* if this is a dereference, put the referenced item in the temporary */
383 if (IS_DEREF_OP(target) || target->opval.op == PTR_OP) {
384 /* create a new temporary containing the item being dereferenced */
385 if (hasSEFcalls(target->left))
386 tempvar1 = replaceAstWithTemporary(&(target->left));
387 } else if (target->opval.op == '[') {
388 /* Array access is similar, but we have to avoid side effects in
389 both values [WIML: Why not transform a[b] to *(a+b) in parser?] */
390 if (hasSEFcalls(target->left))
391 tempvar1 = replaceAstWithTemporary(&(target->left));
392 if (hasSEFcalls(target->right))
393 tempvar2 = replaceAstWithTemporary(&(target->right));
395 /* we would have to handle '.', but it is not generated any more */
396 wassertl(target->opval.op != '.', "obsolete opcode in tree");
398 /* no other kinds of ASTs are lvalues and can contain side effects */
403 writeval = copyAst(target);
405 result = newNode('=', writeval, newNode(op, readval, operand));
407 result = newNode(',', tempvar2, result);
409 result = newNode(',', tempvar1, result);
415 /*-----------------------------------------------------------------*/
416 /* hasSEFcalls - returns TRUE if tree has a function call, */
417 /* inc/decrement, or other side effect */
418 /*-----------------------------------------------------------------*/
420 hasSEFcalls (ast * tree)
425 if (tree->type == EX_OP &&
426 (tree->opval.op == CALL ||
427 tree->opval.op == PCALL ||
428 tree->opval.op == '=' ||
429 tree->opval.op == INC_OP ||
430 tree->opval.op == DEC_OP))
433 return (hasSEFcalls (tree->left) |
434 hasSEFcalls (tree->right));
437 /*-----------------------------------------------------------------*/
438 /* isAstEqual - compares two asts & returns 1 if they are equal */
439 /*-----------------------------------------------------------------*/
441 isAstEqual (ast * t1, ast * t2)
450 if (t1->type != t2->type)
456 if (t1->opval.op != t2->opval.op)
458 return (isAstEqual (t1->left, t2->left) &&
459 isAstEqual (t1->right, t2->right));
463 if (t1->opval.val->sym)
465 if (!t2->opval.val->sym)
468 return isSymbolEqual (t1->opval.val->sym,
473 if (t2->opval.val->sym)
476 return (floatFromVal (t1->opval.val) ==
477 floatFromVal (t2->opval.val));
481 /* only compare these two types */
489 /*-----------------------------------------------------------------*/
490 /* resolveSymbols - resolve symbols from the symbol table */
491 /*-----------------------------------------------------------------*/
493 resolveSymbols (ast * tree)
495 /* walk the entire tree and check for values */
496 /* with symbols if we find one then replace */
497 /* symbol with that from the symbol table */
504 /* if not block & function */
505 if (tree->type == EX_OP &&
506 (tree->opval.op != FUNCTION &&
507 tree->opval.op != BLOCK &&
508 tree->opval.op != NULLOP))
510 filename = tree->filename;
511 lineno = tree->lineno;
515 /* make sure we resolve the true & false labels for ifx */
516 if (tree->type == EX_OP && tree->opval.op == IFX)
522 if ((csym = findSym (LabelTab, tree->trueLabel,
523 tree->trueLabel->name)))
524 tree->trueLabel = csym;
526 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
527 tree->trueLabel->name);
530 if (tree->falseLabel)
532 if ((csym = findSym (LabelTab,
534 tree->falseLabel->name)))
535 tree->falseLabel = csym;
537 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
538 tree->falseLabel->name);
543 /* if this is a label resolve it from the labelTab */
544 if (IS_AST_VALUE (tree) &&
545 tree->opval.val->sym &&
546 tree->opval.val->sym->islbl)
549 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
550 tree->opval.val->sym->name);
553 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
554 tree->opval.val->sym->name);
556 tree->opval.val->sym = csym;
558 goto resolveChildren;
561 /* do only for leafs */
562 if (IS_AST_VALUE (tree) &&
563 tree->opval.val->sym &&
564 !tree->opval.val->sym->implicit)
567 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
569 /* if found in the symbol table & they r not the same */
570 if (csym && tree->opval.val->sym != csym)
572 tree->opval.val->sym = csym;
573 tree->opval.val->type = csym->type;
574 tree->opval.val->etype = csym->etype;
577 /* if not found in the symbol table */
578 /* mark it as undefined assume it is */
579 /* an integer in data space */
580 if (!csym && !tree->opval.val->sym->implicit)
583 /* if this is a function name then */
584 /* mark it as returning an int */
587 tree->opval.val->sym->type = newLink (DECLARATOR);
588 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
589 tree->opval.val->sym->type->next =
590 tree->opval.val->sym->etype = newIntLink ();
591 tree->opval.val->etype = tree->opval.val->etype;
592 tree->opval.val->type = tree->opval.val->sym->type;
593 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
594 tree->opval.val->sym->name);
595 //tree->opval.val->sym->undefined = 1;
596 allocVariables (tree->opval.val->sym);
600 tree->opval.val->sym->undefined = 1;
601 tree->opval.val->type =
602 tree->opval.val->etype = newIntLink ();
603 tree->opval.val->sym->type =
604 tree->opval.val->sym->etype = newIntLink ();
610 resolveSymbols (tree->left);
611 resolveSymbols (tree->right);
616 /*-----------------------------------------------------------------*/
617 /* setAstLineno - walks a ast tree & sets the line number */
618 /*-----------------------------------------------------------------*/
619 int setAstLineno (ast * tree, int lineno)
624 tree->lineno = lineno;
625 setAstLineno (tree->left, lineno);
626 setAstLineno (tree->right, lineno);
630 /*-----------------------------------------------------------------*/
631 /* funcOfType :- function of type with name */
632 /*-----------------------------------------------------------------*/
634 funcOfType (char *name, sym_link * type, sym_link * argType,
638 /* create the symbol */
639 sym = newSymbol (name, 0);
641 /* setup return value */
642 sym->type = newLink (DECLARATOR);
643 DCL_TYPE (sym->type) = FUNCTION;
644 sym->type->next = copyLinkChain (type);
645 sym->etype = getSpec (sym->type);
646 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
648 /* if arguments required */
652 args = FUNC_ARGS(sym->type) = newValue ();
656 args->type = copyLinkChain (argType);
657 args->etype = getSpec (args->type);
658 SPEC_EXTR(args->etype)=1;
661 args = args->next = newValue ();
668 allocVariables (sym);
673 /*-----------------------------------------------------------------*/
674 /* funcOfTypeVarg :- function of type with name and argtype */
675 /*-----------------------------------------------------------------*/
677 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
682 /* create the symbol */
683 sym = newSymbol (name, 0);
685 /* setup return value */
686 sym->type = newLink (DECLARATOR);
687 DCL_TYPE (sym->type) = FUNCTION;
688 sym->type->next = typeFromStr(rtype);
689 sym->etype = getSpec (sym->type);
691 /* if arguments required */
694 args = FUNC_ARGS(sym->type) = newValue ();
696 for ( i = 0 ; i < nArgs ; i++ ) {
697 args->type = typeFromStr(atypes[i]);
698 args->etype = getSpec (args->type);
699 SPEC_EXTR(args->etype)=1;
700 if ((i + 1) == nArgs) break;
701 args = args->next = newValue ();
708 allocVariables (sym);
713 /*-----------------------------------------------------------------*/
714 /* reverseParms - will reverse a parameter tree */
715 /*-----------------------------------------------------------------*/
717 reverseParms (ast * ptree)
723 /* top down if we find a nonParm tree then quit */
724 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
726 /* The various functions expect the parameter tree to be right heavy. */
727 /* Rotate the tree to be left heavy so that after reversal it is */
728 /* right heavy again. */
729 while ((ttree = ptree->right) && ttree->type == EX_OP &&
730 ttree->opval.op == PARAM)
732 ptree->right = ttree->right;
733 ttree->right = ttree->left;
734 ttree->left = ptree->left;
740 ptree->left = ptree->right;
741 ptree->right = ttree;
743 reverseParms (ptree->left);
744 reverseParms (ptree->right);
750 /*-----------------------------------------------------------------*/
751 /* processParms - makes sure the parameters are okay and do some */
752 /* processing with them */
753 /*-----------------------------------------------------------------*/
755 processParms (ast *func,
758 int *parmNumber, /* unused, although updated */
761 RESULT_TYPE resultType;
764 /* if none of them exist */
765 if (!defParm && !*actParm)
770 if (getenv("DEBUG_SANITY"))
772 fprintf (stderr, "processParms: %s ", defParm->name);
774 /* make sure the type is complete and sane */
775 checkTypeSanity(defParm->etype, defParm->name);
778 if (IS_CODEPTR (func->ftype))
779 functype = func->ftype->next;
781 functype = func->ftype;
783 /* if the function is being called via a pointer & */
784 /* it has not been defined a reentrant then we cannot */
785 /* have parameters */
786 /* PIC16 port can... */
787 if (!TARGET_IS_PIC16)
789 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
791 werror (W_NONRENT_ARGS);
797 /* if defined parameters ended but actual parameters */
798 /* exist and this is not defined as a variable arg */
799 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
801 werror (E_TOO_MANY_PARMS);
805 /* if defined parameters present but no actual parameters */
806 if (defParm && !*actParm)
808 werror (E_TOO_FEW_PARMS);
812 /* if this is a PARAM node then match left & right */
813 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
815 (*actParm)->decorated = 1;
816 return (processParms (func, defParm,
817 &(*actParm)->left, parmNumber, FALSE) ||
818 processParms (func, defParm ? defParm->next : NULL,
819 &(*actParm)->right, parmNumber, rightmost));
821 else if (defParm) /* not vararg */
823 /* If we have found a value node by following only right-hand links,
824 * then we know that there are no more values after us.
826 * Therefore, if there are more defined parameters, the caller didn't
829 if (rightmost && defParm->next)
831 werror (E_TOO_FEW_PARMS);
836 /* decorate parameter */
837 resultType = defParm ? getResultTypeFromType (defParm->type) :
839 *actParm = decorateType (*actParm, resultType);
841 if (IS_VOID((*actParm)->ftype))
843 werror (E_VOID_VALUE_USED);
847 /* If this is a varargs function... */
848 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
853 if (IS_CAST_OP (*actParm)
854 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
856 /* Parameter was explicitly typecast; don't touch it. */
860 ftype = (*actParm)->ftype;
862 /* If it's a char, upcast to int. */
863 if (IS_INTEGRAL (ftype)
864 && (getSize (ftype) < (unsigned) INTSIZE))
866 newType = newAst_LINK(INTTYPE);
869 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
871 newType = newAst_LINK (copyLinkChain(ftype));
872 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
875 if (IS_AGGREGATE (ftype))
877 newType = newAst_LINK (copyLinkChain (ftype));
878 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
883 /* cast required; change this op to a cast. */
884 (*actParm)->decorated = 0;
885 *actParm = newNode (CAST, newType, *actParm);
886 (*actParm)->lineno = (*actParm)->right->lineno;
888 decorateType (*actParm, RESULT_TYPE_NONE);
893 /* if defined parameters ended but actual has not & */
895 if (!defParm && *actParm &&
896 (options.stackAuto || IFFUNC_ISREENT (functype)))
899 resolveSymbols (*actParm);
901 /* the parameter type must be at least castable */
902 if (compareType (defParm->type, (*actParm)->ftype) == 0)
904 werror (E_INCOMPAT_TYPES);
905 printFromToType ((*actParm)->ftype, defParm->type);
909 /* if the parameter is castable then add the cast */
910 if (compareType (defParm->type, (*actParm)->ftype) < 0)
914 resultType = getResultTypeFromType (defParm->etype);
915 pTree = resolveSymbols (copyAst (*actParm));
917 /* now change the current one to a cast */
918 (*actParm)->type = EX_OP;
919 (*actParm)->opval.op = CAST;
920 (*actParm)->left = newAst_LINK (defParm->type);
921 (*actParm)->right = pTree;
922 (*actParm)->decorated = 0; /* force typechecking */
923 decorateType (*actParm, resultType);
926 /* make a copy and change the regparm type to the defined parm */
927 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
928 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
929 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
934 /*-----------------------------------------------------------------*/
935 /* createIvalType - generates ival for basic types */
936 /*-----------------------------------------------------------------*/
938 createIvalType (ast * sym, sym_link * type, initList * ilist)
942 /* if initList is deep */
943 if (ilist->type == INIT_DEEP)
944 ilist = ilist->init.deep;
946 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
947 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
950 /*-----------------------------------------------------------------*/
951 /* createIvalStruct - generates initial value for structures */
952 /*-----------------------------------------------------------------*/
954 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
961 sflds = SPEC_STRUCT (type)->fields;
962 if (ilist->type != INIT_DEEP)
964 werror (E_INIT_STRUCT, "");
968 iloop = ilist->init.deep;
970 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
972 /* if we have come to end */
976 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
977 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
978 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
979 iloop, rast, rootValue)),
985 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
986 W_EXCESS_INITIALIZERS, "struct",
987 sym->opval.val->sym->name);
994 /*-----------------------------------------------------------------*/
995 /* createIvalArray - generates code for array initialization */
996 /*-----------------------------------------------------------------*/
998 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
1002 int lcnt = 0, size = 0;
1003 literalList *literalL;
1005 /* take care of the special case */
1006 /* array of characters can be init */
1008 if (IS_CHAR (type->next))
1009 if ((rast = createIvalCharPtr (sym,
1011 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
1014 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1016 /* not the special case */
1017 if (ilist->type != INIT_DEEP)
1019 werror (E_INIT_STRUCT, "");
1023 iloop = ilist->init.deep;
1024 lcnt = DCL_ELEM (type);
1026 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
1030 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
1032 rast = newNode(ARRAYINIT, aSym, NULL);
1033 rast->values.constlist = literalL;
1035 // Make sure size is set to length of initializer list.
1039 iloop = iloop->next;
1042 if (lcnt && size > lcnt)
1044 // Array size was specified, and we have more initializers than needed.
1045 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
1046 W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
1055 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
1056 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
1057 rast = createIval (aSym, type->next, iloop, rast, rootValue);
1058 iloop = (iloop ? iloop->next : NULL);
1064 /* no of elements given and we */
1065 /* have generated for all of them */
1068 // is this a better way? at least it won't crash
1069 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1070 werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name);
1077 /* if we have not been given a size */
1078 if (!DCL_ELEM (type))
1080 /* check, if it's a flexible array */
1081 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1082 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1084 DCL_ELEM (type) = size;
1087 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1091 /*-----------------------------------------------------------------*/
1092 /* createIvalCharPtr - generates initial values for char pointers */
1093 /*-----------------------------------------------------------------*/
1095 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1100 /* if this is a pointer & right is a literal array then */
1101 /* just assignment will do */
1102 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1103 SPEC_SCLS (iexpr->etype) == S_CODE)
1104 && IS_ARRAY (iexpr->ftype)))
1105 return newNode ('=', sym, iexpr);
1107 /* left side is an array so we have to assign each */
1109 if ((IS_LITERAL (iexpr->etype) ||
1110 SPEC_SCLS (iexpr->etype) == S_CODE)
1111 && IS_ARRAY (iexpr->ftype))
1113 /* for each character generate an assignment */
1114 /* to the array element */
1115 char *s = SPEC_CVAL (iexpr->etype).v_char;
1117 unsigned int symsize = getSize (type);
1119 size = getSize (iexpr->ftype);
1120 if (symsize && size>symsize)
1122 if (size>(symsize+1))
1124 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1126 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1132 for (i=0;i<size;i++)
1134 rast = newNode (NULLOP,
1138 newAst_VALUE (valueFromLit ((float) i))),
1139 newAst_VALUE (valueFromLit (*s))));
1143 // now WE don't need iexpr's symbol anymore
1144 freeStringSymbol(AST_SYMBOL(iexpr));
1146 /* if we have not been given a size */
1147 if (!DCL_ELEM (type))
1149 /* check, if it's a flexible array */
1150 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1151 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1153 DCL_ELEM (type) = size;
1156 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1162 /*-----------------------------------------------------------------*/
1163 /* createIvalPtr - generates initial value for pointers */
1164 /*-----------------------------------------------------------------*/
1166 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1172 if (ilist->type == INIT_DEEP)
1173 ilist = ilist->init.deep;
1175 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1177 /* if character pointer */
1178 if (IS_CHAR (type->next))
1179 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1182 return newNode ('=', sym, iexpr);
1185 /*-----------------------------------------------------------------*/
1186 /* createIval - generates code for initial value */
1187 /*-----------------------------------------------------------------*/
1189 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1196 /* if structure then */
1197 if (IS_STRUCT (type))
1198 rast = createIvalStruct (sym, type, ilist, rootValue);
1200 /* if this is a pointer */
1202 rast = createIvalPtr (sym, type, ilist, rootValue);
1204 /* if this is an array */
1205 if (IS_ARRAY (type))
1206 rast = createIvalArray (sym, type, ilist, rootValue);
1208 /* if type is SPECIFIER */
1210 rast = createIvalType (sym, type, ilist);
1213 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1215 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1218 /*-----------------------------------------------------------------*/
1219 /* initAggregates - initialises aggregate variables with initv */
1220 /*-----------------------------------------------------------------*/
1221 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1222 ast *newAst = newAst_VALUE (symbolVal (sym));
1223 return createIval (newAst, sym->type, ival, wid, newAst);
1226 /*-----------------------------------------------------------------*/
1227 /* gatherAutoInit - creates assignment expressions for initial */
1229 /*-----------------------------------------------------------------*/
1231 gatherAutoInit (symbol * autoChain)
1238 for (sym = autoChain; sym; sym = sym->next)
1241 /* resolve the symbols in the ival */
1243 resolveIvalSym (sym->ival, sym->type);
1246 /* if we are PIC16 port,
1247 * and this is a static,
1248 * and have initial value,
1249 * and not S_CODE, don't emit in gs segment,
1250 * but allow glue.c:pic16emitRegularMap to put symbol
1251 * in idata section */
1252 if(TARGET_IS_PIC16 &&
1253 IS_STATIC (sym->etype) && sym->ival
1254 && SPEC_SCLS(sym->etype) != S_CODE) {
1255 SPEC_SCLS (sym->etype) = S_DATA;
1260 /* if this is a static variable & has an */
1261 /* initial value the code needs to be lifted */
1262 /* here to the main portion since they can be */
1263 /* initialised only once at the start */
1264 if (IS_STATIC (sym->etype) && sym->ival &&
1265 SPEC_SCLS (sym->etype) != S_CODE)
1269 /* insert the symbol into the symbol table */
1270 /* with level = 0 & name = rname */
1271 newSym = copySymbol (sym);
1272 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1274 /* now lift the code to main */
1275 if (IS_AGGREGATE (sym->type)) {
1276 work = initAggregates (sym, sym->ival, NULL);
1278 if (getNelements(sym->type, sym->ival)>1) {
1279 werrorfl (sym->fileDef, sym->lineDef,
1280 W_EXCESS_INITIALIZERS, "scalar",
1283 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1284 list2expr (sym->ival));
1287 setAstLineno (work, sym->lineDef);
1291 staticAutos = newNode (NULLOP, staticAutos, work);
1298 /* if there is an initial value */
1299 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1301 initList *ilist=sym->ival;
1303 while (ilist->type == INIT_DEEP) {
1304 ilist = ilist->init.deep;
1307 /* update lineno for error msg */
1308 lineno = sym->lineDef;
1309 setAstLineno (ilist->init.node, sym->lineDef);
1311 if (IS_AGGREGATE (sym->type)) {
1312 work = initAggregates (sym, sym->ival, NULL);
1314 if (getNelements(sym->type, sym->ival)>1) {
1315 werrorfl (sym->fileDef, sym->lineDef,
1316 W_EXCESS_INITIALIZERS, "scalar",
1319 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1320 list2expr (sym->ival));
1324 setAstLineno (work, sym->lineDef);
1328 init = newNode (NULLOP, init, work);
1337 /*-----------------------------------------------------------------*/
1338 /* freeStringSymbol - delete a literal string if no more usage */
1339 /*-----------------------------------------------------------------*/
1340 void freeStringSymbol(symbol *sym) {
1341 /* make sure this is a literal string */
1342 assert (sym->isstrlit);
1343 if (--sym->isstrlit == 0) { // lower the usage count
1344 memmap *segment=SPEC_OCLS(sym->etype);
1346 deleteSetItem(&segment->syms, sym);
1351 /*-----------------------------------------------------------------*/
1352 /* stringToSymbol - creates a symbol from a literal string */
1353 /*-----------------------------------------------------------------*/
1355 stringToSymbol (value * val)
1357 char name[SDCC_NAME_MAX + 1];
1358 static int charLbl = 0;
1363 // have we heard this before?
1364 for (sp=statsg->syms; sp; sp=sp->next) {
1366 size = getSize (sym->type);
1367 if (sym->isstrlit && size == getSize (val->type) &&
1368 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1369 // yes, this is old news. Don't publish it again.
1370 sym->isstrlit++; // but raise the usage count
1371 return symbolVal(sym);
1375 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1376 sym = newSymbol (name, 0); /* make it @ level 0 */
1377 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1379 /* copy the type from the value passed */
1380 sym->type = copyLinkChain (val->type);
1381 sym->etype = getSpec (sym->type);
1382 /* change to storage class & output class */
1383 SPEC_SCLS (sym->etype) = S_CODE;
1384 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1385 SPEC_STAT (sym->etype) = 1;
1386 /* make the level & block = 0 */
1387 sym->block = sym->level = 0;
1389 /* create an ival */
1390 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1395 allocVariables (sym);
1398 return symbolVal (sym);
1402 /*-----------------------------------------------------------------*/
1403 /* processBlockVars - will go thru the ast looking for block if */
1404 /* a block is found then will allocate the syms */
1405 /* will also gather the auto inits present */
1406 /*-----------------------------------------------------------------*/
1408 processBlockVars (ast * tree, int *stack, int action)
1413 /* if this is a block */
1414 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1418 if (action == ALLOCATE)
1420 *stack += allocVariables (tree->values.sym);
1421 autoInit = gatherAutoInit (tree->values.sym);
1423 /* if there are auto inits then do them */
1425 tree->left = newNode (NULLOP, autoInit, tree->left);
1427 else /* action is deallocate */
1428 deallocLocal (tree->values.sym);
1431 processBlockVars (tree->left, stack, action);
1432 processBlockVars (tree->right, stack, action);
1437 /*-------------------------------------------------------------*/
1438 /* constExprTree - returns TRUE if this tree is a constant */
1440 /*-------------------------------------------------------------*/
1441 bool constExprTree (ast *cexpr) {
1447 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1449 switch (cexpr->type)
1452 if (IS_AST_LIT_VALUE(cexpr)) {
1453 // this is a literal
1456 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1457 // a function's address will never change
1460 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1461 // an array's address will never change
1464 if (IS_AST_SYM_VALUE(cexpr) &&
1465 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1466 // a symbol in code space will never change
1467 // This is only for the 'char *s="hallo"' case and will have to leave
1468 //printf(" code space symbol");
1473 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1474 "unexpected link in expression tree\n");
1477 if (cexpr->opval.op==ARRAYINIT) {
1478 // this is a list of literals
1481 if (cexpr->opval.op=='=') {
1482 return constExprTree(cexpr->right);
1484 if (cexpr->opval.op==CAST) {
1485 // cast ignored, maybe we should throw a warning here?
1486 return constExprTree(cexpr->right);
1488 if (cexpr->opval.op=='&') {
1491 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1494 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1499 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1504 /*-----------------------------------------------------------------*/
1505 /* constExprValue - returns the value of a constant expression */
1506 /* or NULL if it is not a constant expression */
1507 /*-----------------------------------------------------------------*/
1509 constExprValue (ast * cexpr, int check)
1511 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1513 /* if this is not a constant then */
1514 if (!IS_LITERAL (cexpr->ftype))
1516 /* then check if this is a literal array
1518 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1519 SPEC_CVAL (cexpr->etype).v_char &&
1520 IS_ARRAY (cexpr->ftype))
1522 value *val = valFromType (cexpr->ftype);
1523 SPEC_SCLS (val->etype) = S_LITERAL;
1524 val->sym = cexpr->opval.val->sym;
1525 val->sym->type = copyLinkChain (cexpr->ftype);
1526 val->sym->etype = getSpec (val->sym->type);
1527 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1531 /* if we are casting a literal value then */
1532 if (IS_AST_OP (cexpr) &&
1533 cexpr->opval.op == CAST &&
1534 IS_LITERAL (cexpr->right->ftype))
1536 return valCastLiteral (cexpr->ftype,
1537 floatFromVal (cexpr->right->opval.val));
1540 if (IS_AST_VALUE (cexpr))
1542 return cexpr->opval.val;
1546 werror (E_CONST_EXPECTED, "found expression");
1551 /* return the value */
1552 if (IS_AST_VALUE (cexpr))
1554 return cexpr->opval.val;
1559 /*-----------------------------------------------------------------*/
1560 /* isLabelInAst - will return true if a given label is found */
1561 /*-----------------------------------------------------------------*/
1563 isLabelInAst (symbol * label, ast * tree)
1565 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1568 if (IS_AST_OP (tree) &&
1569 tree->opval.op == LABEL &&
1570 isSymbolEqual (AST_SYMBOL (tree->left), label))
1573 return isLabelInAst (label, tree->right) &&
1574 isLabelInAst (label, tree->left);
1578 /*-----------------------------------------------------------------*/
1579 /* isLoopCountable - return true if the loop count can be determi- */
1580 /* -ned at compile time . */
1581 /*-----------------------------------------------------------------*/
1583 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1584 symbol ** sym, ast ** init, ast ** end)
1587 /* the loop is considered countable if the following
1588 conditions are true :-
1590 a) initExpr :- <sym> = <const>
1591 b) condExpr :- <sym> < <const1>
1592 c) loopExpr :- <sym> ++
1595 /* first check the initExpr */
1596 if (IS_AST_OP (initExpr) &&
1597 initExpr->opval.op == '=' && /* is assignment */
1598 IS_AST_SYM_VALUE (initExpr->left))
1599 { /* left is a symbol */
1601 *sym = AST_SYMBOL (initExpr->left);
1602 *init = initExpr->right;
1607 /* don't reverse loop with volatile counter */
1608 if (IS_VOLATILE ((*sym)->type))
1611 /* for now the symbol has to be of
1613 if (!IS_INTEGRAL ((*sym)->type))
1616 /* now check condExpr */
1617 if (IS_AST_OP (condExpr))
1620 switch (condExpr->opval.op)
1623 if (IS_AST_SYM_VALUE (condExpr->left) &&
1624 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1625 IS_AST_LIT_VALUE (condExpr->right))
1627 *end = condExpr->right;
1633 if (IS_AST_OP (condExpr->left) &&
1634 condExpr->left->opval.op == '>' &&
1635 IS_AST_LIT_VALUE (condExpr->left->right) &&
1636 IS_AST_SYM_VALUE (condExpr->left->left) &&
1637 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1640 *end = newNode ('+', condExpr->left->right,
1641 newAst_VALUE (constVal ("1")));
1654 /* check loop expression is of the form <sym>++ */
1655 if (!IS_AST_OP (loopExpr))
1658 /* check if <sym> ++ */
1659 if (loopExpr->opval.op == INC_OP)
1665 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1666 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1673 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1674 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1682 if (loopExpr->opval.op == ADD_ASSIGN)
1685 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1686 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1687 IS_AST_LIT_VALUE (loopExpr->right) &&
1688 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1696 /*-----------------------------------------------------------------*/
1697 /* astHasVolatile - returns true if ast contains any volatile */
1698 /*-----------------------------------------------------------------*/
1700 astHasVolatile (ast * tree)
1705 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1708 if (IS_AST_OP (tree))
1709 return astHasVolatile (tree->left) ||
1710 astHasVolatile (tree->right);
1715 /*-----------------------------------------------------------------*/
1716 /* astHasPointer - return true if the ast contains any ptr variable */
1717 /*-----------------------------------------------------------------*/
1719 astHasPointer (ast * tree)
1724 if (IS_AST_LINK (tree))
1727 /* if we hit an array expression then check
1728 only the left side */
1729 if (IS_AST_OP (tree) && tree->opval.op == '[')
1730 return astHasPointer (tree->left);
1732 if (IS_AST_VALUE (tree))
1733 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1735 return astHasPointer (tree->left) ||
1736 astHasPointer (tree->right);
1740 /*-----------------------------------------------------------------*/
1741 /* astHasSymbol - return true if the ast has the given symbol */
1742 /*-----------------------------------------------------------------*/
1744 astHasSymbol (ast * tree, symbol * sym)
1746 if (!tree || IS_AST_LINK (tree))
1749 if (IS_AST_VALUE (tree))
1751 if (IS_AST_SYM_VALUE (tree))
1752 return isSymbolEqual (AST_SYMBOL (tree), sym);
1757 return astHasSymbol (tree->left, sym) ||
1758 astHasSymbol (tree->right, sym);
1761 /*-----------------------------------------------------------------*/
1762 /* astHasDeref - return true if the ast has an indirect access */
1763 /*-----------------------------------------------------------------*/
1765 astHasDeref (ast * tree)
1767 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1770 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1772 return astHasDeref (tree->left) || astHasDeref (tree->right);
1775 /*-----------------------------------------------------------------*/
1776 /* isConformingBody - the loop body has to conform to a set of rules */
1777 /* for the loop to be considered reversible read on for rules */
1778 /*-----------------------------------------------------------------*/
1780 isConformingBody (ast * pbody, symbol * sym, ast * body)
1783 /* we are going to do a pre-order traversal of the
1784 tree && check for the following conditions. (essentially
1785 a set of very shallow tests )
1786 a) the sym passed does not participate in
1787 any arithmetic operation
1788 b) There are no function calls
1789 c) all jumps are within the body
1790 d) address of loop control variable not taken
1791 e) if an assignment has a pointer on the
1792 left hand side make sure right does not have
1793 loop control variable */
1795 /* if we reach the end or a leaf then true */
1796 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1799 /* if anything else is "volatile" */
1800 if (IS_VOLATILE (TETYPE (pbody)))
1803 /* we will walk the body in a pre-order traversal for
1805 switch (pbody->opval.op)
1807 /*------------------------------------------------------------------*/
1809 // if the loopvar is used as an index
1810 /* array op is commutative -- must check both left & right */
1811 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1814 return isConformingBody (pbody->right, sym, body)
1815 && isConformingBody (pbody->left, sym, body);
1817 /*------------------------------------------------------------------*/
1822 /*------------------------------------------------------------------*/
1826 /* sure we are not sym is not modified */
1828 IS_AST_SYM_VALUE (pbody->left) &&
1829 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1833 IS_AST_SYM_VALUE (pbody->right) &&
1834 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1839 /*------------------------------------------------------------------*/
1841 case '*': /* can be unary : if right is null then unary operation */
1846 /* if right is NULL then unary operation */
1847 /*------------------------------------------------------------------*/
1848 /*----------------------------*/
1850 /*----------------------------*/
1853 if (IS_AST_SYM_VALUE (pbody->left) &&
1854 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1857 return isConformingBody (pbody->left, sym, body);
1861 if (astHasSymbol (pbody->left, sym) ||
1862 astHasSymbol (pbody->right, sym))
1867 /*------------------------------------------------------------------*/
1878 if (IS_AST_SYM_VALUE (pbody->left) &&
1879 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1882 if (IS_AST_SYM_VALUE (pbody->right) &&
1883 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1886 return isConformingBody (pbody->left, sym, body) &&
1887 isConformingBody (pbody->right, sym, body);
1895 if (IS_AST_SYM_VALUE (pbody->left) &&
1896 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1898 return isConformingBody (pbody->left, sym, body);
1900 /*------------------------------------------------------------------*/
1912 case SIZEOF: /* evaluate wihout code generation */
1914 if (IS_AST_SYM_VALUE (pbody->left) &&
1915 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1918 if (IS_AST_SYM_VALUE (pbody->right) &&
1919 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1922 return isConformingBody (pbody->left, sym, body) &&
1923 isConformingBody (pbody->right, sym, body);
1925 /*------------------------------------------------------------------*/
1928 /* if left has a pointer & right has loop
1929 control variable then we cannot */
1930 if (astHasPointer (pbody->left) &&
1931 astHasSymbol (pbody->right, sym))
1933 if (astHasVolatile (pbody->left))
1936 if (IS_AST_SYM_VALUE (pbody->left)) {
1937 // if the loopvar has an assignment
1938 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1940 // if the loopvar is used in another (maybe conditional) block
1941 if (astHasSymbol (pbody->right, sym) &&
1942 (pbody->level >= body->level)) {
1947 if (astHasVolatile (pbody->left))
1950 if (astHasDeref(pbody->right)) return FALSE;
1952 return isConformingBody (pbody->left, sym, body) &&
1953 isConformingBody (pbody->right, sym, body);
1964 assert ("Parser should not have generated this\n");
1966 /*------------------------------------------------------------------*/
1967 /*----------------------------*/
1968 /* comma operator */
1969 /*----------------------------*/
1971 return isConformingBody (pbody->left, sym, body) &&
1972 isConformingBody (pbody->right, sym, body);
1974 /*------------------------------------------------------------------*/
1975 /*----------------------------*/
1977 /*----------------------------*/
1979 /* if local & not passed as paramater then ok */
1980 if (sym->level && !astHasSymbol(pbody->right,sym))
1984 /*------------------------------------------------------------------*/
1985 /*----------------------------*/
1986 /* return statement */
1987 /*----------------------------*/
1992 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1997 if (astHasSymbol (pbody->left, sym))
2004 return isConformingBody (pbody->left, sym, body) &&
2005 isConformingBody (pbody->right, sym, body);
2011 /*-----------------------------------------------------------------*/
2012 /* isLoopReversible - takes a for loop as input && returns true */
2013 /* if the for loop is reversible. If yes will set the value of */
2014 /* the loop control var & init value & termination value */
2015 /*-----------------------------------------------------------------*/
2017 isLoopReversible (ast * loop, symbol ** loopCntrl,
2018 ast ** init, ast ** end)
2020 /* if option says don't do it then don't */
2021 if (optimize.noLoopReverse)
2023 /* there are several tests to determine this */
2025 /* for loop has to be of the form
2026 for ( <sym> = <const1> ;
2027 [<sym> < <const2>] ;
2028 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
2030 if (!isLoopCountable (AST_FOR (loop, initExpr),
2031 AST_FOR (loop, condExpr),
2032 AST_FOR (loop, loopExpr),
2033 loopCntrl, init, end))
2036 /* now do some serious checking on the body of the loop
2039 return isConformingBody (loop->left, *loopCntrl, loop->left);
2043 /*-----------------------------------------------------------------*/
2044 /* replLoopSym - replace the loop sym by loop sym -1 */
2045 /*-----------------------------------------------------------------*/
2047 replLoopSym (ast * body, symbol * sym)
2050 if (!body || IS_AST_LINK (body))
2053 if (IS_AST_SYM_VALUE (body))
2056 if (isSymbolEqual (AST_SYMBOL (body), sym))
2060 body->opval.op = '-';
2061 body->left = newAst_VALUE (symbolVal (sym));
2062 body->right = newAst_VALUE (constVal ("1"));
2070 replLoopSym (body->left, sym);
2071 replLoopSym (body->right, sym);
2075 /*-----------------------------------------------------------------*/
2076 /* reverseLoop - do the actual loop reversal */
2077 /*-----------------------------------------------------------------*/
2079 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
2083 /* create the following tree
2088 if (sym) goto for_continue ;
2091 /* put it together piece by piece */
2092 rloop = newNode (NULLOP,
2093 createIf (newAst_VALUE (symbolVal (sym)),
2095 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2098 newAst_VALUE (symbolVal (sym)),
2101 replLoopSym (loop->left, sym);
2102 setAstLineno (rloop, init->lineno);
2104 rloop = newNode (NULLOP,
2106 newAst_VALUE (symbolVal (sym)),
2107 newNode ('-', end, init)),
2108 createLabel (AST_FOR (loop, continueLabel),
2112 newNode (SUB_ASSIGN,
2113 newAst_VALUE (symbolVal (sym)),
2114 newAst_VALUE (constVal ("1"))),
2117 rloop->lineno=init->lineno;
2118 return decorateType (rloop, RESULT_TYPE_NONE);
2122 /*-----------------------------------------------------------------*/
2123 /* searchLitOp - search tree (*ops only) for an ast with literal */
2124 /*-----------------------------------------------------------------*/
2126 searchLitOp (ast *tree, ast **parent, const char *ops)
2130 if (tree && optimize.global_cse)
2132 /* is there a literal operand? */
2134 IS_AST_OP(tree->right) &&
2135 tree->right->right &&
2136 (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1]))
2138 if (IS_LITERAL (RTYPE (tree->right)) !=
2139 IS_LITERAL (LTYPE (tree->right)))
2141 tree->right->decorated = 0;
2142 tree->decorated = 0;
2146 ret = searchLitOp (tree->right, parent, ops);
2151 IS_AST_OP(tree->left) &&
2152 tree->left->right &&
2153 (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1]))
2155 if (IS_LITERAL (RTYPE (tree->left)) !=
2156 IS_LITERAL (LTYPE (tree->left)))
2158 tree->left->decorated = 0;
2159 tree->decorated = 0;
2163 ret = searchLitOp (tree->left, parent, ops);
2171 /*-----------------------------------------------------------------*/
2172 /* getResultFromType */
2173 /*-----------------------------------------------------------------*/
2175 getResultTypeFromType (sym_link *type)
2177 /* type = getSpec (type); */
2179 return RESULT_TYPE_BIT;
2180 if (IS_BITFIELD (type))
2182 int blen = SPEC_BLEN (type);
2185 return RESULT_TYPE_BIT;
2187 return RESULT_TYPE_CHAR;
2188 return RESULT_TYPE_INT;
2191 return RESULT_TYPE_CHAR;
2192 if (IS_INT (type) && !IS_LONG (type))
2193 return RESULT_TYPE_INT;
2194 return RESULT_TYPE_OTHER;
2197 /*-----------------------------------------------------------------*/
2198 /* addCast - adds casts to a type specified by RESULT_TYPE */
2199 /*-----------------------------------------------------------------*/
2201 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2204 bool upCasted = FALSE;
2208 case RESULT_TYPE_NONE:
2209 /* if thing smaller than int must be promoted to int */
2211 getSize (tree->etype) >= INTSIZE)
2212 /* promotion not necessary or already an int */
2214 /* char and bits: promote to int */
2215 newLink = newIntLink();
2218 case RESULT_TYPE_BIT:
2220 /* already an int */
2221 bitsForType (tree->etype) >= 16 ||
2222 /* bit to bit operation: don't promote, the code generators
2223 hopefully know everything about promotion rules */
2224 bitsForType (tree->etype) == 1)
2226 newLink = newIntLink();
2229 case RESULT_TYPE_CHAR:
2230 if (IS_CHAR (tree->etype) ||
2231 IS_FLOAT(tree->etype) ||
2232 IS_FIXED(tree->etype))
2234 newLink = newCharLink();
2236 case RESULT_TYPE_INT:
2238 if (getSize (tree->etype) > INTSIZE)
2240 /* warn ("Loosing significant digits"); */
2244 /* char: promote to int */
2246 getSize (tree->etype) >= INTSIZE)
2248 newLink = newIntLink();
2251 case RESULT_TYPE_IFX:
2252 case RESULT_TYPE_OTHER:
2254 /* return type is ifx, long, float: promote char to int */
2255 getSize (tree->etype) >= INTSIZE)
2257 newLink = newIntLink();
2263 tree->decorated = 0;
2264 tree = newNode (CAST, newAst_LINK (newLink), tree);
2265 tree->lineno = tree->right->lineno;
2266 /* keep unsigned type during cast to smaller type,
2267 but not when promoting from char to int */
2269 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2270 return decorateType (tree, resultType);
2273 /*-----------------------------------------------------------------*/
2274 /* resultTypePropagate - decides if resultType can be propagated */
2275 /*-----------------------------------------------------------------*/
2277 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2279 switch (tree->opval.op)
2298 return RESULT_TYPE_NONE;
2302 return RESULT_TYPE_IFX;
2304 return RESULT_TYPE_NONE;
2308 /*-----------------------------------------------------------------*/
2309 /* getLeftResultType - gets type from left branch for propagation */
2310 /*-----------------------------------------------------------------*/
2312 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2314 switch (tree->opval.op)
2318 if (IS_PTR (LTYPE (tree)))
2319 return RESULT_TYPE_NONE;
2321 return getResultTypeFromType (LETYPE (tree));
2323 if (IS_PTR (currFunc->type->next))
2324 return RESULT_TYPE_NONE;
2326 return getResultTypeFromType (currFunc->type->next);
2328 if (!IS_ARRAY (LTYPE (tree)))
2330 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2331 return RESULT_TYPE_CHAR;
2338 /*------------------------------------------------------------------*/
2339 /* gatherImplicitVariables: assigns correct type information to */
2340 /* symbols and values created by replaceAstWithTemporary */
2341 /* and adds the symbols to the declarations list of the */
2342 /* innermost block that contains them */
2343 /*------------------------------------------------------------------*/
2345 gatherImplicitVariables (ast * tree, ast * block)
2350 if (tree->type == EX_OP && tree->opval.op == BLOCK)
2352 /* keep track of containing scope */
2355 if (tree->type == EX_OP && tree->opval.op == '=' &&
2356 tree->left->type == EX_VALUE && tree->left->opval.val->sym)
2358 symbol *assignee = tree->left->opval.val->sym;
2360 /* special case for assignment to compiler-generated temporary variable:
2361 compute type of RHS, and set the symbol's type to match */
2362 if (assignee->type == NULL && assignee->infertype) {
2363 ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
2365 if (dtr != tree->right)
2368 assignee->type = copyLinkChain(TTYPE(dtr));
2369 assignee->etype = getSpec(assignee->type);
2370 SPEC_SCLS (assignee->etype) = S_AUTO;
2371 SPEC_OCLS (assignee->etype) = NULL;
2372 SPEC_EXTR (assignee->etype) = 0;
2373 SPEC_STAT (assignee->etype) = 0;
2374 SPEC_VOLATILE (assignee->etype) = 0;
2375 SPEC_ABSA (assignee->etype) = 0;
2377 wassertl(block != NULL, "implicit variable not contained in block");
2378 wassert(assignee->next == NULL);
2379 if (block != NULL) {
2380 symbol **decl = &(block->values.sym);
2383 wassert(*decl != assignee); /* should not already be in list */
2384 decl = &( (*decl)->next );
2391 if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) &&
2392 tree->opval.val->type == NULL &&
2393 tree->opval.val->sym &&
2394 tree->opval.val->sym->infertype)
2396 /* fixup type of value for compiler-inferred temporary var */
2397 tree->opval.val->type = tree->opval.val->sym->type;
2398 tree->opval.val->etype = tree->opval.val->sym->etype;
2401 gatherImplicitVariables(tree->left, block);
2402 gatherImplicitVariables(tree->right, block);
2405 /*--------------------------------------------------------------------*/
2406 /* decorateType - compute type for this tree, also does type checking.*/
2407 /* This is done bottom up, since type has to flow upwards. */
2408 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2409 /* result is a char and the operand(s) are int's. */
2410 /* It also does constant folding, and parameter checking. */
2411 /*--------------------------------------------------------------------*/
2413 decorateType (ast * tree, RESULT_TYPE resultType)
2417 RESULT_TYPE resultTypeProp;
2422 /* if already has type then do nothing */
2423 if (tree->decorated)
2426 tree->decorated = 1;
2429 /* print the line */
2430 /* if not block & function */
2431 if (tree->type == EX_OP &&
2432 (tree->opval.op != FUNCTION &&
2433 tree->opval.op != BLOCK &&
2434 tree->opval.op != NULLOP))
2436 filename = tree->filename;
2437 lineno = tree->lineno;
2441 /* if any child is an error | this one is an error do nothing */
2442 if (tree->isError ||
2443 (tree->left && tree->left->isError) ||
2444 (tree->right && tree->right->isError))
2447 /*------------------------------------------------------------------*/
2448 /*----------------------------*/
2449 /* leaf has been reached */
2450 /*----------------------------*/
2451 lineno = tree->lineno;
2452 /* if this is of type value */
2453 /* just get the type */
2454 if (tree->type == EX_VALUE)
2457 if (IS_LITERAL (tree->opval.val->etype))
2460 /* if this is a character array then declare it */
2461 if (IS_ARRAY (tree->opval.val->type))
2462 tree->opval.val = stringToSymbol (tree->opval.val);
2464 /* otherwise just copy the type information */
2465 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2469 if (tree->opval.val->sym)
2471 /* if the undefined flag is set then give error message */
2472 if (tree->opval.val->sym->undefined)
2474 werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name);
2476 TTYPE (tree) = TETYPE (tree) =
2477 tree->opval.val->type = tree->opval.val->sym->type =
2478 tree->opval.val->etype = tree->opval.val->sym->etype =
2479 copyLinkChain (INTTYPE);
2481 else if (tree->opval.val->sym->implicit)
2483 /* if implicit i.e. struct/union member then no type */
2484 TTYPE (tree) = TETYPE (tree) = NULL;
2488 /* copy the type from the value into the ast */
2489 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2491 /* and mark the symbol as referenced */
2492 tree->opval.val->sym->isref = 1;
2496 wassert(0); /* unreached: all values are literals or symbols */
2501 /* if type link for the case of cast */
2502 if (tree->type == EX_LINK)
2504 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2512 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2514 if (tree->left && tree->left->type == EX_OPERAND
2515 && (tree->left->opval.op == INC_OP
2516 || tree->left->opval.op == DEC_OP)
2517 && tree->left->left)
2519 tree->left->right = tree->left->left;
2520 tree->left->left = NULL;
2522 if (tree->right && tree->right->type == EX_OPERAND
2523 && (tree->right->opval.op == INC_OP
2524 || tree->right->opval.op == DEC_OP)
2525 && tree->right->left)
2527 tree->right->right = tree->right->left;
2528 tree->right->left = NULL;
2533 /* Before decorating the left branch we've to decide in dependence
2534 upon tree->opval.op, if resultType can be propagated */
2535 resultTypeProp = resultTypePropagate (tree, resultType);
2537 if (tree->opval.op == '?')
2538 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2540 dtl = decorateType (tree->left, resultTypeProp);
2542 /* if an array node, we may need to swap branches */
2543 if (tree->opval.op == '[')
2545 /* determine which is the array & which the index */
2546 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2547 IS_INTEGRAL (LTYPE (tree)))
2549 ast *tempTree = tree->left;
2550 tree->left = tree->right;
2551 tree->right = tempTree;
2555 /* After decorating the left branch there's type information available
2556 in tree->left->?type. If the op is e.g. '=' we extract the type
2557 information from there and propagate it to the right branch. */
2558 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2560 switch (tree->opval.op)
2563 /* delay right side for '?' operator since conditional macro
2564 expansions might rely on this */
2568 /* decorate right side for CALL (parameter list) in processParms();
2569 there is resultType available */
2573 dtr = decorateType (tree->right, resultTypeProp);
2577 /* this is to take care of situations
2578 when the tree gets rewritten */
2579 if (dtl != tree->left)
2581 if (dtr != tree->right)
2583 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2587 /* depending on type of operator do */
2589 switch (tree->opval.op)
2591 /*------------------------------------------------------------------*/
2592 /*----------------------------*/
2594 /*----------------------------*/
2597 /* first check if this is a array or a pointer */
2598 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2600 werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
2601 goto errorTreeReturn;
2604 /* check if the type of the idx */
2605 if (!IS_INTEGRAL (RTYPE (tree)))
2607 werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
2608 goto errorTreeReturn;
2611 /* if the left is an rvalue then error */
2614 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
2615 goto errorTreeReturn;
2618 if (IS_LITERAL (RTYPE (tree)))
2620 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2621 int arraySize = DCL_ELEM (LTYPE (tree));
2622 if (arraySize && arrayIndex >= arraySize)
2624 werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2629 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2630 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2633 /*------------------------------------------------------------------*/
2634 /*----------------------------*/
2636 /*----------------------------*/
2638 /* if this is not a structure */
2639 if (!IS_STRUCT (LTYPE (tree)))
2641 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
2642 goto errorTreeReturn;
2644 TTYPE (tree) = structElemType (LTYPE (tree),
2645 (tree->right->type == EX_VALUE ?
2646 tree->right->opval.val : NULL));
2647 TETYPE (tree) = getSpec (TTYPE (tree));
2650 /*------------------------------------------------------------------*/
2651 /*----------------------------*/
2652 /* struct/union pointer */
2653 /*----------------------------*/
2655 /* if not pointer to a structure */
2656 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2658 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
2659 goto errorTreeReturn;
2662 if (!IS_STRUCT (LTYPE (tree)->next))
2664 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
2665 goto errorTreeReturn;
2668 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2669 (tree->right->type == EX_VALUE ?
2670 tree->right->opval.val : NULL));
2671 TETYPE (tree) = getSpec (TTYPE (tree));
2673 /* adjust the storage class */
2674 switch (DCL_TYPE(tree->left->ftype)) {
2676 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2679 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2682 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2685 SPEC_SCLS (TETYPE (tree)) = 0;
2688 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2691 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2694 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2697 SPEC_SCLS (TETYPE (tree)) = 0;
2704 /* This breaks with extern declarations, bitfields, and perhaps other */
2705 /* cases (gcse). Let's leave this optimization disabled for now and */
2706 /* ponder if there's a safe way to do this. -- EEP */
2708 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2709 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2711 /* If defined struct type at addr var
2712 then rewrite (&struct var)->member
2714 and define membertype at (addr+offsetof(struct var,member)) temp
2717 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2718 AST_SYMBOL(tree->right));
2720 sym = newSymbol(genSymName (0), 0);
2721 sym->type = TTYPE (tree);
2722 sym->etype = getSpec(sym->type);
2723 sym->lineDef = tree->lineno;
2726 SPEC_STAT (sym->etype) = 1;
2727 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2729 SPEC_ABSA(sym->etype) = 1;
2730 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2733 AST_VALUE (tree) = symbolVal(sym);
2736 tree->type = EX_VALUE;
2744 /*------------------------------------------------------------------*/
2745 /*----------------------------*/
2746 /* ++/-- operation */
2747 /*----------------------------*/
2751 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2752 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2753 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2754 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2763 /*------------------------------------------------------------------*/
2764 /*----------------------------*/
2766 /*----------------------------*/
2767 case '&': /* can be unary */
2768 /* if right is NULL then unary operation */
2769 if (tree->right) /* not an unary operation */
2772 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2774 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2775 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2776 printTypeChain (LTYPE (tree), stderr);
2777 fprintf (stderr, ",");
2778 printTypeChain (RTYPE (tree), stderr);
2779 fprintf (stderr, "\n");
2780 goto errorTreeReturn;
2783 /* if they are both literal */
2784 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2786 tree->type = EX_VALUE;
2787 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2788 valFromType (RETYPE (tree)), '&');
2790 tree->right = tree->left = NULL;
2791 TETYPE (tree) = tree->opval.val->etype;
2792 TTYPE (tree) = tree->opval.val->type;
2796 /* see if this is a GETHBIT operation if yes
2799 ast *otree = optimizeGetHbit (tree, resultType);
2802 return decorateType (otree, RESULT_TYPE_NONE);
2805 /* see if this is a GETABIT operation if yes
2808 ast *otree = optimizeGetAbit (tree, resultType);
2811 return decorateType (otree, RESULT_TYPE_NONE);
2814 /* see if this is a GETBYTE operation if yes
2817 ast *otree = optimizeGetByte (tree, resultType);
2820 return decorateType (otree, RESULT_TYPE_NONE);
2823 /* see if this is a GETWORD operation if yes
2826 ast *otree = optimizeGetWord (tree, resultType);
2829 return decorateType (otree, RESULT_TYPE_NONE);
2832 /* if left is a literal exchange left & right */
2833 if (IS_LITERAL (LTYPE (tree)))
2835 ast *tTree = tree->left;
2836 tree->left = tree->right;
2837 tree->right = tTree;
2840 /* if right is a literal and */
2841 /* we can find a 2nd literal in an and-tree then */
2842 /* rearrange the tree */
2843 if (IS_LITERAL (RTYPE (tree)))
2846 ast *litTree = searchLitOp (tree, &parent, "&");
2850 ast *tTree = litTree->left;
2851 litTree->left = tree->right;
2852 tree->right = tTree;
2853 /* both operands in litTree are literal now */
2854 decorateType (parent, resultType);
2858 LRVAL (tree) = RRVAL (tree) = 1;
2860 TTYPE (tree) = computeType (LTYPE (tree),
2864 TETYPE (tree) = getSpec (TTYPE (tree));
2869 /*------------------------------------------------------------------*/
2870 /*----------------------------*/
2872 /*----------------------------*/
2873 p = newLink (DECLARATOR);
2874 /* if bit field then error */
2875 if (IS_BITVAR (tree->left->etype))
2877 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
2878 goto errorTreeReturn;
2881 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2883 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
2884 goto errorTreeReturn;
2887 if (IS_FUNC (LTYPE (tree)))
2889 // this ought to be ignored
2890 return (tree->left);
2893 if (IS_LITERAL(LTYPE(tree)))
2895 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
2896 goto errorTreeReturn;
2901 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
2902 goto errorTreeReturn;
2905 DCL_TYPE (p) = POINTER;
2906 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2907 DCL_TYPE (p) = CPOINTER;
2908 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2909 DCL_TYPE (p) = FPOINTER;
2910 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2911 DCL_TYPE (p) = PPOINTER;
2912 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2913 DCL_TYPE (p) = IPOINTER;
2914 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2915 DCL_TYPE (p) = EEPPOINTER;
2916 else if (SPEC_OCLS(tree->left->etype))
2917 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2919 DCL_TYPE (p) = POINTER;
2921 if (IS_AST_SYM_VALUE (tree->left))
2923 AST_SYMBOL (tree->left)->addrtaken = 1;
2924 AST_SYMBOL (tree->left)->allocreq = 1;
2927 p->next = LTYPE (tree);
2929 TETYPE (tree) = getSpec (TTYPE (tree));
2934 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2935 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2937 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2938 AST_SYMBOL(tree->left->right));
2939 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2940 valueFromLit(element->offset));
2943 tree->type = EX_VALUE;
2944 tree->values.literalFromCast = 1;
2950 /*------------------------------------------------------------------*/
2951 /*----------------------------*/
2953 /*----------------------------*/
2955 /* if the rewrite succeeds then don't go any further */
2957 ast *wtree = optimizeRRCRLC (tree);
2959 return decorateType (wtree, RESULT_TYPE_NONE);
2961 wtree = optimizeSWAP (tree);
2963 return decorateType (wtree, RESULT_TYPE_NONE);
2966 /* if left is a literal exchange left & right */
2967 if (IS_LITERAL (LTYPE (tree)))
2969 ast *tTree = tree->left;
2970 tree->left = tree->right;
2971 tree->right = tTree;
2974 /* if right is a literal and */
2975 /* we can find a 2nd literal in an or-tree then */
2976 /* rearrange the tree */
2977 if (IS_LITERAL (RTYPE (tree)))
2980 ast *litTree = searchLitOp (tree, &parent, "|");
2984 ast *tTree = litTree->left;
2985 litTree->left = tree->right;
2986 tree->right = tTree;
2987 /* both operands in tTree are literal now */
2988 decorateType (parent, resultType);
2993 /*------------------------------------------------------------------*/
2994 /*----------------------------*/
2996 /*----------------------------*/
2998 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3000 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3001 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3002 printTypeChain (LTYPE (tree), stderr);
3003 fprintf (stderr, ",");
3004 printTypeChain (RTYPE (tree), stderr);
3005 fprintf (stderr, "\n");
3006 goto errorTreeReturn;
3009 /* if they are both literal then rewrite the tree */
3010 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3012 tree->type = EX_VALUE;
3013 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3014 valFromType (RETYPE (tree)),
3016 tree->right = tree->left = NULL;
3017 TETYPE (tree) = tree->opval.val->etype;
3018 TTYPE (tree) = tree->opval.val->type;
3022 /* if left is a literal exchange left & right */
3023 if (IS_LITERAL (LTYPE (tree)))
3025 ast *tTree = tree->left;
3026 tree->left = tree->right;
3027 tree->right = tTree;
3030 /* if right is a literal and */
3031 /* we can find a 2nd literal in a xor-tree then */
3032 /* rearrange the tree */
3033 if (IS_LITERAL (RTYPE (tree)) &&
3034 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3037 ast *litTree = searchLitOp (tree, &parent, "^");
3041 ast *tTree = litTree->left;
3042 litTree->left = tree->right;
3043 tree->right = tTree;
3044 /* both operands in litTree are literal now */
3045 decorateType (parent, resultType);
3049 LRVAL (tree) = RRVAL (tree) = 1;
3051 TTYPE (tree) = computeType (LTYPE (tree),
3055 TETYPE (tree) = getSpec (TTYPE (tree));
3059 /*------------------------------------------------------------------*/
3060 /*----------------------------*/
3062 /*----------------------------*/
3064 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3066 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
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->opval.val = valDiv (valFromType (LETYPE (tree)),
3075 valFromType (RETYPE (tree)));
3076 tree->right = tree->left = NULL;
3077 TETYPE (tree) = getSpec (TTYPE (tree) =
3078 tree->opval.val->type);
3082 LRVAL (tree) = RRVAL (tree) = 1;
3084 TETYPE (tree) = getSpec (TTYPE (tree) =
3085 computeType (LTYPE (tree),
3090 /* if right is a literal and */
3091 /* left is also a division by a literal then */
3092 /* rearrange the tree */
3093 if (IS_LITERAL (RTYPE (tree))
3094 /* avoid infinite loop */
3095 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
3098 ast *litTree = searchLitOp (tree, &parent, "/");
3101 if (IS_LITERAL (RTYPE (litTree)))
3105 litTree->right = newNode ('*',
3107 copyAst (tree->right));
3108 litTree->right->lineno = tree->lineno;
3110 tree->right->opval.val = constVal ("1");
3111 decorateType (parent, resultType);
3115 /* litTree->left is literal: no gcse possible.
3116 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3117 this would cause an infinit loop. */
3118 parent->decorated = 1;
3119 decorateType (litTree, resultType);
3126 /*------------------------------------------------------------------*/
3127 /*----------------------------*/
3129 /*----------------------------*/
3131 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3133 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3134 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3135 printTypeChain (LTYPE (tree), stderr);
3136 fprintf (stderr, ",");
3137 printTypeChain (RTYPE (tree), stderr);
3138 fprintf (stderr, "\n");
3139 goto errorTreeReturn;
3141 /* if they are both literal then */
3142 /* rewrite the tree */
3143 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3145 tree->type = EX_VALUE;
3146 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3147 valFromType (RETYPE (tree)));
3148 tree->right = tree->left = NULL;
3149 TETYPE (tree) = getSpec (TTYPE (tree) =
3150 tree->opval.val->type);
3153 LRVAL (tree) = RRVAL (tree) = 1;
3154 TETYPE (tree) = getSpec (TTYPE (tree) =
3155 computeType (LTYPE (tree),
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3163 /* address dereference */
3164 /*----------------------------*/
3165 case '*': /* can be unary : if right is null then unary operation */
3168 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3170 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
3171 goto errorTreeReturn;
3176 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
3177 goto errorTreeReturn;
3179 if (IS_ADDRESS_OF_OP(tree->left))
3181 /* replace *&obj with obj */
3182 return tree->left->left;
3184 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3185 TETYPE (tree) = getSpec (TTYPE (tree));
3186 /* adjust the storage class */
3187 switch (DCL_TYPE(tree->left->ftype)) {
3189 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3192 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3195 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3198 SPEC_SCLS (TETYPE (tree)) = 0;
3201 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3204 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3207 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3210 SPEC_SCLS (TETYPE (tree)) = 0;
3219 /*------------------------------------------------------------------*/
3220 /*----------------------------*/
3221 /* multiplication */
3222 /*----------------------------*/
3223 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3225 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
3226 goto errorTreeReturn;
3229 /* if they are both literal then */
3230 /* rewrite the tree */
3231 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3233 tree->type = EX_VALUE;
3234 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3235 valFromType (RETYPE (tree)));
3236 tree->right = tree->left = NULL;
3237 TETYPE (tree) = getSpec (TTYPE (tree) =
3238 tree->opval.val->type);
3242 /* if left is a literal exchange left & right */
3243 if (IS_LITERAL (LTYPE (tree)))
3245 ast *tTree = tree->left;
3246 tree->left = tree->right;
3247 tree->right = tTree;
3250 /* if right is a literal and */
3251 /* we can find a 2nd literal in a mul-tree then */
3252 /* rearrange the tree */
3253 if (IS_LITERAL (RTYPE (tree)))
3256 ast *litTree = searchLitOp (tree, &parent, "*");
3260 ast *tTree = litTree->left;
3261 litTree->left = tree->right;
3262 tree->right = tTree;
3263 /* both operands in litTree are literal now */
3264 decorateType (parent, resultType);
3268 LRVAL (tree) = RRVAL (tree) = 1;
3269 tree->left = addCast (tree->left, resultType, FALSE);
3270 tree->right = addCast (tree->right, resultType, FALSE);
3271 TETYPE (tree) = getSpec (TTYPE (tree) =
3272 computeType (LTYPE (tree),
3279 /*------------------------------------------------------------------*/
3280 /*----------------------------*/
3281 /* unary '+' operator */
3282 /*----------------------------*/
3287 if (!IS_ARITHMETIC (LTYPE (tree)))
3289 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
3290 goto errorTreeReturn;
3293 /* if left is a literal then do it */
3294 if (IS_LITERAL (LTYPE (tree)))
3296 tree->type = EX_VALUE;
3297 tree->opval.val = valFromType (LETYPE (tree));
3299 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3303 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3307 /*------------------------------------------------------------------*/
3308 /*----------------------------*/
3310 /*----------------------------*/
3312 /* this is not a unary operation */
3313 /* if both pointers then problem */
3314 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3315 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3317 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
3318 goto errorTreeReturn;
3321 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3322 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3324 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3325 goto errorTreeReturn;
3328 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3329 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3331 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3332 goto errorTreeReturn;
3334 /* if they are both literal then */
3335 /* rewrite the tree */
3336 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3338 tree->type = EX_VALUE;
3339 tree->left = addCast (tree->left, resultType, TRUE);
3340 tree->right = addCast (tree->right, resultType, TRUE);
3341 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3342 valFromType (RETYPE (tree)));
3343 tree->right = tree->left = NULL;
3344 TETYPE (tree) = getSpec (TTYPE (tree) =
3345 tree->opval.val->type);
3349 /* if the right is a pointer or left is a literal
3350 xchange left & right */
3351 if (IS_ARRAY (RTYPE (tree)) ||
3352 IS_PTR (RTYPE (tree)) ||
3353 IS_LITERAL (LTYPE (tree)))
3355 ast *tTree = tree->left;
3356 tree->left = tree->right;
3357 tree->right = tTree;
3360 /* if right is a literal and */
3361 /* left is also an addition/subtraction with a literal then */
3362 /* rearrange the tree */
3363 if (IS_LITERAL (RTYPE (tree)))
3365 ast *litTree, *parent;
3366 litTree = searchLitOp (tree, &parent, "+-");
3369 if (litTree->opval.op == '+')
3373 ast *tTree = litTree->left;
3374 litTree->left = tree->right;
3375 tree->right = tree->left;
3378 else if (litTree->opval.op == '-')
3380 if (IS_LITERAL (RTYPE (litTree)))
3384 ast *tTree = litTree->left;
3385 litTree->left = tree->right;
3386 tree->right = tTree;
3392 ast *tTree = litTree->right;
3393 litTree->right = tree->right;
3394 tree->right = tTree;
3395 litTree->opval.op = '+';
3396 tree->opval.op = '-';
3399 decorateType (parent, resultType);
3403 LRVAL (tree) = RRVAL (tree) = 1;
3404 /* if the left is a pointer */
3405 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3406 TETYPE (tree) = getSpec (TTYPE (tree) =
3410 tree->left = addCast (tree->left, resultType, TRUE);
3411 tree->right = addCast (tree->right, resultType, TRUE);
3412 TETYPE (tree) = getSpec (TTYPE (tree) =
3413 computeType (LTYPE (tree),
3421 /*------------------------------------------------------------------*/
3422 /*----------------------------*/
3424 /*----------------------------*/
3425 case '-': /* can be unary */
3426 /* if right is null then unary */
3430 if (!IS_ARITHMETIC (LTYPE (tree)))
3432 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3433 goto errorTreeReturn;
3436 /* if left is a literal then do it */
3437 if (IS_LITERAL (LTYPE (tree)))
3439 tree->type = EX_VALUE;
3440 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3442 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3445 tree->left = addCast (tree->left, resultType, TRUE);
3446 TETYPE (tree) = getSpec (TTYPE (tree) =
3447 computeType (LTYPE (tree),
3455 /*------------------------------------------------------------------*/
3456 /*----------------------------*/
3458 /*----------------------------*/
3460 if (!(IS_PTR (LTYPE (tree)) ||
3461 IS_ARRAY (LTYPE (tree)) ||
3462 IS_ARITHMETIC (LTYPE (tree))))
3464 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3465 goto errorTreeReturn;
3468 if (!(IS_PTR (RTYPE (tree)) ||
3469 IS_ARRAY (RTYPE (tree)) ||
3470 IS_ARITHMETIC (RTYPE (tree))))
3472 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3473 goto errorTreeReturn;
3476 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3477 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3478 IS_INTEGRAL (RTYPE (tree))))
3480 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3481 goto errorTreeReturn;
3484 /* if they are both literal then */
3485 /* rewrite the tree */
3486 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3488 tree->type = EX_VALUE;
3489 tree->left = addCast (tree->left, resultType, TRUE);
3490 tree->right = addCast (tree->right, resultType, TRUE);
3491 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3492 valFromType (RETYPE (tree)));
3493 tree->right = tree->left = NULL;
3494 TETYPE (tree) = getSpec (TTYPE (tree) =
3495 tree->opval.val->type);
3499 /* if the left & right are equal then zero */
3500 if (isAstEqual (tree->left, tree->right))
3502 tree->type = EX_VALUE;
3503 tree->left = tree->right = NULL;
3504 tree->opval.val = constVal ("0");
3505 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3509 /* if both of them are pointers or arrays then */
3510 /* the result is going to be an integer */
3511 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3512 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3513 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3515 /* if only the left is a pointer */
3516 /* then result is a pointer */
3517 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3518 TETYPE (tree) = getSpec (TTYPE (tree) =
3522 tree->left = addCast (tree->left, resultType, TRUE);
3523 tree->right = addCast (tree->right, resultType, TRUE);
3525 TETYPE (tree) = getSpec (TTYPE (tree) =
3526 computeType (LTYPE (tree),
3532 LRVAL (tree) = RRVAL (tree) = 1;
3534 /* if right is a literal and */
3535 /* left is also an addition/subtraction with a literal then */
3536 /* rearrange the tree */
3537 if (IS_LITERAL (RTYPE (tree))
3538 /* avoid infinite loop */
3539 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
3541 ast *litTree, *litParent;
3542 litTree = searchLitOp (tree, &litParent, "+-");
3545 if (litTree->opval.op == '+')
3549 ast *tTree = litTree->left;
3550 litTree->left = litTree->right;
3551 litTree->right = tree->right;
3552 tree->right = tTree;
3553 tree->opval.op = '+';
3554 litTree->opval.op = '-';
3556 else if (litTree->opval.op == '-')
3558 if (IS_LITERAL (RTYPE (litTree)))
3562 ast *tTree = litTree->left;
3563 litTree->left = tree->right;
3564 tree->right = litParent->left;
3565 litParent->left = tTree;
3566 litTree->opval.op = '+';
3568 tree->decorated = 0;
3569 decorateType (tree, resultType);
3575 ast *tTree = litTree->right;
3576 litTree->right = tree->right;
3577 tree->right = tTree;
3580 decorateType (litParent, resultType);
3585 /*------------------------------------------------------------------*/
3586 /*----------------------------*/
3588 /*----------------------------*/
3590 /* can be only integral type */
3591 if (!IS_INTEGRAL (LTYPE (tree)))
3593 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3594 goto errorTreeReturn;
3597 /* if left is a literal then do it */
3598 if (IS_LITERAL (LTYPE (tree)))
3600 tree->type = EX_VALUE;
3601 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3603 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3604 return addCast (tree, resultType, TRUE);
3607 if (resultType == RESULT_TYPE_BIT &&
3608 IS_UNSIGNED (tree->left->etype) &&
3609 getSize (tree->left->etype) < INTSIZE)
3611 /* promotion rules are responsible for this strange result:
3612 bit -> int -> ~int -> bit
3613 uchar -> int -> ~int -> bit
3615 werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
3617 /* optimize bit-result, even if we optimize a buggy source */
3618 tree->type = EX_VALUE;
3619 tree->opval.val = constVal ("1");
3622 tree->left = addCast (tree->left, resultType, TRUE);
3624 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3627 /*------------------------------------------------------------------*/
3628 /*----------------------------*/
3630 /*----------------------------*/
3632 /* can be pointer */
3633 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3634 !IS_PTR (LTYPE (tree)) &&
3635 !IS_ARRAY (LTYPE (tree)))
3637 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3638 goto errorTreeReturn;
3641 /* if left is another '!' */
3642 if (tree->left->opval.op == '!')
3644 /* remove double '!!X' by 'X ? 1 : 0' */
3645 tree->opval.op = '?';
3646 tree->left = tree->left->left;
3647 tree->right = newNode (':',
3648 newAst_VALUE (constVal ("1")),
3649 newAst_VALUE (constVal ("0")));
3650 tree->right->lineno = tree->lineno;
3651 tree->decorated = 0;
3652 return decorateType (tree, resultType);
3655 /* if left is a literal then do it */
3656 if (IS_LITERAL (LTYPE (tree)))
3658 tree->type = EX_VALUE;
3659 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3661 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3665 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3668 /*------------------------------------------------------------------*/
3669 /*----------------------------*/
3671 /*----------------------------*/
3675 TTYPE (tree) = LTYPE (tree);
3676 TETYPE (tree) = LETYPE (tree);
3681 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3685 TTYPE (tree) = TETYPE (tree) = newCharLink();
3689 TTYPE (tree) = TETYPE (tree) = newIntLink();
3694 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3696 werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
3697 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3698 printTypeChain (LTYPE (tree), stderr);
3699 fprintf (stderr, ",");
3700 printTypeChain (RTYPE (tree), stderr);
3701 fprintf (stderr, "\n");
3702 goto errorTreeReturn;
3705 /* make smaller type only if it's a LEFT_OP */
3706 if (tree->opval.op == LEFT_OP)
3707 tree->left = addCast (tree->left, resultType, TRUE);
3709 /* if they are both literal then */
3710 /* rewrite the tree */
3711 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3713 tree->type = EX_VALUE;
3714 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3715 valFromType (RETYPE (tree)),
3716 (tree->opval.op == LEFT_OP ? 1 : 0));
3717 tree->right = tree->left = NULL;
3718 TETYPE (tree) = getSpec (TTYPE (tree) =
3719 tree->opval.val->type);
3723 /* see if this is a GETBYTE operation if yes
3726 ast *otree = optimizeGetByte (tree, resultType);
3729 return decorateType (otree, RESULT_TYPE_NONE);
3732 /* see if this is a GETWORD operation if yes
3735 ast *otree = optimizeGetWord (tree, resultType);
3738 return decorateType (otree, RESULT_TYPE_NONE);
3741 LRVAL (tree) = RRVAL (tree) = 1;
3742 if (tree->opval.op == LEFT_OP)
3744 TETYPE (tree) = getSpec (TTYPE (tree) =
3745 computeType (LTYPE (tree),
3752 /* no promotion necessary */
3753 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3754 if (IS_LITERAL (TTYPE (tree)))
3755 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3758 /* if only the right side is a literal & we are
3759 shifting more than size of the left operand then zero */
3760 if (IS_LITERAL (RTYPE (tree)) &&
3761 ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
3762 (getSize (TETYPE (tree)) * 8))
3764 if (tree->opval.op==LEFT_OP ||
3765 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3767 werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
3768 (tree->opval.op == LEFT_OP ? "left" : "right"));
3769 tree->type = EX_VALUE;
3770 tree->left = tree->right = NULL;
3771 tree->opval.val = constVal ("0");
3772 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3779 /*------------------------------------------------------------------*/
3780 /*----------------------------*/
3782 /*----------------------------*/
3783 case CAST: /* change the type */
3784 /* cannot cast to an aggregate type */
3785 if (IS_AGGREGATE (LTYPE (tree)))
3787 werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
3788 goto errorTreeReturn;
3791 /* make sure the type is complete and sane */
3792 changePointer(LTYPE(tree));
3793 checkTypeSanity(LETYPE(tree), "(cast)");
3795 /* if 'from' and 'to' are the same remove the superfluous cast, */
3796 /* this helps other optimizations */
3797 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3802 /* If code memory is read only, then pointers to code memory */
3803 /* implicitly point to constants -- make this explicit */
3805 sym_link *t = LTYPE(tree);
3806 while (t && t->next)
3808 if (IS_CODEPTR(t) && port->mem.code_ro)
3810 if (IS_SPEC(t->next))
3811 SPEC_CONST (t->next) = 1;
3813 DCL_PTR_CONST (t->next) = 1;
3820 /* if the right is a literal replace the tree */
3821 if (IS_LITERAL (RETYPE (tree))) {
3822 if (!IS_PTR (LTYPE (tree))) {
3823 tree->type = EX_VALUE;
3825 valCastLiteral (LTYPE (tree),
3826 floatFromVal (valFromType (RETYPE (tree))));
3829 TTYPE (tree) = tree->opval.val->type;
3830 tree->values.literalFromCast = 1;
3831 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3832 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3833 sym_link *rest = LTYPE(tree)->next;
3834 werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
3835 TTYPE(tree) = newLink(DECLARATOR);
3836 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3837 TTYPE(tree)->next = rest;
3838 tree->left->opval.lnk = TTYPE(tree);
3841 TTYPE (tree) = LTYPE (tree);
3845 TTYPE (tree) = LTYPE (tree);
3849 #if 0 // this is already checked, now this could be explicit
3850 /* if pointer to struct then check names */
3851 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3852 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3853 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3855 werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3856 SPEC_STRUCT(LETYPE(tree))->tag);
3859 if (IS_ADDRESS_OF_OP(tree->right)
3860 && IS_AST_SYM_VALUE (tree->right->left)
3861 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3863 symbol * sym = AST_SYMBOL (tree->right->left);
3864 unsigned int gptype = 0;
3865 unsigned int addr = SPEC_ADDR (sym->etype);
3867 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
3868 || TARGET_IS_PIC16) )
3870 switch (SPEC_SCLS (sym->etype))
3873 gptype = GPTYPE_CODE;
3876 gptype = GPTYPE_FAR;
3880 gptype = GPTYPE_NEAR;
3883 gptype = GPTYPE_XSTACK;
3888 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3889 gptype = GPTYPE_NEAR;
3891 addr |= gptype << (8*(GPTRSIZE - 1));
3894 tree->type = EX_VALUE;
3896 valCastLiteral (LTYPE (tree), addr);
3897 TTYPE (tree) = tree->opval.val->type;
3898 TETYPE (tree) = getSpec (TTYPE (tree));
3901 tree->values.literalFromCast = 1;
3905 /* handle offsetof macro: */
3906 /* #define offsetof(TYPE, MEMBER) \ */
3907 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3908 if (IS_ADDRESS_OF_OP(tree->right)
3909 && IS_AST_OP (tree->right->left)
3910 && tree->right->left->opval.op == PTR_OP
3911 && IS_AST_OP (tree->right->left->left)
3912 && tree->right->left->left->opval.op == CAST
3913 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3915 symbol *element = getStructElement (
3916 SPEC_STRUCT (LETYPE(tree->right->left)),
3917 AST_SYMBOL(tree->right->left->right)
3921 tree->type = EX_VALUE;
3922 tree->opval.val = valCastLiteral (
3925 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3928 TTYPE (tree) = tree->opval.val->type;
3929 TETYPE (tree) = getSpec (TTYPE (tree));
3936 /* if the right is a literal replace the tree */
3937 if (IS_LITERAL (RETYPE (tree))) {
3939 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3940 /* rewrite (type *)litaddr
3942 and define type at litaddr temp
3943 (but only if type's storage class is not generic)
3945 ast *newTree = newNode ('&', NULL, NULL);
3948 TTYPE (newTree) = LTYPE (tree);
3949 TETYPE (newTree) = getSpec(LTYPE (tree));
3951 /* define a global symbol at the casted address*/
3952 sym = newSymbol(genSymName (0), 0);
3953 sym->type = LTYPE (tree)->next;
3955 sym->type = newLink (V_VOID);
3956 sym->etype = getSpec(sym->type);
3957 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3958 sym->lineDef = tree->lineno;
3961 SPEC_STAT (sym->etype) = 1;
3962 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3963 SPEC_ABSA(sym->etype) = 1;
3964 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3967 newTree->left = newAst_VALUE(symbolVal(sym));
3968 newTree->left->lineno = tree->lineno;
3969 LTYPE (newTree) = sym->type;
3970 LETYPE (newTree) = sym->etype;
3971 LLVAL (newTree) = 1;
3972 LRVAL (newTree) = 0;
3973 TLVAL (newTree) = 1;
3977 if (!IS_PTR (LTYPE (tree))) {
3978 tree->type = EX_VALUE;
3980 valCastLiteral (LTYPE (tree),
3981 floatFromVal (valFromType (RTYPE (tree))));
3982 TTYPE (tree) = tree->opval.val->type;
3985 tree->values.literalFromCast = 1;
3986 TETYPE (tree) = getSpec (TTYPE (tree));
3990 TTYPE (tree) = LTYPE (tree);
3994 TETYPE (tree) = getSpec (TTYPE (tree));
3998 /*------------------------------------------------------------------*/
3999 /*----------------------------*/
4000 /* logical &&, || */
4001 /*----------------------------*/
4004 /* each must be arithmetic type or be a pointer */
4005 if (!IS_PTR (LTYPE (tree)) &&
4006 !IS_ARRAY (LTYPE (tree)) &&
4007 !IS_INTEGRAL (LTYPE (tree)))
4009 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4010 goto errorTreeReturn;
4013 if (!IS_PTR (RTYPE (tree)) &&
4014 !IS_ARRAY (RTYPE (tree)) &&
4015 !IS_INTEGRAL (RTYPE (tree)))
4017 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4018 goto errorTreeReturn;
4020 /* if they are both literal then */
4021 /* rewrite the tree */
4022 if (IS_LITERAL (RTYPE (tree)) &&
4023 IS_LITERAL (LTYPE (tree)))
4025 tree->type = EX_VALUE;
4026 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4027 valFromType (RTYPE (tree)),
4029 tree->right = tree->left = NULL;
4030 TETYPE (tree) = getSpec (TTYPE (tree) =
4031 tree->opval.val->type);
4034 LRVAL (tree) = RRVAL (tree) = 1;
4035 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4038 /*------------------------------------------------------------------*/
4039 /*----------------------------*/
4040 /* comparison operators */
4041 /*----------------------------*/
4049 ast *lt = optimizeCompare (tree);
4055 /* if they are pointers they must be castable */
4056 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4058 if (tree->opval.op==EQ_OP &&
4059 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4060 // we cannot cast a gptr to a !gptr: switch the leaves
4061 struct ast *s=tree->left;
4062 tree->left=tree->right;
4065 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4067 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4068 fprintf (stderr, "comparing type ");
4069 printTypeChain (LTYPE (tree), stderr);
4070 fprintf (stderr, "to type ");
4071 printTypeChain (RTYPE (tree), stderr);
4072 fprintf (stderr, "\n");
4073 goto errorTreeReturn;
4076 /* else they should be promotable to one another */
4079 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4080 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4082 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4084 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4085 fprintf (stderr, "comparing type ");
4086 printTypeChain (LTYPE (tree), stderr);
4087 fprintf (stderr, "to type ");
4088 printTypeChain (RTYPE (tree), stderr);
4089 fprintf (stderr, "\n");
4090 goto errorTreeReturn;
4095 CCR_RESULT ccr_result = CCR_OK;
4097 /* if left is integral and right is literal
4098 then check constant range */
4099 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4100 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4101 tree->opval.op, FALSE);
4102 if (ccr_result == CCR_OK &&
4103 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4104 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4105 tree->opval.op, TRUE);
4108 case CCR_ALWAYS_TRUE:
4109 case CCR_ALWAYS_FALSE:
4110 if (!options.lessPedantic)
4111 werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
4112 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4113 return decorateType (newAst_VALUE (constVal (
4114 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4122 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4123 if (tree->opval.op == '>' &&
4124 SPEC_USIGN(LETYPE(tree)) &&
4125 IS_LITERAL(RTYPE(tree)) &&
4126 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
4128 if (resultType == RESULT_TYPE_IFX)
4130 /* the parent is an ifx: */
4131 /* if (unsigned value) */
4135 /* (unsigned value) ? 1 : 0 */
4136 tree->opval.op = '?';
4137 tree->right = newNode (':',
4138 newAst_VALUE (constVal ("1")),
4139 tree->right); /* val 0 */
4140 tree->right->lineno = tree->lineno;
4141 tree->right->left->lineno = tree->lineno;
4142 tree->decorated = 0;
4143 return decorateType (tree, resultType);
4146 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4147 if (IS_LITERAL(RTYPE(tree)) &&
4148 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4149 tree->opval.op == EQ_OP &&
4150 resultType == RESULT_TYPE_IFX)
4152 tree->opval.op = '!';
4154 tree->decorated = 0;
4155 return decorateType (tree, resultType);
4158 /* if they are both literal then */
4159 /* rewrite the tree */
4160 if (IS_LITERAL (RTYPE (tree)) &&
4161 IS_LITERAL (LTYPE (tree)))
4163 tree->type = EX_VALUE;
4164 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4165 valFromType (RETYPE (tree)),
4167 tree->right = tree->left = NULL;
4168 TETYPE (tree) = getSpec (TTYPE (tree) =
4169 tree->opval.val->type);
4173 /* if one is 'signed char ' and the other one is 'unsigned char' */
4174 /* it's necessary to promote to int */
4175 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4176 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4178 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4179 if it's possible to use a 'signed char' */
4181 /* is left a 'unsigned char'? */
4182 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4183 /* the value range of a 'unsigned char' is 0...255;
4184 if the actual value is < 128 it can be changed to signed */
4185 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
4187 /* now we've got 2 'signed char'! */
4188 SPEC_USIGN (RETYPE (tree)) = 0;
4190 /* same test for the left operand: */
4191 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4192 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4194 SPEC_USIGN (LETYPE (tree)) = 0;
4198 werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
4199 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4200 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4204 LRVAL (tree) = RRVAL (tree) = 1;
4205 TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4207 /* condition transformations */
4209 unsigned transformedOp = 0;
4211 switch (tree->opval.op)
4213 case '<': /* transform (a < b) to !(a >= b) */
4215 transformedOp = GE_OP;
4217 case '>': /* transform (a > b) to !(a <= b) */
4219 transformedOp = LE_OP;
4221 case LE_OP: /* transform (a <= b) to !(a > b) */
4223 transformedOp = '>';
4225 case GE_OP: /* transform (a >= b) to !(a < b) */
4227 transformedOp = '<';
4229 case NE_OP: /* transform (a != b) to !(a == b) */
4231 transformedOp = EQ_OP;
4233 case EQ_OP: /* transform (a == b) to !(a != b) */
4235 transformedOp = NE_OP;
4242 tree->opval.op = transformedOp;
4243 tree->decorated = 0;
4244 tree = newNode ('!', tree, NULL);
4245 tree->lineno = tree->left->lineno;
4246 return decorateType (tree, resultType);
4252 /*------------------------------------------------------------------*/
4253 /*----------------------------*/
4255 /*----------------------------*/
4256 case SIZEOF: /* evaluate wihout code generation */
4257 /* change the type to a integer */
4259 int size = getSize (tree->right->ftype);
4260 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4261 if (!size && !IS_VOID(tree->right->ftype))
4262 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4264 tree->type = EX_VALUE;
4265 tree->opval.val = constVal (buffer);
4266 tree->right = tree->left = NULL;
4267 TETYPE (tree) = getSpec (TTYPE (tree) =
4268 tree->opval.val->type);
4271 /*------------------------------------------------------------------*/
4272 /*----------------------------*/
4274 /*----------------------------*/
4276 /* return typeof enum value */
4277 tree->type = EX_VALUE;
4280 if (IS_SPEC(tree->right->ftype)) {
4281 switch (SPEC_NOUN(tree->right->ftype)) {
4283 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4284 else typeofv = TYPEOF_INT;
4287 typeofv = TYPEOF_FLOAT;
4290 typeofv = TYPEOF_FIXED16X16;
4293 typeofv = TYPEOF_CHAR;
4296 typeofv = TYPEOF_VOID;
4299 typeofv = TYPEOF_STRUCT;
4302 typeofv = TYPEOF_BITFIELD;
4305 typeofv = TYPEOF_BIT;
4308 typeofv = TYPEOF_SBIT;
4314 switch (DCL_TYPE(tree->right->ftype)) {
4316 typeofv = TYPEOF_POINTER;
4319 typeofv = TYPEOF_FPOINTER;
4322 typeofv = TYPEOF_CPOINTER;
4325 typeofv = TYPEOF_GPOINTER;
4328 typeofv = TYPEOF_PPOINTER;
4331 typeofv = TYPEOF_IPOINTER;
4334 typeofv = TYPEOF_ARRAY;
4337 typeofv = TYPEOF_FUNCTION;
4343 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4344 tree->opval.val = constVal (buffer);
4345 tree->right = tree->left = NULL;
4346 TETYPE (tree) = getSpec (TTYPE (tree) =
4347 tree->opval.val->type);
4350 /*------------------------------------------------------------------*/
4351 /*----------------------------*/
4352 /* conditional operator '?' */
4353 /*----------------------------*/
4355 /* the type is value of the colon operator (on the right) */
4356 assert (IS_COLON_OP (tree->right));
4357 /* if already known then replace the tree : optimizer will do it
4358 but faster to do it here */
4359 if (IS_LITERAL (LTYPE (tree)))
4361 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4362 return decorateType (tree->right->left, resultTypeProp);
4364 return decorateType (tree->right->right, resultTypeProp);
4368 tree->right = decorateType (tree->right, resultTypeProp);
4369 TTYPE (tree) = RTYPE (tree);
4370 TETYPE (tree) = getSpec (TTYPE (tree));
4375 /* if they don't match we have a problem */
4376 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4377 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4379 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
4380 goto errorTreeReturn;
4383 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4384 resultType, tree->opval.op);
4385 TETYPE (tree) = getSpec (TTYPE (tree));
4389 #if 0 // assignment operators are converted by the parser
4390 /*------------------------------------------------------------------*/
4391 /*----------------------------*/
4392 /* assignment operators */
4393 /*----------------------------*/
4396 /* for these it must be both must be integral */
4397 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4398 !IS_ARITHMETIC (RTYPE (tree)))
4400 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4401 goto errorTreeReturn;
4404 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4406 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4407 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4411 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4412 goto errorTreeReturn;
4423 /* for these it must be both must be integral */
4424 if (!IS_INTEGRAL (LTYPE (tree)) ||
4425 !IS_INTEGRAL (RTYPE (tree)))
4427 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4428 goto errorTreeReturn;
4431 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4433 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4434 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4438 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4439 goto errorTreeReturn;
4445 /*------------------------------------------------------------------*/
4446 /*----------------------------*/
4448 /*----------------------------*/
4450 if (!(IS_PTR (LTYPE (tree)) ||
4451 IS_ARITHMETIC (LTYPE (tree))))
4453 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4454 goto errorTreeReturn;
4457 if (!(IS_PTR (RTYPE (tree)) ||
4458 IS_ARITHMETIC (RTYPE (tree))))
4460 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4461 goto errorTreeReturn;
4464 TETYPE (tree) = getSpec (TTYPE (tree) =
4465 computeType (LTYPE (tree),
4470 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4471 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
4475 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
4476 goto errorTreeReturn;
4482 /*------------------------------------------------------------------*/
4483 /*----------------------------*/
4485 /*----------------------------*/
4487 /* this is not a unary operation */
4488 /* if both pointers then problem */
4489 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4491 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
4492 goto errorTreeReturn;
4495 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4497 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4498 goto errorTreeReturn;
4501 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4503 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4504 goto errorTreeReturn;
4507 TETYPE (tree) = getSpec (TTYPE (tree) =
4508 computeType (LTYPE (tree),
4513 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4514 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
4518 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
4519 goto errorTreeReturn;
4522 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4523 tree->opval.op = '=';
4528 /*------------------------------------------------------------------*/
4529 /*----------------------------*/
4530 /* straight assignemnt */
4531 /*----------------------------*/
4533 /* cannot be an aggregate */
4534 if (IS_AGGREGATE (LTYPE (tree)))
4536 werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
4537 goto errorTreeReturn;
4540 /* they should either match or be castable */
4541 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4543 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
4544 printFromToType(RTYPE(tree),LTYPE(tree));
4547 /* if the left side of the tree is of type void
4548 then report error */
4549 if (IS_VOID (LTYPE (tree)))
4551 werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
4552 printFromToType(RTYPE(tree), LTYPE(tree));
4555 TETYPE (tree) = getSpec (TTYPE (tree) =
4559 if (!tree->initMode ) {
4560 if (IS_CONSTANT(LTYPE(tree)))
4561 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
4565 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
4566 goto errorTreeReturn;
4571 /*------------------------------------------------------------------*/
4572 /*----------------------------*/
4573 /* comma operator */
4574 /*----------------------------*/
4576 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4579 /*------------------------------------------------------------------*/
4580 /*----------------------------*/
4582 /*----------------------------*/
4585 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4586 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4588 if (tree->left->opval.op == '*' && !tree->left->right)
4589 tree->left = tree->left->left;
4592 /* require a function or pointer to function */
4593 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4595 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4596 goto errorTreeReturn;
4599 /* if there are parms, make sure that
4600 parms are decorate / process / reverse only once */
4602 !tree->right->decorated)
4607 if (IS_FUNCPTR (LTYPE (tree)))
4609 functype = LTYPE (tree)->next;
4610 processFuncPtrArgs (functype);
4613 functype = LTYPE (tree);
4615 if (processParms (tree->left, FUNC_ARGS(functype),
4616 &tree->right, &parmNumber, TRUE))
4618 goto errorTreeReturn;
4621 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4622 !IFFUNC_ISBUILTIN(functype))
4624 reverseParms (tree->right);
4627 TTYPE (tree) = functype->next;
4628 TETYPE (tree) = getSpec (TTYPE (tree));
4632 /*------------------------------------------------------------------*/
4633 /*----------------------------*/
4634 /* return statement */
4635 /*----------------------------*/
4640 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4642 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4643 printFromToType (RTYPE(tree), currFunc->type->next);
4644 goto errorTreeReturn;
4647 if (IS_VOID (currFunc->type->next)
4649 !IS_VOID (RTYPE (tree)))
4651 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4652 goto errorTreeReturn;
4655 /* if there is going to be a casting required then add it */
4656 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4659 decorateType (newNode (CAST,
4660 newAst_LINK (copyLinkChain (currFunc->type->next)),
4670 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4672 werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
4673 goto errorTreeReturn;
4676 TTYPE (tree) = TETYPE (tree) = NULL;
4679 /*------------------------------------------------------------------*/
4680 /*----------------------------*/
4681 /* switch statement */
4682 /*----------------------------*/
4684 /* the switch value must be an integer */
4685 if (!IS_INTEGRAL (LTYPE (tree)))
4687 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4688 goto errorTreeReturn;
4691 TTYPE (tree) = TETYPE (tree) = NULL;
4694 /*------------------------------------------------------------------*/
4695 /*----------------------------*/
4697 /*----------------------------*/
4699 tree->left = backPatchLabels (tree->left,
4702 TTYPE (tree) = TETYPE (tree) = NULL;
4705 /*------------------------------------------------------------------*/
4706 /*----------------------------*/
4708 /*----------------------------*/
4711 AST_FOR (tree, initExpr) = decorateType (
4712 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4713 AST_FOR (tree, condExpr) = decorateType (
4714 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4715 AST_FOR (tree, loopExpr) = decorateType (
4716 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4718 /* if the for loop is reversible then
4719 reverse it otherwise do what we normally
4725 if (isLoopReversible (tree, &sym, &init, &end))
4726 return reverseLoop (tree, sym, init, end);
4728 return decorateType (createFor (AST_FOR (tree, trueLabel),
4729 AST_FOR (tree, continueLabel),
4730 AST_FOR (tree, falseLabel),
4731 AST_FOR (tree, condLabel),
4732 AST_FOR (tree, initExpr),
4733 AST_FOR (tree, condExpr),
4734 AST_FOR (tree, loopExpr),
4735 tree->left), RESULT_TYPE_NONE);
4738 werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
4739 "node PARAM shouldn't be processed here");
4740 /* but in processParams() */
4743 TTYPE (tree) = TETYPE (tree) = NULL;
4747 /* some error found this tree will be killed */
4749 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4750 tree->opval.op = NULLOP;
4756 /*-----------------------------------------------------------------*/
4757 /* sizeofOp - processes size of operation */
4758 /*-----------------------------------------------------------------*/
4760 sizeofOp (sym_link * type)
4765 /* make sure the type is complete and sane */
4766 checkTypeSanity(type, "(sizeof)");
4768 /* get the size and convert it to character */
4769 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4770 if (!size && !IS_VOID(type))
4771 werror (E_SIZEOF_INCOMPLETE_TYPE);
4773 /* now convert into value */
4774 return constVal (buff);
4778 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4779 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4780 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4781 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4782 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4783 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4784 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4786 /*-----------------------------------------------------------------*/
4787 /* backPatchLabels - change and or not operators to flow control */
4788 /*-----------------------------------------------------------------*/
4790 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4796 /* while-loops insert a label between the IFX and the condition,
4797 therefore look behind the label too */
4798 if (tree->opval.op == LABEL &&
4800 IS_ANDORNOT (tree->right))
4802 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4806 if (!(IS_ANDORNOT (tree)))
4809 /* if this an and */
4812 static int localLbl = 0;
4815 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4816 localLabel = newSymbol (buffer, NestLevel);
4818 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4820 /* if left is already a IFX then just change the if true label in that */
4821 if (!IS_IFX (tree->left))
4822 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4824 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4825 /* right is a IFX then just join */
4826 if (IS_IFX (tree->right))
4827 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4829 tree->right = createLabel (localLabel, tree->right);
4830 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4832 return newNode (NULLOP, tree->left, tree->right);
4835 /* if this is an or operation */
4838 static int localLbl = 0;
4841 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4842 localLabel = newSymbol (buffer, NestLevel);
4844 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4846 /* if left is already a IFX then just change the if true label in that */
4847 if (!IS_IFX (tree->left))
4848 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4850 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4851 /* right is a IFX then just join */
4852 if (IS_IFX (tree->right))
4853 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4855 tree->right = createLabel (localLabel, tree->right);
4856 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4858 return newNode (NULLOP, tree->left, tree->right);
4864 /* call with exchanged labels */
4865 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4867 /* if left isn't already a IFX */
4868 if (!IS_IFX (tree->left))
4870 tree->left = newNode (IFX, tree->left, NULL);
4871 tree->left->trueLabel = falseLabel;
4872 tree->left->falseLabel = trueLabel;
4879 tree->trueLabel = trueLabel;
4880 tree->falseLabel = falseLabel;
4887 /*-----------------------------------------------------------------*/
4888 /* createBlock - create expression tree for block */
4889 /*-----------------------------------------------------------------*/
4891 createBlock (symbol * decl, ast * body)
4895 /* if the block has nothing */
4899 ex = newNode (BLOCK, NULL, body);
4900 ex->values.sym = decl;
4907 /*-----------------------------------------------------------------*/
4908 /* createLabel - creates the expression tree for labels */
4909 /*-----------------------------------------------------------------*/
4911 createLabel (symbol * label, ast * stmnt)
4914 char name[SDCC_NAME_MAX + 1];
4917 /* must create fresh symbol if the symbol name */
4918 /* exists in the symbol table, since there can */
4919 /* be a variable with the same name as the labl */
4920 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4921 (csym->level == label->level))
4922 label = newSymbol (label->name, label->level);
4924 /* change the name before putting it in add _ */
4925 SNPRINTF(name, sizeof(name), "%s", label->name);
4927 /* put the label in the LabelSymbol table */
4928 /* but first check if a label of the same */
4930 if ((csym = findSym (LabelTab, NULL, name)))
4931 werror (E_DUPLICATE_LABEL, label->name);
4933 addSym (LabelTab, label, name, label->level, 0, 0);
4937 label->key = labelKey++;
4938 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4944 /*-----------------------------------------------------------------*/
4945 /* createCase - generates the parsetree for a case statement */
4946 /*-----------------------------------------------------------------*/
4948 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4950 char caseLbl[SDCC_NAME_MAX + 1];
4954 /* if the switch statement does not exist */
4955 /* then case is out of context */
4958 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4962 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4963 /* if not a constant then error */
4964 if (!IS_LITERAL (caseVal->ftype))
4966 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4970 /* if not a integer than error */
4971 if (!IS_INTEGRAL (caseVal->ftype))
4973 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4977 /* find the end of the switch values chain */
4978 if (!(val = swStat->values.switchVals.swVals))
4979 swStat->values.switchVals.swVals = caseVal->opval.val;
4982 /* also order the cases according to value */
4984 int cVal = (int) floatFromVal (caseVal->opval.val);
4985 while (val && (int) floatFromVal (val) < cVal)
4991 /* if we reached the end then */
4994 pval->next = caseVal->opval.val;
4996 else if ((int) floatFromVal (val) == cVal)
4998 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5004 /* we found a value greater than */
5005 /* the current value we must add this */
5006 /* before the value */
5007 caseVal->opval.val->next = val;
5009 /* if this was the first in chain */
5010 if (swStat->values.switchVals.swVals == val)
5011 swStat->values.switchVals.swVals =
5014 pval->next = caseVal->opval.val;
5019 /* create the case label */
5020 SNPRINTF(caseLbl, sizeof(caseLbl),
5022 swStat->values.switchVals.swNum,
5023 (int) floatFromVal (caseVal->opval.val));
5025 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5030 /*-----------------------------------------------------------------*/
5031 /* createDefault - creates the parse tree for the default statement */
5032 /*-----------------------------------------------------------------*/
5034 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5036 char defLbl[SDCC_NAME_MAX + 1];
5038 /* if the switch statement does not exist */
5039 /* then case is out of context */
5042 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5046 if (swStat->values.switchVals.swDefault)
5048 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5053 /* turn on the default flag */
5054 swStat->values.switchVals.swDefault = 1;
5056 /* create the label */
5057 SNPRINTF (defLbl, sizeof(defLbl),
5058 "_default_%d", swStat->values.switchVals.swNum);
5059 return createLabel (newSymbol (defLbl, 0), stmnt);
5062 /*-----------------------------------------------------------------*/
5063 /* createIf - creates the parsetree for the if statement */
5064 /*-----------------------------------------------------------------*/
5066 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5068 static int Lblnum = 0;
5070 symbol *ifTrue, *ifFalse, *ifEnd;
5072 /* if neither exists */
5073 if (!elseBody && !ifBody) {
5074 // if there are no side effects (i++, j() etc)
5075 if (!hasSEFcalls(condAst)) {
5080 /* create the labels */
5081 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5082 ifFalse = newSymbol (buffer, NestLevel);
5083 /* if no else body then end == false */
5088 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5089 ifEnd = newSymbol (buffer, NestLevel);
5092 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5093 ifTrue = newSymbol (buffer, NestLevel);
5097 /* attach the ifTrue label to the top of it body */
5098 ifBody = createLabel (ifTrue, ifBody);
5099 /* attach a goto end to the ifBody if else is present */
5102 ifBody = newNode (NULLOP, ifBody,
5104 newAst_VALUE (symbolVal (ifEnd)),
5106 /* put the elseLabel on the else body */
5107 elseBody = createLabel (ifFalse, elseBody);
5108 /* out the end at the end of the body */
5109 elseBody = newNode (NULLOP,
5111 createLabel (ifEnd, NULL));
5115 ifBody = newNode (NULLOP, ifBody,
5116 createLabel (ifFalse, NULL));
5118 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5119 if (IS_IFX (condAst))
5122 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5124 return newNode (NULLOP, ifTree,
5125 newNode (NULLOP, ifBody, elseBody));
5129 /*-----------------------------------------------------------------*/
5130 /* createDo - creates parse tree for do */
5133 /* _docontinue_n: */
5134 /* condition_expression +-> trueLabel -> _dobody_n */
5136 /* +-> falseLabel-> _dobreak_n */
5138 /*-----------------------------------------------------------------*/
5140 createDo (symbol * trueLabel, symbol * continueLabel,
5141 symbol * falseLabel, ast * condAst, ast * doBody)
5146 /* if the body does not exist then it is simple */
5149 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5150 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5151 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5152 doTree->trueLabel = continueLabel;
5153 doTree->falseLabel = NULL;
5155 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5159 /* otherwise we have a body */
5160 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5162 /* attach the body label to the top */
5163 doBody = createLabel (trueLabel, doBody);
5164 /* attach the continue label to end of body */
5165 doBody = newNode (NULLOP, doBody,
5166 createLabel (continueLabel, NULL));
5168 /* now put the break label at the end */
5169 if (IS_IFX (condAst))
5172 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5174 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5176 /* putting it together */
5177 return newNode (NULLOP, doBody, doTree);
5180 /*-----------------------------------------------------------------*/
5181 /* createFor - creates parse tree for 'for' statement */
5184 /* condExpr +-> trueLabel -> _forbody_n */
5186 /* +-> falseLabel-> _forbreak_n */
5189 /* _forcontinue_n: */
5191 /* goto _forcond_n ; */
5193 /*-----------------------------------------------------------------*/
5195 createFor (symbol * trueLabel, symbol * continueLabel,
5196 symbol * falseLabel, symbol * condLabel,
5197 ast * initExpr, ast * condExpr, ast * loopExpr,
5202 /* if loopexpression not present then we can generate it */
5203 /* the same way as a while */
5205 return newNode (NULLOP, initExpr,
5206 createWhile (trueLabel, continueLabel,
5207 falseLabel, condExpr, forBody));
5208 /* vanilla for statement */
5209 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5211 if (condExpr && !IS_IFX (condExpr))
5212 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5215 /* attach condition label to condition */
5216 condExpr = createLabel (condLabel, condExpr);
5218 /* attach body label to body */
5219 forBody = createLabel (trueLabel, forBody);
5221 /* attach continue to forLoop expression & attach */
5222 /* goto the forcond @ and of loopExpression */
5223 loopExpr = createLabel (continueLabel,
5227 newAst_VALUE (symbolVal (condLabel)),
5229 /* now start putting them together */
5230 forTree = newNode (NULLOP, initExpr, condExpr);
5231 forTree = newNode (NULLOP, forTree, forBody);
5232 forTree = newNode (NULLOP, forTree, loopExpr);
5233 /* finally add the break label */
5234 forTree = newNode (NULLOP, forTree,
5235 createLabel (falseLabel, NULL));
5239 /*-----------------------------------------------------------------*/
5240 /* createWhile - creates parse tree for while statement */
5241 /* the while statement will be created as follows */
5243 /* _while_continue_n: */
5244 /* condition_expression +-> trueLabel -> _while_boby_n */
5246 /* +-> falseLabel -> _while_break_n */
5247 /* _while_body_n: */
5249 /* goto _while_continue_n */
5250 /* _while_break_n: */
5251 /*-----------------------------------------------------------------*/
5253 createWhile (symbol * trueLabel, symbol * continueLabel,
5254 symbol * falseLabel, ast * condExpr, ast * whileBody)
5258 /* put the continue label */
5259 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5260 condExpr = createLabel (continueLabel, condExpr);
5261 condExpr->lineno = 0;
5263 /* put the body label in front of the body */
5264 whileBody = createLabel (trueLabel, whileBody);
5265 whileBody->lineno = 0;
5266 /* put a jump to continue at the end of the body */
5267 /* and put break label at the end of the body */
5268 whileBody = newNode (NULLOP,
5271 newAst_VALUE (symbolVal (continueLabel)),
5272 createLabel (falseLabel, NULL)));
5274 /* put it all together */
5275 if (IS_IFX (condExpr))
5276 whileTree = condExpr;
5279 whileTree = newNode (IFX, condExpr, NULL);
5280 /* put the true & false labels in place */
5281 whileTree->trueLabel = trueLabel;
5282 whileTree->falseLabel = falseLabel;
5285 return newNode (NULLOP, whileTree, whileBody);
5288 /*-----------------------------------------------------------------*/
5289 /* isShiftRightLitVal _BitAndLitVal - helper function */
5290 /*-----------------------------------------------------------------*/
5292 isShiftRightLitVal_BitAndLitVal (ast * tree)
5294 /* if this is not a bit and */
5295 if (!IS_BITAND (tree))
5298 /* will look for tree of the form
5299 ( expr >> litval2) & litval1 */
5300 if (!IS_AST_LIT_VALUE (tree->right))
5303 if (!IS_RIGHT_OP (tree->left))
5306 if (!IS_AST_LIT_VALUE (tree->left->right))
5309 return tree->left->left;
5312 /*-----------------------------------------------------------------*/
5313 /* isBitAndPowOf2 - helper function */
5314 /*-----------------------------------------------------------------*/
5316 isBitAndPow2 (ast * tree)
5318 /* if this is not a bit and */
5319 if (!IS_BITAND (tree))
5322 /* will look for tree of the form
5323 ( expr & (1 << litval) */
5324 if (!IS_AST_LIT_VALUE (tree->right))
5327 return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
5330 /*-----------------------------------------------------------------*/
5331 /* optimizeGetHbit - get highest order bit of the expression */
5332 /*-----------------------------------------------------------------*/
5334 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5339 expr = isShiftRightLitVal_BitAndLitVal(tree);
5342 if ((AST_LIT_VALUE (tree->right) != 1) ||
5343 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5344 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5347 if (!expr && (resultType == RESULT_TYPE_BIT))
5350 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5356 /* make sure the port supports GETHBIT */
5357 if (port->hasExtBitOp
5358 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5361 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5364 /*-----------------------------------------------------------------*/
5365 /* optimizeGetAbit - get a single bit of the expression */
5366 /*-----------------------------------------------------------------*/
5368 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5373 expr = isShiftRightLitVal_BitAndLitVal(tree);
5376 if (AST_LIT_VALUE (tree->right) != 1)
5378 count = tree->left->right;
5380 if (!expr && (resultType == RESULT_TYPE_BIT))
5382 int p2 = isBitAndPow2 (tree);
5386 count = newAst_VALUE (valueFromLit (p2));
5392 /* make sure the port supports GETABIT */
5393 if (port->hasExtBitOp
5394 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5397 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5401 /*-----------------------------------------------------------------*/
5402 /* optimizeGetByte - get a byte of the expression */
5403 /*-----------------------------------------------------------------*/
5405 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5411 expr = isShiftRightLitVal_BitAndLitVal(tree);
5414 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5415 count = tree->left->right;
5416 if (AST_LIT_VALUE (tree->right) != 0xFF)
5419 if (!expr && resultType == RESULT_TYPE_CHAR)
5421 /* if this is a right shift over a multiple of 8 */
5422 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5424 i = (unsigned int) AST_LIT_VALUE (tree->right);
5425 count = tree->right;
5429 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5432 /* make sure the port supports GETBYTE */
5433 if (port->hasExtBitOp
5434 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5437 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5440 /*-----------------------------------------------------------------*/
5441 /* optimizeGetWord - get two bytes of the expression */
5442 /*-----------------------------------------------------------------*/
5444 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5450 expr = isShiftRightLitVal_BitAndLitVal(tree);
5453 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5454 count = tree->left->right;
5455 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5458 if (!expr && resultType == RESULT_TYPE_INT)
5460 /* if this is a right shift over a multiple of 8 */
5461 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5463 i = (unsigned int) AST_LIT_VALUE (tree->right);
5464 count = tree->right;
5468 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5471 /* make sure the port supports GETWORD */
5472 if (port->hasExtBitOp
5473 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5476 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5479 /*-----------------------------------------------------------------*/
5480 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5481 /*-----------------------------------------------------------------*/
5483 optimizeRRCRLC (ast * root)
5485 /* will look for trees of the form
5486 (?expr << 1) | (?expr >> 7) or
5487 (?expr >> 7) | (?expr << 1) will make that
5488 into a RLC : operation ..
5490 (?expr >> 1) | (?expr << 7) or
5491 (?expr << 7) | (?expr >> 1) will make that
5492 into a RRC operation
5493 note : by 7 I mean (number of bits required to hold the
5495 /* if the root operation is not a | operation then not */
5496 if (!IS_BITOR (root))
5499 /* I have to think of a better way to match patterns this sucks */
5500 /* that aside let's start looking for the first case : I use a
5501 negative check a lot to improve the efficiency */
5502 /* (?expr << 1) | (?expr >> 7) */
5503 if (IS_LEFT_OP (root->left) &&
5504 IS_RIGHT_OP (root->right))
5507 if (!SPEC_USIGN (TETYPE (root->left->left)))
5510 if (!IS_AST_LIT_VALUE (root->left->right) ||
5511 !IS_AST_LIT_VALUE (root->right->right))
5514 /* make sure it is the same expression */
5515 if (!isAstEqual (root->left->left,
5519 if (AST_LIT_VALUE (root->left->right) != 1)
5522 if (AST_LIT_VALUE (root->right->right) !=
5523 (getSize (TTYPE (root->left->left)) * 8 - 1))
5526 /* make sure the port supports RLC */
5527 if (port->hasExtBitOp
5528 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5531 /* whew got the first case : create the AST */
5532 return newNode (RLC, root->left->left, NULL);
5536 /* check for second case */
5537 /* (?expr >> 7) | (?expr << 1) */
5538 if (IS_LEFT_OP (root->right) &&
5539 IS_RIGHT_OP (root->left))
5542 if (!SPEC_USIGN (TETYPE (root->left->left)))
5545 if (!IS_AST_LIT_VALUE (root->left->right) ||
5546 !IS_AST_LIT_VALUE (root->right->right))
5549 /* make sure it is the same symbol */
5550 if (!isAstEqual (root->left->left,
5554 if (AST_LIT_VALUE (root->right->right) != 1)
5557 if (AST_LIT_VALUE (root->left->right) !=
5558 (getSize (TTYPE (root->left->left)) * 8 - 1))
5561 /* make sure the port supports RLC */
5562 if (port->hasExtBitOp
5563 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5566 /* whew got the first case : create the AST */
5567 return newNode (RLC, root->left->left, NULL);
5572 /* third case for RRC */
5573 /* (?symbol >> 1) | (?symbol << 7) */
5574 if (IS_LEFT_OP (root->right) &&
5575 IS_RIGHT_OP (root->left))
5578 if (!SPEC_USIGN (TETYPE (root->left->left)))
5581 if (!IS_AST_LIT_VALUE (root->left->right) ||
5582 !IS_AST_LIT_VALUE (root->right->right))
5585 /* make sure it is the same symbol */
5586 if (!isAstEqual (root->left->left,
5590 if (AST_LIT_VALUE (root->left->right) != 1)
5593 if (AST_LIT_VALUE (root->right->right) !=
5594 (getSize (TTYPE (root->left->left)) * 8 - 1))
5597 /* make sure the port supports RRC */
5598 if (port->hasExtBitOp
5599 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5602 /* whew got the first case : create the AST */
5603 return newNode (RRC, root->left->left, NULL);
5607 /* fourth and last case for now */
5608 /* (?symbol << 7) | (?symbol >> 1) */
5609 if (IS_RIGHT_OP (root->right) &&
5610 IS_LEFT_OP (root->left))
5613 if (!SPEC_USIGN (TETYPE (root->left->left)))
5616 if (!IS_AST_LIT_VALUE (root->left->right) ||
5617 !IS_AST_LIT_VALUE (root->right->right))
5620 /* make sure it is the same symbol */
5621 if (!isAstEqual (root->left->left,
5625 if (AST_LIT_VALUE (root->right->right) != 1)
5628 if (AST_LIT_VALUE (root->left->right) !=
5629 (getSize (TTYPE (root->left->left)) * 8 - 1))
5632 /* make sure the port supports RRC */
5633 if (port->hasExtBitOp
5634 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5637 /* whew got the first case : create the AST */
5638 return newNode (RRC, root->left->left, NULL);
5642 /* not found return root */
5646 /*-----------------------------------------------------------------*/
5647 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5648 /*-----------------------------------------------------------------*/
5650 optimizeSWAP (ast * root)
5652 /* will look for trees of the form
5653 (?expr << 4) | (?expr >> 4) or
5654 (?expr >> 4) | (?expr << 4) will make that
5655 into a SWAP : operation ..
5656 note : by 4 I mean (number of bits required to hold the
5658 /* if the root operation is not a | operation then not */
5659 if (!IS_BITOR (root))
5662 /* (?expr << 4) | (?expr >> 4) */
5663 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5664 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5667 if (!SPEC_USIGN (TETYPE (root->left->left)))
5670 if (!IS_AST_LIT_VALUE (root->left->right) ||
5671 !IS_AST_LIT_VALUE (root->right->right))
5674 /* make sure it is the same expression */
5675 if (!isAstEqual (root->left->left,
5679 if (AST_LIT_VALUE (root->left->right) !=
5680 (getSize (TTYPE (root->left->left)) * 4))
5683 if (AST_LIT_VALUE (root->right->right) !=
5684 (getSize (TTYPE (root->left->left)) * 4))
5687 /* make sure the port supports SWAP */
5688 if (port->hasExtBitOp
5689 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5692 /* found it : create the AST */
5693 return newNode (SWAP, root->left->left, NULL);
5697 /* not found return root */
5701 /*-----------------------------------------------------------------*/
5702 /* optimizeCompare - optimizes compares for bit variables */
5703 /*-----------------------------------------------------------------*/
5705 optimizeCompare (ast * root)
5707 ast *optExpr = NULL;
5710 unsigned int litValue;
5712 /* if nothing then return nothing */
5716 /* if not a compare op then do leaves */
5717 if (!IS_COMPARE_OP (root))
5719 root->left = optimizeCompare (root->left);
5720 root->right = optimizeCompare (root->right);
5724 /* if left & right are the same then depending
5725 of the operation do */
5726 if (isAstEqual (root->left, root->right))
5728 switch (root->opval.op)
5733 optExpr = newAst_VALUE (constVal ("0"));
5738 optExpr = newAst_VALUE (constVal ("1"));
5742 return decorateType (optExpr, RESULT_TYPE_NONE);
5745 vleft = (root->left->type == EX_VALUE ?
5746 root->left->opval.val : NULL);
5748 vright = (root->right->type == EX_VALUE ?
5749 root->right->opval.val : NULL);
5751 /* if left is a BITVAR in BITSPACE */
5752 /* and right is a LITERAL then opt- */
5753 /* imize else do nothing */
5754 if (vleft && vright &&
5755 IS_BITVAR (vleft->etype) &&
5756 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5757 IS_LITERAL (vright->etype))
5760 /* if right side > 1 then comparison may never succeed */
5761 if ((litValue = (int) floatFromVal (vright)) > 1)
5763 werror (W_BAD_COMPARE);
5769 switch (root->opval.op)
5771 case '>': /* bit value greater than 1 cannot be */
5772 werror (W_BAD_COMPARE);
5776 case '<': /* bit value < 1 means 0 */
5778 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5781 case LE_OP: /* bit value <= 1 means no check */
5782 optExpr = newAst_VALUE (vright);
5785 case GE_OP: /* bit value >= 1 means only check for = */
5787 optExpr = newAst_VALUE (vleft);
5792 { /* literal is zero */
5793 switch (root->opval.op)
5795 case '<': /* bit value < 0 cannot be */
5796 werror (W_BAD_COMPARE);
5800 case '>': /* bit value > 0 means 1 */
5802 optExpr = newAst_VALUE (vleft);
5805 case LE_OP: /* bit value <= 0 means no check */
5806 case GE_OP: /* bit value >= 0 means no check */
5807 werror (W_BAD_COMPARE);
5811 case EQ_OP: /* bit == 0 means ! of bit */
5812 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5816 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5817 } /* end-of-if of BITVAR */
5823 /*-----------------------------------------------------------------*/
5824 /* addSymToBlock : adds the symbol to the first block we find */
5825 /*-----------------------------------------------------------------*/
5827 addSymToBlock (symbol * sym, ast * tree)
5829 /* reached end of tree or a leaf */
5830 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5834 if (IS_AST_OP (tree) &&
5835 tree->opval.op == BLOCK)
5838 symbol *lsym = copySymbol (sym);
5840 lsym->next = AST_VALUES (tree, sym);
5841 AST_VALUES (tree, sym) = lsym;
5845 addSymToBlock (sym, tree->left);
5846 addSymToBlock (sym, tree->right);
5849 /*-----------------------------------------------------------------*/
5850 /* processRegParms - do processing for register parameters */
5851 /*-----------------------------------------------------------------*/
5853 processRegParms (value * args, ast * body)
5857 if (IS_REGPARM (args->etype))
5858 addSymToBlock (args->sym, body);
5863 /*-----------------------------------------------------------------*/
5864 /* resetParmKey - resets the operandkeys for the symbols */
5865 /*-----------------------------------------------------------------*/
5866 DEFSETFUNC (resetParmKey)
5879 /*------------------------------------------------------------------*/
5880 /* fixupInlineLabel - change a label in an inlined function so that */
5881 /* it is always unique no matter how many times */
5882 /* the function is inlined. */
5883 /*------------------------------------------------------------------*/
5885 fixupInlineLabel (symbol * sym)
5887 char name[SDCC_NAME_MAX + 1];
5889 SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
5890 strcpy (sym->name, name);
5894 /*------------------------------------------------------------------*/
5895 /* copyAstLoc - copy location information (file, line, block, etc.) */
5896 /* from one ast node to another */
5897 /*------------------------------------------------------------------*/
5899 copyAstLoc (ast * dest, ast * src)
5901 dest->lineno = src->lineno;
5902 dest->filename = src->filename;
5903 dest->level = src->level;
5904 dest->block = src->block;
5905 dest->seqPoint = src->seqPoint;
5910 /*-----------------------------------------------------------------*/
5911 /* fixupInline - perform various fixups on an inline function tree */
5912 /* to take into account that it is no longer a */
5913 /* stand-alone function. */
5914 /*-----------------------------------------------------------------*/
5916 fixupInline (ast * tree, int level)
5918 tree->block = currBlockno;
5920 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
5927 /* Add any declared variables back into the symbol table */
5928 decls = tree->values.sym;
5931 decls->level = level;
5932 decls->block = currBlockno;
5933 addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0);
5934 decls = decls->next;
5938 tree->level = level;
5940 /* Update symbols */
5941 if (IS_AST_VALUE (tree) &&
5942 tree->opval.val->sym)
5944 symbol * sym = tree->opval.val->sym;
5947 sym->block = currBlockno;
5949 /* If the symbol is a label, we need to renumber it */
5951 fixupInlineLabel (sym);
5954 /* Update IFX target labels */
5955 if (tree->type == EX_OP && tree->opval.op == IFX)
5957 if (tree->trueLabel)
5958 fixupInlineLabel (tree->trueLabel);
5959 if (tree->falseLabel)
5960 fixupInlineLabel (tree->falseLabel);
5963 /* Replace RETURN with optional assignment and a GOTO to the end */
5964 /* of the inlined function */
5965 if (tree->type == EX_OP && tree->opval.op == RETURN)
5967 ast * assignTree = NULL;
5970 if (inlineState.retsym && tree->right)
5972 assignTree = newNode ('=',
5973 newAst_VALUE (symbolVal (inlineState.retsym)),
5975 copyAstLoc (assignTree, tree);
5978 gotoTree = newNode (GOTO,
5979 newAst_VALUE (symbolVal (inlineState.retlab)),
5981 copyAstLoc (gotoTree, tree);
5983 tree->opval.op = NULLOP;
5984 tree->left = assignTree;
5985 tree->right = gotoTree;
5988 /* Update any children */
5990 fixupInline (tree->left, level);
5992 fixupInline (tree->right, level);
5994 if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
5996 symbol * label = tree->left->opval.val->sym;
5998 label->key = labelKey++;
5999 /* Add this label back into the symbol table */
6000 addSym (LabelTab, label, label->name, label->level, 0, 0);
6004 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
6010 /*-----------------------------------------------------------------*/
6011 /* inlineAddDecl - add a variable declaration to an ast block. It */
6012 /* is also added to the symbol table if addSymTab */
6014 /*-----------------------------------------------------------------*/
6016 inlineAddDecl (symbol * sym, ast * block, int addSymTab)
6020 symbol **decl = &(block->values.sym);
6022 sym->level = block->level;
6023 sym->block = block->block;
6027 if (strcmp ((*decl)->name, sym->name) == 0)
6029 decl = &( (*decl)->next );
6035 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0);
6041 /*-----------------------------------------------------------------*/
6042 /* inlineTempVar - create a temporary variable for inlining */
6043 /*-----------------------------------------------------------------*/
6045 inlineTempVar (sym_link * type, int level)
6049 sym = newSymbol (genSymName(level), level );
6050 sym->type = copyLinkChain (type);
6051 sym->etype = getSpec(sym->type);
6052 SPEC_SCLS (sym->etype) = S_AUTO;
6053 SPEC_OCLS (sym->etype) = NULL;
6054 SPEC_EXTR (sym->etype) = 0;
6055 SPEC_STAT (sym->etype) = 0;
6056 if IS_SPEC (sym->type)
6057 SPEC_VOLATILE (sym->type) = 0;
6059 DCL_PTR_VOLATILE (sym->type) = 0;
6060 SPEC_ABSA (sym->etype) = 0;
6066 /*-----------------------------------------------------------------*/
6067 /* inlineFindParmRecurse - recursive function for inlineFindParm */
6068 /*-----------------------------------------------------------------*/
6070 inlineFindParmRecurse (ast * parms, int *index)
6075 if (parms->type == EX_OP && parms->opval.op == PARAM)
6079 p=inlineFindParmRecurse (parms->left, index);
6082 p=inlineFindParmRecurse (parms->right, index);
6093 /*-----------------------------------------------------------------*/
6094 /* inlineFindParm - search an ast tree of parameters to find one */
6095 /* at a particular index (0=first parameter). */
6096 /* Returns NULL if not found. */
6097 /*-----------------------------------------------------------------*/
6099 inlineFindParm (ast * parms, int index)
6101 return inlineFindParmRecurse (parms, &index);
6105 /*-----------------------------------------------------------------*/
6106 /* expandInlineFuncs - replace calls to inline functions with the */
6107 /* function itself */
6108 /*-----------------------------------------------------------------*/
6110 expandInlineFuncs (ast * tree, ast * block)
6112 if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left
6113 && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym)
6115 symbol * func = tree->left->opval.val->sym;
6118 /* The symbol is probably not bound yet, so find the real one */
6119 csym = findSymWithLevel (SymbolTab, func);
6123 /* Is this an inline function that we can inline? */
6124 if (IFFUNC_ISINLINE (func->type) && func->funcTree)
6126 symbol * retsym = NULL;
6134 /* Generate a label for the inlined function to branch to */
6135 /* in case it contains a return statement */
6136 retlab = newSymbol (genSymName(tree->level+1), tree->level+1 );
6139 inlineState.retlab = retlab;
6141 /* Build the subtree for the inlined function in the form: */
6142 /* { //inlinetree block */
6143 /* { //inlinetree2 block */
6144 /* inline_function_code; */
6148 temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL);
6149 copyAstLoc (temptree, tree);
6150 temptree = newNode (NULLOP, copyAst (func->funcTree), temptree);
6151 copyAstLoc (temptree, tree);
6152 temptree = newNode (BLOCK, NULL, temptree);
6153 copyAstLoc (temptree, tree);
6154 inlinetree2 = temptree;
6155 inlinetree = newNode (BLOCK, NULL, inlinetree2);
6156 copyAstLoc (inlinetree, tree);
6158 /* To pass parameters to the inlined function, we need some */
6159 /* intermediate variables. This avoids scoping problems */
6160 /* when the parameter declaration names are used differently */
6161 /* during the function call. For example, a function */
6162 /* declared as func(int x, int y) but called as func(y,x). */
6163 /* { //inlinetree block */
6164 /* type1 temparg1; */
6166 /* typen tempargn; */
6167 /* temparg1 = argument1; */
6169 /* tempargn = argumentn; */
6170 /* { //inlinetree2 block */
6174 /* param1 = temparg1; */
6176 /* paramn = tempargn; */
6177 /* inline_function_code; */
6181 args = FUNC_ARGS (func->type);
6188 symbol * parm = copySymbol (args->sym);
6190 temparg = inlineTempVar (args->sym->type, tree->level+1);
6191 inlineAddDecl (temparg, inlinetree, FALSE);
6193 passedarg = inlineFindParm (tree->right, argIndex);
6194 assigntree = newNode ('=',
6195 newAst_VALUE (symbolVal (temparg)),
6197 inlinetree->right = newNode (NULLOP,
6201 inlineAddDecl (parm, inlinetree2, FALSE);
6204 assigntree = newNode ('=',
6205 newAst_VALUE (symbolVal (parm)),
6206 newAst_VALUE (symbolVal (temparg)));
6207 inlinetree2->right = newNode (NULLOP,
6209 inlinetree2->right);
6216 /* Handle the return type */
6217 if (!IS_VOID (func->type->next))
6219 /* Create a temporary symbol to hold the return value and */
6220 /* join it with the inlined function using the comma */
6221 /* operator. The fixupInline function will take care of */
6222 /* changing return statements into assignments to retsym. */
6223 /* (parameter passing and return label omitted for clarity) */
6224 /* rettype retsym; */
6226 /* {{inline_function_code}}, retsym */
6228 retsym = inlineTempVar (func->type->next, tree->level);
6229 inlineAddDecl (retsym, block, TRUE);
6231 tree->opval.op = ',';
6232 tree->left = inlinetree;
6233 tree->right = newAst_VALUE (symbolVal (retsym));
6237 tree->opval.op = NULLOP;
6239 tree->right = inlinetree;
6241 inlineState.retsym = retsym;
6243 /* Renumber the various internal counters on the inlined */
6244 /* function's tree nodes and symbols. Add the inlined */
6245 /* function's local variables to the appropriate scope(s). */
6246 /* Convert inlined return statements to an assignment to */
6247 /* retsym (if needed) and a goto retlab. */
6248 fixupInline (inlinetree, inlinetree->level);
6249 inlineState.count++;
6254 /* Recursively continue to search for functions to inline. */
6255 if (IS_AST_OP (tree))
6257 if (tree->opval.op == BLOCK)
6261 expandInlineFuncs (tree->left, block);
6263 expandInlineFuncs (tree->right, block);
6268 /*-----------------------------------------------------------------*/
6269 /* createFunction - This is the key node that calls the iCode for */
6270 /* generating the code for a function. Note code */
6271 /* is generated function by function, later when */
6272 /* add inter-procedural analysis this will change */
6273 /*-----------------------------------------------------------------*/
6275 createFunction (symbol * name, ast * body)
6281 iCode *piCode = NULL;
6283 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
6284 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
6286 /* if check function return 0 then some problem */
6287 if (checkFunction (name, NULL) == 0)
6290 /* create a dummy block if none exists */
6292 body = newNode (BLOCK, NULL, NULL);
6296 /* check if the function name already in the symbol table */
6297 if ((csym = findSym (SymbolTab, NULL, name->name)))
6300 /* special case for compiler defined functions
6301 we need to add the name to the publics list : this
6302 actually means we are now compiling the compiler
6306 addSet (&publics, name);
6311 addSymChain (&name);
6312 allocVariables (name);
6314 name->lastLine = lexLineno;
6317 /* set the stack pointer */
6318 stackPtr = -port->stack.direction * port->stack.call_overhead;
6321 if (IFFUNC_ISISR (name->type))
6322 stackPtr -= port->stack.direction * port->stack.isr_overhead;
6324 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
6326 if (options.useXstack)
6327 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
6329 stackPtr -= port->stack.direction * port->stack.reent_overhead;
6332 fetype = getSpec (name->type); /* get the specifier for the function */
6333 /* if this is a reentrant function then */
6334 if (IFFUNC_ISREENT (name->type))
6337 inlineState.count = 0;
6338 expandInlineFuncs (body, NULL);
6340 if (FUNC_ISINLINE (name->type))
6341 name->funcTree = copyAst (body);
6343 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
6345 /* do processing for parameters that are passed in registers */
6346 processRegParms (FUNC_ARGS(name->type), body);
6348 /* set the stack pointer */
6352 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
6354 /* allocate & autoinit the block variables */
6355 processBlockVars (body, &stack, ALLOCATE);
6357 /* name needs to be mangled */
6358 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
6360 body = resolveSymbols (body); /* resolve the symbols */
6361 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
6363 /* save the stack information */
6364 if (options.useXstack)
6365 name->xstack = SPEC_STAK (fetype) = stack;
6367 name->stack = SPEC_STAK (fetype) = stack;
6369 ex = newAst_VALUE (symbolVal (name)); /* create name */
6370 ex = newNode (FUNCTION, ex, body);
6371 ex->values.args = FUNC_ARGS(name->type);
6373 if (options.dump_tree)
6378 /* Do not generate code for inline functions unless extern also */
6379 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
6382 /* create the node & generate intermediate code */
6384 codeOutBuf = &code->oBuf;
6385 piCode = iCodeFromAst (ex);
6386 name->generated = 1;
6391 eBBlockFromiCode (piCode);
6393 /* if there are any statics then do them */
6396 GcurMemmap = statsg;
6397 codeOutBuf = &statsg->oBuf;
6398 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6404 /* dealloc the block variables */
6405 processBlockVars (body, &stack, DEALLOCATE);
6406 outputDebugStackSymbols();
6407 /* deallocate paramaters */
6408 deallocParms (FUNC_ARGS(name->type));
6410 if (IFFUNC_ISREENT (name->type))
6413 /* we are done freeup memory & cleanup */
6415 if (port->reset_labelKey) labelKey = 1;
6417 FUNC_HASBODY(name->type) = 1;
6418 addSet (&operKeyReset, name);
6419 applyToSet (operKeyReset, resetParmKey);
6424 cleanUpLevel (LabelTab, 0);
6425 cleanUpBlock (StructTab, 1);
6426 cleanUpBlock (TypedefTab, 1);
6428 xstack->syms = NULL;
6429 istack->syms = NULL;
6434 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6435 /*-----------------------------------------------------------------*/
6436 /* ast_print : prints the ast (for debugging purposes) */
6437 /*-----------------------------------------------------------------*/
6439 void ast_print (ast * tree, FILE *outfile, int indent)
6444 /* can print only decorated trees */
6445 if (!tree->decorated) return;
6447 /* if any child is an error | this one is an error do nothing */
6448 if (tree->isError ||
6449 (tree->left && tree->left->isError) ||
6450 (tree->right && tree->right->isError)) {
6451 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6455 /* print the line */
6456 /* if not block & function */
6457 if (tree->type == EX_OP &&
6458 (tree->opval.op != FUNCTION &&
6459 tree->opval.op != BLOCK &&
6460 tree->opval.op != NULLOP)) {
6463 if (tree->opval.op == FUNCTION) {
6465 value *args=FUNC_ARGS(tree->left->opval.val->type);
6466 fprintf(outfile,"FUNCTION (%s=%p) type (",
6467 tree->left->opval.val->name, tree);
6468 printTypeChain (tree->left->opval.val->type->next,outfile);
6469 fprintf(outfile,") args (");
6472 fprintf (outfile, ", ");
6474 printTypeChain (args ? args->type : NULL, outfile);
6476 args= args ? args->next : NULL;
6478 fprintf(outfile,")\n");
6479 ast_print(tree->left,outfile,indent);
6480 ast_print(tree->right,outfile,indent);
6483 if (tree->opval.op == BLOCK) {
6484 symbol *decls = tree->values.sym;
6485 INDENT(indent,outfile);
6486 fprintf(outfile,"{\n");
6488 INDENT(indent+2,outfile);
6489 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6490 decls->name, decls);
6491 printTypeChain(decls->type,outfile);
6492 fprintf(outfile,")\n");
6494 decls = decls->next;
6496 ast_print(tree->right,outfile,indent+2);
6497 INDENT(indent,outfile);
6498 fprintf(outfile,"}\n");
6501 if (tree->opval.op == NULLOP) {
6502 ast_print(tree->left,outfile,indent);
6503 ast_print(tree->right,outfile,indent);
6506 INDENT(indent,outfile);
6508 /*------------------------------------------------------------------*/
6509 /*----------------------------*/
6510 /* leaf has been reached */
6511 /*----------------------------*/
6512 /* if this is of type value */
6513 /* just get the type */
6514 if (tree->type == EX_VALUE) {
6516 if (IS_LITERAL (tree->opval.val->etype)) {
6517 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6518 if (SPEC_USIGN (tree->opval.val->etype))
6519 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
6521 fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
6522 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
6523 floatFromVal(tree->opval.val));
6524 } else if (tree->opval.val->sym) {
6525 /* if the undefined flag is set then give error message */
6526 if (tree->opval.val->sym->undefined) {
6527 fprintf(outfile,"UNDEFINED SYMBOL ");
6529 fprintf(outfile,"SYMBOL ");
6531 fprintf(outfile,"(%s=%p @ %p)",
6532 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6535 fprintf(outfile," type (");
6536 printTypeChain(tree->ftype,outfile);
6537 fprintf(outfile,")\n");
6539 fprintf(outfile,"\n");
6544 /* if type link for the case of cast */
6545 if (tree->type == EX_LINK) {
6546 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6547 printTypeChain(tree->opval.lnk,outfile);
6548 fprintf(outfile,")\n");
6553 /* depending on type of operator do */
6555 switch (tree->opval.op) {
6556 /*------------------------------------------------------------------*/
6557 /*----------------------------*/
6559 /*----------------------------*/
6561 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6562 printTypeChain(tree->ftype,outfile);
6563 fprintf(outfile,")\n");
6564 ast_print(tree->left,outfile,indent+2);
6565 ast_print(tree->right,outfile,indent+2);
6568 /*------------------------------------------------------------------*/
6569 /*----------------------------*/
6571 /*----------------------------*/
6573 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6574 printTypeChain(tree->ftype,outfile);
6575 fprintf(outfile,")\n");
6576 ast_print(tree->left,outfile,indent+2);
6577 ast_print(tree->right,outfile,indent+2);
6580 /*------------------------------------------------------------------*/
6581 /*----------------------------*/
6582 /* struct/union pointer */
6583 /*----------------------------*/
6585 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6586 printTypeChain(tree->ftype,outfile);
6587 fprintf(outfile,")\n");
6588 ast_print(tree->left,outfile,indent+2);
6589 ast_print(tree->right,outfile,indent+2);
6592 /*------------------------------------------------------------------*/
6593 /*----------------------------*/
6594 /* ++/-- operation */
6595 /*----------------------------*/
6598 fprintf(outfile,"post-");
6600 fprintf(outfile,"pre-");
6601 fprintf(outfile,"INC_OP (%p) type (",tree);
6602 printTypeChain(tree->ftype,outfile);
6603 fprintf(outfile,")\n");
6604 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6605 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6610 fprintf(outfile,"post-");
6612 fprintf(outfile,"pre-");
6613 fprintf(outfile,"DEC_OP (%p) type (",tree);
6614 printTypeChain(tree->ftype,outfile);
6615 fprintf(outfile,")\n");
6616 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6617 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6620 /*------------------------------------------------------------------*/
6621 /*----------------------------*/
6623 /*----------------------------*/
6626 fprintf(outfile,"& (%p) type (",tree);
6627 printTypeChain(tree->ftype,outfile);
6628 fprintf(outfile,")\n");
6629 ast_print(tree->left,outfile,indent+2);
6630 ast_print(tree->right,outfile,indent+2);
6632 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6633 printTypeChain(tree->ftype,outfile);
6634 fprintf(outfile,")\n");
6635 ast_print(tree->left,outfile,indent+2);
6636 ast_print(tree->right,outfile,indent+2);
6639 /*----------------------------*/
6641 /*----------------------------*/
6643 fprintf(outfile,"OR (%p) type (",tree);
6644 printTypeChain(tree->ftype,outfile);
6645 fprintf(outfile,")\n");
6646 ast_print(tree->left,outfile,indent+2);
6647 ast_print(tree->right,outfile,indent+2);
6649 /*------------------------------------------------------------------*/
6650 /*----------------------------*/
6652 /*----------------------------*/
6654 fprintf(outfile,"XOR (%p) type (",tree);
6655 printTypeChain(tree->ftype,outfile);
6656 fprintf(outfile,")\n");
6657 ast_print(tree->left,outfile,indent+2);
6658 ast_print(tree->right,outfile,indent+2);
6661 /*------------------------------------------------------------------*/
6662 /*----------------------------*/
6664 /*----------------------------*/
6666 fprintf(outfile,"DIV (%p) type (",tree);
6667 printTypeChain(tree->ftype,outfile);
6668 fprintf(outfile,")\n");
6669 ast_print(tree->left,outfile,indent+2);
6670 ast_print(tree->right,outfile,indent+2);
6672 /*------------------------------------------------------------------*/
6673 /*----------------------------*/
6675 /*----------------------------*/
6677 fprintf(outfile,"MOD (%p) type (",tree);
6678 printTypeChain(tree->ftype,outfile);
6679 fprintf(outfile,")\n");
6680 ast_print(tree->left,outfile,indent+2);
6681 ast_print(tree->right,outfile,indent+2);
6684 /*------------------------------------------------------------------*/
6685 /*----------------------------*/
6686 /* address dereference */
6687 /*----------------------------*/
6688 case '*': /* can be unary : if right is null then unary operation */
6690 fprintf(outfile,"DEREF (%p) type (",tree);
6691 printTypeChain(tree->ftype,outfile);
6692 fprintf(outfile,")\n");
6693 ast_print(tree->left,outfile,indent+2);
6696 /*------------------------------------------------------------------*/
6697 /*----------------------------*/
6698 /* multiplication */
6699 /*----------------------------*/
6700 fprintf(outfile,"MULT (%p) type (",tree);
6701 printTypeChain(tree->ftype,outfile);
6702 fprintf(outfile,")\n");
6703 ast_print(tree->left,outfile,indent+2);
6704 ast_print(tree->right,outfile,indent+2);
6708 /*------------------------------------------------------------------*/
6709 /*----------------------------*/
6710 /* unary '+' operator */
6711 /*----------------------------*/
6715 fprintf(outfile,"UPLUS (%p) type (",tree);
6716 printTypeChain(tree->ftype,outfile);
6717 fprintf(outfile,")\n");
6718 ast_print(tree->left,outfile,indent+2);
6720 /*------------------------------------------------------------------*/
6721 /*----------------------------*/
6723 /*----------------------------*/
6724 fprintf(outfile,"ADD (%p) type (",tree);
6725 printTypeChain(tree->ftype,outfile);
6726 fprintf(outfile,")\n");
6727 ast_print(tree->left,outfile,indent+2);
6728 ast_print(tree->right,outfile,indent+2);
6731 /*------------------------------------------------------------------*/
6732 /*----------------------------*/
6734 /*----------------------------*/
6735 case '-': /* can be unary */
6737 fprintf(outfile,"UMINUS (%p) type (",tree);
6738 printTypeChain(tree->ftype,outfile);
6739 fprintf(outfile,")\n");
6740 ast_print(tree->left,outfile,indent+2);
6742 /*------------------------------------------------------------------*/
6743 /*----------------------------*/
6745 /*----------------------------*/
6746 fprintf(outfile,"SUB (%p) type (",tree);
6747 printTypeChain(tree->ftype,outfile);
6748 fprintf(outfile,")\n");
6749 ast_print(tree->left,outfile,indent+2);
6750 ast_print(tree->right,outfile,indent+2);
6753 /*------------------------------------------------------------------*/
6754 /*----------------------------*/
6756 /*----------------------------*/
6758 fprintf(outfile,"COMPL (%p) type (",tree);
6759 printTypeChain(tree->ftype,outfile);
6760 fprintf(outfile,")\n");
6761 ast_print(tree->left,outfile,indent+2);
6763 /*------------------------------------------------------------------*/
6764 /*----------------------------*/
6766 /*----------------------------*/
6768 fprintf(outfile,"NOT (%p) type (",tree);
6769 printTypeChain(tree->ftype,outfile);
6770 fprintf(outfile,")\n");
6771 ast_print(tree->left,outfile,indent+2);
6773 /*------------------------------------------------------------------*/
6774 /*----------------------------*/
6776 /*----------------------------*/
6778 fprintf(outfile,"RRC (%p) type (",tree);
6779 printTypeChain(tree->ftype,outfile);
6780 fprintf(outfile,")\n");
6781 ast_print(tree->left,outfile,indent+2);
6785 fprintf(outfile,"RLC (%p) type (",tree);
6786 printTypeChain(tree->ftype,outfile);
6787 fprintf(outfile,")\n");
6788 ast_print(tree->left,outfile,indent+2);
6791 fprintf(outfile,"SWAP (%p) type (",tree);
6792 printTypeChain(tree->ftype,outfile);
6793 fprintf(outfile,")\n");
6794 ast_print(tree->left,outfile,indent+2);
6797 fprintf(outfile,"GETHBIT (%p) type (",tree);
6798 printTypeChain(tree->ftype,outfile);
6799 fprintf(outfile,")\n");
6800 ast_print(tree->left,outfile,indent+2);
6803 fprintf(outfile,"GETABIT (%p) type (",tree);
6804 printTypeChain(tree->ftype,outfile);
6805 fprintf(outfile,")\n");
6806 ast_print(tree->left,outfile,indent+2);
6807 ast_print(tree->right,outfile,indent+2);
6810 fprintf(outfile,"GETBYTE (%p) type (",tree);
6811 printTypeChain(tree->ftype,outfile);
6812 fprintf(outfile,")\n");
6813 ast_print(tree->left,outfile,indent+2);
6814 ast_print(tree->right,outfile,indent+2);
6817 fprintf(outfile,"GETWORD (%p) type (",tree);
6818 printTypeChain(tree->ftype,outfile);
6819 fprintf(outfile,")\n");
6820 ast_print(tree->left,outfile,indent+2);
6821 ast_print(tree->right,outfile,indent+2);
6824 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6825 printTypeChain(tree->ftype,outfile);
6826 fprintf(outfile,")\n");
6827 ast_print(tree->left,outfile,indent+2);
6828 ast_print(tree->right,outfile,indent+2);
6831 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6832 printTypeChain(tree->ftype,outfile);
6833 fprintf(outfile,")\n");
6834 ast_print(tree->left,outfile,indent+2);
6835 ast_print(tree->right,outfile,indent+2);
6837 /*------------------------------------------------------------------*/
6838 /*----------------------------*/
6840 /*----------------------------*/
6841 case CAST: /* change the type */
6842 fprintf(outfile,"CAST (%p) from type (",tree);
6843 printTypeChain(tree->right->ftype,outfile);
6844 fprintf(outfile,") to type (");
6845 printTypeChain(tree->ftype,outfile);
6846 fprintf(outfile,")\n");
6847 ast_print(tree->right,outfile,indent+2);
6851 fprintf(outfile,"ANDAND (%p) type (",tree);
6852 printTypeChain(tree->ftype,outfile);
6853 fprintf(outfile,")\n");
6854 ast_print(tree->left,outfile,indent+2);
6855 ast_print(tree->right,outfile,indent+2);
6858 fprintf(outfile,"OROR (%p) type (",tree);
6859 printTypeChain(tree->ftype,outfile);
6860 fprintf(outfile,")\n");
6861 ast_print(tree->left,outfile,indent+2);
6862 ast_print(tree->right,outfile,indent+2);
6865 /*------------------------------------------------------------------*/
6866 /*----------------------------*/
6867 /* comparison operators */
6868 /*----------------------------*/
6870 fprintf(outfile,"GT(>) (%p) type (",tree);
6871 printTypeChain(tree->ftype,outfile);
6872 fprintf(outfile,")\n");
6873 ast_print(tree->left,outfile,indent+2);
6874 ast_print(tree->right,outfile,indent+2);
6877 fprintf(outfile,"LT(<) (%p) type (",tree);
6878 printTypeChain(tree->ftype,outfile);
6879 fprintf(outfile,")\n");
6880 ast_print(tree->left,outfile,indent+2);
6881 ast_print(tree->right,outfile,indent+2);
6884 fprintf(outfile,"LE(<=) (%p) type (",tree);
6885 printTypeChain(tree->ftype,outfile);
6886 fprintf(outfile,")\n");
6887 ast_print(tree->left,outfile,indent+2);
6888 ast_print(tree->right,outfile,indent+2);
6891 fprintf(outfile,"GE(>=) (%p) type (",tree);
6892 printTypeChain(tree->ftype,outfile);
6893 fprintf(outfile,")\n");
6894 ast_print(tree->left,outfile,indent+2);
6895 ast_print(tree->right,outfile,indent+2);
6898 fprintf(outfile,"EQ(==) (%p) type (",tree);
6899 printTypeChain(tree->ftype,outfile);
6900 fprintf(outfile,")\n");
6901 ast_print(tree->left,outfile,indent+2);
6902 ast_print(tree->right,outfile,indent+2);
6905 fprintf(outfile,"NE(!=) (%p) type (",tree);
6906 printTypeChain(tree->ftype,outfile);
6907 fprintf(outfile,")\n");
6908 ast_print(tree->left,outfile,indent+2);
6909 ast_print(tree->right,outfile,indent+2);
6910 /*------------------------------------------------------------------*/
6911 /*----------------------------*/
6913 /*----------------------------*/
6914 case SIZEOF: /* evaluate wihout code generation */
6915 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6918 /*------------------------------------------------------------------*/
6919 /*----------------------------*/
6920 /* conditional operator '?' */
6921 /*----------------------------*/
6923 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6924 printTypeChain(tree->ftype,outfile);
6925 fprintf(outfile,")\n");
6926 ast_print(tree->left,outfile,indent+2);
6927 ast_print(tree->right,outfile,indent+2);
6931 fprintf(outfile,"COLON(:) (%p) type (",tree);
6932 printTypeChain(tree->ftype,outfile);
6933 fprintf(outfile,")\n");
6934 ast_print(tree->left,outfile,indent+2);
6935 ast_print(tree->right,outfile,indent+2);
6938 /*------------------------------------------------------------------*/
6939 /*----------------------------*/
6940 /* assignment operators */
6941 /*----------------------------*/
6943 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6944 printTypeChain(tree->ftype,outfile);
6945 fprintf(outfile,")\n");
6946 ast_print(tree->left,outfile,indent+2);
6947 ast_print(tree->right,outfile,indent+2);
6950 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6951 printTypeChain(tree->ftype,outfile);
6952 fprintf(outfile,")\n");
6953 ast_print(tree->left,outfile,indent+2);
6954 ast_print(tree->right,outfile,indent+2);
6957 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6958 printTypeChain(tree->ftype,outfile);
6959 fprintf(outfile,")\n");
6960 ast_print(tree->left,outfile,indent+2);
6961 ast_print(tree->right,outfile,indent+2);
6964 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6965 printTypeChain(tree->ftype,outfile);
6966 fprintf(outfile,")\n");
6967 ast_print(tree->left,outfile,indent+2);
6968 ast_print(tree->right,outfile,indent+2);
6971 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6972 printTypeChain(tree->ftype,outfile);
6973 fprintf(outfile,")\n");
6974 ast_print(tree->left,outfile,indent+2);
6975 ast_print(tree->right,outfile,indent+2);
6978 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6979 printTypeChain(tree->ftype,outfile);
6980 fprintf(outfile,")\n");
6981 ast_print(tree->left,outfile,indent+2);
6982 ast_print(tree->right,outfile,indent+2);
6985 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6986 printTypeChain(tree->ftype,outfile);
6987 fprintf(outfile,")\n");
6988 ast_print(tree->left,outfile,indent+2);
6989 ast_print(tree->right,outfile,indent+2);
6991 /*------------------------------------------------------------------*/
6992 /*----------------------------*/
6994 /*----------------------------*/
6996 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6997 printTypeChain(tree->ftype,outfile);
6998 fprintf(outfile,")\n");
6999 ast_print(tree->left,outfile,indent+2);
7000 ast_print(tree->right,outfile,indent+2);
7002 /*------------------------------------------------------------------*/
7003 /*----------------------------*/
7005 /*----------------------------*/
7007 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
7008 printTypeChain(tree->ftype,outfile);
7009 fprintf(outfile,")\n");
7010 ast_print(tree->left,outfile,indent+2);
7011 ast_print(tree->right,outfile,indent+2);
7013 /*------------------------------------------------------------------*/
7014 /*----------------------------*/
7015 /* straight assignemnt */
7016 /*----------------------------*/
7018 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
7019 printTypeChain(tree->ftype,outfile);
7020 fprintf(outfile,")\n");
7021 ast_print(tree->left,outfile,indent+2);
7022 ast_print(tree->right,outfile,indent+2);
7024 /*------------------------------------------------------------------*/
7025 /*----------------------------*/
7026 /* comma operator */
7027 /*----------------------------*/
7029 fprintf(outfile,"COMMA(,) (%p) type (",tree);
7030 printTypeChain(tree->ftype,outfile);
7031 fprintf(outfile,")\n");
7032 ast_print(tree->left,outfile,indent+2);
7033 ast_print(tree->right,outfile,indent+2);
7035 /*------------------------------------------------------------------*/
7036 /*----------------------------*/
7038 /*----------------------------*/
7041 fprintf(outfile,"CALL (%p) type (",tree);
7042 printTypeChain(tree->ftype,outfile);
7043 fprintf(outfile,")\n");
7044 ast_print(tree->left,outfile,indent+2);
7045 ast_print(tree->right,outfile,indent+2);
7048 fprintf(outfile,"PARMS\n");
7049 ast_print(tree->left,outfile,indent+2);
7050 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
7051 ast_print(tree->right,outfile,indent+2);
7054 /*------------------------------------------------------------------*/
7055 /*----------------------------*/
7056 /* return statement */
7057 /*----------------------------*/
7059 fprintf(outfile,"RETURN (%p) type (",tree);
7061 printTypeChain(tree->right->ftype,outfile);
7063 fprintf(outfile,")\n");
7064 ast_print(tree->right,outfile,indent+2);
7066 /*------------------------------------------------------------------*/
7067 /*----------------------------*/
7068 /* label statement */
7069 /*----------------------------*/
7071 fprintf(outfile,"LABEL (%p)\n",tree);
7072 ast_print(tree->left,outfile,indent+2);
7073 ast_print(tree->right,outfile,indent);
7075 /*------------------------------------------------------------------*/
7076 /*----------------------------*/
7077 /* switch statement */
7078 /*----------------------------*/
7082 fprintf(outfile,"SWITCH (%p) ",tree);
7083 ast_print(tree->left,outfile,0);
7084 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
7085 INDENT(indent+2,outfile);
7086 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
7087 (int) floatFromVal(val),
7088 tree->values.switchVals.swNum,
7089 (int) floatFromVal(val));
7091 ast_print(tree->right,outfile,indent);
7094 /*------------------------------------------------------------------*/
7095 /*----------------------------*/
7097 /*----------------------------*/
7099 fprintf(outfile,"IF (%p) \n",tree);
7100 ast_print(tree->left,outfile,indent+2);
7101 if (tree->trueLabel) {
7102 INDENT(indent+2,outfile);
7103 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
7105 if (tree->falseLabel) {
7106 INDENT(indent+2,outfile);
7107 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
7109 ast_print(tree->right,outfile,indent+2);
7111 /*----------------------------*/
7112 /* goto Statement */
7113 /*----------------------------*/
7115 fprintf(outfile,"GOTO (%p) \n",tree);
7116 ast_print(tree->left,outfile,indent+2);
7117 fprintf(outfile,"\n");
7119 /*------------------------------------------------------------------*/
7120 /*----------------------------*/
7122 /*----------------------------*/
7124 fprintf(outfile,"FOR (%p) \n",tree);
7125 if (AST_FOR( tree, initExpr)) {
7126 INDENT(indent+2,outfile);
7127 fprintf(outfile,"INIT EXPR ");
7128 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
7130 if (AST_FOR( tree, condExpr)) {
7131 INDENT(indent+2,outfile);
7132 fprintf(outfile,"COND EXPR ");
7133 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
7135 if (AST_FOR( tree, loopExpr)) {
7136 INDENT(indent+2,outfile);
7137 fprintf(outfile,"LOOP EXPR ");
7138 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
7140 fprintf(outfile,"FOR LOOP BODY \n");
7141 ast_print(tree->left,outfile,indent+2);
7144 fprintf(outfile,"CRITICAL (%p) \n",tree);
7145 ast_print(tree->left,outfile,indent+2);
7153 ast_print(t,stdout,0);
7156 /*-----------------------------------------------------------------*/
7157 /* astErrors : returns non-zero if errors present in tree */
7158 /*-----------------------------------------------------------------*/
7159 int astErrors(ast *t)
7168 if (t->type == EX_VALUE
7169 && t->opval.val->sym
7170 && t->opval.val->sym->undefined)
7173 errors += astErrors(t->left);
7174 errors += astErrors(t->right);