1 /*-------------------------------------------------------------------------
2 SDCCast.c - source file for parser support & all ast related routines
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #define DEBUG_CF(x) /* puts(x); */
31 set *operKeyReset = NULL;
32 ast *staticAutos = NULL;
35 int count; /* number of inline functions inserted */
36 symbol * retsym; /* variable for inlined function return value */
37 symbol * retlab; /* label ending inlined function (virtual return) */
40 #define LRVAL(x) x->left->rvalue
41 #define RRVAL(x) x->right->rvalue
42 #define TRVAL(x) x->rvalue
43 #define LLVAL(x) x->left->lvalue
44 #define RLVAL(x) x->right->lvalue
45 #define TLVAL(x) x->lvalue
46 #define RTYPE(x) x->right->ftype
47 #define RETYPE(x) x->right->etype
48 #define LTYPE(x) x->left->ftype
49 #define LETYPE(x) x->left->etype
50 #define TTYPE(x) x->ftype
51 #define TETYPE(x) x->etype
57 symbol *currFunc=NULL;
58 static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
59 static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
60 static ast *optimizeCompare (ast *);
61 ast *optimizeRRCRLC (ast *);
62 ast *optimizeSWAP (ast *);
63 ast *optimizeGetHbit (ast *, RESULT_TYPE);
64 ast *optimizeGetAbit (ast *, RESULT_TYPE);
65 ast *optimizeGetByte (ast *, RESULT_TYPE);
66 ast *optimizeGetWord (ast *, RESULT_TYPE);
67 static ast *backPatchLabels (ast *, symbol *, symbol *);
70 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
71 struct dbuf_s *codeOutBuf;
75 printTypeChain (tree->ftype, stdout);
80 /*-----------------------------------------------------------------*/
81 /* newAst - creates a fresh node for an expression tree */
82 /*-----------------------------------------------------------------*/
84 newAst_ (unsigned type)
87 static int oldLineno = 0;
89 ex = Safe_alloc ( sizeof (ast));
92 ex->lineno = (noLineno ? oldLineno : lexLineno);
93 ex->filename = lexFilename;
94 ex->level = NestLevel;
95 ex->block = currBlockno;
96 ex->initMode = inInitMode;
97 ex->seqPoint = seqPointNo;
102 newAst_VALUE (value * val)
104 ast *ex = newAst_ (EX_VALUE);
110 newAst_OP (unsigned op)
112 ast *ex = newAst_ (EX_OP);
118 newAst_LINK (sym_link * val)
120 ast *ex = newAst_ (EX_LINK);
125 /*-----------------------------------------------------------------*/
126 /* newNode - creates a new node */
127 /*-----------------------------------------------------------------*/
129 newNode (long op, ast * left, ast * right)
140 /*-----------------------------------------------------------------*/
141 /* newIfxNode - creates a new Ifx Node */
142 /*-----------------------------------------------------------------*/
144 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
148 /* if this is a literal then we already know the result */
149 if (condAst->etype && IS_LITERAL (condAst->etype))
151 /* then depending on the expression value */
152 if (floatFromVal (condAst->opval.val))
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (trueLabel)),
157 ifxNode = newNode (GOTO,
158 newAst_VALUE (symbolVal (falseLabel)),
163 ifxNode = newNode (IFX, condAst, NULL);
164 ifxNode->trueLabel = trueLabel;
165 ifxNode->falseLabel = falseLabel;
171 /*-----------------------------------------------------------------*/
172 /* copyAstValues - copies value portion of ast if needed */
173 /*-----------------------------------------------------------------*/
175 copyAstValues (ast * dest, ast * src)
177 switch (src->opval.op)
180 dest->values.sym = copySymbolChain (src->values.sym);
184 dest->values.switchVals.swVals =
185 copyValue (src->values.switchVals.swVals);
186 dest->values.switchVals.swDefault =
187 src->values.switchVals.swDefault;
188 dest->values.switchVals.swNum =
189 src->values.switchVals.swNum;
193 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
197 dest->values.constlist = copyLiteralList(src->values.constlist);
201 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
202 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
203 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
204 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
205 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
206 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
207 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
212 /*-----------------------------------------------------------------*/
213 /* copyAst - makes a copy of a given astession */
214 /*-----------------------------------------------------------------*/
223 dest = Safe_alloc ( sizeof (ast));
225 dest->type = src->type;
226 dest->lineno = src->lineno;
227 dest->level = src->level;
228 dest->funcName = src->funcName;
229 dest->reversed = src->reversed;
232 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
234 /* if this is a leaf */
236 if (src->type == EX_VALUE)
238 dest->opval.val = copyValue (src->opval.val);
243 if (src->type == EX_LINK)
245 dest->opval.lnk = copyLinkChain (src->opval.lnk);
249 dest->opval.op = src->opval.op;
251 /* if this is a node that has special values */
252 copyAstValues (dest, src);
254 dest->trueLabel = copySymbol (src->trueLabel);
255 dest->falseLabel = copySymbol (src->falseLabel);
256 dest->left = copyAst (src->left);
257 dest->right = copyAst (src->right);
263 /*-----------------------------------------------------------------*/
264 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
265 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
266 /*-----------------------------------------------------------------*/
267 ast *removeIncDecOps (ast * tree) {
269 // traverse the tree and remove inc/dec ops
274 if (tree->type == EX_OP &&
275 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
282 tree->left=removeIncDecOps(tree->left);
283 tree->right=removeIncDecOps(tree->right);
288 /*-----------------------------------------------------------------*/
289 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
290 /* "*++s += 3" -> "*++s = *++s + 3" */
291 /*-----------------------------------------------------------------*/
292 ast *removePreIncDecOps (ast * tree) {
294 // traverse the tree and remove pre-inc/dec ops
299 if (tree->type == EX_OP &&
300 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
305 tree->left=removePreIncDecOps(tree->left);
306 tree->right=removePreIncDecOps(tree->right);
311 /*-----------------------------------------------------------------*/
312 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
313 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
314 /*-----------------------------------------------------------------*/
315 ast *removePostIncDecOps (ast * tree) {
317 // traverse the tree and remove pre-inc/dec ops
322 if (tree->type == EX_OP &&
323 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
328 tree->left=removePostIncDecOps(tree->left);
329 tree->right=removePostIncDecOps(tree->right);
334 /*-----------------------------------------------------------------*/
335 /* replaceAstWithTemporary: Replace the AST pointed to by the arg */
336 /* with a reference to a new temporary variable. Returns*/
337 /* an AST which assigns the original value to the */
339 /*-----------------------------------------------------------------*/
340 static ast *replaceAstWithTemporary(ast **treeptr)
342 symbol *sym = newSymbol (genSymName(NestLevel), NestLevel );
345 /* Tell gatherImplicitVariables() to automatically give the
346 symbol the correct type */
351 tempvar = newNode('=', newAst_VALUE(symbolVal(sym)), *treeptr);
352 *treeptr = newAst_VALUE(symbolVal(sym));
359 /*-----------------------------------------------------------------*/
360 /* createRMW: Create a read-modify-write expression, using a */
361 /* temporary variable if necessary to avoid duplicating */
362 /* any side effects, for use in e.g. */
363 /* foo()->count += 5; becomes */
364 /* tmp = foo(); tmp->count = tmp->count + 5; */
365 /*-----------------------------------------------------------------*/
366 ast * createRMW (ast *target, unsigned op, ast *operand)
368 ast *readval, *writeval;
369 ast *tempvar1 = NULL;
370 ast *tempvar2 = NULL;
373 if (!target || !operand) {
377 /* we need to create two copies of target: one to read from and
378 one to write to. but we need to do this without duplicating
379 any side effects that may be contained in the tree. */
381 if (IS_AST_OP(target)) {
382 /* if this is a dereference, put the referenced item in the temporary */
383 if (IS_DEREF_OP(target) || target->opval.op == PTR_OP) {
384 /* create a new temporary containing the item being dereferenced */
385 if (hasSEFcalls(target->left))
386 tempvar1 = replaceAstWithTemporary(&(target->left));
387 } else if (target->opval.op == '[') {
388 /* Array access is similar, but we have to avoid side effects in
389 both values [WIML: Why not transform a[b] to *(a+b) in parser?] */
390 if (hasSEFcalls(target->left))
391 tempvar1 = replaceAstWithTemporary(&(target->left));
392 if (hasSEFcalls(target->right))
393 tempvar2 = replaceAstWithTemporary(&(target->right));
395 /* we would have to handle '.', but it is not generated any more */
396 wassertl(target->opval.op != '.', "obsolete opcode in tree");
398 /* no other kinds of ASTs are lvalues and can contain side effects */
403 writeval = copyAst(target);
405 result = newNode('=', writeval, newNode(op, readval, operand));
407 result = newNode(',', tempvar2, result);
409 result = newNode(',', tempvar1, result);
415 /*-----------------------------------------------------------------*/
416 /* hasSEFcalls - returns TRUE if tree has a function call, */
417 /* inc/decrement, or other side effect */
418 /*-----------------------------------------------------------------*/
420 hasSEFcalls (ast * tree)
425 if (tree->type == EX_OP &&
426 (tree->opval.op == CALL ||
427 tree->opval.op == PCALL ||
428 tree->opval.op == '=' ||
429 tree->opval.op == INC_OP ||
430 tree->opval.op == DEC_OP))
433 return (hasSEFcalls (tree->left) |
434 hasSEFcalls (tree->right));
437 /*-----------------------------------------------------------------*/
438 /* isAstEqual - compares two asts & returns 1 if they are equal */
439 /*-----------------------------------------------------------------*/
441 isAstEqual (ast * t1, ast * t2)
450 if (t1->type != t2->type)
456 if (t1->opval.op != t2->opval.op)
458 return (isAstEqual (t1->left, t2->left) &&
459 isAstEqual (t1->right, t2->right));
463 if (t1->opval.val->sym)
465 if (!t2->opval.val->sym)
468 return isSymbolEqual (t1->opval.val->sym,
473 if (t2->opval.val->sym)
476 return (floatFromVal (t1->opval.val) ==
477 floatFromVal (t2->opval.val));
481 /* only compare these two types */
489 /*-----------------------------------------------------------------*/
490 /* resolveSymbols - resolve symbols from the symbol table */
491 /*-----------------------------------------------------------------*/
493 resolveSymbols (ast * tree)
495 /* walk the entire tree and check for values */
496 /* with symbols if we find one then replace */
497 /* symbol with that from the symbol table */
504 /* if not block & function */
505 if (tree->type == EX_OP &&
506 (tree->opval.op != FUNCTION &&
507 tree->opval.op != BLOCK &&
508 tree->opval.op != NULLOP))
510 filename = tree->filename;
511 lineno = tree->lineno;
515 /* make sure we resolve the true & false labels for ifx */
516 if (tree->type == EX_OP && tree->opval.op == IFX)
522 if ((csym = findSym (LabelTab, tree->trueLabel,
523 tree->trueLabel->name)))
524 tree->trueLabel = csym;
526 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
527 tree->trueLabel->name);
530 if (tree->falseLabel)
532 if ((csym = findSym (LabelTab,
534 tree->falseLabel->name)))
535 tree->falseLabel = csym;
537 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
538 tree->falseLabel->name);
543 /* if this is a label resolve it from the labelTab */
544 if (IS_AST_VALUE (tree) &&
545 tree->opval.val->sym &&
546 tree->opval.val->sym->islbl)
549 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
550 tree->opval.val->sym->name);
553 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
554 tree->opval.val->sym->name);
556 tree->opval.val->sym = csym;
558 goto resolveChildren;
561 /* do only for leafs */
562 if (IS_AST_VALUE (tree) &&
563 tree->opval.val->sym &&
564 !tree->opval.val->sym->implicit)
567 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
569 /* if found in the symbol table & they r not the same */
570 if (csym && tree->opval.val->sym != csym)
572 tree->opval.val->sym = csym;
573 tree->opval.val->type = csym->type;
574 tree->opval.val->etype = csym->etype;
577 /* if not found in the symbol table */
578 /* mark it as undefined assume it is */
579 /* an integer in data space */
580 if (!csym && !tree->opval.val->sym->implicit)
583 /* if this is a function name then */
584 /* mark it as returning an int */
587 tree->opval.val->sym->type = newLink (DECLARATOR);
588 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
589 tree->opval.val->sym->type->next =
590 tree->opval.val->sym->etype = newIntLink ();
591 tree->opval.val->etype = tree->opval.val->etype;
592 tree->opval.val->type = tree->opval.val->sym->type;
593 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
594 tree->opval.val->sym->name);
595 //tree->opval.val->sym->undefined = 1;
596 allocVariables (tree->opval.val->sym);
600 tree->opval.val->sym->undefined = 1;
601 tree->opval.val->type =
602 tree->opval.val->etype = newIntLink ();
603 tree->opval.val->sym->type =
604 tree->opval.val->sym->etype = newIntLink ();
610 resolveSymbols (tree->left);
611 resolveSymbols (tree->right);
616 /*-----------------------------------------------------------------*/
617 /* setAstLineno - walks a ast tree & sets the line number */
618 /*-----------------------------------------------------------------*/
619 int setAstLineno (ast * tree, int lineno)
624 tree->lineno = lineno;
625 setAstLineno (tree->left, lineno);
626 setAstLineno (tree->right, lineno);
630 /*-----------------------------------------------------------------*/
631 /* funcOfType :- function of type with name */
632 /*-----------------------------------------------------------------*/
634 funcOfType (char *name, sym_link * type, sym_link * argType,
638 /* create the symbol */
639 sym = newSymbol (name, 0);
641 /* setup return value */
642 sym->type = newLink (DECLARATOR);
643 DCL_TYPE (sym->type) = FUNCTION;
644 sym->type->next = copyLinkChain (type);
645 sym->etype = getSpec (sym->type);
646 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
648 /* if arguments required */
652 args = FUNC_ARGS(sym->type) = newValue ();
656 args->type = copyLinkChain (argType);
657 args->etype = getSpec (args->type);
658 SPEC_EXTR(args->etype)=1;
661 args = args->next = newValue ();
668 allocVariables (sym);
673 /*-----------------------------------------------------------------*/
674 /* funcOfTypeVarg :- function of type with name and argtype */
675 /*-----------------------------------------------------------------*/
677 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
682 /* create the symbol */
683 sym = newSymbol (name, 0);
685 /* setup return value */
686 sym->type = newLink (DECLARATOR);
687 DCL_TYPE (sym->type) = FUNCTION;
688 sym->type->next = typeFromStr(rtype);
689 sym->etype = getSpec (sym->type);
691 /* if arguments required */
694 args = FUNC_ARGS(sym->type) = newValue ();
696 for ( i = 0 ; i < nArgs ; i++ ) {
697 args->type = typeFromStr(atypes[i]);
698 args->etype = getSpec (args->type);
699 SPEC_EXTR(args->etype)=1;
700 if ((i + 1) == nArgs) break;
701 args = args->next = newValue ();
708 allocVariables (sym);
713 /*-----------------------------------------------------------------*/
714 /* reverseParms - will reverse a parameter tree */
715 /*-----------------------------------------------------------------*/
717 reverseParms (ast * ptree)
723 /* top down if we find a nonParm tree then quit */
724 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
726 /* The various functions expect the parameter tree to be right heavy. */
727 /* Rotate the tree to be left heavy so that after reversal it is */
728 /* right heavy again. */
729 while ((ttree = ptree->right) && ttree->type == EX_OP &&
730 ttree->opval.op == PARAM)
732 ptree->right = ttree->right;
733 ttree->right = ttree->left;
734 ttree->left = ptree->left;
740 ptree->left = ptree->right;
741 ptree->right = ttree;
743 reverseParms (ptree->left);
744 reverseParms (ptree->right);
750 /*-----------------------------------------------------------------*/
751 /* processParms - makes sure the parameters are okay and do some */
752 /* processing with them */
753 /*-----------------------------------------------------------------*/
755 processParms (ast *func,
758 int *parmNumber, /* unused, although updated */
761 RESULT_TYPE resultType;
764 /* if none of them exist */
765 if (!defParm && !*actParm)
770 if (getenv("DEBUG_SANITY"))
772 fprintf (stderr, "processParms: %s ", defParm->name);
774 /* make sure the type is complete and sane */
775 checkTypeSanity(defParm->etype, defParm->name);
778 if (IS_CODEPTR (func->ftype))
779 functype = func->ftype->next;
781 functype = func->ftype;
783 /* if the function is being called via a pointer & */
784 /* it has not been defined a reentrant then we cannot */
785 /* have parameters */
786 /* PIC16 port can... */
787 if (!TARGET_IS_PIC16)
789 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
791 werror (W_NONRENT_ARGS);
797 /* if defined parameters ended but actual parameters */
798 /* exist and this is not defined as a variable arg */
799 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
801 werror (E_TOO_MANY_PARMS);
805 /* if defined parameters present but no actual parameters */
806 if (defParm && !*actParm)
808 werror (E_TOO_FEW_PARMS);
812 /* if this is a PARAM node then match left & right */
813 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
815 (*actParm)->decorated = 1;
816 return (processParms (func, defParm,
817 &(*actParm)->left, parmNumber, FALSE) ||
818 processParms (func, defParm ? defParm->next : NULL,
819 &(*actParm)->right, parmNumber, rightmost));
821 else if (defParm) /* not vararg */
823 /* If we have found a value node by following only right-hand links,
824 * then we know that there are no more values after us.
826 * Therefore, if there are more defined parameters, the caller didn't
829 if (rightmost && defParm->next)
831 werror (E_TOO_FEW_PARMS);
836 /* decorate parameter */
837 resultType = defParm ? getResultTypeFromType (defParm->type) :
839 *actParm = decorateType (*actParm, resultType);
841 if (IS_VOID((*actParm)->ftype))
843 werror (E_VOID_VALUE_USED);
847 /* If this is a varargs function... */
848 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
853 if (IS_CAST_OP (*actParm)
854 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
856 /* Parameter was explicitly typecast; don't touch it. */
860 ftype = (*actParm)->ftype;
862 /* If it's a char, upcast to int. */
863 if (IS_INTEGRAL (ftype)
864 && (getSize (ftype) < (unsigned) INTSIZE))
866 newType = newAst_LINK(INTTYPE);
869 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
871 newType = newAst_LINK (copyLinkChain(ftype));
872 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
875 if (IS_AGGREGATE (ftype))
877 newType = newAst_LINK (copyLinkChain (ftype));
878 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
883 /* cast required; change this op to a cast. */
884 (*actParm)->decorated = 0;
885 *actParm = newNode (CAST, newType, *actParm);
886 (*actParm)->lineno = (*actParm)->right->lineno;
888 decorateType (*actParm, RESULT_TYPE_NONE);
893 /* if defined parameters ended but actual has not & */
895 if (!defParm && *actParm &&
896 (options.stackAuto || IFFUNC_ISREENT (functype)))
899 resolveSymbols (*actParm);
901 /* the parameter type must be at least castable */
902 if (compareType (defParm->type, (*actParm)->ftype) == 0)
904 werror (E_INCOMPAT_TYPES);
905 printFromToType ((*actParm)->ftype, defParm->type);
909 /* if the parameter is castable then add the cast */
910 if (compareType (defParm->type, (*actParm)->ftype) < 0)
914 resultType = getResultTypeFromType (defParm->etype);
915 pTree = resolveSymbols (copyAst (*actParm));
917 /* now change the current one to a cast */
918 (*actParm)->type = EX_OP;
919 (*actParm)->opval.op = CAST;
920 (*actParm)->left = newAst_LINK (defParm->type);
921 (*actParm)->right = pTree;
922 (*actParm)->decorated = 0; /* force typechecking */
923 decorateType (*actParm, resultType);
926 /* make a copy and change the regparm type to the defined parm */
927 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
928 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
929 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
934 /*-----------------------------------------------------------------*/
935 /* createIvalType - generates ival for basic types */
936 /*-----------------------------------------------------------------*/
938 createIvalType (ast * sym, sym_link * type, initList * ilist)
942 /* if initList is deep */
943 if (ilist->type == INIT_DEEP)
944 ilist = ilist->init.deep;
946 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
947 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
950 /*-----------------------------------------------------------------*/
951 /* createIvalStruct - generates initial value for structures */
952 /*-----------------------------------------------------------------*/
954 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
961 sflds = SPEC_STRUCT (type)->fields;
962 if (ilist->type != INIT_DEEP)
964 werror (E_INIT_STRUCT, "");
968 iloop = ilist->init.deep;
970 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
972 /* if we have come to end */
976 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
977 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
978 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
979 iloop, rast, rootValue)),
985 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
986 W_EXCESS_INITIALIZERS, "struct",
987 sym->opval.val->sym->name);
994 /*-----------------------------------------------------------------*/
995 /* createIvalArray - generates code for array initialization */
996 /*-----------------------------------------------------------------*/
998 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
1002 int lcnt = 0, size = 0;
1003 literalList *literalL;
1005 /* take care of the special case */
1006 /* array of characters can be init */
1008 if (IS_CHAR (type->next))
1009 if ((rast = createIvalCharPtr (sym,
1011 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
1014 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1016 /* not the special case */
1017 if (ilist->type != INIT_DEEP)
1019 werror (E_INIT_STRUCT, "");
1023 iloop = ilist->init.deep;
1024 lcnt = DCL_ELEM (type);
1026 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
1030 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
1032 rast = newNode(ARRAYINIT, aSym, NULL);
1033 rast->values.constlist = literalL;
1035 // Make sure size is set to length of initializer list.
1039 iloop = iloop->next;
1042 if (lcnt && size > lcnt)
1044 // Array size was specified, and we have more initializers than needed.
1045 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
1046 W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
1055 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
1056 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
1057 rast = createIval (aSym, type->next, iloop, rast, rootValue);
1058 iloop = (iloop ? iloop->next : NULL);
1064 /* no of elements given and we */
1065 /* have generated for all of them */
1068 // is this a better way? at least it won't crash
1069 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1070 werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name);
1077 /* if we have not been given a size */
1078 if (!DCL_ELEM (type))
1080 /* check, if it's a flexible array */
1081 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1082 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1084 DCL_ELEM (type) = size;
1087 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1091 /*-----------------------------------------------------------------*/
1092 /* createIvalCharPtr - generates initial values for char pointers */
1093 /*-----------------------------------------------------------------*/
1095 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1100 /* if this is a pointer & right is a literal array then */
1101 /* just assignment will do */
1102 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1103 SPEC_SCLS (iexpr->etype) == S_CODE)
1104 && IS_ARRAY (iexpr->ftype)))
1105 return newNode ('=', sym, iexpr);
1107 /* left side is an array so we have to assign each */
1109 if ((IS_LITERAL (iexpr->etype) ||
1110 SPEC_SCLS (iexpr->etype) == S_CODE)
1111 && IS_ARRAY (iexpr->ftype))
1113 /* for each character generate an assignment */
1114 /* to the array element */
1115 char *s = SPEC_CVAL (iexpr->etype).v_char;
1117 unsigned int symsize = getSize (type);
1119 size = getSize (iexpr->ftype);
1120 if (symsize && size>symsize)
1122 if (size>(symsize+1))
1124 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1126 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1132 for (i=0;i<size;i++)
1134 rast = newNode (NULLOP,
1138 newAst_VALUE (valueFromLit ((float) i))),
1139 newAst_VALUE (valueFromLit (*s))));
1143 // now WE don't need iexpr's symbol anymore
1144 freeStringSymbol(AST_SYMBOL(iexpr));
1146 /* if we have not been given a size */
1147 if (!DCL_ELEM (type))
1149 /* check, if it's a flexible array */
1150 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1151 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1153 DCL_ELEM (type) = size;
1156 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1162 /*-----------------------------------------------------------------*/
1163 /* createIvalPtr - generates initial value for pointers */
1164 /*-----------------------------------------------------------------*/
1166 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1172 if (ilist->type == INIT_DEEP)
1173 ilist = ilist->init.deep;
1175 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1177 /* if character pointer */
1178 if (IS_CHAR (type->next))
1179 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1182 return newNode ('=', sym, iexpr);
1185 /*-----------------------------------------------------------------*/
1186 /* createIval - generates code for initial value */
1187 /*-----------------------------------------------------------------*/
1189 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1196 /* if structure then */
1197 if (IS_STRUCT (type))
1198 rast = createIvalStruct (sym, type, ilist, rootValue);
1200 /* if this is a pointer */
1202 rast = createIvalPtr (sym, type, ilist, rootValue);
1204 /* if this is an array */
1205 if (IS_ARRAY (type))
1206 rast = createIvalArray (sym, type, ilist, rootValue);
1208 /* if type is SPECIFIER */
1210 rast = createIvalType (sym, type, ilist);
1213 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1215 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1218 /*-----------------------------------------------------------------*/
1219 /* initAggregates - initialises aggregate variables with initv */
1220 /*-----------------------------------------------------------------*/
1221 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1222 ast *newAst = newAst_VALUE (symbolVal (sym));
1223 return createIval (newAst, sym->type, ival, wid, newAst);
1226 /*-----------------------------------------------------------------*/
1227 /* gatherAutoInit - creates assignment expressions for initial */
1229 /*-----------------------------------------------------------------*/
1231 gatherAutoInit (symbol * autoChain)
1238 for (sym = autoChain; sym; sym = sym->next)
1241 /* resolve the symbols in the ival */
1243 resolveIvalSym (sym->ival, sym->type);
1246 /* if we are PIC16 port,
1247 * and this is a static,
1248 * and have initial value,
1249 * and not S_CODE, don't emit in gs segment,
1250 * but allow glue.c:pic16emitRegularMap to put symbol
1251 * in idata section */
1252 if(TARGET_IS_PIC16 &&
1253 IS_STATIC (sym->etype) && sym->ival
1254 && SPEC_SCLS(sym->etype) != S_CODE) {
1255 SPEC_SCLS (sym->etype) = S_DATA;
1260 /* if this is a static variable & has an */
1261 /* initial value the code needs to be lifted */
1262 /* here to the main portion since they can be */
1263 /* initialised only once at the start */
1264 if (IS_STATIC (sym->etype) && sym->ival &&
1265 SPEC_SCLS (sym->etype) != S_CODE)
1269 /* insert the symbol into the symbol table */
1270 /* with level = 0 & name = rname */
1271 newSym = copySymbol (sym);
1272 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1274 /* now lift the code to main */
1275 if (IS_AGGREGATE (sym->type)) {
1276 work = initAggregates (sym, sym->ival, NULL);
1278 if (getNelements(sym->type, sym->ival)>1) {
1279 werrorfl (sym->fileDef, sym->lineDef,
1280 W_EXCESS_INITIALIZERS, "scalar",
1283 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1284 list2expr (sym->ival));
1287 setAstLineno (work, sym->lineDef);
1291 staticAutos = newNode (NULLOP, staticAutos, work);
1298 /* if there is an initial value */
1299 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1301 initList *ilist=sym->ival;
1303 while (ilist->type == INIT_DEEP) {
1304 ilist = ilist->init.deep;
1307 /* update lineno for error msg */
1308 lineno = sym->lineDef;
1309 setAstLineno (ilist->init.node, sym->lineDef);
1311 if (IS_AGGREGATE (sym->type)) {
1312 work = initAggregates (sym, sym->ival, NULL);
1314 if (getNelements(sym->type, sym->ival)>1) {
1315 werrorfl (sym->fileDef, sym->lineDef,
1316 W_EXCESS_INITIALIZERS, "scalar",
1319 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1320 list2expr (sym->ival));
1324 setAstLineno (work, sym->lineDef);
1328 init = newNode (NULLOP, init, work);
1337 /*-----------------------------------------------------------------*/
1338 /* freeStringSymbol - delete a literal string if no more usage */
1339 /*-----------------------------------------------------------------*/
1340 void freeStringSymbol(symbol *sym) {
1341 /* make sure this is a literal string */
1342 assert (sym->isstrlit);
1343 if (--sym->isstrlit == 0) { // lower the usage count
1344 memmap *segment=SPEC_OCLS(sym->etype);
1346 deleteSetItem(&segment->syms, sym);
1351 /*-----------------------------------------------------------------*/
1352 /* stringToSymbol - creates a symbol from a literal string */
1353 /*-----------------------------------------------------------------*/
1355 stringToSymbol (value * val)
1357 char name[SDCC_NAME_MAX + 1];
1358 static int charLbl = 0;
1363 // have we heard this before?
1364 for (sp=statsg->syms; sp; sp=sp->next) {
1366 size = getSize (sym->type);
1367 if (sym->isstrlit && size == getSize (val->type) &&
1368 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1369 // yes, this is old news. Don't publish it again.
1370 sym->isstrlit++; // but raise the usage count
1371 return symbolVal(sym);
1375 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1376 sym = newSymbol (name, 0); /* make it @ level 0 */
1377 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1379 /* copy the type from the value passed */
1380 sym->type = copyLinkChain (val->type);
1381 sym->etype = getSpec (sym->type);
1382 /* change to storage class & output class */
1383 SPEC_SCLS (sym->etype) = S_CODE;
1384 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1385 SPEC_STAT (sym->etype) = 1;
1386 /* make the level & block = 0 */
1387 sym->block = sym->level = 0;
1389 /* create an ival */
1390 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1395 allocVariables (sym);
1398 return symbolVal (sym);
1402 /*-----------------------------------------------------------------*/
1403 /* processBlockVars - will go thru the ast looking for block if */
1404 /* a block is found then will allocate the syms */
1405 /* will also gather the auto inits present */
1406 /*-----------------------------------------------------------------*/
1408 processBlockVars (ast * tree, int *stack, int action)
1413 /* if this is a block */
1414 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1418 if (action == ALLOCATE)
1420 *stack += allocVariables (tree->values.sym);
1421 autoInit = gatherAutoInit (tree->values.sym);
1423 /* if there are auto inits then do them */
1425 tree->left = newNode (NULLOP, autoInit, tree->left);
1427 else /* action is deallocate */
1428 deallocLocal (tree->values.sym);
1431 processBlockVars (tree->left, stack, action);
1432 processBlockVars (tree->right, stack, action);
1437 /*-------------------------------------------------------------*/
1438 /* constExprTree - returns TRUE if this tree is a constant */
1440 /*-------------------------------------------------------------*/
1441 bool constExprTree (ast *cexpr) {
1447 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1449 switch (cexpr->type)
1452 if (IS_AST_LIT_VALUE(cexpr)) {
1453 // this is a literal
1456 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1457 // a function's address will never change
1460 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1461 // an array's address will never change
1464 if (IS_AST_SYM_VALUE(cexpr) &&
1465 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1466 // a symbol in code space will never change
1467 // This is only for the 'char *s="hallo"' case and will have to leave
1468 //printf(" code space symbol");
1473 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1474 "unexpected link in expression tree\n");
1477 if (cexpr->opval.op==ARRAYINIT) {
1478 // this is a list of literals
1481 if (cexpr->opval.op=='=') {
1482 return constExprTree(cexpr->right);
1484 if (cexpr->opval.op==CAST) {
1485 // cast ignored, maybe we should throw a warning here?
1486 return constExprTree(cexpr->right);
1488 if (cexpr->opval.op=='&') {
1491 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1494 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1499 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1504 /*-----------------------------------------------------------------*/
1505 /* constExprValue - returns the value of a constant expression */
1506 /* or NULL if it is not a constant expression */
1507 /*-----------------------------------------------------------------*/
1509 constExprValue (ast * cexpr, int check)
1511 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1513 /* if this is not a constant then */
1514 if (!IS_LITERAL (cexpr->ftype))
1516 /* then check if this is a literal array
1518 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1519 SPEC_CVAL (cexpr->etype).v_char &&
1520 IS_ARRAY (cexpr->ftype))
1522 value *val = valFromType (cexpr->ftype);
1523 SPEC_SCLS (val->etype) = S_LITERAL;
1524 val->sym = cexpr->opval.val->sym;
1525 val->sym->type = copyLinkChain (cexpr->ftype);
1526 val->sym->etype = getSpec (val->sym->type);
1527 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1531 /* if we are casting a literal value then */
1532 if (IS_AST_OP (cexpr) &&
1533 cexpr->opval.op == CAST &&
1534 IS_LITERAL (cexpr->right->ftype))
1536 return valCastLiteral (cexpr->ftype,
1537 floatFromVal (cexpr->right->opval.val));
1540 if (IS_AST_VALUE (cexpr))
1542 return cexpr->opval.val;
1546 werror (E_CONST_EXPECTED, "found expression");
1551 /* return the value */
1552 if (IS_AST_VALUE (cexpr))
1554 return cexpr->opval.val;
1559 /*-----------------------------------------------------------------*/
1560 /* isLabelInAst - will return true if a given label is found */
1561 /*-----------------------------------------------------------------*/
1563 isLabelInAst (symbol * label, ast * tree)
1565 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1568 if (IS_AST_OP (tree) &&
1569 tree->opval.op == LABEL &&
1570 isSymbolEqual (AST_SYMBOL (tree->left), label))
1573 return isLabelInAst (label, tree->right) &&
1574 isLabelInAst (label, tree->left);
1577 /*-----------------------------------------------------------------*/
1578 /* isLoopCountable - return true if the loop count can be determi- */
1579 /* -ned at compile time . */
1580 /*-----------------------------------------------------------------*/
1582 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1583 symbol ** sym, ast ** init, ast ** end)
1586 /* the loop is considered countable if the following
1587 conditions are true :-
1589 a) initExpr :- <sym> = <const>
1590 b) condExpr :- <sym> < <const1>
1591 c) loopExpr :- <sym> ++
1594 /* first check the initExpr */
1595 if (IS_AST_OP (initExpr) &&
1596 initExpr->opval.op == '=' && /* is assignment */
1597 IS_AST_SYM_VALUE (initExpr->left))
1598 { /* left is a symbol */
1600 *sym = AST_SYMBOL (initExpr->left);
1601 *init = initExpr->right;
1606 /* don't reverse loop with volatile counter */
1607 if (IS_VOLATILE ((*sym)->type))
1610 /* for now the symbol has to be of
1612 if (!IS_INTEGRAL ((*sym)->type))
1615 /* now check condExpr */
1616 if (IS_AST_OP (condExpr))
1619 switch (condExpr->opval.op)
1622 if (IS_AST_SYM_VALUE (condExpr->left) &&
1623 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1624 IS_AST_LIT_VALUE (condExpr->right))
1626 *end = condExpr->right;
1632 if (IS_AST_OP (condExpr->left) &&
1633 condExpr->left->opval.op == '>' &&
1634 IS_AST_LIT_VALUE (condExpr->left->right) &&
1635 IS_AST_SYM_VALUE (condExpr->left->left) &&
1636 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1639 *end = newNode ('+', condExpr->left->right,
1640 newAst_VALUE (constVal ("1")));
1653 /* check loop expression is of the form <sym>++ */
1654 if (!IS_AST_OP (loopExpr))
1657 /* check if <sym> ++ */
1658 if (loopExpr->opval.op == INC_OP)
1664 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1665 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1672 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1673 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1681 if (loopExpr->opval.op == ADD_ASSIGN)
1684 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1685 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1686 IS_AST_LIT_VALUE (loopExpr->right) &&
1687 AST_ULONG_VALUE (loopExpr->right) != 1)
1695 /*-----------------------------------------------------------------*/
1696 /* astHasVolatile - returns true if ast contains any volatile */
1697 /*-----------------------------------------------------------------*/
1699 astHasVolatile (ast * tree)
1704 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1707 if (IS_AST_OP (tree))
1708 return astHasVolatile (tree->left) ||
1709 astHasVolatile (tree->right);
1714 /*-----------------------------------------------------------------*/
1715 /* astHasPointer - return true if the ast contains any ptr variable */
1716 /*-----------------------------------------------------------------*/
1718 astHasPointer (ast * tree)
1723 if (IS_AST_LINK (tree))
1726 /* if we hit an array expression then check
1727 only the left side */
1728 if (IS_AST_OP (tree) && tree->opval.op == '[')
1729 return astHasPointer (tree->left);
1731 if (IS_AST_VALUE (tree))
1732 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1734 return astHasPointer (tree->left) ||
1735 astHasPointer (tree->right);
1739 /*-----------------------------------------------------------------*/
1740 /* astHasSymbol - return true if the ast has the given symbol */
1741 /*-----------------------------------------------------------------*/
1743 astHasSymbol (ast * tree, symbol * sym)
1745 if (!tree || IS_AST_LINK (tree))
1748 if (IS_AST_VALUE (tree))
1750 if (IS_AST_SYM_VALUE (tree))
1751 return isSymbolEqual (AST_SYMBOL (tree), sym);
1756 return astHasSymbol (tree->left, sym) ||
1757 astHasSymbol (tree->right, sym);
1760 /*-----------------------------------------------------------------*/
1761 /* astHasDeref - return true if the ast has an indirect access */
1762 /*-----------------------------------------------------------------*/
1764 astHasDeref (ast * tree)
1766 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1769 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1771 return astHasDeref (tree->left) || astHasDeref (tree->right);
1774 /*-----------------------------------------------------------------*/
1775 /* isConformingBody - the loop body has to conform to a set of rules */
1776 /* for the loop to be considered reversible read on for rules */
1777 /*-----------------------------------------------------------------*/
1779 isConformingBody (ast * pbody, symbol * sym, ast * body)
1782 /* we are going to do a pre-order traversal of the
1783 tree && check for the following conditions. (essentially
1784 a set of very shallow tests )
1785 a) the sym passed does not participate in
1786 any arithmetic operation
1787 b) There are no function calls
1788 c) all jumps are within the body
1789 d) address of loop control variable not taken
1790 e) if an assignment has a pointer on the
1791 left hand side make sure right does not have
1792 loop control variable */
1794 /* if we reach the end or a leaf then true */
1795 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1798 /* if anything else is "volatile" */
1799 if (IS_VOLATILE (TETYPE (pbody)))
1802 /* we will walk the body in a pre-order traversal for
1804 switch (pbody->opval.op)
1806 /*------------------------------------------------------------------*/
1808 // if the loopvar is used as an index
1809 /* array op is commutative -- must check both left & right */
1810 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1813 return isConformingBody (pbody->right, sym, body)
1814 && isConformingBody (pbody->left, sym, body);
1816 /*------------------------------------------------------------------*/
1821 /*------------------------------------------------------------------*/
1825 /* sure we are not sym is not modified */
1827 IS_AST_SYM_VALUE (pbody->left) &&
1828 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1832 IS_AST_SYM_VALUE (pbody->right) &&
1833 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1838 /*------------------------------------------------------------------*/
1840 case '*': /* can be unary : if right is null then unary operation */
1845 /* if right is NULL then unary operation */
1846 /*------------------------------------------------------------------*/
1847 /*----------------------------*/
1849 /*----------------------------*/
1852 if (IS_AST_SYM_VALUE (pbody->left) &&
1853 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1856 return isConformingBody (pbody->left, sym, body);
1860 if (astHasSymbol (pbody->left, sym) ||
1861 astHasSymbol (pbody->right, sym))
1866 /*------------------------------------------------------------------*/
1877 if (IS_AST_SYM_VALUE (pbody->left) &&
1878 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1881 if (IS_AST_SYM_VALUE (pbody->right) &&
1882 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1885 return isConformingBody (pbody->left, sym, body) &&
1886 isConformingBody (pbody->right, sym, body);
1894 if (IS_AST_SYM_VALUE (pbody->left) &&
1895 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1897 return isConformingBody (pbody->left, sym, body);
1899 /*------------------------------------------------------------------*/
1911 case SIZEOF: /* evaluate wihout code generation */
1913 if (IS_AST_SYM_VALUE (pbody->left) &&
1914 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1917 if (IS_AST_SYM_VALUE (pbody->right) &&
1918 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1921 return isConformingBody (pbody->left, sym, body) &&
1922 isConformingBody (pbody->right, sym, body);
1924 /*------------------------------------------------------------------*/
1927 /* if left has a pointer & right has loop
1928 control variable then we cannot */
1929 if (astHasPointer (pbody->left) &&
1930 astHasSymbol (pbody->right, sym))
1932 if (astHasVolatile (pbody->left))
1935 if (IS_AST_SYM_VALUE (pbody->left)) {
1936 // if the loopvar has an assignment
1937 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1939 // if the loopvar is used in another (maybe conditional) block
1940 if (astHasSymbol (pbody->right, sym) &&
1941 (pbody->level >= body->level)) {
1946 if (astHasVolatile (pbody->left))
1949 if (astHasDeref(pbody->right)) return FALSE;
1951 return isConformingBody (pbody->left, sym, body) &&
1952 isConformingBody (pbody->right, sym, body);
1963 assert ("Parser should not have generated this\n");
1965 /*------------------------------------------------------------------*/
1966 /*----------------------------*/
1967 /* comma operator */
1968 /*----------------------------*/
1970 return isConformingBody (pbody->left, sym, body) &&
1971 isConformingBody (pbody->right, sym, body);
1973 /*------------------------------------------------------------------*/
1974 /*----------------------------*/
1976 /*----------------------------*/
1978 /* if local & not passed as paramater then ok */
1979 if (sym->level && !astHasSymbol(pbody->right,sym))
1983 /*------------------------------------------------------------------*/
1984 /*----------------------------*/
1985 /* return statement */
1986 /*----------------------------*/
1991 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1996 if (astHasSymbol (pbody->left, sym))
2003 return isConformingBody (pbody->left, sym, body) &&
2004 isConformingBody (pbody->right, sym, body);
2010 /*-----------------------------------------------------------------*/
2011 /* isLoopReversible - takes a for loop as input && returns true */
2012 /* if the for loop is reversible. If yes will set the value of */
2013 /* the loop control var & init value & termination value */
2014 /*-----------------------------------------------------------------*/
2016 isLoopReversible (ast * loop, symbol ** loopCntrl,
2017 ast ** init, ast ** end)
2019 /* if option says don't do it then don't */
2020 if (optimize.noLoopReverse)
2022 /* there are several tests to determine this */
2024 /* for loop has to be of the form
2025 for ( <sym> = <const1> ;
2026 [<sym> < <const2>] ;
2027 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
2029 if (!isLoopCountable (AST_FOR (loop, initExpr),
2030 AST_FOR (loop, condExpr),
2031 AST_FOR (loop, loopExpr),
2032 loopCntrl, init, end))
2035 /* now do some serious checking on the body of the loop
2038 return isConformingBody (loop->left, *loopCntrl, loop->left);
2042 /*-----------------------------------------------------------------*/
2043 /* replLoopSym - replace the loop sym by loop sym -1 */
2044 /*-----------------------------------------------------------------*/
2046 replLoopSym (ast * body, symbol * sym)
2049 if (!body || IS_AST_LINK (body))
2052 if (IS_AST_SYM_VALUE (body))
2055 if (isSymbolEqual (AST_SYMBOL (body), sym))
2059 body->opval.op = '-';
2060 body->left = newAst_VALUE (symbolVal (sym));
2061 body->right = newAst_VALUE (constVal ("1"));
2069 replLoopSym (body->left, sym);
2070 replLoopSym (body->right, sym);
2074 /*-----------------------------------------------------------------*/
2075 /* reverseLoop - do the actual loop reversal */
2076 /*-----------------------------------------------------------------*/
2078 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
2082 /* create the following tree
2087 if (sym) goto for_continue ;
2090 /* put it together piece by piece */
2091 rloop = newNode (NULLOP,
2092 createIf (newAst_VALUE (symbolVal (sym)),
2094 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2097 newAst_VALUE (symbolVal (sym)),
2100 replLoopSym (loop->left, sym);
2101 setAstLineno (rloop, init->lineno);
2103 rloop = newNode (NULLOP,
2105 newAst_VALUE (symbolVal (sym)),
2106 newNode ('-', end, init)),
2107 createLabel (AST_FOR (loop, continueLabel),
2111 newNode (SUB_ASSIGN,
2112 newAst_VALUE (symbolVal (sym)),
2113 newAst_VALUE (constVal ("1"))),
2116 rloop->lineno=init->lineno;
2117 return decorateType (rloop, RESULT_TYPE_NONE);
2121 /*-----------------------------------------------------------------*/
2122 /* searchLitOp - search tree (*ops only) for an ast with literal */
2123 /*-----------------------------------------------------------------*/
2125 searchLitOp (ast *tree, ast **parent, const char *ops)
2129 if (tree && optimize.global_cse)
2131 /* is there a literal operand? */
2133 IS_AST_OP(tree->right) &&
2134 tree->right->right &&
2135 (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1]))
2137 if (IS_LITERAL (RTYPE (tree->right)) !=
2138 IS_LITERAL (LTYPE (tree->right)))
2140 tree->right->decorated = 0;
2141 tree->decorated = 0;
2145 ret = searchLitOp (tree->right, parent, ops);
2150 IS_AST_OP(tree->left) &&
2151 tree->left->right &&
2152 (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1]))
2154 if (IS_LITERAL (RTYPE (tree->left)) !=
2155 IS_LITERAL (LTYPE (tree->left)))
2157 tree->left->decorated = 0;
2158 tree->decorated = 0;
2162 ret = searchLitOp (tree->left, parent, ops);
2170 /*-----------------------------------------------------------------*/
2171 /* getResultFromType */
2172 /*-----------------------------------------------------------------*/
2174 getResultTypeFromType (sym_link *type)
2176 /* type = getSpec (type); */
2178 return RESULT_TYPE_BIT;
2179 if (IS_BITFIELD (type))
2181 int blen = SPEC_BLEN (type);
2184 return RESULT_TYPE_BIT;
2186 return RESULT_TYPE_CHAR;
2187 return RESULT_TYPE_INT;
2190 return RESULT_TYPE_CHAR;
2191 if (IS_INT (type) && !IS_LONG (type))
2192 return RESULT_TYPE_INT;
2193 return RESULT_TYPE_OTHER;
2196 /*-----------------------------------------------------------------*/
2197 /* addCast - adds casts to a type specified by RESULT_TYPE */
2198 /*-----------------------------------------------------------------*/
2200 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2203 bool upCasted = FALSE;
2207 case RESULT_TYPE_NONE:
2208 /* if thing smaller than int must be promoted to int */
2210 getSize (tree->etype) >= INTSIZE)
2211 /* promotion not necessary or already an int */
2213 /* char and bits: promote to int */
2214 newLink = newIntLink();
2217 case RESULT_TYPE_BIT:
2219 /* already an int */
2220 bitsForType (tree->etype) >= 16 ||
2221 /* bit to bit operation: don't promote, the code generators
2222 hopefully know everything about promotion rules */
2223 bitsForType (tree->etype) == 1)
2225 newLink = newIntLink();
2228 case RESULT_TYPE_CHAR:
2229 if (IS_CHAR (tree->etype) ||
2230 IS_FLOAT(tree->etype) ||
2231 IS_FIXED(tree->etype))
2233 newLink = newCharLink();
2235 case RESULT_TYPE_INT:
2237 if (getSize (tree->etype) > INTSIZE)
2239 /* warn ("Loosing significant digits"); */
2243 /* char: promote to int */
2245 getSize (tree->etype) >= INTSIZE)
2247 newLink = newIntLink();
2250 case RESULT_TYPE_IFX:
2251 case RESULT_TYPE_OTHER:
2253 /* return type is ifx, long, float: promote char to int */
2254 getSize (tree->etype) >= INTSIZE)
2256 newLink = newIntLink();
2262 tree->decorated = 0;
2263 tree = newNode (CAST, newAst_LINK (newLink), tree);
2264 tree->lineno = tree->right->lineno;
2265 /* keep unsigned type during cast to smaller type,
2266 but not when promoting from char to int */
2268 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2269 return decorateType (tree, resultType);
2272 /*-----------------------------------------------------------------*/
2273 /* resultTypePropagate - decides if resultType can be propagated */
2274 /*-----------------------------------------------------------------*/
2276 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2278 switch (tree->opval.op)
2295 if ((IS_AST_VALUE (tree->left) && !IS_INTEGRAL (tree->left->opval.val->etype)) ||
2296 (IS_AST_VALUE (tree->right) && !IS_INTEGRAL (tree->right->opval.val->etype)))
2297 return RESULT_TYPE_NONE;
2302 return RESULT_TYPE_NONE;
2306 return RESULT_TYPE_IFX;
2308 return RESULT_TYPE_NONE;
2312 /*-----------------------------------------------------------------*/
2313 /* getLeftResultType - gets type from left branch for propagation */
2314 /*-----------------------------------------------------------------*/
2316 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2318 switch (tree->opval.op)
2322 if (IS_PTR (LTYPE (tree)))
2323 return RESULT_TYPE_NONE;
2325 return getResultTypeFromType (LETYPE (tree));
2327 if (IS_PTR (currFunc->type->next))
2328 return RESULT_TYPE_NONE;
2330 return getResultTypeFromType (currFunc->type->next);
2332 if (!IS_ARRAY (LTYPE (tree)))
2334 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2335 return RESULT_TYPE_CHAR;
2342 /*------------------------------------------------------------------*/
2343 /* gatherImplicitVariables: assigns correct type information to */
2344 /* symbols and values created by replaceAstWithTemporary */
2345 /* and adds the symbols to the declarations list of the */
2346 /* innermost block that contains them */
2347 /*------------------------------------------------------------------*/
2349 gatherImplicitVariables (ast * tree, ast * block)
2354 if (tree->type == EX_OP && tree->opval.op == BLOCK)
2356 /* keep track of containing scope */
2359 if (tree->type == EX_OP && tree->opval.op == '=' &&
2360 tree->left->type == EX_VALUE && tree->left->opval.val->sym)
2362 symbol *assignee = tree->left->opval.val->sym;
2364 /* special case for assignment to compiler-generated temporary variable:
2365 compute type of RHS, and set the symbol's type to match */
2366 if (assignee->type == NULL && assignee->infertype) {
2367 ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
2369 if (dtr != tree->right)
2372 assignee->type = copyLinkChain(TTYPE(dtr));
2373 assignee->etype = getSpec(assignee->type);
2374 SPEC_SCLS (assignee->etype) = S_AUTO;
2375 SPEC_OCLS (assignee->etype) = NULL;
2376 SPEC_EXTR (assignee->etype) = 0;
2377 SPEC_STAT (assignee->etype) = 0;
2378 SPEC_VOLATILE (assignee->etype) = 0;
2379 SPEC_ABSA (assignee->etype) = 0;
2381 wassertl(block != NULL, "implicit variable not contained in block");
2382 wassert(assignee->next == NULL);
2383 if (block != NULL) {
2384 symbol **decl = &(block->values.sym);
2387 wassert(*decl != assignee); /* should not already be in list */
2388 decl = &( (*decl)->next );
2395 if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) &&
2396 tree->opval.val->type == NULL &&
2397 tree->opval.val->sym &&
2398 tree->opval.val->sym->infertype)
2400 /* fixup type of value for compiler-inferred temporary var */
2401 tree->opval.val->type = tree->opval.val->sym->type;
2402 tree->opval.val->etype = tree->opval.val->sym->etype;
2405 gatherImplicitVariables(tree->left, block);
2406 gatherImplicitVariables(tree->right, block);
2409 /*--------------------------------------------------------------------*/
2410 /* decorateType - compute type for this tree, also does type checking.*/
2411 /* This is done bottom up, since type has to flow upwards. */
2412 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2413 /* result is a char and the operand(s) are int's. */
2414 /* It also does constant folding, and parameter checking. */
2415 /*--------------------------------------------------------------------*/
2417 decorateType (ast * tree, RESULT_TYPE resultType)
2421 RESULT_TYPE resultTypeProp;
2426 /* if already has type then do nothing */
2427 if (tree->decorated)
2430 tree->decorated = 1;
2433 /* print the line */
2434 /* if not block & function */
2435 if (tree->type == EX_OP &&
2436 (tree->opval.op != FUNCTION &&
2437 tree->opval.op != BLOCK &&
2438 tree->opval.op != NULLOP))
2440 filename = tree->filename;
2441 lineno = tree->lineno;
2445 /* if any child is an error | this one is an error do nothing */
2446 if (tree->isError ||
2447 (tree->left && tree->left->isError) ||
2448 (tree->right && tree->right->isError))
2451 /*------------------------------------------------------------------*/
2452 /*----------------------------*/
2453 /* leaf has been reached */
2454 /*----------------------------*/
2455 lineno = tree->lineno;
2456 /* if this is of type value */
2457 /* just get the type */
2458 if (tree->type == EX_VALUE)
2461 if (IS_LITERAL (tree->opval.val->etype))
2464 /* if this is a character array then declare it */
2465 if (IS_ARRAY (tree->opval.val->type))
2466 tree->opval.val = stringToSymbol (tree->opval.val);
2468 /* otherwise just copy the type information */
2469 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2473 if (tree->opval.val->sym)
2475 /* if the undefined flag is set then give error message */
2476 if (tree->opval.val->sym->undefined)
2478 werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name);
2480 TTYPE (tree) = TETYPE (tree) =
2481 tree->opval.val->type = tree->opval.val->sym->type =
2482 tree->opval.val->etype = tree->opval.val->sym->etype =
2483 copyLinkChain (INTTYPE);
2485 else if (tree->opval.val->sym->implicit)
2487 /* if implicit i.e. struct/union member then no type */
2488 TTYPE (tree) = TETYPE (tree) = NULL;
2492 /* copy the type from the value into the ast */
2493 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2495 /* and mark the symbol as referenced */
2496 tree->opval.val->sym->isref = 1;
2500 wassert(0); /* unreached: all values are literals or symbols */
2505 /* if type link for the case of cast */
2506 if (tree->type == EX_LINK)
2508 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2516 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2518 if (tree->left && tree->left->type == EX_OPERAND
2519 && (tree->left->opval.op == INC_OP
2520 || tree->left->opval.op == DEC_OP)
2521 && tree->left->left)
2523 tree->left->right = tree->left->left;
2524 tree->left->left = NULL;
2526 if (tree->right && tree->right->type == EX_OPERAND
2527 && (tree->right->opval.op == INC_OP
2528 || tree->right->opval.op == DEC_OP)
2529 && tree->right->left)
2531 tree->right->right = tree->right->left;
2532 tree->right->left = NULL;
2537 /* Before decorating the left branch we've to decide in dependence
2538 upon tree->opval.op, if resultType can be propagated */
2539 resultTypeProp = resultTypePropagate (tree, resultType);
2541 if ((tree->opval.op == '?') && (resultTypeProp != RESULT_TYPE_BIT))
2542 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2544 dtl = decorateType (tree->left, resultTypeProp);
2546 /* if an array node, we may need to swap branches */
2547 if (tree->opval.op == '[')
2549 /* determine which is the array & which the index */
2550 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2551 IS_INTEGRAL (LTYPE (tree)))
2553 ast *tempTree = tree->left;
2554 tree->left = tree->right;
2555 tree->right = tempTree;
2559 /* After decorating the left branch there's type information available
2560 in tree->left->?type. If the op is e.g. '=' we extract the type
2561 information from there and propagate it to the right branch. */
2562 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2564 switch (tree->opval.op)
2567 /* delay right side for '?' operator since conditional macro
2568 expansions might rely on this */
2572 /* decorate right side for CALL (parameter list) in processParms();
2573 there is resultType available */
2577 /* don't allocate string if it is a sizeof argument */
2579 dtr = decorateType (tree->right, resultTypeProp);
2583 dtr = decorateType (tree->right, resultTypeProp);
2587 /* this is to take care of situations
2588 when the tree gets rewritten */
2589 if (dtl != tree->left)
2591 if (dtr != tree->right)
2593 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2597 /* depending on type of operator do */
2599 switch (tree->opval.op)
2601 /*------------------------------------------------------------------*/
2602 /*----------------------------*/
2604 /*----------------------------*/
2607 /* first check if this is a array or a pointer */
2608 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2610 werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
2611 goto errorTreeReturn;
2614 /* check if the type of the idx */
2615 if (!IS_INTEGRAL (RTYPE (tree)))
2617 werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
2618 goto errorTreeReturn;
2621 /* if the left is an rvalue then error */
2624 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
2625 goto errorTreeReturn;
2628 if (IS_LITERAL (RTYPE (tree)))
2630 int arrayIndex = (int) ulFromVal (valFromType (RETYPE (tree)));
2631 int arraySize = DCL_ELEM (LTYPE (tree));
2632 if (arraySize && arrayIndex >= arraySize)
2634 werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2639 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2640 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2643 /*------------------------------------------------------------------*/
2644 /*----------------------------*/
2646 /*----------------------------*/
2648 /* if this is not a structure */
2649 if (!IS_STRUCT (LTYPE (tree)))
2651 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
2652 goto errorTreeReturn;
2654 TTYPE (tree) = structElemType (LTYPE (tree),
2655 (tree->right->type == EX_VALUE ?
2656 tree->right->opval.val : NULL));
2657 TETYPE (tree) = getSpec (TTYPE (tree));
2660 /*------------------------------------------------------------------*/
2661 /*----------------------------*/
2662 /* struct/union pointer */
2663 /*----------------------------*/
2665 /* if not pointer to a structure */
2666 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2668 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
2669 goto errorTreeReturn;
2672 if (!IS_STRUCT (LTYPE (tree)->next))
2674 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
2675 goto errorTreeReturn;
2678 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2679 (tree->right->type == EX_VALUE ?
2680 tree->right->opval.val : NULL));
2681 TETYPE (tree) = getSpec (TTYPE (tree));
2683 /* adjust the storage class */
2684 switch (DCL_TYPE(tree->left->ftype)) {
2686 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2689 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2692 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2695 SPEC_SCLS (TETYPE (tree)) = 0;
2698 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2701 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2704 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2707 SPEC_SCLS (TETYPE (tree)) = 0;
2714 /* This breaks with extern declarations, bitfields, and perhaps other */
2715 /* cases (gcse). Let's leave this optimization disabled for now and */
2716 /* ponder if there's a safe way to do this. -- EEP */
2718 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2719 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2721 /* If defined struct type at addr var
2722 then rewrite (&struct var)->member
2724 and define membertype at (addr+offsetof(struct var,member)) temp
2727 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2728 AST_SYMBOL(tree->right));
2730 sym = newSymbol(genSymName (0), 0);
2731 sym->type = TTYPE (tree);
2732 sym->etype = getSpec(sym->type);
2733 sym->lineDef = tree->lineno;
2736 SPEC_STAT (sym->etype) = 1;
2737 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2739 SPEC_ABSA(sym->etype) = 1;
2740 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2743 AST_VALUE (tree) = symbolVal(sym);
2746 tree->type = EX_VALUE;
2754 /*------------------------------------------------------------------*/
2755 /*----------------------------*/
2756 /* ++/-- operation */
2757 /*----------------------------*/
2761 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2762 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2763 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2764 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2773 /*------------------------------------------------------------------*/
2774 /*----------------------------*/
2776 /*----------------------------*/
2777 case '&': /* can be unary */
2778 /* if right is NULL then unary operation */
2779 if (tree->right) /* not an unary operation */
2782 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2784 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2785 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2786 printTypeChain (LTYPE (tree), stderr);
2787 fprintf (stderr, ",");
2788 printTypeChain (RTYPE (tree), stderr);
2789 fprintf (stderr, "\n");
2790 goto errorTreeReturn;
2793 /* if they are both literal */
2794 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2796 tree->type = EX_VALUE;
2797 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2798 valFromType (RETYPE (tree)), '&');
2800 tree->right = tree->left = NULL;
2801 TETYPE (tree) = tree->opval.val->etype;
2802 TTYPE (tree) = tree->opval.val->type;
2806 /* see if this is a GETHBIT operation if yes
2809 ast *otree = optimizeGetHbit (tree, resultType);
2812 return decorateType (otree, RESULT_TYPE_NONE);
2815 /* see if this is a GETABIT operation if yes
2818 ast *otree = optimizeGetAbit (tree, resultType);
2821 return decorateType (otree, RESULT_TYPE_NONE);
2824 /* see if this is a GETBYTE operation if yes
2827 ast *otree = optimizeGetByte (tree, resultType);
2830 return decorateType (otree, RESULT_TYPE_NONE);
2833 /* see if this is a GETWORD operation if yes
2836 ast *otree = optimizeGetWord (tree, resultType);
2839 return decorateType (otree, RESULT_TYPE_NONE);
2842 /* if left is a literal exchange left & right */
2843 if (IS_LITERAL (LTYPE (tree)))
2845 ast *tTree = tree->left;
2846 tree->left = tree->right;
2847 tree->right = tTree;
2850 /* if right is a literal and */
2851 /* we can find a 2nd literal in an and-tree then */
2852 /* rearrange the tree */
2853 if (IS_LITERAL (RTYPE (tree)))
2856 ast *litTree = searchLitOp (tree, &parent, "&");
2860 ast *tTree = litTree->left;
2861 litTree->left = tree->right;
2862 tree->right = tTree;
2863 /* both operands in litTree are literal now */
2864 decorateType (parent, resultType);
2868 LRVAL (tree) = RRVAL (tree) = 1;
2870 TTYPE (tree) = computeType (LTYPE (tree),
2874 TETYPE (tree) = getSpec (TTYPE (tree));
2879 /*------------------------------------------------------------------*/
2880 /*----------------------------*/
2882 /*----------------------------*/
2883 p = newLink (DECLARATOR);
2884 /* if bit field then error */
2885 if (IS_BITVAR (tree->left->etype))
2887 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
2888 goto errorTreeReturn;
2891 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2893 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
2894 goto errorTreeReturn;
2897 if (IS_FUNC (LTYPE (tree)))
2899 // this ought to be ignored
2900 return (tree->left);
2903 if (IS_LITERAL(LTYPE(tree)))
2905 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
2906 goto errorTreeReturn;
2911 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
2912 goto errorTreeReturn;
2915 DCL_TYPE (p) = POINTER;
2916 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2917 DCL_TYPE (p) = CPOINTER;
2918 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2919 DCL_TYPE (p) = FPOINTER;
2920 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2921 DCL_TYPE (p) = PPOINTER;
2922 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2923 DCL_TYPE (p) = IPOINTER;
2924 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2925 DCL_TYPE (p) = EEPPOINTER;
2926 else if (SPEC_OCLS(tree->left->etype))
2927 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2929 DCL_TYPE (p) = POINTER;
2931 if (IS_AST_SYM_VALUE (tree->left))
2933 AST_SYMBOL (tree->left)->addrtaken = 1;
2934 AST_SYMBOL (tree->left)->allocreq = 1;
2937 p->next = LTYPE (tree);
2939 TETYPE (tree) = getSpec (TTYPE (tree));
2944 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2945 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2947 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2948 AST_SYMBOL(tree->left->right));
2949 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2950 valueFromLit(element->offset));
2953 tree->type = EX_VALUE;
2954 tree->values.literalFromCast = 1;
2960 /*------------------------------------------------------------------*/
2961 /*----------------------------*/
2963 /*----------------------------*/
2965 /* if the rewrite succeeds then don't go any further */
2967 ast *wtree = optimizeRRCRLC (tree);
2969 return decorateType (wtree, RESULT_TYPE_NONE);
2971 wtree = optimizeSWAP (tree);
2973 return decorateType (wtree, RESULT_TYPE_NONE);
2976 /* if left is a literal exchange left & right */
2977 if (IS_LITERAL (LTYPE (tree)))
2979 ast *tTree = tree->left;
2980 tree->left = tree->right;
2981 tree->right = tTree;
2984 /* if right is a literal and */
2985 /* we can find a 2nd literal in an or-tree then */
2986 /* rearrange the tree */
2987 if (IS_LITERAL (RTYPE (tree)))
2990 ast *litTree = searchLitOp (tree, &parent, "|");
2994 ast *tTree = litTree->left;
2995 litTree->left = tree->right;
2996 tree->right = tTree;
2997 /* both operands in tTree are literal now */
2998 decorateType (parent, resultType);
3003 /*------------------------------------------------------------------*/
3004 /*----------------------------*/
3006 /*----------------------------*/
3008 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3010 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3011 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3012 printTypeChain (LTYPE (tree), stderr);
3013 fprintf (stderr, ",");
3014 printTypeChain (RTYPE (tree), stderr);
3015 fprintf (stderr, "\n");
3016 goto errorTreeReturn;
3019 /* if they are both literal then rewrite the tree */
3020 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3022 tree->type = EX_VALUE;
3023 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3024 valFromType (RETYPE (tree)),
3026 tree->right = tree->left = NULL;
3027 TETYPE (tree) = tree->opval.val->etype;
3028 TTYPE (tree) = tree->opval.val->type;
3032 /* if left is a literal exchange left & right */
3033 if (IS_LITERAL (LTYPE (tree)))
3035 ast *tTree = tree->left;
3036 tree->left = tree->right;
3037 tree->right = tTree;
3040 /* if right is a literal and */
3041 /* we can find a 2nd literal in a xor-tree then */
3042 /* rearrange the tree */
3043 if (IS_LITERAL (RTYPE (tree)) &&
3044 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3047 ast *litTree = searchLitOp (tree, &parent, "^");
3051 ast *tTree = litTree->left;
3052 litTree->left = tree->right;
3053 tree->right = tTree;
3054 /* both operands in litTree are literal now */
3055 decorateType (parent, resultType);
3059 LRVAL (tree) = RRVAL (tree) = 1;
3061 TTYPE (tree) = computeType (LTYPE (tree),
3065 TETYPE (tree) = getSpec (TTYPE (tree));
3069 /*------------------------------------------------------------------*/
3070 /*----------------------------*/
3072 /*----------------------------*/
3074 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3076 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
3077 goto errorTreeReturn;
3079 /* if they are both literal then */
3080 /* rewrite the tree */
3081 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3083 tree->type = EX_VALUE;
3084 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
3085 valFromType (RETYPE (tree)));
3086 tree->right = tree->left = NULL;
3087 TETYPE (tree) = getSpec (TTYPE (tree) =
3088 tree->opval.val->type);
3092 LRVAL (tree) = RRVAL (tree) = 1;
3094 TETYPE (tree) = getSpec (TTYPE (tree) =
3095 computeType (LTYPE (tree),
3100 /* if right is a literal and */
3101 /* left is also a division by a literal then */
3102 /* rearrange the tree */
3103 if (IS_LITERAL (RTYPE (tree))
3104 /* avoid infinite loop */
3105 && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 1)
3108 ast *litTree = searchLitOp (tree, &parent, "/");
3111 if (IS_LITERAL (RTYPE (litTree)))
3115 litTree->right = newNode ('*',
3117 copyAst (tree->right));
3118 litTree->right->lineno = tree->lineno;
3120 tree->right->opval.val = constVal ("1");
3121 decorateType (parent, resultType);
3125 /* litTree->left is literal: no gcse possible.
3126 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3127 this would cause an infinit loop. */
3128 parent->decorated = 1;
3129 decorateType (litTree, resultType);
3136 /*------------------------------------------------------------------*/
3137 /*----------------------------*/
3139 /*----------------------------*/
3141 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3143 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3144 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3145 printTypeChain (LTYPE (tree), stderr);
3146 fprintf (stderr, ",");
3147 printTypeChain (RTYPE (tree), stderr);
3148 fprintf (stderr, "\n");
3149 goto errorTreeReturn;
3151 /* if they are both literal then */
3152 /* rewrite the tree */
3153 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3155 tree->type = EX_VALUE;
3156 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3157 valFromType (RETYPE (tree)));
3158 tree->right = tree->left = NULL;
3159 TETYPE (tree) = getSpec (TTYPE (tree) =
3160 tree->opval.val->type);
3163 LRVAL (tree) = RRVAL (tree) = 1;
3164 TETYPE (tree) = getSpec (TTYPE (tree) =
3165 computeType (LTYPE (tree),
3171 /*------------------------------------------------------------------*/
3172 /*----------------------------*/
3173 /* address dereference */
3174 /*----------------------------*/
3175 case '*': /* can be unary : if right is null then unary operation */
3178 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3180 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
3181 goto errorTreeReturn;
3186 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
3187 goto errorTreeReturn;
3189 if (IS_ADDRESS_OF_OP(tree->left))
3191 /* replace *&obj with obj */
3192 return tree->left->left;
3194 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3195 TETYPE (tree) = getSpec (TTYPE (tree));
3196 /* adjust the storage class */
3197 switch (DCL_TYPE(tree->left->ftype)) {
3199 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3202 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3205 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3208 SPEC_SCLS (TETYPE (tree)) = 0;
3211 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3214 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3217 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3220 SPEC_SCLS (TETYPE (tree)) = 0;
3229 /*------------------------------------------------------------------*/
3230 /*----------------------------*/
3231 /* multiplication */
3232 /*----------------------------*/
3233 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3235 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
3236 goto errorTreeReturn;
3239 /* if they are both literal then */
3240 /* rewrite the tree */
3241 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3243 tree->type = EX_VALUE;
3244 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3245 valFromType (RETYPE (tree)));
3246 tree->right = tree->left = NULL;
3247 TETYPE (tree) = getSpec (TTYPE (tree) =
3248 tree->opval.val->type);
3252 /* if left is a literal exchange left & right */
3253 if (IS_LITERAL (LTYPE (tree)))
3255 ast *tTree = tree->left;
3256 tree->left = tree->right;
3257 tree->right = tTree;
3260 /* if right is a literal and */
3261 /* we can find a 2nd literal in a mul-tree then */
3262 /* rearrange the tree */
3263 if (IS_LITERAL (RTYPE (tree)))
3266 ast *litTree = searchLitOp (tree, &parent, "*");
3270 ast *tTree = litTree->left;
3271 litTree->left = tree->right;
3272 tree->right = tTree;
3273 /* both operands in litTree are literal now */
3274 decorateType (parent, resultType);
3278 LRVAL (tree) = RRVAL (tree) = 1;
3279 tree->left = addCast (tree->left, resultTypeProp, FALSE);
3280 tree->right = addCast (tree->right, resultTypeProp, FALSE);
3281 TETYPE (tree) = getSpec (TTYPE (tree) =
3282 computeType (LTYPE (tree),
3289 /*------------------------------------------------------------------*/
3290 /*----------------------------*/
3291 /* unary '+' operator */
3292 /*----------------------------*/
3297 if (!IS_ARITHMETIC (LTYPE (tree)))
3299 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
3300 goto errorTreeReturn;
3303 /* if left is a literal then do it */
3304 if (IS_LITERAL (LTYPE (tree)))
3306 tree->type = EX_VALUE;
3307 tree->opval.val = valFromType (LETYPE (tree));
3309 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3313 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3317 /*------------------------------------------------------------------*/
3318 /*----------------------------*/
3320 /*----------------------------*/
3322 /* this is not a unary operation */
3323 /* if both pointers then problem */
3324 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3325 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3327 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
3328 goto errorTreeReturn;
3331 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3332 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3334 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3335 goto errorTreeReturn;
3338 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3339 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3341 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3342 goto errorTreeReturn;
3344 /* if they are both literal then */
3345 /* rewrite the tree */
3346 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3348 tree->type = EX_VALUE;
3349 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3350 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3351 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3352 valFromType (RETYPE (tree)));
3353 tree->right = tree->left = NULL;
3354 TETYPE (tree) = getSpec (TTYPE (tree) =
3355 tree->opval.val->type);
3359 /* if the right is a pointer or left is a literal
3360 xchange left & right */
3361 if (IS_ARRAY (RTYPE (tree)) ||
3362 IS_PTR (RTYPE (tree)) ||
3363 IS_LITERAL (LTYPE (tree)))
3365 ast *tTree = tree->left;
3366 tree->left = tree->right;
3367 tree->right = tTree;
3370 /* if right is a literal and */
3371 /* left is also an addition/subtraction with a literal then */
3372 /* rearrange the tree */
3373 if (IS_LITERAL (RTYPE (tree)))
3375 ast *litTree, *parent;
3376 litTree = searchLitOp (tree, &parent, "+-");
3379 if (litTree->opval.op == '+')
3383 ast *tTree = litTree->left;
3384 litTree->left = tree->right;
3385 tree->right = tree->left;
3388 else if (litTree->opval.op == '-')
3390 if (IS_LITERAL (RTYPE (litTree)))
3394 ast *tTree = litTree->left;
3395 litTree->left = tree->right;
3396 tree->right = tTree;
3402 ast *tTree = litTree->right;
3403 litTree->right = tree->right;
3404 tree->right = tTree;
3405 litTree->opval.op = '+';
3406 tree->opval.op = '-';
3409 decorateType (parent, resultType);
3413 LRVAL (tree) = RRVAL (tree) = 1;
3414 /* if the left is a pointer */
3415 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3416 TETYPE (tree) = getSpec (TTYPE (tree) =
3420 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3421 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3422 TETYPE (tree) = getSpec (TTYPE (tree) =
3423 computeType (LTYPE (tree),
3431 /*------------------------------------------------------------------*/
3432 /*----------------------------*/
3434 /*----------------------------*/
3435 case '-': /* can be unary */
3436 /* if right is null then unary */
3440 if (!IS_ARITHMETIC (LTYPE (tree)))
3442 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3443 goto errorTreeReturn;
3446 /* if left is a literal then do it */
3447 if (IS_LITERAL (LTYPE (tree)))
3449 tree->type = EX_VALUE;
3450 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3452 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3455 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3456 TETYPE (tree) = getSpec (TTYPE (tree) =
3457 computeType (LTYPE (tree),
3465 /*------------------------------------------------------------------*/
3466 /*----------------------------*/
3468 /*----------------------------*/
3470 if (!(IS_PTR (LTYPE (tree)) ||
3471 IS_ARRAY (LTYPE (tree)) ||
3472 IS_ARITHMETIC (LTYPE (tree))))
3474 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3475 goto errorTreeReturn;
3478 if (!(IS_PTR (RTYPE (tree)) ||
3479 IS_ARRAY (RTYPE (tree)) ||
3480 IS_ARITHMETIC (RTYPE (tree))))
3482 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3483 goto errorTreeReturn;
3486 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3487 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3488 IS_INTEGRAL (RTYPE (tree))))
3490 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3491 goto errorTreeReturn;
3494 /* if they are both literal then */
3495 /* rewrite the tree */
3496 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3498 tree->type = EX_VALUE;
3499 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3500 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3501 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3502 valFromType (RETYPE (tree)));
3503 tree->right = tree->left = NULL;
3504 TETYPE (tree) = getSpec (TTYPE (tree) =
3505 tree->opval.val->type);
3509 /* if the left & right are equal then zero */
3510 if (isAstEqual (tree->left, tree->right))
3512 tree->type = EX_VALUE;
3513 tree->left = tree->right = NULL;
3514 tree->opval.val = constVal ("0");
3515 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3519 /* if both of them are pointers or arrays then */
3520 /* the result is going to be an integer */
3521 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3522 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3523 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3525 /* if only the left is a pointer */
3526 /* then result is a pointer */
3527 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3528 TETYPE (tree) = getSpec (TTYPE (tree) =
3532 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3533 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3535 TETYPE (tree) = getSpec (TTYPE (tree) =
3536 computeType (LTYPE (tree),
3542 LRVAL (tree) = RRVAL (tree) = 1;
3544 /* if right is a literal and */
3545 /* left is also an addition/subtraction with a literal then */
3546 /* rearrange the tree */
3547 if (IS_LITERAL (RTYPE (tree))
3548 /* avoid infinite loop */
3549 && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 0)
3551 ast *litTree, *litParent;
3552 litTree = searchLitOp (tree, &litParent, "+-");
3555 if (litTree->opval.op == '+')
3559 ast *tTree = litTree->left;
3560 litTree->left = litTree->right;
3561 litTree->right = tree->right;
3562 tree->right = tTree;
3563 tree->opval.op = '+';
3564 litTree->opval.op = '-';
3566 else if (litTree->opval.op == '-')
3568 if (IS_LITERAL (RTYPE (litTree)))
3572 ast *tTree = litTree->left;
3573 litTree->left = tree->right;
3574 tree->right = litParent->left;
3575 litParent->left = tTree;
3576 litTree->opval.op = '+';
3578 tree->decorated = 0;
3579 decorateType (tree, resultType);
3585 ast *tTree = litTree->right;
3586 litTree->right = tree->right;
3587 tree->right = tTree;
3590 decorateType (litParent, resultType);
3595 /*------------------------------------------------------------------*/
3596 /*----------------------------*/
3598 /*----------------------------*/
3600 /* can be only integral type */
3601 if (!IS_INTEGRAL (LTYPE (tree)))
3603 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3604 goto errorTreeReturn;
3607 /* if left is a literal then do it */
3608 if (IS_LITERAL (LTYPE (tree)))
3610 tree->type = EX_VALUE;
3611 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3613 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3614 return addCast (tree, resultTypeProp, TRUE);
3617 if (resultType == RESULT_TYPE_BIT &&
3618 IS_UNSIGNED (tree->left->etype) &&
3619 getSize (tree->left->etype) < INTSIZE)
3621 /* promotion rules are responsible for this strange result:
3622 bit -> int -> ~int -> bit
3623 uchar -> int -> ~int -> bit
3625 werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
3627 /* optimize bit-result, even if we optimize a buggy source */
3628 tree->type = EX_VALUE;
3629 tree->opval.val = constVal ("1");
3632 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3634 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3637 /*------------------------------------------------------------------*/
3638 /*----------------------------*/
3640 /*----------------------------*/
3642 /* can be pointer */
3643 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3644 !IS_PTR (LTYPE (tree)) &&
3645 !IS_ARRAY (LTYPE (tree)))
3647 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3648 goto errorTreeReturn;
3651 /* if left is another '!' */
3652 if (IS_AST_NOT_OPER (tree->left))
3654 if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
3656 /* replace double '!!X' by 'X' */
3657 return tree->left->left;
3659 /* remove double '!!X' by 'X ? 1 : 0' */
3660 tree->opval.op = '?';
3661 tree->left = tree->left->left;
3662 tree->right = newNode (':',
3663 newAst_VALUE (constVal ("1")),
3664 newAst_VALUE (constVal ("0")));
3665 tree->right->lineno = tree->lineno;
3666 tree->decorated = 0;
3667 return decorateType (tree, resultType);
3670 /* if left is a literal then do it */
3671 if (IS_LITERAL (LTYPE (tree)))
3673 tree->type = EX_VALUE;
3674 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3676 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3680 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3683 /*------------------------------------------------------------------*/
3684 /*----------------------------*/
3686 /*----------------------------*/
3690 TTYPE (tree) = LTYPE (tree);
3691 TETYPE (tree) = LETYPE (tree);
3696 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3700 TTYPE (tree) = TETYPE (tree) = newCharLink();
3704 TTYPE (tree) = TETYPE (tree) = newIntLink();
3709 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3711 werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
3712 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3713 printTypeChain (LTYPE (tree), stderr);
3714 fprintf (stderr, ",");
3715 printTypeChain (RTYPE (tree), stderr);
3716 fprintf (stderr, "\n");
3717 goto errorTreeReturn;
3720 /* make smaller type only if it's a LEFT_OP */
3721 if (tree->opval.op == LEFT_OP)
3722 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3724 /* if they are both literal then */
3725 /* rewrite the tree */
3726 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3728 tree->type = EX_VALUE;
3729 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3730 valFromType (RETYPE (tree)),
3731 (tree->opval.op == LEFT_OP ? 1 : 0));
3732 tree->right = tree->left = NULL;
3733 TETYPE (tree) = getSpec (TTYPE (tree) =
3734 tree->opval.val->type);
3738 /* see if this is a GETBYTE operation if yes
3741 ast *otree = optimizeGetByte (tree, resultType);
3744 return decorateType (otree, RESULT_TYPE_NONE);
3747 /* see if this is a GETWORD operation if yes
3750 ast *otree = optimizeGetWord (tree, resultType);
3753 return decorateType (otree, RESULT_TYPE_NONE);
3756 LRVAL (tree) = RRVAL (tree) = 1;
3757 if (tree->opval.op == LEFT_OP)
3759 TETYPE (tree) = getSpec (TTYPE (tree) =
3760 computeType (LTYPE (tree),
3767 /* no promotion necessary */
3768 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3769 if (IS_LITERAL (TTYPE (tree)))
3770 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3773 /* if only the right side is a literal & we are
3774 shifting more than size of the left operand then zero */
3775 if (IS_LITERAL (RTYPE (tree)) &&
3776 ((TYPE_TARGET_ULONG) ulFromVal (valFromType (RETYPE (tree)))) >=
3777 (getSize (TETYPE (tree)) * 8))
3779 if (tree->opval.op==LEFT_OP ||
3780 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3782 werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
3783 (tree->opval.op == LEFT_OP ? "left" : "right"));
3784 tree->type = EX_VALUE;
3785 tree->left = tree->right = NULL;
3786 tree->opval.val = constVal ("0");
3787 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3794 /*------------------------------------------------------------------*/
3795 /*----------------------------*/
3797 /*----------------------------*/
3798 case CAST: /* change the type */
3799 /* cannot cast to an aggregate type */
3800 if (IS_AGGREGATE (LTYPE (tree)))
3802 werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
3803 goto errorTreeReturn;
3806 /* make sure the type is complete and sane */
3807 changePointer(LTYPE(tree));
3808 checkTypeSanity(LETYPE(tree), "(cast)");
3810 /* if 'from' and 'to' are the same remove the superfluous cast, */
3811 /* this helps other optimizations */
3812 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3817 /* If code memory is read only, then pointers to code memory */
3818 /* implicitly point to constants -- make this explicit */
3820 sym_link *t = LTYPE(tree);
3821 while (t && t->next)
3823 if (IS_CODEPTR(t) && port->mem.code_ro)
3825 if (IS_SPEC(t->next))
3826 SPEC_CONST (t->next) = 1;
3828 DCL_PTR_CONST (t->next) = 1;
3835 /* if the right is a literal replace the tree */
3836 if (IS_LITERAL (RETYPE (tree))) {
3837 if (!IS_PTR (LTYPE (tree))) {
3838 tree->type = EX_VALUE;
3840 valCastLiteral (LTYPE (tree),
3841 floatFromVal (valFromType (RETYPE (tree))));
3844 TTYPE (tree) = tree->opval.val->type;
3845 tree->values.literalFromCast = 1;
3846 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3847 ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3848 sym_link *rest = LTYPE(tree)->next;
3849 werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
3850 TTYPE(tree) = newLink(DECLARATOR);
3851 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3852 TTYPE(tree)->next = rest;
3853 tree->left->opval.lnk = TTYPE(tree);
3856 TTYPE (tree) = LTYPE (tree);
3860 TTYPE (tree) = LTYPE (tree);
3864 #if 0 // this is already checked, now this could be explicit
3865 /* if pointer to struct then check names */
3866 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3867 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3868 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3870 werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3871 SPEC_STRUCT(LETYPE(tree))->tag);
3874 if (IS_ADDRESS_OF_OP(tree->right)
3875 && IS_AST_SYM_VALUE (tree->right->left)
3876 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3878 symbol * sym = AST_SYMBOL (tree->right->left);
3879 unsigned int gptype = 0;
3880 unsigned int addr = SPEC_ADDR (sym->etype);
3882 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
3883 || TARGET_IS_PIC16) )
3885 switch (SPEC_SCLS (sym->etype))
3888 gptype = GPTYPE_CODE;
3891 gptype = GPTYPE_FAR;
3895 gptype = GPTYPE_NEAR;
3898 gptype = GPTYPE_XSTACK;
3903 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3904 gptype = GPTYPE_NEAR;
3906 addr |= gptype << (8*(GPTRSIZE - 1));
3909 tree->type = EX_VALUE;
3911 valCastLiteral (LTYPE (tree), addr);
3912 TTYPE (tree) = tree->opval.val->type;
3913 TETYPE (tree) = getSpec (TTYPE (tree));
3916 tree->values.literalFromCast = 1;
3920 /* handle offsetof macro: */
3921 /* #define offsetof(TYPE, MEMBER) \ */
3922 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3923 if (IS_ADDRESS_OF_OP(tree->right)
3924 && IS_AST_OP (tree->right->left)
3925 && tree->right->left->opval.op == PTR_OP
3926 && IS_AST_OP (tree->right->left->left)
3927 && tree->right->left->left->opval.op == CAST
3928 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3930 symbol *element = getStructElement (
3931 SPEC_STRUCT (LETYPE(tree->right->left)),
3932 AST_SYMBOL(tree->right->left->right)
3936 tree->type = EX_VALUE;
3937 tree->opval.val = valCastLiteral (
3940 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3943 TTYPE (tree) = tree->opval.val->type;
3944 TETYPE (tree) = getSpec (TTYPE (tree));
3951 /* if the right is a literal replace the tree */
3952 if (IS_LITERAL (RETYPE (tree))) {
3954 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3955 /* rewrite (type *)litaddr
3957 and define type at litaddr temp
3958 (but only if type's storage class is not generic)
3960 ast *newTree = newNode ('&', NULL, NULL);
3963 TTYPE (newTree) = LTYPE (tree);
3964 TETYPE (newTree) = getSpec(LTYPE (tree));
3966 /* define a global symbol at the casted address*/
3967 sym = newSymbol(genSymName (0), 0);
3968 sym->type = LTYPE (tree)->next;
3970 sym->type = newLink (V_VOID);
3971 sym->etype = getSpec(sym->type);
3972 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3973 sym->lineDef = tree->lineno;
3976 SPEC_STAT (sym->etype) = 1;
3977 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3978 SPEC_ABSA(sym->etype) = 1;
3979 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3982 newTree->left = newAst_VALUE(symbolVal(sym));
3983 newTree->left->lineno = tree->lineno;
3984 LTYPE (newTree) = sym->type;
3985 LETYPE (newTree) = sym->etype;
3986 LLVAL (newTree) = 1;
3987 LRVAL (newTree) = 0;
3988 TLVAL (newTree) = 1;
3992 if (!IS_PTR (LTYPE (tree))) {
3993 tree->type = EX_VALUE;
3995 valCastLiteral (LTYPE (tree),
3996 floatFromVal (valFromType (RTYPE (tree))));
3997 TTYPE (tree) = tree->opval.val->type;
4000 tree->values.literalFromCast = 1;
4001 TETYPE (tree) = getSpec (TTYPE (tree));
4005 TTYPE (tree) = LTYPE (tree);
4009 TETYPE (tree) = getSpec (TTYPE (tree));
4013 /*------------------------------------------------------------------*/
4014 /*----------------------------*/
4015 /* logical &&, || */
4016 /*----------------------------*/
4019 /* each must be arithmetic type or be a pointer */
4020 if (!IS_PTR (LTYPE (tree)) &&
4021 !IS_ARRAY (LTYPE (tree)) &&
4022 !IS_INTEGRAL (LTYPE (tree)))
4024 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4025 goto errorTreeReturn;
4028 if (!IS_PTR (RTYPE (tree)) &&
4029 !IS_ARRAY (RTYPE (tree)) &&
4030 !IS_INTEGRAL (RTYPE (tree)))
4032 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4033 goto errorTreeReturn;
4035 /* if they are both literal then */
4036 /* rewrite the tree */
4037 if (IS_LITERAL (RTYPE (tree)) &&
4038 IS_LITERAL (LTYPE (tree)))
4040 tree->type = EX_VALUE;
4041 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4042 valFromType (RTYPE (tree)),
4044 tree->right = tree->left = NULL;
4045 TETYPE (tree) = getSpec (TTYPE (tree) =
4046 tree->opval.val->type);
4049 LRVAL (tree) = RRVAL (tree) = 1;
4050 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4053 /*------------------------------------------------------------------*/
4054 /*----------------------------*/
4055 /* comparison operators */
4056 /*----------------------------*/
4064 ast *lt = optimizeCompare (tree);
4070 /* if they are pointers they must be castable */
4071 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4073 if (tree->opval.op==EQ_OP &&
4074 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4075 // we cannot cast a gptr to a !gptr: switch the leaves
4076 struct ast *s=tree->left;
4077 tree->left=tree->right;
4080 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4082 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4083 fprintf (stderr, "comparing type ");
4084 printTypeChain (LTYPE (tree), stderr);
4085 fprintf (stderr, "to type ");
4086 printTypeChain (RTYPE (tree), stderr);
4087 fprintf (stderr, "\n");
4088 goto errorTreeReturn;
4091 /* else they should be promotable to one another */
4094 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4095 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4097 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4099 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4100 fprintf (stderr, "comparing type ");
4101 printTypeChain (LTYPE (tree), stderr);
4102 fprintf (stderr, "to type ");
4103 printTypeChain (RTYPE (tree), stderr);
4104 fprintf (stderr, "\n");
4105 goto errorTreeReturn;
4110 CCR_RESULT ccr_result = CCR_OK;
4112 /* if left is integral and right is literal
4113 then check constant range */
4114 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4115 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4116 tree->opval.op, FALSE);
4117 if (ccr_result == CCR_OK &&
4118 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4119 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4120 tree->opval.op, TRUE);
4123 case CCR_ALWAYS_TRUE:
4124 case CCR_ALWAYS_FALSE:
4125 if (!options.lessPedantic)
4126 werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
4127 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4128 return decorateType (newAst_VALUE (constVal (
4129 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4137 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4138 if (tree->opval.op == '>' &&
4139 SPEC_USIGN(LETYPE(tree)) &&
4140 IS_LITERAL(RTYPE(tree)) &&
4141 ((int) ulFromVal (valFromType (RETYPE (tree)))) == 0)
4143 if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
4145 /* the parent is an ifx: */
4146 /* if (unsigned value) */
4150 /* (unsigned value) ? 1 : 0 */
4151 tree->opval.op = '?';
4152 tree->right = newNode (':',
4153 newAst_VALUE (constVal ("1")),
4154 tree->right); /* val 0 */
4155 tree->right->lineno = tree->lineno;
4156 tree->right->left->lineno = tree->lineno;
4157 tree->decorated = 0;
4158 return decorateType (tree, resultType);
4161 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4162 if (IS_LITERAL(RTYPE(tree)) &&
4163 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4164 tree->opval.op == EQ_OP &&
4165 (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT))
4167 tree->opval.op = '!';
4169 tree->decorated = 0;
4170 return decorateType (tree, resultType);
4173 /* if they are both literal then */
4174 /* rewrite the tree */
4175 if (IS_LITERAL (RTYPE (tree)) &&
4176 IS_LITERAL (LTYPE (tree)))
4178 tree->type = EX_VALUE;
4179 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4180 valFromType (RETYPE (tree)),
4182 tree->right = tree->left = NULL;
4183 TETYPE (tree) = getSpec (TTYPE (tree) =
4184 tree->opval.val->type);
4188 /* if one is 'signed char ' and the other one is 'unsigned char' */
4189 /* it's necessary to promote to int */
4190 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4191 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4193 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4194 if it's possible to use a 'signed char' */
4196 /* is left a 'unsigned char'? */
4197 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4198 /* the value range of a 'unsigned char' is 0...255;
4199 if the actual value is < 128 it can be changed to signed */
4200 (int) ulFromVal (valFromType (RETYPE (tree))) < 128)
4202 /* now we've got 2 'signed char'! */
4203 SPEC_USIGN (RETYPE (tree)) = 0;
4205 /* same test for the left operand: */
4206 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4207 (int) ulFromVal (valFromType (LETYPE (tree))) < 128)
4209 SPEC_USIGN (LETYPE (tree)) = 0;
4213 werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
4214 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4215 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4219 LRVAL (tree) = RRVAL (tree) = 1;
4220 TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4222 /* condition transformations */
4224 unsigned transformedOp = 0;
4226 switch (tree->opval.op)
4228 case '<': /* transform (a < b) to !(a >= b) */
4230 transformedOp = GE_OP;
4232 case '>': /* transform (a > b) to !(a <= b) */
4234 transformedOp = LE_OP;
4236 case LE_OP: /* transform (a <= b) to !(a > b) */
4238 transformedOp = '>';
4240 case GE_OP: /* transform (a >= b) to !(a < b) */
4242 transformedOp = '<';
4244 case NE_OP: /* transform (a != b) to !(a == b) */
4246 transformedOp = EQ_OP;
4248 case EQ_OP: /* transform (a == b) to !(a != b) */
4250 transformedOp = NE_OP;
4257 tree->opval.op = transformedOp;
4258 tree->decorated = 0;
4259 tree = newNode ('!', tree, NULL);
4260 tree->lineno = tree->left->lineno;
4261 return decorateType (tree, resultType);
4267 /*------------------------------------------------------------------*/
4268 /*----------------------------*/
4270 /*----------------------------*/
4271 case SIZEOF: /* evaluate wihout code generation */
4272 /* change the type to a integer */
4274 int size = getSize (tree->right->ftype);
4276 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4277 if (!size && !IS_VOID(tree->right->ftype))
4278 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4280 tree->type = EX_VALUE;
4281 tree->opval.val = constVal (buffer);
4282 tree->right = tree->left = NULL;
4283 TETYPE (tree) = getSpec (TTYPE (tree) =
4284 tree->opval.val->type);
4288 /*------------------------------------------------------------------*/
4289 /*----------------------------*/
4291 /*----------------------------*/
4293 /* return typeof enum value */
4294 tree->type = EX_VALUE;
4297 if (IS_SPEC(tree->right->ftype)) {
4298 switch (SPEC_NOUN(tree->right->ftype)) {
4300 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4301 else typeofv = TYPEOF_INT;
4304 typeofv = TYPEOF_FLOAT;
4307 typeofv = TYPEOF_FIXED16X16;
4310 typeofv = TYPEOF_CHAR;
4313 typeofv = TYPEOF_VOID;
4316 typeofv = TYPEOF_STRUCT;
4319 typeofv = TYPEOF_BITFIELD;
4322 typeofv = TYPEOF_BIT;
4325 typeofv = TYPEOF_SBIT;
4331 switch (DCL_TYPE(tree->right->ftype)) {
4333 typeofv = TYPEOF_POINTER;
4336 typeofv = TYPEOF_FPOINTER;
4339 typeofv = TYPEOF_CPOINTER;
4342 typeofv = TYPEOF_GPOINTER;
4345 typeofv = TYPEOF_PPOINTER;
4348 typeofv = TYPEOF_IPOINTER;
4351 typeofv = TYPEOF_ARRAY;
4354 typeofv = TYPEOF_FUNCTION;
4360 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4361 tree->opval.val = constVal (buffer);
4362 tree->right = tree->left = NULL;
4363 TETYPE (tree) = getSpec (TTYPE (tree) =
4364 tree->opval.val->type);
4367 /*------------------------------------------------------------------*/
4368 /*----------------------------*/
4369 /* conditional operator '?' */
4370 /*----------------------------*/
4372 /* the type is value of the colon operator (on the right) */
4373 assert (IS_COLON_OP (tree->right));
4375 /* If already known then replace the tree : optimizer will do it
4376 but faster to do it here. If done before decorating tree->right
4377 this can save generating unused const strings. */
4378 if (IS_LITERAL (LTYPE (tree)))
4380 if (((int) ulFromVal (valFromType (LETYPE (tree)))) != 0)
4381 return decorateType (tree->right->left, resultTypeProp);
4383 return decorateType (tree->right->right, resultTypeProp);
4386 tree->right = decorateType (tree->right, resultTypeProp);
4388 if (IS_AST_LIT_VALUE (tree->right->left) && IS_AST_LIT_VALUE (tree->right->right) &&
4389 ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)))
4391 double valTrue = AST_FLOAT_VALUE (tree->right->left);
4392 double valFalse = AST_FLOAT_VALUE (tree->right->right);
4394 if ((valTrue != 0) && (valFalse == 0))
4396 /* assign cond to result */
4397 tree->left->decorated = 0;
4398 return decorateType (tree->left, resultTypeProp);
4400 else if ((valTrue == 0) && (valFalse != 0))
4402 /* assign !cond to result */
4403 tree->opval.op = '!';
4404 tree->decorated = 0;
4406 return decorateType (tree, resultTypeProp);
4410 /* they have the same boolean value, make them equal */
4411 tree->right->left = tree->right->right;
4415 /* if they are equal then replace the tree */
4416 if (isAstEqual (tree->right->left, tree->right->right))
4418 return tree->right->left;
4421 TTYPE (tree) = RTYPE (tree);
4422 TETYPE (tree) = getSpec (TTYPE (tree));
4426 /* if they don't match we have a problem */
4427 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4428 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4430 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
4431 goto errorTreeReturn;
4434 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4435 resultType, tree->opval.op);
4436 TETYPE (tree) = getSpec (TTYPE (tree));
4440 #if 0 // assignment operators are converted by the parser
4441 /*------------------------------------------------------------------*/
4442 /*----------------------------*/
4443 /* assignment operators */
4444 /*----------------------------*/
4447 /* for these it must be both must be integral */
4448 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4449 !IS_ARITHMETIC (RTYPE (tree)))
4451 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4452 goto errorTreeReturn;
4455 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4457 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4458 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4462 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4463 goto errorTreeReturn;
4474 /* for these it must be both must be integral */
4475 if (!IS_INTEGRAL (LTYPE (tree)) ||
4476 !IS_INTEGRAL (RTYPE (tree)))
4478 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4479 goto errorTreeReturn;
4482 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4484 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4485 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4489 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4490 goto errorTreeReturn;
4496 /*------------------------------------------------------------------*/
4497 /*----------------------------*/
4499 /*----------------------------*/
4501 if (!(IS_PTR (LTYPE (tree)) ||
4502 IS_ARITHMETIC (LTYPE (tree))))
4504 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4505 goto errorTreeReturn;
4508 if (!(IS_PTR (RTYPE (tree)) ||
4509 IS_ARITHMETIC (RTYPE (tree))))
4511 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4512 goto errorTreeReturn;
4515 TETYPE (tree) = getSpec (TTYPE (tree) =
4516 computeType (LTYPE (tree),
4521 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4522 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
4526 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
4527 goto errorTreeReturn;
4533 /*------------------------------------------------------------------*/
4534 /*----------------------------*/
4536 /*----------------------------*/
4538 /* this is not a unary operation */
4539 /* if both pointers then problem */
4540 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4542 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
4543 goto errorTreeReturn;
4546 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4548 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4549 goto errorTreeReturn;
4552 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4554 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4555 goto errorTreeReturn;
4558 TETYPE (tree) = getSpec (TTYPE (tree) =
4559 computeType (LTYPE (tree),
4564 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4565 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
4569 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
4570 goto errorTreeReturn;
4573 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4574 tree->opval.op = '=';
4579 /*------------------------------------------------------------------*/
4580 /*----------------------------*/
4581 /* straight assignemnt */
4582 /*----------------------------*/
4584 /* cannot be an aggregate */
4585 if (IS_AGGREGATE (LTYPE (tree)))
4587 werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
4588 goto errorTreeReturn;
4591 /* they should either match or be castable */
4592 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4594 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
4595 printFromToType(RTYPE(tree),LTYPE(tree));
4598 /* if the left side of the tree is of type void
4599 then report error */
4600 if (IS_VOID (LTYPE (tree)))
4602 werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
4603 printFromToType(RTYPE(tree), LTYPE(tree));
4606 TETYPE (tree) = getSpec (TTYPE (tree) =
4610 if (!tree->initMode ) {
4611 if (IS_CONSTANT(LTYPE(tree)))
4612 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
4616 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
4617 goto errorTreeReturn;
4622 /*------------------------------------------------------------------*/
4623 /*----------------------------*/
4624 /* comma operator */
4625 /*----------------------------*/
4627 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4630 /*------------------------------------------------------------------*/
4631 /*----------------------------*/
4633 /*----------------------------*/
4636 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4637 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4639 if (tree->left->opval.op == '*' && !tree->left->right)
4640 tree->left = tree->left->left;
4643 /* require a function or pointer to function */
4644 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4646 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4647 goto errorTreeReturn;
4650 /* if there are parms, make sure that
4651 parms are decorate / process / reverse only once */
4653 !tree->right->decorated)
4658 if (IS_FUNCPTR (LTYPE (tree)))
4660 functype = LTYPE (tree)->next;
4661 processFuncPtrArgs (functype);
4664 functype = LTYPE (tree);
4666 if (processParms (tree->left, FUNC_ARGS(functype),
4667 &tree->right, &parmNumber, TRUE))
4669 goto errorTreeReturn;
4672 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4673 !IFFUNC_ISBUILTIN(functype))
4675 reverseParms (tree->right);
4678 TTYPE (tree) = functype->next;
4679 TETYPE (tree) = getSpec (TTYPE (tree));
4683 /*------------------------------------------------------------------*/
4684 /*----------------------------*/
4685 /* return statement */
4686 /*----------------------------*/
4691 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4693 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4694 printFromToType (RTYPE(tree), currFunc->type->next);
4695 goto errorTreeReturn;
4698 if (IS_VOID (currFunc->type->next)
4700 !IS_VOID (RTYPE (tree)))
4702 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4703 goto errorTreeReturn;
4706 /* if there is going to be a casting required then add it */
4707 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4710 decorateType (newNode (CAST,
4711 newAst_LINK (copyLinkChain (currFunc->type->next)),
4721 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4723 werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
4724 goto errorTreeReturn;
4727 TTYPE (tree) = TETYPE (tree) = NULL;
4730 /*------------------------------------------------------------------*/
4731 /*----------------------------*/
4732 /* switch statement */
4733 /*----------------------------*/
4735 /* the switch value must be an integer */
4736 if (!IS_INTEGRAL (LTYPE (tree)))
4738 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4739 goto errorTreeReturn;
4742 TTYPE (tree) = TETYPE (tree) = NULL;
4745 /*------------------------------------------------------------------*/
4746 /*----------------------------*/
4748 /*----------------------------*/
4750 tree->left = backPatchLabels (tree->left,
4753 TTYPE (tree) = TETYPE (tree) = NULL;
4756 /*------------------------------------------------------------------*/
4757 /*----------------------------*/
4759 /*----------------------------*/
4762 AST_FOR (tree, initExpr) = decorateType (
4763 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4764 AST_FOR (tree, condExpr) = decorateType (
4765 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4766 AST_FOR (tree, loopExpr) = decorateType (
4767 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4769 /* if the for loop is reversible then
4770 reverse it otherwise do what we normally
4776 if (isLoopReversible (tree, &sym, &init, &end))
4777 return reverseLoop (tree, sym, init, end);
4779 return decorateType (createFor (AST_FOR (tree, trueLabel),
4780 AST_FOR (tree, continueLabel),
4781 AST_FOR (tree, falseLabel),
4782 AST_FOR (tree, condLabel),
4783 AST_FOR (tree, initExpr),
4784 AST_FOR (tree, condExpr),
4785 AST_FOR (tree, loopExpr),
4786 tree->left), RESULT_TYPE_NONE);
4789 werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
4790 "node PARAM shouldn't be processed here");
4791 /* but in processParams() */
4794 TTYPE (tree) = TETYPE (tree) = NULL;
4798 /* some error found this tree will be killed */
4800 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4801 tree->opval.op = NULLOP;
4807 /*-----------------------------------------------------------------*/
4808 /* sizeofOp - processes size of operation */
4809 /*-----------------------------------------------------------------*/
4811 sizeofOp (sym_link * type)
4816 /* make sure the type is complete and sane */
4817 checkTypeSanity(type, "(sizeof)");
4819 /* get the size and convert it to character */
4820 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4821 if (!size && !IS_VOID(type))
4822 werror (E_SIZEOF_INCOMPLETE_TYPE);
4824 /* now convert into value */
4825 return constVal (buff);
4829 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4830 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4831 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4832 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4833 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4834 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4835 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4837 /*-----------------------------------------------------------------*/
4838 /* backPatchLabels - change and or not operators to flow control */
4839 /*-----------------------------------------------------------------*/
4841 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4847 /* while-loops insert a label between the IFX and the condition,
4848 therefore look behind the label too */
4849 if (tree->opval.op == LABEL &&
4851 IS_ANDORNOT (tree->right))
4853 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4857 if (!(IS_ANDORNOT (tree)))
4860 /* if this an and */
4863 static int localLbl = 0;
4866 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4867 localLabel = newSymbol (buffer, NestLevel);
4869 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4871 /* if left is already a IFX then just change the if true label in that */
4872 if (!IS_IFX (tree->left))
4873 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4875 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4876 /* right is a IFX then just join */
4877 if (IS_IFX (tree->right))
4878 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4880 tree->right = createLabel (localLabel, tree->right);
4881 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4883 return newNode (NULLOP, tree->left, tree->right);
4886 /* if this is an or operation */
4889 static int localLbl = 0;
4892 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4893 localLabel = newSymbol (buffer, NestLevel);
4895 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4897 /* if left is already a IFX then just change the if true label in that */
4898 if (!IS_IFX (tree->left))
4899 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4901 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4902 /* right is a IFX then just join */
4903 if (IS_IFX (tree->right))
4904 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4906 tree->right = createLabel (localLabel, tree->right);
4907 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4909 return newNode (NULLOP, tree->left, tree->right);
4915 /* call with exchanged labels */
4916 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4918 /* if left isn't already a IFX */
4919 if (!IS_IFX (tree->left))
4921 tree->left = newNode (IFX, tree->left, NULL);
4922 tree->left->trueLabel = falseLabel;
4923 tree->left->falseLabel = trueLabel;
4930 tree->trueLabel = trueLabel;
4931 tree->falseLabel = falseLabel;
4938 /*-----------------------------------------------------------------*/
4939 /* createBlock - create expression tree for block */
4940 /*-----------------------------------------------------------------*/
4942 createBlock (symbol * decl, ast * body)
4946 /* if the block has nothing */
4950 ex = newNode (BLOCK, NULL, body);
4951 ex->values.sym = decl;
4958 /*-----------------------------------------------------------------*/
4959 /* createLabel - creates the expression tree for labels */
4960 /*-----------------------------------------------------------------*/
4962 createLabel (symbol * label, ast * stmnt)
4965 char name[SDCC_NAME_MAX + 1];
4968 /* must create fresh symbol if the symbol name */
4969 /* exists in the symbol table, since there can */
4970 /* be a variable with the same name as the labl */
4971 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4972 (csym->level == label->level))
4973 label = newSymbol (label->name, label->level);
4975 /* change the name before putting it in add _ */
4976 SNPRINTF(name, sizeof(name), "%s", label->name);
4978 /* put the label in the LabelSymbol table */
4979 /* but first check if a label of the same */
4981 if ((csym = findSym (LabelTab, NULL, name)))
4982 werror (E_DUPLICATE_LABEL, label->name);
4984 addSym (LabelTab, label, name, label->level, 0, 0);
4988 label->key = labelKey++;
4989 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4995 /*-----------------------------------------------------------------*/
4996 /* createCase - generates the parsetree for a case statement */
4997 /*-----------------------------------------------------------------*/
4999 createCase (ast * swStat, ast * caseVal, ast * stmnt)
5001 char caseLbl[SDCC_NAME_MAX + 1];
5005 /* if the switch statement does not exist */
5006 /* then case is out of context */
5009 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
5013 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
5014 /* if not a constant then error */
5015 if (!IS_LITERAL (caseVal->ftype))
5017 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
5021 /* if not a integer than error */
5022 if (!IS_INTEGRAL (caseVal->ftype))
5024 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
5028 /* find the end of the switch values chain */
5029 if (!(val = swStat->values.switchVals.swVals))
5030 swStat->values.switchVals.swVals = caseVal->opval.val;
5033 /* also order the cases according to value */
5035 int cVal = (int) ulFromVal (caseVal->opval.val);
5036 while (val && (int) ulFromVal (val) < cVal)
5042 /* if we reached the end then */
5045 pval->next = caseVal->opval.val;
5047 else if ((int) ulFromVal (val) == cVal)
5049 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5055 /* we found a value greater than */
5056 /* the current value we must add this */
5057 /* before the value */
5058 caseVal->opval.val->next = val;
5060 /* if this was the first in chain */
5061 if (swStat->values.switchVals.swVals == val)
5062 swStat->values.switchVals.swVals =
5065 pval->next = caseVal->opval.val;
5070 /* create the case label */
5071 SNPRINTF(caseLbl, sizeof(caseLbl),
5073 swStat->values.switchVals.swNum,
5074 (int) ulFromVal (caseVal->opval.val));
5076 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5081 /*-----------------------------------------------------------------*/
5082 /* createDefault - creates the parse tree for the default statement */
5083 /*-----------------------------------------------------------------*/
5085 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5087 char defLbl[SDCC_NAME_MAX + 1];
5089 /* if the switch statement does not exist */
5090 /* then case is out of context */
5093 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5097 if (swStat->values.switchVals.swDefault)
5099 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5104 /* turn on the default flag */
5105 swStat->values.switchVals.swDefault = 1;
5107 /* create the label */
5108 SNPRINTF (defLbl, sizeof(defLbl),
5109 "_default_%d", swStat->values.switchVals.swNum);
5110 return createLabel (newSymbol (defLbl, 0), stmnt);
5113 /*-----------------------------------------------------------------*/
5114 /* createIf - creates the parsetree for the if statement */
5115 /*-----------------------------------------------------------------*/
5117 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5119 static int Lblnum = 0;
5121 symbol *ifTrue, *ifFalse, *ifEnd;
5123 /* if neither exists */
5124 if (!elseBody && !ifBody) {
5125 // if there are no side effects (i++, j() etc)
5126 if (!hasSEFcalls(condAst)) {
5131 /* create the labels */
5132 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5133 ifFalse = newSymbol (buffer, NestLevel);
5134 /* if no else body then end == false */
5139 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5140 ifEnd = newSymbol (buffer, NestLevel);
5143 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5144 ifTrue = newSymbol (buffer, NestLevel);
5148 /* attach the ifTrue label to the top of it body */
5149 ifBody = createLabel (ifTrue, ifBody);
5150 /* attach a goto end to the ifBody if else is present */
5153 ifBody = newNode (NULLOP, ifBody,
5155 newAst_VALUE (symbolVal (ifEnd)),
5157 /* put the elseLabel on the else body */
5158 elseBody = createLabel (ifFalse, elseBody);
5159 /* out the end at the end of the body */
5160 elseBody = newNode (NULLOP,
5162 createLabel (ifEnd, NULL));
5166 ifBody = newNode (NULLOP, ifBody,
5167 createLabel (ifFalse, NULL));
5169 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5170 if (IS_IFX (condAst))
5173 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5175 return newNode (NULLOP, ifTree,
5176 newNode (NULLOP, ifBody, elseBody));
5180 /*-----------------------------------------------------------------*/
5181 /* createDo - creates parse tree for do */
5184 /* _docontinue_n: */
5185 /* condition_expression +-> trueLabel -> _dobody_n */
5187 /* +-> falseLabel-> _dobreak_n */
5189 /*-----------------------------------------------------------------*/
5191 createDo (symbol * trueLabel, symbol * continueLabel,
5192 symbol * falseLabel, ast * condAst, ast * doBody)
5197 /* if the body does not exist then it is simple */
5200 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5201 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5202 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5203 doTree->trueLabel = continueLabel;
5204 doTree->falseLabel = NULL;
5206 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5210 /* otherwise we have a body */
5211 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5213 /* attach the body label to the top */
5214 doBody = createLabel (trueLabel, doBody);
5215 /* attach the continue label to end of body */
5216 doBody = newNode (NULLOP, doBody,
5217 createLabel (continueLabel, NULL));
5219 /* now put the break label at the end */
5220 if (IS_IFX (condAst))
5223 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5225 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5227 /* putting it together */
5228 return newNode (NULLOP, doBody, doTree);
5231 /*-----------------------------------------------------------------*/
5232 /* createFor - creates parse tree for 'for' statement */
5235 /* condExpr +-> trueLabel -> _forbody_n */
5237 /* +-> falseLabel-> _forbreak_n */
5240 /* _forcontinue_n: */
5242 /* goto _forcond_n ; */
5244 /*-----------------------------------------------------------------*/
5246 createFor (symbol * trueLabel, symbol * continueLabel,
5247 symbol * falseLabel, symbol * condLabel,
5248 ast * initExpr, ast * condExpr, ast * loopExpr,
5253 /* if loopexpression not present then we can generate it */
5254 /* the same way as a while */
5256 return newNode (NULLOP, initExpr,
5257 createWhile (trueLabel, continueLabel,
5258 falseLabel, condExpr, forBody));
5259 /* vanilla for statement */
5260 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5262 if (condExpr && !IS_IFX (condExpr))
5263 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5266 /* attach condition label to condition */
5267 condExpr = createLabel (condLabel, condExpr);
5269 /* attach body label to body */
5270 forBody = createLabel (trueLabel, forBody);
5272 /* attach continue to forLoop expression & attach */
5273 /* goto the forcond @ and of loopExpression */
5274 loopExpr = createLabel (continueLabel,
5278 newAst_VALUE (symbolVal (condLabel)),
5280 /* now start putting them together */
5281 forTree = newNode (NULLOP, initExpr, condExpr);
5282 forTree = newNode (NULLOP, forTree, forBody);
5283 forTree = newNode (NULLOP, forTree, loopExpr);
5284 /* finally add the break label */
5285 forTree = newNode (NULLOP, forTree,
5286 createLabel (falseLabel, NULL));
5290 /*-----------------------------------------------------------------*/
5291 /* createWhile - creates parse tree for while statement */
5292 /* the while statement will be created as follows */
5294 /* _while_continue_n: */
5295 /* condition_expression +-> trueLabel -> _while_boby_n */
5297 /* +-> falseLabel -> _while_break_n */
5298 /* _while_body_n: */
5300 /* goto _while_continue_n */
5301 /* _while_break_n: */
5302 /*-----------------------------------------------------------------*/
5304 createWhile (symbol * trueLabel, symbol * continueLabel,
5305 symbol * falseLabel, ast * condExpr, ast * whileBody)
5309 /* put the continue label */
5310 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5311 condExpr = createLabel (continueLabel, condExpr);
5312 condExpr->lineno = 0;
5314 /* put the body label in front of the body */
5315 whileBody = createLabel (trueLabel, whileBody);
5316 whileBody->lineno = 0;
5317 /* put a jump to continue at the end of the body */
5318 /* and put break label at the end of the body */
5319 whileBody = newNode (NULLOP,
5322 newAst_VALUE (symbolVal (continueLabel)),
5323 createLabel (falseLabel, NULL)));
5325 /* put it all together */
5326 if (IS_IFX (condExpr))
5327 whileTree = condExpr;
5330 whileTree = newNode (IFX, condExpr, NULL);
5331 /* put the true & false labels in place */
5332 whileTree->trueLabel = trueLabel;
5333 whileTree->falseLabel = falseLabel;
5336 return newNode (NULLOP, whileTree, whileBody);
5339 /*-----------------------------------------------------------------*/
5340 /* isShiftRightLitVal _BitAndLitVal - helper function */
5341 /*-----------------------------------------------------------------*/
5343 isShiftRightLitVal_BitAndLitVal (ast * tree)
5345 /* if this is not a bit and */
5346 if (!IS_BITAND (tree))
5349 /* will look for tree of the form
5350 ( expr >> litval2) & litval1 */
5351 if (!IS_AST_LIT_VALUE (tree->right))
5354 if (!IS_RIGHT_OP (tree->left))
5357 if (!IS_AST_LIT_VALUE (tree->left->right))
5360 return tree->left->left;
5363 /*-----------------------------------------------------------------*/
5364 /* isBitAndPowOf2 - helper function */
5365 /*-----------------------------------------------------------------*/
5367 isBitAndPow2 (ast * tree)
5369 /* if this is not a bit and */
5370 if (!IS_BITAND (tree))
5373 /* will look for tree of the form
5374 ( expr & (1 << litval) */
5375 if (!IS_AST_LIT_VALUE (tree->right))
5378 return powof2 (AST_ULONG_VALUE (tree->right));
5381 /*-----------------------------------------------------------------*/
5382 /* optimizeGetHbit - get highest order bit of the expression */
5383 /*-----------------------------------------------------------------*/
5385 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5390 expr = isShiftRightLitVal_BitAndLitVal(tree);
5393 if ((AST_ULONG_VALUE (tree->right) != 1) ||
5394 ((i = AST_ULONG_VALUE (tree->left->right)) !=
5395 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5398 if (!expr && (resultType == RESULT_TYPE_BIT))
5401 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5407 /* make sure the port supports GETHBIT */
5408 if (port->hasExtBitOp
5409 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5412 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5415 /*-----------------------------------------------------------------*/
5416 /* optimizeGetAbit - get a single bit of the expression */
5417 /*-----------------------------------------------------------------*/
5419 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5424 expr = isShiftRightLitVal_BitAndLitVal(tree);
5427 if (AST_ULONG_VALUE (tree->right) != 1)
5429 count = tree->left->right;
5431 if (!expr && (resultType == RESULT_TYPE_BIT))
5433 int p2 = isBitAndPow2 (tree);
5437 count = newAst_VALUE (valueFromLit (p2));
5443 /* make sure the port supports GETABIT */
5444 if (port->hasExtBitOp
5445 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5448 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5452 /*-----------------------------------------------------------------*/
5453 /* optimizeGetByte - get a byte of the expression */
5454 /*-----------------------------------------------------------------*/
5456 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5462 expr = isShiftRightLitVal_BitAndLitVal(tree);
5465 i = AST_ULONG_VALUE (tree->left->right);
5466 count = tree->left->right;
5467 if (AST_ULONG_VALUE (tree->right) != 0xFF)
5470 if (!expr && resultType == RESULT_TYPE_CHAR)
5472 /* if this is a right shift over a multiple of 8 */
5473 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5475 i = AST_ULONG_VALUE (tree->right);
5476 count = tree->right;
5480 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5483 /* make sure the port supports GETBYTE */
5484 if (port->hasExtBitOp
5485 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5488 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5491 /*-----------------------------------------------------------------*/
5492 /* optimizeGetWord - get two bytes of the expression */
5493 /*-----------------------------------------------------------------*/
5495 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5501 expr = isShiftRightLitVal_BitAndLitVal(tree);
5504 i = AST_ULONG_VALUE (tree->left->right);
5505 count = tree->left->right;
5506 if (AST_ULONG_VALUE (tree->right) != 0xFFFF)
5509 if (!expr && resultType == RESULT_TYPE_INT)
5511 /* if this is a right shift over a multiple of 8 */
5512 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5514 i = AST_ULONG_VALUE (tree->right);
5515 count = tree->right;
5519 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5522 /* make sure the port supports GETWORD */
5523 if (port->hasExtBitOp
5524 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5527 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5530 /*-----------------------------------------------------------------*/
5531 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5532 /*-----------------------------------------------------------------*/
5534 optimizeRRCRLC (ast * root)
5536 /* will look for trees of the form
5537 (?expr << 1) | (?expr >> 7) or
5538 (?expr >> 7) | (?expr << 1) will make that
5539 into a RLC : operation ..
5541 (?expr >> 1) | (?expr << 7) or
5542 (?expr << 7) | (?expr >> 1) will make that
5543 into a RRC operation
5544 note : by 7 I mean (number of bits required to hold the
5546 /* if the root operation is not a | operation then not */
5547 if (!IS_BITOR (root))
5550 /* I have to think of a better way to match patterns this sucks */
5551 /* that aside let's start looking for the first case : I use a
5552 negative check a lot to improve the efficiency */
5553 /* (?expr << 1) | (?expr >> 7) */
5554 if (IS_LEFT_OP (root->left) &&
5555 IS_RIGHT_OP (root->right))
5558 if (!SPEC_USIGN (TETYPE (root->left->left)))
5561 if (!IS_AST_LIT_VALUE (root->left->right) ||
5562 !IS_AST_LIT_VALUE (root->right->right))
5565 /* make sure it is the same expression */
5566 if (!isAstEqual (root->left->left,
5570 if (AST_ULONG_VALUE (root->left->right) != 1)
5573 if (AST_ULONG_VALUE (root->right->right) !=
5574 (getSize (TTYPE (root->left->left)) * 8 - 1))
5577 /* make sure the port supports RLC */
5578 if (port->hasExtBitOp
5579 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5582 /* whew got the first case : create the AST */
5583 return newNode (RLC, root->left->left, NULL);
5587 /* check for second case */
5588 /* (?expr >> 7) | (?expr << 1) */
5589 if (IS_LEFT_OP (root->right) &&
5590 IS_RIGHT_OP (root->left))
5593 if (!SPEC_USIGN (TETYPE (root->left->left)))
5596 if (!IS_AST_LIT_VALUE (root->left->right) ||
5597 !IS_AST_LIT_VALUE (root->right->right))
5600 /* make sure it is the same symbol */
5601 if (!isAstEqual (root->left->left,
5605 if (AST_ULONG_VALUE (root->right->right) != 1)
5608 if (AST_ULONG_VALUE (root->left->right) !=
5609 (getSize (TTYPE (root->left->left)) * 8 - 1))
5612 /* make sure the port supports RLC */
5613 if (port->hasExtBitOp
5614 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5617 /* whew got the first case : create the AST */
5618 return newNode (RLC, root->left->left, NULL);
5623 /* third case for RRC */
5624 /* (?symbol >> 1) | (?symbol << 7) */
5625 if (IS_LEFT_OP (root->right) &&
5626 IS_RIGHT_OP (root->left))
5629 if (!SPEC_USIGN (TETYPE (root->left->left)))
5632 if (!IS_AST_LIT_VALUE (root->left->right) ||
5633 !IS_AST_LIT_VALUE (root->right->right))
5636 /* make sure it is the same symbol */
5637 if (!isAstEqual (root->left->left,
5641 if (AST_ULONG_VALUE (root->left->right) != 1)
5644 if (AST_ULONG_VALUE (root->right->right) !=
5645 (getSize (TTYPE (root->left->left)) * 8 - 1))
5648 /* make sure the port supports RRC */
5649 if (port->hasExtBitOp
5650 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5653 /* whew got the first case : create the AST */
5654 return newNode (RRC, root->left->left, NULL);
5658 /* fourth and last case for now */
5659 /* (?symbol << 7) | (?symbol >> 1) */
5660 if (IS_RIGHT_OP (root->right) &&
5661 IS_LEFT_OP (root->left))
5664 if (!SPEC_USIGN (TETYPE (root->left->left)))
5667 if (!IS_AST_LIT_VALUE (root->left->right) ||
5668 !IS_AST_LIT_VALUE (root->right->right))
5671 /* make sure it is the same symbol */
5672 if (!isAstEqual (root->left->left,
5676 if (AST_ULONG_VALUE (root->right->right) != 1)
5679 if (AST_ULONG_VALUE (root->left->right) !=
5680 (getSize (TTYPE (root->left->left)) * 8 - 1))
5683 /* make sure the port supports RRC */
5684 if (port->hasExtBitOp
5685 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5688 /* whew got the first case : create the AST */
5689 return newNode (RRC, root->left->left, NULL);
5693 /* not found return root */
5697 /*-----------------------------------------------------------------*/
5698 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5699 /*-----------------------------------------------------------------*/
5701 optimizeSWAP (ast * root)
5703 /* will look for trees of the form
5704 (?expr << 4) | (?expr >> 4) or
5705 (?expr >> 4) | (?expr << 4) will make that
5706 into a SWAP : operation ..
5707 note : by 4 I mean (number of bits required to hold the
5709 /* if the root operation is not a | operation then not */
5710 if (!IS_BITOR (root))
5713 /* (?expr << 4) | (?expr >> 4) */
5714 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5715 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5718 if (!SPEC_USIGN (TETYPE (root->left->left)))
5721 if (!IS_AST_LIT_VALUE (root->left->right) ||
5722 !IS_AST_LIT_VALUE (root->right->right))
5725 /* make sure it is the same expression */
5726 if (!isAstEqual (root->left->left,
5730 if (AST_ULONG_VALUE (root->left->right) !=
5731 (getSize (TTYPE (root->left->left)) * 4))
5734 if (AST_ULONG_VALUE (root->right->right) !=
5735 (getSize (TTYPE (root->left->left)) * 4))
5738 /* make sure the port supports SWAP */
5739 if (port->hasExtBitOp
5740 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5743 /* found it : create the AST */
5744 return newNode (SWAP, root->left->left, NULL);
5748 /* not found return root */
5752 /*-----------------------------------------------------------------*/
5753 /* optimizeCompare - optimizes compares for bit variables */
5754 /*-----------------------------------------------------------------*/
5756 optimizeCompare (ast * root)
5758 ast *optExpr = NULL;
5761 unsigned int litValue;
5763 /* if nothing then return nothing */
5767 /* if not a compare op then do leaves */
5768 if (!IS_COMPARE_OP (root))
5770 root->left = optimizeCompare (root->left);
5771 root->right = optimizeCompare (root->right);
5775 /* if left & right are the same then depending
5776 of the operation do */
5777 if (isAstEqual (root->left, root->right))
5779 switch (root->opval.op)
5784 optExpr = newAst_VALUE (constVal ("0"));
5789 optExpr = newAst_VALUE (constVal ("1"));
5793 return decorateType (optExpr, RESULT_TYPE_NONE);
5796 vleft = (root->left->type == EX_VALUE ?
5797 root->left->opval.val : NULL);
5799 vright = (root->right->type == EX_VALUE ?
5800 root->right->opval.val : NULL);
5802 /* if left is a BITVAR in BITSPACE */
5803 /* and right is a LITERAL then */
5804 /* optimize else do nothing */
5805 if (vleft && vright &&
5806 IS_BITVAR (vleft->etype) &&
5807 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5808 IS_LITERAL (vright->etype))
5811 /* if right side > 1 then comparison may never succeed */
5812 if ((litValue = (int) ulFromVal (vright)) > 1)
5814 werror (W_BAD_COMPARE);
5820 switch (root->opval.op)
5822 case '>': /* bit value greater than 1 cannot be */
5823 werror (W_BAD_COMPARE);
5827 case '<': /* bit value < 1 means 0 */
5829 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5832 case LE_OP: /* bit value <= 1 means no check */
5833 optExpr = newAst_VALUE (vright);
5836 case GE_OP: /* bit value >= 1 means only check for = */
5838 optExpr = newAst_VALUE (vleft);
5843 { /* literal is zero */
5844 switch (root->opval.op)
5846 case '<': /* bit value < 0 cannot be */
5847 werror (W_BAD_COMPARE);
5851 case '>': /* bit value > 0 means 1 */
5853 optExpr = newAst_VALUE (vleft);
5856 case LE_OP: /* bit value <= 0 means no check */
5857 case GE_OP: /* bit value >= 0 means no check */
5858 werror (W_BAD_COMPARE);
5862 case EQ_OP: /* bit == 0 means ! of bit */
5863 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5867 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5868 } /* end-of-if of BITVAR */
5874 /*-----------------------------------------------------------------*/
5875 /* addSymToBlock : adds the symbol to the first block we find */
5876 /*-----------------------------------------------------------------*/
5878 addSymToBlock (symbol * sym, ast * tree)
5880 /* reached end of tree or a leaf */
5881 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5885 if (IS_AST_OP (tree) &&
5886 tree->opval.op == BLOCK)
5889 symbol *lsym = copySymbol (sym);
5891 lsym->next = AST_VALUES (tree, sym);
5892 AST_VALUES (tree, sym) = lsym;
5896 addSymToBlock (sym, tree->left);
5897 addSymToBlock (sym, tree->right);
5900 /*-----------------------------------------------------------------*/
5901 /* processRegParms - do processing for register parameters */
5902 /*-----------------------------------------------------------------*/
5904 processRegParms (value * args, ast * body)
5908 if (IS_REGPARM (args->etype))
5909 addSymToBlock (args->sym, body);
5914 /*-----------------------------------------------------------------*/
5915 /* resetParmKey - resets the operandkeys for the symbols */
5916 /*-----------------------------------------------------------------*/
5917 DEFSETFUNC (resetParmKey)
5930 /*------------------------------------------------------------------*/
5931 /* fixupInlineLabel - change a label in an inlined function so that */
5932 /* it is always unique no matter how many times */
5933 /* the function is inlined. */
5934 /*------------------------------------------------------------------*/
5936 fixupInlineLabel (symbol * sym)
5938 char name[SDCC_NAME_MAX + 1];
5940 SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
5941 strcpy (sym->name, name);
5945 /*------------------------------------------------------------------*/
5946 /* copyAstLoc - copy location information (file, line, block, etc.) */
5947 /* from one ast node to another */
5948 /*------------------------------------------------------------------*/
5950 copyAstLoc (ast * dest, ast * src)
5952 dest->lineno = src->lineno;
5953 dest->filename = src->filename;
5954 dest->level = src->level;
5955 dest->block = src->block;
5956 dest->seqPoint = src->seqPoint;
5961 /*-----------------------------------------------------------------*/
5962 /* fixupInline - perform various fixups on an inline function tree */
5963 /* to take into account that it is no longer a */
5964 /* stand-alone function. */
5965 /*-----------------------------------------------------------------*/
5967 fixupInline (ast * tree, int level)
5969 tree->block = currBlockno;
5971 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
5978 /* Add any declared variables back into the symbol table */
5979 decls = tree->values.sym;
5982 decls->level = level;
5983 decls->block = currBlockno;
5984 addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0);
5985 decls = decls->next;
5989 tree->level = level;
5991 /* Update symbols */
5992 if (IS_AST_VALUE (tree) &&
5993 tree->opval.val->sym)
5995 symbol * sym = tree->opval.val->sym;
5998 sym->block = currBlockno;
6001 SYM_SPIL_LOC (sym) = NULL;
6004 /* If the symbol is a label, we need to renumber it */
6006 fixupInlineLabel (sym);
6009 /* Update IFX target labels */
6010 if (tree->type == EX_OP && tree->opval.op == IFX)
6012 if (tree->trueLabel)
6013 fixupInlineLabel (tree->trueLabel);
6014 if (tree->falseLabel)
6015 fixupInlineLabel (tree->falseLabel);
6018 /* Replace RETURN with optional assignment and a GOTO to the end */
6019 /* of the inlined function */
6020 if (tree->type == EX_OP && tree->opval.op == RETURN)
6022 ast * assignTree = NULL;
6025 if (inlineState.retsym && tree->right)
6027 assignTree = newNode ('=',
6028 newAst_VALUE (symbolVal (inlineState.retsym)),
6030 copyAstLoc (assignTree, tree);
6033 gotoTree = newNode (GOTO,
6034 newAst_VALUE (symbolVal (inlineState.retlab)),
6036 copyAstLoc (gotoTree, tree);
6038 tree->opval.op = NULLOP;
6039 tree->left = assignTree;
6040 tree->right = gotoTree;
6043 /* Update any children */
6045 fixupInline (tree->left, level);
6047 fixupInline (tree->right, level);
6049 if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
6051 symbol * label = tree->left->opval.val->sym;
6053 label->key = labelKey++;
6054 /* Add this label back into the symbol table */
6055 addSym (LabelTab, label, label->name, label->level, 0, 0);
6059 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
6065 /*-----------------------------------------------------------------*/
6066 /* inlineAddDecl - add a variable declaration to an ast block. It */
6067 /* is also added to the symbol table if addSymTab */
6069 /*-----------------------------------------------------------------*/
6071 inlineAddDecl (symbol * sym, ast * block, int addSymTab)
6074 SYM_SPIL_LOC (sym) = NULL;
6078 symbol **decl = &(block->values.sym);
6080 sym->level = block->level;
6081 sym->block = block->block;
6085 if (strcmp ((*decl)->name, sym->name) == 0)
6087 decl = &( (*decl)->next );
6093 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0);
6099 /*-----------------------------------------------------------------*/
6100 /* inlineTempVar - create a temporary variable for inlining */
6101 /*-----------------------------------------------------------------*/
6103 inlineTempVar (sym_link * type, int level)
6107 sym = newSymbol (genSymName(level), level );
6108 sym->type = copyLinkChain (type);
6109 sym->etype = getSpec(sym->type);
6110 SPEC_SCLS (sym->etype) = S_AUTO;
6111 SPEC_OCLS (sym->etype) = NULL;
6112 SPEC_EXTR (sym->etype) = 0;
6113 SPEC_STAT (sym->etype) = 0;
6114 if IS_SPEC (sym->type)
6115 SPEC_VOLATILE (sym->type) = 0;
6117 DCL_PTR_VOLATILE (sym->type) = 0;
6118 SPEC_ABSA (sym->etype) = 0;
6124 /*-----------------------------------------------------------------*/
6125 /* inlineFindParmRecurse - recursive function for inlineFindParm */
6126 /*-----------------------------------------------------------------*/
6128 inlineFindParmRecurse (ast * parms, int *index)
6133 if (parms->type == EX_OP && parms->opval.op == PARAM)
6137 p=inlineFindParmRecurse (parms->left, index);
6140 p=inlineFindParmRecurse (parms->right, index);
6151 /*-----------------------------------------------------------------*/
6152 /* inlineFindParm - search an ast tree of parameters to find one */
6153 /* at a particular index (0=first parameter). */
6154 /* Returns NULL if not found. */
6155 /*-----------------------------------------------------------------*/
6157 inlineFindParm (ast * parms, int index)
6159 return inlineFindParmRecurse (parms, &index);
6162 /*-----------------------------------------------------------------*/
6163 /* inlineFindMaxBlockno - find maximum block number in an ast tree */
6164 /*-----------------------------------------------------------------*/
6166 inlineFindMaxBlockno (ast * tree, int maxBlockno)
6173 tempBlockno = inlineFindMaxBlockno (tree->left, maxBlockno);
6174 if (tempBlockno > maxBlockno)
6175 maxBlockno = tempBlockno;
6177 tempBlockno = inlineFindMaxBlockno (tree->right, maxBlockno);
6178 if (tempBlockno > maxBlockno)
6179 maxBlockno = tempBlockno;
6181 if (tree->block > maxBlockno)
6182 maxBlockno = tree->block;
6189 /*-----------------------------------------------------------------*/
6190 /* expandInlineFuncs - replace calls to inline functions with the */
6191 /* function itself */
6192 /*-----------------------------------------------------------------*/
6194 expandInlineFuncs (ast * tree, ast * block)
6196 if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left
6197 && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym)
6199 symbol * func = tree->left->opval.val->sym;
6202 /* The symbol is probably not bound yet, so find the real one */
6203 csym = findSymWithLevel (SymbolTab, func);
6207 /* Is this an inline function that we can inline? */
6208 if (IFFUNC_ISINLINE (func->type) && func->funcTree)
6210 symbol * retsym = NULL;
6218 /* Generate a label for the inlined function to branch to */
6219 /* in case it contains a return statement */
6220 retlab = newSymbol (genSymName(tree->level+1), tree->level+1 );
6223 inlineState.retlab = retlab;
6225 /* Build the subtree for the inlined function in the form: */
6226 /* { //inlinetree block */
6227 /* { //inlinetree2 block */
6228 /* inline_function_code; */
6232 temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL);
6233 copyAstLoc (temptree, tree);
6234 temptree = newNode (NULLOP, copyAst (func->funcTree), temptree);
6235 copyAstLoc (temptree, tree);
6236 temptree = newNode (BLOCK, NULL, temptree);
6237 copyAstLoc (temptree, tree);
6238 inlinetree2 = temptree;
6239 inlinetree = newNode (BLOCK, NULL, inlinetree2);
6240 copyAstLoc (inlinetree, tree);
6242 /* To pass parameters to the inlined function, we need some */
6243 /* intermediate variables. This avoids scoping problems */
6244 /* when the parameter declaration names are used differently */
6245 /* during the function call. For example, a function */
6246 /* declared as func(int x, int y) but called as func(y,x). */
6247 /* { //inlinetree block */
6248 /* type1 temparg1; */
6250 /* typen tempargn; */
6251 /* temparg1 = argument1; */
6253 /* tempargn = argumentn; */
6254 /* { //inlinetree2 block */
6258 /* param1 = temparg1; */
6260 /* paramn = tempargn; */
6261 /* inline_function_code; */
6265 args = FUNC_ARGS (func->type);
6272 symbol * parm = copySymbol (args->sym);
6274 temparg = inlineTempVar (args->sym->type, tree->level+1);
6275 inlineAddDecl (temparg, inlinetree, FALSE);
6277 passedarg = inlineFindParm (tree->right, argIndex);
6278 assigntree = newNode ('=',
6279 newAst_VALUE (symbolVal (temparg)),
6281 inlinetree->right = newNode (NULLOP,
6285 inlineAddDecl (parm, inlinetree2, FALSE);
6288 assigntree = newNode ('=',
6289 newAst_VALUE (symbolVal (parm)),
6290 newAst_VALUE (symbolVal (temparg)));
6291 inlinetree2->right = newNode (NULLOP,
6293 inlinetree2->right);
6300 /* Handle the return type */
6301 if (!IS_VOID (func->type->next))
6303 /* Create a temporary symbol to hold the return value and */
6304 /* join it with the inlined function using the comma */
6305 /* operator. The fixupInline function will take care of */
6306 /* changing return statements into assignments to retsym. */
6307 /* (parameter passing and return label omitted for clarity) */
6308 /* rettype retsym; */
6310 /* {{inline_function_code}}, retsym */
6312 retsym = inlineTempVar (func->type->next, tree->level);
6313 inlineAddDecl (retsym, block, TRUE);
6315 tree->opval.op = ',';
6316 tree->left = inlinetree;
6317 tree->right = newAst_VALUE (symbolVal (retsym));
6321 tree->opval.op = NULLOP;
6323 tree->right = inlinetree;
6325 inlineState.retsym = retsym;
6327 /* Renumber the various internal counters on the inlined */
6328 /* function's tree nodes and symbols. Add the inlined */
6329 /* function's local variables to the appropriate scope(s). */
6330 /* Convert inlined return statements to an assignment to */
6331 /* retsym (if needed) and a goto retlab. */
6332 fixupInline (inlinetree, inlinetree->level);
6333 inlineState.count++;
6338 /* Recursively continue to search for functions to inline. */
6339 if (IS_AST_OP (tree))
6341 if (tree->opval.op == BLOCK)
6345 expandInlineFuncs (tree->left, block);
6347 expandInlineFuncs (tree->right, block);
6352 /*-----------------------------------------------------------------*/
6353 /* createFunction - This is the key node that calls the iCode for */
6354 /* generating the code for a function. Note code */
6355 /* is generated function by function, later when */
6356 /* add inter-procedural analysis this will change */
6357 /*-----------------------------------------------------------------*/
6359 createFunction (symbol * name, ast * body)
6365 iCode *piCode = NULL;
6368 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
6369 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
6371 /* if check function return 0 then some problem */
6372 if (checkFunction (name, NULL) == 0)
6375 /* create a dummy block if none exists */
6377 body = newNode (BLOCK, NULL, NULL);
6381 /* check if the function name already in the symbol table */
6382 if ((csym = findSym (SymbolTab, NULL, name->name)))
6385 /* special case for compiler defined functions
6386 we need to add the name to the publics list : this
6387 actually means we are now compiling the compiler
6391 addSet (&publics, name);
6396 addSymChain (&name);
6397 allocVariables (name);
6399 name->lastLine = lexLineno;
6402 /* set the stack pointer */
6403 stackPtr = -port->stack.direction * port->stack.call_overhead;
6406 if (IFFUNC_ISISR (name->type))
6407 stackPtr -= port->stack.direction * port->stack.isr_overhead;
6409 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
6411 if (options.useXstack)
6412 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
6414 stackPtr -= port->stack.direction * port->stack.reent_overhead;
6417 fetype = getSpec (name->type); /* get the specifier for the function */
6418 /* if this is a reentrant function then */
6419 if (IFFUNC_ISREENT (name->type))
6422 inlineState.count = 0;
6423 savedBlockno = currBlockno;
6424 currBlockno = inlineFindMaxBlockno (body, 0);
6425 expandInlineFuncs (body, NULL);
6426 currBlockno = savedBlockno;
6428 if (FUNC_ISINLINE (name->type))
6429 name->funcTree = copyAst (body);
6431 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
6433 /* do processing for parameters that are passed in registers */
6434 processRegParms (FUNC_ARGS(name->type), body);
6436 /* set the stack pointer */
6440 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
6442 /* allocate & autoinit the block variables */
6443 processBlockVars (body, &stack, ALLOCATE);
6445 /* name needs to be mangled */
6446 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
6448 body = resolveSymbols (body); /* resolve the symbols */
6449 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
6451 /* save the stack information */
6452 if (options.useXstack)
6453 name->xstack = SPEC_STAK (fetype) = stack;
6455 name->stack = SPEC_STAK (fetype) = stack;
6457 ex = newAst_VALUE (symbolVal (name)); /* create name */
6458 ex = newNode (FUNCTION, ex, body);
6459 ex->values.args = FUNC_ARGS(name->type);
6461 if (options.dump_tree)
6466 /* Do not generate code for inline functions unless extern also. */
6468 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
6471 /* Temporary hack: always generate code for static inline functions. */
6472 /* Ideally static inline functions should only be generated if needed. */
6473 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype) && !IS_STATIC (fetype))
6477 /* create the node & generate intermediate code */
6479 codeOutBuf = &code->oBuf;
6480 piCode = iCodeFromAst (ex);
6481 name->generated = 1;
6486 eBBlockFromiCode (piCode);
6488 /* if there are any statics then do them */
6491 GcurMemmap = statsg;
6492 codeOutBuf = &statsg->oBuf;
6493 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6499 /* dealloc the block variables */
6500 processBlockVars (body, &stack, DEALLOCATE);
6501 outputDebugStackSymbols();
6502 /* deallocate paramaters */
6503 deallocParms (FUNC_ARGS(name->type));
6505 if (IFFUNC_ISREENT (name->type))
6508 /* we are done freeup memory & cleanup */
6510 if (port->reset_labelKey) labelKey = 1;
6512 FUNC_HASBODY(name->type) = 1;
6513 addSet (&operKeyReset, name);
6514 applyToSet (operKeyReset, resetParmKey);
6519 cleanUpLevel (LabelTab, 0);
6520 cleanUpBlock (StructTab, 1);
6521 cleanUpBlock (TypedefTab, 1);
6523 xstack->syms = NULL;
6524 istack->syms = NULL;
6529 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6530 /*-----------------------------------------------------------------*/
6531 /* ast_print : prints the ast (for debugging purposes) */
6532 /*-----------------------------------------------------------------*/
6534 void ast_print (ast * tree, FILE *outfile, int indent)
6539 /* can print only decorated trees */
6540 if (!tree->decorated) return;
6542 /* if any child is an error | this one is an error do nothing */
6543 if (tree->isError ||
6544 (tree->left && tree->left->isError) ||
6545 (tree->right && tree->right->isError)) {
6546 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6550 /* print the line */
6551 /* if not block & function */
6552 if (tree->type == EX_OP &&
6553 (tree->opval.op != FUNCTION &&
6554 tree->opval.op != BLOCK &&
6555 tree->opval.op != NULLOP)) {
6558 if (tree->opval.op == FUNCTION) {
6560 value *args=FUNC_ARGS(tree->left->opval.val->type);
6561 fprintf(outfile,"FUNCTION (%s=%p) type (",
6562 tree->left->opval.val->name, tree);
6563 printTypeChain (tree->left->opval.val->type->next,outfile);
6564 fprintf(outfile,") args (");
6567 fprintf (outfile, ", ");
6569 printTypeChain (args ? args->type : NULL, outfile);
6571 args= args ? args->next : NULL;
6573 fprintf(outfile,")\n");
6574 ast_print(tree->left,outfile,indent);
6575 ast_print(tree->right,outfile,indent);
6578 if (tree->opval.op == BLOCK) {
6579 symbol *decls = tree->values.sym;
6580 INDENT(indent,outfile);
6581 fprintf(outfile,"{\n");
6583 INDENT(indent+2,outfile);
6584 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6585 decls->name, decls);
6586 printTypeChain(decls->type,outfile);
6587 fprintf(outfile,")\n");
6589 decls = decls->next;
6591 ast_print(tree->right,outfile,indent+2);
6592 INDENT(indent,outfile);
6593 fprintf(outfile,"}\n");
6596 if (tree->opval.op == NULLOP) {
6597 ast_print(tree->left,outfile,indent);
6598 ast_print(tree->right,outfile,indent);
6601 INDENT(indent,outfile);
6603 /*------------------------------------------------------------------*/
6604 /*----------------------------*/
6605 /* leaf has been reached */
6606 /*----------------------------*/
6607 /* if this is of type value */
6608 /* just get the type */
6609 if (tree->type == EX_VALUE) {
6611 if (IS_LITERAL (tree->opval.val->etype)) {
6612 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6613 if (SPEC_USIGN (tree->opval.val->etype))
6614 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val));
6616 fprintf(outfile,"%d", (TYPE_TARGET_LONG) ulFromVal(tree->opval.val));
6617 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val),
6618 floatFromVal(tree->opval.val));
6619 } else if (tree->opval.val->sym) {
6620 /* if the undefined flag is set then give error message */
6621 if (tree->opval.val->sym->undefined) {
6622 fprintf(outfile,"UNDEFINED SYMBOL ");
6624 fprintf(outfile,"SYMBOL ");
6626 fprintf(outfile,"(%s=%p @ %p)",
6627 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6630 fprintf(outfile," type (");
6631 printTypeChain(tree->ftype,outfile);
6632 fprintf(outfile,")\n");
6634 fprintf(outfile,"\n");
6639 /* if type link for the case of cast */
6640 if (tree->type == EX_LINK) {
6641 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6642 printTypeChain(tree->opval.lnk,outfile);
6643 fprintf(outfile,")\n");
6648 /* depending on type of operator do */
6650 switch (tree->opval.op) {
6651 /*------------------------------------------------------------------*/
6652 /*----------------------------*/
6654 /*----------------------------*/
6656 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6657 printTypeChain(tree->ftype,outfile);
6658 fprintf(outfile,")\n");
6659 ast_print(tree->left,outfile,indent+2);
6660 ast_print(tree->right,outfile,indent+2);
6663 /*------------------------------------------------------------------*/
6664 /*----------------------------*/
6666 /*----------------------------*/
6668 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6669 printTypeChain(tree->ftype,outfile);
6670 fprintf(outfile,")\n");
6671 ast_print(tree->left,outfile,indent+2);
6672 ast_print(tree->right,outfile,indent+2);
6675 /*------------------------------------------------------------------*/
6676 /*----------------------------*/
6677 /* struct/union pointer */
6678 /*----------------------------*/
6680 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6681 printTypeChain(tree->ftype,outfile);
6682 fprintf(outfile,")\n");
6683 ast_print(tree->left,outfile,indent+2);
6684 ast_print(tree->right,outfile,indent+2);
6687 /*------------------------------------------------------------------*/
6688 /*----------------------------*/
6689 /* ++/-- operation */
6690 /*----------------------------*/
6693 fprintf(outfile,"post-");
6695 fprintf(outfile,"pre-");
6696 fprintf(outfile,"INC_OP (%p) type (",tree);
6697 printTypeChain(tree->ftype,outfile);
6698 fprintf(outfile,")\n");
6699 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6700 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6705 fprintf(outfile,"post-");
6707 fprintf(outfile,"pre-");
6708 fprintf(outfile,"DEC_OP (%p) type (",tree);
6709 printTypeChain(tree->ftype,outfile);
6710 fprintf(outfile,")\n");
6711 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6712 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6715 /*------------------------------------------------------------------*/
6716 /*----------------------------*/
6718 /*----------------------------*/
6721 fprintf(outfile,"& (%p) type (",tree);
6722 printTypeChain(tree->ftype,outfile);
6723 fprintf(outfile,")\n");
6724 ast_print(tree->left,outfile,indent+2);
6725 ast_print(tree->right,outfile,indent+2);
6727 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6728 printTypeChain(tree->ftype,outfile);
6729 fprintf(outfile,")\n");
6730 ast_print(tree->left,outfile,indent+2);
6731 ast_print(tree->right,outfile,indent+2);
6734 /*----------------------------*/
6736 /*----------------------------*/
6738 fprintf(outfile,"OR (%p) type (",tree);
6739 printTypeChain(tree->ftype,outfile);
6740 fprintf(outfile,")\n");
6741 ast_print(tree->left,outfile,indent+2);
6742 ast_print(tree->right,outfile,indent+2);
6744 /*------------------------------------------------------------------*/
6745 /*----------------------------*/
6747 /*----------------------------*/
6749 fprintf(outfile,"XOR (%p) type (",tree);
6750 printTypeChain(tree->ftype,outfile);
6751 fprintf(outfile,")\n");
6752 ast_print(tree->left,outfile,indent+2);
6753 ast_print(tree->right,outfile,indent+2);
6756 /*------------------------------------------------------------------*/
6757 /*----------------------------*/
6759 /*----------------------------*/
6761 fprintf(outfile,"DIV (%p) type (",tree);
6762 printTypeChain(tree->ftype,outfile);
6763 fprintf(outfile,")\n");
6764 ast_print(tree->left,outfile,indent+2);
6765 ast_print(tree->right,outfile,indent+2);
6767 /*------------------------------------------------------------------*/
6768 /*----------------------------*/
6770 /*----------------------------*/
6772 fprintf(outfile,"MOD (%p) type (",tree);
6773 printTypeChain(tree->ftype,outfile);
6774 fprintf(outfile,")\n");
6775 ast_print(tree->left,outfile,indent+2);
6776 ast_print(tree->right,outfile,indent+2);
6779 /*------------------------------------------------------------------*/
6780 /*----------------------------*/
6781 /* address dereference */
6782 /*----------------------------*/
6783 case '*': /* can be unary : if right is null then unary operation */
6785 fprintf(outfile,"DEREF (%p) type (",tree);
6786 printTypeChain(tree->ftype,outfile);
6787 fprintf(outfile,")\n");
6788 ast_print(tree->left,outfile,indent+2);
6791 /*------------------------------------------------------------------*/
6792 /*----------------------------*/
6793 /* multiplication */
6794 /*----------------------------*/
6795 fprintf(outfile,"MULT (%p) type (",tree);
6796 printTypeChain(tree->ftype,outfile);
6797 fprintf(outfile,")\n");
6798 ast_print(tree->left,outfile,indent+2);
6799 ast_print(tree->right,outfile,indent+2);
6803 /*------------------------------------------------------------------*/
6804 /*----------------------------*/
6805 /* unary '+' operator */
6806 /*----------------------------*/
6810 fprintf(outfile,"UPLUS (%p) type (",tree);
6811 printTypeChain(tree->ftype,outfile);
6812 fprintf(outfile,")\n");
6813 ast_print(tree->left,outfile,indent+2);
6815 /*------------------------------------------------------------------*/
6816 /*----------------------------*/
6818 /*----------------------------*/
6819 fprintf(outfile,"ADD (%p) type (",tree);
6820 printTypeChain(tree->ftype,outfile);
6821 fprintf(outfile,")\n");
6822 ast_print(tree->left,outfile,indent+2);
6823 ast_print(tree->right,outfile,indent+2);
6826 /*------------------------------------------------------------------*/
6827 /*----------------------------*/
6829 /*----------------------------*/
6830 case '-': /* can be unary */
6832 fprintf(outfile,"UMINUS (%p) type (",tree);
6833 printTypeChain(tree->ftype,outfile);
6834 fprintf(outfile,")\n");
6835 ast_print(tree->left,outfile,indent+2);
6837 /*------------------------------------------------------------------*/
6838 /*----------------------------*/
6840 /*----------------------------*/
6841 fprintf(outfile,"SUB (%p) type (",tree);
6842 printTypeChain(tree->ftype,outfile);
6843 fprintf(outfile,")\n");
6844 ast_print(tree->left,outfile,indent+2);
6845 ast_print(tree->right,outfile,indent+2);
6848 /*------------------------------------------------------------------*/
6849 /*----------------------------*/
6851 /*----------------------------*/
6853 fprintf(outfile,"COMPL (%p) type (",tree);
6854 printTypeChain(tree->ftype,outfile);
6855 fprintf(outfile,")\n");
6856 ast_print(tree->left,outfile,indent+2);
6858 /*------------------------------------------------------------------*/
6859 /*----------------------------*/
6861 /*----------------------------*/
6863 fprintf(outfile,"NOT (%p) type (",tree);
6864 printTypeChain(tree->ftype,outfile);
6865 fprintf(outfile,")\n");
6866 ast_print(tree->left,outfile,indent+2);
6868 /*------------------------------------------------------------------*/
6869 /*----------------------------*/
6871 /*----------------------------*/
6873 fprintf(outfile,"RRC (%p) type (",tree);
6874 printTypeChain(tree->ftype,outfile);
6875 fprintf(outfile,")\n");
6876 ast_print(tree->left,outfile,indent+2);
6880 fprintf(outfile,"RLC (%p) type (",tree);
6881 printTypeChain(tree->ftype,outfile);
6882 fprintf(outfile,")\n");
6883 ast_print(tree->left,outfile,indent+2);
6886 fprintf(outfile,"SWAP (%p) type (",tree);
6887 printTypeChain(tree->ftype,outfile);
6888 fprintf(outfile,")\n");
6889 ast_print(tree->left,outfile,indent+2);
6892 fprintf(outfile,"GETHBIT (%p) type (",tree);
6893 printTypeChain(tree->ftype,outfile);
6894 fprintf(outfile,")\n");
6895 ast_print(tree->left,outfile,indent+2);
6898 fprintf(outfile,"GETABIT (%p) type (",tree);
6899 printTypeChain(tree->ftype,outfile);
6900 fprintf(outfile,")\n");
6901 ast_print(tree->left,outfile,indent+2);
6902 ast_print(tree->right,outfile,indent+2);
6905 fprintf(outfile,"GETBYTE (%p) type (",tree);
6906 printTypeChain(tree->ftype,outfile);
6907 fprintf(outfile,")\n");
6908 ast_print(tree->left,outfile,indent+2);
6909 ast_print(tree->right,outfile,indent+2);
6912 fprintf(outfile,"GETWORD (%p) type (",tree);
6913 printTypeChain(tree->ftype,outfile);
6914 fprintf(outfile,")\n");
6915 ast_print(tree->left,outfile,indent+2);
6916 ast_print(tree->right,outfile,indent+2);
6919 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6920 printTypeChain(tree->ftype,outfile);
6921 fprintf(outfile,")\n");
6922 ast_print(tree->left,outfile,indent+2);
6923 ast_print(tree->right,outfile,indent+2);
6926 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6927 printTypeChain(tree->ftype,outfile);
6928 fprintf(outfile,")\n");
6929 ast_print(tree->left,outfile,indent+2);
6930 ast_print(tree->right,outfile,indent+2);
6932 /*------------------------------------------------------------------*/
6933 /*----------------------------*/
6935 /*----------------------------*/
6936 case CAST: /* change the type */
6937 fprintf(outfile,"CAST (%p) from type (",tree);
6938 printTypeChain(tree->right->ftype,outfile);
6939 fprintf(outfile,") to type (");
6940 printTypeChain(tree->ftype,outfile);
6941 fprintf(outfile,")\n");
6942 ast_print(tree->right,outfile,indent+2);
6946 fprintf(outfile,"ANDAND (%p) type (",tree);
6947 printTypeChain(tree->ftype,outfile);
6948 fprintf(outfile,")\n");
6949 ast_print(tree->left,outfile,indent+2);
6950 ast_print(tree->right,outfile,indent+2);
6953 fprintf(outfile,"OROR (%p) type (",tree);
6954 printTypeChain(tree->ftype,outfile);
6955 fprintf(outfile,")\n");
6956 ast_print(tree->left,outfile,indent+2);
6957 ast_print(tree->right,outfile,indent+2);
6960 /*------------------------------------------------------------------*/
6961 /*----------------------------*/
6962 /* comparison operators */
6963 /*----------------------------*/
6965 fprintf(outfile,"GT(>) (%p) type (",tree);
6966 printTypeChain(tree->ftype,outfile);
6967 fprintf(outfile,")\n");
6968 ast_print(tree->left,outfile,indent+2);
6969 ast_print(tree->right,outfile,indent+2);
6972 fprintf(outfile,"LT(<) (%p) type (",tree);
6973 printTypeChain(tree->ftype,outfile);
6974 fprintf(outfile,")\n");
6975 ast_print(tree->left,outfile,indent+2);
6976 ast_print(tree->right,outfile,indent+2);
6979 fprintf(outfile,"LE(<=) (%p) type (",tree);
6980 printTypeChain(tree->ftype,outfile);
6981 fprintf(outfile,")\n");
6982 ast_print(tree->left,outfile,indent+2);
6983 ast_print(tree->right,outfile,indent+2);
6986 fprintf(outfile,"GE(>=) (%p) type (",tree);
6987 printTypeChain(tree->ftype,outfile);
6988 fprintf(outfile,")\n");
6989 ast_print(tree->left,outfile,indent+2);
6990 ast_print(tree->right,outfile,indent+2);
6993 fprintf(outfile,"EQ(==) (%p) type (",tree);
6994 printTypeChain(tree->ftype,outfile);
6995 fprintf(outfile,")\n");
6996 ast_print(tree->left,outfile,indent+2);
6997 ast_print(tree->right,outfile,indent+2);
7000 fprintf(outfile,"NE(!=) (%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);
7005 /*------------------------------------------------------------------*/
7006 /*----------------------------*/
7008 /*----------------------------*/
7009 case SIZEOF: /* evaluate wihout code generation */
7010 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
7013 /*------------------------------------------------------------------*/
7014 /*----------------------------*/
7015 /* conditional operator '?' */
7016 /*----------------------------*/
7018 fprintf(outfile,"QUEST(?) (%p) type (",tree);
7019 printTypeChain(tree->ftype,outfile);
7020 fprintf(outfile,")\n");
7021 ast_print(tree->left,outfile,indent+2);
7022 ast_print(tree->right,outfile,indent+2);
7026 fprintf(outfile,"COLON(:) (%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 /*------------------------------------------------------------------*/
7034 /*----------------------------*/
7035 /* assignment operators */
7036 /*----------------------------*/
7038 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
7039 printTypeChain(tree->ftype,outfile);
7040 fprintf(outfile,")\n");
7041 ast_print(tree->left,outfile,indent+2);
7042 ast_print(tree->right,outfile,indent+2);
7045 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
7046 printTypeChain(tree->ftype,outfile);
7047 fprintf(outfile,")\n");
7048 ast_print(tree->left,outfile,indent+2);
7049 ast_print(tree->right,outfile,indent+2);
7052 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
7053 printTypeChain(tree->ftype,outfile);
7054 fprintf(outfile,")\n");
7055 ast_print(tree->left,outfile,indent+2);
7056 ast_print(tree->right,outfile,indent+2);
7059 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
7060 printTypeChain(tree->ftype,outfile);
7061 fprintf(outfile,")\n");
7062 ast_print(tree->left,outfile,indent+2);
7063 ast_print(tree->right,outfile,indent+2);
7066 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
7067 printTypeChain(tree->ftype,outfile);
7068 fprintf(outfile,")\n");
7069 ast_print(tree->left,outfile,indent+2);
7070 ast_print(tree->right,outfile,indent+2);
7073 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
7074 printTypeChain(tree->ftype,outfile);
7075 fprintf(outfile,")\n");
7076 ast_print(tree->left,outfile,indent+2);
7077 ast_print(tree->right,outfile,indent+2);
7080 fprintf(outfile,"LSHFTASS(<<=) (%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);
7086 /*------------------------------------------------------------------*/
7087 /*----------------------------*/
7089 /*----------------------------*/
7091 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
7092 printTypeChain(tree->ftype,outfile);
7093 fprintf(outfile,")\n");
7094 ast_print(tree->left,outfile,indent+2);
7095 ast_print(tree->right,outfile,indent+2);
7097 /*------------------------------------------------------------------*/
7098 /*----------------------------*/
7100 /*----------------------------*/
7102 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
7103 printTypeChain(tree->ftype,outfile);
7104 fprintf(outfile,")\n");
7105 ast_print(tree->left,outfile,indent+2);
7106 ast_print(tree->right,outfile,indent+2);
7108 /*------------------------------------------------------------------*/
7109 /*----------------------------*/
7110 /* straight assignemnt */
7111 /*----------------------------*/
7113 fprintf(outfile,"ASSIGN(=) (%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);
7119 /*------------------------------------------------------------------*/
7120 /*----------------------------*/
7121 /* comma operator */
7122 /*----------------------------*/
7124 fprintf(outfile,"COMMA(,) (%p) type (",tree);
7125 printTypeChain(tree->ftype,outfile);
7126 fprintf(outfile,")\n");
7127 ast_print(tree->left,outfile,indent+2);
7128 ast_print(tree->right,outfile,indent+2);
7130 /*------------------------------------------------------------------*/
7131 /*----------------------------*/
7133 /*----------------------------*/
7136 fprintf(outfile,"CALL (%p) type (",tree);
7137 printTypeChain(tree->ftype,outfile);
7138 fprintf(outfile,")\n");
7139 ast_print(tree->left,outfile,indent+2);
7140 ast_print(tree->right,outfile,indent+2);
7143 fprintf(outfile,"PARMS\n");
7144 ast_print(tree->left,outfile,indent+2);
7145 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
7146 ast_print(tree->right,outfile,indent+2);
7149 /*------------------------------------------------------------------*/
7150 /*----------------------------*/
7151 /* return statement */
7152 /*----------------------------*/
7154 fprintf(outfile,"RETURN (%p) type (",tree);
7156 printTypeChain(tree->right->ftype,outfile);
7158 fprintf(outfile,")\n");
7159 ast_print(tree->right,outfile,indent+2);
7161 /*------------------------------------------------------------------*/
7162 /*----------------------------*/
7163 /* label statement */
7164 /*----------------------------*/
7166 fprintf(outfile,"LABEL (%p)\n",tree);
7167 ast_print(tree->left,outfile,indent+2);
7168 ast_print(tree->right,outfile,indent);
7170 /*------------------------------------------------------------------*/
7171 /*----------------------------*/
7172 /* switch statement */
7173 /*----------------------------*/
7177 fprintf(outfile,"SWITCH (%p) ",tree);
7178 ast_print(tree->left,outfile,0);
7179 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
7180 INDENT(indent+2,outfile);
7181 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
7182 (int) ulFromVal(val),
7183 tree->values.switchVals.swNum,
7184 (int) ulFromVal(val));
7186 ast_print(tree->right,outfile,indent);
7189 /*------------------------------------------------------------------*/
7190 /*----------------------------*/
7192 /*----------------------------*/
7194 fprintf(outfile,"IF (%p) \n",tree);
7195 ast_print(tree->left,outfile,indent+2);
7196 if (tree->trueLabel) {
7197 INDENT(indent+2,outfile);
7198 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
7200 if (tree->falseLabel) {
7201 INDENT(indent+2,outfile);
7202 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
7204 ast_print(tree->right,outfile,indent+2);
7206 /*----------------------------*/
7207 /* goto Statement */
7208 /*----------------------------*/
7210 fprintf(outfile,"GOTO (%p) \n",tree);
7211 ast_print(tree->left,outfile,indent+2);
7212 fprintf(outfile,"\n");
7214 /*------------------------------------------------------------------*/
7215 /*----------------------------*/
7217 /*----------------------------*/
7219 fprintf(outfile,"FOR (%p) \n",tree);
7220 if (AST_FOR( tree, initExpr)) {
7221 INDENT(indent+2,outfile);
7222 fprintf(outfile,"INIT EXPR ");
7223 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
7225 if (AST_FOR( tree, condExpr)) {
7226 INDENT(indent+2,outfile);
7227 fprintf(outfile,"COND EXPR ");
7228 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
7230 if (AST_FOR( tree, loopExpr)) {
7231 INDENT(indent+2,outfile);
7232 fprintf(outfile,"LOOP EXPR ");
7233 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
7235 fprintf(outfile,"FOR LOOP BODY \n");
7236 ast_print(tree->left,outfile,indent+2);
7239 fprintf(outfile,"CRITICAL (%p) \n",tree);
7240 ast_print(tree->left,outfile,indent+2);
7248 ast_print(t,stdout,0);
7251 /*-----------------------------------------------------------------*/
7252 /* astErrors : returns non-zero if errors present in tree */
7253 /*-----------------------------------------------------------------*/
7254 int astErrors(ast *t)
7263 if (t->type == EX_VALUE
7264 && t->opval.val->sym
7265 && t->opval.val->sym->undefined)
7268 errors += astErrors(t->left);
7269 errors += astErrors(t->right);