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 /* don't allocate string if it is a sizeof argument */
2575 dtr = decorateType (tree->right, resultTypeProp);
2579 dtr = decorateType (tree->right, resultTypeProp);
2583 /* this is to take care of situations
2584 when the tree gets rewritten */
2585 if (dtl != tree->left)
2587 if (dtr != tree->right)
2589 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2593 /* depending on type of operator do */
2595 switch (tree->opval.op)
2597 /*------------------------------------------------------------------*/
2598 /*----------------------------*/
2600 /*----------------------------*/
2603 /* first check if this is a array or a pointer */
2604 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2606 werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
2607 goto errorTreeReturn;
2610 /* check if the type of the idx */
2611 if (!IS_INTEGRAL (RTYPE (tree)))
2613 werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
2614 goto errorTreeReturn;
2617 /* if the left is an rvalue then error */
2620 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
2621 goto errorTreeReturn;
2624 if (IS_LITERAL (RTYPE (tree)))
2626 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2627 int arraySize = DCL_ELEM (LTYPE (tree));
2628 if (arraySize && arrayIndex >= arraySize)
2630 werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2635 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2636 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2639 /*------------------------------------------------------------------*/
2640 /*----------------------------*/
2642 /*----------------------------*/
2644 /* if this is not a structure */
2645 if (!IS_STRUCT (LTYPE (tree)))
2647 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
2648 goto errorTreeReturn;
2650 TTYPE (tree) = structElemType (LTYPE (tree),
2651 (tree->right->type == EX_VALUE ?
2652 tree->right->opval.val : NULL));
2653 TETYPE (tree) = getSpec (TTYPE (tree));
2656 /*------------------------------------------------------------------*/
2657 /*----------------------------*/
2658 /* struct/union pointer */
2659 /*----------------------------*/
2661 /* if not pointer to a structure */
2662 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2664 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
2665 goto errorTreeReturn;
2668 if (!IS_STRUCT (LTYPE (tree)->next))
2670 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
2671 goto errorTreeReturn;
2674 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2675 (tree->right->type == EX_VALUE ?
2676 tree->right->opval.val : NULL));
2677 TETYPE (tree) = getSpec (TTYPE (tree));
2679 /* adjust the storage class */
2680 switch (DCL_TYPE(tree->left->ftype)) {
2682 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2685 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2688 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2691 SPEC_SCLS (TETYPE (tree)) = 0;
2694 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2697 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2700 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2703 SPEC_SCLS (TETYPE (tree)) = 0;
2710 /* This breaks with extern declarations, bitfields, and perhaps other */
2711 /* cases (gcse). Let's leave this optimization disabled for now and */
2712 /* ponder if there's a safe way to do this. -- EEP */
2714 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2715 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2717 /* If defined struct type at addr var
2718 then rewrite (&struct var)->member
2720 and define membertype at (addr+offsetof(struct var,member)) temp
2723 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2724 AST_SYMBOL(tree->right));
2726 sym = newSymbol(genSymName (0), 0);
2727 sym->type = TTYPE (tree);
2728 sym->etype = getSpec(sym->type);
2729 sym->lineDef = tree->lineno;
2732 SPEC_STAT (sym->etype) = 1;
2733 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2735 SPEC_ABSA(sym->etype) = 1;
2736 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2739 AST_VALUE (tree) = symbolVal(sym);
2742 tree->type = EX_VALUE;
2750 /*------------------------------------------------------------------*/
2751 /*----------------------------*/
2752 /* ++/-- operation */
2753 /*----------------------------*/
2757 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2758 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2759 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2760 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2769 /*------------------------------------------------------------------*/
2770 /*----------------------------*/
2772 /*----------------------------*/
2773 case '&': /* can be unary */
2774 /* if right is NULL then unary operation */
2775 if (tree->right) /* not an unary operation */
2778 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2780 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2781 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2782 printTypeChain (LTYPE (tree), stderr);
2783 fprintf (stderr, ",");
2784 printTypeChain (RTYPE (tree), stderr);
2785 fprintf (stderr, "\n");
2786 goto errorTreeReturn;
2789 /* if they are both literal */
2790 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2792 tree->type = EX_VALUE;
2793 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2794 valFromType (RETYPE (tree)), '&');
2796 tree->right = tree->left = NULL;
2797 TETYPE (tree) = tree->opval.val->etype;
2798 TTYPE (tree) = tree->opval.val->type;
2802 /* see if this is a GETHBIT operation if yes
2805 ast *otree = optimizeGetHbit (tree, resultType);
2808 return decorateType (otree, RESULT_TYPE_NONE);
2811 /* see if this is a GETABIT operation if yes
2814 ast *otree = optimizeGetAbit (tree, resultType);
2817 return decorateType (otree, RESULT_TYPE_NONE);
2820 /* see if this is a GETBYTE operation if yes
2823 ast *otree = optimizeGetByte (tree, resultType);
2826 return decorateType (otree, RESULT_TYPE_NONE);
2829 /* see if this is a GETWORD operation if yes
2832 ast *otree = optimizeGetWord (tree, resultType);
2835 return decorateType (otree, RESULT_TYPE_NONE);
2838 /* if left is a literal exchange left & right */
2839 if (IS_LITERAL (LTYPE (tree)))
2841 ast *tTree = tree->left;
2842 tree->left = tree->right;
2843 tree->right = tTree;
2846 /* if right is a literal and */
2847 /* we can find a 2nd literal in an and-tree then */
2848 /* rearrange the tree */
2849 if (IS_LITERAL (RTYPE (tree)))
2852 ast *litTree = searchLitOp (tree, &parent, "&");
2856 ast *tTree = litTree->left;
2857 litTree->left = tree->right;
2858 tree->right = tTree;
2859 /* both operands in litTree are literal now */
2860 decorateType (parent, resultType);
2864 LRVAL (tree) = RRVAL (tree) = 1;
2866 TTYPE (tree) = computeType (LTYPE (tree),
2870 TETYPE (tree) = getSpec (TTYPE (tree));
2875 /*------------------------------------------------------------------*/
2876 /*----------------------------*/
2878 /*----------------------------*/
2879 p = newLink (DECLARATOR);
2880 /* if bit field then error */
2881 if (IS_BITVAR (tree->left->etype))
2883 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
2884 goto errorTreeReturn;
2887 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2889 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
2890 goto errorTreeReturn;
2893 if (IS_FUNC (LTYPE (tree)))
2895 // this ought to be ignored
2896 return (tree->left);
2899 if (IS_LITERAL(LTYPE(tree)))
2901 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
2902 goto errorTreeReturn;
2907 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
2908 goto errorTreeReturn;
2911 DCL_TYPE (p) = POINTER;
2912 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2913 DCL_TYPE (p) = CPOINTER;
2914 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2915 DCL_TYPE (p) = FPOINTER;
2916 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2917 DCL_TYPE (p) = PPOINTER;
2918 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2919 DCL_TYPE (p) = IPOINTER;
2920 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2921 DCL_TYPE (p) = EEPPOINTER;
2922 else if (SPEC_OCLS(tree->left->etype))
2923 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2925 DCL_TYPE (p) = POINTER;
2927 if (IS_AST_SYM_VALUE (tree->left))
2929 AST_SYMBOL (tree->left)->addrtaken = 1;
2930 AST_SYMBOL (tree->left)->allocreq = 1;
2933 p->next = LTYPE (tree);
2935 TETYPE (tree) = getSpec (TTYPE (tree));
2940 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2941 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2943 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2944 AST_SYMBOL(tree->left->right));
2945 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2946 valueFromLit(element->offset));
2949 tree->type = EX_VALUE;
2950 tree->values.literalFromCast = 1;
2956 /*------------------------------------------------------------------*/
2957 /*----------------------------*/
2959 /*----------------------------*/
2961 /* if the rewrite succeeds then don't go any further */
2963 ast *wtree = optimizeRRCRLC (tree);
2965 return decorateType (wtree, RESULT_TYPE_NONE);
2967 wtree = optimizeSWAP (tree);
2969 return decorateType (wtree, RESULT_TYPE_NONE);
2972 /* if left is a literal exchange left & right */
2973 if (IS_LITERAL (LTYPE (tree)))
2975 ast *tTree = tree->left;
2976 tree->left = tree->right;
2977 tree->right = tTree;
2980 /* if right is a literal and */
2981 /* we can find a 2nd literal in an or-tree then */
2982 /* rearrange the tree */
2983 if (IS_LITERAL (RTYPE (tree)))
2986 ast *litTree = searchLitOp (tree, &parent, "|");
2990 ast *tTree = litTree->left;
2991 litTree->left = tree->right;
2992 tree->right = tTree;
2993 /* both operands in tTree are literal now */
2994 decorateType (parent, resultType);
2999 /*------------------------------------------------------------------*/
3000 /*----------------------------*/
3002 /*----------------------------*/
3004 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3006 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3007 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3008 printTypeChain (LTYPE (tree), stderr);
3009 fprintf (stderr, ",");
3010 printTypeChain (RTYPE (tree), stderr);
3011 fprintf (stderr, "\n");
3012 goto errorTreeReturn;
3015 /* if they are both literal then rewrite the tree */
3016 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3018 tree->type = EX_VALUE;
3019 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3020 valFromType (RETYPE (tree)),
3022 tree->right = tree->left = NULL;
3023 TETYPE (tree) = tree->opval.val->etype;
3024 TTYPE (tree) = tree->opval.val->type;
3028 /* if left is a literal exchange left & right */
3029 if (IS_LITERAL (LTYPE (tree)))
3031 ast *tTree = tree->left;
3032 tree->left = tree->right;
3033 tree->right = tTree;
3036 /* if right is a literal and */
3037 /* we can find a 2nd literal in a xor-tree then */
3038 /* rearrange the tree */
3039 if (IS_LITERAL (RTYPE (tree)) &&
3040 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3043 ast *litTree = searchLitOp (tree, &parent, "^");
3047 ast *tTree = litTree->left;
3048 litTree->left = tree->right;
3049 tree->right = tTree;
3050 /* both operands in litTree are literal now */
3051 decorateType (parent, resultType);
3055 LRVAL (tree) = RRVAL (tree) = 1;
3057 TTYPE (tree) = computeType (LTYPE (tree),
3061 TETYPE (tree) = getSpec (TTYPE (tree));
3065 /*------------------------------------------------------------------*/
3066 /*----------------------------*/
3068 /*----------------------------*/
3070 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3072 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
3073 goto errorTreeReturn;
3075 /* if they are both literal then */
3076 /* rewrite the tree */
3077 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3079 tree->type = EX_VALUE;
3080 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
3081 valFromType (RETYPE (tree)));
3082 tree->right = tree->left = NULL;
3083 TETYPE (tree) = getSpec (TTYPE (tree) =
3084 tree->opval.val->type);
3088 LRVAL (tree) = RRVAL (tree) = 1;
3090 TETYPE (tree) = getSpec (TTYPE (tree) =
3091 computeType (LTYPE (tree),
3096 /* if right is a literal and */
3097 /* left is also a division by a literal then */
3098 /* rearrange the tree */
3099 if (IS_LITERAL (RTYPE (tree))
3100 /* avoid infinite loop */
3101 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
3104 ast *litTree = searchLitOp (tree, &parent, "/");
3107 if (IS_LITERAL (RTYPE (litTree)))
3111 litTree->right = newNode ('*',
3113 copyAst (tree->right));
3114 litTree->right->lineno = tree->lineno;
3116 tree->right->opval.val = constVal ("1");
3117 decorateType (parent, resultType);
3121 /* litTree->left is literal: no gcse possible.
3122 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3123 this would cause an infinit loop. */
3124 parent->decorated = 1;
3125 decorateType (litTree, resultType);
3132 /*------------------------------------------------------------------*/
3133 /*----------------------------*/
3135 /*----------------------------*/
3137 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3139 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3140 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3141 printTypeChain (LTYPE (tree), stderr);
3142 fprintf (stderr, ",");
3143 printTypeChain (RTYPE (tree), stderr);
3144 fprintf (stderr, "\n");
3145 goto errorTreeReturn;
3147 /* if they are both literal then */
3148 /* rewrite the tree */
3149 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3151 tree->type = EX_VALUE;
3152 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3153 valFromType (RETYPE (tree)));
3154 tree->right = tree->left = NULL;
3155 TETYPE (tree) = getSpec (TTYPE (tree) =
3156 tree->opval.val->type);
3159 LRVAL (tree) = RRVAL (tree) = 1;
3160 TETYPE (tree) = getSpec (TTYPE (tree) =
3161 computeType (LTYPE (tree),
3167 /*------------------------------------------------------------------*/
3168 /*----------------------------*/
3169 /* address dereference */
3170 /*----------------------------*/
3171 case '*': /* can be unary : if right is null then unary operation */
3174 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3176 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
3177 goto errorTreeReturn;
3182 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
3183 goto errorTreeReturn;
3185 if (IS_ADDRESS_OF_OP(tree->left))
3187 /* replace *&obj with obj */
3188 return tree->left->left;
3190 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3191 TETYPE (tree) = getSpec (TTYPE (tree));
3192 /* adjust the storage class */
3193 switch (DCL_TYPE(tree->left->ftype)) {
3195 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3198 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3201 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3204 SPEC_SCLS (TETYPE (tree)) = 0;
3207 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3210 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3213 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3216 SPEC_SCLS (TETYPE (tree)) = 0;
3225 /*------------------------------------------------------------------*/
3226 /*----------------------------*/
3227 /* multiplication */
3228 /*----------------------------*/
3229 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3231 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
3232 goto errorTreeReturn;
3235 /* if they are both literal then */
3236 /* rewrite the tree */
3237 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3239 tree->type = EX_VALUE;
3240 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3241 valFromType (RETYPE (tree)));
3242 tree->right = tree->left = NULL;
3243 TETYPE (tree) = getSpec (TTYPE (tree) =
3244 tree->opval.val->type);
3248 /* if left is a literal exchange left & right */
3249 if (IS_LITERAL (LTYPE (tree)))
3251 ast *tTree = tree->left;
3252 tree->left = tree->right;
3253 tree->right = tTree;
3256 /* if right is a literal and */
3257 /* we can find a 2nd literal in a mul-tree then */
3258 /* rearrange the tree */
3259 if (IS_LITERAL (RTYPE (tree)))
3262 ast *litTree = searchLitOp (tree, &parent, "*");
3266 ast *tTree = litTree->left;
3267 litTree->left = tree->right;
3268 tree->right = tTree;
3269 /* both operands in litTree are literal now */
3270 decorateType (parent, resultType);
3274 LRVAL (tree) = RRVAL (tree) = 1;
3275 tree->left = addCast (tree->left, resultType, FALSE);
3276 tree->right = addCast (tree->right, resultType, FALSE);
3277 TETYPE (tree) = getSpec (TTYPE (tree) =
3278 computeType (LTYPE (tree),
3285 /*------------------------------------------------------------------*/
3286 /*----------------------------*/
3287 /* unary '+' operator */
3288 /*----------------------------*/
3293 if (!IS_ARITHMETIC (LTYPE (tree)))
3295 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
3296 goto errorTreeReturn;
3299 /* if left is a literal then do it */
3300 if (IS_LITERAL (LTYPE (tree)))
3302 tree->type = EX_VALUE;
3303 tree->opval.val = valFromType (LETYPE (tree));
3305 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3309 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3313 /*------------------------------------------------------------------*/
3314 /*----------------------------*/
3316 /*----------------------------*/
3318 /* this is not a unary operation */
3319 /* if both pointers then problem */
3320 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3321 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3323 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
3324 goto errorTreeReturn;
3327 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3328 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3330 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3331 goto errorTreeReturn;
3334 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3335 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3337 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3338 goto errorTreeReturn;
3340 /* if they are both literal then */
3341 /* rewrite the tree */
3342 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3344 tree->type = EX_VALUE;
3345 tree->left = addCast (tree->left, resultType, TRUE);
3346 tree->right = addCast (tree->right, resultType, TRUE);
3347 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3348 valFromType (RETYPE (tree)));
3349 tree->right = tree->left = NULL;
3350 TETYPE (tree) = getSpec (TTYPE (tree) =
3351 tree->opval.val->type);
3355 /* if the right is a pointer or left is a literal
3356 xchange left & right */
3357 if (IS_ARRAY (RTYPE (tree)) ||
3358 IS_PTR (RTYPE (tree)) ||
3359 IS_LITERAL (LTYPE (tree)))
3361 ast *tTree = tree->left;
3362 tree->left = tree->right;
3363 tree->right = tTree;
3366 /* if right is a literal and */
3367 /* left is also an addition/subtraction with a literal then */
3368 /* rearrange the tree */
3369 if (IS_LITERAL (RTYPE (tree)))
3371 ast *litTree, *parent;
3372 litTree = searchLitOp (tree, &parent, "+-");
3375 if (litTree->opval.op == '+')
3379 ast *tTree = litTree->left;
3380 litTree->left = tree->right;
3381 tree->right = tree->left;
3384 else if (litTree->opval.op == '-')
3386 if (IS_LITERAL (RTYPE (litTree)))
3390 ast *tTree = litTree->left;
3391 litTree->left = tree->right;
3392 tree->right = tTree;
3398 ast *tTree = litTree->right;
3399 litTree->right = tree->right;
3400 tree->right = tTree;
3401 litTree->opval.op = '+';
3402 tree->opval.op = '-';
3405 decorateType (parent, resultType);
3409 LRVAL (tree) = RRVAL (tree) = 1;
3410 /* if the left is a pointer */
3411 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3412 TETYPE (tree) = getSpec (TTYPE (tree) =
3416 tree->left = addCast (tree->left, resultType, TRUE);
3417 tree->right = addCast (tree->right, resultType, TRUE);
3418 TETYPE (tree) = getSpec (TTYPE (tree) =
3419 computeType (LTYPE (tree),
3427 /*------------------------------------------------------------------*/
3428 /*----------------------------*/
3430 /*----------------------------*/
3431 case '-': /* can be unary */
3432 /* if right is null then unary */
3436 if (!IS_ARITHMETIC (LTYPE (tree)))
3438 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3439 goto errorTreeReturn;
3442 /* if left is a literal then do it */
3443 if (IS_LITERAL (LTYPE (tree)))
3445 tree->type = EX_VALUE;
3446 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3448 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3451 tree->left = addCast (tree->left, resultType, TRUE);
3452 TETYPE (tree) = getSpec (TTYPE (tree) =
3453 computeType (LTYPE (tree),
3461 /*------------------------------------------------------------------*/
3462 /*----------------------------*/
3464 /*----------------------------*/
3466 if (!(IS_PTR (LTYPE (tree)) ||
3467 IS_ARRAY (LTYPE (tree)) ||
3468 IS_ARITHMETIC (LTYPE (tree))))
3470 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3471 goto errorTreeReturn;
3474 if (!(IS_PTR (RTYPE (tree)) ||
3475 IS_ARRAY (RTYPE (tree)) ||
3476 IS_ARITHMETIC (RTYPE (tree))))
3478 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3479 goto errorTreeReturn;
3482 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3483 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3484 IS_INTEGRAL (RTYPE (tree))))
3486 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3487 goto errorTreeReturn;
3490 /* if they are both literal then */
3491 /* rewrite the tree */
3492 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3494 tree->type = EX_VALUE;
3495 tree->left = addCast (tree->left, resultType, TRUE);
3496 tree->right = addCast (tree->right, resultType, TRUE);
3497 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3498 valFromType (RETYPE (tree)));
3499 tree->right = tree->left = NULL;
3500 TETYPE (tree) = getSpec (TTYPE (tree) =
3501 tree->opval.val->type);
3505 /* if the left & right are equal then zero */
3506 if (isAstEqual (tree->left, tree->right))
3508 tree->type = EX_VALUE;
3509 tree->left = tree->right = NULL;
3510 tree->opval.val = constVal ("0");
3511 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3515 /* if both of them are pointers or arrays then */
3516 /* the result is going to be an integer */
3517 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3518 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3519 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3521 /* if only the left is a pointer */
3522 /* then result is a pointer */
3523 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3524 TETYPE (tree) = getSpec (TTYPE (tree) =
3528 tree->left = addCast (tree->left, resultType, TRUE);
3529 tree->right = addCast (tree->right, resultType, TRUE);
3531 TETYPE (tree) = getSpec (TTYPE (tree) =
3532 computeType (LTYPE (tree),
3538 LRVAL (tree) = RRVAL (tree) = 1;
3540 /* if right is a literal and */
3541 /* left is also an addition/subtraction with a literal then */
3542 /* rearrange the tree */
3543 if (IS_LITERAL (RTYPE (tree))
3544 /* avoid infinite loop */
3545 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
3547 ast *litTree, *litParent;
3548 litTree = searchLitOp (tree, &litParent, "+-");
3551 if (litTree->opval.op == '+')
3555 ast *tTree = litTree->left;
3556 litTree->left = litTree->right;
3557 litTree->right = tree->right;
3558 tree->right = tTree;
3559 tree->opval.op = '+';
3560 litTree->opval.op = '-';
3562 else if (litTree->opval.op == '-')
3564 if (IS_LITERAL (RTYPE (litTree)))
3568 ast *tTree = litTree->left;
3569 litTree->left = tree->right;
3570 tree->right = litParent->left;
3571 litParent->left = tTree;
3572 litTree->opval.op = '+';
3574 tree->decorated = 0;
3575 decorateType (tree, resultType);
3581 ast *tTree = litTree->right;
3582 litTree->right = tree->right;
3583 tree->right = tTree;
3586 decorateType (litParent, resultType);
3591 /*------------------------------------------------------------------*/
3592 /*----------------------------*/
3594 /*----------------------------*/
3596 /* can be only integral type */
3597 if (!IS_INTEGRAL (LTYPE (tree)))
3599 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3600 goto errorTreeReturn;
3603 /* if left is a literal then do it */
3604 if (IS_LITERAL (LTYPE (tree)))
3606 tree->type = EX_VALUE;
3607 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3609 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3610 return addCast (tree, resultType, TRUE);
3613 if (resultType == RESULT_TYPE_BIT &&
3614 IS_UNSIGNED (tree->left->etype) &&
3615 getSize (tree->left->etype) < INTSIZE)
3617 /* promotion rules are responsible for this strange result:
3618 bit -> int -> ~int -> bit
3619 uchar -> int -> ~int -> bit
3621 werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
3623 /* optimize bit-result, even if we optimize a buggy source */
3624 tree->type = EX_VALUE;
3625 tree->opval.val = constVal ("1");
3628 tree->left = addCast (tree->left, resultType, TRUE);
3630 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3633 /*------------------------------------------------------------------*/
3634 /*----------------------------*/
3636 /*----------------------------*/
3638 /* can be pointer */
3639 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3640 !IS_PTR (LTYPE (tree)) &&
3641 !IS_ARRAY (LTYPE (tree)))
3643 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3644 goto errorTreeReturn;
3647 /* if left is another '!' */
3648 if (tree->left->opval.op == '!')
3650 /* remove double '!!X' by 'X ? 1 : 0' */
3651 tree->opval.op = '?';
3652 tree->left = tree->left->left;
3653 tree->right = newNode (':',
3654 newAst_VALUE (constVal ("1")),
3655 newAst_VALUE (constVal ("0")));
3656 tree->right->lineno = tree->lineno;
3657 tree->decorated = 0;
3658 return decorateType (tree, resultType);
3661 /* if left is a literal then do it */
3662 if (IS_LITERAL (LTYPE (tree)))
3664 tree->type = EX_VALUE;
3665 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3667 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3671 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3674 /*------------------------------------------------------------------*/
3675 /*----------------------------*/
3677 /*----------------------------*/
3681 TTYPE (tree) = LTYPE (tree);
3682 TETYPE (tree) = LETYPE (tree);
3687 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3691 TTYPE (tree) = TETYPE (tree) = newCharLink();
3695 TTYPE (tree) = TETYPE (tree) = newIntLink();
3700 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3702 werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
3703 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3704 printTypeChain (LTYPE (tree), stderr);
3705 fprintf (stderr, ",");
3706 printTypeChain (RTYPE (tree), stderr);
3707 fprintf (stderr, "\n");
3708 goto errorTreeReturn;
3711 /* make smaller type only if it's a LEFT_OP */
3712 if (tree->opval.op == LEFT_OP)
3713 tree->left = addCast (tree->left, resultType, TRUE);
3715 /* if they are both literal then */
3716 /* rewrite the tree */
3717 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3719 tree->type = EX_VALUE;
3720 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3721 valFromType (RETYPE (tree)),
3722 (tree->opval.op == LEFT_OP ? 1 : 0));
3723 tree->right = tree->left = NULL;
3724 TETYPE (tree) = getSpec (TTYPE (tree) =
3725 tree->opval.val->type);
3729 /* see if this is a GETBYTE operation if yes
3732 ast *otree = optimizeGetByte (tree, resultType);
3735 return decorateType (otree, RESULT_TYPE_NONE);
3738 /* see if this is a GETWORD operation if yes
3741 ast *otree = optimizeGetWord (tree, resultType);
3744 return decorateType (otree, RESULT_TYPE_NONE);
3747 LRVAL (tree) = RRVAL (tree) = 1;
3748 if (tree->opval.op == LEFT_OP)
3750 TETYPE (tree) = getSpec (TTYPE (tree) =
3751 computeType (LTYPE (tree),
3758 /* no promotion necessary */
3759 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3760 if (IS_LITERAL (TTYPE (tree)))
3761 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3764 /* if only the right side is a literal & we are
3765 shifting more than size of the left operand then zero */
3766 if (IS_LITERAL (RTYPE (tree)) &&
3767 ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
3768 (getSize (TETYPE (tree)) * 8))
3770 if (tree->opval.op==LEFT_OP ||
3771 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3773 werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
3774 (tree->opval.op == LEFT_OP ? "left" : "right"));
3775 tree->type = EX_VALUE;
3776 tree->left = tree->right = NULL;
3777 tree->opval.val = constVal ("0");
3778 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3785 /*------------------------------------------------------------------*/
3786 /*----------------------------*/
3788 /*----------------------------*/
3789 case CAST: /* change the type */
3790 /* cannot cast to an aggregate type */
3791 if (IS_AGGREGATE (LTYPE (tree)))
3793 werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
3794 goto errorTreeReturn;
3797 /* make sure the type is complete and sane */
3798 changePointer(LTYPE(tree));
3799 checkTypeSanity(LETYPE(tree), "(cast)");
3801 /* if 'from' and 'to' are the same remove the superfluous cast, */
3802 /* this helps other optimizations */
3803 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3808 /* If code memory is read only, then pointers to code memory */
3809 /* implicitly point to constants -- make this explicit */
3811 sym_link *t = LTYPE(tree);
3812 while (t && t->next)
3814 if (IS_CODEPTR(t) && port->mem.code_ro)
3816 if (IS_SPEC(t->next))
3817 SPEC_CONST (t->next) = 1;
3819 DCL_PTR_CONST (t->next) = 1;
3826 /* if the right is a literal replace the tree */
3827 if (IS_LITERAL (RETYPE (tree))) {
3828 if (!IS_PTR (LTYPE (tree))) {
3829 tree->type = EX_VALUE;
3831 valCastLiteral (LTYPE (tree),
3832 floatFromVal (valFromType (RETYPE (tree))));
3835 TTYPE (tree) = tree->opval.val->type;
3836 tree->values.literalFromCast = 1;
3837 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3838 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3839 sym_link *rest = LTYPE(tree)->next;
3840 werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
3841 TTYPE(tree) = newLink(DECLARATOR);
3842 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3843 TTYPE(tree)->next = rest;
3844 tree->left->opval.lnk = TTYPE(tree);
3847 TTYPE (tree) = LTYPE (tree);
3851 TTYPE (tree) = LTYPE (tree);
3855 #if 0 // this is already checked, now this could be explicit
3856 /* if pointer to struct then check names */
3857 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3858 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3859 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3861 werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3862 SPEC_STRUCT(LETYPE(tree))->tag);
3865 if (IS_ADDRESS_OF_OP(tree->right)
3866 && IS_AST_SYM_VALUE (tree->right->left)
3867 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3869 symbol * sym = AST_SYMBOL (tree->right->left);
3870 unsigned int gptype = 0;
3871 unsigned int addr = SPEC_ADDR (sym->etype);
3873 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
3874 || TARGET_IS_PIC16) )
3876 switch (SPEC_SCLS (sym->etype))
3879 gptype = GPTYPE_CODE;
3882 gptype = GPTYPE_FAR;
3886 gptype = GPTYPE_NEAR;
3889 gptype = GPTYPE_XSTACK;
3894 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3895 gptype = GPTYPE_NEAR;
3897 addr |= gptype << (8*(GPTRSIZE - 1));
3900 tree->type = EX_VALUE;
3902 valCastLiteral (LTYPE (tree), addr);
3903 TTYPE (tree) = tree->opval.val->type;
3904 TETYPE (tree) = getSpec (TTYPE (tree));
3907 tree->values.literalFromCast = 1;
3911 /* handle offsetof macro: */
3912 /* #define offsetof(TYPE, MEMBER) \ */
3913 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3914 if (IS_ADDRESS_OF_OP(tree->right)
3915 && IS_AST_OP (tree->right->left)
3916 && tree->right->left->opval.op == PTR_OP
3917 && IS_AST_OP (tree->right->left->left)
3918 && tree->right->left->left->opval.op == CAST
3919 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3921 symbol *element = getStructElement (
3922 SPEC_STRUCT (LETYPE(tree->right->left)),
3923 AST_SYMBOL(tree->right->left->right)
3927 tree->type = EX_VALUE;
3928 tree->opval.val = valCastLiteral (
3931 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3934 TTYPE (tree) = tree->opval.val->type;
3935 TETYPE (tree) = getSpec (TTYPE (tree));
3942 /* if the right is a literal replace the tree */
3943 if (IS_LITERAL (RETYPE (tree))) {
3945 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3946 /* rewrite (type *)litaddr
3948 and define type at litaddr temp
3949 (but only if type's storage class is not generic)
3951 ast *newTree = newNode ('&', NULL, NULL);
3954 TTYPE (newTree) = LTYPE (tree);
3955 TETYPE (newTree) = getSpec(LTYPE (tree));
3957 /* define a global symbol at the casted address*/
3958 sym = newSymbol(genSymName (0), 0);
3959 sym->type = LTYPE (tree)->next;
3961 sym->type = newLink (V_VOID);
3962 sym->etype = getSpec(sym->type);
3963 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3964 sym->lineDef = tree->lineno;
3967 SPEC_STAT (sym->etype) = 1;
3968 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3969 SPEC_ABSA(sym->etype) = 1;
3970 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3973 newTree->left = newAst_VALUE(symbolVal(sym));
3974 newTree->left->lineno = tree->lineno;
3975 LTYPE (newTree) = sym->type;
3976 LETYPE (newTree) = sym->etype;
3977 LLVAL (newTree) = 1;
3978 LRVAL (newTree) = 0;
3979 TLVAL (newTree) = 1;
3983 if (!IS_PTR (LTYPE (tree))) {
3984 tree->type = EX_VALUE;
3986 valCastLiteral (LTYPE (tree),
3987 floatFromVal (valFromType (RTYPE (tree))));
3988 TTYPE (tree) = tree->opval.val->type;
3991 tree->values.literalFromCast = 1;
3992 TETYPE (tree) = getSpec (TTYPE (tree));
3996 TTYPE (tree) = LTYPE (tree);
4000 TETYPE (tree) = getSpec (TTYPE (tree));
4004 /*------------------------------------------------------------------*/
4005 /*----------------------------*/
4006 /* logical &&, || */
4007 /*----------------------------*/
4010 /* each must be arithmetic type or be a pointer */
4011 if (!IS_PTR (LTYPE (tree)) &&
4012 !IS_ARRAY (LTYPE (tree)) &&
4013 !IS_INTEGRAL (LTYPE (tree)))
4015 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4016 goto errorTreeReturn;
4019 if (!IS_PTR (RTYPE (tree)) &&
4020 !IS_ARRAY (RTYPE (tree)) &&
4021 !IS_INTEGRAL (RTYPE (tree)))
4023 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4024 goto errorTreeReturn;
4026 /* if they are both literal then */
4027 /* rewrite the tree */
4028 if (IS_LITERAL (RTYPE (tree)) &&
4029 IS_LITERAL (LTYPE (tree)))
4031 tree->type = EX_VALUE;
4032 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4033 valFromType (RTYPE (tree)),
4035 tree->right = tree->left = NULL;
4036 TETYPE (tree) = getSpec (TTYPE (tree) =
4037 tree->opval.val->type);
4040 LRVAL (tree) = RRVAL (tree) = 1;
4041 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4044 /*------------------------------------------------------------------*/
4045 /*----------------------------*/
4046 /* comparison operators */
4047 /*----------------------------*/
4055 ast *lt = optimizeCompare (tree);
4061 /* if they are pointers they must be castable */
4062 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4064 if (tree->opval.op==EQ_OP &&
4065 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4066 // we cannot cast a gptr to a !gptr: switch the leaves
4067 struct ast *s=tree->left;
4068 tree->left=tree->right;
4071 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4073 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4074 fprintf (stderr, "comparing type ");
4075 printTypeChain (LTYPE (tree), stderr);
4076 fprintf (stderr, "to type ");
4077 printTypeChain (RTYPE (tree), stderr);
4078 fprintf (stderr, "\n");
4079 goto errorTreeReturn;
4082 /* else they should be promotable to one another */
4085 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4086 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4088 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4090 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4091 fprintf (stderr, "comparing type ");
4092 printTypeChain (LTYPE (tree), stderr);
4093 fprintf (stderr, "to type ");
4094 printTypeChain (RTYPE (tree), stderr);
4095 fprintf (stderr, "\n");
4096 goto errorTreeReturn;
4101 CCR_RESULT ccr_result = CCR_OK;
4103 /* if left is integral and right is literal
4104 then check constant range */
4105 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4106 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4107 tree->opval.op, FALSE);
4108 if (ccr_result == CCR_OK &&
4109 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4110 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4111 tree->opval.op, TRUE);
4114 case CCR_ALWAYS_TRUE:
4115 case CCR_ALWAYS_FALSE:
4116 if (!options.lessPedantic)
4117 werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
4118 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4119 return decorateType (newAst_VALUE (constVal (
4120 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4128 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4129 if (tree->opval.op == '>' &&
4130 SPEC_USIGN(LETYPE(tree)) &&
4131 IS_LITERAL(RTYPE(tree)) &&
4132 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
4134 if (resultType == RESULT_TYPE_IFX)
4136 /* the parent is an ifx: */
4137 /* if (unsigned value) */
4141 /* (unsigned value) ? 1 : 0 */
4142 tree->opval.op = '?';
4143 tree->right = newNode (':',
4144 newAst_VALUE (constVal ("1")),
4145 tree->right); /* val 0 */
4146 tree->right->lineno = tree->lineno;
4147 tree->right->left->lineno = tree->lineno;
4148 tree->decorated = 0;
4149 return decorateType (tree, resultType);
4152 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4153 if (IS_LITERAL(RTYPE(tree)) &&
4154 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4155 tree->opval.op == EQ_OP &&
4156 resultType == RESULT_TYPE_IFX)
4158 tree->opval.op = '!';
4160 tree->decorated = 0;
4161 return decorateType (tree, resultType);
4164 /* if they are both literal then */
4165 /* rewrite the tree */
4166 if (IS_LITERAL (RTYPE (tree)) &&
4167 IS_LITERAL (LTYPE (tree)))
4169 tree->type = EX_VALUE;
4170 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4171 valFromType (RETYPE (tree)),
4173 tree->right = tree->left = NULL;
4174 TETYPE (tree) = getSpec (TTYPE (tree) =
4175 tree->opval.val->type);
4179 /* if one is 'signed char ' and the other one is 'unsigned char' */
4180 /* it's necessary to promote to int */
4181 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4182 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4184 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4185 if it's possible to use a 'signed char' */
4187 /* is left a 'unsigned char'? */
4188 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4189 /* the value range of a 'unsigned char' is 0...255;
4190 if the actual value is < 128 it can be changed to signed */
4191 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
4193 /* now we've got 2 'signed char'! */
4194 SPEC_USIGN (RETYPE (tree)) = 0;
4196 /* same test for the left operand: */
4197 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4198 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4200 SPEC_USIGN (LETYPE (tree)) = 0;
4204 werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
4205 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4206 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4210 LRVAL (tree) = RRVAL (tree) = 1;
4211 TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4213 /* condition transformations */
4215 unsigned transformedOp = 0;
4217 switch (tree->opval.op)
4219 case '<': /* transform (a < b) to !(a >= b) */
4221 transformedOp = GE_OP;
4223 case '>': /* transform (a > b) to !(a <= b) */
4225 transformedOp = LE_OP;
4227 case LE_OP: /* transform (a <= b) to !(a > b) */
4229 transformedOp = '>';
4231 case GE_OP: /* transform (a >= b) to !(a < b) */
4233 transformedOp = '<';
4235 case NE_OP: /* transform (a != b) to !(a == b) */
4237 transformedOp = EQ_OP;
4239 case EQ_OP: /* transform (a == b) to !(a != b) */
4241 transformedOp = NE_OP;
4248 tree->opval.op = transformedOp;
4249 tree->decorated = 0;
4250 tree = newNode ('!', tree, NULL);
4251 tree->lineno = tree->left->lineno;
4252 return decorateType (tree, resultType);
4258 /*------------------------------------------------------------------*/
4259 /*----------------------------*/
4261 /*----------------------------*/
4262 case SIZEOF: /* evaluate wihout code generation */
4263 /* change the type to a integer */
4265 int size = getSize (tree->right->ftype);
4267 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4268 if (!size && !IS_VOID(tree->right->ftype))
4269 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4271 tree->type = EX_VALUE;
4272 tree->opval.val = constVal (buffer);
4273 tree->right = tree->left = NULL;
4274 TETYPE (tree) = getSpec (TTYPE (tree) =
4275 tree->opval.val->type);
4279 /*------------------------------------------------------------------*/
4280 /*----------------------------*/
4282 /*----------------------------*/
4284 /* return typeof enum value */
4285 tree->type = EX_VALUE;
4288 if (IS_SPEC(tree->right->ftype)) {
4289 switch (SPEC_NOUN(tree->right->ftype)) {
4291 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4292 else typeofv = TYPEOF_INT;
4295 typeofv = TYPEOF_FLOAT;
4298 typeofv = TYPEOF_FIXED16X16;
4301 typeofv = TYPEOF_CHAR;
4304 typeofv = TYPEOF_VOID;
4307 typeofv = TYPEOF_STRUCT;
4310 typeofv = TYPEOF_BITFIELD;
4313 typeofv = TYPEOF_BIT;
4316 typeofv = TYPEOF_SBIT;
4322 switch (DCL_TYPE(tree->right->ftype)) {
4324 typeofv = TYPEOF_POINTER;
4327 typeofv = TYPEOF_FPOINTER;
4330 typeofv = TYPEOF_CPOINTER;
4333 typeofv = TYPEOF_GPOINTER;
4336 typeofv = TYPEOF_PPOINTER;
4339 typeofv = TYPEOF_IPOINTER;
4342 typeofv = TYPEOF_ARRAY;
4345 typeofv = TYPEOF_FUNCTION;
4351 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4352 tree->opval.val = constVal (buffer);
4353 tree->right = tree->left = NULL;
4354 TETYPE (tree) = getSpec (TTYPE (tree) =
4355 tree->opval.val->type);
4358 /*------------------------------------------------------------------*/
4359 /*----------------------------*/
4360 /* conditional operator '?' */
4361 /*----------------------------*/
4363 /* the type is value of the colon operator (on the right) */
4364 assert (IS_COLON_OP (tree->right));
4365 /* if already known then replace the tree : optimizer will do it
4366 but faster to do it here */
4367 if (IS_LITERAL (LTYPE (tree)))
4369 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4370 return decorateType (tree->right->left, resultTypeProp);
4372 return decorateType (tree->right->right, resultTypeProp);
4376 tree->right = decorateType (tree->right, resultTypeProp);
4377 TTYPE (tree) = RTYPE (tree);
4378 TETYPE (tree) = getSpec (TTYPE (tree));
4383 /* if they don't match we have a problem */
4384 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4385 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4387 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
4388 goto errorTreeReturn;
4391 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4392 resultType, tree->opval.op);
4393 TETYPE (tree) = getSpec (TTYPE (tree));
4397 #if 0 // assignment operators are converted by the parser
4398 /*------------------------------------------------------------------*/
4399 /*----------------------------*/
4400 /* assignment operators */
4401 /*----------------------------*/
4404 /* for these it must be both must be integral */
4405 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4406 !IS_ARITHMETIC (RTYPE (tree)))
4408 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4409 goto errorTreeReturn;
4412 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4414 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4415 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4419 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4420 goto errorTreeReturn;
4431 /* for these it must be both must be integral */
4432 if (!IS_INTEGRAL (LTYPE (tree)) ||
4433 !IS_INTEGRAL (RTYPE (tree)))
4435 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4436 goto errorTreeReturn;
4439 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4441 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4442 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4446 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4447 goto errorTreeReturn;
4453 /*------------------------------------------------------------------*/
4454 /*----------------------------*/
4456 /*----------------------------*/
4458 if (!(IS_PTR (LTYPE (tree)) ||
4459 IS_ARITHMETIC (LTYPE (tree))))
4461 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4462 goto errorTreeReturn;
4465 if (!(IS_PTR (RTYPE (tree)) ||
4466 IS_ARITHMETIC (RTYPE (tree))))
4468 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4469 goto errorTreeReturn;
4472 TETYPE (tree) = getSpec (TTYPE (tree) =
4473 computeType (LTYPE (tree),
4478 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4479 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
4483 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
4484 goto errorTreeReturn;
4490 /*------------------------------------------------------------------*/
4491 /*----------------------------*/
4493 /*----------------------------*/
4495 /* this is not a unary operation */
4496 /* if both pointers then problem */
4497 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4499 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
4500 goto errorTreeReturn;
4503 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4505 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4506 goto errorTreeReturn;
4509 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4511 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4512 goto errorTreeReturn;
4515 TETYPE (tree) = getSpec (TTYPE (tree) =
4516 computeType (LTYPE (tree),
4521 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4522 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
4526 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
4527 goto errorTreeReturn;
4530 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4531 tree->opval.op = '=';
4536 /*------------------------------------------------------------------*/
4537 /*----------------------------*/
4538 /* straight assignemnt */
4539 /*----------------------------*/
4541 /* cannot be an aggregate */
4542 if (IS_AGGREGATE (LTYPE (tree)))
4544 werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
4545 goto errorTreeReturn;
4548 /* they should either match or be castable */
4549 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4551 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
4552 printFromToType(RTYPE(tree),LTYPE(tree));
4555 /* if the left side of the tree is of type void
4556 then report error */
4557 if (IS_VOID (LTYPE (tree)))
4559 werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
4560 printFromToType(RTYPE(tree), LTYPE(tree));
4563 TETYPE (tree) = getSpec (TTYPE (tree) =
4567 if (!tree->initMode ) {
4568 if (IS_CONSTANT(LTYPE(tree)))
4569 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
4573 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
4574 goto errorTreeReturn;
4579 /*------------------------------------------------------------------*/
4580 /*----------------------------*/
4581 /* comma operator */
4582 /*----------------------------*/
4584 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4587 /*------------------------------------------------------------------*/
4588 /*----------------------------*/
4590 /*----------------------------*/
4593 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4594 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4596 if (tree->left->opval.op == '*' && !tree->left->right)
4597 tree->left = tree->left->left;
4600 /* require a function or pointer to function */
4601 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4603 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4604 goto errorTreeReturn;
4607 /* if there are parms, make sure that
4608 parms are decorate / process / reverse only once */
4610 !tree->right->decorated)
4615 if (IS_FUNCPTR (LTYPE (tree)))
4617 functype = LTYPE (tree)->next;
4618 processFuncPtrArgs (functype);
4621 functype = LTYPE (tree);
4623 if (processParms (tree->left, FUNC_ARGS(functype),
4624 &tree->right, &parmNumber, TRUE))
4626 goto errorTreeReturn;
4629 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4630 !IFFUNC_ISBUILTIN(functype))
4632 reverseParms (tree->right);
4635 TTYPE (tree) = functype->next;
4636 TETYPE (tree) = getSpec (TTYPE (tree));
4640 /*------------------------------------------------------------------*/
4641 /*----------------------------*/
4642 /* return statement */
4643 /*----------------------------*/
4648 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4650 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4651 printFromToType (RTYPE(tree), currFunc->type->next);
4652 goto errorTreeReturn;
4655 if (IS_VOID (currFunc->type->next)
4657 !IS_VOID (RTYPE (tree)))
4659 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4660 goto errorTreeReturn;
4663 /* if there is going to be a casting required then add it */
4664 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4667 decorateType (newNode (CAST,
4668 newAst_LINK (copyLinkChain (currFunc->type->next)),
4678 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4680 werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
4681 goto errorTreeReturn;
4684 TTYPE (tree) = TETYPE (tree) = NULL;
4687 /*------------------------------------------------------------------*/
4688 /*----------------------------*/
4689 /* switch statement */
4690 /*----------------------------*/
4692 /* the switch value must be an integer */
4693 if (!IS_INTEGRAL (LTYPE (tree)))
4695 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4696 goto errorTreeReturn;
4699 TTYPE (tree) = TETYPE (tree) = NULL;
4702 /*------------------------------------------------------------------*/
4703 /*----------------------------*/
4705 /*----------------------------*/
4707 tree->left = backPatchLabels (tree->left,
4710 TTYPE (tree) = TETYPE (tree) = NULL;
4713 /*------------------------------------------------------------------*/
4714 /*----------------------------*/
4716 /*----------------------------*/
4719 AST_FOR (tree, initExpr) = decorateType (
4720 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4721 AST_FOR (tree, condExpr) = decorateType (
4722 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4723 AST_FOR (tree, loopExpr) = decorateType (
4724 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4726 /* if the for loop is reversible then
4727 reverse it otherwise do what we normally
4733 if (isLoopReversible (tree, &sym, &init, &end))
4734 return reverseLoop (tree, sym, init, end);
4736 return decorateType (createFor (AST_FOR (tree, trueLabel),
4737 AST_FOR (tree, continueLabel),
4738 AST_FOR (tree, falseLabel),
4739 AST_FOR (tree, condLabel),
4740 AST_FOR (tree, initExpr),
4741 AST_FOR (tree, condExpr),
4742 AST_FOR (tree, loopExpr),
4743 tree->left), RESULT_TYPE_NONE);
4746 werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
4747 "node PARAM shouldn't be processed here");
4748 /* but in processParams() */
4751 TTYPE (tree) = TETYPE (tree) = NULL;
4755 /* some error found this tree will be killed */
4757 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4758 tree->opval.op = NULLOP;
4764 /*-----------------------------------------------------------------*/
4765 /* sizeofOp - processes size of operation */
4766 /*-----------------------------------------------------------------*/
4768 sizeofOp (sym_link * type)
4773 /* make sure the type is complete and sane */
4774 checkTypeSanity(type, "(sizeof)");
4776 /* get the size and convert it to character */
4777 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4778 if (!size && !IS_VOID(type))
4779 werror (E_SIZEOF_INCOMPLETE_TYPE);
4781 /* now convert into value */
4782 return constVal (buff);
4786 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4787 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4788 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4789 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4790 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4791 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4792 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4794 /*-----------------------------------------------------------------*/
4795 /* backPatchLabels - change and or not operators to flow control */
4796 /*-----------------------------------------------------------------*/
4798 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4804 /* while-loops insert a label between the IFX and the condition,
4805 therefore look behind the label too */
4806 if (tree->opval.op == LABEL &&
4808 IS_ANDORNOT (tree->right))
4810 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4814 if (!(IS_ANDORNOT (tree)))
4817 /* if this an and */
4820 static int localLbl = 0;
4823 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4824 localLabel = newSymbol (buffer, NestLevel);
4826 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4828 /* if left is already a IFX then just change the if true label in that */
4829 if (!IS_IFX (tree->left))
4830 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4832 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4833 /* right is a IFX then just join */
4834 if (IS_IFX (tree->right))
4835 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4837 tree->right = createLabel (localLabel, tree->right);
4838 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4840 return newNode (NULLOP, tree->left, tree->right);
4843 /* if this is an or operation */
4846 static int localLbl = 0;
4849 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4850 localLabel = newSymbol (buffer, NestLevel);
4852 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4854 /* if left is already a IFX then just change the if true label in that */
4855 if (!IS_IFX (tree->left))
4856 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4858 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4859 /* right is a IFX then just join */
4860 if (IS_IFX (tree->right))
4861 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4863 tree->right = createLabel (localLabel, tree->right);
4864 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4866 return newNode (NULLOP, tree->left, tree->right);
4872 /* call with exchanged labels */
4873 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4875 /* if left isn't already a IFX */
4876 if (!IS_IFX (tree->left))
4878 tree->left = newNode (IFX, tree->left, NULL);
4879 tree->left->trueLabel = falseLabel;
4880 tree->left->falseLabel = trueLabel;
4887 tree->trueLabel = trueLabel;
4888 tree->falseLabel = falseLabel;
4895 /*-----------------------------------------------------------------*/
4896 /* createBlock - create expression tree for block */
4897 /*-----------------------------------------------------------------*/
4899 createBlock (symbol * decl, ast * body)
4903 /* if the block has nothing */
4907 ex = newNode (BLOCK, NULL, body);
4908 ex->values.sym = decl;
4915 /*-----------------------------------------------------------------*/
4916 /* createLabel - creates the expression tree for labels */
4917 /*-----------------------------------------------------------------*/
4919 createLabel (symbol * label, ast * stmnt)
4922 char name[SDCC_NAME_MAX + 1];
4925 /* must create fresh symbol if the symbol name */
4926 /* exists in the symbol table, since there can */
4927 /* be a variable with the same name as the labl */
4928 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4929 (csym->level == label->level))
4930 label = newSymbol (label->name, label->level);
4932 /* change the name before putting it in add _ */
4933 SNPRINTF(name, sizeof(name), "%s", label->name);
4935 /* put the label in the LabelSymbol table */
4936 /* but first check if a label of the same */
4938 if ((csym = findSym (LabelTab, NULL, name)))
4939 werror (E_DUPLICATE_LABEL, label->name);
4941 addSym (LabelTab, label, name, label->level, 0, 0);
4945 label->key = labelKey++;
4946 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4952 /*-----------------------------------------------------------------*/
4953 /* createCase - generates the parsetree for a case statement */
4954 /*-----------------------------------------------------------------*/
4956 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4958 char caseLbl[SDCC_NAME_MAX + 1];
4962 /* if the switch statement does not exist */
4963 /* then case is out of context */
4966 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4970 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4971 /* if not a constant then error */
4972 if (!IS_LITERAL (caseVal->ftype))
4974 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4978 /* if not a integer than error */
4979 if (!IS_INTEGRAL (caseVal->ftype))
4981 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4985 /* find the end of the switch values chain */
4986 if (!(val = swStat->values.switchVals.swVals))
4987 swStat->values.switchVals.swVals = caseVal->opval.val;
4990 /* also order the cases according to value */
4992 int cVal = (int) floatFromVal (caseVal->opval.val);
4993 while (val && (int) floatFromVal (val) < cVal)
4999 /* if we reached the end then */
5002 pval->next = caseVal->opval.val;
5004 else if ((int) floatFromVal (val) == cVal)
5006 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5012 /* we found a value greater than */
5013 /* the current value we must add this */
5014 /* before the value */
5015 caseVal->opval.val->next = val;
5017 /* if this was the first in chain */
5018 if (swStat->values.switchVals.swVals == val)
5019 swStat->values.switchVals.swVals =
5022 pval->next = caseVal->opval.val;
5027 /* create the case label */
5028 SNPRINTF(caseLbl, sizeof(caseLbl),
5030 swStat->values.switchVals.swNum,
5031 (int) floatFromVal (caseVal->opval.val));
5033 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5038 /*-----------------------------------------------------------------*/
5039 /* createDefault - creates the parse tree for the default statement */
5040 /*-----------------------------------------------------------------*/
5042 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5044 char defLbl[SDCC_NAME_MAX + 1];
5046 /* if the switch statement does not exist */
5047 /* then case is out of context */
5050 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5054 if (swStat->values.switchVals.swDefault)
5056 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5061 /* turn on the default flag */
5062 swStat->values.switchVals.swDefault = 1;
5064 /* create the label */
5065 SNPRINTF (defLbl, sizeof(defLbl),
5066 "_default_%d", swStat->values.switchVals.swNum);
5067 return createLabel (newSymbol (defLbl, 0), stmnt);
5070 /*-----------------------------------------------------------------*/
5071 /* createIf - creates the parsetree for the if statement */
5072 /*-----------------------------------------------------------------*/
5074 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5076 static int Lblnum = 0;
5078 symbol *ifTrue, *ifFalse, *ifEnd;
5080 /* if neither exists */
5081 if (!elseBody && !ifBody) {
5082 // if there are no side effects (i++, j() etc)
5083 if (!hasSEFcalls(condAst)) {
5088 /* create the labels */
5089 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5090 ifFalse = newSymbol (buffer, NestLevel);
5091 /* if no else body then end == false */
5096 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5097 ifEnd = newSymbol (buffer, NestLevel);
5100 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5101 ifTrue = newSymbol (buffer, NestLevel);
5105 /* attach the ifTrue label to the top of it body */
5106 ifBody = createLabel (ifTrue, ifBody);
5107 /* attach a goto end to the ifBody if else is present */
5110 ifBody = newNode (NULLOP, ifBody,
5112 newAst_VALUE (symbolVal (ifEnd)),
5114 /* put the elseLabel on the else body */
5115 elseBody = createLabel (ifFalse, elseBody);
5116 /* out the end at the end of the body */
5117 elseBody = newNode (NULLOP,
5119 createLabel (ifEnd, NULL));
5123 ifBody = newNode (NULLOP, ifBody,
5124 createLabel (ifFalse, NULL));
5126 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5127 if (IS_IFX (condAst))
5130 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5132 return newNode (NULLOP, ifTree,
5133 newNode (NULLOP, ifBody, elseBody));
5137 /*-----------------------------------------------------------------*/
5138 /* createDo - creates parse tree for do */
5141 /* _docontinue_n: */
5142 /* condition_expression +-> trueLabel -> _dobody_n */
5144 /* +-> falseLabel-> _dobreak_n */
5146 /*-----------------------------------------------------------------*/
5148 createDo (symbol * trueLabel, symbol * continueLabel,
5149 symbol * falseLabel, ast * condAst, ast * doBody)
5154 /* if the body does not exist then it is simple */
5157 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5158 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5159 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5160 doTree->trueLabel = continueLabel;
5161 doTree->falseLabel = NULL;
5163 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5167 /* otherwise we have a body */
5168 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5170 /* attach the body label to the top */
5171 doBody = createLabel (trueLabel, doBody);
5172 /* attach the continue label to end of body */
5173 doBody = newNode (NULLOP, doBody,
5174 createLabel (continueLabel, NULL));
5176 /* now put the break label at the end */
5177 if (IS_IFX (condAst))
5180 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5182 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5184 /* putting it together */
5185 return newNode (NULLOP, doBody, doTree);
5188 /*-----------------------------------------------------------------*/
5189 /* createFor - creates parse tree for 'for' statement */
5192 /* condExpr +-> trueLabel -> _forbody_n */
5194 /* +-> falseLabel-> _forbreak_n */
5197 /* _forcontinue_n: */
5199 /* goto _forcond_n ; */
5201 /*-----------------------------------------------------------------*/
5203 createFor (symbol * trueLabel, symbol * continueLabel,
5204 symbol * falseLabel, symbol * condLabel,
5205 ast * initExpr, ast * condExpr, ast * loopExpr,
5210 /* if loopexpression not present then we can generate it */
5211 /* the same way as a while */
5213 return newNode (NULLOP, initExpr,
5214 createWhile (trueLabel, continueLabel,
5215 falseLabel, condExpr, forBody));
5216 /* vanilla for statement */
5217 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5219 if (condExpr && !IS_IFX (condExpr))
5220 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5223 /* attach condition label to condition */
5224 condExpr = createLabel (condLabel, condExpr);
5226 /* attach body label to body */
5227 forBody = createLabel (trueLabel, forBody);
5229 /* attach continue to forLoop expression & attach */
5230 /* goto the forcond @ and of loopExpression */
5231 loopExpr = createLabel (continueLabel,
5235 newAst_VALUE (symbolVal (condLabel)),
5237 /* now start putting them together */
5238 forTree = newNode (NULLOP, initExpr, condExpr);
5239 forTree = newNode (NULLOP, forTree, forBody);
5240 forTree = newNode (NULLOP, forTree, loopExpr);
5241 /* finally add the break label */
5242 forTree = newNode (NULLOP, forTree,
5243 createLabel (falseLabel, NULL));
5247 /*-----------------------------------------------------------------*/
5248 /* createWhile - creates parse tree for while statement */
5249 /* the while statement will be created as follows */
5251 /* _while_continue_n: */
5252 /* condition_expression +-> trueLabel -> _while_boby_n */
5254 /* +-> falseLabel -> _while_break_n */
5255 /* _while_body_n: */
5257 /* goto _while_continue_n */
5258 /* _while_break_n: */
5259 /*-----------------------------------------------------------------*/
5261 createWhile (symbol * trueLabel, symbol * continueLabel,
5262 symbol * falseLabel, ast * condExpr, ast * whileBody)
5266 /* put the continue label */
5267 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5268 condExpr = createLabel (continueLabel, condExpr);
5269 condExpr->lineno = 0;
5271 /* put the body label in front of the body */
5272 whileBody = createLabel (trueLabel, whileBody);
5273 whileBody->lineno = 0;
5274 /* put a jump to continue at the end of the body */
5275 /* and put break label at the end of the body */
5276 whileBody = newNode (NULLOP,
5279 newAst_VALUE (symbolVal (continueLabel)),
5280 createLabel (falseLabel, NULL)));
5282 /* put it all together */
5283 if (IS_IFX (condExpr))
5284 whileTree = condExpr;
5287 whileTree = newNode (IFX, condExpr, NULL);
5288 /* put the true & false labels in place */
5289 whileTree->trueLabel = trueLabel;
5290 whileTree->falseLabel = falseLabel;
5293 return newNode (NULLOP, whileTree, whileBody);
5296 /*-----------------------------------------------------------------*/
5297 /* isShiftRightLitVal _BitAndLitVal - helper function */
5298 /*-----------------------------------------------------------------*/
5300 isShiftRightLitVal_BitAndLitVal (ast * tree)
5302 /* if this is not a bit and */
5303 if (!IS_BITAND (tree))
5306 /* will look for tree of the form
5307 ( expr >> litval2) & litval1 */
5308 if (!IS_AST_LIT_VALUE (tree->right))
5311 if (!IS_RIGHT_OP (tree->left))
5314 if (!IS_AST_LIT_VALUE (tree->left->right))
5317 return tree->left->left;
5320 /*-----------------------------------------------------------------*/
5321 /* isBitAndPowOf2 - helper function */
5322 /*-----------------------------------------------------------------*/
5324 isBitAndPow2 (ast * tree)
5326 /* if this is not a bit and */
5327 if (!IS_BITAND (tree))
5330 /* will look for tree of the form
5331 ( expr & (1 << litval) */
5332 if (!IS_AST_LIT_VALUE (tree->right))
5335 return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
5338 /*-----------------------------------------------------------------*/
5339 /* optimizeGetHbit - get highest order bit of the expression */
5340 /*-----------------------------------------------------------------*/
5342 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5347 expr = isShiftRightLitVal_BitAndLitVal(tree);
5350 if ((AST_LIT_VALUE (tree->right) != 1) ||
5351 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5352 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5355 if (!expr && (resultType == RESULT_TYPE_BIT))
5358 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5364 /* make sure the port supports GETHBIT */
5365 if (port->hasExtBitOp
5366 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5369 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5372 /*-----------------------------------------------------------------*/
5373 /* optimizeGetAbit - get a single bit of the expression */
5374 /*-----------------------------------------------------------------*/
5376 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5381 expr = isShiftRightLitVal_BitAndLitVal(tree);
5384 if (AST_LIT_VALUE (tree->right) != 1)
5386 count = tree->left->right;
5388 if (!expr && (resultType == RESULT_TYPE_BIT))
5390 int p2 = isBitAndPow2 (tree);
5394 count = newAst_VALUE (valueFromLit (p2));
5400 /* make sure the port supports GETABIT */
5401 if (port->hasExtBitOp
5402 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5405 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5409 /*-----------------------------------------------------------------*/
5410 /* optimizeGetByte - get a byte of the expression */
5411 /*-----------------------------------------------------------------*/
5413 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5419 expr = isShiftRightLitVal_BitAndLitVal(tree);
5422 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5423 count = tree->left->right;
5424 if (AST_LIT_VALUE (tree->right) != 0xFF)
5427 if (!expr && resultType == RESULT_TYPE_CHAR)
5429 /* if this is a right shift over a multiple of 8 */
5430 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5432 i = (unsigned int) AST_LIT_VALUE (tree->right);
5433 count = tree->right;
5437 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5440 /* make sure the port supports GETBYTE */
5441 if (port->hasExtBitOp
5442 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5445 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5448 /*-----------------------------------------------------------------*/
5449 /* optimizeGetWord - get two bytes of the expression */
5450 /*-----------------------------------------------------------------*/
5452 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5458 expr = isShiftRightLitVal_BitAndLitVal(tree);
5461 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5462 count = tree->left->right;
5463 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5466 if (!expr && resultType == RESULT_TYPE_INT)
5468 /* if this is a right shift over a multiple of 8 */
5469 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5471 i = (unsigned int) AST_LIT_VALUE (tree->right);
5472 count = tree->right;
5476 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5479 /* make sure the port supports GETWORD */
5480 if (port->hasExtBitOp
5481 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5484 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5487 /*-----------------------------------------------------------------*/
5488 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5489 /*-----------------------------------------------------------------*/
5491 optimizeRRCRLC (ast * root)
5493 /* will look for trees of the form
5494 (?expr << 1) | (?expr >> 7) or
5495 (?expr >> 7) | (?expr << 1) will make that
5496 into a RLC : operation ..
5498 (?expr >> 1) | (?expr << 7) or
5499 (?expr << 7) | (?expr >> 1) will make that
5500 into a RRC operation
5501 note : by 7 I mean (number of bits required to hold the
5503 /* if the root operation is not a | operation then not */
5504 if (!IS_BITOR (root))
5507 /* I have to think of a better way to match patterns this sucks */
5508 /* that aside let's start looking for the first case : I use a
5509 negative check a lot to improve the efficiency */
5510 /* (?expr << 1) | (?expr >> 7) */
5511 if (IS_LEFT_OP (root->left) &&
5512 IS_RIGHT_OP (root->right))
5515 if (!SPEC_USIGN (TETYPE (root->left->left)))
5518 if (!IS_AST_LIT_VALUE (root->left->right) ||
5519 !IS_AST_LIT_VALUE (root->right->right))
5522 /* make sure it is the same expression */
5523 if (!isAstEqual (root->left->left,
5527 if (AST_LIT_VALUE (root->left->right) != 1)
5530 if (AST_LIT_VALUE (root->right->right) !=
5531 (getSize (TTYPE (root->left->left)) * 8 - 1))
5534 /* make sure the port supports RLC */
5535 if (port->hasExtBitOp
5536 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5539 /* whew got the first case : create the AST */
5540 return newNode (RLC, root->left->left, NULL);
5544 /* check for second case */
5545 /* (?expr >> 7) | (?expr << 1) */
5546 if (IS_LEFT_OP (root->right) &&
5547 IS_RIGHT_OP (root->left))
5550 if (!SPEC_USIGN (TETYPE (root->left->left)))
5553 if (!IS_AST_LIT_VALUE (root->left->right) ||
5554 !IS_AST_LIT_VALUE (root->right->right))
5557 /* make sure it is the same symbol */
5558 if (!isAstEqual (root->left->left,
5562 if (AST_LIT_VALUE (root->right->right) != 1)
5565 if (AST_LIT_VALUE (root->left->right) !=
5566 (getSize (TTYPE (root->left->left)) * 8 - 1))
5569 /* make sure the port supports RLC */
5570 if (port->hasExtBitOp
5571 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5574 /* whew got the first case : create the AST */
5575 return newNode (RLC, root->left->left, NULL);
5580 /* third case for RRC */
5581 /* (?symbol >> 1) | (?symbol << 7) */
5582 if (IS_LEFT_OP (root->right) &&
5583 IS_RIGHT_OP (root->left))
5586 if (!SPEC_USIGN (TETYPE (root->left->left)))
5589 if (!IS_AST_LIT_VALUE (root->left->right) ||
5590 !IS_AST_LIT_VALUE (root->right->right))
5593 /* make sure it is the same symbol */
5594 if (!isAstEqual (root->left->left,
5598 if (AST_LIT_VALUE (root->left->right) != 1)
5601 if (AST_LIT_VALUE (root->right->right) !=
5602 (getSize (TTYPE (root->left->left)) * 8 - 1))
5605 /* make sure the port supports RRC */
5606 if (port->hasExtBitOp
5607 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5610 /* whew got the first case : create the AST */
5611 return newNode (RRC, root->left->left, NULL);
5615 /* fourth and last case for now */
5616 /* (?symbol << 7) | (?symbol >> 1) */
5617 if (IS_RIGHT_OP (root->right) &&
5618 IS_LEFT_OP (root->left))
5621 if (!SPEC_USIGN (TETYPE (root->left->left)))
5624 if (!IS_AST_LIT_VALUE (root->left->right) ||
5625 !IS_AST_LIT_VALUE (root->right->right))
5628 /* make sure it is the same symbol */
5629 if (!isAstEqual (root->left->left,
5633 if (AST_LIT_VALUE (root->right->right) != 1)
5636 if (AST_LIT_VALUE (root->left->right) !=
5637 (getSize (TTYPE (root->left->left)) * 8 - 1))
5640 /* make sure the port supports RRC */
5641 if (port->hasExtBitOp
5642 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5645 /* whew got the first case : create the AST */
5646 return newNode (RRC, root->left->left, NULL);
5650 /* not found return root */
5654 /*-----------------------------------------------------------------*/
5655 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5656 /*-----------------------------------------------------------------*/
5658 optimizeSWAP (ast * root)
5660 /* will look for trees of the form
5661 (?expr << 4) | (?expr >> 4) or
5662 (?expr >> 4) | (?expr << 4) will make that
5663 into a SWAP : operation ..
5664 note : by 4 I mean (number of bits required to hold the
5666 /* if the root operation is not a | operation then not */
5667 if (!IS_BITOR (root))
5670 /* (?expr << 4) | (?expr >> 4) */
5671 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5672 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5675 if (!SPEC_USIGN (TETYPE (root->left->left)))
5678 if (!IS_AST_LIT_VALUE (root->left->right) ||
5679 !IS_AST_LIT_VALUE (root->right->right))
5682 /* make sure it is the same expression */
5683 if (!isAstEqual (root->left->left,
5687 if (AST_LIT_VALUE (root->left->right) !=
5688 (getSize (TTYPE (root->left->left)) * 4))
5691 if (AST_LIT_VALUE (root->right->right) !=
5692 (getSize (TTYPE (root->left->left)) * 4))
5695 /* make sure the port supports SWAP */
5696 if (port->hasExtBitOp
5697 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5700 /* found it : create the AST */
5701 return newNode (SWAP, root->left->left, NULL);
5705 /* not found return root */
5709 /*-----------------------------------------------------------------*/
5710 /* optimizeCompare - optimizes compares for bit variables */
5711 /*-----------------------------------------------------------------*/
5713 optimizeCompare (ast * root)
5715 ast *optExpr = NULL;
5718 unsigned int litValue;
5720 /* if nothing then return nothing */
5724 /* if not a compare op then do leaves */
5725 if (!IS_COMPARE_OP (root))
5727 root->left = optimizeCompare (root->left);
5728 root->right = optimizeCompare (root->right);
5732 /* if left & right are the same then depending
5733 of the operation do */
5734 if (isAstEqual (root->left, root->right))
5736 switch (root->opval.op)
5741 optExpr = newAst_VALUE (constVal ("0"));
5746 optExpr = newAst_VALUE (constVal ("1"));
5750 return decorateType (optExpr, RESULT_TYPE_NONE);
5753 vleft = (root->left->type == EX_VALUE ?
5754 root->left->opval.val : NULL);
5756 vright = (root->right->type == EX_VALUE ?
5757 root->right->opval.val : NULL);
5759 /* if left is a BITVAR in BITSPACE */
5760 /* and right is a LITERAL then opt- */
5761 /* imize else do nothing */
5762 if (vleft && vright &&
5763 IS_BITVAR (vleft->etype) &&
5764 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5765 IS_LITERAL (vright->etype))
5768 /* if right side > 1 then comparison may never succeed */
5769 if ((litValue = (int) floatFromVal (vright)) > 1)
5771 werror (W_BAD_COMPARE);
5777 switch (root->opval.op)
5779 case '>': /* bit value greater than 1 cannot be */
5780 werror (W_BAD_COMPARE);
5784 case '<': /* bit value < 1 means 0 */
5786 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5789 case LE_OP: /* bit value <= 1 means no check */
5790 optExpr = newAst_VALUE (vright);
5793 case GE_OP: /* bit value >= 1 means only check for = */
5795 optExpr = newAst_VALUE (vleft);
5800 { /* literal is zero */
5801 switch (root->opval.op)
5803 case '<': /* bit value < 0 cannot be */
5804 werror (W_BAD_COMPARE);
5808 case '>': /* bit value > 0 means 1 */
5810 optExpr = newAst_VALUE (vleft);
5813 case LE_OP: /* bit value <= 0 means no check */
5814 case GE_OP: /* bit value >= 0 means no check */
5815 werror (W_BAD_COMPARE);
5819 case EQ_OP: /* bit == 0 means ! of bit */
5820 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5824 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5825 } /* end-of-if of BITVAR */
5831 /*-----------------------------------------------------------------*/
5832 /* addSymToBlock : adds the symbol to the first block we find */
5833 /*-----------------------------------------------------------------*/
5835 addSymToBlock (symbol * sym, ast * tree)
5837 /* reached end of tree or a leaf */
5838 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5842 if (IS_AST_OP (tree) &&
5843 tree->opval.op == BLOCK)
5846 symbol *lsym = copySymbol (sym);
5848 lsym->next = AST_VALUES (tree, sym);
5849 AST_VALUES (tree, sym) = lsym;
5853 addSymToBlock (sym, tree->left);
5854 addSymToBlock (sym, tree->right);
5857 /*-----------------------------------------------------------------*/
5858 /* processRegParms - do processing for register parameters */
5859 /*-----------------------------------------------------------------*/
5861 processRegParms (value * args, ast * body)
5865 if (IS_REGPARM (args->etype))
5866 addSymToBlock (args->sym, body);
5871 /*-----------------------------------------------------------------*/
5872 /* resetParmKey - resets the operandkeys for the symbols */
5873 /*-----------------------------------------------------------------*/
5874 DEFSETFUNC (resetParmKey)
5887 /*------------------------------------------------------------------*/
5888 /* fixupInlineLabel - change a label in an inlined function so that */
5889 /* it is always unique no matter how many times */
5890 /* the function is inlined. */
5891 /*------------------------------------------------------------------*/
5893 fixupInlineLabel (symbol * sym)
5895 char name[SDCC_NAME_MAX + 1];
5897 SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
5898 strcpy (sym->name, name);
5902 /*------------------------------------------------------------------*/
5903 /* copyAstLoc - copy location information (file, line, block, etc.) */
5904 /* from one ast node to another */
5905 /*------------------------------------------------------------------*/
5907 copyAstLoc (ast * dest, ast * src)
5909 dest->lineno = src->lineno;
5910 dest->filename = src->filename;
5911 dest->level = src->level;
5912 dest->block = src->block;
5913 dest->seqPoint = src->seqPoint;
5918 /*-----------------------------------------------------------------*/
5919 /* fixupInline - perform various fixups on an inline function tree */
5920 /* to take into account that it is no longer a */
5921 /* stand-alone function. */
5922 /*-----------------------------------------------------------------*/
5924 fixupInline (ast * tree, int level)
5926 tree->block = currBlockno;
5928 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
5935 /* Add any declared variables back into the symbol table */
5936 decls = tree->values.sym;
5939 decls->level = level;
5940 decls->block = currBlockno;
5941 addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0);
5942 decls = decls->next;
5946 tree->level = level;
5948 /* Update symbols */
5949 if (IS_AST_VALUE (tree) &&
5950 tree->opval.val->sym)
5952 symbol * sym = tree->opval.val->sym;
5955 sym->block = currBlockno;
5957 /* If the symbol is a label, we need to renumber it */
5959 fixupInlineLabel (sym);
5962 /* Update IFX target labels */
5963 if (tree->type == EX_OP && tree->opval.op == IFX)
5965 if (tree->trueLabel)
5966 fixupInlineLabel (tree->trueLabel);
5967 if (tree->falseLabel)
5968 fixupInlineLabel (tree->falseLabel);
5971 /* Replace RETURN with optional assignment and a GOTO to the end */
5972 /* of the inlined function */
5973 if (tree->type == EX_OP && tree->opval.op == RETURN)
5975 ast * assignTree = NULL;
5978 if (inlineState.retsym && tree->right)
5980 assignTree = newNode ('=',
5981 newAst_VALUE (symbolVal (inlineState.retsym)),
5983 copyAstLoc (assignTree, tree);
5986 gotoTree = newNode (GOTO,
5987 newAst_VALUE (symbolVal (inlineState.retlab)),
5989 copyAstLoc (gotoTree, tree);
5991 tree->opval.op = NULLOP;
5992 tree->left = assignTree;
5993 tree->right = gotoTree;
5996 /* Update any children */
5998 fixupInline (tree->left, level);
6000 fixupInline (tree->right, level);
6002 if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
6004 symbol * label = tree->left->opval.val->sym;
6006 label->key = labelKey++;
6007 /* Add this label back into the symbol table */
6008 addSym (LabelTab, label, label->name, label->level, 0, 0);
6012 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
6018 /*-----------------------------------------------------------------*/
6019 /* inlineAddDecl - add a variable declaration to an ast block. It */
6020 /* is also added to the symbol table if addSymTab */
6022 /*-----------------------------------------------------------------*/
6024 inlineAddDecl (symbol * sym, ast * block, int addSymTab)
6028 symbol **decl = &(block->values.sym);
6030 sym->level = block->level;
6031 sym->block = block->block;
6035 if (strcmp ((*decl)->name, sym->name) == 0)
6037 decl = &( (*decl)->next );
6043 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0);
6049 /*-----------------------------------------------------------------*/
6050 /* inlineTempVar - create a temporary variable for inlining */
6051 /*-----------------------------------------------------------------*/
6053 inlineTempVar (sym_link * type, int level)
6057 sym = newSymbol (genSymName(level), level );
6058 sym->type = copyLinkChain (type);
6059 sym->etype = getSpec(sym->type);
6060 SPEC_SCLS (sym->etype) = S_AUTO;
6061 SPEC_OCLS (sym->etype) = NULL;
6062 SPEC_EXTR (sym->etype) = 0;
6063 SPEC_STAT (sym->etype) = 0;
6064 if IS_SPEC (sym->type)
6065 SPEC_VOLATILE (sym->type) = 0;
6067 DCL_PTR_VOLATILE (sym->type) = 0;
6068 SPEC_ABSA (sym->etype) = 0;
6074 /*-----------------------------------------------------------------*/
6075 /* inlineFindParmRecurse - recursive function for inlineFindParm */
6076 /*-----------------------------------------------------------------*/
6078 inlineFindParmRecurse (ast * parms, int *index)
6083 if (parms->type == EX_OP && parms->opval.op == PARAM)
6087 p=inlineFindParmRecurse (parms->left, index);
6090 p=inlineFindParmRecurse (parms->right, index);
6101 /*-----------------------------------------------------------------*/
6102 /* inlineFindParm - search an ast tree of parameters to find one */
6103 /* at a particular index (0=first parameter). */
6104 /* Returns NULL if not found. */
6105 /*-----------------------------------------------------------------*/
6107 inlineFindParm (ast * parms, int index)
6109 return inlineFindParmRecurse (parms, &index);
6113 /*-----------------------------------------------------------------*/
6114 /* expandInlineFuncs - replace calls to inline functions with the */
6115 /* function itself */
6116 /*-----------------------------------------------------------------*/
6118 expandInlineFuncs (ast * tree, ast * block)
6120 if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left
6121 && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym)
6123 symbol * func = tree->left->opval.val->sym;
6126 /* The symbol is probably not bound yet, so find the real one */
6127 csym = findSymWithLevel (SymbolTab, func);
6131 /* Is this an inline function that we can inline? */
6132 if (IFFUNC_ISINLINE (func->type) && func->funcTree)
6134 symbol * retsym = NULL;
6142 /* Generate a label for the inlined function to branch to */
6143 /* in case it contains a return statement */
6144 retlab = newSymbol (genSymName(tree->level+1), tree->level+1 );
6147 inlineState.retlab = retlab;
6149 /* Build the subtree for the inlined function in the form: */
6150 /* { //inlinetree block */
6151 /* { //inlinetree2 block */
6152 /* inline_function_code; */
6156 temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL);
6157 copyAstLoc (temptree, tree);
6158 temptree = newNode (NULLOP, copyAst (func->funcTree), temptree);
6159 copyAstLoc (temptree, tree);
6160 temptree = newNode (BLOCK, NULL, temptree);
6161 copyAstLoc (temptree, tree);
6162 inlinetree2 = temptree;
6163 inlinetree = newNode (BLOCK, NULL, inlinetree2);
6164 copyAstLoc (inlinetree, tree);
6166 /* To pass parameters to the inlined function, we need some */
6167 /* intermediate variables. This avoids scoping problems */
6168 /* when the parameter declaration names are used differently */
6169 /* during the function call. For example, a function */
6170 /* declared as func(int x, int y) but called as func(y,x). */
6171 /* { //inlinetree block */
6172 /* type1 temparg1; */
6174 /* typen tempargn; */
6175 /* temparg1 = argument1; */
6177 /* tempargn = argumentn; */
6178 /* { //inlinetree2 block */
6182 /* param1 = temparg1; */
6184 /* paramn = tempargn; */
6185 /* inline_function_code; */
6189 args = FUNC_ARGS (func->type);
6196 symbol * parm = copySymbol (args->sym);
6198 temparg = inlineTempVar (args->sym->type, tree->level+1);
6199 inlineAddDecl (temparg, inlinetree, FALSE);
6201 passedarg = inlineFindParm (tree->right, argIndex);
6202 assigntree = newNode ('=',
6203 newAst_VALUE (symbolVal (temparg)),
6205 inlinetree->right = newNode (NULLOP,
6209 inlineAddDecl (parm, inlinetree2, FALSE);
6212 assigntree = newNode ('=',
6213 newAst_VALUE (symbolVal (parm)),
6214 newAst_VALUE (symbolVal (temparg)));
6215 inlinetree2->right = newNode (NULLOP,
6217 inlinetree2->right);
6224 /* Handle the return type */
6225 if (!IS_VOID (func->type->next))
6227 /* Create a temporary symbol to hold the return value and */
6228 /* join it with the inlined function using the comma */
6229 /* operator. The fixupInline function will take care of */
6230 /* changing return statements into assignments to retsym. */
6231 /* (parameter passing and return label omitted for clarity) */
6232 /* rettype retsym; */
6234 /* {{inline_function_code}}, retsym */
6236 retsym = inlineTempVar (func->type->next, tree->level);
6237 inlineAddDecl (retsym, block, TRUE);
6239 tree->opval.op = ',';
6240 tree->left = inlinetree;
6241 tree->right = newAst_VALUE (symbolVal (retsym));
6245 tree->opval.op = NULLOP;
6247 tree->right = inlinetree;
6249 inlineState.retsym = retsym;
6251 /* Renumber the various internal counters on the inlined */
6252 /* function's tree nodes and symbols. Add the inlined */
6253 /* function's local variables to the appropriate scope(s). */
6254 /* Convert inlined return statements to an assignment to */
6255 /* retsym (if needed) and a goto retlab. */
6256 fixupInline (inlinetree, inlinetree->level);
6257 inlineState.count++;
6262 /* Recursively continue to search for functions to inline. */
6263 if (IS_AST_OP (tree))
6265 if (tree->opval.op == BLOCK)
6269 expandInlineFuncs (tree->left, block);
6271 expandInlineFuncs (tree->right, block);
6276 /*-----------------------------------------------------------------*/
6277 /* createFunction - This is the key node that calls the iCode for */
6278 /* generating the code for a function. Note code */
6279 /* is generated function by function, later when */
6280 /* add inter-procedural analysis this will change */
6281 /*-----------------------------------------------------------------*/
6283 createFunction (symbol * name, ast * body)
6289 iCode *piCode = NULL;
6291 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
6292 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
6294 /* if check function return 0 then some problem */
6295 if (checkFunction (name, NULL) == 0)
6298 /* create a dummy block if none exists */
6300 body = newNode (BLOCK, NULL, NULL);
6304 /* check if the function name already in the symbol table */
6305 if ((csym = findSym (SymbolTab, NULL, name->name)))
6308 /* special case for compiler defined functions
6309 we need to add the name to the publics list : this
6310 actually means we are now compiling the compiler
6314 addSet (&publics, name);
6319 addSymChain (&name);
6320 allocVariables (name);
6322 name->lastLine = lexLineno;
6325 /* set the stack pointer */
6326 stackPtr = -port->stack.direction * port->stack.call_overhead;
6329 if (IFFUNC_ISISR (name->type))
6330 stackPtr -= port->stack.direction * port->stack.isr_overhead;
6332 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
6334 if (options.useXstack)
6335 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
6337 stackPtr -= port->stack.direction * port->stack.reent_overhead;
6340 fetype = getSpec (name->type); /* get the specifier for the function */
6341 /* if this is a reentrant function then */
6342 if (IFFUNC_ISREENT (name->type))
6345 inlineState.count = 0;
6346 expandInlineFuncs (body, NULL);
6348 if (FUNC_ISINLINE (name->type))
6349 name->funcTree = copyAst (body);
6351 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
6353 /* do processing for parameters that are passed in registers */
6354 processRegParms (FUNC_ARGS(name->type), body);
6356 /* set the stack pointer */
6360 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
6362 /* allocate & autoinit the block variables */
6363 processBlockVars (body, &stack, ALLOCATE);
6365 /* name needs to be mangled */
6366 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
6368 body = resolveSymbols (body); /* resolve the symbols */
6369 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
6371 /* save the stack information */
6372 if (options.useXstack)
6373 name->xstack = SPEC_STAK (fetype) = stack;
6375 name->stack = SPEC_STAK (fetype) = stack;
6377 ex = newAst_VALUE (symbolVal (name)); /* create name */
6378 ex = newNode (FUNCTION, ex, body);
6379 ex->values.args = FUNC_ARGS(name->type);
6381 if (options.dump_tree)
6386 /* Do not generate code for inline functions unless extern also */
6387 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
6390 /* create the node & generate intermediate code */
6392 codeOutBuf = &code->oBuf;
6393 piCode = iCodeFromAst (ex);
6394 name->generated = 1;
6399 eBBlockFromiCode (piCode);
6401 /* if there are any statics then do them */
6404 GcurMemmap = statsg;
6405 codeOutBuf = &statsg->oBuf;
6406 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6412 /* dealloc the block variables */
6413 processBlockVars (body, &stack, DEALLOCATE);
6414 outputDebugStackSymbols();
6415 /* deallocate paramaters */
6416 deallocParms (FUNC_ARGS(name->type));
6418 if (IFFUNC_ISREENT (name->type))
6421 /* we are done freeup memory & cleanup */
6423 if (port->reset_labelKey) labelKey = 1;
6425 FUNC_HASBODY(name->type) = 1;
6426 addSet (&operKeyReset, name);
6427 applyToSet (operKeyReset, resetParmKey);
6432 cleanUpLevel (LabelTab, 0);
6433 cleanUpBlock (StructTab, 1);
6434 cleanUpBlock (TypedefTab, 1);
6436 xstack->syms = NULL;
6437 istack->syms = NULL;
6442 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6443 /*-----------------------------------------------------------------*/
6444 /* ast_print : prints the ast (for debugging purposes) */
6445 /*-----------------------------------------------------------------*/
6447 void ast_print (ast * tree, FILE *outfile, int indent)
6452 /* can print only decorated trees */
6453 if (!tree->decorated) return;
6455 /* if any child is an error | this one is an error do nothing */
6456 if (tree->isError ||
6457 (tree->left && tree->left->isError) ||
6458 (tree->right && tree->right->isError)) {
6459 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6463 /* print the line */
6464 /* if not block & function */
6465 if (tree->type == EX_OP &&
6466 (tree->opval.op != FUNCTION &&
6467 tree->opval.op != BLOCK &&
6468 tree->opval.op != NULLOP)) {
6471 if (tree->opval.op == FUNCTION) {
6473 value *args=FUNC_ARGS(tree->left->opval.val->type);
6474 fprintf(outfile,"FUNCTION (%s=%p) type (",
6475 tree->left->opval.val->name, tree);
6476 printTypeChain (tree->left->opval.val->type->next,outfile);
6477 fprintf(outfile,") args (");
6480 fprintf (outfile, ", ");
6482 printTypeChain (args ? args->type : NULL, outfile);
6484 args= args ? args->next : NULL;
6486 fprintf(outfile,")\n");
6487 ast_print(tree->left,outfile,indent);
6488 ast_print(tree->right,outfile,indent);
6491 if (tree->opval.op == BLOCK) {
6492 symbol *decls = tree->values.sym;
6493 INDENT(indent,outfile);
6494 fprintf(outfile,"{\n");
6496 INDENT(indent+2,outfile);
6497 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6498 decls->name, decls);
6499 printTypeChain(decls->type,outfile);
6500 fprintf(outfile,")\n");
6502 decls = decls->next;
6504 ast_print(tree->right,outfile,indent+2);
6505 INDENT(indent,outfile);
6506 fprintf(outfile,"}\n");
6509 if (tree->opval.op == NULLOP) {
6510 ast_print(tree->left,outfile,indent);
6511 ast_print(tree->right,outfile,indent);
6514 INDENT(indent,outfile);
6516 /*------------------------------------------------------------------*/
6517 /*----------------------------*/
6518 /* leaf has been reached */
6519 /*----------------------------*/
6520 /* if this is of type value */
6521 /* just get the type */
6522 if (tree->type == EX_VALUE) {
6524 if (IS_LITERAL (tree->opval.val->etype)) {
6525 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6526 if (SPEC_USIGN (tree->opval.val->etype))
6527 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
6529 fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
6530 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
6531 floatFromVal(tree->opval.val));
6532 } else if (tree->opval.val->sym) {
6533 /* if the undefined flag is set then give error message */
6534 if (tree->opval.val->sym->undefined) {
6535 fprintf(outfile,"UNDEFINED SYMBOL ");
6537 fprintf(outfile,"SYMBOL ");
6539 fprintf(outfile,"(%s=%p @ %p)",
6540 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6543 fprintf(outfile," type (");
6544 printTypeChain(tree->ftype,outfile);
6545 fprintf(outfile,")\n");
6547 fprintf(outfile,"\n");
6552 /* if type link for the case of cast */
6553 if (tree->type == EX_LINK) {
6554 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6555 printTypeChain(tree->opval.lnk,outfile);
6556 fprintf(outfile,")\n");
6561 /* depending on type of operator do */
6563 switch (tree->opval.op) {
6564 /*------------------------------------------------------------------*/
6565 /*----------------------------*/
6567 /*----------------------------*/
6569 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6570 printTypeChain(tree->ftype,outfile);
6571 fprintf(outfile,")\n");
6572 ast_print(tree->left,outfile,indent+2);
6573 ast_print(tree->right,outfile,indent+2);
6576 /*------------------------------------------------------------------*/
6577 /*----------------------------*/
6579 /*----------------------------*/
6581 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6582 printTypeChain(tree->ftype,outfile);
6583 fprintf(outfile,")\n");
6584 ast_print(tree->left,outfile,indent+2);
6585 ast_print(tree->right,outfile,indent+2);
6588 /*------------------------------------------------------------------*/
6589 /*----------------------------*/
6590 /* struct/union pointer */
6591 /*----------------------------*/
6593 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6594 printTypeChain(tree->ftype,outfile);
6595 fprintf(outfile,")\n");
6596 ast_print(tree->left,outfile,indent+2);
6597 ast_print(tree->right,outfile,indent+2);
6600 /*------------------------------------------------------------------*/
6601 /*----------------------------*/
6602 /* ++/-- operation */
6603 /*----------------------------*/
6606 fprintf(outfile,"post-");
6608 fprintf(outfile,"pre-");
6609 fprintf(outfile,"INC_OP (%p) type (",tree);
6610 printTypeChain(tree->ftype,outfile);
6611 fprintf(outfile,")\n");
6612 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6613 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6618 fprintf(outfile,"post-");
6620 fprintf(outfile,"pre-");
6621 fprintf(outfile,"DEC_OP (%p) type (",tree);
6622 printTypeChain(tree->ftype,outfile);
6623 fprintf(outfile,")\n");
6624 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6625 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6628 /*------------------------------------------------------------------*/
6629 /*----------------------------*/
6631 /*----------------------------*/
6634 fprintf(outfile,"& (%p) type (",tree);
6635 printTypeChain(tree->ftype,outfile);
6636 fprintf(outfile,")\n");
6637 ast_print(tree->left,outfile,indent+2);
6638 ast_print(tree->right,outfile,indent+2);
6640 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6641 printTypeChain(tree->ftype,outfile);
6642 fprintf(outfile,")\n");
6643 ast_print(tree->left,outfile,indent+2);
6644 ast_print(tree->right,outfile,indent+2);
6647 /*----------------------------*/
6649 /*----------------------------*/
6651 fprintf(outfile,"OR (%p) type (",tree);
6652 printTypeChain(tree->ftype,outfile);
6653 fprintf(outfile,")\n");
6654 ast_print(tree->left,outfile,indent+2);
6655 ast_print(tree->right,outfile,indent+2);
6657 /*------------------------------------------------------------------*/
6658 /*----------------------------*/
6660 /*----------------------------*/
6662 fprintf(outfile,"XOR (%p) type (",tree);
6663 printTypeChain(tree->ftype,outfile);
6664 fprintf(outfile,")\n");
6665 ast_print(tree->left,outfile,indent+2);
6666 ast_print(tree->right,outfile,indent+2);
6669 /*------------------------------------------------------------------*/
6670 /*----------------------------*/
6672 /*----------------------------*/
6674 fprintf(outfile,"DIV (%p) type (",tree);
6675 printTypeChain(tree->ftype,outfile);
6676 fprintf(outfile,")\n");
6677 ast_print(tree->left,outfile,indent+2);
6678 ast_print(tree->right,outfile,indent+2);
6680 /*------------------------------------------------------------------*/
6681 /*----------------------------*/
6683 /*----------------------------*/
6685 fprintf(outfile,"MOD (%p) type (",tree);
6686 printTypeChain(tree->ftype,outfile);
6687 fprintf(outfile,")\n");
6688 ast_print(tree->left,outfile,indent+2);
6689 ast_print(tree->right,outfile,indent+2);
6692 /*------------------------------------------------------------------*/
6693 /*----------------------------*/
6694 /* address dereference */
6695 /*----------------------------*/
6696 case '*': /* can be unary : if right is null then unary operation */
6698 fprintf(outfile,"DEREF (%p) type (",tree);
6699 printTypeChain(tree->ftype,outfile);
6700 fprintf(outfile,")\n");
6701 ast_print(tree->left,outfile,indent+2);
6704 /*------------------------------------------------------------------*/
6705 /*----------------------------*/
6706 /* multiplication */
6707 /*----------------------------*/
6708 fprintf(outfile,"MULT (%p) type (",tree);
6709 printTypeChain(tree->ftype,outfile);
6710 fprintf(outfile,")\n");
6711 ast_print(tree->left,outfile,indent+2);
6712 ast_print(tree->right,outfile,indent+2);
6716 /*------------------------------------------------------------------*/
6717 /*----------------------------*/
6718 /* unary '+' operator */
6719 /*----------------------------*/
6723 fprintf(outfile,"UPLUS (%p) type (",tree);
6724 printTypeChain(tree->ftype,outfile);
6725 fprintf(outfile,")\n");
6726 ast_print(tree->left,outfile,indent+2);
6728 /*------------------------------------------------------------------*/
6729 /*----------------------------*/
6731 /*----------------------------*/
6732 fprintf(outfile,"ADD (%p) type (",tree);
6733 printTypeChain(tree->ftype,outfile);
6734 fprintf(outfile,")\n");
6735 ast_print(tree->left,outfile,indent+2);
6736 ast_print(tree->right,outfile,indent+2);
6739 /*------------------------------------------------------------------*/
6740 /*----------------------------*/
6742 /*----------------------------*/
6743 case '-': /* can be unary */
6745 fprintf(outfile,"UMINUS (%p) type (",tree);
6746 printTypeChain(tree->ftype,outfile);
6747 fprintf(outfile,")\n");
6748 ast_print(tree->left,outfile,indent+2);
6750 /*------------------------------------------------------------------*/
6751 /*----------------------------*/
6753 /*----------------------------*/
6754 fprintf(outfile,"SUB (%p) type (",tree);
6755 printTypeChain(tree->ftype,outfile);
6756 fprintf(outfile,")\n");
6757 ast_print(tree->left,outfile,indent+2);
6758 ast_print(tree->right,outfile,indent+2);
6761 /*------------------------------------------------------------------*/
6762 /*----------------------------*/
6764 /*----------------------------*/
6766 fprintf(outfile,"COMPL (%p) type (",tree);
6767 printTypeChain(tree->ftype,outfile);
6768 fprintf(outfile,")\n");
6769 ast_print(tree->left,outfile,indent+2);
6771 /*------------------------------------------------------------------*/
6772 /*----------------------------*/
6774 /*----------------------------*/
6776 fprintf(outfile,"NOT (%p) type (",tree);
6777 printTypeChain(tree->ftype,outfile);
6778 fprintf(outfile,")\n");
6779 ast_print(tree->left,outfile,indent+2);
6781 /*------------------------------------------------------------------*/
6782 /*----------------------------*/
6784 /*----------------------------*/
6786 fprintf(outfile,"RRC (%p) type (",tree);
6787 printTypeChain(tree->ftype,outfile);
6788 fprintf(outfile,")\n");
6789 ast_print(tree->left,outfile,indent+2);
6793 fprintf(outfile,"RLC (%p) type (",tree);
6794 printTypeChain(tree->ftype,outfile);
6795 fprintf(outfile,")\n");
6796 ast_print(tree->left,outfile,indent+2);
6799 fprintf(outfile,"SWAP (%p) type (",tree);
6800 printTypeChain(tree->ftype,outfile);
6801 fprintf(outfile,")\n");
6802 ast_print(tree->left,outfile,indent+2);
6805 fprintf(outfile,"GETHBIT (%p) type (",tree);
6806 printTypeChain(tree->ftype,outfile);
6807 fprintf(outfile,")\n");
6808 ast_print(tree->left,outfile,indent+2);
6811 fprintf(outfile,"GETABIT (%p) type (",tree);
6812 printTypeChain(tree->ftype,outfile);
6813 fprintf(outfile,")\n");
6814 ast_print(tree->left,outfile,indent+2);
6815 ast_print(tree->right,outfile,indent+2);
6818 fprintf(outfile,"GETBYTE (%p) type (",tree);
6819 printTypeChain(tree->ftype,outfile);
6820 fprintf(outfile,")\n");
6821 ast_print(tree->left,outfile,indent+2);
6822 ast_print(tree->right,outfile,indent+2);
6825 fprintf(outfile,"GETWORD (%p) type (",tree);
6826 printTypeChain(tree->ftype,outfile);
6827 fprintf(outfile,")\n");
6828 ast_print(tree->left,outfile,indent+2);
6829 ast_print(tree->right,outfile,indent+2);
6832 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6833 printTypeChain(tree->ftype,outfile);
6834 fprintf(outfile,")\n");
6835 ast_print(tree->left,outfile,indent+2);
6836 ast_print(tree->right,outfile,indent+2);
6839 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6840 printTypeChain(tree->ftype,outfile);
6841 fprintf(outfile,")\n");
6842 ast_print(tree->left,outfile,indent+2);
6843 ast_print(tree->right,outfile,indent+2);
6845 /*------------------------------------------------------------------*/
6846 /*----------------------------*/
6848 /*----------------------------*/
6849 case CAST: /* change the type */
6850 fprintf(outfile,"CAST (%p) from type (",tree);
6851 printTypeChain(tree->right->ftype,outfile);
6852 fprintf(outfile,") to type (");
6853 printTypeChain(tree->ftype,outfile);
6854 fprintf(outfile,")\n");
6855 ast_print(tree->right,outfile,indent+2);
6859 fprintf(outfile,"ANDAND (%p) type (",tree);
6860 printTypeChain(tree->ftype,outfile);
6861 fprintf(outfile,")\n");
6862 ast_print(tree->left,outfile,indent+2);
6863 ast_print(tree->right,outfile,indent+2);
6866 fprintf(outfile,"OROR (%p) type (",tree);
6867 printTypeChain(tree->ftype,outfile);
6868 fprintf(outfile,")\n");
6869 ast_print(tree->left,outfile,indent+2);
6870 ast_print(tree->right,outfile,indent+2);
6873 /*------------------------------------------------------------------*/
6874 /*----------------------------*/
6875 /* comparison operators */
6876 /*----------------------------*/
6878 fprintf(outfile,"GT(>) (%p) type (",tree);
6879 printTypeChain(tree->ftype,outfile);
6880 fprintf(outfile,")\n");
6881 ast_print(tree->left,outfile,indent+2);
6882 ast_print(tree->right,outfile,indent+2);
6885 fprintf(outfile,"LT(<) (%p) type (",tree);
6886 printTypeChain(tree->ftype,outfile);
6887 fprintf(outfile,")\n");
6888 ast_print(tree->left,outfile,indent+2);
6889 ast_print(tree->right,outfile,indent+2);
6892 fprintf(outfile,"LE(<=) (%p) type (",tree);
6893 printTypeChain(tree->ftype,outfile);
6894 fprintf(outfile,")\n");
6895 ast_print(tree->left,outfile,indent+2);
6896 ast_print(tree->right,outfile,indent+2);
6899 fprintf(outfile,"GE(>=) (%p) type (",tree);
6900 printTypeChain(tree->ftype,outfile);
6901 fprintf(outfile,")\n");
6902 ast_print(tree->left,outfile,indent+2);
6903 ast_print(tree->right,outfile,indent+2);
6906 fprintf(outfile,"EQ(==) (%p) type (",tree);
6907 printTypeChain(tree->ftype,outfile);
6908 fprintf(outfile,")\n");
6909 ast_print(tree->left,outfile,indent+2);
6910 ast_print(tree->right,outfile,indent+2);
6913 fprintf(outfile,"NE(!=) (%p) type (",tree);
6914 printTypeChain(tree->ftype,outfile);
6915 fprintf(outfile,")\n");
6916 ast_print(tree->left,outfile,indent+2);
6917 ast_print(tree->right,outfile,indent+2);
6918 /*------------------------------------------------------------------*/
6919 /*----------------------------*/
6921 /*----------------------------*/
6922 case SIZEOF: /* evaluate wihout code generation */
6923 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6926 /*------------------------------------------------------------------*/
6927 /*----------------------------*/
6928 /* conditional operator '?' */
6929 /*----------------------------*/
6931 fprintf(outfile,"QUEST(?) (%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);
6939 fprintf(outfile,"COLON(:) (%p) type (",tree);
6940 printTypeChain(tree->ftype,outfile);
6941 fprintf(outfile,")\n");
6942 ast_print(tree->left,outfile,indent+2);
6943 ast_print(tree->right,outfile,indent+2);
6946 /*------------------------------------------------------------------*/
6947 /*----------------------------*/
6948 /* assignment operators */
6949 /*----------------------------*/
6951 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6952 printTypeChain(tree->ftype,outfile);
6953 fprintf(outfile,")\n");
6954 ast_print(tree->left,outfile,indent+2);
6955 ast_print(tree->right,outfile,indent+2);
6958 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6959 printTypeChain(tree->ftype,outfile);
6960 fprintf(outfile,")\n");
6961 ast_print(tree->left,outfile,indent+2);
6962 ast_print(tree->right,outfile,indent+2);
6965 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6966 printTypeChain(tree->ftype,outfile);
6967 fprintf(outfile,")\n");
6968 ast_print(tree->left,outfile,indent+2);
6969 ast_print(tree->right,outfile,indent+2);
6972 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6973 printTypeChain(tree->ftype,outfile);
6974 fprintf(outfile,")\n");
6975 ast_print(tree->left,outfile,indent+2);
6976 ast_print(tree->right,outfile,indent+2);
6979 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6980 printTypeChain(tree->ftype,outfile);
6981 fprintf(outfile,")\n");
6982 ast_print(tree->left,outfile,indent+2);
6983 ast_print(tree->right,outfile,indent+2);
6986 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6987 printTypeChain(tree->ftype,outfile);
6988 fprintf(outfile,")\n");
6989 ast_print(tree->left,outfile,indent+2);
6990 ast_print(tree->right,outfile,indent+2);
6993 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6994 printTypeChain(tree->ftype,outfile);
6995 fprintf(outfile,")\n");
6996 ast_print(tree->left,outfile,indent+2);
6997 ast_print(tree->right,outfile,indent+2);
6999 /*------------------------------------------------------------------*/
7000 /*----------------------------*/
7002 /*----------------------------*/
7004 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
7005 printTypeChain(tree->ftype,outfile);
7006 fprintf(outfile,")\n");
7007 ast_print(tree->left,outfile,indent+2);
7008 ast_print(tree->right,outfile,indent+2);
7010 /*------------------------------------------------------------------*/
7011 /*----------------------------*/
7013 /*----------------------------*/
7015 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
7016 printTypeChain(tree->ftype,outfile);
7017 fprintf(outfile,")\n");
7018 ast_print(tree->left,outfile,indent+2);
7019 ast_print(tree->right,outfile,indent+2);
7021 /*------------------------------------------------------------------*/
7022 /*----------------------------*/
7023 /* straight assignemnt */
7024 /*----------------------------*/
7026 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
7027 printTypeChain(tree->ftype,outfile);
7028 fprintf(outfile,")\n");
7029 ast_print(tree->left,outfile,indent+2);
7030 ast_print(tree->right,outfile,indent+2);
7032 /*------------------------------------------------------------------*/
7033 /*----------------------------*/
7034 /* comma operator */
7035 /*----------------------------*/
7037 fprintf(outfile,"COMMA(,) (%p) type (",tree);
7038 printTypeChain(tree->ftype,outfile);
7039 fprintf(outfile,")\n");
7040 ast_print(tree->left,outfile,indent+2);
7041 ast_print(tree->right,outfile,indent+2);
7043 /*------------------------------------------------------------------*/
7044 /*----------------------------*/
7046 /*----------------------------*/
7049 fprintf(outfile,"CALL (%p) type (",tree);
7050 printTypeChain(tree->ftype,outfile);
7051 fprintf(outfile,")\n");
7052 ast_print(tree->left,outfile,indent+2);
7053 ast_print(tree->right,outfile,indent+2);
7056 fprintf(outfile,"PARMS\n");
7057 ast_print(tree->left,outfile,indent+2);
7058 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
7059 ast_print(tree->right,outfile,indent+2);
7062 /*------------------------------------------------------------------*/
7063 /*----------------------------*/
7064 /* return statement */
7065 /*----------------------------*/
7067 fprintf(outfile,"RETURN (%p) type (",tree);
7069 printTypeChain(tree->right->ftype,outfile);
7071 fprintf(outfile,")\n");
7072 ast_print(tree->right,outfile,indent+2);
7074 /*------------------------------------------------------------------*/
7075 /*----------------------------*/
7076 /* label statement */
7077 /*----------------------------*/
7079 fprintf(outfile,"LABEL (%p)\n",tree);
7080 ast_print(tree->left,outfile,indent+2);
7081 ast_print(tree->right,outfile,indent);
7083 /*------------------------------------------------------------------*/
7084 /*----------------------------*/
7085 /* switch statement */
7086 /*----------------------------*/
7090 fprintf(outfile,"SWITCH (%p) ",tree);
7091 ast_print(tree->left,outfile,0);
7092 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
7093 INDENT(indent+2,outfile);
7094 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
7095 (int) floatFromVal(val),
7096 tree->values.switchVals.swNum,
7097 (int) floatFromVal(val));
7099 ast_print(tree->right,outfile,indent);
7102 /*------------------------------------------------------------------*/
7103 /*----------------------------*/
7105 /*----------------------------*/
7107 fprintf(outfile,"IF (%p) \n",tree);
7108 ast_print(tree->left,outfile,indent+2);
7109 if (tree->trueLabel) {
7110 INDENT(indent+2,outfile);
7111 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
7113 if (tree->falseLabel) {
7114 INDENT(indent+2,outfile);
7115 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
7117 ast_print(tree->right,outfile,indent+2);
7119 /*----------------------------*/
7120 /* goto Statement */
7121 /*----------------------------*/
7123 fprintf(outfile,"GOTO (%p) \n",tree);
7124 ast_print(tree->left,outfile,indent+2);
7125 fprintf(outfile,"\n");
7127 /*------------------------------------------------------------------*/
7128 /*----------------------------*/
7130 /*----------------------------*/
7132 fprintf(outfile,"FOR (%p) \n",tree);
7133 if (AST_FOR( tree, initExpr)) {
7134 INDENT(indent+2,outfile);
7135 fprintf(outfile,"INIT EXPR ");
7136 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
7138 if (AST_FOR( tree, condExpr)) {
7139 INDENT(indent+2,outfile);
7140 fprintf(outfile,"COND EXPR ");
7141 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
7143 if (AST_FOR( tree, loopExpr)) {
7144 INDENT(indent+2,outfile);
7145 fprintf(outfile,"LOOP EXPR ");
7146 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
7148 fprintf(outfile,"FOR LOOP BODY \n");
7149 ast_print(tree->left,outfile,indent+2);
7152 fprintf(outfile,"CRITICAL (%p) \n",tree);
7153 ast_print(tree->left,outfile,indent+2);
7161 ast_print(t,stdout,0);
7164 /*-----------------------------------------------------------------*/
7165 /* astErrors : returns non-zero if errors present in tree */
7166 /*-----------------------------------------------------------------*/
7167 int astErrors(ast *t)
7176 if (t->type == EX_VALUE
7177 && t->opval.val->sym
7178 && t->opval.val->sym->undefined)
7181 errors += astErrors(t->left);
7182 errors += astErrors(t->right);