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)
88 ex = Safe_alloc ( sizeof (ast));
91 ex->lineno = (noLineno ? 0 : lexLineno);
92 ex->filename = lexFilename;
93 ex->level = NestLevel;
94 ex->block = currBlockno;
95 ex->initMode = inInitMode;
96 ex->seqPoint = seqPointNo;
101 newAst_VALUE (value * val)
103 ast *ex = newAst_ (EX_VALUE);
109 newAst_OP (unsigned op)
111 ast *ex = newAst_ (EX_OP);
117 newAst_LINK (sym_link * val)
119 ast *ex = newAst_ (EX_LINK);
124 /*-----------------------------------------------------------------*/
125 /* newNode - creates a new node */
126 /*-----------------------------------------------------------------*/
128 newNode (long op, ast * left, ast * right)
139 /*-----------------------------------------------------------------*/
140 /* newIfxNode - creates a new Ifx Node */
141 /*-----------------------------------------------------------------*/
143 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
147 /* if this is a literal then we already know the result */
148 if (condAst->etype && IS_LITERAL (condAst->etype))
150 /* then depending on the expression value */
151 if (floatFromVal (condAst->opval.val))
152 ifxNode = newNode (GOTO,
153 newAst_VALUE (symbolVal (trueLabel)),
156 ifxNode = newNode (GOTO,
157 newAst_VALUE (symbolVal (falseLabel)),
162 ifxNode = newNode (IFX, condAst, NULL);
163 ifxNode->trueLabel = trueLabel;
164 ifxNode->falseLabel = falseLabel;
170 /*-----------------------------------------------------------------*/
171 /* copyAstValues - copies value portion of ast if needed */
172 /*-----------------------------------------------------------------*/
174 copyAstValues (ast * dest, ast * src)
176 switch (src->opval.op)
179 dest->values.sym = copySymbolChain (src->values.sym);
183 dest->values.switchVals.swVals =
184 copyValue (src->values.switchVals.swVals);
185 dest->values.switchVals.swDefault =
186 src->values.switchVals.swDefault;
187 dest->values.switchVals.swNum =
188 src->values.switchVals.swNum;
192 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
196 dest->values.constlist = copyLiteralList(src->values.constlist);
200 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
201 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
202 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
203 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
204 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
205 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
206 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
211 /*-----------------------------------------------------------------*/
212 /* copyAst - makes a copy of a given astession */
213 /*-----------------------------------------------------------------*/
222 dest = Safe_alloc ( sizeof (ast));
224 dest->type = src->type;
225 dest->filename = src->filename;
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));
394 } else if ((target->opval.op == INC_OP) || (target->opval.op == DEC_OP)) {
395 /* illegal pre/post-increment/decrement */
396 werrorfl (target->filename, target->lineno, E_LVALUE_REQUIRED, "=");
398 /* we would have to handle '.', but it is not generated any more */
399 wassertl(target->opval.op != '.', "obsolete opcode in tree");
401 /* no other kinds of ASTs are lvalues and can contain side effects */
406 writeval = copyAst(target);
408 result = newNode('=', writeval, newNode(op, readval, operand));
410 result = newNode(',', tempvar2, result);
412 result = newNode(',', tempvar1, result);
418 /*-----------------------------------------------------------------*/
419 /* hasSEFcalls - returns TRUE if tree has a function call, */
420 /* inc/decrement, or other side effect */
421 /*-----------------------------------------------------------------*/
423 hasSEFcalls (ast * tree)
428 if (tree->type == EX_OP &&
429 (tree->opval.op == CALL ||
430 tree->opval.op == PCALL ||
431 tree->opval.op == '=' ||
432 tree->opval.op == INC_OP ||
433 tree->opval.op == DEC_OP))
436 return (hasSEFcalls (tree->left) |
437 hasSEFcalls (tree->right));
440 /*-----------------------------------------------------------------*/
441 /* isAstEqual - compares two asts & returns 1 if they are equal */
442 /*-----------------------------------------------------------------*/
444 isAstEqual (ast * t1, ast * t2)
453 if (t1->type != t2->type)
459 if (t1->opval.op != t2->opval.op)
461 return (isAstEqual (t1->left, t2->left) &&
462 isAstEqual (t1->right, t2->right));
466 if (t1->opval.val->sym)
468 if (!t2->opval.val->sym)
471 return isSymbolEqual (t1->opval.val->sym,
476 if (t2->opval.val->sym)
479 return (floatFromVal (t1->opval.val) ==
480 floatFromVal (t2->opval.val));
484 /* only compare these two types */
492 /*-----------------------------------------------------------------*/
493 /* resolveSymbols - resolve symbols from the symbol table */
494 /*-----------------------------------------------------------------*/
496 resolveSymbols (ast * tree)
498 /* walk the entire tree and check for values */
499 /* with symbols if we find one then replace */
500 /* symbol with that from the symbol table */
507 /* if not block & function */
508 if (tree->type == EX_OP &&
509 (tree->opval.op != FUNCTION &&
510 tree->opval.op != BLOCK &&
511 tree->opval.op != NULLOP))
513 filename = tree->filename;
514 lineno = tree->lineno;
518 /* make sure we resolve the true & false labels for ifx */
519 if (tree->type == EX_OP && tree->opval.op == IFX)
525 if ((csym = findSym (LabelTab, tree->trueLabel,
526 tree->trueLabel->name)))
527 tree->trueLabel = csym;
529 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
530 tree->trueLabel->name);
533 if (tree->falseLabel)
535 if ((csym = findSym (LabelTab,
537 tree->falseLabel->name)))
538 tree->falseLabel = csym;
540 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
541 tree->falseLabel->name);
545 /* if this is a label resolve it from the labelTab */
546 if (IS_AST_VALUE (tree) &&
547 tree->opval.val->sym &&
548 tree->opval.val->sym->islbl)
550 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
551 tree->opval.val->sym->name);
554 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
555 tree->opval.val->sym->name);
557 tree->opval.val->sym = csym;
559 goto resolveChildren;
562 /* do only for leafs */
563 if (IS_AST_VALUE (tree) &&
564 tree->opval.val->sym &&
565 !tree->opval.val->sym->implicit)
567 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
569 /* if found in the symbol table & they are 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 */
579 /* is an integer in data space */
580 if (!csym && !tree->opval.val->sym->implicit)
582 /* if this is a function name then */
583 /* mark it as returning an int */
586 tree->opval.val->sym->type = newLink (DECLARATOR);
587 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
588 tree->opval.val->sym->type->next =
589 tree->opval.val->sym->etype = newIntLink ();
590 tree->opval.val->etype = tree->opval.val->etype;
591 tree->opval.val->type = tree->opval.val->sym->type;
592 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
593 tree->opval.val->sym->name);
594 //tree->opval.val->sym->undefined = 1;
595 allocVariables (tree->opval.val->sym);
599 tree->opval.val->sym->undefined = 1;
600 tree->opval.val->type =
601 tree->opval.val->etype = newIntLink ();
602 tree->opval.val->sym->type =
603 tree->opval.val->sym->etype = newIntLink ();
609 resolveSymbols (tree->left);
610 resolveSymbols (tree->right);
615 /*------------------------------------------------------------------------*/
616 /* setAstFileLine - walks a ast tree & sets the file name and line number */
617 /*------------------------------------------------------------------------*/
618 int setAstFileLine (ast * tree, char *filename, int lineno)
623 tree->filename = filename;
624 tree->lineno = lineno;
625 setAstFileLine (tree->left, filename, lineno);
626 setAstFileLine (tree->right, filename, 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 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 (E_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 /* don't perform integer promotion of explicitly typecasted variable arguments
854 * if sdcc extensions are enabled */
855 if (options.std_sdcc &&
856 (IS_CAST_OP (*actParm) ||
857 (IS_AST_SYM_VALUE (*actParm) && AST_VALUES (*actParm, removedCast)) ||
858 (IS_AST_LIT_VALUE (*actParm) && AST_VALUES (*actParm, literalFromCast))))
860 /* Parameter was explicitly typecast; don't touch it. */
864 ftype = (*actParm)->ftype;
866 resultType = RESULT_TYPE_NONE;
868 /* If it's a char, upcast to int. */
869 if (IS_INTEGRAL (ftype)
870 && (getSize (ftype) < (unsigned) INTSIZE))
872 newType = newAst_LINK(INTTYPE);
875 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
877 newType = newAst_LINK (copyLinkChain(ftype));
878 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
879 resultType = RESULT_TYPE_GPTR;
882 if (IS_AGGREGATE (ftype))
884 newType = newAst_LINK (copyLinkChain (ftype));
885 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
886 resultType = RESULT_TYPE_GPTR;
891 /* cast required; change this op to a cast. */
892 (*actParm)->decorated = 0;
893 *actParm = newNode (CAST, newType, *actParm);
894 (*actParm)->filename = (*actParm)->right->filename;
895 (*actParm)->lineno = (*actParm)->right->lineno;
897 decorateType (*actParm, resultType);
902 /* if defined parameters ended but actual has not & */
904 if (!defParm && *actParm &&
905 (options.stackAuto || IFFUNC_ISREENT (functype)))
908 resolveSymbols (*actParm);
910 /* the parameter type must be at least castable */
911 if (compareType (defParm->type, (*actParm)->ftype) == 0)
913 werror (E_INCOMPAT_TYPES);
914 printFromToType ((*actParm)->ftype, defParm->type);
918 /* if the parameter is castable then add the cast */
919 if (compareType (defParm->type, (*actParm)->ftype) < 0)
923 resultType = getResultTypeFromType (defParm->etype);
924 pTree = resolveSymbols (copyAst (*actParm));
926 /* now change the current one to a cast */
927 (*actParm)->type = EX_OP;
928 (*actParm)->opval.op = CAST;
929 (*actParm)->left = newAst_LINK (defParm->type);
930 (*actParm)->right = pTree;
931 (*actParm)->decorated = 0; /* force typechecking */
932 decorateType (*actParm, IS_GENPTR (defParm->type) ? RESULT_TYPE_GPTR : resultType);
935 /* make a copy and change the regparm type to the defined parm */
936 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
937 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
938 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
940 /* if the function is being called via a pointer & */
941 /* this parameter is not passed in registers */
942 /* then the function must be defined reentrant */
943 if (IS_FUNCPTR (func->ftype) && !SPEC_REGPARM ((*actParm)->etype) &&
944 !IFFUNC_ISREENT (functype) && !options.stackAuto)
946 werror (E_NONRENT_ARGS);
955 /*-----------------------------------------------------------------*/
956 /* createIvalType - generates ival for basic types */
957 /*-----------------------------------------------------------------*/
959 createIvalType (ast * sym, sym_link * type, initList * ilist)
963 /* if initList is deep */
964 if (ilist && ilist->type == INIT_DEEP)
965 ilist = ilist->init.deep;
968 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
970 iExpr = newAst_VALUE (valueFromLit (0));
971 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
974 /*-----------------------------------------------------------------*/
975 /* createIvalStruct - generates initial value for structures */
976 /*-----------------------------------------------------------------*/
978 createIvalStruct (ast *sym, sym_link *type, initList *ilist, ast *rootValue)
984 sym_link * etype = getSpec (type);
986 if (ilist && ilist->type != INIT_DEEP)
988 werror (E_INIT_STRUCT, "");
992 iloop = ilist ? ilist->init.deep : NULL;
994 for (sflds = SPEC_STRUCT (type)->fields; sflds; sflds = sflds->next)
996 /* if we have come to end */
997 if (!iloop && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype)))
1000 if (!IS_BITFIELD (sflds->type) || !SPEC_BUNNAMED (sflds->etype))
1002 sflds->implicit = 1;
1003 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
1004 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
1005 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast, rootValue)), RESULT_TYPE_NONE);
1006 iloop = iloop ? iloop->next : NULL;
1012 if (IS_AST_VALUE (sym))
1013 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
1014 W_EXCESS_INITIALIZERS, "struct",
1015 sym->opval.val->sym->name);
1017 werrorfl (sym->filename, sym->lineno, E_INIT_COUNT);
1023 /*-----------------------------------------------------------------*/
1024 /* createIvalArray - generates code for array initialization */
1025 /*-----------------------------------------------------------------*/
1027 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
1031 int lcnt = 0, size = 0;
1032 literalList *literalL;
1033 sym_link * etype = getSpec (type);
1035 /* take care of the special case */
1036 /* array of characters can be init */
1038 if (IS_CHAR (type->next))
1039 if ((rast = createIvalCharPtr (sym,
1041 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
1044 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1046 /* not the special case */
1047 if (ilist && ilist->type != INIT_DEEP)
1049 werror (E_INIT_STRUCT, "");
1053 iloop = ilist ? ilist->init.deep : NULL;
1054 lcnt = DCL_ELEM (type);
1057 (!lcnt || !DCL_ELEM (type) || !AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype)))
1062 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL, lcnt))
1066 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
1068 rast = newNode(ARRAYINIT, aSym, NULL);
1069 rast->values.constlist = literalL;
1071 // Make sure size is set to length of initializer list.
1075 iloop = iloop->next;
1078 if (lcnt && size > lcnt)
1080 // Array size was specified, and we have more initializers than needed.
1081 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
1082 W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
1092 (!lcnt || !DCL_ELEM (type) || !AST_SYMBOL (rootValue)->islocal || SPEC_STAT (etype)))
1097 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
1098 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
1099 rast = createIval (aSym, type->next, iloop, rast, rootValue);
1101 iloop = (iloop ? iloop->next : NULL);
1103 /* no of elements given and we */
1104 /* have generated for all of them */
1107 // is this a better way? at least it won't crash
1108 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1109 werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name);
1116 /* if we have not been given a size */
1117 if (!DCL_ELEM (type))
1119 /* check, if it's a flexible array */
1120 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1121 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1123 DCL_ELEM (type) = size;
1126 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1130 /*-----------------------------------------------------------------*/
1131 /* createIvalCharPtr - generates initial values for char pointers */
1132 /*-----------------------------------------------------------------*/
1134 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1139 /* if this is a pointer & right is a literal array then */
1140 /* just assignment will do */
1141 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1142 SPEC_SCLS (iexpr->etype) == S_CODE)
1143 && IS_ARRAY (iexpr->ftype)))
1144 return newNode ('=', sym, iexpr);
1146 /* left side is an array so we have to assign each element */
1149 /* for each character generate an assignment */
1150 /* to the array element */
1152 unsigned int symsize = getSize (type);
1154 if (!AST_SYMBOL (rootVal)->islocal || SPEC_STAT (getSpec (type)))
1157 for (i = 0; i < symsize; ++i)
1159 rast = newNode (NULLOP,
1163 newAst_VALUE (valueFromLit ((float) i))),
1164 newAst_VALUE (valueFromLit (0))));
1167 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1170 if ((IS_LITERAL (iexpr->etype) ||
1171 SPEC_SCLS (iexpr->etype) == S_CODE)
1172 && IS_ARRAY (iexpr->ftype))
1174 /* for each character generate an assignment */
1175 /* to the array element */
1176 char *s = SPEC_CVAL (iexpr->etype).v_char;
1178 unsigned int symsize = getSize (type);
1180 size = getSize (iexpr->ftype);
1181 if (symsize && size > symsize)
1185 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1187 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1193 for (i = 0; i < size; i++)
1195 rast = newNode (NULLOP,
1199 newAst_VALUE (valueFromLit ((float) i))),
1200 newAst_VALUE (valueFromLit (*s++))));
1203 // now WE don't need iexpr's symbol anymore
1204 freeStringSymbol(AST_SYMBOL(iexpr));
1206 /* if we have not been given a size */
1207 if (!DCL_ELEM (type))
1209 /* check, if it's a flexible array */
1210 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1211 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1213 DCL_ELEM (type) = size;
1216 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1222 /*-----------------------------------------------------------------*/
1223 /* createIvalPtr - generates initial value for pointers */
1224 /*-----------------------------------------------------------------*/
1226 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1232 if (ilist && ilist->type == INIT_DEEP)
1233 ilist = ilist->init.deep;
1235 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1237 /* if character pointer */
1238 if (IS_CHAR (type->next))
1239 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1242 return newNode ('=', sym, iexpr);
1245 /*-----------------------------------------------------------------*/
1246 /* createIval - generates code for initial value */
1247 /*-----------------------------------------------------------------*/
1249 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1253 if (!ilist && (!AST_SYMBOL (rootValue)->islocal || SPEC_STAT (getSpec (type))))
1256 /* if structure then */
1257 if (IS_STRUCT (type))
1258 rast = createIvalStruct (sym, type, ilist, rootValue);
1260 /* if this is a pointer */
1262 rast = createIvalPtr (sym, type, ilist, rootValue);
1264 /* if this is an array */
1265 if (IS_ARRAY (type))
1266 rast = createIvalArray (sym, type, ilist, rootValue);
1268 /* if type is SPECIFIER */
1270 rast = createIvalType (sym, type, ilist);
1273 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1275 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1278 /*-----------------------------------------------------------------*/
1279 /* initAggregates - initialises aggregate variables with initv */
1280 /*-----------------------------------------------------------------*/
1281 ast * initAggregates (symbol * sym, initList * ival, ast * wid)
1283 ast *newAst = newAst_VALUE (symbolVal (sym));
1284 return createIval (newAst, sym->type, ival, wid, newAst);
1287 /*-----------------------------------------------------------------*/
1288 /* gatherAutoInit - creates assignment expressions for initial */
1290 /*-----------------------------------------------------------------*/
1292 gatherAutoInit (symbol * autoChain)
1299 for (sym = autoChain; sym; sym = sym->next)
1301 /* resolve the symbols in the ival */
1303 resolveIvalSym (sym->ival, sym->type);
1306 /* if we are PIC16 port,
1307 * and this is a static,
1308 * and have initial value,
1309 * and not S_CODE, don't emit in gs segment,
1310 * but allow glue.c:pic16emitRegularMap to put symbol
1311 * in idata section */
1312 if(TARGET_IS_PIC16 &&
1313 IS_STATIC (sym->etype) && sym->ival
1314 && SPEC_SCLS(sym->etype) != S_CODE) {
1315 SPEC_SCLS (sym->etype) = S_DATA;
1320 /* if this is a static variable & has an */
1321 /* initial value the code needs to be lifted */
1322 /* here to the main portion since they can be */
1323 /* initialised only once at the start */
1324 if (IS_STATIC (sym->etype) && sym->ival &&
1325 SPEC_SCLS (sym->etype) != S_CODE)
1329 /* insert the symbol into the symbol table */
1330 /* with level = 0 & name = rname */
1331 newSym = copySymbol (sym);
1332 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1334 /* now lift the code to main */
1335 if (IS_AGGREGATE (sym->type)) {
1336 work = initAggregates (sym, sym->ival, NULL);
1338 if (getNelements(sym->type, sym->ival)>1) {
1339 werrorfl (sym->fileDef, sym->lineDef,
1340 W_EXCESS_INITIALIZERS, "scalar",
1343 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1344 list2expr (sym->ival));
1347 setAstFileLine (work, sym->fileDef, sym->lineDef);
1351 staticAutos = newNode (NULLOP, staticAutos, work);
1358 /* if there is an initial value */
1359 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1361 initList *ilist = sym->ival;
1363 while (ilist->type == INIT_DEEP)
1365 ilist = ilist->init.deep;
1368 /* update lineno for error msg */
1369 filename = sym->fileDef;
1370 lineno = sym->lineDef;
1371 setAstFileLine (ilist->init.node, sym->fileDef, sym->lineDef);
1373 if (IS_AGGREGATE (sym->type))
1375 work = initAggregates (sym, sym->ival, NULL);
1379 if (getNelements(sym->type, sym->ival)>1)
1381 werrorfl (sym->fileDef, sym->lineDef,
1382 W_EXCESS_INITIALIZERS, "scalar",
1385 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1386 list2expr (sym->ival));
1390 setAstFileLine (work, sym->fileDef, sym->lineDef);
1394 init = newNode (NULLOP, init, work);
1403 /*-----------------------------------------------------------------*/
1404 /* freeStringSymbol - delete a literal string if no more usage */
1405 /*-----------------------------------------------------------------*/
1406 void freeStringSymbol(symbol *sym) {
1407 /* make sure this is a literal string */
1408 assert (sym->isstrlit);
1409 if (--sym->isstrlit == 0) { // lower the usage count
1410 memmap *segment=SPEC_OCLS(sym->etype);
1412 deleteSetItem(&segment->syms, sym);
1417 /*-----------------------------------------------------------------*/
1418 /* stringToSymbol - creates a symbol from a literal string */
1419 /*-----------------------------------------------------------------*/
1421 stringToSymbol (value * val)
1423 char name[SDCC_NAME_MAX + 1];
1424 static int charLbl = 0;
1429 // have we heard this before?
1430 for (sp = statsg->syms; sp; sp = sp->next)
1433 size = getSize (sym->type);
1434 if (sym->isstrlit && size == getSize (val->type) &&
1435 !memcmp (SPEC_CVAL (sym->etype).v_char, SPEC_CVAL (val->etype).v_char, size))
1437 // yes, this is old news. Don't publish it again.
1438 sym->isstrlit++; // but raise the usage count
1439 return symbolVal (sym);
1443 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1444 sym = newSymbol (name, 0); /* make it @ level 0 */
1445 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1447 /* copy the type from the value passed */
1448 sym->type = copyLinkChain (val->type);
1449 sym->etype = getSpec (sym->type);
1450 /* change to storage class & output class */
1451 SPEC_SCLS (sym->etype) = S_CODE;
1452 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1453 SPEC_STAT (sym->etype) = 1;
1454 /* make the level & block = 0 */
1455 sym->block = sym->level = 0;
1457 /* create an ival */
1458 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1463 allocVariables (sym);
1466 return symbolVal (sym);
1470 /*-----------------------------------------------------------------*/
1471 /* processBlockVars - will go thru the ast looking for block if */
1472 /* a block is found then will allocate the syms */
1473 /* will also gather the auto inits present */
1474 /*-----------------------------------------------------------------*/
1476 processBlockVars (ast * tree, int *stack, int action)
1481 /* if this is a block */
1482 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1486 if (action == ALLOCATE)
1488 *stack += allocVariables (tree->values.sym);
1489 autoInit = gatherAutoInit (tree->values.sym);
1491 /* if there are auto inits then do them */
1493 tree->left = newNode (NULLOP, autoInit, tree->left);
1495 else /* action is deallocate */
1496 deallocLocal (tree->values.sym);
1499 processBlockVars (tree->left, stack, action);
1500 processBlockVars (tree->right, stack, action);
1504 /*-------------------------------------------------------------*/
1505 /* constExprTree - returns TRUE if this tree is a constant */
1507 /*-------------------------------------------------------------*/
1508 bool constExprTree (ast *cexpr) {
1514 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1516 switch (cexpr->type)
1519 if (IS_AST_LIT_VALUE(cexpr)) {
1520 // this is a literal
1523 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1524 // a function's address will never change
1527 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1528 // an array's address will never change
1531 if (IS_AST_SYM_VALUE(cexpr) &&
1532 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1533 // a symbol in code space will never change
1534 // This is only for the 'char *s="hallo"' case and will have to leave
1535 //printf(" code space symbol");
1540 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1541 "unexpected link in expression tree\n");
1544 if (cexpr->opval.op==ARRAYINIT) {
1545 // this is a list of literals
1548 if (cexpr->opval.op=='=') {
1549 return constExprTree(cexpr->right);
1551 if (cexpr->opval.op==CAST) {
1552 // cast ignored, maybe we should throw a warning here?
1553 return constExprTree(cexpr->right);
1555 if (cexpr->opval.op=='&') {
1558 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1561 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1566 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1571 /*-----------------------------------------------------------------*/
1572 /* constExprValue - returns the value of a constant expression */
1573 /* or NULL if it is not a constant expression */
1574 /*-----------------------------------------------------------------*/
1576 constExprValue (ast * cexpr, int check)
1578 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1580 /* if this is not a constant then */
1581 if (!IS_LITERAL (cexpr->ftype))
1583 /* then check if this is a literal array
1585 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1586 SPEC_CVAL (cexpr->etype).v_char &&
1587 IS_ARRAY (cexpr->ftype))
1589 value *val = valFromType (cexpr->ftype);
1590 SPEC_SCLS (val->etype) = S_LITERAL;
1591 val->sym = cexpr->opval.val->sym;
1592 val->sym->type = copyLinkChain (cexpr->ftype);
1593 val->sym->etype = getSpec (val->sym->type);
1594 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1598 /* if we are casting a literal value then */
1599 if (IS_AST_OP (cexpr) &&
1600 cexpr->opval.op == CAST &&
1601 IS_LITERAL (cexpr->right->ftype))
1603 return valCastLiteral (cexpr->ftype,
1604 floatFromVal (cexpr->right->opval.val));
1607 if (IS_AST_VALUE (cexpr))
1609 return cexpr->opval.val;
1613 werror (E_CONST_EXPECTED, "found expression");
1618 /* return the value */
1619 if (IS_AST_VALUE (cexpr))
1621 return cexpr->opval.val;
1626 /*-----------------------------------------------------------------*/
1627 /* isLabelInAst - will return true if a given label is found */
1628 /*-----------------------------------------------------------------*/
1630 isLabelInAst (symbol * label, ast * tree)
1632 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1635 if (IS_AST_OP (tree) &&
1636 tree->opval.op == LABEL &&
1637 isSymbolEqual (AST_SYMBOL (tree->left), label))
1640 return isLabelInAst (label, tree->right) &&
1641 isLabelInAst (label, tree->left);
1644 /*-----------------------------------------------------------------*/
1645 /* isLoopCountable - return true if the loop count can be determi- */
1646 /* -ned at compile time . */
1647 /*-----------------------------------------------------------------*/
1649 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1650 symbol ** sym, ast ** init, ast ** end)
1653 /* the loop is considered countable if the following
1654 conditions are true :-
1656 a) initExpr :- <sym> = <const>
1657 b) condExpr :- <sym> < <const1>
1658 c) loopExpr :- <sym> ++
1661 /* first check the initExpr */
1662 if (IS_AST_OP (initExpr) &&
1663 initExpr->opval.op == '=' && /* is assignment */
1664 IS_AST_SYM_VALUE (initExpr->left))
1665 { /* left is a symbol */
1667 *sym = AST_SYMBOL (initExpr->left);
1668 *init = initExpr->right;
1673 /* don't reverse loop with volatile counter */
1674 if (IS_VOLATILE ((*sym)->type))
1677 /* for now the symbol has to be of
1679 if (!IS_INTEGRAL ((*sym)->type))
1682 /* now check condExpr */
1683 if (IS_AST_OP (condExpr))
1686 switch (condExpr->opval.op)
1689 if (IS_AST_SYM_VALUE (condExpr->left) &&
1690 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1691 IS_AST_LIT_VALUE (condExpr->right))
1693 *end = condExpr->right;
1699 if (IS_AST_OP (condExpr->left) &&
1700 condExpr->left->opval.op == '>' &&
1701 IS_AST_LIT_VALUE (condExpr->left->right) &&
1702 IS_AST_SYM_VALUE (condExpr->left->left) &&
1703 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1706 *end = newNode ('+', condExpr->left->right,
1707 newAst_VALUE (constCharVal (1)));
1720 /* check loop expression is of the form <sym>++ */
1721 if (!IS_AST_OP (loopExpr))
1724 /* check if <sym> ++ */
1725 if (loopExpr->opval.op == INC_OP)
1731 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1732 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1739 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1740 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1748 if (loopExpr->opval.op == ADD_ASSIGN)
1751 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1752 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1753 IS_AST_LIT_VALUE (loopExpr->right) &&
1754 AST_ULONG_VALUE (loopExpr->right) != 1)
1762 /*-----------------------------------------------------------------*/
1763 /* astHasVolatile - returns true if ast contains any volatile */
1764 /*-----------------------------------------------------------------*/
1766 astHasVolatile (ast * tree)
1771 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1774 if (IS_AST_OP (tree))
1775 return astHasVolatile (tree->left) ||
1776 astHasVolatile (tree->right);
1781 /*-----------------------------------------------------------------*/
1782 /* astHasPointer - return true if the ast contains any ptr variable */
1783 /*-----------------------------------------------------------------*/
1785 astHasPointer (ast * tree)
1790 if (IS_AST_LINK (tree))
1793 /* if we hit an array expression then check
1794 only the left side */
1795 if (IS_AST_OP (tree) && tree->opval.op == '[')
1796 return astHasPointer (tree->left);
1798 if (IS_AST_VALUE (tree))
1799 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1801 return astHasPointer (tree->left) ||
1802 astHasPointer (tree->right);
1806 /*-----------------------------------------------------------------*/
1807 /* astHasSymbol - return true if the ast has the given symbol */
1808 /*-----------------------------------------------------------------*/
1810 astHasSymbol (ast * tree, symbol * sym)
1812 if (!tree || IS_AST_LINK (tree))
1815 if (IS_AST_VALUE (tree))
1817 if (IS_AST_SYM_VALUE (tree))
1818 return isSymbolEqual (AST_SYMBOL (tree), sym);
1823 return astHasSymbol (tree->left, sym) ||
1824 astHasSymbol (tree->right, sym);
1827 /*-----------------------------------------------------------------*/
1828 /* astHasDeref - return true if the ast has an indirect access */
1829 /*-----------------------------------------------------------------*/
1831 astHasDeref (ast * tree)
1833 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1836 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1838 return astHasDeref (tree->left) || astHasDeref (tree->right);
1841 /*-----------------------------------------------------------------*/
1842 /* isConformingBody - the loop body has to conform to a set of */
1843 /* rules for the loop to be considered reversible read on for rules*/
1844 /*-----------------------------------------------------------------*/
1846 isConformingBody (ast * pbody, symbol * sym, ast * body)
1849 /* we are going to do a pre-order traversal of the
1850 tree && check for the following conditions. (essentially
1851 a set of very shallow tests )
1852 a) the sym passed does not participate in any arithmetic operation
1853 b) There are no function calls
1854 c) all jumps are within the body
1855 d) address of loop control variable not taken
1856 e) if an assignment has a pointer on the left hand side make sure
1857 right does not have loop control variable
1860 /* if we reach the end or a leaf then true */
1861 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1864 /* if anything else is "volatile" */
1865 if (IS_VOLATILE (TETYPE (pbody)))
1868 /* we will walk the body in a pre-order traversal for
1870 switch (pbody->opval.op)
1872 /*------------------------------------------------------------------*/
1874 // if the loopvar is used as an index
1875 /* array op is commutative -- must check both left & right */
1876 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1879 return isConformingBody (pbody->right, sym, body)
1880 && isConformingBody (pbody->left, sym, body);
1882 /*------------------------------------------------------------------*/
1887 /*------------------------------------------------------------------*/
1891 /* sure we are not sym is not modified */
1893 IS_AST_SYM_VALUE (pbody->left) &&
1894 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1898 IS_AST_SYM_VALUE (pbody->right) &&
1899 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1904 /*------------------------------------------------------------------*/
1906 case '*': /* can be unary : if right is null then unary operation */
1911 /* if right is NULL then unary operation */
1912 /*------------------------------------------------------------------*/
1913 /*----------------------------*/
1915 /*----------------------------*/
1918 if (IS_AST_SYM_VALUE (pbody->left) &&
1919 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1922 return isConformingBody (pbody->left, sym, body);
1926 if (astHasSymbol (pbody->left, sym) ||
1927 astHasSymbol (pbody->right, sym))
1932 /*------------------------------------------------------------------*/
1943 if (IS_AST_SYM_VALUE (pbody->left) &&
1944 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1947 if (IS_AST_SYM_VALUE (pbody->right) &&
1948 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1951 return isConformingBody (pbody->left, sym, body) &&
1952 isConformingBody (pbody->right, sym, body);
1960 if (IS_AST_SYM_VALUE (pbody->left) &&
1961 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1963 return isConformingBody (pbody->left, sym, body);
1965 /*------------------------------------------------------------------*/
1977 case SIZEOF: /* evaluate wihout code generation */
1979 if (IS_AST_SYM_VALUE (pbody->left) &&
1980 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1983 if (IS_AST_SYM_VALUE (pbody->right) &&
1984 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1987 return isConformingBody (pbody->left, sym, body) &&
1988 isConformingBody (pbody->right, sym, body);
1990 /*------------------------------------------------------------------*/
1993 /* if left has a pointer & right has loop
1994 control variable then we cannot */
1995 if (astHasPointer (pbody->left) &&
1996 astHasSymbol (pbody->right, sym))
1998 if (astHasVolatile (pbody->left))
2001 if (IS_AST_SYM_VALUE (pbody->left)) {
2002 // if the loopvar has an assignment
2003 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
2005 // if the loopvar is used in another (maybe conditional) block
2006 if (astHasSymbol (pbody->right, sym) &&
2007 (pbody->level >= body->level)) {
2012 if (astHasVolatile (pbody->left))
2015 if (astHasDeref(pbody->right))
2018 return isConformingBody (pbody->left, sym, body) &&
2019 isConformingBody (pbody->right, sym, body);
2030 assert ("Parser should not have generated this\n");
2032 /*------------------------------------------------------------------*/
2033 /*----------------------------*/
2034 /* comma operator */
2035 /*----------------------------*/
2037 return isConformingBody (pbody->left, sym, body) &&
2038 isConformingBody (pbody->right, sym, body);
2040 /*------------------------------------------------------------------*/
2041 /*----------------------------*/
2043 /*----------------------------*/
2045 /* if local & not passed as parameter &
2046 not used to find the function then ok */
2047 if (sym->level && !astHasSymbol (pbody->right, sym) &&
2048 !astHasSymbol (pbody->left, sym))
2054 /*------------------------------------------------------------------*/
2055 /*----------------------------*/
2056 /* return statement */
2057 /*----------------------------*/
2062 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
2067 if (astHasSymbol (pbody->left, sym))
2074 return isConformingBody (pbody->left, sym, body) &&
2075 isConformingBody (pbody->right, sym, body);
2078 /*-----------------------------------------------------------------*/
2079 /* isLoopReversible - takes a for loop as input && returns true */
2080 /* if the for loop is reversible. If yes will set the value of */
2081 /* the loop control var & init value & termination value */
2082 /*-----------------------------------------------------------------*/
2084 isLoopReversible (ast * loop, symbol ** loopCntrl,
2085 ast ** init, ast ** end)
2087 /* if option says don't do it then don't */
2088 if (optimize.noLoopReverse)
2090 /* there are several tests to determine this */
2092 /* for loop has to be of the form
2093 for ( <sym> = <const1> ;
2094 [<sym> < <const2>] ;
2095 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
2097 if (!isLoopCountable (AST_FOR (loop, initExpr),
2098 AST_FOR (loop, condExpr),
2099 AST_FOR (loop, loopExpr),
2100 loopCntrl, init, end))
2103 /* now do some serious checking on the body of the loop
2106 return isConformingBody (loop->left, *loopCntrl, loop->left);
2110 /*-----------------------------------------------------------------*/
2111 /* replLoopSym - replace the loop sym by loop sym -1 */
2112 /*-----------------------------------------------------------------*/
2114 replLoopSym (ast * body, symbol * sym)
2117 if (!body || IS_AST_LINK (body))
2120 if (IS_AST_SYM_VALUE (body))
2123 if (isSymbolEqual (AST_SYMBOL (body), sym))
2127 body->opval.op = '-';
2128 body->left = newAst_VALUE (symbolVal (sym));
2129 body->right = newAst_VALUE (constCharVal (1));
2137 replLoopSym (body->left, sym);
2138 replLoopSym (body->right, sym);
2142 /*-----------------------------------------------------------------*/
2143 /* reverseLoop - do the actual loop reversal */
2144 /*-----------------------------------------------------------------*/
2146 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
2150 /* create the following tree
2155 if (sym) goto for_continue ;
2158 /* put it together piece by piece */
2159 rloop = newNode (NULLOP,
2160 createIf (newAst_VALUE (symbolVal (sym)),
2162 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2165 newAst_VALUE (symbolVal (sym)),
2168 replLoopSym (loop->left, sym);
2169 setAstFileLine (rloop, init->filename, init->lineno);
2171 rloop = newNode (NULLOP,
2173 newAst_VALUE (symbolVal (sym)),
2174 newNode ('-', end, init)),
2175 createLabel (AST_FOR (loop, continueLabel),
2179 newNode (SUB_ASSIGN,
2180 newAst_VALUE (symbolVal (sym)),
2181 newAst_VALUE (constCharVal (1))),
2184 rloop->lineno=init->lineno;
2185 return decorateType (rloop, RESULT_TYPE_NONE);
2189 /*-----------------------------------------------------------------*/
2190 /* searchLitOp - search tree (*ops only) for an ast with literal */
2191 /*-----------------------------------------------------------------*/
2193 searchLitOp (ast *tree, ast **parent, const char *ops)
2197 if (tree && optimize.global_cse)
2199 /* is there a literal operand? */
2201 IS_AST_OP(tree->right) &&
2202 tree->right->right &&
2203 (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1]))
2205 if (IS_LITERAL (RTYPE (tree->right)) !=
2206 IS_LITERAL (LTYPE (tree->right)))
2208 tree->right->decorated = 0;
2209 tree->decorated = 0;
2213 ret = searchLitOp (tree->right, parent, ops);
2218 IS_AST_OP(tree->left) &&
2219 tree->left->right &&
2220 (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1]))
2222 if (IS_LITERAL (RTYPE (tree->left)) !=
2223 IS_LITERAL (LTYPE (tree->left)))
2225 tree->left->decorated = 0;
2226 tree->decorated = 0;
2230 ret = searchLitOp (tree->left, parent, ops);
2238 /*-----------------------------------------------------------------*/
2239 /* getResultFromType */
2240 /*-----------------------------------------------------------------*/
2242 getResultTypeFromType (sym_link *type)
2244 /* type = getSpec (type); */
2246 return RESULT_TYPE_BIT;
2247 if (IS_BITFIELD (type))
2249 int blen = SPEC_BLEN (type);
2252 return RESULT_TYPE_BIT;
2254 return RESULT_TYPE_CHAR;
2255 return RESULT_TYPE_INT;
2258 return RESULT_TYPE_CHAR;
2259 if (IS_INT (type) && !IS_LONG (type))
2260 return RESULT_TYPE_INT;
2261 return RESULT_TYPE_OTHER;
2264 /*-----------------------------------------------------------------*/
2265 /* addCast - adds casts to a type specified by RESULT_TYPE */
2266 /*-----------------------------------------------------------------*/
2268 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2271 bool upCasted = FALSE;
2275 case RESULT_TYPE_NONE:
2276 /* if thing smaller than int must be promoted to int */
2278 getSize (tree->etype) >= INTSIZE)
2279 /* promotion not necessary or already an int */
2281 /* char and bits: promote to int */
2282 newLink = newIntLink();
2285 case RESULT_TYPE_BIT:
2287 /* already an int */
2288 bitsForType (tree->etype) >= 16 ||
2289 /* bit to bit operation: don't promote, the code generators
2290 hopefully know everything about promotion rules */
2291 bitsForType (tree->etype) == 1)
2293 newLink = newIntLink();
2296 case RESULT_TYPE_CHAR:
2297 if (IS_CHAR (tree->etype) ||
2298 IS_FLOAT(tree->etype) ||
2299 IS_FIXED(tree->etype))
2301 newLink = newCharLink();
2303 case RESULT_TYPE_INT:
2305 if (getSize (tree->etype) > INTSIZE)
2307 /* warn ("Loosing significant digits"); */
2311 /* char: promote to int */
2313 getSize (tree->etype) >= INTSIZE)
2315 newLink = newIntLink();
2318 case RESULT_TYPE_IFX:
2319 case RESULT_TYPE_OTHER:
2321 /* return type is ifx, long, float: promote char to int */
2322 getSize (tree->etype) >= INTSIZE)
2324 newLink = newIntLink();
2330 tree->decorated = 0;
2331 tree = newNode (CAST, newAst_LINK (newLink), tree);
2332 tree->filename = tree->right->filename;
2333 tree->lineno = tree->right->lineno;
2334 /* keep unsigned type during cast to smaller type,
2335 but not when promoting from char to int */
2337 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2338 return decorateType (tree, resultType);
2341 /*-----------------------------------------------------------------*/
2342 /* resultTypePropagate - decides if resultType can be propagated */
2343 /*-----------------------------------------------------------------*/
2345 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2347 switch (tree->opval.op)
2364 if ((IS_AST_VALUE (tree->left) && !IS_INTEGRAL (tree->left->opval.val->etype)) ||
2365 (IS_AST_VALUE (tree->right) && !IS_INTEGRAL (tree->right->opval.val->etype)))
2366 return RESULT_TYPE_NONE;
2371 return RESULT_TYPE_NONE;
2375 return RESULT_TYPE_IFX;
2377 return RESULT_TYPE_NONE;
2381 /*-----------------------------------------------------------------*/
2382 /* getLeftResultType - gets type from left branch for propagation */
2383 /*-----------------------------------------------------------------*/
2385 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2387 switch (tree->opval.op)
2391 if (IS_PTR (LTYPE (tree)))
2392 return RESULT_TYPE_NONE;
2394 return getResultTypeFromType (LETYPE (tree));
2396 if (IS_PTR (currFunc->type->next))
2397 return RESULT_TYPE_NONE;
2399 return getResultTypeFromType (currFunc->type->next);
2401 if (!IS_ARRAY (LTYPE (tree)))
2403 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2404 return RESULT_TYPE_CHAR;
2411 /*------------------------------------------------------------------*/
2412 /* gatherImplicitVariables: assigns correct type information to */
2413 /* symbols and values created by replaceAstWithTemporary */
2414 /* and adds the symbols to the declarations list of the */
2415 /* innermost block that contains them */
2416 /*------------------------------------------------------------------*/
2418 gatherImplicitVariables (ast * tree, ast * block)
2423 if (tree->type == EX_OP && tree->opval.op == BLOCK)
2425 /* keep track of containing scope */
2428 if (tree->type == EX_OP && tree->opval.op == '=' &&
2429 tree->left->type == EX_VALUE && tree->left->opval.val->sym)
2431 symbol *assignee = tree->left->opval.val->sym;
2433 /* special case for assignment to compiler-generated temporary variable:
2434 compute type of RHS, and set the symbol's type to match */
2435 if (assignee->type == NULL && assignee->infertype) {
2436 ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
2438 if (dtr != tree->right)
2441 assignee->type = copyLinkChain(TTYPE(dtr));
2442 assignee->etype = getSpec(assignee->type);
2443 SPEC_SCLS (assignee->etype) = S_AUTO;
2444 SPEC_OCLS (assignee->etype) = NULL;
2445 SPEC_EXTR (assignee->etype) = 0;
2446 SPEC_STAT (assignee->etype) = 0;
2447 SPEC_VOLATILE (assignee->etype) = 0;
2448 SPEC_ABSA (assignee->etype) = 0;
2450 wassertl(block != NULL, "implicit variable not contained in block");
2451 wassert(assignee->next == NULL);
2452 if (block != NULL) {
2453 symbol **decl = &(block->values.sym);
2456 wassert(*decl != assignee); /* should not already be in list */
2457 decl = &( (*decl)->next );
2464 if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) &&
2465 tree->opval.val->type == NULL &&
2466 tree->opval.val->sym &&
2467 tree->opval.val->sym->infertype)
2469 /* fixup type of value for compiler-inferred temporary var */
2470 tree->opval.val->type = tree->opval.val->sym->type;
2471 tree->opval.val->etype = tree->opval.val->sym->etype;
2474 gatherImplicitVariables(tree->left, block);
2475 gatherImplicitVariables(tree->right, block);
2478 /*--------------------------------------------------------------------*/
2479 /* decorateType - compute type for this tree, also does type checking.*/
2480 /* This is done bottom up, since type has to flow upwards. */
2481 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2482 /* result is a char and the operand(s) are int's. */
2483 /* It also does constant folding, and parameter checking. */
2484 /*--------------------------------------------------------------------*/
2486 decorateType (ast * tree, RESULT_TYPE resultType)
2490 RESULT_TYPE resultTypeProp;
2495 /* if already has type then do nothing */
2496 if (tree->decorated)
2499 tree->decorated = 1;
2502 /* print the line */
2503 /* if not block & function */
2504 if (tree->type == EX_OP &&
2505 (tree->opval.op != FUNCTION &&
2506 tree->opval.op != BLOCK &&
2507 tree->opval.op != NULLOP))
2509 filename = tree->filename;
2510 lineno = tree->lineno;
2514 /* if any child is an error | this one is an error do nothing */
2515 if (tree->isError ||
2516 (tree->left && tree->left->isError) ||
2517 (tree->right && tree->right->isError))
2520 /*------------------------------------------------------------------*/
2521 /*----------------------------*/
2522 /* leaf has been reached */
2523 /*----------------------------*/
2524 filename = tree->filename;
2525 lineno = tree->lineno;
2526 /* if this is of type value */
2527 /* just get the type */
2528 if (tree->type == EX_VALUE)
2530 if (IS_LITERAL (tree->opval.val->etype))
2532 /* if this is a character array then declare it */
2533 if (IS_ARRAY (tree->opval.val->type))
2534 tree->opval.val = stringToSymbol (tree->opval.val);
2536 /* otherwise just copy the type information */
2537 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2541 if (tree->opval.val->sym)
2543 /* if the undefined flag is set then give error message */
2544 if (tree->opval.val->sym->undefined)
2546 werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name);
2548 TTYPE (tree) = TETYPE (tree) =
2549 tree->opval.val->type = tree->opval.val->sym->type =
2550 tree->opval.val->etype = tree->opval.val->sym->etype =
2551 copyLinkChain (INTTYPE);
2553 else if (tree->opval.val->sym->implicit)
2555 /* if implicit i.e. struct/union member then no type */
2556 TTYPE (tree) = TETYPE (tree) = NULL;
2560 /* copy the type from the value into the ast */
2561 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2563 /* and mark the symbol as referenced */
2564 tree->opval.val->sym->isref = 1;
2568 wassert(0); /* unreached: all values are literals or symbols */
2573 /* if type link for the case of cast */
2574 if (tree->type == EX_LINK)
2576 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2584 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2586 if (tree->left && tree->left->type == EX_OPERAND
2587 && (tree->left->opval.op == INC_OP
2588 || tree->left->opval.op == DEC_OP)
2589 && tree->left->left)
2591 tree->left->right = tree->left->left;
2592 tree->left->left = NULL;
2594 if (tree->right && tree->right->type == EX_OPERAND
2595 && (tree->right->opval.op == INC_OP
2596 || tree->right->opval.op == DEC_OP)
2597 && tree->right->left)
2599 tree->right->right = tree->right->left;
2600 tree->right->left = NULL;
2605 /* Before decorating the left branch we've to decide in dependence
2606 upon tree->opval.op, if resultType can be propagated */
2607 resultTypeProp = resultTypePropagate (tree, resultType);
2609 if ((tree->opval.op == '?') && (resultTypeProp != RESULT_TYPE_BIT))
2610 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2612 dtl = decorateType (tree->left, resultTypeProp);
2614 /* if an array node, we may need to swap branches */
2615 if (tree->opval.op == '[')
2617 /* determine which is the array & which the index */
2618 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2619 IS_INTEGRAL (LTYPE (tree)))
2621 ast *tempTree = tree->left;
2622 tree->left = tree->right;
2623 tree->right = tempTree;
2627 /* After decorating the left branch there's type information available
2628 in tree->left->?type. If the op is e.g. '=' we extract the type
2629 information from there and propagate it to the right branch. */
2630 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2632 switch (tree->opval.op)
2635 /* delay right side for '?' operator since conditional macro
2636 expansions might rely on this */
2640 /* decorate right side for CALL (parameter list) in processParms();
2641 there is resultType available */
2645 /* don't allocate string if it is a sizeof argument */
2647 dtr = decorateType (tree->right, resultTypeProp);
2651 dtr = decorateType (tree->right, resultTypeProp);
2655 /* this is to take care of situations
2656 when the tree gets rewritten */
2657 if (dtl != tree->left)
2659 if (dtr != tree->right)
2661 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2665 /* depending on type of operator do */
2667 switch (tree->opval.op)
2669 /*------------------------------------------------------------------*/
2670 /*----------------------------*/
2672 /*----------------------------*/
2675 /* first check if this is a array or a pointer */
2676 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2678 werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
2679 goto errorTreeReturn;
2682 /* check if the type of the idx */
2683 if (!IS_INTEGRAL (RTYPE (tree)))
2685 werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
2686 goto errorTreeReturn;
2689 /* if the left is an rvalue then error */
2692 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
2693 goto errorTreeReturn;
2696 if (IS_LITERAL (RTYPE (tree)))
2698 int arrayIndex = (int) ulFromVal (valFromType (RETYPE (tree)));
2699 int arraySize = DCL_ELEM (LTYPE (tree));
2700 if (arraySize && arrayIndex >= arraySize)
2702 werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2707 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2708 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2711 /*------------------------------------------------------------------*/
2712 /*----------------------------*/
2714 /*----------------------------*/
2716 /* if this is not a structure */
2717 if (!IS_STRUCT (LTYPE (tree)))
2719 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
2720 goto errorTreeReturn;
2722 TTYPE (tree) = structElemType (LTYPE (tree),
2723 (tree->right->type == EX_VALUE ?
2724 tree->right->opval.val : NULL));
2725 TETYPE (tree) = getSpec (TTYPE (tree));
2728 /*------------------------------------------------------------------*/
2729 /*----------------------------*/
2730 /* struct/union pointer */
2731 /*----------------------------*/
2733 /* if not pointer to a structure */
2734 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2736 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
2737 goto errorTreeReturn;
2740 if (!IS_STRUCT (LTYPE (tree)->next))
2742 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
2743 goto errorTreeReturn;
2746 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2747 (tree->right->type == EX_VALUE ?
2748 tree->right->opval.val : NULL));
2749 TETYPE (tree) = getSpec (TTYPE (tree));
2751 /* adjust the storage class */
2752 switch (DCL_TYPE(tree->left->ftype)) {
2754 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2757 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2760 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2763 SPEC_SCLS (TETYPE (tree)) = 0;
2766 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2769 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2772 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2775 SPEC_SCLS (TETYPE (tree)) = 0;
2782 /* This breaks with extern declarations, bitfields, and perhaps other */
2783 /* cases (gcse). Let's leave this optimization disabled for now and */
2784 /* ponder if there's a safe way to do this. -- EEP */
2786 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2787 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2789 /* If defined struct type at addr var
2790 then rewrite (&struct var)->member
2792 and define membertype at (addr+offsetof(struct var,member)) temp
2795 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2796 AST_SYMBOL(tree->right));
2798 sym = newSymbol(genSymName (0), 0);
2799 sym->type = TTYPE (tree);
2800 sym->etype = getSpec(sym->type);
2801 sym->lineDef = tree->lineno;
2804 SPEC_STAT (sym->etype) = 1;
2805 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2807 SPEC_ABSA(sym->etype) = 1;
2808 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2811 AST_VALUE (tree) = symbolVal(sym);
2814 tree->type = EX_VALUE;
2822 /*------------------------------------------------------------------*/
2823 /*----------------------------*/
2824 /* ++/-- operation */
2825 /*----------------------------*/
2829 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2830 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2831 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2832 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2841 /*------------------------------------------------------------------*/
2842 /*----------------------------*/
2844 /*----------------------------*/
2845 case '&': /* can be unary */
2846 /* if right is NULL then unary operation */
2847 if (tree->right) /* not an unary operation */
2850 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2852 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2853 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2854 printTypeChain (LTYPE (tree), stderr);
2855 fprintf (stderr, ",");
2856 printTypeChain (RTYPE (tree), stderr);
2857 fprintf (stderr, "\n");
2858 goto errorTreeReturn;
2861 /* if they are both literal */
2862 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2864 tree->type = EX_VALUE;
2865 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2866 valFromType (RETYPE (tree)), '&');
2868 tree->right = tree->left = NULL;
2869 TETYPE (tree) = tree->opval.val->etype;
2870 TTYPE (tree) = tree->opval.val->type;
2874 /* see if this is a GETHBIT operation if yes
2877 ast *otree = optimizeGetHbit (tree, resultType);
2880 return decorateType (otree, RESULT_TYPE_NONE);
2883 /* see if this is a GETABIT operation if yes
2886 ast *otree = optimizeGetAbit (tree, resultType);
2889 return decorateType (otree, RESULT_TYPE_NONE);
2892 /* see if this is a GETBYTE operation if yes
2895 ast *otree = optimizeGetByte (tree, resultType);
2898 return decorateType (otree, RESULT_TYPE_NONE);
2901 /* see if this is a GETWORD operation if yes
2904 ast *otree = optimizeGetWord (tree, resultType);
2907 return decorateType (otree, RESULT_TYPE_NONE);
2910 /* if left is a literal exchange left & right */
2911 if (IS_LITERAL (LTYPE (tree)))
2913 ast *tTree = tree->left;
2914 tree->left = tree->right;
2915 tree->right = tTree;
2918 /* if right is a literal and */
2919 /* we can find a 2nd literal in an and-tree then */
2920 /* rearrange the tree */
2921 if (IS_LITERAL (RTYPE (tree)))
2924 ast *litTree = searchLitOp (tree, &parent, "&");
2928 ast *tTree = litTree->left;
2929 litTree->left = tree->right;
2930 tree->right = tTree;
2931 /* both operands in litTree are literal now */
2932 decorateType (parent, resultType);
2936 LRVAL (tree) = RRVAL (tree) = 1;
2938 TTYPE (tree) = computeType (LTYPE (tree),
2942 TETYPE (tree) = getSpec (TTYPE (tree));
2947 /*------------------------------------------------------------------*/
2948 /*----------------------------*/
2950 /*----------------------------*/
2951 p = newLink (DECLARATOR);
2952 /* if bit field then error */
2953 if (IS_BITVAR (tree->left->etype))
2955 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
2956 goto errorTreeReturn;
2959 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2961 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
2962 goto errorTreeReturn;
2965 if (IS_FUNC (LTYPE (tree)))
2967 // this ought to be ignored
2968 return (tree->left);
2971 if (IS_LITERAL(LTYPE(tree)))
2973 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
2974 goto errorTreeReturn;
2979 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
2980 goto errorTreeReturn;
2983 DCL_TYPE (p) = POINTER;
2984 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2985 DCL_TYPE (p) = CPOINTER;
2986 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2987 DCL_TYPE (p) = FPOINTER;
2988 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2989 DCL_TYPE (p) = PPOINTER;
2990 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2991 DCL_TYPE (p) = IPOINTER;
2992 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2993 DCL_TYPE (p) = EEPPOINTER;
2994 else if (SPEC_OCLS(tree->left->etype))
2995 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2997 DCL_TYPE (p) = POINTER;
2999 if (IS_AST_SYM_VALUE (tree->left))
3001 AST_SYMBOL (tree->left)->addrtaken = 1;
3002 AST_SYMBOL (tree->left)->allocreq = 1;
3005 p->next = LTYPE (tree);
3007 TETYPE (tree) = getSpec (TTYPE (tree));
3012 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
3013 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
3015 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
3016 AST_SYMBOL(tree->left->right));
3017 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
3018 valueFromLit(element->offset));
3021 tree->type = EX_VALUE;
3022 tree->values.literalFromCast = 1;
3028 /*------------------------------------------------------------------*/
3029 /*----------------------------*/
3031 /*----------------------------*/
3033 /* if the rewrite succeeds then don't go any further */
3035 ast *wtree = optimizeRRCRLC (tree);
3037 return decorateType (wtree, RESULT_TYPE_NONE);
3039 wtree = optimizeSWAP (tree);
3041 return decorateType (wtree, RESULT_TYPE_NONE);
3044 /* if left is a literal exchange left & right */
3045 if (IS_LITERAL (LTYPE (tree)))
3047 ast *tTree = tree->left;
3048 tree->left = tree->right;
3049 tree->right = tTree;
3052 /* if right is a literal and */
3053 /* we can find a 2nd literal in an or-tree then */
3054 /* rearrange the tree */
3055 if (IS_LITERAL (RTYPE (tree)))
3058 ast *litTree = searchLitOp (tree, &parent, "|");
3062 ast *tTree = litTree->left;
3063 litTree->left = tree->right;
3064 tree->right = tTree;
3065 /* both operands in tTree are literal now */
3066 decorateType (parent, resultType);
3071 /*------------------------------------------------------------------*/
3072 /*----------------------------*/
3074 /*----------------------------*/
3076 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3078 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3079 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3080 printTypeChain (LTYPE (tree), stderr);
3081 fprintf (stderr, ",");
3082 printTypeChain (RTYPE (tree), stderr);
3083 fprintf (stderr, "\n");
3084 goto errorTreeReturn;
3087 /* if they are both literal then rewrite the tree */
3088 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3090 tree->type = EX_VALUE;
3091 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3092 valFromType (RETYPE (tree)),
3094 tree->right = tree->left = NULL;
3095 TETYPE (tree) = tree->opval.val->etype;
3096 TTYPE (tree) = tree->opval.val->type;
3100 /* if left is a literal exchange left & right */
3101 if (IS_LITERAL (LTYPE (tree)))
3103 ast *tTree = tree->left;
3104 tree->left = tree->right;
3105 tree->right = tTree;
3108 /* if right is a literal and */
3109 /* we can find a 2nd literal in a xor-tree then */
3110 /* rearrange the tree */
3111 if (IS_LITERAL (RTYPE (tree)) &&
3112 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3115 ast *litTree = searchLitOp (tree, &parent, "^");
3119 ast *tTree = litTree->left;
3120 litTree->left = tree->right;
3121 tree->right = tTree;
3122 /* both operands in litTree are literal now */
3123 decorateType (parent, resultType);
3127 LRVAL (tree) = RRVAL (tree) = 1;
3129 TTYPE (tree) = computeType (LTYPE (tree),
3133 TETYPE (tree) = getSpec (TTYPE (tree));
3137 /*------------------------------------------------------------------*/
3138 /*----------------------------*/
3140 /*----------------------------*/
3142 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3144 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
3145 goto errorTreeReturn;
3147 /* if they are both literal then */
3148 /* rewrite the tree */
3149 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3151 tree->type = EX_VALUE;
3152 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
3153 valFromType (RETYPE (tree)));
3154 tree->right = tree->left = NULL;
3155 TETYPE (tree) = getSpec (TTYPE (tree) =
3156 tree->opval.val->type);
3160 LRVAL (tree) = RRVAL (tree) = 1;
3162 TETYPE (tree) = getSpec (TTYPE (tree) =
3163 computeType (LTYPE (tree),
3168 /* if right is a literal and */
3169 /* left is also a division by a literal then */
3170 /* rearrange the tree */
3171 if (IS_LITERAL (RTYPE (tree))
3172 /* avoid infinite loop */
3173 && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 1)
3176 ast *litTree = searchLitOp (tree, &parent, "/");
3179 if (IS_LITERAL (RTYPE (litTree)))
3183 litTree->right = newNode ('*',
3185 copyAst (tree->right));
3186 litTree->right->filename = tree->filename;
3187 litTree->right->lineno = tree->lineno;
3189 tree->right->opval.val = constCharVal (1);
3190 decorateType (parent, resultType);
3194 /* litTree->left is literal: no gcse possible.
3195 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3196 this would cause an infinit loop. */
3197 parent->decorated = 1;
3198 decorateType (litTree, resultType);
3205 /*------------------------------------------------------------------*/
3206 /*----------------------------*/
3208 /*----------------------------*/
3210 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3212 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3213 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3214 printTypeChain (LTYPE (tree), stderr);
3215 fprintf (stderr, ",");
3216 printTypeChain (RTYPE (tree), stderr);
3217 fprintf (stderr, "\n");
3218 goto errorTreeReturn;
3220 /* if they are both literal then */
3221 /* rewrite the tree */
3222 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3224 tree->type = EX_VALUE;
3225 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3226 valFromType (RETYPE (tree)));
3227 tree->right = tree->left = NULL;
3228 TETYPE (tree) = getSpec (TTYPE (tree) =
3229 tree->opval.val->type);
3232 LRVAL (tree) = RRVAL (tree) = 1;
3233 TETYPE (tree) = getSpec (TTYPE (tree) =
3234 computeType (LTYPE (tree),
3240 /*------------------------------------------------------------------*/
3241 /*----------------------------*/
3242 /* address dereference */
3243 /*----------------------------*/
3244 case '*': /* can be unary : if right is null then unary operation */
3247 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3249 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
3250 goto errorTreeReturn;
3255 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
3256 goto errorTreeReturn;
3258 if (IS_ADDRESS_OF_OP (tree->left))
3260 /* replace *&obj with obj */
3261 return tree->left->left;
3263 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3264 TETYPE (tree) = getSpec (TTYPE (tree));
3265 /* adjust the storage class */
3266 switch (DCL_TYPE(tree->left->ftype)) {
3268 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3271 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3274 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3277 SPEC_SCLS (TETYPE (tree)) = 0;
3280 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3283 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3286 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3289 SPEC_SCLS (TETYPE (tree)) = 0;
3298 /*------------------------------------------------------------------*/
3299 /*----------------------------*/
3300 /* multiplication */
3301 /*----------------------------*/
3302 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3304 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
3305 goto errorTreeReturn;
3308 /* if they are both literal then */
3309 /* rewrite the tree */
3310 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3312 tree->type = EX_VALUE;
3313 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3314 valFromType (RETYPE (tree)));
3315 tree->right = tree->left = NULL;
3316 TETYPE (tree) = getSpec (TTYPE (tree) =
3317 tree->opval.val->type);
3321 /* if left is a literal exchange left & right */
3322 if (IS_LITERAL (LTYPE (tree)))
3324 ast *tTree = tree->left;
3325 tree->left = tree->right;
3326 tree->right = tTree;
3329 /* if right is a literal and */
3330 /* we can find a 2nd literal in a mul-tree then */
3331 /* rearrange the tree */
3332 if (IS_LITERAL (RTYPE (tree)))
3335 ast *litTree = searchLitOp (tree, &parent, "*");
3339 ast *tTree = litTree->left;
3340 litTree->left = tree->right;
3341 tree->right = tTree;
3342 /* both operands in litTree are literal now */
3343 decorateType (parent, resultType);
3347 LRVAL (tree) = RRVAL (tree) = 1;
3348 tree->left = addCast (tree->left, resultTypeProp, FALSE);
3349 tree->right = addCast (tree->right, resultTypeProp, FALSE);
3350 TETYPE (tree) = getSpec (TTYPE (tree) =
3351 computeType (LTYPE (tree),
3358 /*------------------------------------------------------------------*/
3359 /*----------------------------*/
3360 /* unary '+' operator */
3361 /*----------------------------*/
3366 if (!IS_ARITHMETIC (LTYPE (tree)))
3368 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
3369 goto errorTreeReturn;
3372 /* if left is a literal then do it */
3373 if (IS_LITERAL (LTYPE (tree)))
3375 tree->type = EX_VALUE;
3376 tree->opval.val = valFromType (LETYPE (tree));
3378 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3382 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3386 /*------------------------------------------------------------------*/
3387 /*----------------------------*/
3389 /*----------------------------*/
3391 /* this is not a unary operation */
3392 /* if both pointers then problem */
3393 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3394 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3396 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
3397 goto errorTreeReturn;
3400 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3401 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3403 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3404 goto errorTreeReturn;
3407 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3408 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3410 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3411 goto errorTreeReturn;
3413 /* if they are both literal then */
3414 /* rewrite the tree */
3415 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3417 tree->type = EX_VALUE;
3418 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3419 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3420 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3421 valFromType (RETYPE (tree)));
3422 tree->right = tree->left = NULL;
3423 TETYPE (tree) = getSpec (TTYPE (tree) =
3424 tree->opval.val->type);
3428 /* if the right is a pointer or left is a literal
3429 xchange left & right */
3430 if (IS_ARRAY (RTYPE (tree)) ||
3431 IS_PTR (RTYPE (tree)) ||
3432 IS_LITERAL (LTYPE (tree)))
3434 ast *tTree = tree->left;
3435 tree->left = tree->right;
3436 tree->right = tTree;
3439 /* if right is a literal and */
3440 /* left is also an addition/subtraction with a literal then */
3441 /* rearrange the tree */
3442 if (IS_LITERAL (RTYPE (tree)))
3444 ast *litTree, *parent;
3445 litTree = searchLitOp (tree, &parent, "+-");
3448 if (litTree->opval.op == '+')
3452 ast *tTree = litTree->left;
3453 litTree->left = tree->right;
3454 tree->right = tree->left;
3457 else if (litTree->opval.op == '-')
3459 if (IS_LITERAL (RTYPE (litTree)))
3463 ast *tTree = litTree->left;
3464 litTree->left = tree->right;
3465 tree->right = tTree;
3471 ast *tTree = litTree->right;
3472 litTree->right = tree->right;
3473 tree->right = tTree;
3474 litTree->opval.op = '+';
3475 tree->opval.op = '-';
3478 decorateType (parent, resultType);
3482 LRVAL (tree) = RRVAL (tree) = 1;
3483 /* if the left is a pointer */
3484 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3485 TETYPE (tree) = getSpec (TTYPE (tree) =
3489 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3490 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3491 TETYPE (tree) = getSpec (TTYPE (tree) =
3492 computeType (LTYPE (tree),
3500 /*------------------------------------------------------------------*/
3501 /*----------------------------*/
3503 /*----------------------------*/
3504 case '-': /* can be unary */
3505 /* if right is null then unary */
3509 if (!IS_ARITHMETIC (LTYPE (tree)))
3511 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3512 goto errorTreeReturn;
3515 /* if left is a literal then do it */
3516 if (IS_LITERAL (LTYPE (tree)))
3518 tree->type = EX_VALUE;
3519 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3521 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3524 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3525 TETYPE (tree) = getSpec (TTYPE (tree) =
3526 computeType (LTYPE (tree),
3534 /*------------------------------------------------------------------*/
3535 /*----------------------------*/
3537 /*----------------------------*/
3539 if (!(IS_PTR (LTYPE (tree)) ||
3540 IS_ARRAY (LTYPE (tree)) ||
3541 IS_ARITHMETIC (LTYPE (tree))))
3543 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3544 goto errorTreeReturn;
3547 if (!(IS_PTR (RTYPE (tree)) ||
3548 IS_ARRAY (RTYPE (tree)) ||
3549 IS_ARITHMETIC (RTYPE (tree))))
3551 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3552 goto errorTreeReturn;
3555 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3556 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3557 IS_INTEGRAL (RTYPE (tree))))
3559 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3560 goto errorTreeReturn;
3563 /* if they are both literal then */
3564 /* rewrite the tree */
3565 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3567 tree->type = EX_VALUE;
3568 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3569 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3570 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3571 valFromType (RETYPE (tree)));
3572 tree->right = tree->left = NULL;
3573 TETYPE (tree) = getSpec (TTYPE (tree) =
3574 tree->opval.val->type);
3578 /* if the left & right are equal then zero */
3579 if (isAstEqual (tree->left, tree->right))
3581 tree->type = EX_VALUE;
3582 tree->left = tree->right = NULL;
3583 tree->opval.val = constCharVal (0);
3584 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3588 /* if both of them are pointers or arrays then */
3589 /* the result is going to be an integer */
3590 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3591 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3592 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3594 /* if only the left is a pointer */
3595 /* then result is a pointer */
3596 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3597 TETYPE (tree) = getSpec (TTYPE (tree) =
3601 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3602 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3604 TETYPE (tree) = getSpec (TTYPE (tree) =
3605 computeType (LTYPE (tree),
3611 LRVAL (tree) = RRVAL (tree) = 1;
3613 /* if right is a literal and */
3614 /* left is also an addition/subtraction with a literal then */
3615 /* rearrange the tree */
3616 if (IS_LITERAL (RTYPE (tree))
3617 /* avoid infinite loop */
3618 && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 0)
3620 ast *litTree, *litParent;
3621 litTree = searchLitOp (tree, &litParent, "+-");
3624 if (litTree->opval.op == '+')
3628 ast *tTree = litTree->left;
3629 litTree->left = litTree->right;
3630 litTree->right = tree->right;
3631 tree->right = tTree;
3632 tree->opval.op = '+';
3633 litTree->opval.op = '-';
3635 else if (litTree->opval.op == '-')
3637 if (IS_LITERAL (RTYPE (litTree)))
3641 ast *tTree = litTree->left;
3642 litTree->left = tree->right;
3643 tree->right = litParent->left;
3644 litParent->left = tTree;
3645 litTree->opval.op = '+';
3647 tree->decorated = 0;
3648 decorateType (tree, resultType);
3654 ast *tTree = litTree->right;
3655 litTree->right = tree->right;
3656 tree->right = tTree;
3659 decorateType (litParent, resultType);
3664 /*------------------------------------------------------------------*/
3665 /*----------------------------*/
3667 /*----------------------------*/
3669 /* can be only integral type */
3670 if (!IS_INTEGRAL (LTYPE (tree)))
3672 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3673 goto errorTreeReturn;
3676 /* if left is a literal then do it */
3677 if (IS_LITERAL (LTYPE (tree)))
3679 tree->type = EX_VALUE;
3680 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3682 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3683 return addCast (tree, resultTypeProp, TRUE);
3686 if (resultType == RESULT_TYPE_BIT &&
3687 IS_UNSIGNED (tree->left->etype) &&
3688 getSize (tree->left->etype) < INTSIZE)
3690 /* promotion rules are responsible for this strange result:
3691 bit -> int -> ~int -> bit
3692 uchar -> int -> ~int -> bit
3694 werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
3696 /* optimize bit-result, even if we optimize a buggy source */
3697 tree->type = EX_VALUE;
3698 tree->opval.val = constCharVal (1);
3701 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3703 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3706 /*------------------------------------------------------------------*/
3707 /*----------------------------*/
3709 /*----------------------------*/
3711 /* can be pointer */
3712 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3713 !IS_PTR (LTYPE (tree)) &&
3714 !IS_ARRAY (LTYPE (tree)))
3716 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3717 goto errorTreeReturn;
3720 /* if left is another '!' */
3721 if (IS_AST_NOT_OPER (tree->left))
3723 if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
3725 /* replace double '!!X' by 'X' */
3726 return tree->left->left;
3728 /* remove double '!!X' by 'X ? 1 : 0' */
3729 tree->opval.op = '?';
3730 tree->left = tree->left->left;
3731 tree->right = newNode (':',
3732 newAst_VALUE (constCharVal (1)),
3733 newAst_VALUE (constCharVal (0)));
3734 tree->right->filename = tree->filename;
3735 tree->right->lineno = tree->lineno;
3736 tree->decorated = 0;
3737 return decorateType (tree, resultType);
3740 /* if left is a literal then do it */
3741 if (IS_LITERAL (LTYPE (tree)))
3743 tree->type = EX_VALUE;
3744 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3746 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3750 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3753 /*------------------------------------------------------------------*/
3754 /*----------------------------*/
3756 /*----------------------------*/
3760 TTYPE (tree) = LTYPE (tree);
3761 TETYPE (tree) = LETYPE (tree);
3766 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3770 TTYPE (tree) = TETYPE (tree) = newCharLink();
3774 TTYPE (tree) = TETYPE (tree) = newIntLink();
3779 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3781 werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
3782 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3783 printTypeChain (LTYPE (tree), stderr);
3784 fprintf (stderr, ",");
3785 printTypeChain (RTYPE (tree), stderr);
3786 fprintf (stderr, "\n");
3787 goto errorTreeReturn;
3790 /* make smaller type only if it's a LEFT_OP */
3791 if (tree->opval.op == LEFT_OP)
3792 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3794 /* if they are both literal then */
3795 /* rewrite the tree */
3796 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3798 tree->type = EX_VALUE;
3799 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3800 valFromType (RETYPE (tree)),
3801 (tree->opval.op == LEFT_OP ? 1 : 0));
3802 tree->right = tree->left = NULL;
3803 TETYPE (tree) = getSpec (TTYPE (tree) =
3804 tree->opval.val->type);
3808 /* see if this is a GETBYTE operation if yes
3811 ast *otree = optimizeGetByte (tree, resultType);
3814 return decorateType (otree, RESULT_TYPE_NONE);
3817 /* see if this is a GETWORD operation if yes
3820 ast *otree = optimizeGetWord (tree, resultType);
3823 return decorateType (otree, RESULT_TYPE_NONE);
3826 LRVAL (tree) = RRVAL (tree) = 1;
3827 if (tree->opval.op == LEFT_OP)
3829 TETYPE (tree) = getSpec (TTYPE (tree) =
3830 computeType (LTYPE (tree),
3837 /* no promotion necessary */
3838 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3839 if (IS_LITERAL (TTYPE (tree)))
3840 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3843 /* if only the right side is a literal & we are
3844 shifting more than size of the left operand then zero */
3845 if (IS_LITERAL (RTYPE (tree)) &&
3846 ((TYPE_TARGET_ULONG) ulFromVal (valFromType (RETYPE (tree)))) >=
3847 (getSize (TETYPE (tree)) * 8))
3849 if (tree->opval.op==LEFT_OP ||
3850 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3852 werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
3853 (tree->opval.op == LEFT_OP ? "left" : "right"));
3854 tree->type = EX_VALUE;
3855 tree->left = tree->right = NULL;
3856 tree->opval.val = constCharVal (0);
3857 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3864 /*------------------------------------------------------------------*/
3865 /*----------------------------*/
3867 /*----------------------------*/
3868 case CAST: /* change the type */
3869 /* cannot cast to an aggregate type */
3870 if (IS_AGGREGATE (LTYPE (tree)))
3872 werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
3873 goto errorTreeReturn;
3876 /* make sure the type is complete and sane */
3877 changePointer(LTYPE(tree));
3878 checkTypeSanity(LETYPE(tree), "(cast)");
3880 /* if 'from' and 'to' are the same remove the superfluous cast,
3881 * this helps other optimizations */
3882 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3884 /* mark that the explicit cast has been removed,
3885 * for proper processing (no integer promotion) of explicitly typecasted variable arguments */
3886 tree->right->values.removedCast = 1;
3890 /* If code memory is read only, then pointers to code memory */
3891 /* implicitly point to constants -- make this explicit */
3893 sym_link *t = LTYPE(tree);
3894 while (t && t->next)
3896 if (IS_CODEPTR(t) && port->mem.code_ro)
3898 if (IS_SPEC(t->next))
3899 SPEC_CONST (t->next) = 1;
3901 DCL_PTR_CONST (t->next) = 1;
3908 /* if the right is a literal replace the tree */
3909 if (IS_LITERAL (RETYPE (tree)))
3911 if (!IS_PTR (LTYPE (tree)))
3913 tree->type = EX_VALUE;
3915 valCastLiteral (LTYPE (tree),
3916 floatFromVal (valFromType (RETYPE (tree))));
3919 TTYPE (tree) = tree->opval.val->type;
3920 tree->values.literalFromCast = 1;
3922 else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3923 ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */
3925 sym_link *rest = LTYPE(tree)->next;
3926 werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
3927 TTYPE(tree) = newLink(DECLARATOR);
3928 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3929 TTYPE(tree)->next = rest;
3930 tree->left->opval.lnk = TTYPE(tree);
3935 TTYPE (tree) = LTYPE (tree);
3941 TTYPE (tree) = LTYPE (tree);
3945 #if 0 // this is already checked, now this could be explicit
3946 /* if pointer to struct then check names */
3947 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3948 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3949 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3951 werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3952 SPEC_STRUCT(LETYPE(tree))->tag);
3955 if (IS_ADDRESS_OF_OP(tree->right)
3956 && IS_AST_SYM_VALUE (tree->right->left)
3957 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype))
3959 symbol * sym = AST_SYMBOL (tree->right->left);
3960 unsigned int gptype = 0;
3961 unsigned int addr = SPEC_ADDR (sym->etype);
3963 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE) || TARGET_IS_PIC16) )
3965 switch (SPEC_SCLS (sym->etype))
3968 gptype = GPTYPE_CODE;
3971 gptype = GPTYPE_FAR;
3975 gptype = GPTYPE_NEAR;
3978 gptype = GPTYPE_XSTACK;
3983 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3984 gptype = GPTYPE_NEAR;
3986 addr |= gptype << (8*(GPTRSIZE - 1));
3989 tree->type = EX_VALUE;
3990 tree->opval.val = valCastLiteral (LTYPE (tree), addr);
3991 TTYPE (tree) = tree->opval.val->type;
3992 TETYPE (tree) = getSpec (TTYPE (tree));
3995 tree->values.literalFromCast = 1;
3999 /* handle offsetof macro: */
4000 /* #define offsetof(TYPE, MEMBER) \ */
4001 /* ((unsigned) &((TYPE *)0)->MEMBER) */
4002 if (IS_ADDRESS_OF_OP(tree->right)
4003 && IS_AST_OP (tree->right->left)
4004 && tree->right->left->opval.op == PTR_OP
4005 && IS_AST_OP (tree->right->left->left)
4006 && tree->right->left->left->opval.op == CAST
4007 && IS_AST_LIT_VALUE(tree->right->left->left->right))
4009 symbol *element = getStructElement (
4010 SPEC_STRUCT (LETYPE(tree->right->left)),
4011 AST_SYMBOL(tree->right->left->right)
4016 tree->type = EX_VALUE;
4017 tree->opval.val = valCastLiteral (
4020 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
4023 TTYPE (tree) = tree->opval.val->type;
4024 TETYPE (tree) = getSpec (TTYPE (tree));
4031 /* if the right is a literal replace the tree */
4032 if (IS_LITERAL (RETYPE (tree)))
4035 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) )
4037 /* rewrite (type *)litaddr
4039 and define type at litaddr temp
4040 (but only if type's storage class is not generic)
4042 ast *newTree = newNode ('&', NULL, NULL);
4045 TTYPE (newTree) = LTYPE (tree);
4046 TETYPE (newTree) = getSpec(LTYPE (tree));
4048 /* define a global symbol at the casted address*/
4049 sym = newSymbol(genSymName (0), 0);
4050 sym->type = LTYPE (tree)->next;
4052 sym->type = newLink (V_VOID);
4053 sym->etype = getSpec(sym->type);
4054 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
4055 sym->lineDef = tree->lineno;
4058 SPEC_STAT (sym->etype) = 1;
4059 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
4060 SPEC_ABSA(sym->etype) = 1;
4061 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
4064 newTree->left = newAst_VALUE(symbolVal(sym));
4065 newTree->left->filename = tree->filename;
4066 newTree->left->lineno = tree->lineno;
4067 LTYPE (newTree) = sym->type;
4068 LETYPE (newTree) = sym->etype;
4069 LLVAL (newTree) = 1;
4070 LRVAL (newTree) = 0;
4071 TLVAL (newTree) = 1;
4075 if (!IS_PTR (LTYPE (tree)))
4077 tree->type = EX_VALUE;
4079 valCastLiteral (LTYPE (tree), floatFromVal (valFromType (RTYPE (tree))));
4080 TTYPE (tree) = tree->opval.val->type;
4083 tree->values.literalFromCast = 1;
4084 TETYPE (tree) = getSpec (TTYPE (tree));
4088 if (IS_GENPTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) && !IS_GENPTR (RTYPE (tree)) && (resultType != RESULT_TYPE_GPTR))
4090 DCL_TYPE (LTYPE (tree)) = DCL_TYPE (RTYPE (tree));
4092 TTYPE (tree) = LTYPE (tree);
4096 TETYPE (tree) = getSpec (TTYPE (tree));
4100 /*------------------------------------------------------------------*/
4101 /*----------------------------*/
4102 /* logical &&, || */
4103 /*----------------------------*/
4106 /* each must be arithmetic type or be a pointer */
4107 if (!IS_PTR (LTYPE (tree)) &&
4108 !IS_ARRAY (LTYPE (tree)) &&
4109 !IS_INTEGRAL (LTYPE (tree)))
4111 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4112 goto errorTreeReturn;
4115 if (!IS_PTR (RTYPE (tree)) &&
4116 !IS_ARRAY (RTYPE (tree)) &&
4117 !IS_INTEGRAL (RTYPE (tree)))
4119 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4120 goto errorTreeReturn;
4122 /* if they are both literal then */
4123 /* rewrite the tree */
4124 if (IS_LITERAL (RTYPE (tree)) &&
4125 IS_LITERAL (LTYPE (tree)))
4127 tree->type = EX_VALUE;
4128 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4129 valFromType (RTYPE (tree)),
4131 tree->right = tree->left = NULL;
4132 TETYPE (tree) = getSpec (TTYPE (tree) =
4133 tree->opval.val->type);
4136 LRVAL (tree) = RRVAL (tree) = 1;
4137 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4140 /*------------------------------------------------------------------*/
4141 /*----------------------------*/
4142 /* comparison operators */
4143 /*----------------------------*/
4151 ast *lt = optimizeCompare (tree);
4157 /* if they are pointers they must be castable */
4158 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4160 if (tree->opval.op==EQ_OP &&
4161 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4162 // we cannot cast a gptr to a !gptr: switch the leaves
4163 struct ast *s=tree->left;
4164 tree->left=tree->right;
4167 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4169 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4170 fprintf (stderr, "comparing type ");
4171 printTypeChain (LTYPE (tree), stderr);
4172 fprintf (stderr, "to type ");
4173 printTypeChain (RTYPE (tree), stderr);
4174 fprintf (stderr, "\n");
4175 goto errorTreeReturn;
4178 /* else they should be promotable to one another */
4181 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4182 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4184 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4186 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4187 fprintf (stderr, "comparing type ");
4188 printTypeChain (LTYPE (tree), stderr);
4189 fprintf (stderr, "to type ");
4190 printTypeChain (RTYPE (tree), stderr);
4191 fprintf (stderr, "\n");
4192 goto errorTreeReturn;
4197 CCR_RESULT ccr_result = CCR_OK;
4199 /* if left is integral and right is literal
4200 then check constant range */
4201 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4202 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4203 tree->opval.op, FALSE);
4204 if (ccr_result == CCR_OK &&
4205 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4206 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4207 tree->opval.op, TRUE);
4210 case CCR_ALWAYS_TRUE:
4211 case CCR_ALWAYS_FALSE:
4212 if (!options.lessPedantic)
4213 werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
4214 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4215 return decorateType (newAst_VALUE (constCharVal ((unsigned char)(ccr_result == CCR_ALWAYS_TRUE))), resultType);
4222 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4223 if (tree->opval.op == '>' &&
4224 SPEC_USIGN(LETYPE(tree)) &&
4225 IS_LITERAL(RTYPE(tree)) &&
4226 ((int) ulFromVal (valFromType (RETYPE (tree)))) == 0)
4228 if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
4230 /* the parent is an ifx: */
4231 /* if (unsigned value) */
4235 /* (unsigned value) ? 1 : 0 */
4236 tree->opval.op = '?';
4237 tree->right = newNode (':',
4238 newAst_VALUE (constCharVal (1)),
4239 tree->right); /* val 0 */
4240 tree->right->filename = tree->filename;
4241 tree->right->lineno = tree->lineno;
4242 tree->right->left->filename = tree->filename;
4243 tree->right->left->lineno = tree->lineno;
4244 tree->decorated = 0;
4245 return decorateType (tree, resultType);
4248 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4249 if (IS_LITERAL(RTYPE(tree)) &&
4250 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4251 tree->opval.op == EQ_OP &&
4252 (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT))
4254 tree->opval.op = '!';
4256 tree->decorated = 0;
4257 return decorateType (tree, resultType);
4260 /* if they are both literal then */
4261 /* rewrite the tree */
4262 if (IS_LITERAL (RTYPE (tree)) &&
4263 IS_LITERAL (LTYPE (tree)))
4265 tree->type = EX_VALUE;
4266 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4267 valFromType (RETYPE (tree)),
4269 tree->right = tree->left = NULL;
4270 TETYPE (tree) = getSpec (TTYPE (tree) =
4271 tree->opval.val->type);
4275 /* if one is 'signed char ' and the other one is 'unsigned char' */
4276 /* it's necessary to promote to int */
4277 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4278 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4280 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4281 if it's possible to use a 'signed char' */
4283 /* is left a 'unsigned char'? */
4284 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4285 /* the value range of a 'unsigned char' is 0...255;
4286 if the actual value is < 128 it can be changed to signed */
4287 (int) ulFromVal (valFromType (RETYPE (tree))) < 128)
4289 /* now we've got 2 'signed char'! */
4290 SPEC_USIGN (RETYPE (tree)) = 0;
4292 /* same test for the left operand: */
4293 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4294 (int) ulFromVal (valFromType (LETYPE (tree))) < 128)
4296 SPEC_USIGN (LETYPE (tree)) = 0;
4300 werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
4301 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4302 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4306 LRVAL (tree) = RRVAL (tree) = 1;
4307 TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4309 /* condition transformations */
4311 unsigned transformedOp = 0;
4313 switch (tree->opval.op)
4315 case '<': /* transform (a < b) to !(a >= b) */
4317 transformedOp = GE_OP;
4319 case '>': /* transform (a > b) to !(a <= b) */
4321 transformedOp = LE_OP;
4323 case LE_OP: /* transform (a <= b) to !(a > b) */
4325 transformedOp = '>';
4327 case GE_OP: /* transform (a >= b) to !(a < b) */
4329 transformedOp = '<';
4331 case NE_OP: /* transform (a != b) to !(a == b) */
4333 transformedOp = EQ_OP;
4335 case EQ_OP: /* transform (a == b) to !(a != b) */
4337 transformedOp = NE_OP;
4344 tree->opval.op = transformedOp;
4345 tree->decorated = 0;
4346 tree = newNode ('!', tree, NULL);
4347 tree->filename = tree->left->filename;
4348 tree->lineno = tree->left->lineno;
4349 return decorateType (tree, resultType);
4355 /*------------------------------------------------------------------*/
4356 /*----------------------------*/
4358 /*----------------------------*/
4359 case SIZEOF: /* evaluate wihout code generation */
4360 /* change the type to a integer */
4362 int size = getSize (tree->right->ftype);
4364 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4365 if (!size && !IS_VOID(tree->right->ftype))
4366 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4368 tree->type = EX_VALUE;
4369 tree->opval.val = constVal (buffer);
4370 tree->right = tree->left = NULL;
4371 TETYPE (tree) = getSpec (TTYPE (tree) =
4372 tree->opval.val->type);
4376 /*------------------------------------------------------------------*/
4377 /*----------------------------*/
4379 /*----------------------------*/
4381 /* return typeof enum value */
4382 tree->type = EX_VALUE;
4385 if (IS_SPEC(tree->right->ftype)) {
4386 switch (SPEC_NOUN(tree->right->ftype)) {
4388 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4389 else typeofv = TYPEOF_INT;
4392 typeofv = TYPEOF_FLOAT;
4395 typeofv = TYPEOF_FIXED16X16;
4398 typeofv = TYPEOF_CHAR;
4401 typeofv = TYPEOF_VOID;
4404 typeofv = TYPEOF_STRUCT;
4407 typeofv = TYPEOF_BITFIELD;
4410 typeofv = TYPEOF_BIT;
4413 typeofv = TYPEOF_SBIT;
4419 switch (DCL_TYPE(tree->right->ftype)) {
4421 typeofv = TYPEOF_POINTER;
4424 typeofv = TYPEOF_FPOINTER;
4427 typeofv = TYPEOF_CPOINTER;
4430 typeofv = TYPEOF_GPOINTER;
4433 typeofv = TYPEOF_PPOINTER;
4436 typeofv = TYPEOF_IPOINTER;
4439 typeofv = TYPEOF_ARRAY;
4442 typeofv = TYPEOF_FUNCTION;
4448 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4449 tree->opval.val = constVal (buffer);
4450 tree->right = tree->left = NULL;
4451 TETYPE (tree) = getSpec (TTYPE (tree) =
4452 tree->opval.val->type);
4455 /*------------------------------------------------------------------*/
4456 /*----------------------------*/
4457 /* conditional operator '?' */
4458 /*----------------------------*/
4460 /* the type is value of the colon operator (on the right) */
4461 assert (IS_COLON_OP (tree->right));
4463 /* If already known then replace the tree : optimizer will do it
4464 but faster to do it here. If done before decorating tree->right
4465 this can save generating unused const strings. */
4466 if (IS_LITERAL (LTYPE (tree)))
4468 if (((int) ulFromVal (valFromType (LETYPE (tree)))) != 0)
4469 return decorateType (tree->right->left, resultTypeProp);
4471 return decorateType (tree->right->right, resultTypeProp);
4474 tree->right = decorateType (tree->right, resultTypeProp);
4476 if (IS_AST_LIT_VALUE (tree->right->left) && IS_AST_LIT_VALUE (tree->right->right) &&
4477 ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)))
4479 double valTrue = AST_FLOAT_VALUE (tree->right->left);
4480 double valFalse = AST_FLOAT_VALUE (tree->right->right);
4482 if ((valTrue != 0) && (valFalse == 0))
4484 /* assign cond to result */
4485 tree->left->decorated = 0;
4486 return decorateType (tree->left, resultTypeProp);
4488 else if ((valTrue == 0) && (valFalse != 0))
4490 /* assign !cond to result */
4491 tree->opval.op = '!';
4492 tree->decorated = 0;
4494 return decorateType (tree, resultTypeProp);
4498 /* they have the same boolean value, make them equal */
4499 tree->right->left = tree->right->right;
4503 /* if they are equal then replace the tree */
4504 if (isAstEqual (tree->right->left, tree->right->right))
4506 return tree->right->left;
4509 TTYPE (tree) = RTYPE (tree);
4510 TETYPE (tree) = getSpec (TTYPE (tree));
4514 /* if they don't match we have a problem */
4515 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4516 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4518 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
4519 goto errorTreeReturn;
4522 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4523 resultType, tree->opval.op);
4524 TETYPE (tree) = getSpec (TTYPE (tree));
4528 #if 0 // assignment operators are converted by the parser
4529 /*------------------------------------------------------------------*/
4530 /*----------------------------*/
4531 /* assignment operators */
4532 /*----------------------------*/
4535 /* for these it must be both must be integral */
4536 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4537 !IS_ARITHMETIC (RTYPE (tree)))
4539 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4540 goto errorTreeReturn;
4543 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4545 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4546 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4550 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4551 goto errorTreeReturn;
4562 /* for these it must be both must be integral */
4563 if (!IS_INTEGRAL (LTYPE (tree)) ||
4564 !IS_INTEGRAL (RTYPE (tree)))
4566 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4567 goto errorTreeReturn;
4570 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4572 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4573 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4577 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4578 goto errorTreeReturn;
4584 /*------------------------------------------------------------------*/
4585 /*----------------------------*/
4587 /*----------------------------*/
4589 if (!(IS_PTR (LTYPE (tree)) ||
4590 IS_ARITHMETIC (LTYPE (tree))))
4592 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4593 goto errorTreeReturn;
4596 if (!(IS_PTR (RTYPE (tree)) ||
4597 IS_ARITHMETIC (RTYPE (tree))))
4599 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4600 goto errorTreeReturn;
4603 TETYPE (tree) = getSpec (TTYPE (tree) =
4604 computeType (LTYPE (tree),
4609 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4610 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
4614 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
4615 goto errorTreeReturn;
4621 /*------------------------------------------------------------------*/
4622 /*----------------------------*/
4624 /*----------------------------*/
4626 /* this is not a unary operation */
4627 /* if both pointers then problem */
4628 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4630 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
4631 goto errorTreeReturn;
4634 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4636 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4637 goto errorTreeReturn;
4640 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4642 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4643 goto errorTreeReturn;
4646 TETYPE (tree) = getSpec (TTYPE (tree) =
4647 computeType (LTYPE (tree),
4652 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4653 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
4657 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
4658 goto errorTreeReturn;
4661 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4662 tree->opval.op = '=';
4667 /*------------------------------------------------------------------*/
4668 /*----------------------------*/
4669 /* straight assignemnt */
4670 /*----------------------------*/
4672 /* cannot be an aggregate */
4673 if (IS_AGGREGATE (LTYPE (tree)))
4675 werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
4676 goto errorTreeReturn;
4679 /* they should either match or be castable */
4680 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4682 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
4683 printFromToType(RTYPE(tree),LTYPE(tree));
4686 /* if the left side of the tree is of type void
4687 then report error */
4688 if (IS_VOID (LTYPE (tree)))
4690 werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
4691 printFromToType(RTYPE(tree), LTYPE(tree));
4694 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4697 if (!tree->initMode ) {
4698 if (IS_CONSTANT(LTYPE(tree)))
4699 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
4703 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
4704 goto errorTreeReturn;
4709 /*------------------------------------------------------------------*/
4710 /*----------------------------*/
4711 /* comma operator */
4712 /*----------------------------*/
4714 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4717 /*------------------------------------------------------------------*/
4718 /*----------------------------*/
4720 /*----------------------------*/
4723 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4724 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4726 if (tree->left->opval.op == '*' && !tree->left->right)
4727 tree->left = tree->left->left;
4730 /* require a function or pointer to function */
4731 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4733 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4734 goto errorTreeReturn;
4737 /* if there are parms, make sure that
4738 parms are decorate / process / reverse only once */
4740 !tree->right->decorated)
4745 if (IS_FUNCPTR (LTYPE (tree)))
4747 functype = LTYPE (tree)->next;
4748 processFuncPtrArgs (functype);
4751 functype = LTYPE (tree);
4753 if (processParms (tree->left, FUNC_ARGS(functype),
4754 &tree->right, &parmNumber, TRUE))
4756 goto errorTreeReturn;
4759 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4760 !IFFUNC_ISBUILTIN(functype))
4762 reverseParms (tree->right);
4765 TTYPE (tree) = functype->next;
4766 TETYPE (tree) = getSpec (TTYPE (tree));
4770 /*------------------------------------------------------------------*/
4771 /*----------------------------*/
4772 /* return statement */
4773 /*----------------------------*/
4778 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4780 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4781 printFromToType (RTYPE(tree), currFunc->type->next);
4782 goto errorTreeReturn;
4785 if (IS_VOID (currFunc->type->next)
4787 !IS_VOID (RTYPE (tree)))
4789 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4790 goto errorTreeReturn;
4793 /* if there is going to be a casting required then add it */
4794 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4797 decorateType (newNode (CAST,
4798 newAst_LINK (copyLinkChain (currFunc->type->next)),
4800 IS_GENPTR (currFunc->type->next) ? RESULT_TYPE_GPTR : RESULT_TYPE_NONE);
4808 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4810 werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
4811 goto errorTreeReturn;
4814 TTYPE (tree) = TETYPE (tree) = NULL;
4817 /*------------------------------------------------------------------*/
4818 /*----------------------------*/
4819 /* switch statement */
4820 /*----------------------------*/
4822 /* the switch value must be an integer */
4823 if (!IS_INTEGRAL (LTYPE (tree)))
4825 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4826 goto errorTreeReturn;
4829 TTYPE (tree) = TETYPE (tree) = NULL;
4832 /*------------------------------------------------------------------*/
4833 /*----------------------------*/
4835 /*----------------------------*/
4837 tree->left = backPatchLabels (tree->left,
4840 TTYPE (tree) = TETYPE (tree) = NULL;
4843 /*------------------------------------------------------------------*/
4844 /*----------------------------*/
4846 /*----------------------------*/
4849 AST_FOR (tree, initExpr) = decorateType (
4850 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4851 AST_FOR (tree, condExpr) = decorateType (
4852 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4853 AST_FOR (tree, loopExpr) = decorateType (
4854 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4856 /* if the for loop is reversible then
4857 reverse it otherwise do what we normally
4863 if (isLoopReversible (tree, &sym, &init, &end))
4864 return reverseLoop (tree, sym, init, end);
4866 return decorateType (createFor (AST_FOR (tree, trueLabel),
4867 AST_FOR (tree, continueLabel),
4868 AST_FOR (tree, falseLabel),
4869 AST_FOR (tree, condLabel),
4870 AST_FOR (tree, initExpr),
4871 AST_FOR (tree, condExpr),
4872 AST_FOR (tree, loopExpr),
4873 tree->left), RESULT_TYPE_NONE);
4876 werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
4877 "node PARAM shouldn't be processed here");
4878 /* but in processParams() */
4881 TTYPE (tree) = TETYPE (tree) = NULL;
4885 /* some error found this tree will be killed */
4887 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4888 tree->opval.op = NULLOP;
4894 /*-----------------------------------------------------------------*/
4895 /* sizeofOp - processes size of operation */
4896 /*-----------------------------------------------------------------*/
4898 sizeofOp (sym_link * type)
4903 /* make sure the type is complete and sane */
4904 checkTypeSanity(type, "(sizeof)");
4906 /* get the size and convert it to character */
4907 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4908 if (!size && !IS_VOID(type))
4909 werror (E_SIZEOF_INCOMPLETE_TYPE);
4911 /* now convert into value */
4912 return constVal (buff);
4916 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4917 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4918 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4919 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4920 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4921 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4922 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4924 /*-----------------------------------------------------------------*/
4925 /* backPatchLabels - change and or not operators to flow control */
4926 /*-----------------------------------------------------------------*/
4928 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4934 /* while-loops insert a label between the IFX and the condition,
4935 therefore look behind the label too */
4936 if (tree->opval.op == LABEL &&
4938 IS_ANDORNOT (tree->right))
4940 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4944 if (!(IS_ANDORNOT (tree)))
4947 /* if this an and */
4950 static int localLbl = 0;
4953 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4954 localLabel = newSymbol (buffer, NestLevel);
4956 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4958 /* if left is already a IFX then just change the if true label in that */
4959 if (!IS_IFX (tree->left))
4960 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4962 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4963 /* right is a IFX then just join */
4964 if (IS_IFX (tree->right))
4965 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4967 tree->right = createLabel (localLabel, tree->right);
4968 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4970 return newNode (NULLOP, tree->left, tree->right);
4973 /* if this is an or operation */
4976 static int localLbl = 0;
4979 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4980 localLabel = newSymbol (buffer, NestLevel);
4982 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4984 /* if left is already a IFX then just change the if true label in that */
4985 if (!IS_IFX (tree->left))
4986 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4988 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4989 /* right is a IFX then just join */
4990 if (IS_IFX (tree->right))
4991 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4993 tree->right = createLabel (localLabel, tree->right);
4994 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4996 return newNode (NULLOP, tree->left, tree->right);
5002 /* call with exchanged labels */
5003 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
5005 /* if left isn't already a IFX */
5006 if (!IS_IFX (tree->left))
5008 tree->left = newNode (IFX, tree->left, NULL);
5009 tree->left->trueLabel = falseLabel;
5010 tree->left->falseLabel = trueLabel;
5017 tree->trueLabel = trueLabel;
5018 tree->falseLabel = falseLabel;
5025 /*-----------------------------------------------------------------*/
5026 /* createBlock - create expression tree for block */
5027 /*-----------------------------------------------------------------*/
5029 createBlock (symbol * decl, ast * body)
5033 /* if the block has nothing */
5037 ex = newNode (BLOCK, NULL, body);
5038 ex->values.sym = decl;
5041 ex->filename = NULL;
5046 /*-----------------------------------------------------------------*/
5047 /* createLabel - creates the expression tree for labels */
5048 /*-----------------------------------------------------------------*/
5050 createLabel (symbol * label, ast * stmnt)
5053 char name[SDCC_NAME_MAX + 1];
5056 /* must create fresh symbol if the symbol name */
5057 /* exists in the symbol table, since there can */
5058 /* be a variable with the same name as the labl */
5059 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
5060 (csym->level == label->level))
5061 label = newSymbol (label->name, label->level);
5063 /* change the name before putting it in add _ */
5064 SNPRINTF(name, sizeof(name), "%s", label->name);
5066 /* put the label in the LabelSymbol table */
5067 /* but first check if a label of the same */
5069 if ((csym = findSym (LabelTab, NULL, name)))
5070 werror (E_DUPLICATE_LABEL, label->name);
5072 addSym (LabelTab, label, name, label->level, 0, 0);
5076 label->key = labelKey++;
5077 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
5078 rValue->filename = NULL;
5084 /*-----------------------------------------------------------------*/
5085 /* createCase - generates the parsetree for a case statement */
5086 /*-----------------------------------------------------------------*/
5088 createCase (ast * swStat, ast * caseVal, ast * stmnt)
5090 char caseLbl[SDCC_NAME_MAX + 1];
5094 /* if the switch statement does not exist */
5095 /* then case is out of context */
5098 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
5102 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
5103 /* if not a constant then error */
5104 if (!IS_LITERAL (caseVal->ftype))
5106 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
5110 /* if not a integer than error */
5111 if (!IS_INTEGRAL (caseVal->ftype))
5113 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
5117 /* find the end of the switch values chain */
5118 if (!(val = swStat->values.switchVals.swVals))
5119 swStat->values.switchVals.swVals = caseVal->opval.val;
5122 /* also order the cases according to value */
5124 int cVal = (int) ulFromVal (caseVal->opval.val);
5125 while (val && (int) ulFromVal (val) < cVal)
5131 /* if we reached the end then */
5134 pval->next = caseVal->opval.val;
5136 else if ((int) ulFromVal (val) == cVal)
5138 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5144 /* we found a value greater than */
5145 /* the current value we must add this */
5146 /* before the value */
5147 caseVal->opval.val->next = val;
5149 /* if this was the first in chain */
5150 if (swStat->values.switchVals.swVals == val)
5151 swStat->values.switchVals.swVals =
5154 pval->next = caseVal->opval.val;
5159 /* create the case label */
5160 SNPRINTF(caseLbl, sizeof(caseLbl),
5162 swStat->values.switchVals.swNum,
5163 (int) ulFromVal (caseVal->opval.val));
5165 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5166 rexpr->filename = 0;
5171 /*-----------------------------------------------------------------*/
5172 /* createDefault - creates the parse tree for the default statement */
5173 /*-----------------------------------------------------------------*/
5175 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5177 char defLbl[SDCC_NAME_MAX + 1];
5179 /* if the switch statement does not exist */
5180 /* then case is out of context */
5183 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5187 if (swStat->values.switchVals.swDefault)
5189 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5194 /* turn on the default flag */
5195 swStat->values.switchVals.swDefault = 1;
5197 /* create the label */
5198 SNPRINTF (defLbl, sizeof(defLbl),
5199 "_default_%d", swStat->values.switchVals.swNum);
5200 return createLabel (newSymbol (defLbl, 0), stmnt);
5203 /*-----------------------------------------------------------------*/
5204 /* createIf - creates the parsetree for the if statement */
5205 /*-----------------------------------------------------------------*/
5207 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5209 static int Lblnum = 0;
5211 symbol *ifTrue, *ifFalse, *ifEnd;
5213 /* if neither exists */
5214 if (!elseBody && !ifBody) {
5215 // if there are no side effects (i++, j() etc)
5216 if (!hasSEFcalls(condAst)) {
5221 /* create the labels */
5222 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5223 ifFalse = newSymbol (buffer, NestLevel);
5224 /* if no else body then end == false */
5229 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5230 ifEnd = newSymbol (buffer, NestLevel);
5233 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5234 ifTrue = newSymbol (buffer, NestLevel);
5238 /* attach the ifTrue label to the top of it body */
5239 ifBody = createLabel (ifTrue, ifBody);
5240 /* attach a goto end to the ifBody if else is present */
5243 ifBody = newNode (NULLOP, ifBody,
5245 newAst_VALUE (symbolVal (ifEnd)),
5247 /* put the elseLabel on the else body */
5248 elseBody = createLabel (ifFalse, elseBody);
5249 /* out the end at the end of the body */
5250 elseBody = newNode (NULLOP,
5252 createLabel (ifEnd, NULL));
5256 ifBody = newNode (NULLOP, ifBody,
5257 createLabel (ifFalse, NULL));
5259 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5260 if (IS_IFX (condAst))
5263 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5265 return newNode (NULLOP, ifTree,
5266 newNode (NULLOP, ifBody, elseBody));
5270 /*-----------------------------------------------------------------*/
5271 /* createDo - creates parse tree for do */
5274 /* _docontinue_n: */
5275 /* condition_expression +-> trueLabel -> _dobody_n */
5277 /* +-> falseLabel-> _dobreak_n */
5279 /*-----------------------------------------------------------------*/
5281 createDo (symbol * trueLabel, symbol * continueLabel,
5282 symbol * falseLabel, ast * condAst, ast * doBody)
5287 /* if the body does not exist then it is simple */
5290 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5291 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5292 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5293 doTree->trueLabel = continueLabel;
5294 doTree->falseLabel = NULL;
5296 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5300 /* otherwise we have a body */
5301 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5303 /* attach the body label to the top */
5304 doBody = createLabel (trueLabel, doBody);
5305 /* attach the continue label to end of body */
5306 doBody = newNode (NULLOP, doBody,
5307 createLabel (continueLabel, NULL));
5309 /* now put the break label at the end */
5310 if (IS_IFX (condAst))
5313 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5315 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5317 /* putting it together */
5318 return newNode (NULLOP, doBody, doTree);
5321 /*-----------------------------------------------------------------*/
5322 /* createFor - creates parse tree for 'for' statement */
5325 /* condExpr +-> trueLabel -> _forbody_n */
5327 /* +-> falseLabel-> _forbreak_n */
5330 /* _forcontinue_n: */
5332 /* goto _forcond_n ; */
5334 /*-----------------------------------------------------------------*/
5336 createFor (symbol * trueLabel, symbol * continueLabel,
5337 symbol * falseLabel, symbol * condLabel,
5338 ast * initExpr, ast * condExpr, ast * loopExpr,
5343 /* if loopexpression not present then we can generate it */
5344 /* the same way as a while */
5346 return newNode (NULLOP, initExpr,
5347 createWhile (trueLabel, continueLabel,
5348 falseLabel, condExpr, forBody));
5349 /* vanilla for statement */
5350 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5352 if (condExpr && !IS_IFX (condExpr))
5353 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5356 /* attach condition label to condition */
5357 condExpr = createLabel (condLabel, condExpr);
5359 /* attach body label to body */
5360 forBody = createLabel (trueLabel, forBody);
5362 /* attach continue to forLoop expression & attach */
5363 /* goto the forcond @ and of loopExpression */
5364 loopExpr = createLabel (continueLabel,
5368 newAst_VALUE (symbolVal (condLabel)),
5370 /* now start putting them together */
5371 forTree = newNode (NULLOP, initExpr, condExpr);
5372 forTree = newNode (NULLOP, forTree, forBody);
5373 forTree = newNode (NULLOP, forTree, loopExpr);
5374 /* finally add the break label */
5375 forTree = newNode (NULLOP, forTree,
5376 createLabel (falseLabel, NULL));
5380 /*-----------------------------------------------------------------*/
5381 /* createWhile - creates parse tree for while statement */
5382 /* the while statement will be created as follows */
5384 /* _while_continue_n: */
5385 /* condition_expression +-> trueLabel -> _while_boby_n */
5387 /* +-> falseLabel -> _while_break_n */
5388 /* _while_body_n: */
5390 /* goto _while_continue_n */
5391 /* _while_break_n: */
5392 /*-----------------------------------------------------------------*/
5394 createWhile (symbol * trueLabel, symbol * continueLabel,
5395 symbol * falseLabel, ast * condExpr, ast * whileBody)
5399 /* put the continue label */
5400 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5401 condExpr = createLabel (continueLabel, condExpr);
5402 condExpr->filename = NULL;
5403 condExpr->lineno = 0;
5405 /* put the body label in front of the body */
5406 whileBody = createLabel (trueLabel, whileBody);
5407 whileBody->filename = NULL;
5408 whileBody->lineno = 0;
5409 /* put a jump to continue at the end of the body */
5410 /* and put break label at the end of the body */
5411 whileBody = newNode (NULLOP,
5414 newAst_VALUE (symbolVal (continueLabel)),
5415 createLabel (falseLabel, NULL)));
5417 /* put it all together */
5418 if (IS_IFX (condExpr))
5419 whileTree = condExpr;
5422 whileTree = newNode (IFX, condExpr, NULL);
5423 /* put the true & false labels in place */
5424 whileTree->trueLabel = trueLabel;
5425 whileTree->falseLabel = falseLabel;
5428 return newNode (NULLOP, whileTree, whileBody);
5431 /*-----------------------------------------------------------------*/
5432 /* isShiftRightLitVal _BitAndLitVal - helper function */
5433 /*-----------------------------------------------------------------*/
5435 isShiftRightLitVal_BitAndLitVal (ast * tree)
5437 /* if this is not a bit and */
5438 if (!IS_BITAND (tree))
5441 /* will look for tree of the form
5442 ( expr >> litval2) & litval1 */
5443 if (!IS_AST_LIT_VALUE (tree->right))
5446 if (!IS_RIGHT_OP (tree->left))
5449 if (!IS_AST_LIT_VALUE (tree->left->right))
5452 return tree->left->left;
5455 /*-----------------------------------------------------------------*/
5456 /* isBitAndPowOf2 - helper function */
5457 /*-----------------------------------------------------------------*/
5459 isBitAndPow2 (ast * tree)
5461 /* if this is not a bit and */
5462 if (!IS_BITAND (tree))
5465 /* will look for tree of the form
5466 ( expr & (1 << litval) */
5467 if (!IS_AST_LIT_VALUE (tree->right))
5470 return powof2 (AST_ULONG_VALUE (tree->right));
5473 /*-----------------------------------------------------------------*/
5474 /* optimizeGetHbit - get highest order bit of the expression */
5475 /*-----------------------------------------------------------------*/
5477 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5482 expr = isShiftRightLitVal_BitAndLitVal(tree);
5485 if ((AST_ULONG_VALUE (tree->right) != 1) ||
5486 ((i = AST_ULONG_VALUE (tree->left->right)) !=
5487 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5490 if (!expr && (resultType == RESULT_TYPE_BIT))
5493 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5499 /* make sure the port supports GETHBIT */
5500 if (port->hasExtBitOp
5501 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5504 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5507 /*-----------------------------------------------------------------*/
5508 /* optimizeGetAbit - get a single bit of the expression */
5509 /*-----------------------------------------------------------------*/
5511 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5516 expr = isShiftRightLitVal_BitAndLitVal(tree);
5519 if (AST_ULONG_VALUE (tree->right) != 1)
5521 count = tree->left->right;
5523 if (!expr && (resultType == RESULT_TYPE_BIT))
5525 int p2 = isBitAndPow2 (tree);
5529 count = newAst_VALUE (valueFromLit (p2));
5535 /* make sure the port supports GETABIT */
5536 if (port->hasExtBitOp
5537 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5540 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5544 /*-----------------------------------------------------------------*/
5545 /* optimizeGetByte - get a byte of the expression */
5546 /*-----------------------------------------------------------------*/
5548 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5554 expr = isShiftRightLitVal_BitAndLitVal(tree);
5557 i = AST_ULONG_VALUE (tree->left->right);
5558 count = tree->left->right;
5559 if (AST_ULONG_VALUE (tree->right) != 0xFF)
5562 if (!expr && resultType == RESULT_TYPE_CHAR)
5564 /* if this is a right shift over a multiple of 8 */
5565 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5567 i = AST_ULONG_VALUE (tree->right);
5568 count = tree->right;
5572 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5575 /* make sure the port supports GETBYTE */
5576 if (port->hasExtBitOp
5577 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5580 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5583 /*-----------------------------------------------------------------*/
5584 /* optimizeGetWord - get two bytes of the expression */
5585 /*-----------------------------------------------------------------*/
5587 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5593 expr = isShiftRightLitVal_BitAndLitVal(tree);
5596 i = AST_ULONG_VALUE (tree->left->right);
5597 count = tree->left->right;
5598 if (AST_ULONG_VALUE (tree->right) != 0xFFFF)
5601 if (!expr && resultType == RESULT_TYPE_INT)
5603 /* if this is a right shift over a multiple of 8 */
5604 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5606 i = AST_ULONG_VALUE (tree->right);
5607 count = tree->right;
5611 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5614 /* make sure the port supports GETWORD */
5615 if (port->hasExtBitOp
5616 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5619 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5622 /*-----------------------------------------------------------------*/
5623 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5624 /*-----------------------------------------------------------------*/
5626 optimizeRRCRLC (ast * root)
5628 /* will look for trees of the form
5629 (?expr << 1) | (?expr >> 7) or
5630 (?expr >> 7) | (?expr << 1) will make that
5631 into a RLC : operation ..
5633 (?expr >> 1) | (?expr << 7) or
5634 (?expr << 7) | (?expr >> 1) will make that
5635 into a RRC operation
5636 note : by 7 I mean (number of bits required to hold the
5638 /* if the root operation is not a | operation then not */
5639 if (!IS_BITOR (root))
5642 /* I have to think of a better way to match patterns this sucks */
5643 /* that aside let's start looking for the first case : I use a
5644 negative check a lot to improve the efficiency */
5645 /* (?expr << 1) | (?expr >> 7) */
5646 if (IS_LEFT_OP (root->left) &&
5647 IS_RIGHT_OP (root->right))
5650 if (!SPEC_USIGN (TETYPE (root->left->left)))
5653 if (!IS_AST_LIT_VALUE (root->left->right) ||
5654 !IS_AST_LIT_VALUE (root->right->right))
5657 /* make sure it is the same expression */
5658 if (!isAstEqual (root->left->left,
5662 if (AST_ULONG_VALUE (root->left->right) != 1)
5665 if (AST_ULONG_VALUE (root->right->right) !=
5666 (getSize (TTYPE (root->left->left)) * 8 - 1))
5669 /* make sure the port supports RLC */
5670 if (port->hasExtBitOp
5671 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5674 /* whew got the first case : create the AST */
5675 return newNode (RLC, root->left->left, NULL);
5679 /* check for second case */
5680 /* (?expr >> 7) | (?expr << 1) */
5681 if (IS_LEFT_OP (root->right) &&
5682 IS_RIGHT_OP (root->left))
5685 if (!SPEC_USIGN (TETYPE (root->left->left)))
5688 if (!IS_AST_LIT_VALUE (root->left->right) ||
5689 !IS_AST_LIT_VALUE (root->right->right))
5692 /* make sure it is the same symbol */
5693 if (!isAstEqual (root->left->left,
5697 if (AST_ULONG_VALUE (root->right->right) != 1)
5700 if (AST_ULONG_VALUE (root->left->right) !=
5701 (getSize (TTYPE (root->left->left)) * 8 - 1))
5704 /* make sure the port supports RLC */
5705 if (port->hasExtBitOp
5706 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5709 /* whew got the first case : create the AST */
5710 return newNode (RLC, root->left->left, NULL);
5715 /* third case for RRC */
5716 /* (?symbol >> 1) | (?symbol << 7) */
5717 if (IS_LEFT_OP (root->right) &&
5718 IS_RIGHT_OP (root->left))
5721 if (!SPEC_USIGN (TETYPE (root->left->left)))
5724 if (!IS_AST_LIT_VALUE (root->left->right) ||
5725 !IS_AST_LIT_VALUE (root->right->right))
5728 /* make sure it is the same symbol */
5729 if (!isAstEqual (root->left->left,
5733 if (AST_ULONG_VALUE (root->left->right) != 1)
5736 if (AST_ULONG_VALUE (root->right->right) !=
5737 (getSize (TTYPE (root->left->left)) * 8 - 1))
5740 /* make sure the port supports RRC */
5741 if (port->hasExtBitOp
5742 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5745 /* whew got the first case : create the AST */
5746 return newNode (RRC, root->left->left, NULL);
5750 /* fourth and last case for now */
5751 /* (?symbol << 7) | (?symbol >> 1) */
5752 if (IS_RIGHT_OP (root->right) &&
5753 IS_LEFT_OP (root->left))
5756 if (!SPEC_USIGN (TETYPE (root->left->left)))
5759 if (!IS_AST_LIT_VALUE (root->left->right) ||
5760 !IS_AST_LIT_VALUE (root->right->right))
5763 /* make sure it is the same symbol */
5764 if (!isAstEqual (root->left->left,
5768 if (AST_ULONG_VALUE (root->right->right) != 1)
5771 if (AST_ULONG_VALUE (root->left->right) !=
5772 (getSize (TTYPE (root->left->left)) * 8 - 1))
5775 /* make sure the port supports RRC */
5776 if (port->hasExtBitOp
5777 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5780 /* whew got the first case : create the AST */
5781 return newNode (RRC, root->left->left, NULL);
5785 /* not found return root */
5789 /*-----------------------------------------------------------------*/
5790 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5791 /*-----------------------------------------------------------------*/
5793 optimizeSWAP (ast * root)
5795 /* will look for trees of the form
5796 (?expr << 4) | (?expr >> 4) or
5797 (?expr >> 4) | (?expr << 4) will make that
5798 into a SWAP : operation ..
5799 note : by 4 I mean (number of bits required to hold the
5801 /* if the root operation is not a | operation then not */
5802 if (!IS_BITOR (root))
5805 /* (?expr << 4) | (?expr >> 4) */
5806 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5807 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5810 if (!SPEC_USIGN (TETYPE (root->left->left)))
5813 if (!IS_AST_LIT_VALUE (root->left->right) ||
5814 !IS_AST_LIT_VALUE (root->right->right))
5817 /* make sure it is the same expression */
5818 if (!isAstEqual (root->left->left,
5822 if (AST_ULONG_VALUE (root->left->right) !=
5823 (getSize (TTYPE (root->left->left)) * 4))
5826 if (AST_ULONG_VALUE (root->right->right) !=
5827 (getSize (TTYPE (root->left->left)) * 4))
5830 /* make sure the port supports SWAP */
5831 if (port->hasExtBitOp
5832 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5835 /* found it : create the AST */
5836 return newNode (SWAP, root->left->left, NULL);
5840 /* not found return root */
5844 /*-----------------------------------------------------------------*/
5845 /* optimizeCompare - optimizes compares for bit variables */
5846 /*-----------------------------------------------------------------*/
5848 optimizeCompare (ast * root)
5850 ast *optExpr = NULL;
5853 unsigned int litValue;
5855 /* if nothing then return nothing */
5859 /* if not a compare op then do leaves */
5860 if (!IS_COMPARE_OP (root))
5862 root->left = optimizeCompare (root->left);
5863 root->right = optimizeCompare (root->right);
5867 /* if left & right are the same then depending
5868 of the operation do */
5869 if (isAstEqual (root->left, root->right))
5871 switch (root->opval.op)
5876 optExpr = newAst_VALUE (constCharVal (0));
5881 optExpr = newAst_VALUE (constCharVal (1));
5885 return decorateType (optExpr, RESULT_TYPE_NONE);
5888 vleft = (root->left->type == EX_VALUE ?
5889 root->left->opval.val : NULL);
5891 vright = (root->right->type == EX_VALUE ?
5892 root->right->opval.val : NULL);
5894 /* if left is a BITVAR in BITSPACE */
5895 /* and right is a LITERAL then */
5896 /* optimize else do nothing */
5897 if (vleft && vright &&
5898 IS_BITVAR (vleft->etype) &&
5899 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5900 IS_LITERAL (vright->etype))
5903 /* if right side > 1 then comparison may never succeed */
5904 if ((litValue = (int) ulFromVal (vright)) > 1)
5906 werror (W_BAD_COMPARE);
5912 switch (root->opval.op)
5914 case '>': /* bit value greater than 1 cannot be */
5915 werror (W_BAD_COMPARE);
5919 case '<': /* bit value < 1 means 0 */
5921 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5924 case LE_OP: /* bit value <= 1 means no check */
5925 optExpr = newAst_VALUE (vright);
5928 case GE_OP: /* bit value >= 1 means only check for = */
5930 optExpr = newAst_VALUE (vleft);
5935 { /* literal is zero */
5936 switch (root->opval.op)
5938 case '<': /* bit value < 0 cannot be */
5939 werror (W_BAD_COMPARE);
5943 case '>': /* bit value > 0 means 1 */
5945 optExpr = newAst_VALUE (vleft);
5948 case LE_OP: /* bit value <= 0 means no check */
5949 case GE_OP: /* bit value >= 0 means no check */
5950 werror (W_BAD_COMPARE);
5954 case EQ_OP: /* bit == 0 means ! of bit */
5955 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5959 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5960 } /* end-of-if of BITVAR */
5966 /*-----------------------------------------------------------------*/
5967 /* addSymToBlock : adds the symbol to the first block we find */
5968 /*-----------------------------------------------------------------*/
5970 addSymToBlock (symbol * sym, ast * tree)
5972 /* reached end of tree or a leaf */
5973 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5977 if (IS_AST_OP (tree) &&
5978 tree->opval.op == BLOCK)
5981 symbol *lsym = copySymbol (sym);
5983 lsym->next = AST_VALUES (tree, sym);
5984 AST_VALUES (tree, sym) = lsym;
5988 addSymToBlock (sym, tree->left);
5989 addSymToBlock (sym, tree->right);
5992 /*-----------------------------------------------------------------*/
5993 /* processRegParms - do processing for register parameters */
5994 /*-----------------------------------------------------------------*/
5996 processRegParms (value * args, ast * body)
6000 if (IS_REGPARM (args->etype))
6001 addSymToBlock (args->sym, body);
6006 /*-----------------------------------------------------------------*/
6007 /* resetParmKey - resets the operandkeys for the symbols */
6008 /*-----------------------------------------------------------------*/
6009 DEFSETFUNC (resetParmKey)
6020 /*------------------------------------------------------------------*/
6021 /* fixupInlineLabel - change a label in an inlined function so that */
6022 /* it is always unique no matter how many times */
6023 /* the function is inlined. */
6024 /*------------------------------------------------------------------*/
6026 fixupInlineLabel (symbol * sym)
6028 char name[SDCC_NAME_MAX + 1];
6030 SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
6031 strcpy (sym->name, name);
6034 /*------------------------------------------------------------------*/
6035 /* copyAstLoc - copy location information (file, line, block, etc.) */
6036 /* from one ast node to another */
6037 /*------------------------------------------------------------------*/
6039 copyAstLoc (ast * dest, ast * src)
6041 dest->filename = src->filename;
6042 dest->lineno = src->lineno;
6043 dest->level = src->level;
6044 dest->block = src->block;
6045 dest->seqPoint = src->seqPoint;
6048 /*-----------------------------------------------------------------*/
6049 /* fixupInline - perform various fixups on an inline function tree */
6050 /* to take into account that it is no longer a */
6051 /* stand-alone function. */
6052 /*-----------------------------------------------------------------*/
6054 fixupInline (ast * tree, int level)
6056 int savedBlockno = currBlockno;
6058 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
6062 currBlockno = ++blockNo;
6065 /* Add any declared variables back into the symbol table */
6066 decls = tree->values.sym;
6069 decls->level = level;
6070 decls->block = currBlockno;
6071 addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0);
6072 decls = decls->next;
6076 tree->level = level;
6077 tree->block = currBlockno;
6079 /* Update symbols */
6080 if (IS_AST_VALUE (tree) &&
6081 tree->opval.val->sym)
6083 symbol * sym = tree->opval.val->sym;
6086 sym->block = currBlockno;
6089 SYM_SPIL_LOC (sym) = NULL;
6092 /* If the symbol is a label, we need to renumber it */
6094 fixupInlineLabel (sym);
6097 /* Update IFX target labels */
6098 if (tree->type == EX_OP && tree->opval.op == IFX)
6100 if (tree->trueLabel)
6101 fixupInlineLabel (tree->trueLabel);
6102 if (tree->falseLabel)
6103 fixupInlineLabel (tree->falseLabel);
6106 /* Replace RETURN with optional assignment and a GOTO to the end */
6107 /* of the inlined function */
6108 if (tree->type == EX_OP && tree->opval.op == RETURN)
6110 ast * assignTree = NULL;
6113 if (inlineState.retsym && tree->right)
6115 assignTree = newNode ('=',
6116 newAst_VALUE (symbolVal (inlineState.retsym)),
6118 copyAstLoc (assignTree, tree);
6121 gotoTree = newNode (GOTO,
6122 newAst_VALUE (symbolVal (inlineState.retlab)),
6124 copyAstLoc (gotoTree, tree);
6126 tree->opval.op = NULLOP;
6127 tree->left = assignTree;
6128 tree->right = gotoTree;
6131 /* Update any children */
6133 fixupInline (tree->left, level);
6135 fixupInline (tree->right, level);
6137 if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
6139 symbol * label = tree->left->opval.val->sym;
6141 label->key = labelKey++;
6142 /* Add this label back into the symbol table */
6143 addSym (LabelTab, label, label->name, label->level, 0, 0);
6146 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
6149 currBlockno = savedBlockno;
6153 /*-----------------------------------------------------------------*/
6154 /* inlineAddDecl - add a variable declaration to an ast block. It */
6155 /* is also added to the symbol table if addSymTab */
6157 /*-----------------------------------------------------------------*/
6159 inlineAddDecl (symbol * sym, ast * block, int addSymTab)
6162 SYM_SPIL_LOC (sym) = NULL;
6166 symbol **decl = &(block->values.sym);
6168 sym->level = block->level;
6169 sym->block = block->block;
6173 if (strcmp ((*decl)->name, sym->name) == 0)
6175 decl = &( (*decl)->next );
6181 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0);
6186 /*-----------------------------------------------------------------*/
6187 /* inlineTempVar - create a temporary variable for inlining */
6188 /*-----------------------------------------------------------------*/
6190 inlineTempVar (sym_link * type, int level)
6194 sym = newSymbol (genSymName(level), level );
6195 sym->type = copyLinkChain (type);
6196 sym->etype = getSpec(sym->type);
6197 SPEC_SCLS (sym->etype) = S_AUTO;
6198 SPEC_OCLS (sym->etype) = NULL;
6199 SPEC_EXTR (sym->etype) = 0;
6200 SPEC_STAT (sym->etype) = 0;
6201 if IS_SPEC (sym->type)
6202 SPEC_VOLATILE (sym->type) = 0;
6204 DCL_PTR_VOLATILE (sym->type) = 0;
6205 SPEC_ABSA (sym->etype) = 0;
6210 /*-----------------------------------------------------------------*/
6211 /* inlineFindParmRecurse - recursive function for inlineFindParm */
6212 /*-----------------------------------------------------------------*/
6214 inlineFindParmRecurse (ast * parms, int *index)
6219 if (parms->type == EX_OP && parms->opval.op == PARAM)
6223 p=inlineFindParmRecurse (parms->left, index);
6226 p=inlineFindParmRecurse (parms->right, index);
6236 /*-----------------------------------------------------------------*/
6237 /* inlineFindParm - search an ast tree of parameters to find one */
6238 /* at a particular index (0=first parameter). */
6239 /* Returns NULL if not found. */
6240 /*-----------------------------------------------------------------*/
6242 inlineFindParm (ast * parms, int index)
6244 return inlineFindParmRecurse (parms, &index);
6247 /*-----------------------------------------------------------------*/
6248 /* expandInlineFuncs - replace calls to inline functions with the */
6249 /* function itself */
6250 /*-----------------------------------------------------------------*/
6252 expandInlineFuncs (ast * tree, ast * block)
6254 if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left
6255 && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym)
6257 symbol * func = tree->left->opval.val->sym;
6260 /* The symbol is probably not bound yet, so find the real one */
6261 csym = findSymWithLevel (SymbolTab, func);
6265 /* Is this an inline function that we can inline? */
6266 if (IFFUNC_ISINLINE (func->type) && func->funcTree)
6268 symbol * retsym = NULL;
6276 /* Generate a label for the inlined function to branch to */
6277 /* in case it contains a return statement */
6278 retlab = newSymbol (genSymName(tree->level+1), tree->level+1 );
6281 inlineState.retlab = retlab;
6283 /* Build the subtree for the inlined function in the form: */
6284 /* { //inlinetree block */
6285 /* { //inlinetree2 block */
6286 /* inline_function_code; */
6290 temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL);
6291 copyAstLoc (temptree, tree);
6292 temptree = newNode (NULLOP, copyAst (func->funcTree), temptree);
6293 copyAstLoc (temptree, tree);
6294 temptree = newNode (BLOCK, NULL, temptree);
6295 copyAstLoc (temptree, tree);
6296 inlinetree2 = temptree;
6297 inlinetree = newNode (BLOCK, NULL, inlinetree2);
6298 copyAstLoc (inlinetree, tree);
6300 /* To pass parameters to the inlined function, we need some */
6301 /* intermediate variables. This avoids scoping problems */
6302 /* when the parameter declaration names are used differently */
6303 /* during the function call. For example, a function */
6304 /* declared as func(int x, int y) but called as func(y,x). */
6305 /* { //inlinetree block */
6306 /* type1 temparg1 = argument1; */
6308 /* typen tempargn = argumentn; */
6309 /* { //inlinetree2 block */
6310 /* type1 param1 = temparg1; */
6312 /* typen paramn = tempargn; */
6313 /* inline_function_code; */
6317 args = FUNC_ARGS (func->type);
6324 ast * passedarg = inlineFindParm (tree->right, argIndex);
6328 werror(E_TOO_FEW_PARMS);
6332 temparg = inlineTempVar (args->sym->type, tree->level+1);
6333 inlineAddDecl (temparg, inlinetree, FALSE);
6335 assigntree = newNode ('=',
6336 newAst_VALUE (symbolVal (temparg)),
6338 assigntree->initMode=1; // tell that assignment is initializer
6339 inlinetree->right = newNode (NULLOP,
6343 parm = copySymbol (args->sym);
6344 inlineAddDecl (parm, inlinetree2, FALSE);
6347 assigntree = newNode ('=',
6348 newAst_VALUE (symbolVal (parm)),
6349 newAst_VALUE (symbolVal (temparg)));
6350 assigntree->initMode=1; // tell that assignment is initializer
6351 inlinetree2->right = newNode (NULLOP,
6353 inlinetree2->right);
6359 /* Handle the return type */
6360 if (!IS_VOID (func->type->next))
6362 /* Create a temporary symbol to hold the return value and */
6363 /* join it with the inlined function using the comma */
6364 /* operator. The fixupInline function will take care of */
6365 /* changing return statements into assignments to retsym. */
6366 /* (parameter passing and return label omitted for clarity) */
6367 /* rettype retsym; */
6369 /* {{inline_function_code}}, retsym */
6371 retsym = inlineTempVar (func->type->next, tree->level);
6372 inlineAddDecl (retsym, block, TRUE);
6374 tree->opval.op = ',';
6375 tree->left = inlinetree;
6376 tree->right = newAst_VALUE (symbolVal (retsym));
6380 tree->opval.op = NULLOP;
6382 tree->right = inlinetree;
6384 inlineState.retsym = retsym;
6386 /* Renumber the various internal counters on the inlined */
6387 /* function's tree nodes and symbols. Add the inlined */
6388 /* function's local variables to the appropriate scope(s). */
6389 /* Convert inlined return statements to an assignment to */
6390 /* retsym (if needed) and a goto retlab. */
6391 fixupInline (inlinetree, inlinetree->level);
6392 inlineState.count++;
6396 /* Recursively continue to search for functions to inline. */
6397 if (IS_AST_OP (tree))
6399 if (tree->opval.op == BLOCK)
6403 expandInlineFuncs (tree->left, block);
6405 expandInlineFuncs (tree->right, block);
6409 /*-----------------------------------------------------------------*/
6410 /* createFunction - This is the key node that calls the iCode for */
6411 /* generating the code for a function. Note code */
6412 /* is generated function by function, later when */
6413 /* add inter-procedural analysis this will change */
6414 /*-----------------------------------------------------------------*/
6416 createFunction (symbol * name, ast * body)
6422 iCode *piCode = NULL;
6424 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
6425 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
6427 /* if check function return 0 then some problem */
6428 if (checkFunction (name, NULL) == 0)
6431 /* create a dummy block if none exists */
6433 body = newNode (BLOCK, NULL, NULL);
6437 /* check if the function name already in the symbol table */
6438 if ((csym = findSym (SymbolTab, NULL, name->name)))
6441 /* special case for compiler defined functions
6442 we need to add the name to the publics list : this
6443 actually means we are now compiling the compiler
6447 addSet (&publics, name);
6452 addSymChain (&name);
6453 allocVariables (name);
6455 name->lastLine = lexLineno;
6458 /* set the stack pointer */
6459 stackPtr = -port->stack.direction * port->stack.call_overhead;
6462 if (IFFUNC_ISISR (name->type))
6463 stackPtr -= port->stack.direction * port->stack.isr_overhead;
6465 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
6467 if (options.useXstack)
6468 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
6470 stackPtr -= port->stack.direction * port->stack.reent_overhead;
6473 fetype = getSpec (name->type); /* get the specifier for the function */
6474 /* if this is a reentrant function then */
6475 if (IFFUNC_ISREENT (name->type))
6478 inlineState.count = 0;
6479 expandInlineFuncs (body, NULL);
6481 if (FUNC_ISINLINE (name->type))
6482 name->funcTree = copyAst (body);
6484 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
6486 /* do processing for parameters that are passed in registers */
6487 processRegParms (FUNC_ARGS(name->type), body);
6489 /* set the stack pointer */
6493 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
6495 /* allocate & autoinit the block variables */
6496 processBlockVars (body, &stack, ALLOCATE);
6498 /* name needs to be mangled */
6499 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
6501 body = resolveSymbols (body); /* resolve the symbols */
6502 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
6504 /* save the stack information */
6505 if (options.useXstack)
6506 name->xstack = SPEC_STAK (fetype) = stack;
6508 name->stack = SPEC_STAK (fetype) = stack;
6510 ex = newAst_VALUE (symbolVal (name)); /* create name */
6511 ex = newNode (FUNCTION, ex, body);
6512 ex->values.args = FUNC_ARGS(name->type);
6514 if (options.dump_tree)
6519 /* Do not generate code for inline functions unless extern also. */
6521 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
6524 /* Temporary hack: always generate code for static inline functions. */
6525 /* Ideally static inline functions should only be generated if needed. */
6526 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype) && !IS_STATIC (fetype))
6530 /* create the node & generate intermediate code */
6532 codeOutBuf = &code->oBuf;
6533 piCode = iCodeFromAst (ex);
6534 name->generated = 1;
6539 eBBlockFromiCode (piCode);
6541 /* if there are any statics then do them */
6544 GcurMemmap = statsg;
6545 codeOutBuf = &statsg->oBuf;
6546 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6552 /* dealloc the block variables */
6553 processBlockVars (body, &stack, DEALLOCATE);
6554 outputDebugStackSymbols();
6555 /* deallocate paramaters */
6556 deallocParms (FUNC_ARGS(name->type));
6558 if (IFFUNC_ISREENT (name->type))
6561 /* we are done freeup memory & cleanup */
6563 if (port->reset_labelKey)
6566 FUNC_HASBODY(name->type) = 1;
6567 addSet (&operKeyReset, name);
6568 applyToSet (operKeyReset, resetParmKey);
6573 cleanUpLevel (LabelTab, 0);
6574 cleanUpBlock (StructTab, 1);
6575 cleanUpBlock (TypedefTab, 1);
6577 xstack->syms = NULL;
6578 istack->syms = NULL;
6583 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6584 /*-----------------------------------------------------------------*/
6585 /* ast_print : prints the ast (for debugging purposes) */
6586 /*-----------------------------------------------------------------*/
6588 void ast_print (ast * tree, FILE *outfile, int indent)
6593 /* can print only decorated trees */
6594 if (!tree->decorated) return;
6596 /* if any child is an error | this one is an error do nothing */
6597 if (tree->isError ||
6598 (tree->left && tree->left->isError) ||
6599 (tree->right && tree->right->isError)) {
6600 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6604 /* print the line */
6605 /* if not block & function */
6606 if (tree->type == EX_OP &&
6607 (tree->opval.op != FUNCTION &&
6608 tree->opval.op != BLOCK &&
6609 tree->opval.op != NULLOP)) {
6612 if (tree->opval.op == FUNCTION) {
6614 value *args=FUNC_ARGS(tree->left->opval.val->type);
6615 fprintf(outfile,"FUNCTION (%s=%p) type (",
6616 tree->left->opval.val->name, tree);
6617 printTypeChain (tree->left->opval.val->type->next,outfile);
6618 fprintf(outfile,") args (");
6621 fprintf (outfile, ", ");
6623 printTypeChain (args ? args->type : NULL, outfile);
6625 args= args ? args->next : NULL;
6627 fprintf(outfile,")\n");
6628 ast_print(tree->left,outfile,indent);
6629 ast_print(tree->right,outfile,indent);
6632 if (tree->opval.op == BLOCK) {
6633 symbol *decls = tree->values.sym;
6634 INDENT(indent,outfile);
6635 fprintf(outfile,"{\n");
6637 INDENT(indent+2,outfile);
6638 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6639 decls->name, decls);
6640 printTypeChain(decls->type,outfile);
6641 fprintf(outfile,")\n");
6643 decls = decls->next;
6645 ast_print(tree->right,outfile,indent+2);
6646 INDENT(indent,outfile);
6647 fprintf(outfile,"}\n");
6650 if (tree->opval.op == NULLOP) {
6651 ast_print(tree->left,outfile,indent);
6652 ast_print(tree->right,outfile,indent);
6655 INDENT(indent,outfile);
6657 /*------------------------------------------------------------------*/
6658 /*----------------------------*/
6659 /* leaf has been reached */
6660 /*----------------------------*/
6661 /* if this is of type value */
6662 /* just get the type */
6663 if (tree->type == EX_VALUE) {
6665 if (IS_LITERAL (tree->opval.val->etype)) {
6666 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6667 if (SPEC_USIGN (tree->opval.val->etype))
6668 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val));
6670 fprintf(outfile,"%d", (TYPE_TARGET_LONG) ulFromVal(tree->opval.val));
6671 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val),
6672 floatFromVal(tree->opval.val));
6673 } else if (tree->opval.val->sym) {
6674 /* if the undefined flag is set then give error message */
6675 if (tree->opval.val->sym->undefined) {
6676 fprintf(outfile,"UNDEFINED SYMBOL ");
6678 fprintf(outfile,"SYMBOL ");
6680 fprintf(outfile,"(%s=%p @ %p)",
6681 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6684 fprintf(outfile," type (");
6685 printTypeChain(tree->ftype,outfile);
6686 fprintf(outfile,")\n");
6688 fprintf(outfile,"\n");
6693 /* if type link for the case of cast */
6694 if (tree->type == EX_LINK) {
6695 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6696 printTypeChain(tree->opval.lnk,outfile);
6697 fprintf(outfile,")\n");
6702 /* depending on type of operator do */
6704 switch (tree->opval.op) {
6705 /*------------------------------------------------------------------*/
6706 /*----------------------------*/
6708 /*----------------------------*/
6710 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6711 printTypeChain(tree->ftype,outfile);
6712 fprintf(outfile,")\n");
6713 ast_print(tree->left,outfile,indent+2);
6714 ast_print(tree->right,outfile,indent+2);
6717 /*------------------------------------------------------------------*/
6718 /*----------------------------*/
6720 /*----------------------------*/
6722 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6723 printTypeChain(tree->ftype,outfile);
6724 fprintf(outfile,")\n");
6725 ast_print(tree->left,outfile,indent+2);
6726 ast_print(tree->right,outfile,indent+2);
6729 /*------------------------------------------------------------------*/
6730 /*----------------------------*/
6731 /* struct/union pointer */
6732 /*----------------------------*/
6734 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6735 printTypeChain(tree->ftype,outfile);
6736 fprintf(outfile,")\n");
6737 ast_print(tree->left,outfile,indent+2);
6738 ast_print(tree->right,outfile,indent+2);
6741 /*------------------------------------------------------------------*/
6742 /*----------------------------*/
6743 /* ++/-- operation */
6744 /*----------------------------*/
6747 fprintf(outfile,"post-");
6749 fprintf(outfile,"pre-");
6750 fprintf(outfile,"INC_OP (%p) type (",tree);
6751 printTypeChain(tree->ftype,outfile);
6752 fprintf(outfile,")\n");
6753 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6754 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6759 fprintf(outfile,"post-");
6761 fprintf(outfile,"pre-");
6762 fprintf(outfile,"DEC_OP (%p) type (",tree);
6763 printTypeChain(tree->ftype,outfile);
6764 fprintf(outfile,")\n");
6765 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6766 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6769 /*------------------------------------------------------------------*/
6770 /*----------------------------*/
6772 /*----------------------------*/
6775 fprintf(outfile,"& (%p) type (",tree);
6776 printTypeChain(tree->ftype,outfile);
6777 fprintf(outfile,")\n");
6778 ast_print(tree->left,outfile,indent+2);
6779 ast_print(tree->right,outfile,indent+2);
6781 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6782 printTypeChain(tree->ftype,outfile);
6783 fprintf(outfile,")\n");
6784 ast_print(tree->left,outfile,indent+2);
6785 ast_print(tree->right,outfile,indent+2);
6788 /*----------------------------*/
6790 /*----------------------------*/
6792 fprintf(outfile,"OR (%p) type (",tree);
6793 printTypeChain(tree->ftype,outfile);
6794 fprintf(outfile,")\n");
6795 ast_print(tree->left,outfile,indent+2);
6796 ast_print(tree->right,outfile,indent+2);
6798 /*------------------------------------------------------------------*/
6799 /*----------------------------*/
6801 /*----------------------------*/
6803 fprintf(outfile,"XOR (%p) type (",tree);
6804 printTypeChain(tree->ftype,outfile);
6805 fprintf(outfile,")\n");
6806 ast_print(tree->left,outfile,indent+2);
6807 ast_print(tree->right,outfile,indent+2);
6810 /*------------------------------------------------------------------*/
6811 /*----------------------------*/
6813 /*----------------------------*/
6815 fprintf(outfile,"DIV (%p) type (",tree);
6816 printTypeChain(tree->ftype,outfile);
6817 fprintf(outfile,")\n");
6818 ast_print(tree->left,outfile,indent+2);
6819 ast_print(tree->right,outfile,indent+2);
6821 /*------------------------------------------------------------------*/
6822 /*----------------------------*/
6824 /*----------------------------*/
6826 fprintf(outfile,"MOD (%p) type (",tree);
6827 printTypeChain(tree->ftype,outfile);
6828 fprintf(outfile,")\n");
6829 ast_print(tree->left,outfile,indent+2);
6830 ast_print(tree->right,outfile,indent+2);
6833 /*------------------------------------------------------------------*/
6834 /*----------------------------*/
6835 /* address dereference */
6836 /*----------------------------*/
6837 case '*': /* can be unary : if right is null then unary operation */
6839 fprintf(outfile,"DEREF (%p) type (",tree);
6840 printTypeChain(tree->ftype,outfile);
6841 fprintf(outfile,")\n");
6842 ast_print(tree->left,outfile,indent+2);
6845 /*------------------------------------------------------------------*/
6846 /*----------------------------*/
6847 /* multiplication */
6848 /*----------------------------*/
6849 fprintf(outfile,"MULT (%p) type (",tree);
6850 printTypeChain(tree->ftype,outfile);
6851 fprintf(outfile,")\n");
6852 ast_print(tree->left,outfile,indent+2);
6853 ast_print(tree->right,outfile,indent+2);
6857 /*------------------------------------------------------------------*/
6858 /*----------------------------*/
6859 /* unary '+' operator */
6860 /*----------------------------*/
6864 fprintf(outfile,"UPLUS (%p) type (",tree);
6865 printTypeChain(tree->ftype,outfile);
6866 fprintf(outfile,")\n");
6867 ast_print(tree->left,outfile,indent+2);
6869 /*------------------------------------------------------------------*/
6870 /*----------------------------*/
6872 /*----------------------------*/
6873 fprintf(outfile,"ADD (%p) type (",tree);
6874 printTypeChain(tree->ftype,outfile);
6875 fprintf(outfile,")\n");
6876 ast_print(tree->left,outfile,indent+2);
6877 ast_print(tree->right,outfile,indent+2);
6880 /*------------------------------------------------------------------*/
6881 /*----------------------------*/
6883 /*----------------------------*/
6884 case '-': /* can be unary */
6886 fprintf(outfile,"UMINUS (%p) type (",tree);
6887 printTypeChain(tree->ftype,outfile);
6888 fprintf(outfile,")\n");
6889 ast_print(tree->left,outfile,indent+2);
6891 /*------------------------------------------------------------------*/
6892 /*----------------------------*/
6894 /*----------------------------*/
6895 fprintf(outfile,"SUB (%p) type (",tree);
6896 printTypeChain(tree->ftype,outfile);
6897 fprintf(outfile,")\n");
6898 ast_print(tree->left,outfile,indent+2);
6899 ast_print(tree->right,outfile,indent+2);
6902 /*------------------------------------------------------------------*/
6903 /*----------------------------*/
6905 /*----------------------------*/
6907 fprintf(outfile,"COMPL (%p) type (",tree);
6908 printTypeChain(tree->ftype,outfile);
6909 fprintf(outfile,")\n");
6910 ast_print(tree->left,outfile,indent+2);
6912 /*------------------------------------------------------------------*/
6913 /*----------------------------*/
6915 /*----------------------------*/
6917 fprintf(outfile,"NOT (%p) type (",tree);
6918 printTypeChain(tree->ftype,outfile);
6919 fprintf(outfile,")\n");
6920 ast_print(tree->left,outfile,indent+2);
6922 /*------------------------------------------------------------------*/
6923 /*----------------------------*/
6925 /*----------------------------*/
6927 fprintf(outfile,"RRC (%p) type (",tree);
6928 printTypeChain(tree->ftype,outfile);
6929 fprintf(outfile,")\n");
6930 ast_print(tree->left,outfile,indent+2);
6934 fprintf(outfile,"RLC (%p) type (",tree);
6935 printTypeChain(tree->ftype,outfile);
6936 fprintf(outfile,")\n");
6937 ast_print(tree->left,outfile,indent+2);
6940 fprintf(outfile,"SWAP (%p) type (",tree);
6941 printTypeChain(tree->ftype,outfile);
6942 fprintf(outfile,")\n");
6943 ast_print(tree->left,outfile,indent+2);
6946 fprintf(outfile,"GETHBIT (%p) type (",tree);
6947 printTypeChain(tree->ftype,outfile);
6948 fprintf(outfile,")\n");
6949 ast_print(tree->left,outfile,indent+2);
6952 fprintf(outfile,"GETABIT (%p) type (",tree);
6953 printTypeChain(tree->ftype,outfile);
6954 fprintf(outfile,")\n");
6955 ast_print(tree->left,outfile,indent+2);
6956 ast_print(tree->right,outfile,indent+2);
6959 fprintf(outfile,"GETBYTE (%p) type (",tree);
6960 printTypeChain(tree->ftype,outfile);
6961 fprintf(outfile,")\n");
6962 ast_print(tree->left,outfile,indent+2);
6963 ast_print(tree->right,outfile,indent+2);
6966 fprintf(outfile,"GETWORD (%p) type (",tree);
6967 printTypeChain(tree->ftype,outfile);
6968 fprintf(outfile,")\n");
6969 ast_print(tree->left,outfile,indent+2);
6970 ast_print(tree->right,outfile,indent+2);
6973 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6974 printTypeChain(tree->ftype,outfile);
6975 fprintf(outfile,")\n");
6976 ast_print(tree->left,outfile,indent+2);
6977 ast_print(tree->right,outfile,indent+2);
6980 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6981 printTypeChain(tree->ftype,outfile);
6982 fprintf(outfile,")\n");
6983 ast_print(tree->left,outfile,indent+2);
6984 ast_print(tree->right,outfile,indent+2);
6986 /*------------------------------------------------------------------*/
6987 /*----------------------------*/
6989 /*----------------------------*/
6990 case CAST: /* change the type */
6991 fprintf(outfile,"CAST (%p) from type (",tree);
6992 printTypeChain(tree->right->ftype,outfile);
6993 fprintf(outfile,") to type (");
6994 printTypeChain(tree->ftype,outfile);
6995 fprintf(outfile,")\n");
6996 ast_print(tree->right,outfile,indent+2);
7000 fprintf(outfile,"ANDAND (%p) type (",tree);
7001 printTypeChain(tree->ftype,outfile);
7002 fprintf(outfile,")\n");
7003 ast_print(tree->left,outfile,indent+2);
7004 ast_print(tree->right,outfile,indent+2);
7007 fprintf(outfile,"OROR (%p) type (",tree);
7008 printTypeChain(tree->ftype,outfile);
7009 fprintf(outfile,")\n");
7010 ast_print(tree->left,outfile,indent+2);
7011 ast_print(tree->right,outfile,indent+2);
7014 /*------------------------------------------------------------------*/
7015 /*----------------------------*/
7016 /* comparison operators */
7017 /*----------------------------*/
7019 fprintf(outfile,"GT(>) (%p) type (",tree);
7020 printTypeChain(tree->ftype,outfile);
7021 fprintf(outfile,")\n");
7022 ast_print(tree->left,outfile,indent+2);
7023 ast_print(tree->right,outfile,indent+2);
7026 fprintf(outfile,"LT(<) (%p) type (",tree);
7027 printTypeChain(tree->ftype,outfile);
7028 fprintf(outfile,")\n");
7029 ast_print(tree->left,outfile,indent+2);
7030 ast_print(tree->right,outfile,indent+2);
7033 fprintf(outfile,"LE(<=) (%p) type (",tree);
7034 printTypeChain(tree->ftype,outfile);
7035 fprintf(outfile,")\n");
7036 ast_print(tree->left,outfile,indent+2);
7037 ast_print(tree->right,outfile,indent+2);
7040 fprintf(outfile,"GE(>=) (%p) type (",tree);
7041 printTypeChain(tree->ftype,outfile);
7042 fprintf(outfile,")\n");
7043 ast_print(tree->left,outfile,indent+2);
7044 ast_print(tree->right,outfile,indent+2);
7047 fprintf(outfile,"EQ(==) (%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,"NE(!=) (%p) type (",tree);
7055 printTypeChain(tree->ftype,outfile);
7056 fprintf(outfile,")\n");
7057 ast_print(tree->left,outfile,indent+2);
7058 ast_print(tree->right,outfile,indent+2);
7059 /*------------------------------------------------------------------*/
7060 /*----------------------------*/
7062 /*----------------------------*/
7063 case SIZEOF: /* evaluate wihout code generation */
7064 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
7067 /*------------------------------------------------------------------*/
7068 /*----------------------------*/
7069 /* conditional operator '?' */
7070 /*----------------------------*/
7072 fprintf(outfile,"QUEST(?) (%p) type (",tree);
7073 printTypeChain(tree->ftype,outfile);
7074 fprintf(outfile,")\n");
7075 ast_print(tree->left,outfile,indent+2);
7076 ast_print(tree->right,outfile,indent+2);
7080 fprintf(outfile,"COLON(:) (%p) type (",tree);
7081 printTypeChain(tree->ftype,outfile);
7082 fprintf(outfile,")\n");
7083 ast_print(tree->left,outfile,indent+2);
7084 ast_print(tree->right,outfile,indent+2);
7087 /*------------------------------------------------------------------*/
7088 /*----------------------------*/
7089 /* assignment operators */
7090 /*----------------------------*/
7092 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
7093 printTypeChain(tree->ftype,outfile);
7094 fprintf(outfile,")\n");
7095 ast_print(tree->left,outfile,indent+2);
7096 ast_print(tree->right,outfile,indent+2);
7099 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
7100 printTypeChain(tree->ftype,outfile);
7101 fprintf(outfile,")\n");
7102 ast_print(tree->left,outfile,indent+2);
7103 ast_print(tree->right,outfile,indent+2);
7106 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
7107 printTypeChain(tree->ftype,outfile);
7108 fprintf(outfile,")\n");
7109 ast_print(tree->left,outfile,indent+2);
7110 ast_print(tree->right,outfile,indent+2);
7113 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
7114 printTypeChain(tree->ftype,outfile);
7115 fprintf(outfile,")\n");
7116 ast_print(tree->left,outfile,indent+2);
7117 ast_print(tree->right,outfile,indent+2);
7120 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
7121 printTypeChain(tree->ftype,outfile);
7122 fprintf(outfile,")\n");
7123 ast_print(tree->left,outfile,indent+2);
7124 ast_print(tree->right,outfile,indent+2);
7127 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
7128 printTypeChain(tree->ftype,outfile);
7129 fprintf(outfile,")\n");
7130 ast_print(tree->left,outfile,indent+2);
7131 ast_print(tree->right,outfile,indent+2);
7134 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
7135 printTypeChain(tree->ftype,outfile);
7136 fprintf(outfile,")\n");
7137 ast_print(tree->left,outfile,indent+2);
7138 ast_print(tree->right,outfile,indent+2);
7140 /*------------------------------------------------------------------*/
7141 /*----------------------------*/
7143 /*----------------------------*/
7145 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
7146 printTypeChain(tree->ftype,outfile);
7147 fprintf(outfile,")\n");
7148 ast_print(tree->left,outfile,indent+2);
7149 ast_print(tree->right,outfile,indent+2);
7151 /*------------------------------------------------------------------*/
7152 /*----------------------------*/
7154 /*----------------------------*/
7156 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
7157 printTypeChain(tree->ftype,outfile);
7158 fprintf(outfile,")\n");
7159 ast_print(tree->left,outfile,indent+2);
7160 ast_print(tree->right,outfile,indent+2);
7162 /*------------------------------------------------------------------*/
7163 /*----------------------------*/
7164 /* straight assignemnt */
7165 /*----------------------------*/
7167 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
7168 printTypeChain(tree->ftype,outfile);
7169 fprintf(outfile,")\n");
7170 ast_print(tree->left,outfile,indent+2);
7171 ast_print(tree->right,outfile,indent+2);
7173 /*------------------------------------------------------------------*/
7174 /*----------------------------*/
7175 /* comma operator */
7176 /*----------------------------*/
7178 fprintf(outfile,"COMMA(,) (%p) type (",tree);
7179 printTypeChain(tree->ftype,outfile);
7180 fprintf(outfile,")\n");
7181 ast_print(tree->left,outfile,indent+2);
7182 ast_print(tree->right,outfile,indent+2);
7184 /*------------------------------------------------------------------*/
7185 /*----------------------------*/
7187 /*----------------------------*/
7190 fprintf(outfile,"CALL (%p) type (",tree);
7191 printTypeChain(tree->ftype,outfile);
7192 fprintf(outfile,")\n");
7193 ast_print(tree->left,outfile,indent+2);
7194 ast_print(tree->right,outfile,indent+2);
7197 fprintf(outfile,"PARMS\n");
7198 ast_print(tree->left,outfile,indent+2);
7199 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
7200 ast_print(tree->right,outfile,indent+2);
7203 /*------------------------------------------------------------------*/
7204 /*----------------------------*/
7205 /* return statement */
7206 /*----------------------------*/
7208 fprintf(outfile,"RETURN (%p) type (",tree);
7210 printTypeChain(tree->right->ftype,outfile);
7212 fprintf(outfile,")\n");
7213 ast_print(tree->right,outfile,indent+2);
7215 /*------------------------------------------------------------------*/
7216 /*----------------------------*/
7217 /* label statement */
7218 /*----------------------------*/
7220 fprintf(outfile,"LABEL (%p)\n",tree);
7221 ast_print(tree->left,outfile,indent+2);
7222 ast_print(tree->right,outfile,indent);
7224 /*------------------------------------------------------------------*/
7225 /*----------------------------*/
7226 /* switch statement */
7227 /*----------------------------*/
7231 fprintf(outfile,"SWITCH (%p) ",tree);
7232 ast_print(tree->left,outfile,0);
7233 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
7234 INDENT(indent+2,outfile);
7235 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
7236 (int) ulFromVal(val),
7237 tree->values.switchVals.swNum,
7238 (int) ulFromVal(val));
7240 ast_print(tree->right,outfile,indent);
7243 /*------------------------------------------------------------------*/
7244 /*----------------------------*/
7246 /*----------------------------*/
7248 fprintf(outfile,"IF (%p) \n",tree);
7249 ast_print(tree->left,outfile,indent+2);
7250 if (tree->trueLabel) {
7251 INDENT(indent+2,outfile);
7252 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
7254 if (tree->falseLabel) {
7255 INDENT(indent+2,outfile);
7256 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
7258 ast_print(tree->right,outfile,indent+2);
7260 /*----------------------------*/
7261 /* goto Statement */
7262 /*----------------------------*/
7264 fprintf(outfile,"GOTO (%p) \n",tree);
7265 ast_print(tree->left,outfile,indent+2);
7266 fprintf(outfile,"\n");
7268 /*------------------------------------------------------------------*/
7269 /*----------------------------*/
7271 /*----------------------------*/
7273 fprintf(outfile,"FOR (%p) \n",tree);
7274 if (AST_FOR( tree, initExpr)) {
7275 INDENT(indent+2,outfile);
7276 fprintf(outfile,"INIT EXPR ");
7277 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
7279 if (AST_FOR( tree, condExpr)) {
7280 INDENT(indent+2,outfile);
7281 fprintf(outfile,"COND EXPR ");
7282 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
7284 if (AST_FOR( tree, loopExpr)) {
7285 INDENT(indent+2,outfile);
7286 fprintf(outfile,"LOOP EXPR ");
7287 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
7289 fprintf(outfile,"FOR LOOP BODY \n");
7290 ast_print(tree->left,outfile,indent+2);
7293 fprintf(outfile,"CRITICAL (%p) \n",tree);
7294 ast_print(tree->left,outfile,indent+2);
7302 ast_print(t,stdout,0);
7305 /*-----------------------------------------------------------------*/
7306 /* astErrors : returns non-zero if errors present in tree */
7307 /*-----------------------------------------------------------------*/
7308 int astErrors(ast *t)
7317 if (t->type == EX_VALUE
7318 && t->opval.val->sym
7319 && t->opval.val->sym->undefined)
7322 errors += astErrors(t->left);
7323 errors += astErrors(t->right);