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));
394 } else if ((target->opval.op == INC_OP) || (target->opval.op == DEC_OP)) {
395 /* illegal pre/post-increment/decrement */
396 werrorfl (target->filename, target->lineno, E_LVALUE_REQUIRED, "=");
398 /* we would have to handle '.', but it is not generated any more */
399 wassertl(target->opval.op != '.', "obsolete opcode in tree");
401 /* no other kinds of ASTs are lvalues and can contain side effects */
406 writeval = copyAst(target);
408 result = newNode('=', writeval, newNode(op, readval, operand));
410 result = newNode(',', tempvar2, result);
412 result = newNode(',', tempvar1, result);
418 /*-----------------------------------------------------------------*/
419 /* hasSEFcalls - returns TRUE if tree has a function call, */
420 /* inc/decrement, or other side effect */
421 /*-----------------------------------------------------------------*/
423 hasSEFcalls (ast * tree)
428 if (tree->type == EX_OP &&
429 (tree->opval.op == CALL ||
430 tree->opval.op == PCALL ||
431 tree->opval.op == '=' ||
432 tree->opval.op == INC_OP ||
433 tree->opval.op == DEC_OP))
436 return (hasSEFcalls (tree->left) |
437 hasSEFcalls (tree->right));
440 /*-----------------------------------------------------------------*/
441 /* isAstEqual - compares two asts & returns 1 if they are equal */
442 /*-----------------------------------------------------------------*/
444 isAstEqual (ast * t1, ast * t2)
453 if (t1->type != t2->type)
459 if (t1->opval.op != t2->opval.op)
461 return (isAstEqual (t1->left, t2->left) &&
462 isAstEqual (t1->right, t2->right));
466 if (t1->opval.val->sym)
468 if (!t2->opval.val->sym)
471 return isSymbolEqual (t1->opval.val->sym,
476 if (t2->opval.val->sym)
479 return (floatFromVal (t1->opval.val) ==
480 floatFromVal (t2->opval.val));
484 /* only compare these two types */
492 /*-----------------------------------------------------------------*/
493 /* resolveSymbols - resolve symbols from the symbol table */
494 /*-----------------------------------------------------------------*/
496 resolveSymbols (ast * tree)
498 /* walk the entire tree and check for values */
499 /* with symbols if we find one then replace */
500 /* symbol with that from the symbol table */
507 /* if not block & function */
508 if (tree->type == EX_OP &&
509 (tree->opval.op != FUNCTION &&
510 tree->opval.op != BLOCK &&
511 tree->opval.op != NULLOP))
513 filename = tree->filename;
514 lineno = tree->lineno;
518 /* make sure we resolve the true & false labels for ifx */
519 if (tree->type == EX_OP && tree->opval.op == IFX)
525 if ((csym = findSym (LabelTab, tree->trueLabel,
526 tree->trueLabel->name)))
527 tree->trueLabel = csym;
529 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
530 tree->trueLabel->name);
533 if (tree->falseLabel)
535 if ((csym = findSym (LabelTab,
537 tree->falseLabel->name)))
538 tree->falseLabel = csym;
540 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
541 tree->falseLabel->name);
546 /* if this is a label resolve it from the labelTab */
547 if (IS_AST_VALUE (tree) &&
548 tree->opval.val->sym &&
549 tree->opval.val->sym->islbl)
552 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
553 tree->opval.val->sym->name);
556 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
557 tree->opval.val->sym->name);
559 tree->opval.val->sym = csym;
561 goto resolveChildren;
564 /* do only for leafs */
565 if (IS_AST_VALUE (tree) &&
566 tree->opval.val->sym &&
567 !tree->opval.val->sym->implicit)
570 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
572 /* if found in the symbol table & they r not the same */
573 if (csym && tree->opval.val->sym != csym)
575 tree->opval.val->sym = csym;
576 tree->opval.val->type = csym->type;
577 tree->opval.val->etype = csym->etype;
580 /* if not found in the symbol table */
581 /* mark it as undefined assume it is */
582 /* an integer in data space */
583 if (!csym && !tree->opval.val->sym->implicit)
586 /* if this is a function name then */
587 /* mark it as returning an int */
590 tree->opval.val->sym->type = newLink (DECLARATOR);
591 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
592 tree->opval.val->sym->type->next =
593 tree->opval.val->sym->etype = newIntLink ();
594 tree->opval.val->etype = tree->opval.val->etype;
595 tree->opval.val->type = tree->opval.val->sym->type;
596 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
597 tree->opval.val->sym->name);
598 //tree->opval.val->sym->undefined = 1;
599 allocVariables (tree->opval.val->sym);
603 tree->opval.val->sym->undefined = 1;
604 tree->opval.val->type =
605 tree->opval.val->etype = newIntLink ();
606 tree->opval.val->sym->type =
607 tree->opval.val->sym->etype = newIntLink ();
613 resolveSymbols (tree->left);
614 resolveSymbols (tree->right);
619 /*-----------------------------------------------------------------*/
620 /* setAstLineno - walks a ast tree & sets the line number */
621 /*-----------------------------------------------------------------*/
622 int setAstLineno (ast * tree, int lineno)
627 tree->lineno = lineno;
628 setAstLineno (tree->left, lineno);
629 setAstLineno (tree->right, lineno);
633 /*-----------------------------------------------------------------*/
634 /* funcOfType :- function of type with name */
635 /*-----------------------------------------------------------------*/
637 funcOfType (char *name, sym_link * type, sym_link * argType,
641 /* create the symbol */
642 sym = newSymbol (name, 0);
644 /* setup return value */
645 sym->type = newLink (DECLARATOR);
646 DCL_TYPE (sym->type) = FUNCTION;
647 sym->type->next = copyLinkChain (type);
648 sym->etype = getSpec (sym->type);
649 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
651 /* if arguments required */
655 args = FUNC_ARGS(sym->type) = newValue ();
659 args->type = copyLinkChain (argType);
660 args->etype = getSpec (args->type);
661 SPEC_EXTR(args->etype)=1;
664 args = args->next = newValue ();
671 allocVariables (sym);
676 /*-----------------------------------------------------------------*/
677 /* funcOfTypeVarg :- function of type with name and argtype */
678 /*-----------------------------------------------------------------*/
680 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
685 /* create the symbol */
686 sym = newSymbol (name, 0);
688 /* setup return value */
689 sym->type = newLink (DECLARATOR);
690 DCL_TYPE (sym->type) = FUNCTION;
691 sym->type->next = typeFromStr(rtype);
692 sym->etype = getSpec (sym->type);
694 /* if arguments required */
697 args = FUNC_ARGS(sym->type) = newValue ();
699 for ( i = 0 ; i < nArgs ; i++ ) {
700 args->type = typeFromStr(atypes[i]);
701 args->etype = getSpec (args->type);
702 SPEC_EXTR(args->etype)=1;
703 if ((i + 1) == nArgs) break;
704 args = args->next = newValue ();
711 allocVariables (sym);
716 /*-----------------------------------------------------------------*/
717 /* reverseParms - will reverse a parameter tree */
718 /*-----------------------------------------------------------------*/
720 reverseParms (ast * ptree)
726 /* top down if we find a nonParm tree then quit */
727 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
729 /* The various functions expect the parameter tree to be right heavy. */
730 /* Rotate the tree to be left heavy so that after reversal it is */
731 /* right heavy again. */
732 while ((ttree = ptree->right) && ttree->type == EX_OP &&
733 ttree->opval.op == PARAM)
735 ptree->right = ttree->right;
736 ttree->right = ttree->left;
737 ttree->left = ptree->left;
743 ptree->left = ptree->right;
744 ptree->right = ttree;
746 reverseParms (ptree->left);
747 reverseParms (ptree->right);
753 /*-----------------------------------------------------------------*/
754 /* processParms - makes sure the parameters are okay and do some */
755 /* processing with them */
756 /*-----------------------------------------------------------------*/
758 processParms (ast *func,
761 int *parmNumber, /* unused, although updated */
764 RESULT_TYPE resultType;
767 /* if none of them exist */
768 if (!defParm && !*actParm)
773 if (getenv("DEBUG_SANITY"))
775 fprintf (stderr, "processParms: %s ", defParm->name);
777 /* make sure the type is complete and sane */
778 checkTypeSanity(defParm->etype, defParm->name);
781 if (IS_CODEPTR (func->ftype))
782 functype = func->ftype->next;
784 functype = func->ftype;
786 /* if the function is being called via a pointer & */
787 /* it has not been defined a reentrant then we cannot */
788 /* have parameters */
789 /* PIC16 port can... */
790 if (!TARGET_IS_PIC16)
792 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
794 werror (W_NONRENT_ARGS);
800 /* if defined parameters ended but actual parameters */
801 /* exist and this is not defined as a variable arg */
802 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
804 werror (E_TOO_MANY_PARMS);
808 /* if defined parameters present but no actual parameters */
809 if (defParm && !*actParm)
811 werror (E_TOO_FEW_PARMS);
815 /* if this is a PARAM node then match left & right */
816 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
818 (*actParm)->decorated = 1;
819 return (processParms (func, defParm,
820 &(*actParm)->left, parmNumber, FALSE) ||
821 processParms (func, defParm ? defParm->next : NULL,
822 &(*actParm)->right, parmNumber, rightmost));
824 else if (defParm) /* not vararg */
826 /* If we have found a value node by following only right-hand links,
827 * then we know that there are no more values after us.
829 * Therefore, if there are more defined parameters, the caller didn't
832 if (rightmost && defParm->next)
834 werror (E_TOO_FEW_PARMS);
839 /* decorate parameter */
840 resultType = defParm ? getResultTypeFromType (defParm->type) :
842 *actParm = decorateType (*actParm, resultType);
844 if (IS_VOID((*actParm)->ftype))
846 werror (E_VOID_VALUE_USED);
850 /* If this is a varargs function... */
851 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
856 if (IS_CAST_OP (*actParm)
857 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
859 /* Parameter was explicitly typecast; don't touch it. */
863 ftype = (*actParm)->ftype;
865 /* If it's a char, upcast to int. */
866 if (IS_INTEGRAL (ftype)
867 && (getSize (ftype) < (unsigned) INTSIZE))
869 newType = newAst_LINK(INTTYPE);
872 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
874 newType = newAst_LINK (copyLinkChain(ftype));
875 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
878 if (IS_AGGREGATE (ftype))
880 newType = newAst_LINK (copyLinkChain (ftype));
881 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
886 /* cast required; change this op to a cast. */
887 (*actParm)->decorated = 0;
888 *actParm = newNode (CAST, newType, *actParm);
889 (*actParm)->lineno = (*actParm)->right->lineno;
891 decorateType (*actParm, RESULT_TYPE_NONE);
896 /* if defined parameters ended but actual has not & */
898 if (!defParm && *actParm &&
899 (options.stackAuto || IFFUNC_ISREENT (functype)))
902 resolveSymbols (*actParm);
904 /* the parameter type must be at least castable */
905 if (compareType (defParm->type, (*actParm)->ftype) == 0)
907 werror (E_INCOMPAT_TYPES);
908 printFromToType ((*actParm)->ftype, defParm->type);
912 /* if the parameter is castable then add the cast */
913 if (compareType (defParm->type, (*actParm)->ftype) < 0)
917 resultType = getResultTypeFromType (defParm->etype);
918 pTree = resolveSymbols (copyAst (*actParm));
920 /* now change the current one to a cast */
921 (*actParm)->type = EX_OP;
922 (*actParm)->opval.op = CAST;
923 (*actParm)->left = newAst_LINK (defParm->type);
924 (*actParm)->right = pTree;
925 (*actParm)->decorated = 0; /* force typechecking */
926 decorateType (*actParm, resultType);
929 /* make a copy and change the regparm type to the defined parm */
930 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
931 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
932 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
937 /*-----------------------------------------------------------------*/
938 /* createIvalType - generates ival for basic types */
939 /*-----------------------------------------------------------------*/
941 createIvalType (ast * sym, sym_link * type, initList * ilist)
945 /* if initList is deep */
946 if (ilist->type == INIT_DEEP)
947 ilist = ilist->init.deep;
949 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
950 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
953 /*-----------------------------------------------------------------*/
954 /* createIvalStruct - generates initial value for structures */
955 /*-----------------------------------------------------------------*/
957 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
964 sflds = SPEC_STRUCT (type)->fields;
965 if (ilist->type != INIT_DEEP)
967 werror (E_INIT_STRUCT, "");
971 iloop = ilist->init.deep;
973 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
975 /* if we have come to end */
979 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
980 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
981 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
982 iloop, rast, rootValue)),
988 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
989 W_EXCESS_INITIALIZERS, "struct",
990 sym->opval.val->sym->name);
997 /*-----------------------------------------------------------------*/
998 /* createIvalArray - generates code for array initialization */
999 /*-----------------------------------------------------------------*/
1001 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
1005 int lcnt = 0, size = 0;
1006 literalList *literalL;
1008 /* take care of the special case */
1009 /* array of characters can be init */
1011 if (IS_CHAR (type->next))
1012 if ((rast = createIvalCharPtr (sym,
1014 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
1017 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1019 /* not the special case */
1020 if (ilist->type != INIT_DEEP)
1022 werror (E_INIT_STRUCT, "");
1026 iloop = ilist->init.deep;
1027 lcnt = DCL_ELEM (type);
1029 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
1033 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
1035 rast = newNode(ARRAYINIT, aSym, NULL);
1036 rast->values.constlist = literalL;
1038 // Make sure size is set to length of initializer list.
1042 iloop = iloop->next;
1045 if (lcnt && size > lcnt)
1047 // Array size was specified, and we have more initializers than needed.
1048 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
1049 W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
1058 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
1059 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
1060 rast = createIval (aSym, type->next, iloop, rast, rootValue);
1061 iloop = (iloop ? iloop->next : NULL);
1067 /* no of elements given and we */
1068 /* have generated for all of them */
1071 // is this a better way? at least it won't crash
1072 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1073 werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name);
1080 /* if we have not been given a size */
1081 if (!DCL_ELEM (type))
1083 /* check, if it's a flexible array */
1084 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1085 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1087 DCL_ELEM (type) = size;
1090 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1094 /*-----------------------------------------------------------------*/
1095 /* createIvalCharPtr - generates initial values for char pointers */
1096 /*-----------------------------------------------------------------*/
1098 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1103 /* if this is a pointer & right is a literal array then */
1104 /* just assignment will do */
1105 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1106 SPEC_SCLS (iexpr->etype) == S_CODE)
1107 && IS_ARRAY (iexpr->ftype)))
1108 return newNode ('=', sym, iexpr);
1110 /* left side is an array so we have to assign each element */
1111 if ((IS_LITERAL (iexpr->etype) ||
1112 SPEC_SCLS (iexpr->etype) == S_CODE)
1113 && IS_ARRAY (iexpr->ftype))
1115 /* for each character generate an assignment */
1116 /* to the array element */
1117 char *s = SPEC_CVAL (iexpr->etype).v_char;
1119 unsigned int symsize = getSize (type);
1121 size = getSize (iexpr->ftype);
1122 if (symsize && size>symsize)
1124 if (size>(symsize+1))
1126 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1128 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1134 for (i=0;i<size;i++)
1136 rast = newNode (NULLOP,
1140 newAst_VALUE (valueFromLit ((float) i))),
1141 newAst_VALUE (valueFromLit (*s))));
1145 // now WE don't need iexpr's symbol anymore
1146 freeStringSymbol(AST_SYMBOL(iexpr));
1148 /* if we have not been given a size */
1149 if (!DCL_ELEM (type))
1151 /* check, if it's a flexible array */
1152 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1153 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1155 DCL_ELEM (type) = size;
1158 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1164 /*-----------------------------------------------------------------*/
1165 /* createIvalPtr - generates initial value for pointers */
1166 /*-----------------------------------------------------------------*/
1168 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1174 if (ilist->type == INIT_DEEP)
1175 ilist = ilist->init.deep;
1177 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1179 /* if character pointer */
1180 if (IS_CHAR (type->next))
1181 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1184 return newNode ('=', sym, iexpr);
1187 /*-----------------------------------------------------------------*/
1188 /* createIval - generates code for initial value */
1189 /*-----------------------------------------------------------------*/
1191 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1198 /* if structure then */
1199 if (IS_STRUCT (type))
1200 rast = createIvalStruct (sym, type, ilist, rootValue);
1202 /* if this is a pointer */
1204 rast = createIvalPtr (sym, type, ilist, rootValue);
1206 /* if this is an array */
1207 if (IS_ARRAY (type))
1208 rast = createIvalArray (sym, type, ilist, rootValue);
1210 /* if type is SPECIFIER */
1212 rast = createIvalType (sym, type, ilist);
1215 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1217 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1220 /*-----------------------------------------------------------------*/
1221 /* initAggregates - initialises aggregate variables with initv */
1222 /*-----------------------------------------------------------------*/
1223 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1224 ast *newAst = newAst_VALUE (symbolVal (sym));
1225 return createIval (newAst, sym->type, ival, wid, newAst);
1228 /*-----------------------------------------------------------------*/
1229 /* gatherAutoInit - creates assignment expressions for initial */
1231 /*-----------------------------------------------------------------*/
1233 gatherAutoInit (symbol * autoChain)
1240 for (sym = autoChain; sym; sym = sym->next)
1243 /* resolve the symbols in the ival */
1245 resolveIvalSym (sym->ival, sym->type);
1248 /* if we are PIC16 port,
1249 * and this is a static,
1250 * and have initial value,
1251 * and not S_CODE, don't emit in gs segment,
1252 * but allow glue.c:pic16emitRegularMap to put symbol
1253 * in idata section */
1254 if(TARGET_IS_PIC16 &&
1255 IS_STATIC (sym->etype) && sym->ival
1256 && SPEC_SCLS(sym->etype) != S_CODE) {
1257 SPEC_SCLS (sym->etype) = S_DATA;
1262 /* if this is a static variable & has an */
1263 /* initial value the code needs to be lifted */
1264 /* here to the main portion since they can be */
1265 /* initialised only once at the start */
1266 if (IS_STATIC (sym->etype) && sym->ival &&
1267 SPEC_SCLS (sym->etype) != S_CODE)
1271 /* insert the symbol into the symbol table */
1272 /* with level = 0 & name = rname */
1273 newSym = copySymbol (sym);
1274 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1276 /* now lift the code to main */
1277 if (IS_AGGREGATE (sym->type)) {
1278 work = initAggregates (sym, sym->ival, NULL);
1280 if (getNelements(sym->type, sym->ival)>1) {
1281 werrorfl (sym->fileDef, sym->lineDef,
1282 W_EXCESS_INITIALIZERS, "scalar",
1285 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1286 list2expr (sym->ival));
1289 setAstLineno (work, sym->lineDef);
1293 staticAutos = newNode (NULLOP, staticAutos, work);
1300 /* if there is an initial value */
1301 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1303 initList *ilist=sym->ival;
1305 while (ilist->type == INIT_DEEP) {
1306 ilist = ilist->init.deep;
1309 /* update lineno for error msg */
1310 lineno = sym->lineDef;
1311 setAstLineno (ilist->init.node, sym->lineDef);
1313 if (IS_AGGREGATE (sym->type)) {
1314 work = initAggregates (sym, sym->ival, NULL);
1316 if (getNelements(sym->type, sym->ival)>1) {
1317 werrorfl (sym->fileDef, sym->lineDef,
1318 W_EXCESS_INITIALIZERS, "scalar",
1321 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1322 list2expr (sym->ival));
1326 setAstLineno (work, sym->lineDef);
1330 init = newNode (NULLOP, init, work);
1339 /*-----------------------------------------------------------------*/
1340 /* freeStringSymbol - delete a literal string if no more usage */
1341 /*-----------------------------------------------------------------*/
1342 void freeStringSymbol(symbol *sym) {
1343 /* make sure this is a literal string */
1344 assert (sym->isstrlit);
1345 if (--sym->isstrlit == 0) { // lower the usage count
1346 memmap *segment=SPEC_OCLS(sym->etype);
1348 deleteSetItem(&segment->syms, sym);
1353 /*-----------------------------------------------------------------*/
1354 /* stringToSymbol - creates a symbol from a literal string */
1355 /*-----------------------------------------------------------------*/
1357 stringToSymbol (value * val)
1359 char name[SDCC_NAME_MAX + 1];
1360 static int charLbl = 0;
1365 // have we heard this before?
1366 for (sp=statsg->syms; sp; sp=sp->next) {
1368 size = getSize (sym->type);
1369 if (sym->isstrlit && size == getSize (val->type) &&
1370 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1371 // yes, this is old news. Don't publish it again.
1372 sym->isstrlit++; // but raise the usage count
1373 return symbolVal(sym);
1377 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1378 sym = newSymbol (name, 0); /* make it @ level 0 */
1379 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1381 /* copy the type from the value passed */
1382 sym->type = copyLinkChain (val->type);
1383 sym->etype = getSpec (sym->type);
1384 /* change to storage class & output class */
1385 SPEC_SCLS (sym->etype) = S_CODE;
1386 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1387 SPEC_STAT (sym->etype) = 1;
1388 /* make the level & block = 0 */
1389 sym->block = sym->level = 0;
1391 /* create an ival */
1392 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1397 allocVariables (sym);
1400 return symbolVal (sym);
1404 /*-----------------------------------------------------------------*/
1405 /* processBlockVars - will go thru the ast looking for block if */
1406 /* a block is found then will allocate the syms */
1407 /* will also gather the auto inits present */
1408 /*-----------------------------------------------------------------*/
1410 processBlockVars (ast * tree, int *stack, int action)
1415 /* if this is a block */
1416 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1420 if (action == ALLOCATE)
1422 *stack += allocVariables (tree->values.sym);
1423 autoInit = gatherAutoInit (tree->values.sym);
1425 /* if there are auto inits then do them */
1427 tree->left = newNode (NULLOP, autoInit, tree->left);
1429 else /* action is deallocate */
1430 deallocLocal (tree->values.sym);
1433 processBlockVars (tree->left, stack, action);
1434 processBlockVars (tree->right, stack, action);
1439 /*-------------------------------------------------------------*/
1440 /* constExprTree - returns TRUE if this tree is a constant */
1442 /*-------------------------------------------------------------*/
1443 bool constExprTree (ast *cexpr) {
1449 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1451 switch (cexpr->type)
1454 if (IS_AST_LIT_VALUE(cexpr)) {
1455 // this is a literal
1458 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1459 // a function's address will never change
1462 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1463 // an array's address will never change
1466 if (IS_AST_SYM_VALUE(cexpr) &&
1467 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1468 // a symbol in code space will never change
1469 // This is only for the 'char *s="hallo"' case and will have to leave
1470 //printf(" code space symbol");
1475 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1476 "unexpected link in expression tree\n");
1479 if (cexpr->opval.op==ARRAYINIT) {
1480 // this is a list of literals
1483 if (cexpr->opval.op=='=') {
1484 return constExprTree(cexpr->right);
1486 if (cexpr->opval.op==CAST) {
1487 // cast ignored, maybe we should throw a warning here?
1488 return constExprTree(cexpr->right);
1490 if (cexpr->opval.op=='&') {
1493 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1496 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1501 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1506 /*-----------------------------------------------------------------*/
1507 /* constExprValue - returns the value of a constant expression */
1508 /* or NULL if it is not a constant expression */
1509 /*-----------------------------------------------------------------*/
1511 constExprValue (ast * cexpr, int check)
1513 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1515 /* if this is not a constant then */
1516 if (!IS_LITERAL (cexpr->ftype))
1518 /* then check if this is a literal array
1520 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1521 SPEC_CVAL (cexpr->etype).v_char &&
1522 IS_ARRAY (cexpr->ftype))
1524 value *val = valFromType (cexpr->ftype);
1525 SPEC_SCLS (val->etype) = S_LITERAL;
1526 val->sym = cexpr->opval.val->sym;
1527 val->sym->type = copyLinkChain (cexpr->ftype);
1528 val->sym->etype = getSpec (val->sym->type);
1529 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1533 /* if we are casting a literal value then */
1534 if (IS_AST_OP (cexpr) &&
1535 cexpr->opval.op == CAST &&
1536 IS_LITERAL (cexpr->right->ftype))
1538 return valCastLiteral (cexpr->ftype,
1539 floatFromVal (cexpr->right->opval.val));
1542 if (IS_AST_VALUE (cexpr))
1544 return cexpr->opval.val;
1548 werror (E_CONST_EXPECTED, "found expression");
1553 /* return the value */
1554 if (IS_AST_VALUE (cexpr))
1556 return cexpr->opval.val;
1561 /*-----------------------------------------------------------------*/
1562 /* isLabelInAst - will return true if a given label is found */
1563 /*-----------------------------------------------------------------*/
1565 isLabelInAst (symbol * label, ast * tree)
1567 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1570 if (IS_AST_OP (tree) &&
1571 tree->opval.op == LABEL &&
1572 isSymbolEqual (AST_SYMBOL (tree->left), label))
1575 return isLabelInAst (label, tree->right) &&
1576 isLabelInAst (label, tree->left);
1579 /*-----------------------------------------------------------------*/
1580 /* isLoopCountable - return true if the loop count can be determi- */
1581 /* -ned at compile time . */
1582 /*-----------------------------------------------------------------*/
1584 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1585 symbol ** sym, ast ** init, ast ** end)
1588 /* the loop is considered countable if the following
1589 conditions are true :-
1591 a) initExpr :- <sym> = <const>
1592 b) condExpr :- <sym> < <const1>
1593 c) loopExpr :- <sym> ++
1596 /* first check the initExpr */
1597 if (IS_AST_OP (initExpr) &&
1598 initExpr->opval.op == '=' && /* is assignment */
1599 IS_AST_SYM_VALUE (initExpr->left))
1600 { /* left is a symbol */
1602 *sym = AST_SYMBOL (initExpr->left);
1603 *init = initExpr->right;
1608 /* don't reverse loop with volatile counter */
1609 if (IS_VOLATILE ((*sym)->type))
1612 /* for now the symbol has to be of
1614 if (!IS_INTEGRAL ((*sym)->type))
1617 /* now check condExpr */
1618 if (IS_AST_OP (condExpr))
1621 switch (condExpr->opval.op)
1624 if (IS_AST_SYM_VALUE (condExpr->left) &&
1625 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1626 IS_AST_LIT_VALUE (condExpr->right))
1628 *end = condExpr->right;
1634 if (IS_AST_OP (condExpr->left) &&
1635 condExpr->left->opval.op == '>' &&
1636 IS_AST_LIT_VALUE (condExpr->left->right) &&
1637 IS_AST_SYM_VALUE (condExpr->left->left) &&
1638 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1641 *end = newNode ('+', condExpr->left->right,
1642 newAst_VALUE (constVal ("1")));
1655 /* check loop expression is of the form <sym>++ */
1656 if (!IS_AST_OP (loopExpr))
1659 /* check if <sym> ++ */
1660 if (loopExpr->opval.op == INC_OP)
1666 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1667 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1674 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1675 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1683 if (loopExpr->opval.op == ADD_ASSIGN)
1686 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1687 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1688 IS_AST_LIT_VALUE (loopExpr->right) &&
1689 AST_ULONG_VALUE (loopExpr->right) != 1)
1697 /*-----------------------------------------------------------------*/
1698 /* astHasVolatile - returns true if ast contains any volatile */
1699 /*-----------------------------------------------------------------*/
1701 astHasVolatile (ast * tree)
1706 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1709 if (IS_AST_OP (tree))
1710 return astHasVolatile (tree->left) ||
1711 astHasVolatile (tree->right);
1716 /*-----------------------------------------------------------------*/
1717 /* astHasPointer - return true if the ast contains any ptr variable */
1718 /*-----------------------------------------------------------------*/
1720 astHasPointer (ast * tree)
1725 if (IS_AST_LINK (tree))
1728 /* if we hit an array expression then check
1729 only the left side */
1730 if (IS_AST_OP (tree) && tree->opval.op == '[')
1731 return astHasPointer (tree->left);
1733 if (IS_AST_VALUE (tree))
1734 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1736 return astHasPointer (tree->left) ||
1737 astHasPointer (tree->right);
1741 /*-----------------------------------------------------------------*/
1742 /* astHasSymbol - return true if the ast has the given symbol */
1743 /*-----------------------------------------------------------------*/
1745 astHasSymbol (ast * tree, symbol * sym)
1747 if (!tree || IS_AST_LINK (tree))
1750 if (IS_AST_VALUE (tree))
1752 if (IS_AST_SYM_VALUE (tree))
1753 return isSymbolEqual (AST_SYMBOL (tree), sym);
1758 return astHasSymbol (tree->left, sym) ||
1759 astHasSymbol (tree->right, sym);
1762 /*-----------------------------------------------------------------*/
1763 /* astHasDeref - return true if the ast has an indirect access */
1764 /*-----------------------------------------------------------------*/
1766 astHasDeref (ast * tree)
1768 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1771 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1773 return astHasDeref (tree->left) || astHasDeref (tree->right);
1776 /*-----------------------------------------------------------------*/
1777 /* isConformingBody - the loop body has to conform to a set of rules */
1778 /* for the loop to be considered reversible read on for rules */
1779 /*-----------------------------------------------------------------*/
1781 isConformingBody (ast * pbody, symbol * sym, ast * body)
1784 /* we are going to do a pre-order traversal of the
1785 tree && check for the following conditions. (essentially
1786 a set of very shallow tests )
1787 a) the sym passed does not participate in
1788 any arithmetic operation
1789 b) There are no function calls
1790 c) all jumps are within the body
1791 d) address of loop control variable not taken
1792 e) if an assignment has a pointer on the
1793 left hand side make sure right does not have
1794 loop control variable */
1796 /* if we reach the end or a leaf then true */
1797 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1800 /* if anything else is "volatile" */
1801 if (IS_VOLATILE (TETYPE (pbody)))
1804 /* we will walk the body in a pre-order traversal for
1806 switch (pbody->opval.op)
1808 /*------------------------------------------------------------------*/
1810 // if the loopvar is used as an index
1811 /* array op is commutative -- must check both left & right */
1812 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1815 return isConformingBody (pbody->right, sym, body)
1816 && isConformingBody (pbody->left, sym, body);
1818 /*------------------------------------------------------------------*/
1823 /*------------------------------------------------------------------*/
1827 /* sure we are not sym is not modified */
1829 IS_AST_SYM_VALUE (pbody->left) &&
1830 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1834 IS_AST_SYM_VALUE (pbody->right) &&
1835 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1840 /*------------------------------------------------------------------*/
1842 case '*': /* can be unary : if right is null then unary operation */
1847 /* if right is NULL then unary operation */
1848 /*------------------------------------------------------------------*/
1849 /*----------------------------*/
1851 /*----------------------------*/
1854 if (IS_AST_SYM_VALUE (pbody->left) &&
1855 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1858 return isConformingBody (pbody->left, sym, body);
1862 if (astHasSymbol (pbody->left, sym) ||
1863 astHasSymbol (pbody->right, sym))
1868 /*------------------------------------------------------------------*/
1879 if (IS_AST_SYM_VALUE (pbody->left) &&
1880 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1883 if (IS_AST_SYM_VALUE (pbody->right) &&
1884 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1887 return isConformingBody (pbody->left, sym, body) &&
1888 isConformingBody (pbody->right, sym, body);
1896 if (IS_AST_SYM_VALUE (pbody->left) &&
1897 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1899 return isConformingBody (pbody->left, sym, body);
1901 /*------------------------------------------------------------------*/
1913 case SIZEOF: /* evaluate wihout code generation */
1915 if (IS_AST_SYM_VALUE (pbody->left) &&
1916 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1919 if (IS_AST_SYM_VALUE (pbody->right) &&
1920 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1923 return isConformingBody (pbody->left, sym, body) &&
1924 isConformingBody (pbody->right, sym, body);
1926 /*------------------------------------------------------------------*/
1929 /* if left has a pointer & right has loop
1930 control variable then we cannot */
1931 if (astHasPointer (pbody->left) &&
1932 astHasSymbol (pbody->right, sym))
1934 if (astHasVolatile (pbody->left))
1937 if (IS_AST_SYM_VALUE (pbody->left)) {
1938 // if the loopvar has an assignment
1939 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1941 // if the loopvar is used in another (maybe conditional) block
1942 if (astHasSymbol (pbody->right, sym) &&
1943 (pbody->level >= body->level)) {
1948 if (astHasVolatile (pbody->left))
1951 if (astHasDeref(pbody->right)) return FALSE;
1953 return isConformingBody (pbody->left, sym, body) &&
1954 isConformingBody (pbody->right, sym, body);
1965 assert ("Parser should not have generated this\n");
1967 /*------------------------------------------------------------------*/
1968 /*----------------------------*/
1969 /* comma operator */
1970 /*----------------------------*/
1972 return isConformingBody (pbody->left, sym, body) &&
1973 isConformingBody (pbody->right, sym, body);
1975 /*------------------------------------------------------------------*/
1976 /*----------------------------*/
1978 /*----------------------------*/
1980 /* if local & not passed as paramater then ok */
1981 if (sym->level && !astHasSymbol(pbody->right,sym))
1985 /*------------------------------------------------------------------*/
1986 /*----------------------------*/
1987 /* return statement */
1988 /*----------------------------*/
1993 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1998 if (astHasSymbol (pbody->left, sym))
2005 return isConformingBody (pbody->left, sym, body) &&
2006 isConformingBody (pbody->right, sym, body);
2012 /*-----------------------------------------------------------------*/
2013 /* isLoopReversible - takes a for loop as input && returns true */
2014 /* if the for loop is reversible. If yes will set the value of */
2015 /* the loop control var & init value & termination value */
2016 /*-----------------------------------------------------------------*/
2018 isLoopReversible (ast * loop, symbol ** loopCntrl,
2019 ast ** init, ast ** end)
2021 /* if option says don't do it then don't */
2022 if (optimize.noLoopReverse)
2024 /* there are several tests to determine this */
2026 /* for loop has to be of the form
2027 for ( <sym> = <const1> ;
2028 [<sym> < <const2>] ;
2029 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
2031 if (!isLoopCountable (AST_FOR (loop, initExpr),
2032 AST_FOR (loop, condExpr),
2033 AST_FOR (loop, loopExpr),
2034 loopCntrl, init, end))
2037 /* now do some serious checking on the body of the loop
2040 return isConformingBody (loop->left, *loopCntrl, loop->left);
2044 /*-----------------------------------------------------------------*/
2045 /* replLoopSym - replace the loop sym by loop sym -1 */
2046 /*-----------------------------------------------------------------*/
2048 replLoopSym (ast * body, symbol * sym)
2051 if (!body || IS_AST_LINK (body))
2054 if (IS_AST_SYM_VALUE (body))
2057 if (isSymbolEqual (AST_SYMBOL (body), sym))
2061 body->opval.op = '-';
2062 body->left = newAst_VALUE (symbolVal (sym));
2063 body->right = newAst_VALUE (constVal ("1"));
2071 replLoopSym (body->left, sym);
2072 replLoopSym (body->right, sym);
2076 /*-----------------------------------------------------------------*/
2077 /* reverseLoop - do the actual loop reversal */
2078 /*-----------------------------------------------------------------*/
2080 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
2084 /* create the following tree
2089 if (sym) goto for_continue ;
2092 /* put it together piece by piece */
2093 rloop = newNode (NULLOP,
2094 createIf (newAst_VALUE (symbolVal (sym)),
2096 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2099 newAst_VALUE (symbolVal (sym)),
2102 replLoopSym (loop->left, sym);
2103 setAstLineno (rloop, init->lineno);
2105 rloop = newNode (NULLOP,
2107 newAst_VALUE (symbolVal (sym)),
2108 newNode ('-', end, init)),
2109 createLabel (AST_FOR (loop, continueLabel),
2113 newNode (SUB_ASSIGN,
2114 newAst_VALUE (symbolVal (sym)),
2115 newAst_VALUE (constVal ("1"))),
2118 rloop->lineno=init->lineno;
2119 return decorateType (rloop, RESULT_TYPE_NONE);
2123 /*-----------------------------------------------------------------*/
2124 /* searchLitOp - search tree (*ops only) for an ast with literal */
2125 /*-----------------------------------------------------------------*/
2127 searchLitOp (ast *tree, ast **parent, const char *ops)
2131 if (tree && optimize.global_cse)
2133 /* is there a literal operand? */
2135 IS_AST_OP(tree->right) &&
2136 tree->right->right &&
2137 (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1]))
2139 if (IS_LITERAL (RTYPE (tree->right)) !=
2140 IS_LITERAL (LTYPE (tree->right)))
2142 tree->right->decorated = 0;
2143 tree->decorated = 0;
2147 ret = searchLitOp (tree->right, parent, ops);
2152 IS_AST_OP(tree->left) &&
2153 tree->left->right &&
2154 (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1]))
2156 if (IS_LITERAL (RTYPE (tree->left)) !=
2157 IS_LITERAL (LTYPE (tree->left)))
2159 tree->left->decorated = 0;
2160 tree->decorated = 0;
2164 ret = searchLitOp (tree->left, parent, ops);
2172 /*-----------------------------------------------------------------*/
2173 /* getResultFromType */
2174 /*-----------------------------------------------------------------*/
2176 getResultTypeFromType (sym_link *type)
2178 /* type = getSpec (type); */
2180 return RESULT_TYPE_BIT;
2181 if (IS_BITFIELD (type))
2183 int blen = SPEC_BLEN (type);
2186 return RESULT_TYPE_BIT;
2188 return RESULT_TYPE_CHAR;
2189 return RESULT_TYPE_INT;
2192 return RESULT_TYPE_CHAR;
2193 if (IS_INT (type) && !IS_LONG (type))
2194 return RESULT_TYPE_INT;
2195 return RESULT_TYPE_OTHER;
2198 /*-----------------------------------------------------------------*/
2199 /* addCast - adds casts to a type specified by RESULT_TYPE */
2200 /*-----------------------------------------------------------------*/
2202 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2205 bool upCasted = FALSE;
2209 case RESULT_TYPE_NONE:
2210 /* if thing smaller than int must be promoted to int */
2212 getSize (tree->etype) >= INTSIZE)
2213 /* promotion not necessary or already an int */
2215 /* char and bits: promote to int */
2216 newLink = newIntLink();
2219 case RESULT_TYPE_BIT:
2221 /* already an int */
2222 bitsForType (tree->etype) >= 16 ||
2223 /* bit to bit operation: don't promote, the code generators
2224 hopefully know everything about promotion rules */
2225 bitsForType (tree->etype) == 1)
2227 newLink = newIntLink();
2230 case RESULT_TYPE_CHAR:
2231 if (IS_CHAR (tree->etype) ||
2232 IS_FLOAT(tree->etype) ||
2233 IS_FIXED(tree->etype))
2235 newLink = newCharLink();
2237 case RESULT_TYPE_INT:
2239 if (getSize (tree->etype) > INTSIZE)
2241 /* warn ("Loosing significant digits"); */
2245 /* char: promote to int */
2247 getSize (tree->etype) >= INTSIZE)
2249 newLink = newIntLink();
2252 case RESULT_TYPE_IFX:
2253 case RESULT_TYPE_OTHER:
2255 /* return type is ifx, long, float: promote char to int */
2256 getSize (tree->etype) >= INTSIZE)
2258 newLink = newIntLink();
2264 tree->decorated = 0;
2265 tree = newNode (CAST, newAst_LINK (newLink), tree);
2266 tree->lineno = tree->right->lineno;
2267 /* keep unsigned type during cast to smaller type,
2268 but not when promoting from char to int */
2270 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2271 return decorateType (tree, resultType);
2274 /*-----------------------------------------------------------------*/
2275 /* resultTypePropagate - decides if resultType can be propagated */
2276 /*-----------------------------------------------------------------*/
2278 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2280 switch (tree->opval.op)
2297 if ((IS_AST_VALUE (tree->left) && !IS_INTEGRAL (tree->left->opval.val->etype)) ||
2298 (IS_AST_VALUE (tree->right) && !IS_INTEGRAL (tree->right->opval.val->etype)))
2299 return RESULT_TYPE_NONE;
2304 return RESULT_TYPE_NONE;
2308 return RESULT_TYPE_IFX;
2310 return RESULT_TYPE_NONE;
2314 /*-----------------------------------------------------------------*/
2315 /* getLeftResultType - gets type from left branch for propagation */
2316 /*-----------------------------------------------------------------*/
2318 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2320 switch (tree->opval.op)
2324 if (IS_PTR (LTYPE (tree)))
2325 return RESULT_TYPE_NONE;
2327 return getResultTypeFromType (LETYPE (tree));
2329 if (IS_PTR (currFunc->type->next))
2330 return RESULT_TYPE_NONE;
2332 return getResultTypeFromType (currFunc->type->next);
2334 if (!IS_ARRAY (LTYPE (tree)))
2336 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2337 return RESULT_TYPE_CHAR;
2344 /*------------------------------------------------------------------*/
2345 /* gatherImplicitVariables: assigns correct type information to */
2346 /* symbols and values created by replaceAstWithTemporary */
2347 /* and adds the symbols to the declarations list of the */
2348 /* innermost block that contains them */
2349 /*------------------------------------------------------------------*/
2351 gatherImplicitVariables (ast * tree, ast * block)
2356 if (tree->type == EX_OP && tree->opval.op == BLOCK)
2358 /* keep track of containing scope */
2361 if (tree->type == EX_OP && tree->opval.op == '=' &&
2362 tree->left->type == EX_VALUE && tree->left->opval.val->sym)
2364 symbol *assignee = tree->left->opval.val->sym;
2366 /* special case for assignment to compiler-generated temporary variable:
2367 compute type of RHS, and set the symbol's type to match */
2368 if (assignee->type == NULL && assignee->infertype) {
2369 ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
2371 if (dtr != tree->right)
2374 assignee->type = copyLinkChain(TTYPE(dtr));
2375 assignee->etype = getSpec(assignee->type);
2376 SPEC_SCLS (assignee->etype) = S_AUTO;
2377 SPEC_OCLS (assignee->etype) = NULL;
2378 SPEC_EXTR (assignee->etype) = 0;
2379 SPEC_STAT (assignee->etype) = 0;
2380 SPEC_VOLATILE (assignee->etype) = 0;
2381 SPEC_ABSA (assignee->etype) = 0;
2383 wassertl(block != NULL, "implicit variable not contained in block");
2384 wassert(assignee->next == NULL);
2385 if (block != NULL) {
2386 symbol **decl = &(block->values.sym);
2389 wassert(*decl != assignee); /* should not already be in list */
2390 decl = &( (*decl)->next );
2397 if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) &&
2398 tree->opval.val->type == NULL &&
2399 tree->opval.val->sym &&
2400 tree->opval.val->sym->infertype)
2402 /* fixup type of value for compiler-inferred temporary var */
2403 tree->opval.val->type = tree->opval.val->sym->type;
2404 tree->opval.val->etype = tree->opval.val->sym->etype;
2407 gatherImplicitVariables(tree->left, block);
2408 gatherImplicitVariables(tree->right, block);
2411 /*--------------------------------------------------------------------*/
2412 /* decorateType - compute type for this tree, also does type checking.*/
2413 /* This is done bottom up, since type has to flow upwards. */
2414 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2415 /* result is a char and the operand(s) are int's. */
2416 /* It also does constant folding, and parameter checking. */
2417 /*--------------------------------------------------------------------*/
2419 decorateType (ast * tree, RESULT_TYPE resultType)
2423 RESULT_TYPE resultTypeProp;
2428 /* if already has type then do nothing */
2429 if (tree->decorated)
2432 tree->decorated = 1;
2435 /* print the line */
2436 /* if not block & function */
2437 if (tree->type == EX_OP &&
2438 (tree->opval.op != FUNCTION &&
2439 tree->opval.op != BLOCK &&
2440 tree->opval.op != NULLOP))
2442 filename = tree->filename;
2443 lineno = tree->lineno;
2447 /* if any child is an error | this one is an error do nothing */
2448 if (tree->isError ||
2449 (tree->left && tree->left->isError) ||
2450 (tree->right && tree->right->isError))
2453 /*------------------------------------------------------------------*/
2454 /*----------------------------*/
2455 /* leaf has been reached */
2456 /*----------------------------*/
2457 lineno = tree->lineno;
2458 /* if this is of type value */
2459 /* just get the type */
2460 if (tree->type == EX_VALUE)
2463 if (IS_LITERAL (tree->opval.val->etype))
2466 /* if this is a character array then declare it */
2467 if (IS_ARRAY (tree->opval.val->type))
2468 tree->opval.val = stringToSymbol (tree->opval.val);
2470 /* otherwise just copy the type information */
2471 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2475 if (tree->opval.val->sym)
2477 /* if the undefined flag is set then give error message */
2478 if (tree->opval.val->sym->undefined)
2480 werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name);
2482 TTYPE (tree) = TETYPE (tree) =
2483 tree->opval.val->type = tree->opval.val->sym->type =
2484 tree->opval.val->etype = tree->opval.val->sym->etype =
2485 copyLinkChain (INTTYPE);
2487 else if (tree->opval.val->sym->implicit)
2489 /* if implicit i.e. struct/union member then no type */
2490 TTYPE (tree) = TETYPE (tree) = NULL;
2494 /* copy the type from the value into the ast */
2495 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2497 /* and mark the symbol as referenced */
2498 tree->opval.val->sym->isref = 1;
2502 wassert(0); /* unreached: all values are literals or symbols */
2507 /* if type link for the case of cast */
2508 if (tree->type == EX_LINK)
2510 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2518 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2520 if (tree->left && tree->left->type == EX_OPERAND
2521 && (tree->left->opval.op == INC_OP
2522 || tree->left->opval.op == DEC_OP)
2523 && tree->left->left)
2525 tree->left->right = tree->left->left;
2526 tree->left->left = NULL;
2528 if (tree->right && tree->right->type == EX_OPERAND
2529 && (tree->right->opval.op == INC_OP
2530 || tree->right->opval.op == DEC_OP)
2531 && tree->right->left)
2533 tree->right->right = tree->right->left;
2534 tree->right->left = NULL;
2539 /* Before decorating the left branch we've to decide in dependence
2540 upon tree->opval.op, if resultType can be propagated */
2541 resultTypeProp = resultTypePropagate (tree, resultType);
2543 if ((tree->opval.op == '?') && (resultTypeProp != RESULT_TYPE_BIT))
2544 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2546 dtl = decorateType (tree->left, resultTypeProp);
2548 /* if an array node, we may need to swap branches */
2549 if (tree->opval.op == '[')
2551 /* determine which is the array & which the index */
2552 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2553 IS_INTEGRAL (LTYPE (tree)))
2555 ast *tempTree = tree->left;
2556 tree->left = tree->right;
2557 tree->right = tempTree;
2561 /* After decorating the left branch there's type information available
2562 in tree->left->?type. If the op is e.g. '=' we extract the type
2563 information from there and propagate it to the right branch. */
2564 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2566 switch (tree->opval.op)
2569 /* delay right side for '?' operator since conditional macro
2570 expansions might rely on this */
2574 /* decorate right side for CALL (parameter list) in processParms();
2575 there is resultType available */
2579 /* don't allocate string if it is a sizeof argument */
2581 dtr = decorateType (tree->right, resultTypeProp);
2585 dtr = decorateType (tree->right, resultTypeProp);
2589 /* this is to take care of situations
2590 when the tree gets rewritten */
2591 if (dtl != tree->left)
2593 if (dtr != tree->right)
2595 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2599 /* depending on type of operator do */
2601 switch (tree->opval.op)
2603 /*------------------------------------------------------------------*/
2604 /*----------------------------*/
2606 /*----------------------------*/
2609 /* first check if this is a array or a pointer */
2610 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2612 werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
2613 goto errorTreeReturn;
2616 /* check if the type of the idx */
2617 if (!IS_INTEGRAL (RTYPE (tree)))
2619 werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
2620 goto errorTreeReturn;
2623 /* if the left is an rvalue then error */
2626 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
2627 goto errorTreeReturn;
2630 if (IS_LITERAL (RTYPE (tree)))
2632 int arrayIndex = (int) ulFromVal (valFromType (RETYPE (tree)));
2633 int arraySize = DCL_ELEM (LTYPE (tree));
2634 if (arraySize && arrayIndex >= arraySize)
2636 werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2641 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2642 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2645 /*------------------------------------------------------------------*/
2646 /*----------------------------*/
2648 /*----------------------------*/
2650 /* if this is not a structure */
2651 if (!IS_STRUCT (LTYPE (tree)))
2653 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
2654 goto errorTreeReturn;
2656 TTYPE (tree) = structElemType (LTYPE (tree),
2657 (tree->right->type == EX_VALUE ?
2658 tree->right->opval.val : NULL));
2659 TETYPE (tree) = getSpec (TTYPE (tree));
2662 /*------------------------------------------------------------------*/
2663 /*----------------------------*/
2664 /* struct/union pointer */
2665 /*----------------------------*/
2667 /* if not pointer to a structure */
2668 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2670 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
2671 goto errorTreeReturn;
2674 if (!IS_STRUCT (LTYPE (tree)->next))
2676 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
2677 goto errorTreeReturn;
2680 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2681 (tree->right->type == EX_VALUE ?
2682 tree->right->opval.val : NULL));
2683 TETYPE (tree) = getSpec (TTYPE (tree));
2685 /* adjust the storage class */
2686 switch (DCL_TYPE(tree->left->ftype)) {
2688 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2691 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2694 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2697 SPEC_SCLS (TETYPE (tree)) = 0;
2700 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2703 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2706 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2709 SPEC_SCLS (TETYPE (tree)) = 0;
2716 /* This breaks with extern declarations, bitfields, and perhaps other */
2717 /* cases (gcse). Let's leave this optimization disabled for now and */
2718 /* ponder if there's a safe way to do this. -- EEP */
2720 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2721 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2723 /* If defined struct type at addr var
2724 then rewrite (&struct var)->member
2726 and define membertype at (addr+offsetof(struct var,member)) temp
2729 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2730 AST_SYMBOL(tree->right));
2732 sym = newSymbol(genSymName (0), 0);
2733 sym->type = TTYPE (tree);
2734 sym->etype = getSpec(sym->type);
2735 sym->lineDef = tree->lineno;
2738 SPEC_STAT (sym->etype) = 1;
2739 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2741 SPEC_ABSA(sym->etype) = 1;
2742 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2745 AST_VALUE (tree) = symbolVal(sym);
2748 tree->type = EX_VALUE;
2756 /*------------------------------------------------------------------*/
2757 /*----------------------------*/
2758 /* ++/-- operation */
2759 /*----------------------------*/
2763 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2764 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2765 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2766 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2775 /*------------------------------------------------------------------*/
2776 /*----------------------------*/
2778 /*----------------------------*/
2779 case '&': /* can be unary */
2780 /* if right is NULL then unary operation */
2781 if (tree->right) /* not an unary operation */
2784 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2786 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2787 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2788 printTypeChain (LTYPE (tree), stderr);
2789 fprintf (stderr, ",");
2790 printTypeChain (RTYPE (tree), stderr);
2791 fprintf (stderr, "\n");
2792 goto errorTreeReturn;
2795 /* if they are both literal */
2796 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2798 tree->type = EX_VALUE;
2799 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2800 valFromType (RETYPE (tree)), '&');
2802 tree->right = tree->left = NULL;
2803 TETYPE (tree) = tree->opval.val->etype;
2804 TTYPE (tree) = tree->opval.val->type;
2808 /* see if this is a GETHBIT operation if yes
2811 ast *otree = optimizeGetHbit (tree, resultType);
2814 return decorateType (otree, RESULT_TYPE_NONE);
2817 /* see if this is a GETABIT operation if yes
2820 ast *otree = optimizeGetAbit (tree, resultType);
2823 return decorateType (otree, RESULT_TYPE_NONE);
2826 /* see if this is a GETBYTE operation if yes
2829 ast *otree = optimizeGetByte (tree, resultType);
2832 return decorateType (otree, RESULT_TYPE_NONE);
2835 /* see if this is a GETWORD operation if yes
2838 ast *otree = optimizeGetWord (tree, resultType);
2841 return decorateType (otree, RESULT_TYPE_NONE);
2844 /* if left is a literal exchange left & right */
2845 if (IS_LITERAL (LTYPE (tree)))
2847 ast *tTree = tree->left;
2848 tree->left = tree->right;
2849 tree->right = tTree;
2852 /* if right is a literal and */
2853 /* we can find a 2nd literal in an and-tree then */
2854 /* rearrange the tree */
2855 if (IS_LITERAL (RTYPE (tree)))
2858 ast *litTree = searchLitOp (tree, &parent, "&");
2862 ast *tTree = litTree->left;
2863 litTree->left = tree->right;
2864 tree->right = tTree;
2865 /* both operands in litTree are literal now */
2866 decorateType (parent, resultType);
2870 LRVAL (tree) = RRVAL (tree) = 1;
2872 TTYPE (tree) = computeType (LTYPE (tree),
2876 TETYPE (tree) = getSpec (TTYPE (tree));
2881 /*------------------------------------------------------------------*/
2882 /*----------------------------*/
2884 /*----------------------------*/
2885 p = newLink (DECLARATOR);
2886 /* if bit field then error */
2887 if (IS_BITVAR (tree->left->etype))
2889 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
2890 goto errorTreeReturn;
2893 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2895 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
2896 goto errorTreeReturn;
2899 if (IS_FUNC (LTYPE (tree)))
2901 // this ought to be ignored
2902 return (tree->left);
2905 if (IS_LITERAL(LTYPE(tree)))
2907 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
2908 goto errorTreeReturn;
2913 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
2914 goto errorTreeReturn;
2917 DCL_TYPE (p) = POINTER;
2918 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2919 DCL_TYPE (p) = CPOINTER;
2920 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2921 DCL_TYPE (p) = FPOINTER;
2922 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2923 DCL_TYPE (p) = PPOINTER;
2924 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2925 DCL_TYPE (p) = IPOINTER;
2926 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2927 DCL_TYPE (p) = EEPPOINTER;
2928 else if (SPEC_OCLS(tree->left->etype))
2929 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2931 DCL_TYPE (p) = POINTER;
2933 if (IS_AST_SYM_VALUE (tree->left))
2935 AST_SYMBOL (tree->left)->addrtaken = 1;
2936 AST_SYMBOL (tree->left)->allocreq = 1;
2939 p->next = LTYPE (tree);
2941 TETYPE (tree) = getSpec (TTYPE (tree));
2946 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2947 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2949 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2950 AST_SYMBOL(tree->left->right));
2951 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2952 valueFromLit(element->offset));
2955 tree->type = EX_VALUE;
2956 tree->values.literalFromCast = 1;
2962 /*------------------------------------------------------------------*/
2963 /*----------------------------*/
2965 /*----------------------------*/
2967 /* if the rewrite succeeds then don't go any further */
2969 ast *wtree = optimizeRRCRLC (tree);
2971 return decorateType (wtree, RESULT_TYPE_NONE);
2973 wtree = optimizeSWAP (tree);
2975 return decorateType (wtree, RESULT_TYPE_NONE);
2978 /* if left is a literal exchange left & right */
2979 if (IS_LITERAL (LTYPE (tree)))
2981 ast *tTree = tree->left;
2982 tree->left = tree->right;
2983 tree->right = tTree;
2986 /* if right is a literal and */
2987 /* we can find a 2nd literal in an or-tree then */
2988 /* rearrange the tree */
2989 if (IS_LITERAL (RTYPE (tree)))
2992 ast *litTree = searchLitOp (tree, &parent, "|");
2996 ast *tTree = litTree->left;
2997 litTree->left = tree->right;
2998 tree->right = tTree;
2999 /* both operands in tTree are literal now */
3000 decorateType (parent, resultType);
3005 /*------------------------------------------------------------------*/
3006 /*----------------------------*/
3008 /*----------------------------*/
3010 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3012 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3013 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3014 printTypeChain (LTYPE (tree), stderr);
3015 fprintf (stderr, ",");
3016 printTypeChain (RTYPE (tree), stderr);
3017 fprintf (stderr, "\n");
3018 goto errorTreeReturn;
3021 /* if they are both literal then rewrite the tree */
3022 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3024 tree->type = EX_VALUE;
3025 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3026 valFromType (RETYPE (tree)),
3028 tree->right = tree->left = NULL;
3029 TETYPE (tree) = tree->opval.val->etype;
3030 TTYPE (tree) = tree->opval.val->type;
3034 /* if left is a literal exchange left & right */
3035 if (IS_LITERAL (LTYPE (tree)))
3037 ast *tTree = tree->left;
3038 tree->left = tree->right;
3039 tree->right = tTree;
3042 /* if right is a literal and */
3043 /* we can find a 2nd literal in a xor-tree then */
3044 /* rearrange the tree */
3045 if (IS_LITERAL (RTYPE (tree)) &&
3046 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3049 ast *litTree = searchLitOp (tree, &parent, "^");
3053 ast *tTree = litTree->left;
3054 litTree->left = tree->right;
3055 tree->right = tTree;
3056 /* both operands in litTree are literal now */
3057 decorateType (parent, resultType);
3061 LRVAL (tree) = RRVAL (tree) = 1;
3063 TTYPE (tree) = computeType (LTYPE (tree),
3067 TETYPE (tree) = getSpec (TTYPE (tree));
3071 /*------------------------------------------------------------------*/
3072 /*----------------------------*/
3074 /*----------------------------*/
3076 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3078 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
3079 goto errorTreeReturn;
3081 /* if they are both literal then */
3082 /* rewrite the tree */
3083 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3085 tree->type = EX_VALUE;
3086 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
3087 valFromType (RETYPE (tree)));
3088 tree->right = tree->left = NULL;
3089 TETYPE (tree) = getSpec (TTYPE (tree) =
3090 tree->opval.val->type);
3094 LRVAL (tree) = RRVAL (tree) = 1;
3096 TETYPE (tree) = getSpec (TTYPE (tree) =
3097 computeType (LTYPE (tree),
3102 /* if right is a literal and */
3103 /* left is also a division by a literal then */
3104 /* rearrange the tree */
3105 if (IS_LITERAL (RTYPE (tree))
3106 /* avoid infinite loop */
3107 && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 1)
3110 ast *litTree = searchLitOp (tree, &parent, "/");
3113 if (IS_LITERAL (RTYPE (litTree)))
3117 litTree->right = newNode ('*',
3119 copyAst (tree->right));
3120 litTree->right->lineno = tree->lineno;
3122 tree->right->opval.val = constVal ("1");
3123 decorateType (parent, resultType);
3127 /* litTree->left is literal: no gcse possible.
3128 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3129 this would cause an infinit loop. */
3130 parent->decorated = 1;
3131 decorateType (litTree, resultType);
3138 /*------------------------------------------------------------------*/
3139 /*----------------------------*/
3141 /*----------------------------*/
3143 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3145 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3146 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3147 printTypeChain (LTYPE (tree), stderr);
3148 fprintf (stderr, ",");
3149 printTypeChain (RTYPE (tree), stderr);
3150 fprintf (stderr, "\n");
3151 goto errorTreeReturn;
3153 /* if they are both literal then */
3154 /* rewrite the tree */
3155 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3157 tree->type = EX_VALUE;
3158 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3159 valFromType (RETYPE (tree)));
3160 tree->right = tree->left = NULL;
3161 TETYPE (tree) = getSpec (TTYPE (tree) =
3162 tree->opval.val->type);
3165 LRVAL (tree) = RRVAL (tree) = 1;
3166 TETYPE (tree) = getSpec (TTYPE (tree) =
3167 computeType (LTYPE (tree),
3173 /*------------------------------------------------------------------*/
3174 /*----------------------------*/
3175 /* address dereference */
3176 /*----------------------------*/
3177 case '*': /* can be unary : if right is null then unary operation */
3180 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3182 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
3183 goto errorTreeReturn;
3188 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
3189 goto errorTreeReturn;
3191 if (IS_ADDRESS_OF_OP(tree->left))
3193 /* replace *&obj with obj */
3194 return tree->left->left;
3196 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3197 TETYPE (tree) = getSpec (TTYPE (tree));
3198 /* adjust the storage class */
3199 switch (DCL_TYPE(tree->left->ftype)) {
3201 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3204 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3207 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3210 SPEC_SCLS (TETYPE (tree)) = 0;
3213 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3216 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3219 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3222 SPEC_SCLS (TETYPE (tree)) = 0;
3231 /*------------------------------------------------------------------*/
3232 /*----------------------------*/
3233 /* multiplication */
3234 /*----------------------------*/
3235 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3237 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
3238 goto errorTreeReturn;
3241 /* if they are both literal then */
3242 /* rewrite the tree */
3243 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3245 tree->type = EX_VALUE;
3246 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3247 valFromType (RETYPE (tree)));
3248 tree->right = tree->left = NULL;
3249 TETYPE (tree) = getSpec (TTYPE (tree) =
3250 tree->opval.val->type);
3254 /* if left is a literal exchange left & right */
3255 if (IS_LITERAL (LTYPE (tree)))
3257 ast *tTree = tree->left;
3258 tree->left = tree->right;
3259 tree->right = tTree;
3262 /* if right is a literal and */
3263 /* we can find a 2nd literal in a mul-tree then */
3264 /* rearrange the tree */
3265 if (IS_LITERAL (RTYPE (tree)))
3268 ast *litTree = searchLitOp (tree, &parent, "*");
3272 ast *tTree = litTree->left;
3273 litTree->left = tree->right;
3274 tree->right = tTree;
3275 /* both operands in litTree are literal now */
3276 decorateType (parent, resultType);
3280 LRVAL (tree) = RRVAL (tree) = 1;
3281 tree->left = addCast (tree->left, resultTypeProp, FALSE);
3282 tree->right = addCast (tree->right, resultTypeProp, FALSE);
3283 TETYPE (tree) = getSpec (TTYPE (tree) =
3284 computeType (LTYPE (tree),
3291 /*------------------------------------------------------------------*/
3292 /*----------------------------*/
3293 /* unary '+' operator */
3294 /*----------------------------*/
3299 if (!IS_ARITHMETIC (LTYPE (tree)))
3301 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
3302 goto errorTreeReturn;
3305 /* if left is a literal then do it */
3306 if (IS_LITERAL (LTYPE (tree)))
3308 tree->type = EX_VALUE;
3309 tree->opval.val = valFromType (LETYPE (tree));
3311 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3315 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3319 /*------------------------------------------------------------------*/
3320 /*----------------------------*/
3322 /*----------------------------*/
3324 /* this is not a unary operation */
3325 /* if both pointers then problem */
3326 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3327 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3329 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
3330 goto errorTreeReturn;
3333 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3334 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3336 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3337 goto errorTreeReturn;
3340 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3341 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3343 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3344 goto errorTreeReturn;
3346 /* if they are both literal then */
3347 /* rewrite the tree */
3348 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3350 tree->type = EX_VALUE;
3351 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3352 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3353 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3354 valFromType (RETYPE (tree)));
3355 tree->right = tree->left = NULL;
3356 TETYPE (tree) = getSpec (TTYPE (tree) =
3357 tree->opval.val->type);
3361 /* if the right is a pointer or left is a literal
3362 xchange left & right */
3363 if (IS_ARRAY (RTYPE (tree)) ||
3364 IS_PTR (RTYPE (tree)) ||
3365 IS_LITERAL (LTYPE (tree)))
3367 ast *tTree = tree->left;
3368 tree->left = tree->right;
3369 tree->right = tTree;
3372 /* if right is a literal and */
3373 /* left is also an addition/subtraction with a literal then */
3374 /* rearrange the tree */
3375 if (IS_LITERAL (RTYPE (tree)))
3377 ast *litTree, *parent;
3378 litTree = searchLitOp (tree, &parent, "+-");
3381 if (litTree->opval.op == '+')
3385 ast *tTree = litTree->left;
3386 litTree->left = tree->right;
3387 tree->right = tree->left;
3390 else if (litTree->opval.op == '-')
3392 if (IS_LITERAL (RTYPE (litTree)))
3396 ast *tTree = litTree->left;
3397 litTree->left = tree->right;
3398 tree->right = tTree;
3404 ast *tTree = litTree->right;
3405 litTree->right = tree->right;
3406 tree->right = tTree;
3407 litTree->opval.op = '+';
3408 tree->opval.op = '-';
3411 decorateType (parent, resultType);
3415 LRVAL (tree) = RRVAL (tree) = 1;
3416 /* if the left is a pointer */
3417 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3418 TETYPE (tree) = getSpec (TTYPE (tree) =
3422 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3423 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3424 TETYPE (tree) = getSpec (TTYPE (tree) =
3425 computeType (LTYPE (tree),
3433 /*------------------------------------------------------------------*/
3434 /*----------------------------*/
3436 /*----------------------------*/
3437 case '-': /* can be unary */
3438 /* if right is null then unary */
3442 if (!IS_ARITHMETIC (LTYPE (tree)))
3444 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3445 goto errorTreeReturn;
3448 /* if left is a literal then do it */
3449 if (IS_LITERAL (LTYPE (tree)))
3451 tree->type = EX_VALUE;
3452 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3454 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3457 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3458 TETYPE (tree) = getSpec (TTYPE (tree) =
3459 computeType (LTYPE (tree),
3467 /*------------------------------------------------------------------*/
3468 /*----------------------------*/
3470 /*----------------------------*/
3472 if (!(IS_PTR (LTYPE (tree)) ||
3473 IS_ARRAY (LTYPE (tree)) ||
3474 IS_ARITHMETIC (LTYPE (tree))))
3476 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3477 goto errorTreeReturn;
3480 if (!(IS_PTR (RTYPE (tree)) ||
3481 IS_ARRAY (RTYPE (tree)) ||
3482 IS_ARITHMETIC (RTYPE (tree))))
3484 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3485 goto errorTreeReturn;
3488 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3489 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3490 IS_INTEGRAL (RTYPE (tree))))
3492 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3493 goto errorTreeReturn;
3496 /* if they are both literal then */
3497 /* rewrite the tree */
3498 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3500 tree->type = EX_VALUE;
3501 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3502 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3503 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3504 valFromType (RETYPE (tree)));
3505 tree->right = tree->left = NULL;
3506 TETYPE (tree) = getSpec (TTYPE (tree) =
3507 tree->opval.val->type);
3511 /* if the left & right are equal then zero */
3512 if (isAstEqual (tree->left, tree->right))
3514 tree->type = EX_VALUE;
3515 tree->left = tree->right = NULL;
3516 tree->opval.val = constVal ("0");
3517 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3521 /* if both of them are pointers or arrays then */
3522 /* the result is going to be an integer */
3523 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3524 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3525 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3527 /* if only the left is a pointer */
3528 /* then result is a pointer */
3529 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3530 TETYPE (tree) = getSpec (TTYPE (tree) =
3534 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3535 tree->right = addCast (tree->right, resultTypeProp, TRUE);
3537 TETYPE (tree) = getSpec (TTYPE (tree) =
3538 computeType (LTYPE (tree),
3544 LRVAL (tree) = RRVAL (tree) = 1;
3546 /* if right is a literal and */
3547 /* left is also an addition/subtraction with a literal then */
3548 /* rearrange the tree */
3549 if (IS_LITERAL (RTYPE (tree))
3550 /* avoid infinite loop */
3551 && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 0)
3553 ast *litTree, *litParent;
3554 litTree = searchLitOp (tree, &litParent, "+-");
3557 if (litTree->opval.op == '+')
3561 ast *tTree = litTree->left;
3562 litTree->left = litTree->right;
3563 litTree->right = tree->right;
3564 tree->right = tTree;
3565 tree->opval.op = '+';
3566 litTree->opval.op = '-';
3568 else if (litTree->opval.op == '-')
3570 if (IS_LITERAL (RTYPE (litTree)))
3574 ast *tTree = litTree->left;
3575 litTree->left = tree->right;
3576 tree->right = litParent->left;
3577 litParent->left = tTree;
3578 litTree->opval.op = '+';
3580 tree->decorated = 0;
3581 decorateType (tree, resultType);
3587 ast *tTree = litTree->right;
3588 litTree->right = tree->right;
3589 tree->right = tTree;
3592 decorateType (litParent, resultType);
3597 /*------------------------------------------------------------------*/
3598 /*----------------------------*/
3600 /*----------------------------*/
3602 /* can be only integral type */
3603 if (!IS_INTEGRAL (LTYPE (tree)))
3605 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3606 goto errorTreeReturn;
3609 /* if left is a literal then do it */
3610 if (IS_LITERAL (LTYPE (tree)))
3612 tree->type = EX_VALUE;
3613 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3615 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3616 return addCast (tree, resultTypeProp, TRUE);
3619 if (resultType == RESULT_TYPE_BIT &&
3620 IS_UNSIGNED (tree->left->etype) &&
3621 getSize (tree->left->etype) < INTSIZE)
3623 /* promotion rules are responsible for this strange result:
3624 bit -> int -> ~int -> bit
3625 uchar -> int -> ~int -> bit
3627 werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
3629 /* optimize bit-result, even if we optimize a buggy source */
3630 tree->type = EX_VALUE;
3631 tree->opval.val = constVal ("1");
3634 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3636 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3639 /*------------------------------------------------------------------*/
3640 /*----------------------------*/
3642 /*----------------------------*/
3644 /* can be pointer */
3645 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3646 !IS_PTR (LTYPE (tree)) &&
3647 !IS_ARRAY (LTYPE (tree)))
3649 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3650 goto errorTreeReturn;
3653 /* if left is another '!' */
3654 if (IS_AST_NOT_OPER (tree->left))
3656 if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
3658 /* replace double '!!X' by 'X' */
3659 return tree->left->left;
3661 /* remove double '!!X' by 'X ? 1 : 0' */
3662 tree->opval.op = '?';
3663 tree->left = tree->left->left;
3664 tree->right = newNode (':',
3665 newAst_VALUE (constVal ("1")),
3666 newAst_VALUE (constVal ("0")));
3667 tree->right->lineno = tree->lineno;
3668 tree->decorated = 0;
3669 return decorateType (tree, resultType);
3672 /* if left is a literal then do it */
3673 if (IS_LITERAL (LTYPE (tree)))
3675 tree->type = EX_VALUE;
3676 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3678 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3682 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3685 /*------------------------------------------------------------------*/
3686 /*----------------------------*/
3688 /*----------------------------*/
3692 TTYPE (tree) = LTYPE (tree);
3693 TETYPE (tree) = LETYPE (tree);
3698 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3702 TTYPE (tree) = TETYPE (tree) = newCharLink();
3706 TTYPE (tree) = TETYPE (tree) = newIntLink();
3711 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3713 werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
3714 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3715 printTypeChain (LTYPE (tree), stderr);
3716 fprintf (stderr, ",");
3717 printTypeChain (RTYPE (tree), stderr);
3718 fprintf (stderr, "\n");
3719 goto errorTreeReturn;
3722 /* make smaller type only if it's a LEFT_OP */
3723 if (tree->opval.op == LEFT_OP)
3724 tree->left = addCast (tree->left, resultTypeProp, TRUE);
3726 /* if they are both literal then */
3727 /* rewrite the tree */
3728 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3730 tree->type = EX_VALUE;
3731 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3732 valFromType (RETYPE (tree)),
3733 (tree->opval.op == LEFT_OP ? 1 : 0));
3734 tree->right = tree->left = NULL;
3735 TETYPE (tree) = getSpec (TTYPE (tree) =
3736 tree->opval.val->type);
3740 /* see if this is a GETBYTE operation if yes
3743 ast *otree = optimizeGetByte (tree, resultType);
3746 return decorateType (otree, RESULT_TYPE_NONE);
3749 /* see if this is a GETWORD operation if yes
3752 ast *otree = optimizeGetWord (tree, resultType);
3755 return decorateType (otree, RESULT_TYPE_NONE);
3758 LRVAL (tree) = RRVAL (tree) = 1;
3759 if (tree->opval.op == LEFT_OP)
3761 TETYPE (tree) = getSpec (TTYPE (tree) =
3762 computeType (LTYPE (tree),
3769 /* no promotion necessary */
3770 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3771 if (IS_LITERAL (TTYPE (tree)))
3772 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3775 /* if only the right side is a literal & we are
3776 shifting more than size of the left operand then zero */
3777 if (IS_LITERAL (RTYPE (tree)) &&
3778 ((TYPE_TARGET_ULONG) ulFromVal (valFromType (RETYPE (tree)))) >=
3779 (getSize (TETYPE (tree)) * 8))
3781 if (tree->opval.op==LEFT_OP ||
3782 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3784 werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
3785 (tree->opval.op == LEFT_OP ? "left" : "right"));
3786 tree->type = EX_VALUE;
3787 tree->left = tree->right = NULL;
3788 tree->opval.val = constVal ("0");
3789 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3796 /*------------------------------------------------------------------*/
3797 /*----------------------------*/
3799 /*----------------------------*/
3800 case CAST: /* change the type */
3801 /* cannot cast to an aggregate type */
3802 if (IS_AGGREGATE (LTYPE (tree)))
3804 werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
3805 goto errorTreeReturn;
3808 /* make sure the type is complete and sane */
3809 changePointer(LTYPE(tree));
3810 checkTypeSanity(LETYPE(tree), "(cast)");
3812 /* if 'from' and 'to' are the same remove the superfluous cast, */
3813 /* this helps other optimizations */
3814 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3819 /* If code memory is read only, then pointers to code memory */
3820 /* implicitly point to constants -- make this explicit */
3822 sym_link *t = LTYPE(tree);
3823 while (t && t->next)
3825 if (IS_CODEPTR(t) && port->mem.code_ro)
3827 if (IS_SPEC(t->next))
3828 SPEC_CONST (t->next) = 1;
3830 DCL_PTR_CONST (t->next) = 1;
3837 /* if the right is a literal replace the tree */
3838 if (IS_LITERAL (RETYPE (tree))) {
3839 if (!IS_PTR (LTYPE (tree))) {
3840 tree->type = EX_VALUE;
3842 valCastLiteral (LTYPE (tree),
3843 floatFromVal (valFromType (RETYPE (tree))));
3846 TTYPE (tree) = tree->opval.val->type;
3847 tree->values.literalFromCast = 1;
3848 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3849 ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3850 sym_link *rest = LTYPE(tree)->next;
3851 werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
3852 TTYPE(tree) = newLink(DECLARATOR);
3853 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3854 TTYPE(tree)->next = rest;
3855 tree->left->opval.lnk = TTYPE(tree);
3858 TTYPE (tree) = LTYPE (tree);
3862 TTYPE (tree) = LTYPE (tree);
3866 #if 0 // this is already checked, now this could be explicit
3867 /* if pointer to struct then check names */
3868 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3869 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3870 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3872 werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3873 SPEC_STRUCT(LETYPE(tree))->tag);
3876 if (IS_ADDRESS_OF_OP(tree->right)
3877 && IS_AST_SYM_VALUE (tree->right->left)
3878 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3880 symbol * sym = AST_SYMBOL (tree->right->left);
3881 unsigned int gptype = 0;
3882 unsigned int addr = SPEC_ADDR (sym->etype);
3884 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
3885 || TARGET_IS_PIC16) )
3887 switch (SPEC_SCLS (sym->etype))
3890 gptype = GPTYPE_CODE;
3893 gptype = GPTYPE_FAR;
3897 gptype = GPTYPE_NEAR;
3900 gptype = GPTYPE_XSTACK;
3905 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3906 gptype = GPTYPE_NEAR;
3908 addr |= gptype << (8*(GPTRSIZE - 1));
3911 tree->type = EX_VALUE;
3913 valCastLiteral (LTYPE (tree), addr);
3914 TTYPE (tree) = tree->opval.val->type;
3915 TETYPE (tree) = getSpec (TTYPE (tree));
3918 tree->values.literalFromCast = 1;
3922 /* handle offsetof macro: */
3923 /* #define offsetof(TYPE, MEMBER) \ */
3924 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3925 if (IS_ADDRESS_OF_OP(tree->right)
3926 && IS_AST_OP (tree->right->left)
3927 && tree->right->left->opval.op == PTR_OP
3928 && IS_AST_OP (tree->right->left->left)
3929 && tree->right->left->left->opval.op == CAST
3930 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3932 symbol *element = getStructElement (
3933 SPEC_STRUCT (LETYPE(tree->right->left)),
3934 AST_SYMBOL(tree->right->left->right)
3938 tree->type = EX_VALUE;
3939 tree->opval.val = valCastLiteral (
3942 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3945 TTYPE (tree) = tree->opval.val->type;
3946 TETYPE (tree) = getSpec (TTYPE (tree));
3953 /* if the right is a literal replace the tree */
3954 if (IS_LITERAL (RETYPE (tree))) {
3956 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3957 /* rewrite (type *)litaddr
3959 and define type at litaddr temp
3960 (but only if type's storage class is not generic)
3962 ast *newTree = newNode ('&', NULL, NULL);
3965 TTYPE (newTree) = LTYPE (tree);
3966 TETYPE (newTree) = getSpec(LTYPE (tree));
3968 /* define a global symbol at the casted address*/
3969 sym = newSymbol(genSymName (0), 0);
3970 sym->type = LTYPE (tree)->next;
3972 sym->type = newLink (V_VOID);
3973 sym->etype = getSpec(sym->type);
3974 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3975 sym->lineDef = tree->lineno;
3978 SPEC_STAT (sym->etype) = 1;
3979 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3980 SPEC_ABSA(sym->etype) = 1;
3981 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3984 newTree->left = newAst_VALUE(symbolVal(sym));
3985 newTree->left->lineno = tree->lineno;
3986 LTYPE (newTree) = sym->type;
3987 LETYPE (newTree) = sym->etype;
3988 LLVAL (newTree) = 1;
3989 LRVAL (newTree) = 0;
3990 TLVAL (newTree) = 1;
3994 if (!IS_PTR (LTYPE (tree))) {
3995 tree->type = EX_VALUE;
3997 valCastLiteral (LTYPE (tree),
3998 floatFromVal (valFromType (RTYPE (tree))));
3999 TTYPE (tree) = tree->opval.val->type;
4002 tree->values.literalFromCast = 1;
4003 TETYPE (tree) = getSpec (TTYPE (tree));
4007 TTYPE (tree) = LTYPE (tree);
4011 TETYPE (tree) = getSpec (TTYPE (tree));
4015 /*------------------------------------------------------------------*/
4016 /*----------------------------*/
4017 /* logical &&, || */
4018 /*----------------------------*/
4021 /* each must be arithmetic type or be a pointer */
4022 if (!IS_PTR (LTYPE (tree)) &&
4023 !IS_ARRAY (LTYPE (tree)) &&
4024 !IS_INTEGRAL (LTYPE (tree)))
4026 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4027 goto errorTreeReturn;
4030 if (!IS_PTR (RTYPE (tree)) &&
4031 !IS_ARRAY (RTYPE (tree)) &&
4032 !IS_INTEGRAL (RTYPE (tree)))
4034 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4035 goto errorTreeReturn;
4037 /* if they are both literal then */
4038 /* rewrite the tree */
4039 if (IS_LITERAL (RTYPE (tree)) &&
4040 IS_LITERAL (LTYPE (tree)))
4042 tree->type = EX_VALUE;
4043 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4044 valFromType (RTYPE (tree)),
4046 tree->right = tree->left = NULL;
4047 TETYPE (tree) = getSpec (TTYPE (tree) =
4048 tree->opval.val->type);
4051 LRVAL (tree) = RRVAL (tree) = 1;
4052 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4055 /*------------------------------------------------------------------*/
4056 /*----------------------------*/
4057 /* comparison operators */
4058 /*----------------------------*/
4066 ast *lt = optimizeCompare (tree);
4072 /* if they are pointers they must be castable */
4073 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4075 if (tree->opval.op==EQ_OP &&
4076 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4077 // we cannot cast a gptr to a !gptr: switch the leaves
4078 struct ast *s=tree->left;
4079 tree->left=tree->right;
4082 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4084 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4085 fprintf (stderr, "comparing type ");
4086 printTypeChain (LTYPE (tree), stderr);
4087 fprintf (stderr, "to type ");
4088 printTypeChain (RTYPE (tree), stderr);
4089 fprintf (stderr, "\n");
4090 goto errorTreeReturn;
4093 /* else they should be promotable to one another */
4096 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4097 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4099 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4101 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4102 fprintf (stderr, "comparing type ");
4103 printTypeChain (LTYPE (tree), stderr);
4104 fprintf (stderr, "to type ");
4105 printTypeChain (RTYPE (tree), stderr);
4106 fprintf (stderr, "\n");
4107 goto errorTreeReturn;
4112 CCR_RESULT ccr_result = CCR_OK;
4114 /* if left is integral and right is literal
4115 then check constant range */
4116 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4117 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4118 tree->opval.op, FALSE);
4119 if (ccr_result == CCR_OK &&
4120 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4121 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4122 tree->opval.op, TRUE);
4125 case CCR_ALWAYS_TRUE:
4126 case CCR_ALWAYS_FALSE:
4127 if (!options.lessPedantic)
4128 werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
4129 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4130 return decorateType (newAst_VALUE (constVal (
4131 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4139 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4140 if (tree->opval.op == '>' &&
4141 SPEC_USIGN(LETYPE(tree)) &&
4142 IS_LITERAL(RTYPE(tree)) &&
4143 ((int) ulFromVal (valFromType (RETYPE (tree)))) == 0)
4145 if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
4147 /* the parent is an ifx: */
4148 /* if (unsigned value) */
4152 /* (unsigned value) ? 1 : 0 */
4153 tree->opval.op = '?';
4154 tree->right = newNode (':',
4155 newAst_VALUE (constVal ("1")),
4156 tree->right); /* val 0 */
4157 tree->right->lineno = tree->lineno;
4158 tree->right->left->lineno = tree->lineno;
4159 tree->decorated = 0;
4160 return decorateType (tree, resultType);
4163 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4164 if (IS_LITERAL(RTYPE(tree)) &&
4165 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4166 tree->opval.op == EQ_OP &&
4167 (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT))
4169 tree->opval.op = '!';
4171 tree->decorated = 0;
4172 return decorateType (tree, resultType);
4175 /* if they are both literal then */
4176 /* rewrite the tree */
4177 if (IS_LITERAL (RTYPE (tree)) &&
4178 IS_LITERAL (LTYPE (tree)))
4180 tree->type = EX_VALUE;
4181 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4182 valFromType (RETYPE (tree)),
4184 tree->right = tree->left = NULL;
4185 TETYPE (tree) = getSpec (TTYPE (tree) =
4186 tree->opval.val->type);
4190 /* if one is 'signed char ' and the other one is 'unsigned char' */
4191 /* it's necessary to promote to int */
4192 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4193 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4195 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4196 if it's possible to use a 'signed char' */
4198 /* is left a 'unsigned char'? */
4199 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4200 /* the value range of a 'unsigned char' is 0...255;
4201 if the actual value is < 128 it can be changed to signed */
4202 (int) ulFromVal (valFromType (RETYPE (tree))) < 128)
4204 /* now we've got 2 'signed char'! */
4205 SPEC_USIGN (RETYPE (tree)) = 0;
4207 /* same test for the left operand: */
4208 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4209 (int) ulFromVal (valFromType (LETYPE (tree))) < 128)
4211 SPEC_USIGN (LETYPE (tree)) = 0;
4215 werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
4216 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4217 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4221 LRVAL (tree) = RRVAL (tree) = 1;
4222 TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4224 /* condition transformations */
4226 unsigned transformedOp = 0;
4228 switch (tree->opval.op)
4230 case '<': /* transform (a < b) to !(a >= b) */
4232 transformedOp = GE_OP;
4234 case '>': /* transform (a > b) to !(a <= b) */
4236 transformedOp = LE_OP;
4238 case LE_OP: /* transform (a <= b) to !(a > b) */
4240 transformedOp = '>';
4242 case GE_OP: /* transform (a >= b) to !(a < b) */
4244 transformedOp = '<';
4246 case NE_OP: /* transform (a != b) to !(a == b) */
4248 transformedOp = EQ_OP;
4250 case EQ_OP: /* transform (a == b) to !(a != b) */
4252 transformedOp = NE_OP;
4259 tree->opval.op = transformedOp;
4260 tree->decorated = 0;
4261 tree = newNode ('!', tree, NULL);
4262 tree->lineno = tree->left->lineno;
4263 return decorateType (tree, resultType);
4269 /*------------------------------------------------------------------*/
4270 /*----------------------------*/
4272 /*----------------------------*/
4273 case SIZEOF: /* evaluate wihout code generation */
4274 /* change the type to a integer */
4276 int size = getSize (tree->right->ftype);
4278 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4279 if (!size && !IS_VOID(tree->right->ftype))
4280 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4282 tree->type = EX_VALUE;
4283 tree->opval.val = constVal (buffer);
4284 tree->right = tree->left = NULL;
4285 TETYPE (tree) = getSpec (TTYPE (tree) =
4286 tree->opval.val->type);
4290 /*------------------------------------------------------------------*/
4291 /*----------------------------*/
4293 /*----------------------------*/
4295 /* return typeof enum value */
4296 tree->type = EX_VALUE;
4299 if (IS_SPEC(tree->right->ftype)) {
4300 switch (SPEC_NOUN(tree->right->ftype)) {
4302 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4303 else typeofv = TYPEOF_INT;
4306 typeofv = TYPEOF_FLOAT;
4309 typeofv = TYPEOF_FIXED16X16;
4312 typeofv = TYPEOF_CHAR;
4315 typeofv = TYPEOF_VOID;
4318 typeofv = TYPEOF_STRUCT;
4321 typeofv = TYPEOF_BITFIELD;
4324 typeofv = TYPEOF_BIT;
4327 typeofv = TYPEOF_SBIT;
4333 switch (DCL_TYPE(tree->right->ftype)) {
4335 typeofv = TYPEOF_POINTER;
4338 typeofv = TYPEOF_FPOINTER;
4341 typeofv = TYPEOF_CPOINTER;
4344 typeofv = TYPEOF_GPOINTER;
4347 typeofv = TYPEOF_PPOINTER;
4350 typeofv = TYPEOF_IPOINTER;
4353 typeofv = TYPEOF_ARRAY;
4356 typeofv = TYPEOF_FUNCTION;
4362 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4363 tree->opval.val = constVal (buffer);
4364 tree->right = tree->left = NULL;
4365 TETYPE (tree) = getSpec (TTYPE (tree) =
4366 tree->opval.val->type);
4369 /*------------------------------------------------------------------*/
4370 /*----------------------------*/
4371 /* conditional operator '?' */
4372 /*----------------------------*/
4374 /* the type is value of the colon operator (on the right) */
4375 assert (IS_COLON_OP (tree->right));
4377 /* If already known then replace the tree : optimizer will do it
4378 but faster to do it here. If done before decorating tree->right
4379 this can save generating unused const strings. */
4380 if (IS_LITERAL (LTYPE (tree)))
4382 if (((int) ulFromVal (valFromType (LETYPE (tree)))) != 0)
4383 return decorateType (tree->right->left, resultTypeProp);
4385 return decorateType (tree->right->right, resultTypeProp);
4388 tree->right = decorateType (tree->right, resultTypeProp);
4390 if (IS_AST_LIT_VALUE (tree->right->left) && IS_AST_LIT_VALUE (tree->right->right) &&
4391 ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)))
4393 double valTrue = AST_FLOAT_VALUE (tree->right->left);
4394 double valFalse = AST_FLOAT_VALUE (tree->right->right);
4396 if ((valTrue != 0) && (valFalse == 0))
4398 /* assign cond to result */
4399 tree->left->decorated = 0;
4400 return decorateType (tree->left, resultTypeProp);
4402 else if ((valTrue == 0) && (valFalse != 0))
4404 /* assign !cond to result */
4405 tree->opval.op = '!';
4406 tree->decorated = 0;
4408 return decorateType (tree, resultTypeProp);
4412 /* they have the same boolean value, make them equal */
4413 tree->right->left = tree->right->right;
4417 /* if they are equal then replace the tree */
4418 if (isAstEqual (tree->right->left, tree->right->right))
4420 return tree->right->left;
4423 TTYPE (tree) = RTYPE (tree);
4424 TETYPE (tree) = getSpec (TTYPE (tree));
4428 /* if they don't match we have a problem */
4429 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4430 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4432 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
4433 goto errorTreeReturn;
4436 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4437 resultType, tree->opval.op);
4438 TETYPE (tree) = getSpec (TTYPE (tree));
4442 #if 0 // assignment operators are converted by the parser
4443 /*------------------------------------------------------------------*/
4444 /*----------------------------*/
4445 /* assignment operators */
4446 /*----------------------------*/
4449 /* for these it must be both must be integral */
4450 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4451 !IS_ARITHMETIC (RTYPE (tree)))
4453 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4454 goto errorTreeReturn;
4457 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4459 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4460 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4464 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4465 goto errorTreeReturn;
4476 /* for these it must be both must be integral */
4477 if (!IS_INTEGRAL (LTYPE (tree)) ||
4478 !IS_INTEGRAL (RTYPE (tree)))
4480 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4481 goto errorTreeReturn;
4484 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4486 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4487 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4491 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4492 goto errorTreeReturn;
4498 /*------------------------------------------------------------------*/
4499 /*----------------------------*/
4501 /*----------------------------*/
4503 if (!(IS_PTR (LTYPE (tree)) ||
4504 IS_ARITHMETIC (LTYPE (tree))))
4506 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4507 goto errorTreeReturn;
4510 if (!(IS_PTR (RTYPE (tree)) ||
4511 IS_ARITHMETIC (RTYPE (tree))))
4513 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4514 goto errorTreeReturn;
4517 TETYPE (tree) = getSpec (TTYPE (tree) =
4518 computeType (LTYPE (tree),
4523 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4524 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
4528 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
4529 goto errorTreeReturn;
4535 /*------------------------------------------------------------------*/
4536 /*----------------------------*/
4538 /*----------------------------*/
4540 /* this is not a unary operation */
4541 /* if both pointers then problem */
4542 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4544 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
4545 goto errorTreeReturn;
4548 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4550 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4551 goto errorTreeReturn;
4554 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4556 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4557 goto errorTreeReturn;
4560 TETYPE (tree) = getSpec (TTYPE (tree) =
4561 computeType (LTYPE (tree),
4566 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4567 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
4571 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
4572 goto errorTreeReturn;
4575 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4576 tree->opval.op = '=';
4581 /*------------------------------------------------------------------*/
4582 /*----------------------------*/
4583 /* straight assignemnt */
4584 /*----------------------------*/
4586 /* cannot be an aggregate */
4587 if (IS_AGGREGATE (LTYPE (tree)))
4589 werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
4590 goto errorTreeReturn;
4593 /* they should either match or be castable */
4594 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4596 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
4597 printFromToType(RTYPE(tree),LTYPE(tree));
4600 /* if the left side of the tree is of type void
4601 then report error */
4602 if (IS_VOID (LTYPE (tree)))
4604 werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
4605 printFromToType(RTYPE(tree), LTYPE(tree));
4608 TETYPE (tree) = getSpec (TTYPE (tree) =
4612 if (!tree->initMode ) {
4613 if (IS_CONSTANT(LTYPE(tree)))
4614 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
4618 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
4619 goto errorTreeReturn;
4624 /*------------------------------------------------------------------*/
4625 /*----------------------------*/
4626 /* comma operator */
4627 /*----------------------------*/
4629 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4632 /*------------------------------------------------------------------*/
4633 /*----------------------------*/
4635 /*----------------------------*/
4638 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4639 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4641 if (tree->left->opval.op == '*' && !tree->left->right)
4642 tree->left = tree->left->left;
4645 /* require a function or pointer to function */
4646 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4648 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4649 goto errorTreeReturn;
4652 /* if there are parms, make sure that
4653 parms are decorate / process / reverse only once */
4655 !tree->right->decorated)
4660 if (IS_FUNCPTR (LTYPE (tree)))
4662 functype = LTYPE (tree)->next;
4663 processFuncPtrArgs (functype);
4666 functype = LTYPE (tree);
4668 if (processParms (tree->left, FUNC_ARGS(functype),
4669 &tree->right, &parmNumber, TRUE))
4671 goto errorTreeReturn;
4674 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4675 !IFFUNC_ISBUILTIN(functype))
4677 reverseParms (tree->right);
4680 TTYPE (tree) = functype->next;
4681 TETYPE (tree) = getSpec (TTYPE (tree));
4685 /*------------------------------------------------------------------*/
4686 /*----------------------------*/
4687 /* return statement */
4688 /*----------------------------*/
4693 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4695 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4696 printFromToType (RTYPE(tree), currFunc->type->next);
4697 goto errorTreeReturn;
4700 if (IS_VOID (currFunc->type->next)
4702 !IS_VOID (RTYPE (tree)))
4704 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4705 goto errorTreeReturn;
4708 /* if there is going to be a casting required then add it */
4709 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4712 decorateType (newNode (CAST,
4713 newAst_LINK (copyLinkChain (currFunc->type->next)),
4723 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4725 werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
4726 goto errorTreeReturn;
4729 TTYPE (tree) = TETYPE (tree) = NULL;
4732 /*------------------------------------------------------------------*/
4733 /*----------------------------*/
4734 /* switch statement */
4735 /*----------------------------*/
4737 /* the switch value must be an integer */
4738 if (!IS_INTEGRAL (LTYPE (tree)))
4740 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4741 goto errorTreeReturn;
4744 TTYPE (tree) = TETYPE (tree) = NULL;
4747 /*------------------------------------------------------------------*/
4748 /*----------------------------*/
4750 /*----------------------------*/
4752 tree->left = backPatchLabels (tree->left,
4755 TTYPE (tree) = TETYPE (tree) = NULL;
4758 /*------------------------------------------------------------------*/
4759 /*----------------------------*/
4761 /*----------------------------*/
4764 AST_FOR (tree, initExpr) = decorateType (
4765 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4766 AST_FOR (tree, condExpr) = decorateType (
4767 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4768 AST_FOR (tree, loopExpr) = decorateType (
4769 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4771 /* if the for loop is reversible then
4772 reverse it otherwise do what we normally
4778 if (isLoopReversible (tree, &sym, &init, &end))
4779 return reverseLoop (tree, sym, init, end);
4781 return decorateType (createFor (AST_FOR (tree, trueLabel),
4782 AST_FOR (tree, continueLabel),
4783 AST_FOR (tree, falseLabel),
4784 AST_FOR (tree, condLabel),
4785 AST_FOR (tree, initExpr),
4786 AST_FOR (tree, condExpr),
4787 AST_FOR (tree, loopExpr),
4788 tree->left), RESULT_TYPE_NONE);
4791 werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
4792 "node PARAM shouldn't be processed here");
4793 /* but in processParams() */
4796 TTYPE (tree) = TETYPE (tree) = NULL;
4800 /* some error found this tree will be killed */
4802 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4803 tree->opval.op = NULLOP;
4809 /*-----------------------------------------------------------------*/
4810 /* sizeofOp - processes size of operation */
4811 /*-----------------------------------------------------------------*/
4813 sizeofOp (sym_link * type)
4818 /* make sure the type is complete and sane */
4819 checkTypeSanity(type, "(sizeof)");
4821 /* get the size and convert it to character */
4822 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4823 if (!size && !IS_VOID(type))
4824 werror (E_SIZEOF_INCOMPLETE_TYPE);
4826 /* now convert into value */
4827 return constVal (buff);
4831 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4832 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4833 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4834 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4835 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4836 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4837 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4839 /*-----------------------------------------------------------------*/
4840 /* backPatchLabels - change and or not operators to flow control */
4841 /*-----------------------------------------------------------------*/
4843 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4849 /* while-loops insert a label between the IFX and the condition,
4850 therefore look behind the label too */
4851 if (tree->opval.op == LABEL &&
4853 IS_ANDORNOT (tree->right))
4855 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4859 if (!(IS_ANDORNOT (tree)))
4862 /* if this an and */
4865 static int localLbl = 0;
4868 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4869 localLabel = newSymbol (buffer, NestLevel);
4871 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4873 /* if left is already a IFX then just change the if true label in that */
4874 if (!IS_IFX (tree->left))
4875 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4877 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4878 /* right is a IFX then just join */
4879 if (IS_IFX (tree->right))
4880 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4882 tree->right = createLabel (localLabel, tree->right);
4883 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4885 return newNode (NULLOP, tree->left, tree->right);
4888 /* if this is an or operation */
4891 static int localLbl = 0;
4894 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4895 localLabel = newSymbol (buffer, NestLevel);
4897 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4899 /* if left is already a IFX then just change the if true label in that */
4900 if (!IS_IFX (tree->left))
4901 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4903 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4904 /* right is a IFX then just join */
4905 if (IS_IFX (tree->right))
4906 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4908 tree->right = createLabel (localLabel, tree->right);
4909 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4911 return newNode (NULLOP, tree->left, tree->right);
4917 /* call with exchanged labels */
4918 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4920 /* if left isn't already a IFX */
4921 if (!IS_IFX (tree->left))
4923 tree->left = newNode (IFX, tree->left, NULL);
4924 tree->left->trueLabel = falseLabel;
4925 tree->left->falseLabel = trueLabel;
4932 tree->trueLabel = trueLabel;
4933 tree->falseLabel = falseLabel;
4940 /*-----------------------------------------------------------------*/
4941 /* createBlock - create expression tree for block */
4942 /*-----------------------------------------------------------------*/
4944 createBlock (symbol * decl, ast * body)
4948 /* if the block has nothing */
4952 ex = newNode (BLOCK, NULL, body);
4953 ex->values.sym = decl;
4960 /*-----------------------------------------------------------------*/
4961 /* createLabel - creates the expression tree for labels */
4962 /*-----------------------------------------------------------------*/
4964 createLabel (symbol * label, ast * stmnt)
4967 char name[SDCC_NAME_MAX + 1];
4970 /* must create fresh symbol if the symbol name */
4971 /* exists in the symbol table, since there can */
4972 /* be a variable with the same name as the labl */
4973 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4974 (csym->level == label->level))
4975 label = newSymbol (label->name, label->level);
4977 /* change the name before putting it in add _ */
4978 SNPRINTF(name, sizeof(name), "%s", label->name);
4980 /* put the label in the LabelSymbol table */
4981 /* but first check if a label of the same */
4983 if ((csym = findSym (LabelTab, NULL, name)))
4984 werror (E_DUPLICATE_LABEL, label->name);
4986 addSym (LabelTab, label, name, label->level, 0, 0);
4990 label->key = labelKey++;
4991 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4997 /*-----------------------------------------------------------------*/
4998 /* createCase - generates the parsetree for a case statement */
4999 /*-----------------------------------------------------------------*/
5001 createCase (ast * swStat, ast * caseVal, ast * stmnt)
5003 char caseLbl[SDCC_NAME_MAX + 1];
5007 /* if the switch statement does not exist */
5008 /* then case is out of context */
5011 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
5015 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
5016 /* if not a constant then error */
5017 if (!IS_LITERAL (caseVal->ftype))
5019 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
5023 /* if not a integer than error */
5024 if (!IS_INTEGRAL (caseVal->ftype))
5026 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
5030 /* find the end of the switch values chain */
5031 if (!(val = swStat->values.switchVals.swVals))
5032 swStat->values.switchVals.swVals = caseVal->opval.val;
5035 /* also order the cases according to value */
5037 int cVal = (int) ulFromVal (caseVal->opval.val);
5038 while (val && (int) ulFromVal (val) < cVal)
5044 /* if we reached the end then */
5047 pval->next = caseVal->opval.val;
5049 else if ((int) ulFromVal (val) == cVal)
5051 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5057 /* we found a value greater than */
5058 /* the current value we must add this */
5059 /* before the value */
5060 caseVal->opval.val->next = val;
5062 /* if this was the first in chain */
5063 if (swStat->values.switchVals.swVals == val)
5064 swStat->values.switchVals.swVals =
5067 pval->next = caseVal->opval.val;
5072 /* create the case label */
5073 SNPRINTF(caseLbl, sizeof(caseLbl),
5075 swStat->values.switchVals.swNum,
5076 (int) ulFromVal (caseVal->opval.val));
5078 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5083 /*-----------------------------------------------------------------*/
5084 /* createDefault - creates the parse tree for the default statement */
5085 /*-----------------------------------------------------------------*/
5087 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5089 char defLbl[SDCC_NAME_MAX + 1];
5091 /* if the switch statement does not exist */
5092 /* then case is out of context */
5095 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5099 if (swStat->values.switchVals.swDefault)
5101 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5106 /* turn on the default flag */
5107 swStat->values.switchVals.swDefault = 1;
5109 /* create the label */
5110 SNPRINTF (defLbl, sizeof(defLbl),
5111 "_default_%d", swStat->values.switchVals.swNum);
5112 return createLabel (newSymbol (defLbl, 0), stmnt);
5115 /*-----------------------------------------------------------------*/
5116 /* createIf - creates the parsetree for the if statement */
5117 /*-----------------------------------------------------------------*/
5119 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5121 static int Lblnum = 0;
5123 symbol *ifTrue, *ifFalse, *ifEnd;
5125 /* if neither exists */
5126 if (!elseBody && !ifBody) {
5127 // if there are no side effects (i++, j() etc)
5128 if (!hasSEFcalls(condAst)) {
5133 /* create the labels */
5134 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5135 ifFalse = newSymbol (buffer, NestLevel);
5136 /* if no else body then end == false */
5141 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5142 ifEnd = newSymbol (buffer, NestLevel);
5145 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5146 ifTrue = newSymbol (buffer, NestLevel);
5150 /* attach the ifTrue label to the top of it body */
5151 ifBody = createLabel (ifTrue, ifBody);
5152 /* attach a goto end to the ifBody if else is present */
5155 ifBody = newNode (NULLOP, ifBody,
5157 newAst_VALUE (symbolVal (ifEnd)),
5159 /* put the elseLabel on the else body */
5160 elseBody = createLabel (ifFalse, elseBody);
5161 /* out the end at the end of the body */
5162 elseBody = newNode (NULLOP,
5164 createLabel (ifEnd, NULL));
5168 ifBody = newNode (NULLOP, ifBody,
5169 createLabel (ifFalse, NULL));
5171 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5172 if (IS_IFX (condAst))
5175 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5177 return newNode (NULLOP, ifTree,
5178 newNode (NULLOP, ifBody, elseBody));
5182 /*-----------------------------------------------------------------*/
5183 /* createDo - creates parse tree for do */
5186 /* _docontinue_n: */
5187 /* condition_expression +-> trueLabel -> _dobody_n */
5189 /* +-> falseLabel-> _dobreak_n */
5191 /*-----------------------------------------------------------------*/
5193 createDo (symbol * trueLabel, symbol * continueLabel,
5194 symbol * falseLabel, ast * condAst, ast * doBody)
5199 /* if the body does not exist then it is simple */
5202 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5203 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5204 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5205 doTree->trueLabel = continueLabel;
5206 doTree->falseLabel = NULL;
5208 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5212 /* otherwise we have a body */
5213 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5215 /* attach the body label to the top */
5216 doBody = createLabel (trueLabel, doBody);
5217 /* attach the continue label to end of body */
5218 doBody = newNode (NULLOP, doBody,
5219 createLabel (continueLabel, NULL));
5221 /* now put the break label at the end */
5222 if (IS_IFX (condAst))
5225 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5227 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5229 /* putting it together */
5230 return newNode (NULLOP, doBody, doTree);
5233 /*-----------------------------------------------------------------*/
5234 /* createFor - creates parse tree for 'for' statement */
5237 /* condExpr +-> trueLabel -> _forbody_n */
5239 /* +-> falseLabel-> _forbreak_n */
5242 /* _forcontinue_n: */
5244 /* goto _forcond_n ; */
5246 /*-----------------------------------------------------------------*/
5248 createFor (symbol * trueLabel, symbol * continueLabel,
5249 symbol * falseLabel, symbol * condLabel,
5250 ast * initExpr, ast * condExpr, ast * loopExpr,
5255 /* if loopexpression not present then we can generate it */
5256 /* the same way as a while */
5258 return newNode (NULLOP, initExpr,
5259 createWhile (trueLabel, continueLabel,
5260 falseLabel, condExpr, forBody));
5261 /* vanilla for statement */
5262 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5264 if (condExpr && !IS_IFX (condExpr))
5265 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5268 /* attach condition label to condition */
5269 condExpr = createLabel (condLabel, condExpr);
5271 /* attach body label to body */
5272 forBody = createLabel (trueLabel, forBody);
5274 /* attach continue to forLoop expression & attach */
5275 /* goto the forcond @ and of loopExpression */
5276 loopExpr = createLabel (continueLabel,
5280 newAst_VALUE (symbolVal (condLabel)),
5282 /* now start putting them together */
5283 forTree = newNode (NULLOP, initExpr, condExpr);
5284 forTree = newNode (NULLOP, forTree, forBody);
5285 forTree = newNode (NULLOP, forTree, loopExpr);
5286 /* finally add the break label */
5287 forTree = newNode (NULLOP, forTree,
5288 createLabel (falseLabel, NULL));
5292 /*-----------------------------------------------------------------*/
5293 /* createWhile - creates parse tree for while statement */
5294 /* the while statement will be created as follows */
5296 /* _while_continue_n: */
5297 /* condition_expression +-> trueLabel -> _while_boby_n */
5299 /* +-> falseLabel -> _while_break_n */
5300 /* _while_body_n: */
5302 /* goto _while_continue_n */
5303 /* _while_break_n: */
5304 /*-----------------------------------------------------------------*/
5306 createWhile (symbol * trueLabel, symbol * continueLabel,
5307 symbol * falseLabel, ast * condExpr, ast * whileBody)
5311 /* put the continue label */
5312 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5313 condExpr = createLabel (continueLabel, condExpr);
5314 condExpr->lineno = 0;
5316 /* put the body label in front of the body */
5317 whileBody = createLabel (trueLabel, whileBody);
5318 whileBody->lineno = 0;
5319 /* put a jump to continue at the end of the body */
5320 /* and put break label at the end of the body */
5321 whileBody = newNode (NULLOP,
5324 newAst_VALUE (symbolVal (continueLabel)),
5325 createLabel (falseLabel, NULL)));
5327 /* put it all together */
5328 if (IS_IFX (condExpr))
5329 whileTree = condExpr;
5332 whileTree = newNode (IFX, condExpr, NULL);
5333 /* put the true & false labels in place */
5334 whileTree->trueLabel = trueLabel;
5335 whileTree->falseLabel = falseLabel;
5338 return newNode (NULLOP, whileTree, whileBody);
5341 /*-----------------------------------------------------------------*/
5342 /* isShiftRightLitVal _BitAndLitVal - helper function */
5343 /*-----------------------------------------------------------------*/
5345 isShiftRightLitVal_BitAndLitVal (ast * tree)
5347 /* if this is not a bit and */
5348 if (!IS_BITAND (tree))
5351 /* will look for tree of the form
5352 ( expr >> litval2) & litval1 */
5353 if (!IS_AST_LIT_VALUE (tree->right))
5356 if (!IS_RIGHT_OP (tree->left))
5359 if (!IS_AST_LIT_VALUE (tree->left->right))
5362 return tree->left->left;
5365 /*-----------------------------------------------------------------*/
5366 /* isBitAndPowOf2 - helper function */
5367 /*-----------------------------------------------------------------*/
5369 isBitAndPow2 (ast * tree)
5371 /* if this is not a bit and */
5372 if (!IS_BITAND (tree))
5375 /* will look for tree of the form
5376 ( expr & (1 << litval) */
5377 if (!IS_AST_LIT_VALUE (tree->right))
5380 return powof2 (AST_ULONG_VALUE (tree->right));
5383 /*-----------------------------------------------------------------*/
5384 /* optimizeGetHbit - get highest order bit of the expression */
5385 /*-----------------------------------------------------------------*/
5387 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5392 expr = isShiftRightLitVal_BitAndLitVal(tree);
5395 if ((AST_ULONG_VALUE (tree->right) != 1) ||
5396 ((i = AST_ULONG_VALUE (tree->left->right)) !=
5397 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5400 if (!expr && (resultType == RESULT_TYPE_BIT))
5403 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5409 /* make sure the port supports GETHBIT */
5410 if (port->hasExtBitOp
5411 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5414 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5417 /*-----------------------------------------------------------------*/
5418 /* optimizeGetAbit - get a single bit of the expression */
5419 /*-----------------------------------------------------------------*/
5421 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5426 expr = isShiftRightLitVal_BitAndLitVal(tree);
5429 if (AST_ULONG_VALUE (tree->right) != 1)
5431 count = tree->left->right;
5433 if (!expr && (resultType == RESULT_TYPE_BIT))
5435 int p2 = isBitAndPow2 (tree);
5439 count = newAst_VALUE (valueFromLit (p2));
5445 /* make sure the port supports GETABIT */
5446 if (port->hasExtBitOp
5447 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5450 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5454 /*-----------------------------------------------------------------*/
5455 /* optimizeGetByte - get a byte of the expression */
5456 /*-----------------------------------------------------------------*/
5458 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5464 expr = isShiftRightLitVal_BitAndLitVal(tree);
5467 i = AST_ULONG_VALUE (tree->left->right);
5468 count = tree->left->right;
5469 if (AST_ULONG_VALUE (tree->right) != 0xFF)
5472 if (!expr && resultType == RESULT_TYPE_CHAR)
5474 /* if this is a right shift over a multiple of 8 */
5475 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5477 i = AST_ULONG_VALUE (tree->right);
5478 count = tree->right;
5482 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5485 /* make sure the port supports GETBYTE */
5486 if (port->hasExtBitOp
5487 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5490 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5493 /*-----------------------------------------------------------------*/
5494 /* optimizeGetWord - get two bytes of the expression */
5495 /*-----------------------------------------------------------------*/
5497 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5503 expr = isShiftRightLitVal_BitAndLitVal(tree);
5506 i = AST_ULONG_VALUE (tree->left->right);
5507 count = tree->left->right;
5508 if (AST_ULONG_VALUE (tree->right) != 0xFFFF)
5511 if (!expr && resultType == RESULT_TYPE_INT)
5513 /* if this is a right shift over a multiple of 8 */
5514 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5516 i = AST_ULONG_VALUE (tree->right);
5517 count = tree->right;
5521 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5524 /* make sure the port supports GETWORD */
5525 if (port->hasExtBitOp
5526 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5529 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5532 /*-----------------------------------------------------------------*/
5533 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5534 /*-----------------------------------------------------------------*/
5536 optimizeRRCRLC (ast * root)
5538 /* will look for trees of the form
5539 (?expr << 1) | (?expr >> 7) or
5540 (?expr >> 7) | (?expr << 1) will make that
5541 into a RLC : operation ..
5543 (?expr >> 1) | (?expr << 7) or
5544 (?expr << 7) | (?expr >> 1) will make that
5545 into a RRC operation
5546 note : by 7 I mean (number of bits required to hold the
5548 /* if the root operation is not a | operation then not */
5549 if (!IS_BITOR (root))
5552 /* I have to think of a better way to match patterns this sucks */
5553 /* that aside let's start looking for the first case : I use a
5554 negative check a lot to improve the efficiency */
5555 /* (?expr << 1) | (?expr >> 7) */
5556 if (IS_LEFT_OP (root->left) &&
5557 IS_RIGHT_OP (root->right))
5560 if (!SPEC_USIGN (TETYPE (root->left->left)))
5563 if (!IS_AST_LIT_VALUE (root->left->right) ||
5564 !IS_AST_LIT_VALUE (root->right->right))
5567 /* make sure it is the same expression */
5568 if (!isAstEqual (root->left->left,
5572 if (AST_ULONG_VALUE (root->left->right) != 1)
5575 if (AST_ULONG_VALUE (root->right->right) !=
5576 (getSize (TTYPE (root->left->left)) * 8 - 1))
5579 /* make sure the port supports RLC */
5580 if (port->hasExtBitOp
5581 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5584 /* whew got the first case : create the AST */
5585 return newNode (RLC, root->left->left, NULL);
5589 /* check for second case */
5590 /* (?expr >> 7) | (?expr << 1) */
5591 if (IS_LEFT_OP (root->right) &&
5592 IS_RIGHT_OP (root->left))
5595 if (!SPEC_USIGN (TETYPE (root->left->left)))
5598 if (!IS_AST_LIT_VALUE (root->left->right) ||
5599 !IS_AST_LIT_VALUE (root->right->right))
5602 /* make sure it is the same symbol */
5603 if (!isAstEqual (root->left->left,
5607 if (AST_ULONG_VALUE (root->right->right) != 1)
5610 if (AST_ULONG_VALUE (root->left->right) !=
5611 (getSize (TTYPE (root->left->left)) * 8 - 1))
5614 /* make sure the port supports RLC */
5615 if (port->hasExtBitOp
5616 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5619 /* whew got the first case : create the AST */
5620 return newNode (RLC, root->left->left, NULL);
5625 /* third case for RRC */
5626 /* (?symbol >> 1) | (?symbol << 7) */
5627 if (IS_LEFT_OP (root->right) &&
5628 IS_RIGHT_OP (root->left))
5631 if (!SPEC_USIGN (TETYPE (root->left->left)))
5634 if (!IS_AST_LIT_VALUE (root->left->right) ||
5635 !IS_AST_LIT_VALUE (root->right->right))
5638 /* make sure it is the same symbol */
5639 if (!isAstEqual (root->left->left,
5643 if (AST_ULONG_VALUE (root->left->right) != 1)
5646 if (AST_ULONG_VALUE (root->right->right) !=
5647 (getSize (TTYPE (root->left->left)) * 8 - 1))
5650 /* make sure the port supports RRC */
5651 if (port->hasExtBitOp
5652 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5655 /* whew got the first case : create the AST */
5656 return newNode (RRC, root->left->left, NULL);
5660 /* fourth and last case for now */
5661 /* (?symbol << 7) | (?symbol >> 1) */
5662 if (IS_RIGHT_OP (root->right) &&
5663 IS_LEFT_OP (root->left))
5666 if (!SPEC_USIGN (TETYPE (root->left->left)))
5669 if (!IS_AST_LIT_VALUE (root->left->right) ||
5670 !IS_AST_LIT_VALUE (root->right->right))
5673 /* make sure it is the same symbol */
5674 if (!isAstEqual (root->left->left,
5678 if (AST_ULONG_VALUE (root->right->right) != 1)
5681 if (AST_ULONG_VALUE (root->left->right) !=
5682 (getSize (TTYPE (root->left->left)) * 8 - 1))
5685 /* make sure the port supports RRC */
5686 if (port->hasExtBitOp
5687 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5690 /* whew got the first case : create the AST */
5691 return newNode (RRC, root->left->left, NULL);
5695 /* not found return root */
5699 /*-----------------------------------------------------------------*/
5700 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5701 /*-----------------------------------------------------------------*/
5703 optimizeSWAP (ast * root)
5705 /* will look for trees of the form
5706 (?expr << 4) | (?expr >> 4) or
5707 (?expr >> 4) | (?expr << 4) will make that
5708 into a SWAP : operation ..
5709 note : by 4 I mean (number of bits required to hold the
5711 /* if the root operation is not a | operation then not */
5712 if (!IS_BITOR (root))
5715 /* (?expr << 4) | (?expr >> 4) */
5716 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5717 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5720 if (!SPEC_USIGN (TETYPE (root->left->left)))
5723 if (!IS_AST_LIT_VALUE (root->left->right) ||
5724 !IS_AST_LIT_VALUE (root->right->right))
5727 /* make sure it is the same expression */
5728 if (!isAstEqual (root->left->left,
5732 if (AST_ULONG_VALUE (root->left->right) !=
5733 (getSize (TTYPE (root->left->left)) * 4))
5736 if (AST_ULONG_VALUE (root->right->right) !=
5737 (getSize (TTYPE (root->left->left)) * 4))
5740 /* make sure the port supports SWAP */
5741 if (port->hasExtBitOp
5742 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5745 /* found it : create the AST */
5746 return newNode (SWAP, root->left->left, NULL);
5750 /* not found return root */
5754 /*-----------------------------------------------------------------*/
5755 /* optimizeCompare - optimizes compares for bit variables */
5756 /*-----------------------------------------------------------------*/
5758 optimizeCompare (ast * root)
5760 ast *optExpr = NULL;
5763 unsigned int litValue;
5765 /* if nothing then return nothing */
5769 /* if not a compare op then do leaves */
5770 if (!IS_COMPARE_OP (root))
5772 root->left = optimizeCompare (root->left);
5773 root->right = optimizeCompare (root->right);
5777 /* if left & right are the same then depending
5778 of the operation do */
5779 if (isAstEqual (root->left, root->right))
5781 switch (root->opval.op)
5786 optExpr = newAst_VALUE (constVal ("0"));
5791 optExpr = newAst_VALUE (constVal ("1"));
5795 return decorateType (optExpr, RESULT_TYPE_NONE);
5798 vleft = (root->left->type == EX_VALUE ?
5799 root->left->opval.val : NULL);
5801 vright = (root->right->type == EX_VALUE ?
5802 root->right->opval.val : NULL);
5804 /* if left is a BITVAR in BITSPACE */
5805 /* and right is a LITERAL then */
5806 /* optimize else do nothing */
5807 if (vleft && vright &&
5808 IS_BITVAR (vleft->etype) &&
5809 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5810 IS_LITERAL (vright->etype))
5813 /* if right side > 1 then comparison may never succeed */
5814 if ((litValue = (int) ulFromVal (vright)) > 1)
5816 werror (W_BAD_COMPARE);
5822 switch (root->opval.op)
5824 case '>': /* bit value greater than 1 cannot be */
5825 werror (W_BAD_COMPARE);
5829 case '<': /* bit value < 1 means 0 */
5831 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5834 case LE_OP: /* bit value <= 1 means no check */
5835 optExpr = newAst_VALUE (vright);
5838 case GE_OP: /* bit value >= 1 means only check for = */
5840 optExpr = newAst_VALUE (vleft);
5845 { /* literal is zero */
5846 switch (root->opval.op)
5848 case '<': /* bit value < 0 cannot be */
5849 werror (W_BAD_COMPARE);
5853 case '>': /* bit value > 0 means 1 */
5855 optExpr = newAst_VALUE (vleft);
5858 case LE_OP: /* bit value <= 0 means no check */
5859 case GE_OP: /* bit value >= 0 means no check */
5860 werror (W_BAD_COMPARE);
5864 case EQ_OP: /* bit == 0 means ! of bit */
5865 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5869 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5870 } /* end-of-if of BITVAR */
5876 /*-----------------------------------------------------------------*/
5877 /* addSymToBlock : adds the symbol to the first block we find */
5878 /*-----------------------------------------------------------------*/
5880 addSymToBlock (symbol * sym, ast * tree)
5882 /* reached end of tree or a leaf */
5883 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5887 if (IS_AST_OP (tree) &&
5888 tree->opval.op == BLOCK)
5891 symbol *lsym = copySymbol (sym);
5893 lsym->next = AST_VALUES (tree, sym);
5894 AST_VALUES (tree, sym) = lsym;
5898 addSymToBlock (sym, tree->left);
5899 addSymToBlock (sym, tree->right);
5902 /*-----------------------------------------------------------------*/
5903 /* processRegParms - do processing for register parameters */
5904 /*-----------------------------------------------------------------*/
5906 processRegParms (value * args, ast * body)
5910 if (IS_REGPARM (args->etype))
5911 addSymToBlock (args->sym, body);
5916 /*-----------------------------------------------------------------*/
5917 /* resetParmKey - resets the operandkeys for the symbols */
5918 /*-----------------------------------------------------------------*/
5919 DEFSETFUNC (resetParmKey)
5932 /*------------------------------------------------------------------*/
5933 /* fixupInlineLabel - change a label in an inlined function so that */
5934 /* it is always unique no matter how many times */
5935 /* the function is inlined. */
5936 /*------------------------------------------------------------------*/
5938 fixupInlineLabel (symbol * sym)
5940 char name[SDCC_NAME_MAX + 1];
5942 SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
5943 strcpy (sym->name, name);
5947 /*------------------------------------------------------------------*/
5948 /* copyAstLoc - copy location information (file, line, block, etc.) */
5949 /* from one ast node to another */
5950 /*------------------------------------------------------------------*/
5952 copyAstLoc (ast * dest, ast * src)
5954 dest->lineno = src->lineno;
5955 dest->filename = src->filename;
5956 dest->level = src->level;
5957 dest->block = src->block;
5958 dest->seqPoint = src->seqPoint;
5963 /*-----------------------------------------------------------------*/
5964 /* fixupInline - perform various fixups on an inline function tree */
5965 /* to take into account that it is no longer a */
5966 /* stand-alone function. */
5967 /*-----------------------------------------------------------------*/
5969 fixupInline (ast * tree, int level)
5971 tree->block = currBlockno;
5973 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
5980 /* Add any declared variables back into the symbol table */
5981 decls = tree->values.sym;
5984 decls->level = level;
5985 decls->block = currBlockno;
5986 addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0);
5987 decls = decls->next;
5991 tree->level = level;
5993 /* Update symbols */
5994 if (IS_AST_VALUE (tree) &&
5995 tree->opval.val->sym)
5997 symbol * sym = tree->opval.val->sym;
6000 sym->block = currBlockno;
6003 SYM_SPIL_LOC (sym) = NULL;
6006 /* If the symbol is a label, we need to renumber it */
6008 fixupInlineLabel (sym);
6011 /* Update IFX target labels */
6012 if (tree->type == EX_OP && tree->opval.op == IFX)
6014 if (tree->trueLabel)
6015 fixupInlineLabel (tree->trueLabel);
6016 if (tree->falseLabel)
6017 fixupInlineLabel (tree->falseLabel);
6020 /* Replace RETURN with optional assignment and a GOTO to the end */
6021 /* of the inlined function */
6022 if (tree->type == EX_OP && tree->opval.op == RETURN)
6024 ast * assignTree = NULL;
6027 if (inlineState.retsym && tree->right)
6029 assignTree = newNode ('=',
6030 newAst_VALUE (symbolVal (inlineState.retsym)),
6032 copyAstLoc (assignTree, tree);
6035 gotoTree = newNode (GOTO,
6036 newAst_VALUE (symbolVal (inlineState.retlab)),
6038 copyAstLoc (gotoTree, tree);
6040 tree->opval.op = NULLOP;
6041 tree->left = assignTree;
6042 tree->right = gotoTree;
6045 /* Update any children */
6047 fixupInline (tree->left, level);
6049 fixupInline (tree->right, level);
6051 if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
6053 symbol * label = tree->left->opval.val->sym;
6055 label->key = labelKey++;
6056 /* Add this label back into the symbol table */
6057 addSym (LabelTab, label, label->name, label->level, 0, 0);
6061 if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
6067 /*-----------------------------------------------------------------*/
6068 /* inlineAddDecl - add a variable declaration to an ast block. It */
6069 /* is also added to the symbol table if addSymTab */
6071 /*-----------------------------------------------------------------*/
6073 inlineAddDecl (symbol * sym, ast * block, int addSymTab)
6076 SYM_SPIL_LOC (sym) = NULL;
6080 symbol **decl = &(block->values.sym);
6082 sym->level = block->level;
6083 sym->block = block->block;
6087 if (strcmp ((*decl)->name, sym->name) == 0)
6089 decl = &( (*decl)->next );
6095 addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0);
6101 /*-----------------------------------------------------------------*/
6102 /* inlineTempVar - create a temporary variable for inlining */
6103 /*-----------------------------------------------------------------*/
6105 inlineTempVar (sym_link * type, int level)
6109 sym = newSymbol (genSymName(level), level );
6110 sym->type = copyLinkChain (type);
6111 sym->etype = getSpec(sym->type);
6112 SPEC_SCLS (sym->etype) = S_AUTO;
6113 SPEC_OCLS (sym->etype) = NULL;
6114 SPEC_EXTR (sym->etype) = 0;
6115 SPEC_STAT (sym->etype) = 0;
6116 if IS_SPEC (sym->type)
6117 SPEC_VOLATILE (sym->type) = 0;
6119 DCL_PTR_VOLATILE (sym->type) = 0;
6120 SPEC_ABSA (sym->etype) = 0;
6126 /*-----------------------------------------------------------------*/
6127 /* inlineFindParmRecurse - recursive function for inlineFindParm */
6128 /*-----------------------------------------------------------------*/
6130 inlineFindParmRecurse (ast * parms, int *index)
6135 if (parms->type == EX_OP && parms->opval.op == PARAM)
6139 p=inlineFindParmRecurse (parms->left, index);
6142 p=inlineFindParmRecurse (parms->right, index);
6153 /*-----------------------------------------------------------------*/
6154 /* inlineFindParm - search an ast tree of parameters to find one */
6155 /* at a particular index (0=first parameter). */
6156 /* Returns NULL if not found. */
6157 /*-----------------------------------------------------------------*/
6159 inlineFindParm (ast * parms, int index)
6161 return inlineFindParmRecurse (parms, &index);
6164 /*-----------------------------------------------------------------*/
6165 /* inlineFindMaxBlockno - find maximum block number in an ast tree */
6166 /*-----------------------------------------------------------------*/
6168 inlineFindMaxBlockno (ast * tree, int maxBlockno)
6175 tempBlockno = inlineFindMaxBlockno (tree->left, maxBlockno);
6176 if (tempBlockno > maxBlockno)
6177 maxBlockno = tempBlockno;
6179 tempBlockno = inlineFindMaxBlockno (tree->right, maxBlockno);
6180 if (tempBlockno > maxBlockno)
6181 maxBlockno = tempBlockno;
6183 if (tree->block > maxBlockno)
6184 maxBlockno = tree->block;
6191 /*-----------------------------------------------------------------*/
6192 /* expandInlineFuncs - replace calls to inline functions with the */
6193 /* function itself */
6194 /*-----------------------------------------------------------------*/
6196 expandInlineFuncs (ast * tree, ast * block)
6198 if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left
6199 && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym)
6201 symbol * func = tree->left->opval.val->sym;
6204 /* The symbol is probably not bound yet, so find the real one */
6205 csym = findSymWithLevel (SymbolTab, func);
6209 /* Is this an inline function that we can inline? */
6210 if (IFFUNC_ISINLINE (func->type) && func->funcTree)
6212 symbol * retsym = NULL;
6220 /* Generate a label for the inlined function to branch to */
6221 /* in case it contains a return statement */
6222 retlab = newSymbol (genSymName(tree->level+1), tree->level+1 );
6225 inlineState.retlab = retlab;
6227 /* Build the subtree for the inlined function in the form: */
6228 /* { //inlinetree block */
6229 /* { //inlinetree2 block */
6230 /* inline_function_code; */
6234 temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL);
6235 copyAstLoc (temptree, tree);
6236 temptree = newNode (NULLOP, copyAst (func->funcTree), temptree);
6237 copyAstLoc (temptree, tree);
6238 temptree = newNode (BLOCK, NULL, temptree);
6239 copyAstLoc (temptree, tree);
6240 inlinetree2 = temptree;
6241 inlinetree = newNode (BLOCK, NULL, inlinetree2);
6242 copyAstLoc (inlinetree, tree);
6244 /* To pass parameters to the inlined function, we need some */
6245 /* intermediate variables. This avoids scoping problems */
6246 /* when the parameter declaration names are used differently */
6247 /* during the function call. For example, a function */
6248 /* declared as func(int x, int y) but called as func(y,x). */
6249 /* { //inlinetree block */
6250 /* type1 temparg1; */
6252 /* typen tempargn; */
6253 /* temparg1 = argument1; */
6255 /* tempargn = argumentn; */
6256 /* { //inlinetree2 block */
6260 /* param1 = temparg1; */
6262 /* paramn = tempargn; */
6263 /* inline_function_code; */
6267 args = FUNC_ARGS (func->type);
6274 symbol * parm = copySymbol (args->sym);
6276 temparg = inlineTempVar (args->sym->type, tree->level+1);
6277 inlineAddDecl (temparg, inlinetree, FALSE);
6279 passedarg = inlineFindParm (tree->right, argIndex);
6280 assigntree = newNode ('=',
6281 newAst_VALUE (symbolVal (temparg)),
6283 inlinetree->right = newNode (NULLOP,
6287 inlineAddDecl (parm, inlinetree2, FALSE);
6290 assigntree = newNode ('=',
6291 newAst_VALUE (symbolVal (parm)),
6292 newAst_VALUE (symbolVal (temparg)));
6293 inlinetree2->right = newNode (NULLOP,
6295 inlinetree2->right);
6302 /* Handle the return type */
6303 if (!IS_VOID (func->type->next))
6305 /* Create a temporary symbol to hold the return value and */
6306 /* join it with the inlined function using the comma */
6307 /* operator. The fixupInline function will take care of */
6308 /* changing return statements into assignments to retsym. */
6309 /* (parameter passing and return label omitted for clarity) */
6310 /* rettype retsym; */
6312 /* {{inline_function_code}}, retsym */
6314 retsym = inlineTempVar (func->type->next, tree->level);
6315 inlineAddDecl (retsym, block, TRUE);
6317 tree->opval.op = ',';
6318 tree->left = inlinetree;
6319 tree->right = newAst_VALUE (symbolVal (retsym));
6323 tree->opval.op = NULLOP;
6325 tree->right = inlinetree;
6327 inlineState.retsym = retsym;
6329 /* Renumber the various internal counters on the inlined */
6330 /* function's tree nodes and symbols. Add the inlined */
6331 /* function's local variables to the appropriate scope(s). */
6332 /* Convert inlined return statements to an assignment to */
6333 /* retsym (if needed) and a goto retlab. */
6334 fixupInline (inlinetree, inlinetree->level);
6335 inlineState.count++;
6340 /* Recursively continue to search for functions to inline. */
6341 if (IS_AST_OP (tree))
6343 if (tree->opval.op == BLOCK)
6347 expandInlineFuncs (tree->left, block);
6349 expandInlineFuncs (tree->right, block);
6354 /*-----------------------------------------------------------------*/
6355 /* createFunction - This is the key node that calls the iCode for */
6356 /* generating the code for a function. Note code */
6357 /* is generated function by function, later when */
6358 /* add inter-procedural analysis this will change */
6359 /*-----------------------------------------------------------------*/
6361 createFunction (symbol * name, ast * body)
6367 iCode *piCode = NULL;
6370 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
6371 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
6373 /* if check function return 0 then some problem */
6374 if (checkFunction (name, NULL) == 0)
6377 /* create a dummy block if none exists */
6379 body = newNode (BLOCK, NULL, NULL);
6383 /* check if the function name already in the symbol table */
6384 if ((csym = findSym (SymbolTab, NULL, name->name)))
6387 /* special case for compiler defined functions
6388 we need to add the name to the publics list : this
6389 actually means we are now compiling the compiler
6393 addSet (&publics, name);
6398 addSymChain (&name);
6399 allocVariables (name);
6401 name->lastLine = lexLineno;
6404 /* set the stack pointer */
6405 stackPtr = -port->stack.direction * port->stack.call_overhead;
6408 if (IFFUNC_ISISR (name->type))
6409 stackPtr -= port->stack.direction * port->stack.isr_overhead;
6411 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
6413 if (options.useXstack)
6414 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
6416 stackPtr -= port->stack.direction * port->stack.reent_overhead;
6419 fetype = getSpec (name->type); /* get the specifier for the function */
6420 /* if this is a reentrant function then */
6421 if (IFFUNC_ISREENT (name->type))
6424 inlineState.count = 0;
6425 savedBlockno = currBlockno;
6426 currBlockno = inlineFindMaxBlockno (body, 0);
6427 expandInlineFuncs (body, NULL);
6428 currBlockno = savedBlockno;
6430 if (FUNC_ISINLINE (name->type))
6431 name->funcTree = copyAst (body);
6433 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
6435 /* do processing for parameters that are passed in registers */
6436 processRegParms (FUNC_ARGS(name->type), body);
6438 /* set the stack pointer */
6442 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
6444 /* allocate & autoinit the block variables */
6445 processBlockVars (body, &stack, ALLOCATE);
6447 /* name needs to be mangled */
6448 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
6450 body = resolveSymbols (body); /* resolve the symbols */
6451 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
6453 /* save the stack information */
6454 if (options.useXstack)
6455 name->xstack = SPEC_STAK (fetype) = stack;
6457 name->stack = SPEC_STAK (fetype) = stack;
6459 ex = newAst_VALUE (symbolVal (name)); /* create name */
6460 ex = newNode (FUNCTION, ex, body);
6461 ex->values.args = FUNC_ARGS(name->type);
6463 if (options.dump_tree)
6468 /* Do not generate code for inline functions unless extern also. */
6470 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
6473 /* Temporary hack: always generate code for static inline functions. */
6474 /* Ideally static inline functions should only be generated if needed. */
6475 if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype) && !IS_STATIC (fetype))
6479 /* create the node & generate intermediate code */
6481 codeOutBuf = &code->oBuf;
6482 piCode = iCodeFromAst (ex);
6483 name->generated = 1;
6488 eBBlockFromiCode (piCode);
6490 /* if there are any statics then do them */
6493 GcurMemmap = statsg;
6494 codeOutBuf = &statsg->oBuf;
6495 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6501 /* dealloc the block variables */
6502 processBlockVars (body, &stack, DEALLOCATE);
6503 outputDebugStackSymbols();
6504 /* deallocate paramaters */
6505 deallocParms (FUNC_ARGS(name->type));
6507 if (IFFUNC_ISREENT (name->type))
6510 /* we are done freeup memory & cleanup */
6512 if (port->reset_labelKey) labelKey = 1;
6514 FUNC_HASBODY(name->type) = 1;
6515 addSet (&operKeyReset, name);
6516 applyToSet (operKeyReset, resetParmKey);
6521 cleanUpLevel (LabelTab, 0);
6522 cleanUpBlock (StructTab, 1);
6523 cleanUpBlock (TypedefTab, 1);
6525 xstack->syms = NULL;
6526 istack->syms = NULL;
6531 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6532 /*-----------------------------------------------------------------*/
6533 /* ast_print : prints the ast (for debugging purposes) */
6534 /*-----------------------------------------------------------------*/
6536 void ast_print (ast * tree, FILE *outfile, int indent)
6541 /* can print only decorated trees */
6542 if (!tree->decorated) return;
6544 /* if any child is an error | this one is an error do nothing */
6545 if (tree->isError ||
6546 (tree->left && tree->left->isError) ||
6547 (tree->right && tree->right->isError)) {
6548 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6552 /* print the line */
6553 /* if not block & function */
6554 if (tree->type == EX_OP &&
6555 (tree->opval.op != FUNCTION &&
6556 tree->opval.op != BLOCK &&
6557 tree->opval.op != NULLOP)) {
6560 if (tree->opval.op == FUNCTION) {
6562 value *args=FUNC_ARGS(tree->left->opval.val->type);
6563 fprintf(outfile,"FUNCTION (%s=%p) type (",
6564 tree->left->opval.val->name, tree);
6565 printTypeChain (tree->left->opval.val->type->next,outfile);
6566 fprintf(outfile,") args (");
6569 fprintf (outfile, ", ");
6571 printTypeChain (args ? args->type : NULL, outfile);
6573 args= args ? args->next : NULL;
6575 fprintf(outfile,")\n");
6576 ast_print(tree->left,outfile,indent);
6577 ast_print(tree->right,outfile,indent);
6580 if (tree->opval.op == BLOCK) {
6581 symbol *decls = tree->values.sym;
6582 INDENT(indent,outfile);
6583 fprintf(outfile,"{\n");
6585 INDENT(indent+2,outfile);
6586 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6587 decls->name, decls);
6588 printTypeChain(decls->type,outfile);
6589 fprintf(outfile,")\n");
6591 decls = decls->next;
6593 ast_print(tree->right,outfile,indent+2);
6594 INDENT(indent,outfile);
6595 fprintf(outfile,"}\n");
6598 if (tree->opval.op == NULLOP) {
6599 ast_print(tree->left,outfile,indent);
6600 ast_print(tree->right,outfile,indent);
6603 INDENT(indent,outfile);
6605 /*------------------------------------------------------------------*/
6606 /*----------------------------*/
6607 /* leaf has been reached */
6608 /*----------------------------*/
6609 /* if this is of type value */
6610 /* just get the type */
6611 if (tree->type == EX_VALUE) {
6613 if (IS_LITERAL (tree->opval.val->etype)) {
6614 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6615 if (SPEC_USIGN (tree->opval.val->etype))
6616 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val));
6618 fprintf(outfile,"%d", (TYPE_TARGET_LONG) ulFromVal(tree->opval.val));
6619 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val),
6620 floatFromVal(tree->opval.val));
6621 } else if (tree->opval.val->sym) {
6622 /* if the undefined flag is set then give error message */
6623 if (tree->opval.val->sym->undefined) {
6624 fprintf(outfile,"UNDEFINED SYMBOL ");
6626 fprintf(outfile,"SYMBOL ");
6628 fprintf(outfile,"(%s=%p @ %p)",
6629 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6632 fprintf(outfile," type (");
6633 printTypeChain(tree->ftype,outfile);
6634 fprintf(outfile,")\n");
6636 fprintf(outfile,"\n");
6641 /* if type link for the case of cast */
6642 if (tree->type == EX_LINK) {
6643 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6644 printTypeChain(tree->opval.lnk,outfile);
6645 fprintf(outfile,")\n");
6650 /* depending on type of operator do */
6652 switch (tree->opval.op) {
6653 /*------------------------------------------------------------------*/
6654 /*----------------------------*/
6656 /*----------------------------*/
6658 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6659 printTypeChain(tree->ftype,outfile);
6660 fprintf(outfile,")\n");
6661 ast_print(tree->left,outfile,indent+2);
6662 ast_print(tree->right,outfile,indent+2);
6665 /*------------------------------------------------------------------*/
6666 /*----------------------------*/
6668 /*----------------------------*/
6670 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6671 printTypeChain(tree->ftype,outfile);
6672 fprintf(outfile,")\n");
6673 ast_print(tree->left,outfile,indent+2);
6674 ast_print(tree->right,outfile,indent+2);
6677 /*------------------------------------------------------------------*/
6678 /*----------------------------*/
6679 /* struct/union pointer */
6680 /*----------------------------*/
6682 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6683 printTypeChain(tree->ftype,outfile);
6684 fprintf(outfile,")\n");
6685 ast_print(tree->left,outfile,indent+2);
6686 ast_print(tree->right,outfile,indent+2);
6689 /*------------------------------------------------------------------*/
6690 /*----------------------------*/
6691 /* ++/-- operation */
6692 /*----------------------------*/
6695 fprintf(outfile,"post-");
6697 fprintf(outfile,"pre-");
6698 fprintf(outfile,"INC_OP (%p) type (",tree);
6699 printTypeChain(tree->ftype,outfile);
6700 fprintf(outfile,")\n");
6701 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6702 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6707 fprintf(outfile,"post-");
6709 fprintf(outfile,"pre-");
6710 fprintf(outfile,"DEC_OP (%p) type (",tree);
6711 printTypeChain(tree->ftype,outfile);
6712 fprintf(outfile,")\n");
6713 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6714 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6717 /*------------------------------------------------------------------*/
6718 /*----------------------------*/
6720 /*----------------------------*/
6723 fprintf(outfile,"& (%p) type (",tree);
6724 printTypeChain(tree->ftype,outfile);
6725 fprintf(outfile,")\n");
6726 ast_print(tree->left,outfile,indent+2);
6727 ast_print(tree->right,outfile,indent+2);
6729 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6730 printTypeChain(tree->ftype,outfile);
6731 fprintf(outfile,")\n");
6732 ast_print(tree->left,outfile,indent+2);
6733 ast_print(tree->right,outfile,indent+2);
6736 /*----------------------------*/
6738 /*----------------------------*/
6740 fprintf(outfile,"OR (%p) type (",tree);
6741 printTypeChain(tree->ftype,outfile);
6742 fprintf(outfile,")\n");
6743 ast_print(tree->left,outfile,indent+2);
6744 ast_print(tree->right,outfile,indent+2);
6746 /*------------------------------------------------------------------*/
6747 /*----------------------------*/
6749 /*----------------------------*/
6751 fprintf(outfile,"XOR (%p) type (",tree);
6752 printTypeChain(tree->ftype,outfile);
6753 fprintf(outfile,")\n");
6754 ast_print(tree->left,outfile,indent+2);
6755 ast_print(tree->right,outfile,indent+2);
6758 /*------------------------------------------------------------------*/
6759 /*----------------------------*/
6761 /*----------------------------*/
6763 fprintf(outfile,"DIV (%p) type (",tree);
6764 printTypeChain(tree->ftype,outfile);
6765 fprintf(outfile,")\n");
6766 ast_print(tree->left,outfile,indent+2);
6767 ast_print(tree->right,outfile,indent+2);
6769 /*------------------------------------------------------------------*/
6770 /*----------------------------*/
6772 /*----------------------------*/
6774 fprintf(outfile,"MOD (%p) type (",tree);
6775 printTypeChain(tree->ftype,outfile);
6776 fprintf(outfile,")\n");
6777 ast_print(tree->left,outfile,indent+2);
6778 ast_print(tree->right,outfile,indent+2);
6781 /*------------------------------------------------------------------*/
6782 /*----------------------------*/
6783 /* address dereference */
6784 /*----------------------------*/
6785 case '*': /* can be unary : if right is null then unary operation */
6787 fprintf(outfile,"DEREF (%p) type (",tree);
6788 printTypeChain(tree->ftype,outfile);
6789 fprintf(outfile,")\n");
6790 ast_print(tree->left,outfile,indent+2);
6793 /*------------------------------------------------------------------*/
6794 /*----------------------------*/
6795 /* multiplication */
6796 /*----------------------------*/
6797 fprintf(outfile,"MULT (%p) type (",tree);
6798 printTypeChain(tree->ftype,outfile);
6799 fprintf(outfile,")\n");
6800 ast_print(tree->left,outfile,indent+2);
6801 ast_print(tree->right,outfile,indent+2);
6805 /*------------------------------------------------------------------*/
6806 /*----------------------------*/
6807 /* unary '+' operator */
6808 /*----------------------------*/
6812 fprintf(outfile,"UPLUS (%p) type (",tree);
6813 printTypeChain(tree->ftype,outfile);
6814 fprintf(outfile,")\n");
6815 ast_print(tree->left,outfile,indent+2);
6817 /*------------------------------------------------------------------*/
6818 /*----------------------------*/
6820 /*----------------------------*/
6821 fprintf(outfile,"ADD (%p) type (",tree);
6822 printTypeChain(tree->ftype,outfile);
6823 fprintf(outfile,")\n");
6824 ast_print(tree->left,outfile,indent+2);
6825 ast_print(tree->right,outfile,indent+2);
6828 /*------------------------------------------------------------------*/
6829 /*----------------------------*/
6831 /*----------------------------*/
6832 case '-': /* can be unary */
6834 fprintf(outfile,"UMINUS (%p) type (",tree);
6835 printTypeChain(tree->ftype,outfile);
6836 fprintf(outfile,")\n");
6837 ast_print(tree->left,outfile,indent+2);
6839 /*------------------------------------------------------------------*/
6840 /*----------------------------*/
6842 /*----------------------------*/
6843 fprintf(outfile,"SUB (%p) type (",tree);
6844 printTypeChain(tree->ftype,outfile);
6845 fprintf(outfile,")\n");
6846 ast_print(tree->left,outfile,indent+2);
6847 ast_print(tree->right,outfile,indent+2);
6850 /*------------------------------------------------------------------*/
6851 /*----------------------------*/
6853 /*----------------------------*/
6855 fprintf(outfile,"COMPL (%p) type (",tree);
6856 printTypeChain(tree->ftype,outfile);
6857 fprintf(outfile,")\n");
6858 ast_print(tree->left,outfile,indent+2);
6860 /*------------------------------------------------------------------*/
6861 /*----------------------------*/
6863 /*----------------------------*/
6865 fprintf(outfile,"NOT (%p) type (",tree);
6866 printTypeChain(tree->ftype,outfile);
6867 fprintf(outfile,")\n");
6868 ast_print(tree->left,outfile,indent+2);
6870 /*------------------------------------------------------------------*/
6871 /*----------------------------*/
6873 /*----------------------------*/
6875 fprintf(outfile,"RRC (%p) type (",tree);
6876 printTypeChain(tree->ftype,outfile);
6877 fprintf(outfile,")\n");
6878 ast_print(tree->left,outfile,indent+2);
6882 fprintf(outfile,"RLC (%p) type (",tree);
6883 printTypeChain(tree->ftype,outfile);
6884 fprintf(outfile,")\n");
6885 ast_print(tree->left,outfile,indent+2);
6888 fprintf(outfile,"SWAP (%p) type (",tree);
6889 printTypeChain(tree->ftype,outfile);
6890 fprintf(outfile,")\n");
6891 ast_print(tree->left,outfile,indent+2);
6894 fprintf(outfile,"GETHBIT (%p) type (",tree);
6895 printTypeChain(tree->ftype,outfile);
6896 fprintf(outfile,")\n");
6897 ast_print(tree->left,outfile,indent+2);
6900 fprintf(outfile,"GETABIT (%p) type (",tree);
6901 printTypeChain(tree->ftype,outfile);
6902 fprintf(outfile,")\n");
6903 ast_print(tree->left,outfile,indent+2);
6904 ast_print(tree->right,outfile,indent+2);
6907 fprintf(outfile,"GETBYTE (%p) type (",tree);
6908 printTypeChain(tree->ftype,outfile);
6909 fprintf(outfile,")\n");
6910 ast_print(tree->left,outfile,indent+2);
6911 ast_print(tree->right,outfile,indent+2);
6914 fprintf(outfile,"GETWORD (%p) type (",tree);
6915 printTypeChain(tree->ftype,outfile);
6916 fprintf(outfile,")\n");
6917 ast_print(tree->left,outfile,indent+2);
6918 ast_print(tree->right,outfile,indent+2);
6921 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6922 printTypeChain(tree->ftype,outfile);
6923 fprintf(outfile,")\n");
6924 ast_print(tree->left,outfile,indent+2);
6925 ast_print(tree->right,outfile,indent+2);
6928 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6929 printTypeChain(tree->ftype,outfile);
6930 fprintf(outfile,")\n");
6931 ast_print(tree->left,outfile,indent+2);
6932 ast_print(tree->right,outfile,indent+2);
6934 /*------------------------------------------------------------------*/
6935 /*----------------------------*/
6937 /*----------------------------*/
6938 case CAST: /* change the type */
6939 fprintf(outfile,"CAST (%p) from type (",tree);
6940 printTypeChain(tree->right->ftype,outfile);
6941 fprintf(outfile,") to type (");
6942 printTypeChain(tree->ftype,outfile);
6943 fprintf(outfile,")\n");
6944 ast_print(tree->right,outfile,indent+2);
6948 fprintf(outfile,"ANDAND (%p) type (",tree);
6949 printTypeChain(tree->ftype,outfile);
6950 fprintf(outfile,")\n");
6951 ast_print(tree->left,outfile,indent+2);
6952 ast_print(tree->right,outfile,indent+2);
6955 fprintf(outfile,"OROR (%p) type (",tree);
6956 printTypeChain(tree->ftype,outfile);
6957 fprintf(outfile,")\n");
6958 ast_print(tree->left,outfile,indent+2);
6959 ast_print(tree->right,outfile,indent+2);
6962 /*------------------------------------------------------------------*/
6963 /*----------------------------*/
6964 /* comparison operators */
6965 /*----------------------------*/
6967 fprintf(outfile,"GT(>) (%p) type (",tree);
6968 printTypeChain(tree->ftype,outfile);
6969 fprintf(outfile,")\n");
6970 ast_print(tree->left,outfile,indent+2);
6971 ast_print(tree->right,outfile,indent+2);
6974 fprintf(outfile,"LT(<) (%p) type (",tree);
6975 printTypeChain(tree->ftype,outfile);
6976 fprintf(outfile,")\n");
6977 ast_print(tree->left,outfile,indent+2);
6978 ast_print(tree->right,outfile,indent+2);
6981 fprintf(outfile,"LE(<=) (%p) type (",tree);
6982 printTypeChain(tree->ftype,outfile);
6983 fprintf(outfile,")\n");
6984 ast_print(tree->left,outfile,indent+2);
6985 ast_print(tree->right,outfile,indent+2);
6988 fprintf(outfile,"GE(>=) (%p) type (",tree);
6989 printTypeChain(tree->ftype,outfile);
6990 fprintf(outfile,")\n");
6991 ast_print(tree->left,outfile,indent+2);
6992 ast_print(tree->right,outfile,indent+2);
6995 fprintf(outfile,"EQ(==) (%p) type (",tree);
6996 printTypeChain(tree->ftype,outfile);
6997 fprintf(outfile,")\n");
6998 ast_print(tree->left,outfile,indent+2);
6999 ast_print(tree->right,outfile,indent+2);
7002 fprintf(outfile,"NE(!=) (%p) type (",tree);
7003 printTypeChain(tree->ftype,outfile);
7004 fprintf(outfile,")\n");
7005 ast_print(tree->left,outfile,indent+2);
7006 ast_print(tree->right,outfile,indent+2);
7007 /*------------------------------------------------------------------*/
7008 /*----------------------------*/
7010 /*----------------------------*/
7011 case SIZEOF: /* evaluate wihout code generation */
7012 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
7015 /*------------------------------------------------------------------*/
7016 /*----------------------------*/
7017 /* conditional operator '?' */
7018 /*----------------------------*/
7020 fprintf(outfile,"QUEST(?) (%p) type (",tree);
7021 printTypeChain(tree->ftype,outfile);
7022 fprintf(outfile,")\n");
7023 ast_print(tree->left,outfile,indent+2);
7024 ast_print(tree->right,outfile,indent+2);
7028 fprintf(outfile,"COLON(:) (%p) type (",tree);
7029 printTypeChain(tree->ftype,outfile);
7030 fprintf(outfile,")\n");
7031 ast_print(tree->left,outfile,indent+2);
7032 ast_print(tree->right,outfile,indent+2);
7035 /*------------------------------------------------------------------*/
7036 /*----------------------------*/
7037 /* assignment operators */
7038 /*----------------------------*/
7040 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
7041 printTypeChain(tree->ftype,outfile);
7042 fprintf(outfile,")\n");
7043 ast_print(tree->left,outfile,indent+2);
7044 ast_print(tree->right,outfile,indent+2);
7047 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
7048 printTypeChain(tree->ftype,outfile);
7049 fprintf(outfile,")\n");
7050 ast_print(tree->left,outfile,indent+2);
7051 ast_print(tree->right,outfile,indent+2);
7054 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
7055 printTypeChain(tree->ftype,outfile);
7056 fprintf(outfile,")\n");
7057 ast_print(tree->left,outfile,indent+2);
7058 ast_print(tree->right,outfile,indent+2);
7061 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
7062 printTypeChain(tree->ftype,outfile);
7063 fprintf(outfile,")\n");
7064 ast_print(tree->left,outfile,indent+2);
7065 ast_print(tree->right,outfile,indent+2);
7068 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
7069 printTypeChain(tree->ftype,outfile);
7070 fprintf(outfile,")\n");
7071 ast_print(tree->left,outfile,indent+2);
7072 ast_print(tree->right,outfile,indent+2);
7075 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
7076 printTypeChain(tree->ftype,outfile);
7077 fprintf(outfile,")\n");
7078 ast_print(tree->left,outfile,indent+2);
7079 ast_print(tree->right,outfile,indent+2);
7082 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
7083 printTypeChain(tree->ftype,outfile);
7084 fprintf(outfile,")\n");
7085 ast_print(tree->left,outfile,indent+2);
7086 ast_print(tree->right,outfile,indent+2);
7088 /*------------------------------------------------------------------*/
7089 /*----------------------------*/
7091 /*----------------------------*/
7093 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
7094 printTypeChain(tree->ftype,outfile);
7095 fprintf(outfile,")\n");
7096 ast_print(tree->left,outfile,indent+2);
7097 ast_print(tree->right,outfile,indent+2);
7099 /*------------------------------------------------------------------*/
7100 /*----------------------------*/
7102 /*----------------------------*/
7104 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
7105 printTypeChain(tree->ftype,outfile);
7106 fprintf(outfile,")\n");
7107 ast_print(tree->left,outfile,indent+2);
7108 ast_print(tree->right,outfile,indent+2);
7110 /*------------------------------------------------------------------*/
7111 /*----------------------------*/
7112 /* straight assignemnt */
7113 /*----------------------------*/
7115 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
7116 printTypeChain(tree->ftype,outfile);
7117 fprintf(outfile,")\n");
7118 ast_print(tree->left,outfile,indent+2);
7119 ast_print(tree->right,outfile,indent+2);
7121 /*------------------------------------------------------------------*/
7122 /*----------------------------*/
7123 /* comma operator */
7124 /*----------------------------*/
7126 fprintf(outfile,"COMMA(,) (%p) type (",tree);
7127 printTypeChain(tree->ftype,outfile);
7128 fprintf(outfile,")\n");
7129 ast_print(tree->left,outfile,indent+2);
7130 ast_print(tree->right,outfile,indent+2);
7132 /*------------------------------------------------------------------*/
7133 /*----------------------------*/
7135 /*----------------------------*/
7138 fprintf(outfile,"CALL (%p) type (",tree);
7139 printTypeChain(tree->ftype,outfile);
7140 fprintf(outfile,")\n");
7141 ast_print(tree->left,outfile,indent+2);
7142 ast_print(tree->right,outfile,indent+2);
7145 fprintf(outfile,"PARMS\n");
7146 ast_print(tree->left,outfile,indent+2);
7147 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
7148 ast_print(tree->right,outfile,indent+2);
7151 /*------------------------------------------------------------------*/
7152 /*----------------------------*/
7153 /* return statement */
7154 /*----------------------------*/
7156 fprintf(outfile,"RETURN (%p) type (",tree);
7158 printTypeChain(tree->right->ftype,outfile);
7160 fprintf(outfile,")\n");
7161 ast_print(tree->right,outfile,indent+2);
7163 /*------------------------------------------------------------------*/
7164 /*----------------------------*/
7165 /* label statement */
7166 /*----------------------------*/
7168 fprintf(outfile,"LABEL (%p)\n",tree);
7169 ast_print(tree->left,outfile,indent+2);
7170 ast_print(tree->right,outfile,indent);
7172 /*------------------------------------------------------------------*/
7173 /*----------------------------*/
7174 /* switch statement */
7175 /*----------------------------*/
7179 fprintf(outfile,"SWITCH (%p) ",tree);
7180 ast_print(tree->left,outfile,0);
7181 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
7182 INDENT(indent+2,outfile);
7183 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
7184 (int) ulFromVal(val),
7185 tree->values.switchVals.swNum,
7186 (int) ulFromVal(val));
7188 ast_print(tree->right,outfile,indent);
7191 /*------------------------------------------------------------------*/
7192 /*----------------------------*/
7194 /*----------------------------*/
7196 fprintf(outfile,"IF (%p) \n",tree);
7197 ast_print(tree->left,outfile,indent+2);
7198 if (tree->trueLabel) {
7199 INDENT(indent+2,outfile);
7200 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
7202 if (tree->falseLabel) {
7203 INDENT(indent+2,outfile);
7204 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
7206 ast_print(tree->right,outfile,indent+2);
7208 /*----------------------------*/
7209 /* goto Statement */
7210 /*----------------------------*/
7212 fprintf(outfile,"GOTO (%p) \n",tree);
7213 ast_print(tree->left,outfile,indent+2);
7214 fprintf(outfile,"\n");
7216 /*------------------------------------------------------------------*/
7217 /*----------------------------*/
7219 /*----------------------------*/
7221 fprintf(outfile,"FOR (%p) \n",tree);
7222 if (AST_FOR( tree, initExpr)) {
7223 INDENT(indent+2,outfile);
7224 fprintf(outfile,"INIT EXPR ");
7225 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
7227 if (AST_FOR( tree, condExpr)) {
7228 INDENT(indent+2,outfile);
7229 fprintf(outfile,"COND EXPR ");
7230 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
7232 if (AST_FOR( tree, loopExpr)) {
7233 INDENT(indent+2,outfile);
7234 fprintf(outfile,"LOOP EXPR ");
7235 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
7237 fprintf(outfile,"FOR LOOP BODY \n");
7238 ast_print(tree->left,outfile,indent+2);
7241 fprintf(outfile,"CRITICAL (%p) \n",tree);
7242 ast_print(tree->left,outfile,indent+2);
7250 ast_print(t,stdout,0);
7253 /*-----------------------------------------------------------------*/
7254 /* astErrors : returns non-zero if errors present in tree */
7255 /*-----------------------------------------------------------------*/
7256 int astErrors(ast *t)
7265 if (t->type == EX_VALUE
7266 && t->opval.val->sym
7267 && t->opval.val->sym->undefined)
7270 errors += astErrors(t->left);
7271 errors += astErrors(t->right);