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;
2194 return RESULT_TYPE_INT;
2195 return RESULT_TYPE_OTHER;
2198 /*-----------------------------------------------------------------*/
2199 /* addCast - adds casts to a type specified by RESULT_TYPE */
2200 /*-----------------------------------------------------------------*/
2202 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2205 bool upCasted = FALSE;
2209 case RESULT_TYPE_NONE:
2210 /* if thing smaller than int must be promoted to int */
2212 getSize (tree->etype) >= INTSIZE)
2213 /* promotion not necessary or already an int */
2215 /* char and bits: promote to int */
2216 newLink = newIntLink();
2219 case RESULT_TYPE_BIT:
2221 /* already an int */
2222 bitsForType (tree->etype) >= 16 ||
2223 /* bit to bit operation: don't promote, the code generators
2224 hopefully know everything about promotion rules */
2225 bitsForType (tree->etype) == 1)
2227 newLink = newIntLink();
2230 case RESULT_TYPE_CHAR:
2231 if (IS_CHAR (tree->etype) ||
2232 IS_FLOAT(tree->etype) ||
2233 IS_FIXED(tree->etype))
2235 newLink = newCharLink();
2237 case RESULT_TYPE_INT:
2239 if (getSize (tree->etype) > INTSIZE)
2241 /* warn ("Loosing significant digits"); */
2245 /* char: promote to int */
2247 getSize (tree->etype) >= INTSIZE)
2249 newLink = newIntLink();
2252 case RESULT_TYPE_IFX:
2253 case RESULT_TYPE_OTHER:
2255 /* return type is ifx, long, float: promote char to int */
2256 getSize (tree->etype) >= INTSIZE)
2258 newLink = newIntLink();
2264 tree->decorated = 0;
2265 tree = newNode (CAST, newAst_LINK (newLink), tree);
2266 tree->lineno = tree->right->lineno;
2267 /* keep unsigned type during cast to smaller type,
2268 but not when promoting from char to int */
2270 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2271 return decorateType (tree, resultType);
2274 /*-----------------------------------------------------------------*/
2275 /* resultTypePropagate - decides if resultType can be propagated */
2276 /*-----------------------------------------------------------------*/
2278 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2280 switch (tree->opval.op)
2299 return RESULT_TYPE_NONE;
2303 return RESULT_TYPE_IFX;
2305 return RESULT_TYPE_NONE;
2309 /*-----------------------------------------------------------------*/
2310 /* getLeftResultType - gets type from left branch for propagation */
2311 /*-----------------------------------------------------------------*/
2313 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2315 switch (tree->opval.op)
2319 if (IS_PTR (LTYPE (tree)))
2320 return RESULT_TYPE_NONE;
2322 return getResultTypeFromType (LETYPE (tree));
2324 if (IS_PTR (currFunc->type->next))
2325 return RESULT_TYPE_NONE;
2327 return getResultTypeFromType (currFunc->type->next);
2329 if (!IS_ARRAY (LTYPE (tree)))
2331 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2332 return RESULT_TYPE_CHAR;
2339 /*------------------------------------------------------------------*/
2340 /* gatherImplicitVariables: assigns correct type information to */
2341 /* symbols and values created by replaceAstWithTemporary */
2342 /* and adds the symbols to the declarations list of the */
2343 /* innermost block that contains them */
2344 /*------------------------------------------------------------------*/
2346 gatherImplicitVariables (ast * tree, ast * block)
2351 if (tree->type == EX_OP && tree->opval.op == BLOCK)
2353 /* keep track of containing scope */
2356 if (tree->type == EX_OP && tree->opval.op == '=' &&
2357 tree->left->type == EX_VALUE && tree->left->opval.val->sym)
2359 symbol *assignee = tree->left->opval.val->sym;
2361 /* special case for assignment to compiler-generated temporary variable:
2362 compute type of RHS, and set the symbol's type to match */
2363 if (assignee->type == NULL && assignee->infertype) {
2364 ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
2366 if (dtr != tree->right)
2369 assignee->type = copyLinkChain(TTYPE(dtr));
2370 assignee->etype = getSpec(assignee->type);
2371 SPEC_SCLS (assignee->etype) = S_AUTO;
2372 SPEC_OCLS (assignee->etype) = NULL;
2373 SPEC_EXTR (assignee->etype) = 0;
2374 SPEC_STAT (assignee->etype) = 0;
2375 SPEC_VOLATILE (assignee->etype) = 0;
2376 SPEC_ABSA (assignee->etype) = 0;
2378 wassertl(block != NULL, "implicit variable not contained in block");
2379 wassert(assignee->next == NULL);
2380 if (block != NULL) {
2381 symbol **decl = &(block->values.sym);
2384 wassert(*decl != assignee); /* should not already be in list */
2385 decl = &( (*decl)->next );
2392 if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) &&
2393 tree->opval.val->type == NULL &&
2394 tree->opval.val->sym &&
2395 tree->opval.val->sym->infertype)
2397 /* fixup type of value for compiler-inferred temporary var */
2398 tree->opval.val->type = tree->opval.val->sym->type;
2399 tree->opval.val->etype = tree->opval.val->sym->etype;
2402 gatherImplicitVariables(tree->left, block);
2403 gatherImplicitVariables(tree->right, block);
2406 /*--------------------------------------------------------------------*/
2407 /* decorateType - compute type for this tree, also does type checking.*/
2408 /* This is done bottom up, since type has to flow upwards. */
2409 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2410 /* result is a char and the operand(s) are int's. */
2411 /* It also does constant folding, and parameter checking. */
2412 /*--------------------------------------------------------------------*/
2414 decorateType (ast * tree, RESULT_TYPE resultType)
2418 RESULT_TYPE resultTypeProp;
2423 /* if already has type then do nothing */
2424 if (tree->decorated)
2427 tree->decorated = 1;
2430 /* print the line */
2431 /* if not block & function */
2432 if (tree->type == EX_OP &&
2433 (tree->opval.op != FUNCTION &&
2434 tree->opval.op != BLOCK &&
2435 tree->opval.op != NULLOP))
2437 filename = tree->filename;
2438 lineno = tree->lineno;
2442 /* if any child is an error | this one is an error do nothing */
2443 if (tree->isError ||
2444 (tree->left && tree->left->isError) ||
2445 (tree->right && tree->right->isError))
2448 /*------------------------------------------------------------------*/
2449 /*----------------------------*/
2450 /* leaf has been reached */
2451 /*----------------------------*/
2452 lineno = tree->lineno;
2453 /* if this is of type value */
2454 /* just get the type */
2455 if (tree->type == EX_VALUE)
2458 if (IS_LITERAL (tree->opval.val->etype))
2461 /* if this is a character array then declare it */
2462 if (IS_ARRAY (tree->opval.val->type))
2463 tree->opval.val = stringToSymbol (tree->opval.val);
2465 /* otherwise just copy the type information */
2466 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2470 if (tree->opval.val->sym)
2472 /* if the undefined flag is set then give error message */
2473 if (tree->opval.val->sym->undefined)
2475 werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name);
2477 TTYPE (tree) = TETYPE (tree) =
2478 tree->opval.val->type = tree->opval.val->sym->type =
2479 tree->opval.val->etype = tree->opval.val->sym->etype =
2480 copyLinkChain (INTTYPE);
2482 else if (tree->opval.val->sym->implicit)
2484 /* if implicit i.e. struct/union member then no type */
2485 TTYPE (tree) = TETYPE (tree) = NULL;
2489 /* copy the type from the value into the ast */
2490 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2492 /* and mark the symbol as referenced */
2493 tree->opval.val->sym->isref = 1;
2497 wassert(0); /* unreached: all values are literals or symbols */
2502 /* if type link for the case of cast */
2503 if (tree->type == EX_LINK)
2505 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2513 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2515 if (tree->left && tree->left->type == EX_OPERAND
2516 && (tree->left->opval.op == INC_OP
2517 || tree->left->opval.op == DEC_OP)
2518 && tree->left->left)
2520 tree->left->right = tree->left->left;
2521 tree->left->left = NULL;
2523 if (tree->right && tree->right->type == EX_OPERAND
2524 && (tree->right->opval.op == INC_OP
2525 || tree->right->opval.op == DEC_OP)
2526 && tree->right->left)
2528 tree->right->right = tree->right->left;
2529 tree->right->left = NULL;
2534 /* Before decorating the left branch we've to decide in dependence
2535 upon tree->opval.op, if resultType can be propagated */
2536 resultTypeProp = resultTypePropagate (tree, resultType);
2538 if (tree->opval.op == '?')
2539 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2541 dtl = decorateType (tree->left, resultTypeProp);
2543 /* if an array node, we may need to swap branches */
2544 if (tree->opval.op == '[')
2546 /* determine which is the array & which the index */
2547 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2548 IS_INTEGRAL (LTYPE (tree)))
2550 ast *tempTree = tree->left;
2551 tree->left = tree->right;
2552 tree->right = tempTree;
2556 /* After decorating the left branch there's type information available
2557 in tree->left->?type. If the op is e.g. '=' we extract the type
2558 information from there and propagate it to the right branch. */
2559 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2561 switch (tree->opval.op)
2564 /* delay right side for '?' operator since conditional macro
2565 expansions might rely on this */
2569 /* decorate right side for CALL (parameter list) in processParms();
2570 there is resultType available */
2574 dtr = decorateType (tree->right, resultTypeProp);
2578 /* this is to take care of situations
2579 when the tree gets rewritten */
2580 if (dtl != tree->left)
2582 if (dtr != tree->right)
2584 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2588 /* depending on type of operator do */
2590 switch (tree->opval.op)
2592 /*------------------------------------------------------------------*/
2593 /*----------------------------*/
2595 /*----------------------------*/
2598 /* first check if this is a array or a pointer */
2599 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2601 werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
2602 goto errorTreeReturn;
2605 /* check if the type of the idx */
2606 if (!IS_INTEGRAL (RTYPE (tree)))
2608 werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
2609 goto errorTreeReturn;
2612 /* if the left is an rvalue then error */
2615 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
2616 goto errorTreeReturn;
2619 if (IS_LITERAL (RTYPE (tree)))
2621 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2622 int arraySize = DCL_ELEM (LTYPE (tree));
2623 if (arraySize && arrayIndex >= arraySize)
2625 werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2630 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2631 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2634 /*------------------------------------------------------------------*/
2635 /*----------------------------*/
2637 /*----------------------------*/
2639 /* if this is not a structure */
2640 if (!IS_STRUCT (LTYPE (tree)))
2642 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
2643 goto errorTreeReturn;
2645 TTYPE (tree) = structElemType (LTYPE (tree),
2646 (tree->right->type == EX_VALUE ?
2647 tree->right->opval.val : NULL));
2648 TETYPE (tree) = getSpec (TTYPE (tree));
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2653 /* struct/union pointer */
2654 /*----------------------------*/
2656 /* if not pointer to a structure */
2657 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2659 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
2660 goto errorTreeReturn;
2663 if (!IS_STRUCT (LTYPE (tree)->next))
2665 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
2666 goto errorTreeReturn;
2669 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2670 (tree->right->type == EX_VALUE ?
2671 tree->right->opval.val : NULL));
2672 TETYPE (tree) = getSpec (TTYPE (tree));
2674 /* adjust the storage class */
2675 switch (DCL_TYPE(tree->left->ftype)) {
2677 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2680 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2683 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2686 SPEC_SCLS (TETYPE (tree)) = 0;
2689 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2692 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2695 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2698 SPEC_SCLS (TETYPE (tree)) = 0;
2705 /* This breaks with extern declarations, bitfields, and perhaps other */
2706 /* cases (gcse). Let's leave this optimization disabled for now and */
2707 /* ponder if there's a safe way to do this. -- EEP */
2709 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2710 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2712 /* If defined struct type at addr var
2713 then rewrite (&struct var)->member
2715 and define membertype at (addr+offsetof(struct var,member)) temp
2718 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2719 AST_SYMBOL(tree->right));
2721 sym = newSymbol(genSymName (0), 0);
2722 sym->type = TTYPE (tree);
2723 sym->etype = getSpec(sym->type);
2724 sym->lineDef = tree->lineno;
2727 SPEC_STAT (sym->etype) = 1;
2728 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2730 SPEC_ABSA(sym->etype) = 1;
2731 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2734 AST_VALUE (tree) = symbolVal(sym);
2737 tree->type = EX_VALUE;
2745 /*------------------------------------------------------------------*/
2746 /*----------------------------*/
2747 /* ++/-- operation */
2748 /*----------------------------*/
2752 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2753 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2754 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2755 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2767 /*----------------------------*/
2768 case '&': /* can be unary */
2769 /* if right is NULL then unary operation */
2770 if (tree->right) /* not an unary operation */
2773 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2775 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2776 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2777 printTypeChain (LTYPE (tree), stderr);
2778 fprintf (stderr, ",");
2779 printTypeChain (RTYPE (tree), stderr);
2780 fprintf (stderr, "\n");
2781 goto errorTreeReturn;
2784 /* if they are both literal */
2785 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2787 tree->type = EX_VALUE;
2788 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2789 valFromType (RETYPE (tree)), '&');
2791 tree->right = tree->left = NULL;
2792 TETYPE (tree) = tree->opval.val->etype;
2793 TTYPE (tree) = tree->opval.val->type;
2797 /* see if this is a GETHBIT operation if yes
2800 ast *otree = optimizeGetHbit (tree, resultType);
2803 return decorateType (otree, RESULT_TYPE_NONE);
2806 /* see if this is a GETABIT operation if yes
2809 ast *otree = optimizeGetAbit (tree, resultType);
2812 return decorateType (otree, RESULT_TYPE_NONE);
2815 /* see if this is a GETBYTE operation if yes
2818 ast *otree = optimizeGetByte (tree, resultType);
2821 return decorateType (otree, RESULT_TYPE_NONE);
2824 /* see if this is a GETWORD operation if yes
2827 ast *otree = optimizeGetWord (tree, resultType);
2830 return decorateType (otree, RESULT_TYPE_NONE);
2833 /* if left is a literal exchange left & right */
2834 if (IS_LITERAL (LTYPE (tree)))
2836 ast *tTree = tree->left;
2837 tree->left = tree->right;
2838 tree->right = tTree;
2841 /* if right is a literal and */
2842 /* we can find a 2nd literal in an and-tree then */
2843 /* rearrange the tree */
2844 if (IS_LITERAL (RTYPE (tree)))
2847 ast *litTree = searchLitOp (tree, &parent, "&");
2851 ast *tTree = litTree->left;
2852 litTree->left = tree->right;
2853 tree->right = tTree;
2854 /* both operands in litTree are literal now */
2855 decorateType (parent, resultType);
2859 LRVAL (tree) = RRVAL (tree) = 1;
2861 TTYPE (tree) = computeType (LTYPE (tree),
2865 TETYPE (tree) = getSpec (TTYPE (tree));
2870 /*------------------------------------------------------------------*/
2871 /*----------------------------*/
2873 /*----------------------------*/
2874 p = newLink (DECLARATOR);
2875 /* if bit field then error */
2876 if (IS_BITVAR (tree->left->etype))
2878 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
2879 goto errorTreeReturn;
2882 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2884 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
2885 goto errorTreeReturn;
2888 if (IS_FUNC (LTYPE (tree)))
2890 // this ought to be ignored
2891 return (tree->left);
2894 if (IS_LITERAL(LTYPE(tree)))
2896 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
2897 goto errorTreeReturn;
2902 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
2903 goto errorTreeReturn;
2906 DCL_TYPE (p) = POINTER;
2907 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2908 DCL_TYPE (p) = CPOINTER;
2909 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2910 DCL_TYPE (p) = FPOINTER;
2911 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2912 DCL_TYPE (p) = PPOINTER;
2913 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2914 DCL_TYPE (p) = IPOINTER;
2915 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2916 DCL_TYPE (p) = EEPPOINTER;
2917 else if (SPEC_OCLS(tree->left->etype))
2918 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2920 DCL_TYPE (p) = POINTER;
2922 if (IS_AST_SYM_VALUE (tree->left))
2924 AST_SYMBOL (tree->left)->addrtaken = 1;
2925 AST_SYMBOL (tree->left)->allocreq = 1;
2928 p->next = LTYPE (tree);
2930 TETYPE (tree) = getSpec (TTYPE (tree));
2935 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2936 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2938 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2939 AST_SYMBOL(tree->left->right));
2940 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2941 valueFromLit(element->offset));
2944 tree->type = EX_VALUE;
2945 tree->values.literalFromCast = 1;
2951 /*------------------------------------------------------------------*/
2952 /*----------------------------*/
2954 /*----------------------------*/
2956 /* if the rewrite succeeds then don't go any further */
2958 ast *wtree = optimizeRRCRLC (tree);
2960 return decorateType (wtree, RESULT_TYPE_NONE);
2962 wtree = optimizeSWAP (tree);
2964 return decorateType (wtree, RESULT_TYPE_NONE);
2967 /* if left is a literal exchange left & right */
2968 if (IS_LITERAL (LTYPE (tree)))
2970 ast *tTree = tree->left;
2971 tree->left = tree->right;
2972 tree->right = tTree;
2975 /* if right is a literal and */
2976 /* we can find a 2nd literal in an or-tree then */
2977 /* rearrange the tree */
2978 if (IS_LITERAL (RTYPE (tree)))
2981 ast *litTree = searchLitOp (tree, &parent, "|");
2985 ast *tTree = litTree->left;
2986 litTree->left = tree->right;
2987 tree->right = tTree;
2988 /* both operands in tTree are literal now */
2989 decorateType (parent, resultType);
2994 /*------------------------------------------------------------------*/
2995 /*----------------------------*/
2997 /*----------------------------*/
2999 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3001 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3002 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3003 printTypeChain (LTYPE (tree), stderr);
3004 fprintf (stderr, ",");
3005 printTypeChain (RTYPE (tree), stderr);
3006 fprintf (stderr, "\n");
3007 goto errorTreeReturn;
3010 /* if they are both literal then rewrite the tree */
3011 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3013 tree->type = EX_VALUE;
3014 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3015 valFromType (RETYPE (tree)),
3017 tree->right = tree->left = NULL;
3018 TETYPE (tree) = tree->opval.val->etype;
3019 TTYPE (tree) = tree->opval.val->type;
3023 /* if left is a literal exchange left & right */
3024 if (IS_LITERAL (LTYPE (tree)))
3026 ast *tTree = tree->left;
3027 tree->left = tree->right;
3028 tree->right = tTree;
3031 /* if right is a literal and */
3032 /* we can find a 2nd literal in a xor-tree then */
3033 /* rearrange the tree */
3034 if (IS_LITERAL (RTYPE (tree)) &&
3035 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3038 ast *litTree = searchLitOp (tree, &parent, "^");
3042 ast *tTree = litTree->left;
3043 litTree->left = tree->right;
3044 tree->right = tTree;
3045 /* both operands in litTree are literal now */
3046 decorateType (parent, resultType);
3050 LRVAL (tree) = RRVAL (tree) = 1;
3052 TTYPE (tree) = computeType (LTYPE (tree),
3056 TETYPE (tree) = getSpec (TTYPE (tree));
3060 /*------------------------------------------------------------------*/
3061 /*----------------------------*/
3063 /*----------------------------*/
3065 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3067 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
3068 goto errorTreeReturn;
3070 /* if they are both literal then */
3071 /* rewrite the tree */
3072 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3074 tree->type = EX_VALUE;
3075 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
3076 valFromType (RETYPE (tree)));
3077 tree->right = tree->left = NULL;
3078 TETYPE (tree) = getSpec (TTYPE (tree) =
3079 tree->opval.val->type);
3083 LRVAL (tree) = RRVAL (tree) = 1;
3085 TETYPE (tree) = getSpec (TTYPE (tree) =
3086 computeType (LTYPE (tree),
3091 /* if right is a literal and */
3092 /* left is also a division by a literal then */
3093 /* rearrange the tree */
3094 if (IS_LITERAL (RTYPE (tree))
3095 /* avoid infinite loop */
3096 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
3099 ast *litTree = searchLitOp (tree, &parent, "/");
3102 if (IS_LITERAL (RTYPE (litTree)))
3106 litTree->right = newNode ('*',
3108 copyAst (tree->right));
3109 litTree->right->lineno = tree->lineno;
3111 tree->right->opval.val = constVal ("1");
3112 decorateType (parent, resultType);
3116 /* litTree->left is literal: no gcse possible.
3117 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3118 this would cause an infinit loop. */
3119 parent->decorated = 1;
3120 decorateType (litTree, resultType);
3127 /*------------------------------------------------------------------*/
3128 /*----------------------------*/
3130 /*----------------------------*/
3132 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3134 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3135 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3136 printTypeChain (LTYPE (tree), stderr);
3137 fprintf (stderr, ",");
3138 printTypeChain (RTYPE (tree), stderr);
3139 fprintf (stderr, "\n");
3140 goto errorTreeReturn;
3142 /* if they are both literal then */
3143 /* rewrite the tree */
3144 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3146 tree->type = EX_VALUE;
3147 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3148 valFromType (RETYPE (tree)));
3149 tree->right = tree->left = NULL;
3150 TETYPE (tree) = getSpec (TTYPE (tree) =
3151 tree->opval.val->type);
3154 LRVAL (tree) = RRVAL (tree) = 1;
3155 TETYPE (tree) = getSpec (TTYPE (tree) =
3156 computeType (LTYPE (tree),
3162 /*------------------------------------------------------------------*/
3163 /*----------------------------*/
3164 /* address dereference */
3165 /*----------------------------*/
3166 case '*': /* can be unary : if right is null then unary operation */
3169 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3171 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
3172 goto errorTreeReturn;
3177 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
3178 goto errorTreeReturn;
3180 if (IS_ADDRESS_OF_OP(tree->left))
3182 /* replace *&obj with obj */
3183 return tree->left->left;
3185 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3186 TETYPE (tree) = getSpec (TTYPE (tree));
3187 /* adjust the storage class */
3188 switch (DCL_TYPE(tree->left->ftype)) {
3190 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3193 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3196 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3199 SPEC_SCLS (TETYPE (tree)) = 0;
3202 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3205 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3208 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3211 SPEC_SCLS (TETYPE (tree)) = 0;
3220 /*------------------------------------------------------------------*/
3221 /*----------------------------*/
3222 /* multiplication */
3223 /*----------------------------*/
3224 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3226 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
3227 goto errorTreeReturn;
3230 /* if they are both literal then */
3231 /* rewrite the tree */
3232 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3234 tree->type = EX_VALUE;
3235 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3236 valFromType (RETYPE (tree)));
3237 tree->right = tree->left = NULL;
3238 TETYPE (tree) = getSpec (TTYPE (tree) =
3239 tree->opval.val->type);
3243 /* if left is a literal exchange left & right */
3244 if (IS_LITERAL (LTYPE (tree)))
3246 ast *tTree = tree->left;
3247 tree->left = tree->right;
3248 tree->right = tTree;
3251 /* if right is a literal and */
3252 /* we can find a 2nd literal in a mul-tree then */
3253 /* rearrange the tree */
3254 if (IS_LITERAL (RTYPE (tree)))
3257 ast *litTree = searchLitOp (tree, &parent, "*");
3261 ast *tTree = litTree->left;
3262 litTree->left = tree->right;
3263 tree->right = tTree;
3264 /* both operands in litTree are literal now */
3265 decorateType (parent, resultType);
3269 LRVAL (tree) = RRVAL (tree) = 1;
3270 tree->left = addCast (tree->left, resultType, FALSE);
3271 tree->right = addCast (tree->right, resultType, FALSE);
3272 TETYPE (tree) = getSpec (TTYPE (tree) =
3273 computeType (LTYPE (tree),
3280 /*------------------------------------------------------------------*/
3281 /*----------------------------*/
3282 /* unary '+' operator */
3283 /*----------------------------*/
3288 if (!IS_ARITHMETIC (LTYPE (tree)))
3290 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
3291 goto errorTreeReturn;
3294 /* if left is a literal then do it */
3295 if (IS_LITERAL (LTYPE (tree)))
3297 tree->type = EX_VALUE;
3298 tree->opval.val = valFromType (LETYPE (tree));
3300 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3304 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3308 /*------------------------------------------------------------------*/
3309 /*----------------------------*/
3311 /*----------------------------*/
3313 /* this is not a unary operation */
3314 /* if both pointers then problem */
3315 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3316 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3318 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
3319 goto errorTreeReturn;
3322 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3323 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3325 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3326 goto errorTreeReturn;
3329 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3330 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3332 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3333 goto errorTreeReturn;
3335 /* if they are both literal then */
3336 /* rewrite the tree */
3337 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3339 tree->type = EX_VALUE;
3340 tree->left = addCast (tree->left, resultType, TRUE);
3341 tree->right = addCast (tree->right, resultType, TRUE);
3342 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3343 valFromType (RETYPE (tree)));
3344 tree->right = tree->left = NULL;
3345 TETYPE (tree) = getSpec (TTYPE (tree) =
3346 tree->opval.val->type);
3350 /* if the right is a pointer or left is a literal
3351 xchange left & right */
3352 if (IS_ARRAY (RTYPE (tree)) ||
3353 IS_PTR (RTYPE (tree)) ||
3354 IS_LITERAL (LTYPE (tree)))
3356 ast *tTree = tree->left;
3357 tree->left = tree->right;
3358 tree->right = tTree;
3361 /* if right is a literal and */
3362 /* left is also an addition/subtraction with a literal then */
3363 /* rearrange the tree */
3364 if (IS_LITERAL (RTYPE (tree)))
3366 ast *litTree, *parent;
3367 litTree = searchLitOp (tree, &parent, "+-");
3370 if (litTree->opval.op == '+')
3374 ast *tTree = litTree->left;
3375 litTree->left = tree->right;
3376 tree->right = tree->left;
3379 else if (litTree->opval.op == '-')
3381 if (IS_LITERAL (RTYPE (litTree)))
3385 ast *tTree = litTree->left;
3386 litTree->left = tree->right;
3387 tree->right = tTree;
3393 ast *tTree = litTree->right;
3394 litTree->right = tree->right;
3395 tree->right = tTree;
3396 litTree->opval.op = '+';
3397 tree->opval.op = '-';
3400 decorateType (parent, resultType);
3404 LRVAL (tree) = RRVAL (tree) = 1;
3405 /* if the left is a pointer */
3406 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3407 TETYPE (tree) = getSpec (TTYPE (tree) =
3411 tree->left = addCast (tree->left, resultType, TRUE);
3412 tree->right = addCast (tree->right, resultType, TRUE);
3413 TETYPE (tree) = getSpec (TTYPE (tree) =
3414 computeType (LTYPE (tree),
3422 /*------------------------------------------------------------------*/
3423 /*----------------------------*/
3425 /*----------------------------*/
3426 case '-': /* can be unary */
3427 /* if right is null then unary */
3431 if (!IS_ARITHMETIC (LTYPE (tree)))
3433 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3434 goto errorTreeReturn;
3437 /* if left is a literal then do it */
3438 if (IS_LITERAL (LTYPE (tree)))
3440 tree->type = EX_VALUE;
3441 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3443 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3446 tree->left = addCast (tree->left, resultType, TRUE);
3447 TETYPE (tree) = getSpec (TTYPE (tree) =
3448 computeType (LTYPE (tree),
3456 /*------------------------------------------------------------------*/
3457 /*----------------------------*/
3459 /*----------------------------*/
3461 if (!(IS_PTR (LTYPE (tree)) ||
3462 IS_ARRAY (LTYPE (tree)) ||
3463 IS_ARITHMETIC (LTYPE (tree))))
3465 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3466 goto errorTreeReturn;
3469 if (!(IS_PTR (RTYPE (tree)) ||
3470 IS_ARRAY (RTYPE (tree)) ||
3471 IS_ARITHMETIC (RTYPE (tree))))
3473 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3474 goto errorTreeReturn;
3477 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3478 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3479 IS_INTEGRAL (RTYPE (tree))))
3481 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3482 goto errorTreeReturn;
3485 /* if they are both literal then */
3486 /* rewrite the tree */
3487 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3489 tree->type = EX_VALUE;
3490 tree->left = addCast (tree->left, resultType, TRUE);
3491 tree->right = addCast (tree->right, resultType, TRUE);
3492 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3493 valFromType (RETYPE (tree)));
3494 tree->right = tree->left = NULL;
3495 TETYPE (tree) = getSpec (TTYPE (tree) =
3496 tree->opval.val->type);
3500 /* if the left & right are equal then zero */
3501 if (isAstEqual (tree->left, tree->right))
3503 tree->type = EX_VALUE;
3504 tree->left = tree->right = NULL;
3505 tree->opval.val = constVal ("0");
3506 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3510 /* if both of them are pointers or arrays then */
3511 /* the result is going to be an integer */
3512 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3513 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3514 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3516 /* if only the left is a pointer */
3517 /* then result is a pointer */
3518 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3519 TETYPE (tree) = getSpec (TTYPE (tree) =
3523 tree->left = addCast (tree->left, resultType, TRUE);
3524 tree->right = addCast (tree->right, resultType, TRUE);
3526 TETYPE (tree) = getSpec (TTYPE (tree) =
3527 computeType (LTYPE (tree),
3533 LRVAL (tree) = RRVAL (tree) = 1;
3535 /* if right is a literal and */
3536 /* left is also an addition/subtraction with a literal then */
3537 /* rearrange the tree */
3538 if (IS_LITERAL (RTYPE (tree))
3539 /* avoid infinite loop */
3540 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
3542 ast *litTree, *litParent;
3543 litTree = searchLitOp (tree, &litParent, "+-");
3546 if (litTree->opval.op == '+')
3550 ast *tTree = litTree->left;
3551 litTree->left = litTree->right;
3552 litTree->right = tree->right;
3553 tree->right = tTree;
3554 tree->opval.op = '+';
3555 litTree->opval.op = '-';
3557 else if (litTree->opval.op == '-')
3559 if (IS_LITERAL (RTYPE (litTree)))
3563 ast *tTree = litTree->left;
3564 litTree->left = tree->right;
3565 tree->right = litParent->left;
3566 litParent->left = tTree;
3567 litTree->opval.op = '+';
3569 tree->decorated = 0;
3570 decorateType (tree, resultType);
3576 ast *tTree = litTree->right;
3577 litTree->right = tree->right;
3578 tree->right = tTree;
3581 decorateType (litParent, resultType);
3586 /*------------------------------------------------------------------*/
3587 /*----------------------------*/
3589 /*----------------------------*/
3591 /* can be only integral type */
3592 if (!IS_INTEGRAL (LTYPE (tree)))
3594 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3595 goto errorTreeReturn;
3598 /* if left is a literal then do it */
3599 if (IS_LITERAL (LTYPE (tree)))
3601 tree->type = EX_VALUE;
3602 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3604 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3605 return addCast (tree, resultType, TRUE);
3608 if (resultType == RESULT_TYPE_BIT &&
3609 IS_UNSIGNED (tree->left->etype) &&
3610 getSize (tree->left->etype) < INTSIZE)
3612 /* promotion rules are responsible for this strange result:
3613 bit -> int -> ~int -> bit
3614 uchar -> int -> ~int -> bit
3616 werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
3618 /* optimize bit-result, even if we optimize a buggy source */
3619 tree->type = EX_VALUE;
3620 tree->opval.val = constVal ("1");
3623 tree->left = addCast (tree->left, resultType, TRUE);
3625 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3628 /*------------------------------------------------------------------*/
3629 /*----------------------------*/
3631 /*----------------------------*/
3633 /* can be pointer */
3634 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3635 !IS_PTR (LTYPE (tree)) &&
3636 !IS_ARRAY (LTYPE (tree)))
3638 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3639 goto errorTreeReturn;
3642 /* if left is another '!' */
3643 if (tree->left->opval.op == '!')
3645 /* remove double '!!X' by 'X ? 1 : 0' */
3646 tree->opval.op = '?';
3647 tree->left = tree->left->left;
3648 tree->right = newNode (':',
3649 newAst_VALUE (constVal ("1")),
3650 newAst_VALUE (constVal ("0")));
3651 tree->right->lineno = tree->lineno;
3652 tree->decorated = 0;
3653 return decorateType (tree, resultType);
3656 /* if left is a literal then do it */
3657 if (IS_LITERAL (LTYPE (tree)))
3659 tree->type = EX_VALUE;
3660 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3662 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3666 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3669 /*------------------------------------------------------------------*/
3670 /*----------------------------*/
3672 /*----------------------------*/
3676 TTYPE (tree) = LTYPE (tree);
3677 TETYPE (tree) = LETYPE (tree);
3682 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3686 TTYPE (tree) = TETYPE (tree) = newCharLink();
3690 TTYPE (tree) = TETYPE (tree) = newIntLink();
3695 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3697 werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
3698 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3699 printTypeChain (LTYPE (tree), stderr);
3700 fprintf (stderr, ",");
3701 printTypeChain (RTYPE (tree), stderr);
3702 fprintf (stderr, "\n");
3703 goto errorTreeReturn;
3706 /* make smaller type only if it's a LEFT_OP */
3707 if (tree->opval.op == LEFT_OP)
3708 tree->left = addCast (tree->left, resultType, TRUE);
3710 /* if they are both literal then */
3711 /* rewrite the tree */
3712 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3714 tree->type = EX_VALUE;
3715 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3716 valFromType (RETYPE (tree)),
3717 (tree->opval.op == LEFT_OP ? 1 : 0));
3718 tree->right = tree->left = NULL;
3719 TETYPE (tree) = getSpec (TTYPE (tree) =
3720 tree->opval.val->type);
3724 /* see if this is a GETBYTE operation if yes
3727 ast *otree = optimizeGetByte (tree, resultType);
3730 return decorateType (otree, RESULT_TYPE_NONE);
3733 /* see if this is a GETWORD operation if yes
3736 ast *otree = optimizeGetWord (tree, resultType);
3739 return decorateType (otree, RESULT_TYPE_NONE);
3742 LRVAL (tree) = RRVAL (tree) = 1;
3743 if (tree->opval.op == LEFT_OP)
3745 TETYPE (tree) = getSpec (TTYPE (tree) =
3746 computeType (LTYPE (tree),
3753 /* no promotion necessary */
3754 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3755 if (IS_LITERAL (TTYPE (tree)))
3756 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3759 /* if only the right side is a literal & we are
3760 shifting more than size of the left operand then zero */
3761 if (IS_LITERAL (RTYPE (tree)) &&
3762 ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
3763 (getSize (TETYPE (tree)) * 8))
3765 if (tree->opval.op==LEFT_OP ||
3766 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3768 werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
3769 (tree->opval.op == LEFT_OP ? "left" : "right"));
3770 tree->type = EX_VALUE;
3771 tree->left = tree->right = NULL;
3772 tree->opval.val = constVal ("0");
3773 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3780 /*------------------------------------------------------------------*/
3781 /*----------------------------*/
3783 /*----------------------------*/
3784 case CAST: /* change the type */
3785 /* cannot cast to an aggregate type */
3786 if (IS_AGGREGATE (LTYPE (tree)))
3788 werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
3789 goto errorTreeReturn;
3792 /* make sure the type is complete and sane */
3793 changePointer(LTYPE(tree));
3794 checkTypeSanity(LETYPE(tree), "(cast)");
3796 /* if 'from' and 'to' are the same remove the superfluous cast, */
3797 /* this helps other optimizations */
3798 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3803 /* If code memory is read only, then pointers to code memory */
3804 /* implicitly point to constants -- make this explicit */
3806 sym_link *t = LTYPE(tree);
3807 while (t && t->next)
3809 if (IS_CODEPTR(t) && port->mem.code_ro)
3811 if (IS_SPEC(t->next))
3812 SPEC_CONST (t->next) = 1;
3814 DCL_PTR_CONST (t->next) = 1;
3821 /* if the right is a literal replace the tree */
3822 if (IS_LITERAL (RETYPE (tree))) {
3823 if (!IS_PTR (LTYPE (tree))) {
3824 tree->type = EX_VALUE;
3826 valCastLiteral (LTYPE (tree),
3827 floatFromVal (valFromType (RETYPE (tree))));
3830 TTYPE (tree) = tree->opval.val->type;
3831 tree->values.literalFromCast = 1;
3832 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3833 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3834 sym_link *rest = LTYPE(tree)->next;
3835 werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
3836 TTYPE(tree) = newLink(DECLARATOR);
3837 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3838 TTYPE(tree)->next = rest;
3839 tree->left->opval.lnk = TTYPE(tree);
3842 TTYPE (tree) = LTYPE (tree);
3846 TTYPE (tree) = LTYPE (tree);
3850 #if 0 // this is already checked, now this could be explicit
3851 /* if pointer to struct then check names */
3852 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3853 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3854 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3856 werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3857 SPEC_STRUCT(LETYPE(tree))->tag);
3860 if (IS_ADDRESS_OF_OP(tree->right)
3861 && IS_AST_SYM_VALUE (tree->right->left)
3862 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3864 symbol * sym = AST_SYMBOL (tree->right->left);
3865 unsigned int gptype = 0;
3866 unsigned int addr = SPEC_ADDR (sym->etype);
3868 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
3869 || TARGET_IS_PIC16) )
3871 switch (SPEC_SCLS (sym->etype))
3874 gptype = GPTYPE_CODE;
3877 gptype = GPTYPE_FAR;
3881 gptype = GPTYPE_NEAR;
3884 gptype = GPTYPE_XSTACK;
3889 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3890 gptype = GPTYPE_NEAR;
3892 addr |= gptype << (8*(GPTRSIZE - 1));
3895 tree->type = EX_VALUE;
3897 valCastLiteral (LTYPE (tree), addr);
3898 TTYPE (tree) = tree->opval.val->type;
3899 TETYPE (tree) = getSpec (TTYPE (tree));
3902 tree->values.literalFromCast = 1;
3906 /* handle offsetof macro: */
3907 /* #define offsetof(TYPE, MEMBER) \ */
3908 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3909 if (IS_ADDRESS_OF_OP(tree->right)
3910 && IS_AST_OP (tree->right->left)
3911 && tree->right->left->opval.op == PTR_OP
3912 && IS_AST_OP (tree->right->left->left)
3913 && tree->right->left->left->opval.op == CAST
3914 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3916 symbol *element = getStructElement (
3917 SPEC_STRUCT (LETYPE(tree->right->left)),
3918 AST_SYMBOL(tree->right->left->right)
3922 tree->type = EX_VALUE;
3923 tree->opval.val = valCastLiteral (
3926 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3929 TTYPE (tree) = tree->opval.val->type;
3930 TETYPE (tree) = getSpec (TTYPE (tree));
3937 /* if the right is a literal replace the tree */
3938 if (IS_LITERAL (RETYPE (tree))) {
3940 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3941 /* rewrite (type *)litaddr
3943 and define type at litaddr temp
3944 (but only if type's storage class is not generic)
3946 ast *newTree = newNode ('&', NULL, NULL);
3949 TTYPE (newTree) = LTYPE (tree);
3950 TETYPE (newTree) = getSpec(LTYPE (tree));
3952 /* define a global symbol at the casted address*/
3953 sym = newSymbol(genSymName (0), 0);
3954 sym->type = LTYPE (tree)->next;
3956 sym->type = newLink (V_VOID);
3957 sym->etype = getSpec(sym->type);
3958 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3959 sym->lineDef = tree->lineno;
3962 SPEC_STAT (sym->etype) = 1;
3963 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3964 SPEC_ABSA(sym->etype) = 1;
3965 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3968 newTree->left = newAst_VALUE(symbolVal(sym));
3969 newTree->left->lineno = tree->lineno;
3970 LTYPE (newTree) = sym->type;
3971 LETYPE (newTree) = sym->etype;
3972 LLVAL (newTree) = 1;
3973 LRVAL (newTree) = 0;
3974 TLVAL (newTree) = 1;
3978 if (!IS_PTR (LTYPE (tree))) {
3979 tree->type = EX_VALUE;
3981 valCastLiteral (LTYPE (tree),
3982 floatFromVal (valFromType (RTYPE (tree))));
3983 TTYPE (tree) = tree->opval.val->type;
3986 tree->values.literalFromCast = 1;
3987 TETYPE (tree) = getSpec (TTYPE (tree));
3991 TTYPE (tree) = LTYPE (tree);
3995 TETYPE (tree) = getSpec (TTYPE (tree));
3999 /*------------------------------------------------------------------*/
4000 /*----------------------------*/
4001 /* logical &&, || */
4002 /*----------------------------*/
4005 /* each must be arithmetic type or be a pointer */
4006 if (!IS_PTR (LTYPE (tree)) &&
4007 !IS_ARRAY (LTYPE (tree)) &&
4008 !IS_INTEGRAL (LTYPE (tree)))
4010 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4011 goto errorTreeReturn;
4014 if (!IS_PTR (RTYPE (tree)) &&
4015 !IS_ARRAY (RTYPE (tree)) &&
4016 !IS_INTEGRAL (RTYPE (tree)))
4018 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4019 goto errorTreeReturn;
4021 /* if they are both literal then */
4022 /* rewrite the tree */
4023 if (IS_LITERAL (RTYPE (tree)) &&
4024 IS_LITERAL (LTYPE (tree)))
4026 tree->type = EX_VALUE;
4027 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4028 valFromType (RTYPE (tree)),
4030 tree->right = tree->left = NULL;
4031 TETYPE (tree) = getSpec (TTYPE (tree) =
4032 tree->opval.val->type);
4035 LRVAL (tree) = RRVAL (tree) = 1;
4036 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4039 /*------------------------------------------------------------------*/
4040 /*----------------------------*/
4041 /* comparison operators */
4042 /*----------------------------*/
4050 ast *lt = optimizeCompare (tree);
4056 /* if they are pointers they must be castable */
4057 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4059 if (tree->opval.op==EQ_OP &&
4060 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4061 // we cannot cast a gptr to a !gptr: switch the leaves
4062 struct ast *s=tree->left;
4063 tree->left=tree->right;
4066 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4068 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4069 fprintf (stderr, "comparing type ");
4070 printTypeChain (LTYPE (tree), stderr);
4071 fprintf (stderr, "to type ");
4072 printTypeChain (RTYPE (tree), stderr);
4073 fprintf (stderr, "\n");
4074 goto errorTreeReturn;
4077 /* else they should be promotable to one another */
4080 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4081 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4083 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4085 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4086 fprintf (stderr, "comparing type ");
4087 printTypeChain (LTYPE (tree), stderr);
4088 fprintf (stderr, "to type ");
4089 printTypeChain (RTYPE (tree), stderr);
4090 fprintf (stderr, "\n");
4091 goto errorTreeReturn;
4096 CCR_RESULT ccr_result = CCR_OK;
4098 /* if left is integral and right is literal
4099 then check constant range */
4100 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4101 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4102 tree->opval.op, FALSE);
4103 if (ccr_result == CCR_OK &&
4104 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4105 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4106 tree->opval.op, TRUE);
4109 case CCR_ALWAYS_TRUE:
4110 case CCR_ALWAYS_FALSE:
4111 if (!options.lessPedantic)
4112 werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
4113 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4114 return decorateType (newAst_VALUE (constVal (
4115 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4123 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4124 if (tree->opval.op == '>' &&
4125 SPEC_USIGN(LETYPE(tree)) &&
4126 IS_LITERAL(RTYPE(tree)) &&
4127 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
4129 if (resultType == RESULT_TYPE_IFX)
4131 /* the parent is an ifx: */
4132 /* if (unsigned value) */
4136 /* (unsigned value) ? 1 : 0 */
4137 tree->opval.op = '?';
4138 tree->right = newNode (':',
4139 newAst_VALUE (constVal ("1")),
4140 tree->right); /* val 0 */
4141 tree->right->lineno = tree->lineno;
4142 tree->right->left->lineno = tree->lineno;
4143 tree->decorated = 0;
4144 return decorateType (tree, resultType);
4147 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4148 if (IS_LITERAL(RTYPE(tree)) &&
4149 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4150 tree->opval.op == EQ_OP &&
4151 resultType == RESULT_TYPE_IFX)
4153 tree->opval.op = '!';
4155 tree->decorated = 0;
4156 return decorateType (tree, resultType);
4159 /* if they are both literal then */
4160 /* rewrite the tree */
4161 if (IS_LITERAL (RTYPE (tree)) &&
4162 IS_LITERAL (LTYPE (tree)))
4164 tree->type = EX_VALUE;
4165 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4166 valFromType (RETYPE (tree)),
4168 tree->right = tree->left = NULL;
4169 TETYPE (tree) = getSpec (TTYPE (tree) =
4170 tree->opval.val->type);
4174 /* if one is 'signed char ' and the other one is 'unsigned char' */
4175 /* it's necessary to promote to int */
4176 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4177 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4179 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4180 if it's possible to use a 'signed char' */
4182 /* is left a 'unsigned char'? */
4183 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4184 /* the value range of a 'unsigned char' is 0...255;
4185 if the actual value is < 128 it can be changed to signed */
4186 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
4188 /* now we've got 2 'signed char'! */
4189 SPEC_USIGN (RETYPE (tree)) = 0;
4191 /* same test for the left operand: */
4192 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4193 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4195 SPEC_USIGN (LETYPE (tree)) = 0;
4199 werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
4200 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4201 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4205 LRVAL (tree) = RRVAL (tree) = 1;
4206 TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4208 /* condition transformations */
4210 unsigned transformedOp = 0;
4212 switch (tree->opval.op)
4214 case '<': /* transform (a < b) to !(a >= b) */
4216 transformedOp = GE_OP;
4218 case '>': /* transform (a > b) to !(a <= b) */
4220 transformedOp = LE_OP;
4222 case LE_OP: /* transform (a <= b) to !(a > b) */
4224 transformedOp = '>';
4226 case GE_OP: /* transform (a >= b) to !(a < b) */
4228 transformedOp = '<';
4230 case NE_OP: /* transform (a != b) to !(a == b) */
4232 transformedOp = EQ_OP;
4234 case EQ_OP: /* transform (a == b) to !(a != b) */
4236 transformedOp = NE_OP;
4243 tree->opval.op = transformedOp;
4244 tree->decorated = 0;
4245 tree = newNode ('!', tree, NULL);
4246 tree->lineno = tree->left->lineno;
4247 return decorateType (tree, resultType);
4253 /*------------------------------------------------------------------*/
4254 /*----------------------------*/
4256 /*----------------------------*/
4257 case SIZEOF: /* evaluate wihout code generation */
4258 /* change the type to a integer */
4260 int size = getSize (tree->right->ftype);
4261 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4262 if (!size && !IS_VOID(tree->right->ftype))
4263 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4265 tree->type = EX_VALUE;
4266 tree->opval.val = constVal (buffer);
4267 tree->right = tree->left = NULL;
4268 TETYPE (tree) = getSpec (TTYPE (tree) =
4269 tree->opval.val->type);
4272 /*------------------------------------------------------------------*/
4273 /*----------------------------*/
4275 /*----------------------------*/
4277 /* return typeof enum value */
4278 tree->type = EX_VALUE;
4281 if (IS_SPEC(tree->right->ftype)) {
4282 switch (SPEC_NOUN(tree->right->ftype)) {
4284 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4285 else typeofv = TYPEOF_INT;
4288 typeofv = TYPEOF_FLOAT;
4291 typeofv = TYPEOF_FIXED16X16;
4294 typeofv = TYPEOF_CHAR;
4297 typeofv = TYPEOF_VOID;
4300 typeofv = TYPEOF_STRUCT;
4303 typeofv = TYPEOF_BITFIELD;
4306 typeofv = TYPEOF_BIT;
4309 typeofv = TYPEOF_SBIT;
4315 switch (DCL_TYPE(tree->right->ftype)) {
4317 typeofv = TYPEOF_POINTER;
4320 typeofv = TYPEOF_FPOINTER;
4323 typeofv = TYPEOF_CPOINTER;
4326 typeofv = TYPEOF_GPOINTER;
4329 typeofv = TYPEOF_PPOINTER;
4332 typeofv = TYPEOF_IPOINTER;
4335 typeofv = TYPEOF_ARRAY;
4338 typeofv = TYPEOF_FUNCTION;
4344 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4345 tree->opval.val = constVal (buffer);
4346 tree->right = tree->left = NULL;
4347 TETYPE (tree) = getSpec (TTYPE (tree) =
4348 tree->opval.val->type);
4351 /*------------------------------------------------------------------*/
4352 /*----------------------------*/
4353 /* conditional operator '?' */
4354 /*----------------------------*/
4356 /* the type is value of the colon operator (on the right) */
4357 assert (IS_COLON_OP (tree->right));
4358 /* if already known then replace the tree : optimizer will do it
4359 but faster to do it here */
4360 if (IS_LITERAL (LTYPE (tree)))
4362 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4363 return decorateType (tree->right->left, resultTypeProp);
4365 return decorateType (tree->right->right, resultTypeProp);
4369 tree->right = decorateType (tree->right, resultTypeProp);
4370 TTYPE (tree) = RTYPE (tree);
4371 TETYPE (tree) = getSpec (TTYPE (tree));
4376 /* if they don't match we have a problem */
4377 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4378 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4380 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
4381 goto errorTreeReturn;
4384 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4385 resultType, tree->opval.op);
4386 TETYPE (tree) = getSpec (TTYPE (tree));
4390 #if 0 // assignment operators are converted by the parser
4391 /*------------------------------------------------------------------*/
4392 /*----------------------------*/
4393 /* assignment operators */
4394 /*----------------------------*/
4397 /* for these it must be both must be integral */
4398 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4399 !IS_ARITHMETIC (RTYPE (tree)))
4401 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4402 goto errorTreeReturn;
4405 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4407 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4408 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4412 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4413 goto errorTreeReturn;
4424 /* for these it must be both must be integral */
4425 if (!IS_INTEGRAL (LTYPE (tree)) ||
4426 !IS_INTEGRAL (RTYPE (tree)))
4428 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4429 goto errorTreeReturn;
4432 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4434 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4435 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4439 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4440 goto errorTreeReturn;
4446 /*------------------------------------------------------------------*/
4447 /*----------------------------*/
4449 /*----------------------------*/
4451 if (!(IS_PTR (LTYPE (tree)) ||
4452 IS_ARITHMETIC (LTYPE (tree))))
4454 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4455 goto errorTreeReturn;
4458 if (!(IS_PTR (RTYPE (tree)) ||
4459 IS_ARITHMETIC (RTYPE (tree))))
4461 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4462 goto errorTreeReturn;
4465 TETYPE (tree) = getSpec (TTYPE (tree) =
4466 computeType (LTYPE (tree),
4471 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4472 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
4476 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
4477 goto errorTreeReturn;
4483 /*------------------------------------------------------------------*/
4484 /*----------------------------*/
4486 /*----------------------------*/
4488 /* this is not a unary operation */
4489 /* if both pointers then problem */
4490 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4492 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
4493 goto errorTreeReturn;
4496 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4498 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4499 goto errorTreeReturn;
4502 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4504 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4505 goto errorTreeReturn;
4508 TETYPE (tree) = getSpec (TTYPE (tree) =
4509 computeType (LTYPE (tree),
4514 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4515 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
4519 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
4520 goto errorTreeReturn;
4523 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4524 tree->opval.op = '=';
4529 /*------------------------------------------------------------------*/
4530 /*----------------------------*/
4531 /* straight assignemnt */
4532 /*----------------------------*/
4534 /* cannot be an aggregate */
4535 if (IS_AGGREGATE (LTYPE (tree)))
4537 werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
4538 goto errorTreeReturn;
4541 /* they should either match or be castable */
4542 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4544 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
4545 printFromToType(RTYPE(tree),LTYPE(tree));
4548 /* if the left side of the tree is of type void
4549 then report error */
4550 if (IS_VOID (LTYPE (tree)))
4552 werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
4553 printFromToType(RTYPE(tree), LTYPE(tree));
4556 TETYPE (tree) = getSpec (TTYPE (tree) =
4560 if (!tree->initMode ) {
4561 if (IS_CONSTANT(LTYPE(tree)))
4562 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
4566 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
4567 goto errorTreeReturn;
4572 /*------------------------------------------------------------------*/
4573 /*----------------------------*/
4574 /* comma operator */
4575 /*----------------------------*/
4577 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4580 /*------------------------------------------------------------------*/
4581 /*----------------------------*/
4583 /*----------------------------*/
4586 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4587 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4589 if (tree->left->opval.op == '*' && !tree->left->right)
4590 tree->left = tree->left->left;
4593 /* require a function or pointer to function */
4594 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4596 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4597 goto errorTreeReturn;
4600 /* if there are parms, make sure that
4601 parms are decorate / process / reverse only once */
4603 !tree->right->decorated)
4608 if (IS_FUNCPTR (LTYPE (tree)))
4610 functype = LTYPE (tree)->next;
4611 processFuncPtrArgs (functype);
4614 functype = LTYPE (tree);
4616 if (processParms (tree->left, FUNC_ARGS(functype),
4617 &tree->right, &parmNumber, TRUE))
4619 goto errorTreeReturn;
4622 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4623 !IFFUNC_ISBUILTIN(functype))
4625 reverseParms (tree->right);
4628 TTYPE (tree) = functype->next;
4629 TETYPE (tree) = getSpec (TTYPE (tree));
4633 /*------------------------------------------------------------------*/
4634 /*----------------------------*/
4635 /* return statement */
4636 /*----------------------------*/
4641 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4643 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4644 printFromToType (RTYPE(tree), currFunc->type->next);
4645 goto errorTreeReturn;
4648 if (IS_VOID (currFunc->type->next)
4650 !IS_VOID (RTYPE (tree)))
4652 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4653 goto errorTreeReturn;
4656 /* if there is going to be a casting required then add it */
4657 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4660 decorateType (newNode (CAST,
4661 newAst_LINK (copyLinkChain (currFunc->type->next)),
4671 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4673 werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
4674 goto errorTreeReturn;
4677 TTYPE (tree) = TETYPE (tree) = NULL;
4680 /*------------------------------------------------------------------*/
4681 /*----------------------------*/
4682 /* switch statement */
4683 /*----------------------------*/
4685 /* the switch value must be an integer */
4686 if (!IS_INTEGRAL (LTYPE (tree)))
4688 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4689 goto errorTreeReturn;
4692 TTYPE (tree) = TETYPE (tree) = NULL;
4695 /*------------------------------------------------------------------*/
4696 /*----------------------------*/
4698 /*----------------------------*/
4700 tree->left = backPatchLabels (tree->left,
4703 TTYPE (tree) = TETYPE (tree) = NULL;
4706 /*------------------------------------------------------------------*/
4707 /*----------------------------*/
4709 /*----------------------------*/
4712 AST_FOR (tree, initExpr) = decorateType (
4713 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4714 AST_FOR (tree, condExpr) = decorateType (
4715 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4716 AST_FOR (tree, loopExpr) = decorateType (
4717 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4719 /* if the for loop is reversible then
4720 reverse it otherwise do what we normally
4726 if (isLoopReversible (tree, &sym, &init, &end))
4727 return reverseLoop (tree, sym, init, end);
4729 return decorateType (createFor (AST_FOR (tree, trueLabel),
4730 AST_FOR (tree, continueLabel),
4731 AST_FOR (tree, falseLabel),
4732 AST_FOR (tree, condLabel),
4733 AST_FOR (tree, initExpr),
4734 AST_FOR (tree, condExpr),
4735 AST_FOR (tree, loopExpr),
4736 tree->left), RESULT_TYPE_NONE);
4739 werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
4740 "node PARAM shouldn't be processed here");
4741 /* but in processParams() */
4744 TTYPE (tree) = TETYPE (tree) = NULL;
4748 /* some error found this tree will be killed */
4750 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4751 tree->opval.op = NULLOP;
4757 /*-----------------------------------------------------------------*/
4758 /* sizeofOp - processes size of operation */
4759 /*-----------------------------------------------------------------*/
4761 sizeofOp (sym_link * type)
4766 /* make sure the type is complete and sane */
4767 checkTypeSanity(type, "(sizeof)");
4769 /* get the size and convert it to character */
4770 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4771 if (!size && !IS_VOID(type))
4772 werror (E_SIZEOF_INCOMPLETE_TYPE);
4774 /* now convert into value */
4775 return constVal (buff);
4779 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4780 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4781 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4782 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4783 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4784 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4785 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4787 /*-----------------------------------------------------------------*/
4788 /* backPatchLabels - change and or not operators to flow control */
4789 /*-----------------------------------------------------------------*/
4791 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4797 /* while-loops insert a label between the IFX and the condition,
4798 therefore look behind the label too */
4799 if (tree->opval.op == LABEL &&
4801 IS_ANDORNOT (tree->right))
4803 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4807 if (!(IS_ANDORNOT (tree)))
4810 /* if this an and */
4813 static int localLbl = 0;
4816 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4817 localLabel = newSymbol (buffer, NestLevel);
4819 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4821 /* if left is already a IFX then just change the if true label in that */
4822 if (!IS_IFX (tree->left))
4823 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4825 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4826 /* right is a IFX then just join */
4827 if (IS_IFX (tree->right))
4828 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4830 tree->right = createLabel (localLabel, tree->right);
4831 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4833 return newNode (NULLOP, tree->left, tree->right);
4836 /* if this is an or operation */
4839 static int localLbl = 0;
4842 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4843 localLabel = newSymbol (buffer, NestLevel);
4845 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4847 /* if left is already a IFX then just change the if true label in that */
4848 if (!IS_IFX (tree->left))
4849 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4851 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4852 /* right is a IFX then just join */
4853 if (IS_IFX (tree->right))
4854 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4856 tree->right = createLabel (localLabel, tree->right);
4857 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4859 return newNode (NULLOP, tree->left, tree->right);
4865 /* call with exchanged labels */
4866 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4868 /* if left isn't already a IFX */
4869 if (!IS_IFX (tree->left))
4871 tree->left = newNode (IFX, tree->left, NULL);
4872 tree->left->trueLabel = falseLabel;
4873 tree->left->falseLabel = trueLabel;
4880 tree->trueLabel = trueLabel;
4881 tree->falseLabel = falseLabel;
4888 /*-----------------------------------------------------------------*/
4889 /* createBlock - create expression tree for block */
4890 /*-----------------------------------------------------------------*/
4892 createBlock (symbol * decl, ast * body)
4896 /* if the block has nothing */
4900 ex = newNode (BLOCK, NULL, body);
4901 ex->values.sym = decl;
4908 /*-----------------------------------------------------------------*/
4909 /* createLabel - creates the expression tree for labels */
4910 /*-----------------------------------------------------------------*/
4912 createLabel (symbol * label, ast * stmnt)
4915 char name[SDCC_NAME_MAX + 1];
4918 /* must create fresh symbol if the symbol name */
4919 /* exists in the symbol table, since there can */
4920 /* be a variable with the same name as the labl */
4921 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4922 (csym->level == label->level))
4923 label = newSymbol (label->name, label->level);
4925 /* change the name before putting it in add _ */
4926 SNPRINTF(name, sizeof(name), "%s", label->name);
4928 /* put the label in the LabelSymbol table */
4929 /* but first check if a label of the same */
4931 if ((csym = findSym (LabelTab, NULL, name)))
4932 werror (E_DUPLICATE_LABEL, label->name);
4934 addSym (LabelTab, label, name, label->level, 0, 0);
4938 label->key = labelKey++;
4939 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4945 /*-----------------------------------------------------------------*/
4946 /* createCase - generates the parsetree for a case statement */
4947 /*-----------------------------------------------------------------*/
4949 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4951 char caseLbl[SDCC_NAME_MAX + 1];
4955 /* if the switch statement does not exist */
4956 /* then case is out of context */
4959 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4963 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4964 /* if not a constant then error */
4965 if (!IS_LITERAL (caseVal->ftype))
4967 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4971 /* if not a integer than error */
4972 if (!IS_INTEGRAL (caseVal->ftype))
4974 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4978 /* find the end of the switch values chain */
4979 if (!(val = swStat->values.switchVals.swVals))
4980 swStat->values.switchVals.swVals = caseVal->opval.val;
4983 /* also order the cases according to value */
4985 int cVal = (int) floatFromVal (caseVal->opval.val);
4986 while (val && (int) floatFromVal (val) < cVal)
4992 /* if we reached the end then */
4995 pval->next = caseVal->opval.val;
4997 else if ((int) floatFromVal (val) == cVal)
4999 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5005 /* we found a value greater than */
5006 /* the current value we must add this */
5007 /* before the value */
5008 caseVal->opval.val->next = val;
5010 /* if this was the first in chain */
5011 if (swStat->values.switchVals.swVals == val)
5012 swStat->values.switchVals.swVals =
5015 pval->next = caseVal->opval.val;
5020 /* create the case label */
5021 SNPRINTF(caseLbl, sizeof(caseLbl),
5023 swStat->values.switchVals.swNum,
5024 (int) floatFromVal (caseVal->opval.val));
5026 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5031 /*-----------------------------------------------------------------*/
5032 /* createDefault - creates the parse tree for the default statement */
5033 /*-----------------------------------------------------------------*/
5035 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5037 char defLbl[SDCC_NAME_MAX + 1];
5039 /* if the switch statement does not exist */
5040 /* then case is out of context */
5043 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5047 if (swStat->values.switchVals.swDefault)
5049 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5054 /* turn on the default flag */
5055 swStat->values.switchVals.swDefault = 1;
5057 /* create the label */
5058 SNPRINTF (defLbl, sizeof(defLbl),
5059 "_default_%d", swStat->values.switchVals.swNum);
5060 return createLabel (newSymbol (defLbl, 0), stmnt);
5063 /*-----------------------------------------------------------------*/
5064 /* createIf - creates the parsetree for the if statement */
5065 /*-----------------------------------------------------------------*/
5067 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5069 static int Lblnum = 0;
5071 symbol *ifTrue, *ifFalse, *ifEnd;
5073 /* if neither exists */
5074 if (!elseBody && !ifBody) {
5075 // if there are no side effects (i++, j() etc)
5076 if (!hasSEFcalls(condAst)) {
5081 /* create the labels */
5082 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5083 ifFalse = newSymbol (buffer, NestLevel);
5084 /* if no else body then end == false */
5089 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5090 ifEnd = newSymbol (buffer, NestLevel);
5093 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5094 ifTrue = newSymbol (buffer, NestLevel);
5098 /* attach the ifTrue label to the top of it body */
5099 ifBody = createLabel (ifTrue, ifBody);
5100 /* attach a goto end to the ifBody if else is present */
5103 ifBody = newNode (NULLOP, ifBody,
5105 newAst_VALUE (symbolVal (ifEnd)),
5107 /* put the elseLabel on the else body */
5108 elseBody = createLabel (ifFalse, elseBody);
5109 /* out the end at the end of the body */
5110 elseBody = newNode (NULLOP,
5112 createLabel (ifEnd, NULL));
5116 ifBody = newNode (NULLOP, ifBody,
5117 createLabel (ifFalse, NULL));
5119 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5120 if (IS_IFX (condAst))
5123 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5125 return newNode (NULLOP, ifTree,
5126 newNode (NULLOP, ifBody, elseBody));
5130 /*-----------------------------------------------------------------*/
5131 /* createDo - creates parse tree for do */
5134 /* _docontinue_n: */
5135 /* condition_expression +-> trueLabel -> _dobody_n */
5137 /* +-> falseLabel-> _dobreak_n */
5139 /*-----------------------------------------------------------------*/
5141 createDo (symbol * trueLabel, symbol * continueLabel,
5142 symbol * falseLabel, ast * condAst, ast * doBody)
5147 /* if the body does not exist then it is simple */
5150 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5151 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5152 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5153 doTree->trueLabel = continueLabel;
5154 doTree->falseLabel = NULL;
5156 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5160 /* otherwise we have a body */
5161 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5163 /* attach the body label to the top */
5164 doBody = createLabel (trueLabel, doBody);
5165 /* attach the continue label to end of body */
5166 doBody = newNode (NULLOP, doBody,
5167 createLabel (continueLabel, NULL));
5169 /* now put the break label at the end */
5170 if (IS_IFX (condAst))
5173 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5175 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5177 /* putting it together */
5178 return newNode (NULLOP, doBody, doTree);
5181 /*-----------------------------------------------------------------*/
5182 /* createFor - creates parse tree for 'for' statement */
5185 /* condExpr +-> trueLabel -> _forbody_n */
5187 /* +-> falseLabel-> _forbreak_n */
5190 /* _forcontinue_n: */
5192 /* goto _forcond_n ; */
5194 /*-----------------------------------------------------------------*/
5196 createFor (symbol * trueLabel, symbol * continueLabel,
5197 symbol * falseLabel, symbol * condLabel,
5198 ast * initExpr, ast * condExpr, ast * loopExpr,
5203 /* if loopexpression not present then we can generate it */
5204 /* the same way as a while */
5206 return newNode (NULLOP, initExpr,
5207 createWhile (trueLabel, continueLabel,
5208 falseLabel, condExpr, forBody));
5209 /* vanilla for statement */
5210 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5212 if (condExpr && !IS_IFX (condExpr))
5213 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5216 /* attach condition label to condition */
5217 condExpr = createLabel (condLabel, condExpr);
5219 /* attach body label to body */
5220 forBody = createLabel (trueLabel, forBody);
5222 /* attach continue to forLoop expression & attach */
5223 /* goto the forcond @ and of loopExpression */
5224 loopExpr = createLabel (continueLabel,
5228 newAst_VALUE (symbolVal (condLabel)),
5230 /* now start putting them together */
5231 forTree = newNode (NULLOP, initExpr, condExpr);
5232 forTree = newNode (NULLOP, forTree, forBody);
5233 forTree = newNode (NULLOP, forTree, loopExpr);
5234 /* finally add the break label */
5235 forTree = newNode (NULLOP, forTree,
5236 createLabel (falseLabel, NULL));
5240 /*-----------------------------------------------------------------*/
5241 /* createWhile - creates parse tree for while statement */
5242 /* the while statement will be created as follows */
5244 /* _while_continue_n: */
5245 /* condition_expression +-> trueLabel -> _while_boby_n */
5247 /* +-> falseLabel -> _while_break_n */
5248 /* _while_body_n: */
5250 /* goto _while_continue_n */
5251 /* _while_break_n: */
5252 /*-----------------------------------------------------------------*/
5254 createWhile (symbol * trueLabel, symbol * continueLabel,
5255 symbol * falseLabel, ast * condExpr, ast * whileBody)
5259 /* put the continue label */
5260 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5261 condExpr = createLabel (continueLabel, condExpr);
5262 condExpr->lineno = 0;
5264 /* put the body label in front of the body */
5265 whileBody = createLabel (trueLabel, whileBody);
5266 whileBody->lineno = 0;
5267 /* put a jump to continue at the end of the body */
5268 /* and put break label at the end of the body */
5269 whileBody = newNode (NULLOP,
5272 newAst_VALUE (symbolVal (continueLabel)),
5273 createLabel (falseLabel, NULL)));
5275 /* put it all together */
5276 if (IS_IFX (condExpr))
5277 whileTree = condExpr;
5280 whileTree = newNode (IFX, condExpr, NULL);
5281 /* put the true & false labels in place */
5282 whileTree->trueLabel = trueLabel;
5283 whileTree->falseLabel = falseLabel;
5286 return newNode (NULLOP, whileTree, whileBody);
5289 /*-----------------------------------------------------------------*/
5290 /* isShiftRightLitVal _BitAndLitVal - helper function */
5291 /*-----------------------------------------------------------------*/
5293 isShiftRightLitVal_BitAndLitVal (ast * tree)
5295 /* if this is not a bit and */
5296 if (!IS_BITAND (tree))
5299 /* will look for tree of the form
5300 ( expr >> litval2) & litval1 */
5301 if (!IS_AST_LIT_VALUE (tree->right))
5304 if (!IS_RIGHT_OP (tree->left))
5307 if (!IS_AST_LIT_VALUE (tree->left->right))
5310 return tree->left->left;
5313 /*-----------------------------------------------------------------*/
5314 /* isBitAndPowOf2 - helper function */
5315 /*-----------------------------------------------------------------*/
5317 isBitAndPow2 (ast * tree)
5319 /* if this is not a bit and */
5320 if (!IS_BITAND (tree))
5323 /* will look for tree of the form
5324 ( expr & (1 << litval) */
5325 if (!IS_AST_LIT_VALUE (tree->right))
5328 return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
5331 /*-----------------------------------------------------------------*/
5332 /* optimizeGetHbit - get highest order bit of the expression */
5333 /*-----------------------------------------------------------------*/
5335 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5340 expr = isShiftRightLitVal_BitAndLitVal(tree);
5343 if ((AST_LIT_VALUE (tree->right) != 1) ||
5344 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5345 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5348 if (!expr && (resultType == RESULT_TYPE_BIT))
5351 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5357 /* make sure the port supports GETHBIT */
5358 if (port->hasExtBitOp
5359 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5362 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5365 /*-----------------------------------------------------------------*/
5366 /* optimizeGetAbit - get a single bit of the expression */
5367 /*-----------------------------------------------------------------*/
5369 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5374 expr = isShiftRightLitVal_BitAndLitVal(tree);
5377 if (AST_LIT_VALUE (tree->right) != 1)
5379 count = tree->left->right;
5381 if (!expr && (resultType == RESULT_TYPE_BIT))
5383 int p2 = isBitAndPow2 (tree);
5387 count = newAst_VALUE (valueFromLit (p2));
5393 /* make sure the port supports GETABIT */
5394 if (port->hasExtBitOp
5395 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5398 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5402 /*-----------------------------------------------------------------*/
5403 /* optimizeGetByte - get a byte of the expression */
5404 /*-----------------------------------------------------------------*/
5406 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5412 expr = isShiftRightLitVal_BitAndLitVal(tree);
5415 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5416 count = tree->left->right;
5417 if (AST_LIT_VALUE (tree->right) != 0xFF)
5420 if (!expr && resultType == RESULT_TYPE_CHAR)
5422 /* if this is a right shift over a multiple of 8 */
5423 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5425 i = (unsigned int) AST_LIT_VALUE (tree->right);
5426 count = tree->right;
5430 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5433 /* make sure the port supports GETBYTE */
5434 if (port->hasExtBitOp
5435 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5438 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5441 /*-----------------------------------------------------------------*/
5442 /* optimizeGetWord - get two bytes of the expression */
5443 /*-----------------------------------------------------------------*/
5445 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5451 expr = isShiftRightLitVal_BitAndLitVal(tree);
5454 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5455 count = tree->left->right;
5456 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5459 if (!expr && resultType == RESULT_TYPE_INT)
5461 /* if this is a right shift over a multiple of 8 */
5462 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5464 i = (unsigned int) AST_LIT_VALUE (tree->right);
5465 count = tree->right;
5469 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5472 /* make sure the port supports GETWORD */
5473 if (port->hasExtBitOp
5474 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5477 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5480 /*-----------------------------------------------------------------*/
5481 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5482 /*-----------------------------------------------------------------*/
5484 optimizeRRCRLC (ast * root)
5486 /* will look for trees of the form
5487 (?expr << 1) | (?expr >> 7) or
5488 (?expr >> 7) | (?expr << 1) will make that
5489 into a RLC : operation ..
5491 (?expr >> 1) | (?expr << 7) or
5492 (?expr << 7) | (?expr >> 1) will make that
5493 into a RRC operation
5494 note : by 7 I mean (number of bits required to hold the
5496 /* if the root operation is not a | operation then not */
5497 if (!IS_BITOR (root))
5500 /* I have to think of a better way to match patterns this sucks */
5501 /* that aside let's start looking for the first case : I use a
5502 negative check a lot to improve the efficiency */
5503 /* (?expr << 1) | (?expr >> 7) */
5504 if (IS_LEFT_OP (root->left) &&
5505 IS_RIGHT_OP (root->right))
5508 if (!SPEC_USIGN (TETYPE (root->left->left)))
5511 if (!IS_AST_LIT_VALUE (root->left->right) ||
5512 !IS_AST_LIT_VALUE (root->right->right))
5515 /* make sure it is the same expression */
5516 if (!isAstEqual (root->left->left,
5520 if (AST_LIT_VALUE (root->left->right) != 1)
5523 if (AST_LIT_VALUE (root->right->right) !=
5524 (getSize (TTYPE (root->left->left)) * 8 - 1))
5527 /* make sure the port supports RLC */
5528 if (port->hasExtBitOp
5529 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5532 /* whew got the first case : create the AST */
5533 return newNode (RLC, root->left->left, NULL);
5537 /* check for second case */
5538 /* (?expr >> 7) | (?expr << 1) */
5539 if (IS_LEFT_OP (root->right) &&
5540 IS_RIGHT_OP (root->left))
5543 if (!SPEC_USIGN (TETYPE (root->left->left)))
5546 if (!IS_AST_LIT_VALUE (root->left->right) ||
5547 !IS_AST_LIT_VALUE (root->right->right))
5550 /* make sure it is the same symbol */
5551 if (!isAstEqual (root->left->left,
5555 if (AST_LIT_VALUE (root->right->right) != 1)
5558 if (AST_LIT_VALUE (root->left->right) !=
5559 (getSize (TTYPE (root->left->left)) * 8 - 1))
5562 /* make sure the port supports RLC */
5563 if (port->hasExtBitOp
5564 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5567 /* whew got the first case : create the AST */
5568 return newNode (RLC, root->left->left, NULL);
5573 /* third case for RRC */
5574 /* (?symbol >> 1) | (?symbol << 7) */
5575 if (IS_LEFT_OP (root->right) &&
5576 IS_RIGHT_OP (root->left))
5579 if (!SPEC_USIGN (TETYPE (root->left->left)))
5582 if (!IS_AST_LIT_VALUE (root->left->right) ||
5583 !IS_AST_LIT_VALUE (root->right->right))
5586 /* make sure it is the same symbol */
5587 if (!isAstEqual (root->left->left,
5591 if (AST_LIT_VALUE (root->left->right) != 1)
5594 if (AST_LIT_VALUE (root->right->right) !=
5595 (getSize (TTYPE (root->left->left)) * 8 - 1))
5598 /* make sure the port supports RRC */
5599 if (port->hasExtBitOp
5600 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5603 /* whew got the first case : create the AST */
5604 return newNode (RRC, root->left->left, NULL);
5608 /* fourth and last case for now */
5609 /* (?symbol << 7) | (?symbol >> 1) */
5610 if (IS_RIGHT_OP (root->right) &&
5611 IS_LEFT_OP (root->left))
5614 if (!SPEC_USIGN (TETYPE (root->left->left)))
5617 if (!IS_AST_LIT_VALUE (root->left->right) ||
5618 !IS_AST_LIT_VALUE (root->right->right))
5621 /* make sure it is the same symbol */
5622 if (!isAstEqual (root->left->left,
5626 if (AST_LIT_VALUE (root->right->right) != 1)
5629 if (AST_LIT_VALUE (root->left->right) !=
5630 (getSize (TTYPE (root->left->left)) * 8 - 1))
5633 /* make sure the port supports RRC */
5634 if (port->hasExtBitOp
5635 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5638 /* whew got the first case : create the AST */
5639 return newNode (RRC, root->left->left, NULL);
5643 /* not found return root */
5647 /*-----------------------------------------------------------------*/
5648 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5649 /*-----------------------------------------------------------------*/
5651 optimizeSWAP (ast * root)
5653 /* will look for trees of the form
5654 (?expr << 4) | (?expr >> 4) or
5655 (?expr >> 4) | (?expr << 4) will make that
5656 into a SWAP : operation ..
5657 note : by 4 I mean (number of bits required to hold the
5659 /* if the root operation is not a | operation then not */
5660 if (!IS_BITOR (root))
5663 /* (?expr << 4) | (?expr >> 4) */
5664 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5665 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5668 if (!SPEC_USIGN (TETYPE (root->left->left)))
5671 if (!IS_AST_LIT_VALUE (root->left->right) ||
5672 !IS_AST_LIT_VALUE (root->right->right))
5675 /* make sure it is the same expression */
5676 if (!isAstEqual (root->left->left,
5680 if (AST_LIT_VALUE (root->left->right) !=
5681 (getSize (TTYPE (root->left->left)) * 4))
5684 if (AST_LIT_VALUE (root->right->right) !=
5685 (getSize (TTYPE (root->left->left)) * 4))
5688 /* make sure the port supports SWAP */
5689 if (port->hasExtBitOp
5690 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5693 /* found it : create the AST */
5694 return newNode (SWAP, root->left->left, NULL);
5698 /* not found return root */
5702 /*-----------------------------------------------------------------*/
5703 /* optimizeCompare - optimizes compares for bit variables */
5704 /*-----------------------------------------------------------------*/
5706 optimizeCompare (ast * root)
5708 ast *optExpr = NULL;
5711 unsigned int litValue;
5713 /* if nothing then return nothing */
5717 /* if not a compare op then do leaves */
5718 if (!IS_COMPARE_OP (root))
5720 root->left = optimizeCompare (root->left);
5721 root->right = optimizeCompare (root->right);
5725 /* if left & right are the same then depending
5726 of the operation do */
5727 if (isAstEqual (root->left, root->right))
5729 switch (root->opval.op)
5734 optExpr = newAst_VALUE (constVal ("0"));
5739 optExpr = newAst_VALUE (constVal ("1"));
5743 return decorateType (optExpr, RESULT_TYPE_NONE);
5746 vleft = (root->left->type == EX_VALUE ?
5747 root->left->opval.val : NULL);
5749 vright = (root->right->type == EX_VALUE ?
5750 root->right->opval.val : NULL);
5752 /* if left is a BITVAR in BITSPACE */
5753 /* and right is a LITERAL then opt- */
5754 /* imize else do nothing */
5755 if (vleft && vright &&
5756 IS_BITVAR (vleft->etype) &&
5757 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5758 IS_LITERAL (vright->etype))
5761 /* if right side > 1 then comparison may never succeed */
5762 if ((litValue = (int) floatFromVal (vright)) > 1)
5764 werror (W_BAD_COMPARE);
5770 switch (root->opval.op)
5772 case '>': /* bit value greater than 1 cannot be */
5773 werror (W_BAD_COMPARE);
5777 case '<': /* bit value < 1 means 0 */
5779 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5782 case LE_OP: /* bit value <= 1 means no check */
5783 optExpr = newAst_VALUE (vright);
5786 case GE_OP: /* bit value >= 1 means only check for = */
5788 optExpr = newAst_VALUE (vleft);
5793 { /* literal is zero */
5794 switch (root->opval.op)
5796 case '<': /* bit value < 0 cannot be */
5797 werror (W_BAD_COMPARE);
5801 case '>': /* bit value > 0 means 1 */
5803 optExpr = newAst_VALUE (vleft);
5806 case LE_OP: /* bit value <= 0 means no check */
5807 case GE_OP: /* bit value >= 0 means no check */
5808 werror (W_BAD_COMPARE);
5812 case EQ_OP: /* bit == 0 means ! of bit */
5813 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5817 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5818 } /* end-of-if of BITVAR */
5824 /*-----------------------------------------------------------------*/
5825 /* addSymToBlock : adds the symbol to the first block we find */
5826 /*-----------------------------------------------------------------*/
5828 addSymToBlock (symbol * sym, ast * tree)
5830 /* reached end of tree or a leaf */
5831 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5835 if (IS_AST_OP (tree) &&
5836 tree->opval.op == BLOCK)
5839 symbol *lsym = copySymbol (sym);
5841 lsym->next = AST_VALUES (tree, sym);
5842 AST_VALUES (tree, sym) = lsym;
5846 addSymToBlock (sym, tree->left);
5847 addSymToBlock (sym, tree->right);
5850 /*-----------------------------------------------------------------*/
5851 /* processRegParms - do processing for register parameters */
5852 /*-----------------------------------------------------------------*/
5854 processRegParms (value * args, ast * body)
5858 if (IS_REGPARM (args->etype))
5859 addSymToBlock (args->sym, body);
5864 /*-----------------------------------------------------------------*/
5865 /* resetParmKey - resets the operandkeys for the symbols */
5866 /*-----------------------------------------------------------------*/
5867 DEFSETFUNC (resetParmKey)
5880 /*------------------------------------------------------------------*/
5881 /* fixupInlineLabel - change a label in an inlined function so that */
5882 /* it is always unique no matter how many times */
5883 /* the function is inlined. */
5884 /*------------------------------------------------------------------*/
5886 fixupInlineLabel (symbol * sym)
5888 char name[SDCC_NAME_MAX + 1];
5890 SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
5891 strcpy (sym->name, name);
5895 /*------------------------------------------------------------------*/
5896 /* copyAstLoc - copy location information (file, line, block, etc.) */
5897 /* from one ast node to another */
5898 /*------------------------------------------------------------------*/
5900 copyAstLoc (ast * dest, ast * src)
5902 dest->lineno = src->lineno;
5903 dest->filename = src->filename;
5904 dest->level = src->level;
5905 dest->block = src->block;
5906 dest->seqPoint = src->seqPoint;
5911 /*-----------------------------------------------------------------*/
5912 /* fixupInline - perform various fixups on an inline function tree */
5913 /* to take into account that it is no longer a */
5914 /* stand-alone function. */
5915 /*-----------------------------------------------------------------*/
5917 fixupInline (ast * tree, int level)
5919 tree->block = currBlockno;
5921 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
5928 /* Add any declared variables back into the symbol table */
5929 decls = tree->values.sym;
5932 decls->level = level;
5933 decls->block = currBlockno;
5934 addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0);
5935 decls = decls->next;
5939 tree->level = level;
5941 /* Update symbols */
5942 if (IS_AST_VALUE (tree) &&
5943 tree->opval.val->sym)
5945 symbol * sym = tree->opval.val->sym;
5948 sym->block = currBlockno;
5950 /* If the symbol is a label, we need to renumber it */
5952 fixupInlineLabel (sym);
5955 /* Update IFX target labels */
5956 if (tree->type == EX_OP && tree->opval.op == IFX)
5958 if (tree->trueLabel)
5959 fixupInlineLabel (tree->trueLabel);
5960 if (tree->falseLabel)
5961 fixupInlineLabel (tree->falseLabel);
5964 /* Replace RETURN with optional assignment and a GOTO to the end */
5965 /* of the inlined function */
5966 if (tree->type == EX_OP && tree->opval.op == RETURN)
5968 ast * assignTree = NULL;
5971 if (inlineState.retsym && tree->right)
5973 assignTree = newNode ('=',
5974 newAst_VALUE (symbolVal (inlineState.retsym)),
5976 copyAstLoc (assignTree, tree);
5979 gotoTree = newNode (GOTO,
5980 newAst_VALUE (symbolVal (inlineState.retlab)),
5982 copyAstLoc (gotoTree, tree);
5984 tree->opval.op = NULLOP;
5985 tree->left = assignTree;
5986 tree->right = gotoTree;
5989 /* Update any children */
5991 fixupInline (tree->left, level);
5993 fixupInline (tree->right, level);
5995 if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
5997 symbol * label = tree->left->opval.val->sym;
5999 label->key = labelKey++;
6000 /* Add this label back into the symbol table */
6001 addSym (LabelTab, label, label->name, label->level, 0, 0);
6005 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
6011 /*-----------------------------------------------------------------*/
6012 /* inlineAddDecl - add a variable declaration to an ast block. It */
6013 /* is also added to the symbol table if addSymTab */
6015 /*-----------------------------------------------------------------*/
6017 inlineAddDecl (symbol * sym, ast * block, int addSymTab)
6021 symbol **decl = &(block->values.sym);
6023 sym->level = block->level;
6024 sym->block = block->block;
6028 if (strcmp ((*decl)->name, sym->name) == 0)
6030 decl = &( (*decl)->next );
6036 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0);
6042 /*-----------------------------------------------------------------*/
6043 /* inlineTempVar - create a temporary variable for inlining */
6044 /*-----------------------------------------------------------------*/
6046 inlineTempVar (sym_link * type, int level)
6050 sym = newSymbol (genSymName(level), level );
6051 sym->type = copyLinkChain (type);
6052 sym->etype = getSpec(sym->type);
6053 SPEC_SCLS (sym->etype) = S_AUTO;
6054 SPEC_OCLS (sym->etype) = NULL;
6055 SPEC_EXTR (sym->etype) = 0;
6056 SPEC_STAT (sym->etype) = 0;
6057 if IS_SPEC (sym->type)
6058 SPEC_VOLATILE (sym->type) = 0;
6060 DCL_PTR_VOLATILE (sym->type) = 0;
6061 SPEC_ABSA (sym->etype) = 0;
6067 /*-----------------------------------------------------------------*/
6068 /* inlineFindParmRecurse - recursive function for inlineFindParm */
6069 /*-----------------------------------------------------------------*/
6071 inlineFindParmRecurse (ast * parms, int *index)
6076 if (parms->type == EX_OP && parms->opval.op == PARAM)
6080 p=inlineFindParmRecurse (parms->left, index);
6083 p=inlineFindParmRecurse (parms->right, index);
6094 /*-----------------------------------------------------------------*/
6095 /* inlineFindParm - search an ast tree of parameters to find one */
6096 /* at a particular index (0=first parameter). */
6097 /* Returns NULL if not found. */
6098 /*-----------------------------------------------------------------*/
6100 inlineFindParm (ast * parms, int index)
6102 return inlineFindParmRecurse (parms, &index);
6106 /*-----------------------------------------------------------------*/
6107 /* expandInlineFuncs - replace calls to inline functions with the */
6108 /* function itself */
6109 /*-----------------------------------------------------------------*/
6111 expandInlineFuncs (ast * tree, ast * block)
6113 if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left
6114 && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym)
6116 symbol * func = tree->left->opval.val->sym;
6119 /* The symbol is probably not bound yet, so find the real one */
6120 csym = findSymWithLevel (SymbolTab, func);
6124 /* Is this an inline function that we can inline? */
6125 if (IFFUNC_ISINLINE (func->type) && func->funcTree)
6127 symbol * retsym = NULL;
6135 /* Generate a label for the inlined function to branch to */
6136 /* in case it contains a return statement */
6137 retlab = newSymbol (genSymName(tree->level+1), tree->level+1 );
6140 inlineState.retlab = retlab;
6142 /* Build the subtree for the inlined function in the form: */
6143 /* { //inlinetree block */
6144 /* { //inlinetree2 block */
6145 /* inline_function_code; */
6149 temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL);
6150 copyAstLoc (temptree, tree);
6151 temptree = newNode (NULLOP, copyAst (func->funcTree), temptree);
6152 copyAstLoc (temptree, tree);
6153 temptree = newNode (BLOCK, NULL, temptree);
6154 copyAstLoc (temptree, tree);
6155 inlinetree2 = temptree;
6156 inlinetree = newNode (BLOCK, NULL, inlinetree2);
6157 copyAstLoc (inlinetree, tree);
6159 /* To pass parameters to the inlined function, we need some */
6160 /* intermediate variables. This avoids scoping problems */
6161 /* when the parameter declaration names are used differently */
6162 /* during the function call. For example, a function */
6163 /* declared as func(int x, int y) but called as func(y,x). */
6164 /* { //inlinetree block */
6165 /* type1 temparg1; */
6167 /* typen tempargn; */
6168 /* temparg1 = argument1; */
6170 /* tempargn = argumentn; */
6171 /* { //inlinetree2 block */
6175 /* param1 = temparg1; */
6177 /* paramn = tempargn; */
6178 /* inline_function_code; */
6182 args = FUNC_ARGS (func->type);
6189 symbol * parm = copySymbol (args->sym);
6191 temparg = inlineTempVar (args->sym->type, tree->level+1);
6192 inlineAddDecl (temparg, inlinetree, FALSE);
6194 passedarg = inlineFindParm (tree->right, argIndex);
6195 assigntree = newNode ('=',
6196 newAst_VALUE (symbolVal (temparg)),
6198 inlinetree->right = newNode (NULLOP,
6202 inlineAddDecl (parm, inlinetree2, FALSE);
6205 assigntree = newNode ('=',
6206 newAst_VALUE (symbolVal (parm)),
6207 newAst_VALUE (symbolVal (temparg)));
6208 inlinetree2->right = newNode (NULLOP,
6210 inlinetree2->right);
6217 /* Handle the return type */
6218 if (!IS_VOID (func->type->next))
6220 /* Create a temporary symbol to hold the return value and */
6221 /* join it with the inlined function using the comma */
6222 /* operator. The fixupInline function will take care of */
6223 /* changing return statements into assignments to retsym. */
6224 /* (parameter passing and return label omitted for clarity) */
6225 /* rettype retsym; */
6227 /* {{inline_function_code}}, retsym */
6229 retsym = inlineTempVar (func->type->next, tree->level);
6230 inlineAddDecl (retsym, block, TRUE);
6232 tree->opval.op = ',';
6233 tree->left = inlinetree;
6234 tree->right = newAst_VALUE (symbolVal (retsym));
6238 tree->opval.op = NULLOP;
6240 tree->right = inlinetree;
6242 inlineState.retsym = retsym;
6244 /* Renumber the various internal counters on the inlined */
6245 /* function's tree nodes and symbols. Add the inlined */
6246 /* function's local variables to the appropriate scope(s). */
6247 /* Convert inlined return statements to an assignment to */
6248 /* retsym (if needed) and a goto retlab. */
6249 fixupInline (inlinetree, inlinetree->level);
6250 inlineState.count++;
6255 /* Recursively continue to search for functions to inline. */
6256 if (IS_AST_OP (tree))
6258 if (tree->opval.op == BLOCK)
6262 expandInlineFuncs (tree->left, block);
6264 expandInlineFuncs (tree->right, block);
6269 /*-----------------------------------------------------------------*/
6270 /* createFunction - This is the key node that calls the iCode for */
6271 /* generating the code for a function. Note code */
6272 /* is generated function by function, later when */
6273 /* add inter-procedural analysis this will change */
6274 /*-----------------------------------------------------------------*/
6276 createFunction (symbol * name, ast * body)
6282 iCode *piCode = NULL;
6284 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
6285 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
6287 /* if check function return 0 then some problem */
6288 if (checkFunction (name, NULL) == 0)
6291 /* create a dummy block if none exists */
6293 body = newNode (BLOCK, NULL, NULL);
6297 /* check if the function name already in the symbol table */
6298 if ((csym = findSym (SymbolTab, NULL, name->name)))
6301 /* special case for compiler defined functions
6302 we need to add the name to the publics list : this
6303 actually means we are now compiling the compiler
6307 addSet (&publics, name);
6312 addSymChain (&name);
6313 allocVariables (name);
6315 name->lastLine = lexLineno;
6318 /* set the stack pointer */
6319 stackPtr = -port->stack.direction * port->stack.call_overhead;
6322 if (IFFUNC_ISISR (name->type))
6323 stackPtr -= port->stack.direction * port->stack.isr_overhead;
6325 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
6327 if (options.useXstack)
6328 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
6330 stackPtr -= port->stack.direction * port->stack.reent_overhead;
6333 fetype = getSpec (name->type); /* get the specifier for the function */
6334 /* if this is a reentrant function then */
6335 if (IFFUNC_ISREENT (name->type))
6338 inlineState.count = 0;
6339 expandInlineFuncs (body, NULL);
6341 if (FUNC_ISINLINE (name->type))
6342 name->funcTree = copyAst (body);
6344 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
6346 /* do processing for parameters that are passed in registers */
6347 processRegParms (FUNC_ARGS(name->type), body);
6349 /* set the stack pointer */
6353 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
6355 /* allocate & autoinit the block variables */
6356 processBlockVars (body, &stack, ALLOCATE);
6358 /* name needs to be mangled */
6359 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
6361 body = resolveSymbols (body); /* resolve the symbols */
6362 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
6364 /* save the stack information */
6365 if (options.useXstack)
6366 name->xstack = SPEC_STAK (fetype) = stack;
6368 name->stack = SPEC_STAK (fetype) = stack;
6370 ex = newAst_VALUE (symbolVal (name)); /* create name */
6371 ex = newNode (FUNCTION, ex, body);
6372 ex->values.args = FUNC_ARGS(name->type);
6374 if (options.dump_tree) PA(ex);
6377 werror (E_FUNC_NO_CODE, name->name);
6381 /* Do not generate code for inline functions unless extern also */
6382 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
6385 /* create the node & generate intermediate code */
6387 codeOutBuf = &code->oBuf;
6388 piCode = iCodeFromAst (ex);
6389 name->generated = 1;
6393 werror (E_FUNC_NO_CODE, name->name);
6397 eBBlockFromiCode (piCode);
6399 /* if there are any statics then do them */
6402 GcurMemmap = statsg;
6403 codeOutBuf = &statsg->oBuf;
6404 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6410 /* dealloc the block variables */
6411 processBlockVars (body, &stack, DEALLOCATE);
6412 outputDebugStackSymbols();
6413 /* deallocate paramaters */
6414 deallocParms (FUNC_ARGS(name->type));
6416 if (IFFUNC_ISREENT (name->type))
6419 /* we are done freeup memory & cleanup */
6421 if (port->reset_labelKey) labelKey = 1;
6423 FUNC_HASBODY(name->type) = 1;
6424 addSet (&operKeyReset, name);
6425 applyToSet (operKeyReset, resetParmKey);
6430 cleanUpLevel (LabelTab, 0);
6431 cleanUpBlock (StructTab, 1);
6432 cleanUpBlock (TypedefTab, 1);
6434 xstack->syms = NULL;
6435 istack->syms = NULL;
6440 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6441 /*-----------------------------------------------------------------*/
6442 /* ast_print : prints the ast (for debugging purposes) */
6443 /*-----------------------------------------------------------------*/
6445 void ast_print (ast * tree, FILE *outfile, int indent)
6450 /* can print only decorated trees */
6451 if (!tree->decorated) return;
6453 /* if any child is an error | this one is an error do nothing */
6454 if (tree->isError ||
6455 (tree->left && tree->left->isError) ||
6456 (tree->right && tree->right->isError)) {
6457 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6461 /* print the line */
6462 /* if not block & function */
6463 if (tree->type == EX_OP &&
6464 (tree->opval.op != FUNCTION &&
6465 tree->opval.op != BLOCK &&
6466 tree->opval.op != NULLOP)) {
6469 if (tree->opval.op == FUNCTION) {
6471 value *args=FUNC_ARGS(tree->left->opval.val->type);
6472 fprintf(outfile,"FUNCTION (%s=%p) type (",
6473 tree->left->opval.val->name, tree);
6474 printTypeChain (tree->left->opval.val->type->next,outfile);
6475 fprintf(outfile,") args (");
6478 fprintf (outfile, ", ");
6480 printTypeChain (args ? args->type : NULL, outfile);
6482 args= args ? args->next : NULL;
6484 fprintf(outfile,")\n");
6485 ast_print(tree->left,outfile,indent);
6486 ast_print(tree->right,outfile,indent);
6489 if (tree->opval.op == BLOCK) {
6490 symbol *decls = tree->values.sym;
6491 INDENT(indent,outfile);
6492 fprintf(outfile,"{\n");
6494 INDENT(indent+2,outfile);
6495 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6496 decls->name, decls);
6497 printTypeChain(decls->type,outfile);
6498 fprintf(outfile,")\n");
6500 decls = decls->next;
6502 ast_print(tree->right,outfile,indent+2);
6503 INDENT(indent,outfile);
6504 fprintf(outfile,"}\n");
6507 if (tree->opval.op == NULLOP) {
6508 ast_print(tree->left,outfile,indent);
6509 ast_print(tree->right,outfile,indent);
6512 INDENT(indent,outfile);
6514 /*------------------------------------------------------------------*/
6515 /*----------------------------*/
6516 /* leaf has been reached */
6517 /*----------------------------*/
6518 /* if this is of type value */
6519 /* just get the type */
6520 if (tree->type == EX_VALUE) {
6522 if (IS_LITERAL (tree->opval.val->etype)) {
6523 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6524 if (SPEC_USIGN (tree->opval.val->etype))
6525 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
6527 fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
6528 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
6529 floatFromVal(tree->opval.val));
6530 } else if (tree->opval.val->sym) {
6531 /* if the undefined flag is set then give error message */
6532 if (tree->opval.val->sym->undefined) {
6533 fprintf(outfile,"UNDEFINED SYMBOL ");
6535 fprintf(outfile,"SYMBOL ");
6537 fprintf(outfile,"(%s=%p @ %p)",
6538 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6541 fprintf(outfile," type (");
6542 printTypeChain(tree->ftype,outfile);
6543 fprintf(outfile,")\n");
6545 fprintf(outfile,"\n");
6550 /* if type link for the case of cast */
6551 if (tree->type == EX_LINK) {
6552 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6553 printTypeChain(tree->opval.lnk,outfile);
6554 fprintf(outfile,")\n");
6559 /* depending on type of operator do */
6561 switch (tree->opval.op) {
6562 /*------------------------------------------------------------------*/
6563 /*----------------------------*/
6565 /*----------------------------*/
6567 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6568 printTypeChain(tree->ftype,outfile);
6569 fprintf(outfile,")\n");
6570 ast_print(tree->left,outfile,indent+2);
6571 ast_print(tree->right,outfile,indent+2);
6574 /*------------------------------------------------------------------*/
6575 /*----------------------------*/
6577 /*----------------------------*/
6579 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6580 printTypeChain(tree->ftype,outfile);
6581 fprintf(outfile,")\n");
6582 ast_print(tree->left,outfile,indent+2);
6583 ast_print(tree->right,outfile,indent+2);
6586 /*------------------------------------------------------------------*/
6587 /*----------------------------*/
6588 /* struct/union pointer */
6589 /*----------------------------*/
6591 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6592 printTypeChain(tree->ftype,outfile);
6593 fprintf(outfile,")\n");
6594 ast_print(tree->left,outfile,indent+2);
6595 ast_print(tree->right,outfile,indent+2);
6598 /*------------------------------------------------------------------*/
6599 /*----------------------------*/
6600 /* ++/-- operation */
6601 /*----------------------------*/
6604 fprintf(outfile,"post-");
6606 fprintf(outfile,"pre-");
6607 fprintf(outfile,"INC_OP (%p) type (",tree);
6608 printTypeChain(tree->ftype,outfile);
6609 fprintf(outfile,")\n");
6610 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6611 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6616 fprintf(outfile,"post-");
6618 fprintf(outfile,"pre-");
6619 fprintf(outfile,"DEC_OP (%p) type (",tree);
6620 printTypeChain(tree->ftype,outfile);
6621 fprintf(outfile,")\n");
6622 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6623 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6626 /*------------------------------------------------------------------*/
6627 /*----------------------------*/
6629 /*----------------------------*/
6632 fprintf(outfile,"& (%p) type (",tree);
6633 printTypeChain(tree->ftype,outfile);
6634 fprintf(outfile,")\n");
6635 ast_print(tree->left,outfile,indent+2);
6636 ast_print(tree->right,outfile,indent+2);
6638 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6639 printTypeChain(tree->ftype,outfile);
6640 fprintf(outfile,")\n");
6641 ast_print(tree->left,outfile,indent+2);
6642 ast_print(tree->right,outfile,indent+2);
6645 /*----------------------------*/
6647 /*----------------------------*/
6649 fprintf(outfile,"OR (%p) type (",tree);
6650 printTypeChain(tree->ftype,outfile);
6651 fprintf(outfile,")\n");
6652 ast_print(tree->left,outfile,indent+2);
6653 ast_print(tree->right,outfile,indent+2);
6655 /*------------------------------------------------------------------*/
6656 /*----------------------------*/
6658 /*----------------------------*/
6660 fprintf(outfile,"XOR (%p) type (",tree);
6661 printTypeChain(tree->ftype,outfile);
6662 fprintf(outfile,")\n");
6663 ast_print(tree->left,outfile,indent+2);
6664 ast_print(tree->right,outfile,indent+2);
6667 /*------------------------------------------------------------------*/
6668 /*----------------------------*/
6670 /*----------------------------*/
6672 fprintf(outfile,"DIV (%p) type (",tree);
6673 printTypeChain(tree->ftype,outfile);
6674 fprintf(outfile,")\n");
6675 ast_print(tree->left,outfile,indent+2);
6676 ast_print(tree->right,outfile,indent+2);
6678 /*------------------------------------------------------------------*/
6679 /*----------------------------*/
6681 /*----------------------------*/
6683 fprintf(outfile,"MOD (%p) type (",tree);
6684 printTypeChain(tree->ftype,outfile);
6685 fprintf(outfile,")\n");
6686 ast_print(tree->left,outfile,indent+2);
6687 ast_print(tree->right,outfile,indent+2);
6690 /*------------------------------------------------------------------*/
6691 /*----------------------------*/
6692 /* address dereference */
6693 /*----------------------------*/
6694 case '*': /* can be unary : if right is null then unary operation */
6696 fprintf(outfile,"DEREF (%p) type (",tree);
6697 printTypeChain(tree->ftype,outfile);
6698 fprintf(outfile,")\n");
6699 ast_print(tree->left,outfile,indent+2);
6702 /*------------------------------------------------------------------*/
6703 /*----------------------------*/
6704 /* multiplication */
6705 /*----------------------------*/
6706 fprintf(outfile,"MULT (%p) type (",tree);
6707 printTypeChain(tree->ftype,outfile);
6708 fprintf(outfile,")\n");
6709 ast_print(tree->left,outfile,indent+2);
6710 ast_print(tree->right,outfile,indent+2);
6714 /*------------------------------------------------------------------*/
6715 /*----------------------------*/
6716 /* unary '+' operator */
6717 /*----------------------------*/
6721 fprintf(outfile,"UPLUS (%p) type (",tree);
6722 printTypeChain(tree->ftype,outfile);
6723 fprintf(outfile,")\n");
6724 ast_print(tree->left,outfile,indent+2);
6726 /*------------------------------------------------------------------*/
6727 /*----------------------------*/
6729 /*----------------------------*/
6730 fprintf(outfile,"ADD (%p) type (",tree);
6731 printTypeChain(tree->ftype,outfile);
6732 fprintf(outfile,")\n");
6733 ast_print(tree->left,outfile,indent+2);
6734 ast_print(tree->right,outfile,indent+2);
6737 /*------------------------------------------------------------------*/
6738 /*----------------------------*/
6740 /*----------------------------*/
6741 case '-': /* can be unary */
6743 fprintf(outfile,"UMINUS (%p) type (",tree);
6744 printTypeChain(tree->ftype,outfile);
6745 fprintf(outfile,")\n");
6746 ast_print(tree->left,outfile,indent+2);
6748 /*------------------------------------------------------------------*/
6749 /*----------------------------*/
6751 /*----------------------------*/
6752 fprintf(outfile,"SUB (%p) type (",tree);
6753 printTypeChain(tree->ftype,outfile);
6754 fprintf(outfile,")\n");
6755 ast_print(tree->left,outfile,indent+2);
6756 ast_print(tree->right,outfile,indent+2);
6759 /*------------------------------------------------------------------*/
6760 /*----------------------------*/
6762 /*----------------------------*/
6764 fprintf(outfile,"COMPL (%p) type (",tree);
6765 printTypeChain(tree->ftype,outfile);
6766 fprintf(outfile,")\n");
6767 ast_print(tree->left,outfile,indent+2);
6769 /*------------------------------------------------------------------*/
6770 /*----------------------------*/
6772 /*----------------------------*/
6774 fprintf(outfile,"NOT (%p) type (",tree);
6775 printTypeChain(tree->ftype,outfile);
6776 fprintf(outfile,")\n");
6777 ast_print(tree->left,outfile,indent+2);
6779 /*------------------------------------------------------------------*/
6780 /*----------------------------*/
6782 /*----------------------------*/
6784 fprintf(outfile,"RRC (%p) type (",tree);
6785 printTypeChain(tree->ftype,outfile);
6786 fprintf(outfile,")\n");
6787 ast_print(tree->left,outfile,indent+2);
6791 fprintf(outfile,"RLC (%p) type (",tree);
6792 printTypeChain(tree->ftype,outfile);
6793 fprintf(outfile,")\n");
6794 ast_print(tree->left,outfile,indent+2);
6797 fprintf(outfile,"SWAP (%p) type (",tree);
6798 printTypeChain(tree->ftype,outfile);
6799 fprintf(outfile,")\n");
6800 ast_print(tree->left,outfile,indent+2);
6803 fprintf(outfile,"GETHBIT (%p) type (",tree);
6804 printTypeChain(tree->ftype,outfile);
6805 fprintf(outfile,")\n");
6806 ast_print(tree->left,outfile,indent+2);
6809 fprintf(outfile,"GETABIT (%p) type (",tree);
6810 printTypeChain(tree->ftype,outfile);
6811 fprintf(outfile,")\n");
6812 ast_print(tree->left,outfile,indent+2);
6813 ast_print(tree->right,outfile,indent+2);
6816 fprintf(outfile,"GETBYTE (%p) type (",tree);
6817 printTypeChain(tree->ftype,outfile);
6818 fprintf(outfile,")\n");
6819 ast_print(tree->left,outfile,indent+2);
6820 ast_print(tree->right,outfile,indent+2);
6823 fprintf(outfile,"GETWORD (%p) type (",tree);
6824 printTypeChain(tree->ftype,outfile);
6825 fprintf(outfile,")\n");
6826 ast_print(tree->left,outfile,indent+2);
6827 ast_print(tree->right,outfile,indent+2);
6830 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6831 printTypeChain(tree->ftype,outfile);
6832 fprintf(outfile,")\n");
6833 ast_print(tree->left,outfile,indent+2);
6834 ast_print(tree->right,outfile,indent+2);
6837 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6838 printTypeChain(tree->ftype,outfile);
6839 fprintf(outfile,")\n");
6840 ast_print(tree->left,outfile,indent+2);
6841 ast_print(tree->right,outfile,indent+2);
6843 /*------------------------------------------------------------------*/
6844 /*----------------------------*/
6846 /*----------------------------*/
6847 case CAST: /* change the type */
6848 fprintf(outfile,"CAST (%p) from type (",tree);
6849 printTypeChain(tree->right->ftype,outfile);
6850 fprintf(outfile,") to type (");
6851 printTypeChain(tree->ftype,outfile);
6852 fprintf(outfile,")\n");
6853 ast_print(tree->right,outfile,indent+2);
6857 fprintf(outfile,"ANDAND (%p) type (",tree);
6858 printTypeChain(tree->ftype,outfile);
6859 fprintf(outfile,")\n");
6860 ast_print(tree->left,outfile,indent+2);
6861 ast_print(tree->right,outfile,indent+2);
6864 fprintf(outfile,"OROR (%p) type (",tree);
6865 printTypeChain(tree->ftype,outfile);
6866 fprintf(outfile,")\n");
6867 ast_print(tree->left,outfile,indent+2);
6868 ast_print(tree->right,outfile,indent+2);
6871 /*------------------------------------------------------------------*/
6872 /*----------------------------*/
6873 /* comparison operators */
6874 /*----------------------------*/
6876 fprintf(outfile,"GT(>) (%p) type (",tree);
6877 printTypeChain(tree->ftype,outfile);
6878 fprintf(outfile,")\n");
6879 ast_print(tree->left,outfile,indent+2);
6880 ast_print(tree->right,outfile,indent+2);
6883 fprintf(outfile,"LT(<) (%p) type (",tree);
6884 printTypeChain(tree->ftype,outfile);
6885 fprintf(outfile,")\n");
6886 ast_print(tree->left,outfile,indent+2);
6887 ast_print(tree->right,outfile,indent+2);
6890 fprintf(outfile,"LE(<=) (%p) type (",tree);
6891 printTypeChain(tree->ftype,outfile);
6892 fprintf(outfile,")\n");
6893 ast_print(tree->left,outfile,indent+2);
6894 ast_print(tree->right,outfile,indent+2);
6897 fprintf(outfile,"GE(>=) (%p) type (",tree);
6898 printTypeChain(tree->ftype,outfile);
6899 fprintf(outfile,")\n");
6900 ast_print(tree->left,outfile,indent+2);
6901 ast_print(tree->right,outfile,indent+2);
6904 fprintf(outfile,"EQ(==) (%p) type (",tree);
6905 printTypeChain(tree->ftype,outfile);
6906 fprintf(outfile,")\n");
6907 ast_print(tree->left,outfile,indent+2);
6908 ast_print(tree->right,outfile,indent+2);
6911 fprintf(outfile,"NE(!=) (%p) type (",tree);
6912 printTypeChain(tree->ftype,outfile);
6913 fprintf(outfile,")\n");
6914 ast_print(tree->left,outfile,indent+2);
6915 ast_print(tree->right,outfile,indent+2);
6916 /*------------------------------------------------------------------*/
6917 /*----------------------------*/
6919 /*----------------------------*/
6920 case SIZEOF: /* evaluate wihout code generation */
6921 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6924 /*------------------------------------------------------------------*/
6925 /*----------------------------*/
6926 /* conditional operator '?' */
6927 /*----------------------------*/
6929 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6930 printTypeChain(tree->ftype,outfile);
6931 fprintf(outfile,")\n");
6932 ast_print(tree->left,outfile,indent+2);
6933 ast_print(tree->right,outfile,indent+2);
6937 fprintf(outfile,"COLON(:) (%p) type (",tree);
6938 printTypeChain(tree->ftype,outfile);
6939 fprintf(outfile,")\n");
6940 ast_print(tree->left,outfile,indent+2);
6941 ast_print(tree->right,outfile,indent+2);
6944 /*------------------------------------------------------------------*/
6945 /*----------------------------*/
6946 /* assignment operators */
6947 /*----------------------------*/
6949 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6950 printTypeChain(tree->ftype,outfile);
6951 fprintf(outfile,")\n");
6952 ast_print(tree->left,outfile,indent+2);
6953 ast_print(tree->right,outfile,indent+2);
6956 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6957 printTypeChain(tree->ftype,outfile);
6958 fprintf(outfile,")\n");
6959 ast_print(tree->left,outfile,indent+2);
6960 ast_print(tree->right,outfile,indent+2);
6963 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6964 printTypeChain(tree->ftype,outfile);
6965 fprintf(outfile,")\n");
6966 ast_print(tree->left,outfile,indent+2);
6967 ast_print(tree->right,outfile,indent+2);
6970 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6971 printTypeChain(tree->ftype,outfile);
6972 fprintf(outfile,")\n");
6973 ast_print(tree->left,outfile,indent+2);
6974 ast_print(tree->right,outfile,indent+2);
6977 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6978 printTypeChain(tree->ftype,outfile);
6979 fprintf(outfile,")\n");
6980 ast_print(tree->left,outfile,indent+2);
6981 ast_print(tree->right,outfile,indent+2);
6984 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6985 printTypeChain(tree->ftype,outfile);
6986 fprintf(outfile,")\n");
6987 ast_print(tree->left,outfile,indent+2);
6988 ast_print(tree->right,outfile,indent+2);
6991 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6992 printTypeChain(tree->ftype,outfile);
6993 fprintf(outfile,")\n");
6994 ast_print(tree->left,outfile,indent+2);
6995 ast_print(tree->right,outfile,indent+2);
6997 /*------------------------------------------------------------------*/
6998 /*----------------------------*/
7000 /*----------------------------*/
7002 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
7003 printTypeChain(tree->ftype,outfile);
7004 fprintf(outfile,")\n");
7005 ast_print(tree->left,outfile,indent+2);
7006 ast_print(tree->right,outfile,indent+2);
7008 /*------------------------------------------------------------------*/
7009 /*----------------------------*/
7011 /*----------------------------*/
7013 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
7014 printTypeChain(tree->ftype,outfile);
7015 fprintf(outfile,")\n");
7016 ast_print(tree->left,outfile,indent+2);
7017 ast_print(tree->right,outfile,indent+2);
7019 /*------------------------------------------------------------------*/
7020 /*----------------------------*/
7021 /* straight assignemnt */
7022 /*----------------------------*/
7024 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
7025 printTypeChain(tree->ftype,outfile);
7026 fprintf(outfile,")\n");
7027 ast_print(tree->left,outfile,indent+2);
7028 ast_print(tree->right,outfile,indent+2);
7030 /*------------------------------------------------------------------*/
7031 /*----------------------------*/
7032 /* comma operator */
7033 /*----------------------------*/
7035 fprintf(outfile,"COMMA(,) (%p) type (",tree);
7036 printTypeChain(tree->ftype,outfile);
7037 fprintf(outfile,")\n");
7038 ast_print(tree->left,outfile,indent+2);
7039 ast_print(tree->right,outfile,indent+2);
7041 /*------------------------------------------------------------------*/
7042 /*----------------------------*/
7044 /*----------------------------*/
7047 fprintf(outfile,"CALL (%p) type (",tree);
7048 printTypeChain(tree->ftype,outfile);
7049 fprintf(outfile,")\n");
7050 ast_print(tree->left,outfile,indent+2);
7051 ast_print(tree->right,outfile,indent+2);
7054 fprintf(outfile,"PARMS\n");
7055 ast_print(tree->left,outfile,indent+2);
7056 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
7057 ast_print(tree->right,outfile,indent+2);
7060 /*------------------------------------------------------------------*/
7061 /*----------------------------*/
7062 /* return statement */
7063 /*----------------------------*/
7065 fprintf(outfile,"RETURN (%p) type (",tree);
7067 printTypeChain(tree->right->ftype,outfile);
7069 fprintf(outfile,")\n");
7070 ast_print(tree->right,outfile,indent+2);
7072 /*------------------------------------------------------------------*/
7073 /*----------------------------*/
7074 /* label statement */
7075 /*----------------------------*/
7077 fprintf(outfile,"LABEL (%p)\n",tree);
7078 ast_print(tree->left,outfile,indent+2);
7079 ast_print(tree->right,outfile,indent);
7081 /*------------------------------------------------------------------*/
7082 /*----------------------------*/
7083 /* switch statement */
7084 /*----------------------------*/
7088 fprintf(outfile,"SWITCH (%p) ",tree);
7089 ast_print(tree->left,outfile,0);
7090 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
7091 INDENT(indent+2,outfile);
7092 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
7093 (int) floatFromVal(val),
7094 tree->values.switchVals.swNum,
7095 (int) floatFromVal(val));
7097 ast_print(tree->right,outfile,indent);
7100 /*------------------------------------------------------------------*/
7101 /*----------------------------*/
7103 /*----------------------------*/
7105 fprintf(outfile,"IF (%p) \n",tree);
7106 ast_print(tree->left,outfile,indent+2);
7107 if (tree->trueLabel) {
7108 INDENT(indent+2,outfile);
7109 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
7111 if (tree->falseLabel) {
7112 INDENT(indent+2,outfile);
7113 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
7115 ast_print(tree->right,outfile,indent+2);
7117 /*----------------------------*/
7118 /* goto Statement */
7119 /*----------------------------*/
7121 fprintf(outfile,"GOTO (%p) \n",tree);
7122 ast_print(tree->left,outfile,indent+2);
7123 fprintf(outfile,"\n");
7125 /*------------------------------------------------------------------*/
7126 /*----------------------------*/
7128 /*----------------------------*/
7130 fprintf(outfile,"FOR (%p) \n",tree);
7131 if (AST_FOR( tree, initExpr)) {
7132 INDENT(indent+2,outfile);
7133 fprintf(outfile,"INIT EXPR ");
7134 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
7136 if (AST_FOR( tree, condExpr)) {
7137 INDENT(indent+2,outfile);
7138 fprintf(outfile,"COND EXPR ");
7139 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
7141 if (AST_FOR( tree, loopExpr)) {
7142 INDENT(indent+2,outfile);
7143 fprintf(outfile,"LOOP EXPR ");
7144 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
7146 fprintf(outfile,"FOR LOOP BODY \n");
7147 ast_print(tree->left,outfile,indent+2);
7150 fprintf(outfile,"CRITICAL (%p) \n",tree);
7151 ast_print(tree->left,outfile,indent+2);
7159 ast_print(t,stdout,0);
7162 /*-----------------------------------------------------------------*/
7163 /* astErrors : returns non-zero if errors present in tree */
7164 /*-----------------------------------------------------------------*/
7165 int astErrors(ast *t)
7174 if (t->type == EX_VALUE
7175 && t->opval.val->sym
7176 && t->opval.val->sym->undefined)
7179 errors += astErrors(t->left);
7180 errors += astErrors(t->right);