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 #define LRVAL(x) x->left->rvalue
36 #define RRVAL(x) x->right->rvalue
37 #define TRVAL(x) x->rvalue
38 #define LLVAL(x) x->left->lvalue
39 #define RLVAL(x) x->right->lvalue
40 #define TLVAL(x) x->lvalue
41 #define RTYPE(x) x->right->ftype
42 #define RETYPE(x) x->right->etype
43 #define LTYPE(x) x->left->ftype
44 #define LETYPE(x) x->left->etype
45 #define TTYPE(x) x->ftype
46 #define TETYPE(x) x->etype
52 symbol *currFunc=NULL;
53 static ast *createIval (ast *, sym_link *, initList *, ast *, ast *);
54 static ast *createIvalCharPtr (ast *, sym_link *, ast *, ast *);
55 static ast *optimizeCompare (ast *);
56 ast *optimizeRRCRLC (ast *);
57 ast *optimizeSWAP (ast *);
58 ast *optimizeGetHbit (ast *, RESULT_TYPE);
59 ast *optimizeGetAbit (ast *, RESULT_TYPE);
60 ast *optimizeGetByte (ast *, RESULT_TYPE);
61 ast *optimizeGetWord (ast *, RESULT_TYPE);
62 static ast *backPatchLabels (ast *, symbol *, symbol *);
65 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
66 struct dbuf_s *codeOutBuf;
70 printTypeChain (tree->ftype, stdout);
75 /*-----------------------------------------------------------------*/
76 /* newAst - creates a fresh node for an expression tree */
77 /*-----------------------------------------------------------------*/
79 newAst_ (unsigned type)
82 static int oldLineno = 0;
84 ex = Safe_alloc ( sizeof (ast));
87 ex->lineno = (noLineno ? oldLineno : lexLineno);
88 ex->filename = lexFilename;
89 ex->level = NestLevel;
90 ex->block = currBlockno;
91 ex->initMode = inInitMode;
92 ex->seqPoint = seqPointNo;
97 newAst_VALUE (value * val)
99 ast *ex = newAst_ (EX_VALUE);
105 newAst_OP (unsigned op)
107 ast *ex = newAst_ (EX_OP);
113 newAst_LINK (sym_link * val)
115 ast *ex = newAst_ (EX_LINK);
120 /*-----------------------------------------------------------------*/
121 /* newNode - creates a new node */
122 /*-----------------------------------------------------------------*/
124 newNode (long op, ast * left, ast * right)
135 /*-----------------------------------------------------------------*/
136 /* newIfxNode - creates a new Ifx Node */
137 /*-----------------------------------------------------------------*/
139 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
143 /* if this is a literal then we already know the result */
144 if (condAst->etype && IS_LITERAL (condAst->etype))
146 /* then depending on the expression value */
147 if (floatFromVal (condAst->opval.val))
148 ifxNode = newNode (GOTO,
149 newAst_VALUE (symbolVal (trueLabel)),
152 ifxNode = newNode (GOTO,
153 newAst_VALUE (symbolVal (falseLabel)),
158 ifxNode = newNode (IFX, condAst, NULL);
159 ifxNode->trueLabel = trueLabel;
160 ifxNode->falseLabel = falseLabel;
166 /*-----------------------------------------------------------------*/
167 /* copyAstValues - copies value portion of ast if needed */
168 /*-----------------------------------------------------------------*/
170 copyAstValues (ast * dest, ast * src)
172 switch (src->opval.op)
175 dest->values.sym = copySymbolChain (src->values.sym);
179 dest->values.switchVals.swVals =
180 copyValue (src->values.switchVals.swVals);
181 dest->values.switchVals.swDefault =
182 src->values.switchVals.swDefault;
183 dest->values.switchVals.swNum =
184 src->values.switchVals.swNum;
188 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
192 dest->values.constlist = copyLiteralList(src->values.constlist);
196 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
197 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
198 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
199 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
200 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
201 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
202 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
207 /*-----------------------------------------------------------------*/
208 /* copyAst - makes a copy of a given astession */
209 /*-----------------------------------------------------------------*/
218 dest = Safe_alloc ( sizeof (ast));
220 dest->type = src->type;
221 dest->lineno = src->lineno;
222 dest->level = src->level;
223 dest->funcName = src->funcName;
224 dest->reversed = src->reversed;
227 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
229 /* if this is a leaf */
231 if (src->type == EX_VALUE)
233 dest->opval.val = copyValue (src->opval.val);
238 if (src->type == EX_LINK)
240 dest->opval.lnk = copyLinkChain (src->opval.lnk);
244 dest->opval.op = src->opval.op;
246 /* if this is a node that has special values */
247 copyAstValues (dest, src);
249 dest->trueLabel = copySymbol (src->trueLabel);
250 dest->falseLabel = copySymbol (src->falseLabel);
251 dest->left = copyAst (src->left);
252 dest->right = copyAst (src->right);
258 /*-----------------------------------------------------------------*/
259 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
260 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
261 /*-----------------------------------------------------------------*/
262 ast *removeIncDecOps (ast * tree) {
264 // traverse the tree and remove inc/dec ops
269 if (tree->type == EX_OP &&
270 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
277 tree->left=removeIncDecOps(tree->left);
278 tree->right=removeIncDecOps(tree->right);
283 /*-----------------------------------------------------------------*/
284 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
285 /* "*++s += 3" -> "*++s = *++s + 3" */
286 /*-----------------------------------------------------------------*/
287 ast *removePreIncDecOps (ast * tree) {
289 // traverse the tree and remove pre-inc/dec ops
294 if (tree->type == EX_OP &&
295 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
300 tree->left=removePreIncDecOps(tree->left);
301 tree->right=removePreIncDecOps(tree->right);
306 /*-----------------------------------------------------------------*/
307 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
308 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
309 /*-----------------------------------------------------------------*/
310 ast *removePostIncDecOps (ast * tree) {
312 // traverse the tree and remove pre-inc/dec ops
317 if (tree->type == EX_OP &&
318 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
323 tree->left=removePostIncDecOps(tree->left);
324 tree->right=removePostIncDecOps(tree->right);
329 /*-----------------------------------------------------------------*/
330 /* replaceAstWithTemporary: Replace the AST pointed to by the arg */
331 /* with a reference to a new temporary variable. Returns*/
332 /* an AST which assigns the original value to the */
334 /*-----------------------------------------------------------------*/
335 static ast *replaceAstWithTemporary(ast **treeptr)
337 symbol *sym = newSymbol (genSymName(NestLevel), NestLevel );
340 /* Tell gatherImplicitVariables() to automatically give the
341 symbol the correct type */
346 tempvar = newNode('=', newAst_VALUE(symbolVal(sym)), *treeptr);
347 *treeptr = newAst_VALUE(symbolVal(sym));
354 /*-----------------------------------------------------------------*/
355 /* createRMW: Create a read-modify-write expression, using a */
356 /* temporary variable if necessary to avoid duplicating */
357 /* any side effects, for use in e.g. */
358 /* foo()->count += 5; becomes */
359 /* tmp = foo(); tmp->count = tmp->count + 5; */
360 /*-----------------------------------------------------------------*/
361 ast * createRMW (ast *target, unsigned op, ast *operand)
363 ast *readval, *writeval;
364 ast *tempvar1 = NULL;
365 ast *tempvar2 = NULL;
368 if (!target || !operand) {
372 /* we need to create two copies of target: one to read from and
373 one to write to. but we need to do this without duplicating
374 any side effects that may be contained in the tree. */
376 if (IS_AST_OP(target)) {
377 /* if this is a dereference, put the referenced item in the temporary */
378 if (IS_DEREF_OP(target) || target->opval.op == PTR_OP) {
379 /* create a new temporary containing the item being dereferenced */
380 if (hasSEFcalls(target->left))
381 tempvar1 = replaceAstWithTemporary(&(target->left));
382 } else if (target->opval.op == '[') {
383 /* Array access is similar, but we have to avoid side effects in
384 both values [WIML: Why not transform a[b] to *(a+b) in parser?] */
385 if (hasSEFcalls(target->left))
386 tempvar1 = replaceAstWithTemporary(&(target->left));
387 if (hasSEFcalls(target->right))
388 tempvar2 = replaceAstWithTemporary(&(target->right));
390 /* we would have to handle '.', but it is not generated any more */
391 wassertl(target->opval.op != '.', "obsolete opcode in tree");
393 /* no other kinds of ASTs are lvalues and can contain side effects */
398 writeval = copyAst(target);
400 result = newNode('=', writeval, newNode(op, readval, operand));
402 result = newNode(',', tempvar2, result);
404 result = newNode(',', tempvar1, result);
410 /*-----------------------------------------------------------------*/
411 /* hasSEFcalls - returns TRUE if tree has a function call, */
412 /* inc/decrement, or other side effect */
413 /*-----------------------------------------------------------------*/
415 hasSEFcalls (ast * tree)
420 if (tree->type == EX_OP &&
421 (tree->opval.op == CALL ||
422 tree->opval.op == PCALL ||
423 tree->opval.op == '=' ||
424 tree->opval.op == INC_OP ||
425 tree->opval.op == DEC_OP))
428 return (hasSEFcalls (tree->left) |
429 hasSEFcalls (tree->right));
432 /*-----------------------------------------------------------------*/
433 /* isAstEqual - compares two asts & returns 1 if they are equal */
434 /*-----------------------------------------------------------------*/
436 isAstEqual (ast * t1, ast * t2)
445 if (t1->type != t2->type)
451 if (t1->opval.op != t2->opval.op)
453 return (isAstEqual (t1->left, t2->left) &&
454 isAstEqual (t1->right, t2->right));
458 if (t1->opval.val->sym)
460 if (!t2->opval.val->sym)
463 return isSymbolEqual (t1->opval.val->sym,
468 if (t2->opval.val->sym)
471 return (floatFromVal (t1->opval.val) ==
472 floatFromVal (t2->opval.val));
476 /* only compare these two types */
484 /*-----------------------------------------------------------------*/
485 /* resolveSymbols - resolve symbols from the symbol table */
486 /*-----------------------------------------------------------------*/
488 resolveSymbols (ast * tree)
490 /* walk the entire tree and check for values */
491 /* with symbols if we find one then replace */
492 /* symbol with that from the symbol table */
499 /* if not block & function */
500 if (tree->type == EX_OP &&
501 (tree->opval.op != FUNCTION &&
502 tree->opval.op != BLOCK &&
503 tree->opval.op != NULLOP))
505 filename = tree->filename;
506 lineno = tree->lineno;
510 /* make sure we resolve the true & false labels for ifx */
511 if (tree->type == EX_OP && tree->opval.op == IFX)
517 if ((csym = findSym (LabelTab, tree->trueLabel,
518 tree->trueLabel->name)))
519 tree->trueLabel = csym;
521 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
522 tree->trueLabel->name);
525 if (tree->falseLabel)
527 if ((csym = findSym (LabelTab,
529 tree->falseLabel->name)))
530 tree->falseLabel = csym;
532 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
533 tree->falseLabel->name);
538 /* if this is a label resolve it from the labelTab */
539 if (IS_AST_VALUE (tree) &&
540 tree->opval.val->sym &&
541 tree->opval.val->sym->islbl)
544 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
545 tree->opval.val->sym->name);
548 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
549 tree->opval.val->sym->name);
551 tree->opval.val->sym = csym;
553 goto resolveChildren;
556 /* do only for leafs */
557 if (IS_AST_VALUE (tree) &&
558 tree->opval.val->sym &&
559 !tree->opval.val->sym->implicit)
562 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
564 /* if found in the symbol table & they r not the same */
565 if (csym && tree->opval.val->sym != csym)
567 tree->opval.val->sym = csym;
568 tree->opval.val->type = csym->type;
569 tree->opval.val->etype = csym->etype;
572 /* if not found in the symbol table */
573 /* mark it as undefined assume it is */
574 /* an integer in data space */
575 if (!csym && !tree->opval.val->sym->implicit)
578 /* if this is a function name then */
579 /* mark it as returning an int */
582 tree->opval.val->sym->type = newLink (DECLARATOR);
583 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
584 tree->opval.val->sym->type->next =
585 tree->opval.val->sym->etype = newIntLink ();
586 tree->opval.val->etype = tree->opval.val->etype;
587 tree->opval.val->type = tree->opval.val->sym->type;
588 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
589 tree->opval.val->sym->name);
590 //tree->opval.val->sym->undefined = 1;
591 allocVariables (tree->opval.val->sym);
595 tree->opval.val->sym->undefined = 1;
596 tree->opval.val->type =
597 tree->opval.val->etype = newIntLink ();
598 tree->opval.val->sym->type =
599 tree->opval.val->sym->etype = newIntLink ();
605 resolveSymbols (tree->left);
606 resolveSymbols (tree->right);
611 /*-----------------------------------------------------------------*/
612 /* setAstLineno - walks a ast tree & sets the line number */
613 /*-----------------------------------------------------------------*/
614 int setAstLineno (ast * tree, int lineno)
619 tree->lineno = lineno;
620 setAstLineno (tree->left, lineno);
621 setAstLineno (tree->right, lineno);
625 /*-----------------------------------------------------------------*/
626 /* funcOfType :- function of type with name */
627 /*-----------------------------------------------------------------*/
629 funcOfType (char *name, sym_link * type, sym_link * argType,
633 /* create the symbol */
634 sym = newSymbol (name, 0);
636 /* setup return value */
637 sym->type = newLink (DECLARATOR);
638 DCL_TYPE (sym->type) = FUNCTION;
639 sym->type->next = copyLinkChain (type);
640 sym->etype = getSpec (sym->type);
641 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
643 /* if arguments required */
647 args = FUNC_ARGS(sym->type) = newValue ();
651 args->type = copyLinkChain (argType);
652 args->etype = getSpec (args->type);
653 SPEC_EXTR(args->etype)=1;
656 args = args->next = newValue ();
663 allocVariables (sym);
668 /*-----------------------------------------------------------------*/
669 /* funcOfTypeVarg :- function of type with name and argtype */
670 /*-----------------------------------------------------------------*/
672 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
677 /* create the symbol */
678 sym = newSymbol (name, 0);
680 /* setup return value */
681 sym->type = newLink (DECLARATOR);
682 DCL_TYPE (sym->type) = FUNCTION;
683 sym->type->next = typeFromStr(rtype);
684 sym->etype = getSpec (sym->type);
686 /* if arguments required */
689 args = FUNC_ARGS(sym->type) = newValue ();
691 for ( i = 0 ; i < nArgs ; i++ ) {
692 args->type = typeFromStr(atypes[i]);
693 args->etype = getSpec (args->type);
694 SPEC_EXTR(args->etype)=1;
695 if ((i + 1) == nArgs) break;
696 args = args->next = newValue ();
703 allocVariables (sym);
708 /*-----------------------------------------------------------------*/
709 /* reverseParms - will reverse a parameter tree */
710 /*-----------------------------------------------------------------*/
712 reverseParms (ast * ptree)
718 /* top down if we find a nonParm tree then quit */
719 if (ptree->type == EX_OP && ptree->opval.op == PARAM && !ptree->reversed)
721 /* The various functions expect the parameter tree to be right heavy. */
722 /* Rotate the tree to be left heavy so that after reversal it is */
723 /* right heavy again. */
724 while ((ttree = ptree->right) && ttree->type == EX_OP &&
725 ttree->opval.op == PARAM)
727 ptree->right = ttree->right;
728 ttree->right = ttree->left;
729 ttree->left = ptree->left;
735 ptree->left = ptree->right;
736 ptree->right = ttree;
738 reverseParms (ptree->left);
739 reverseParms (ptree->right);
745 /*-----------------------------------------------------------------*/
746 /* processParms - makes sure the parameters are okay and do some */
747 /* processing with them */
748 /*-----------------------------------------------------------------*/
750 processParms (ast *func,
753 int *parmNumber, /* unused, although updated */
756 RESULT_TYPE resultType;
759 /* if none of them exist */
760 if (!defParm && !*actParm)
765 if (getenv("DEBUG_SANITY"))
767 fprintf (stderr, "processParms: %s ", defParm->name);
769 /* make sure the type is complete and sane */
770 checkTypeSanity(defParm->etype, defParm->name);
773 if (IS_CODEPTR (func->ftype))
774 functype = func->ftype->next;
776 functype = func->ftype;
778 /* if the function is being called via a pointer & */
779 /* it has not been defined a reentrant then we cannot */
780 /* have parameters */
781 /* PIC16 port can... */
782 if (!TARGET_IS_PIC16)
784 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
786 werror (W_NONRENT_ARGS);
792 /* if defined parameters ended but actual parameters */
793 /* exist and this is not defined as a variable arg */
794 if (!defParm && *actParm && !IFFUNC_HASVARARGS(functype))
796 werror (E_TOO_MANY_PARMS);
800 /* if defined parameters present but no actual parameters */
801 if (defParm && !*actParm)
803 werror (E_TOO_FEW_PARMS);
807 /* if this is a PARAM node then match left & right */
808 if ((*actParm)->type == EX_OP && (*actParm)->opval.op == PARAM)
810 (*actParm)->decorated = 1;
811 return (processParms (func, defParm,
812 &(*actParm)->left, parmNumber, FALSE) ||
813 processParms (func, defParm ? defParm->next : NULL,
814 &(*actParm)->right, parmNumber, rightmost));
816 else if (defParm) /* not vararg */
818 /* If we have found a value node by following only right-hand links,
819 * then we know that there are no more values after us.
821 * Therefore, if there are more defined parameters, the caller didn't
824 if (rightmost && defParm->next)
826 werror (E_TOO_FEW_PARMS);
831 /* decorate parameter */
832 resultType = defParm ? getResultTypeFromType (defParm->type) :
834 *actParm = decorateType (*actParm, resultType);
836 if (IS_VOID((*actParm)->ftype))
838 werror (E_VOID_VALUE_USED);
842 /* If this is a varargs function... */
843 if (!defParm && *actParm && IFFUNC_HASVARARGS(functype))
848 if (IS_CAST_OP (*actParm)
849 || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
851 /* Parameter was explicitly typecast; don't touch it. */
855 ftype = (*actParm)->ftype;
857 /* If it's a char, upcast to int. */
858 if (IS_INTEGRAL (ftype)
859 && (getSize (ftype) < (unsigned) INTSIZE))
861 newType = newAst_LINK(INTTYPE);
864 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
866 newType = newAst_LINK (copyLinkChain(ftype));
867 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
870 if (IS_AGGREGATE (ftype))
872 newType = newAst_LINK (copyLinkChain (ftype));
873 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
878 /* cast required; change this op to a cast. */
879 (*actParm)->decorated = 0;
880 *actParm = newNode (CAST, newType, *actParm);
881 (*actParm)->lineno = (*actParm)->right->lineno;
883 decorateType (*actParm, RESULT_TYPE_NONE);
888 /* if defined parameters ended but actual has not & */
890 if (!defParm && *actParm &&
891 (options.stackAuto || IFFUNC_ISREENT (functype)))
894 resolveSymbols (*actParm);
896 /* the parameter type must be at least castable */
897 if (compareType (defParm->type, (*actParm)->ftype) == 0)
899 werror (E_INCOMPAT_TYPES);
900 printFromToType ((*actParm)->ftype, defParm->type);
904 /* if the parameter is castable then add the cast */
905 if (compareType (defParm->type, (*actParm)->ftype) < 0)
909 resultType = getResultTypeFromType (defParm->etype);
910 pTree = resolveSymbols (copyAst (*actParm));
912 /* now change the current one to a cast */
913 (*actParm)->type = EX_OP;
914 (*actParm)->opval.op = CAST;
915 (*actParm)->left = newAst_LINK (defParm->type);
916 (*actParm)->right = pTree;
917 (*actParm)->decorated = 0; /* force typechecking */
918 decorateType (*actParm, resultType);
921 /* make a copy and change the regparm type to the defined parm */
922 (*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
923 SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
924 SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
929 /*-----------------------------------------------------------------*/
930 /* createIvalType - generates ival for basic types */
931 /*-----------------------------------------------------------------*/
933 createIvalType (ast * sym, sym_link * type, initList * ilist)
937 /* if initList is deep */
938 if (ilist->type == INIT_DEEP)
939 ilist = ilist->init.deep;
941 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
942 return decorateType (newNode ('=', sym, iExpr), RESULT_TYPE_NONE);
945 /*-----------------------------------------------------------------*/
946 /* createIvalStruct - generates initial value for structures */
947 /*-----------------------------------------------------------------*/
949 createIvalStruct (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
956 sflds = SPEC_STRUCT (type)->fields;
957 if (ilist->type != INIT_DEEP)
959 werror (E_INIT_STRUCT, "");
963 iloop = ilist->init.deep;
965 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
967 /* if we have come to end */
971 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
972 lAst = decorateType (resolveSymbols (lAst), RESULT_TYPE_NONE);
973 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type,
974 iloop, rast, rootValue)),
980 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
981 W_EXCESS_INITIALIZERS, "struct",
982 sym->opval.val->sym->name);
989 /*-----------------------------------------------------------------*/
990 /* createIvalArray - generates code for array initialization */
991 /*-----------------------------------------------------------------*/
993 createIvalArray (ast * sym, sym_link * type, initList * ilist, ast *rootValue)
997 int lcnt = 0, size = 0;
998 literalList *literalL;
1000 /* take care of the special case */
1001 /* array of characters can be init */
1003 if (IS_CHAR (type->next))
1004 if ((rast = createIvalCharPtr (sym,
1006 decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE),
1009 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1011 /* not the special case */
1012 if (ilist->type != INIT_DEEP)
1014 werror (E_INIT_STRUCT, "");
1018 iloop = ilist->init.deep;
1019 lcnt = DCL_ELEM (type);
1021 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
1025 aSym = decorateType (resolveSymbols(sym), RESULT_TYPE_NONE);
1027 rast = newNode(ARRAYINIT, aSym, NULL);
1028 rast->values.constlist = literalL;
1030 // Make sure size is set to length of initializer list.
1034 iloop = iloop->next;
1037 if (lcnt && size > lcnt)
1039 // Array size was specified, and we have more initializers than needed.
1040 werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
1041 W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
1050 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
1051 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
1052 rast = createIval (aSym, type->next, iloop, rast, rootValue);
1053 iloop = (iloop ? iloop->next : NULL);
1059 /* no of elements given and we */
1060 /* have generated for all of them */
1063 // is this a better way? at least it won't crash
1064 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1065 werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name);
1072 /* if we have not been given a size */
1073 if (!DCL_ELEM (type))
1075 /* check, if it's a flexible array */
1076 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1077 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1079 DCL_ELEM (type) = size;
1082 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1086 /*-----------------------------------------------------------------*/
1087 /* createIvalCharPtr - generates initial values for char pointers */
1088 /*-----------------------------------------------------------------*/
1090 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1095 /* if this is a pointer & right is a literal array then */
1096 /* just assignment will do */
1097 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1098 SPEC_SCLS (iexpr->etype) == S_CODE)
1099 && IS_ARRAY (iexpr->ftype)))
1100 return newNode ('=', sym, iexpr);
1102 /* left side is an array so we have to assign each */
1104 if ((IS_LITERAL (iexpr->etype) ||
1105 SPEC_SCLS (iexpr->etype) == S_CODE)
1106 && IS_ARRAY (iexpr->ftype))
1108 /* for each character generate an assignment */
1109 /* to the array element */
1110 char *s = SPEC_CVAL (iexpr->etype).v_char;
1112 unsigned int symsize = getSize (type);
1114 size = getSize (iexpr->ftype);
1115 if (symsize && size>symsize)
1117 if (size>(symsize+1))
1119 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1121 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1127 for (i=0;i<size;i++)
1129 rast = newNode (NULLOP,
1133 newAst_VALUE (valueFromLit ((float) i))),
1134 newAst_VALUE (valueFromLit (*s))));
1138 // now WE don't need iexpr's symbol anymore
1139 freeStringSymbol(AST_SYMBOL(iexpr));
1141 /* if we have not been given a size */
1142 if (!DCL_ELEM (type))
1144 /* check, if it's a flexible array */
1145 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1146 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1148 DCL_ELEM (type) = size;
1151 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1157 /*-----------------------------------------------------------------*/
1158 /* createIvalPtr - generates initial value for pointers */
1159 /*-----------------------------------------------------------------*/
1161 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1167 if (ilist->type == INIT_DEEP)
1168 ilist = ilist->init.deep;
1170 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1172 /* if character pointer */
1173 if (IS_CHAR (type->next))
1174 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1177 return newNode ('=', sym, iexpr);
1180 /*-----------------------------------------------------------------*/
1181 /* createIval - generates code for initial value */
1182 /*-----------------------------------------------------------------*/
1184 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1191 /* if structure then */
1192 if (IS_STRUCT (type))
1193 rast = createIvalStruct (sym, type, ilist, rootValue);
1195 /* if this is a pointer */
1197 rast = createIvalPtr (sym, type, ilist, rootValue);
1199 /* if this is an array */
1200 if (IS_ARRAY (type))
1201 rast = createIvalArray (sym, type, ilist, rootValue);
1203 /* if type is SPECIFIER */
1205 rast = createIvalType (sym, type, ilist);
1208 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1210 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1213 /*-----------------------------------------------------------------*/
1214 /* initAggregates - initialises aggregate variables with initv */
1215 /*-----------------------------------------------------------------*/
1216 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1217 ast *newAst = newAst_VALUE (symbolVal (sym));
1218 return createIval (newAst, sym->type, ival, wid, newAst);
1221 /*-----------------------------------------------------------------*/
1222 /* gatherAutoInit - creates assignment expressions for initial */
1224 /*-----------------------------------------------------------------*/
1226 gatherAutoInit (symbol * autoChain)
1233 for (sym = autoChain; sym; sym = sym->next)
1236 /* resolve the symbols in the ival */
1238 resolveIvalSym (sym->ival, sym->type);
1241 /* if we are PIC16 port,
1242 * and this is a static,
1243 * and have initial value,
1244 * and not S_CODE, don't emit in gs segment,
1245 * but allow glue.c:pic16emitRegularMap to put symbol
1246 * in idata section */
1247 if(TARGET_IS_PIC16 &&
1248 IS_STATIC (sym->etype) && sym->ival
1249 && SPEC_SCLS(sym->etype) != S_CODE) {
1250 SPEC_SCLS (sym->etype) = S_DATA;
1255 /* if this is a static variable & has an */
1256 /* initial value the code needs to be lifted */
1257 /* here to the main portion since they can be */
1258 /* initialised only once at the start */
1259 if (IS_STATIC (sym->etype) && sym->ival &&
1260 SPEC_SCLS (sym->etype) != S_CODE)
1264 /* insert the symbol into the symbol table */
1265 /* with level = 0 & name = rname */
1266 newSym = copySymbol (sym);
1267 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1269 /* now lift the code to main */
1270 if (IS_AGGREGATE (sym->type)) {
1271 work = initAggregates (sym, sym->ival, NULL);
1273 if (getNelements(sym->type, sym->ival)>1) {
1274 werrorfl (sym->fileDef, sym->lineDef,
1275 W_EXCESS_INITIALIZERS, "scalar",
1278 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1279 list2expr (sym->ival));
1282 setAstLineno (work, sym->lineDef);
1286 staticAutos = newNode (NULLOP, staticAutos, work);
1293 /* if there is an initial value */
1294 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1296 initList *ilist=sym->ival;
1298 while (ilist->type == INIT_DEEP) {
1299 ilist = ilist->init.deep;
1302 /* update lineno for error msg */
1303 lineno = sym->lineDef;
1304 setAstLineno (ilist->init.node, sym->lineDef);
1306 if (IS_AGGREGATE (sym->type)) {
1307 work = initAggregates (sym, sym->ival, NULL);
1309 if (getNelements(sym->type, sym->ival)>1) {
1310 werrorfl (sym->fileDef, sym->lineDef,
1311 W_EXCESS_INITIALIZERS, "scalar",
1314 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1315 list2expr (sym->ival));
1319 setAstLineno (work, sym->lineDef);
1323 init = newNode (NULLOP, init, work);
1332 /*-----------------------------------------------------------------*/
1333 /* freeStringSymbol - delete a literal string if no more usage */
1334 /*-----------------------------------------------------------------*/
1335 void freeStringSymbol(symbol *sym) {
1336 /* make sure this is a literal string */
1337 assert (sym->isstrlit);
1338 if (--sym->isstrlit == 0) { // lower the usage count
1339 memmap *segment=SPEC_OCLS(sym->etype);
1341 deleteSetItem(&segment->syms, sym);
1346 /*-----------------------------------------------------------------*/
1347 /* stringToSymbol - creates a symbol from a literal string */
1348 /*-----------------------------------------------------------------*/
1350 stringToSymbol (value * val)
1352 char name[SDCC_NAME_MAX + 1];
1353 static int charLbl = 0;
1358 // have we heard this before?
1359 for (sp=statsg->syms; sp; sp=sp->next) {
1361 size = getSize (sym->type);
1362 if (sym->isstrlit && size == getSize (val->type) &&
1363 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1364 // yes, this is old news. Don't publish it again.
1365 sym->isstrlit++; // but raise the usage count
1366 return symbolVal(sym);
1370 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1371 sym = newSymbol (name, 0); /* make it @ level 0 */
1372 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1374 /* copy the type from the value passed */
1375 sym->type = copyLinkChain (val->type);
1376 sym->etype = getSpec (sym->type);
1377 /* change to storage class & output class */
1378 SPEC_SCLS (sym->etype) = S_CODE;
1379 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1380 SPEC_STAT (sym->etype) = 1;
1381 /* make the level & block = 0 */
1382 sym->block = sym->level = 0;
1384 /* create an ival */
1385 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1390 allocVariables (sym);
1393 return symbolVal (sym);
1397 /*-----------------------------------------------------------------*/
1398 /* processBlockVars - will go thru the ast looking for block if */
1399 /* a block is found then will allocate the syms */
1400 /* will also gather the auto inits present */
1401 /*-----------------------------------------------------------------*/
1403 processBlockVars (ast * tree, int *stack, int action)
1408 /* if this is a block */
1409 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1413 if (action == ALLOCATE)
1415 *stack += allocVariables (tree->values.sym);
1416 autoInit = gatherAutoInit (tree->values.sym);
1418 /* if there are auto inits then do them */
1420 tree->left = newNode (NULLOP, autoInit, tree->left);
1422 else /* action is deallocate */
1423 deallocLocal (tree->values.sym);
1426 processBlockVars (tree->left, stack, action);
1427 processBlockVars (tree->right, stack, action);
1432 /*-------------------------------------------------------------*/
1433 /* constExprTree - returns TRUE if this tree is a constant */
1435 /*-------------------------------------------------------------*/
1436 bool constExprTree (ast *cexpr) {
1442 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1444 switch (cexpr->type)
1447 if (IS_AST_LIT_VALUE(cexpr)) {
1448 // this is a literal
1451 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1452 // a function's address will never change
1455 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1456 // an array's address will never change
1459 if (IS_AST_SYM_VALUE(cexpr) &&
1460 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1461 // a symbol in code space will never change
1462 // This is only for the 'char *s="hallo"' case and will have to leave
1463 //printf(" code space symbol");
1468 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1469 "unexpected link in expression tree\n");
1472 if (cexpr->opval.op==ARRAYINIT) {
1473 // this is a list of literals
1476 if (cexpr->opval.op=='=') {
1477 return constExprTree(cexpr->right);
1479 if (cexpr->opval.op==CAST) {
1480 // cast ignored, maybe we should throw a warning here?
1481 return constExprTree(cexpr->right);
1483 if (cexpr->opval.op=='&') {
1486 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1489 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1494 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1499 /*-----------------------------------------------------------------*/
1500 /* constExprValue - returns the value of a constant expression */
1501 /* or NULL if it is not a constant expression */
1502 /*-----------------------------------------------------------------*/
1504 constExprValue (ast * cexpr, int check)
1506 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1508 /* if this is not a constant then */
1509 if (!IS_LITERAL (cexpr->ftype))
1511 /* then check if this is a literal array
1513 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1514 SPEC_CVAL (cexpr->etype).v_char &&
1515 IS_ARRAY (cexpr->ftype))
1517 value *val = valFromType (cexpr->ftype);
1518 SPEC_SCLS (val->etype) = S_LITERAL;
1519 val->sym = cexpr->opval.val->sym;
1520 val->sym->type = copyLinkChain (cexpr->ftype);
1521 val->sym->etype = getSpec (val->sym->type);
1522 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1526 /* if we are casting a literal value then */
1527 if (IS_AST_OP (cexpr) &&
1528 cexpr->opval.op == CAST &&
1529 IS_LITERAL (cexpr->right->ftype))
1531 return valCastLiteral (cexpr->ftype,
1532 floatFromVal (cexpr->right->opval.val));
1535 if (IS_AST_VALUE (cexpr))
1537 return cexpr->opval.val;
1541 werror (E_CONST_EXPECTED, "found expression");
1546 /* return the value */
1547 if (IS_AST_VALUE (cexpr))
1549 return cexpr->opval.val;
1554 /*-----------------------------------------------------------------*/
1555 /* isLabelInAst - will return true if a given label is found */
1556 /*-----------------------------------------------------------------*/
1558 isLabelInAst (symbol * label, ast * tree)
1560 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1563 if (IS_AST_OP (tree) &&
1564 tree->opval.op == LABEL &&
1565 isSymbolEqual (AST_SYMBOL (tree->left), label))
1568 return isLabelInAst (label, tree->right) &&
1569 isLabelInAst (label, tree->left);
1573 /*-----------------------------------------------------------------*/
1574 /* isLoopCountable - return true if the loop count can be determi- */
1575 /* -ned at compile time . */
1576 /*-----------------------------------------------------------------*/
1578 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1579 symbol ** sym, ast ** init, ast ** end)
1582 /* the loop is considered countable if the following
1583 conditions are true :-
1585 a) initExpr :- <sym> = <const>
1586 b) condExpr :- <sym> < <const1>
1587 c) loopExpr :- <sym> ++
1590 /* first check the initExpr */
1591 if (IS_AST_OP (initExpr) &&
1592 initExpr->opval.op == '=' && /* is assignment */
1593 IS_AST_SYM_VALUE (initExpr->left))
1594 { /* left is a symbol */
1596 *sym = AST_SYMBOL (initExpr->left);
1597 *init = initExpr->right;
1602 /* don't reverse loop with volatile counter */
1603 if (IS_VOLATILE ((*sym)->type))
1606 /* for now the symbol has to be of
1608 if (!IS_INTEGRAL ((*sym)->type))
1611 /* now check condExpr */
1612 if (IS_AST_OP (condExpr))
1615 switch (condExpr->opval.op)
1618 if (IS_AST_SYM_VALUE (condExpr->left) &&
1619 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1620 IS_AST_LIT_VALUE (condExpr->right))
1622 *end = condExpr->right;
1628 if (IS_AST_OP (condExpr->left) &&
1629 condExpr->left->opval.op == '>' &&
1630 IS_AST_LIT_VALUE (condExpr->left->right) &&
1631 IS_AST_SYM_VALUE (condExpr->left->left) &&
1632 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1635 *end = newNode ('+', condExpr->left->right,
1636 newAst_VALUE (constVal ("1")));
1649 /* check loop expression is of the form <sym>++ */
1650 if (!IS_AST_OP (loopExpr))
1653 /* check if <sym> ++ */
1654 if (loopExpr->opval.op == INC_OP)
1660 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1661 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1668 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1669 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1677 if (loopExpr->opval.op == ADD_ASSIGN)
1680 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1681 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1682 IS_AST_LIT_VALUE (loopExpr->right) &&
1683 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1691 /*-----------------------------------------------------------------*/
1692 /* astHasVolatile - returns true if ast contains any volatile */
1693 /*-----------------------------------------------------------------*/
1695 astHasVolatile (ast * tree)
1700 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1703 if (IS_AST_OP (tree))
1704 return astHasVolatile (tree->left) ||
1705 astHasVolatile (tree->right);
1710 /*-----------------------------------------------------------------*/
1711 /* astHasPointer - return true if the ast contains any ptr variable */
1712 /*-----------------------------------------------------------------*/
1714 astHasPointer (ast * tree)
1719 if (IS_AST_LINK (tree))
1722 /* if we hit an array expression then check
1723 only the left side */
1724 if (IS_AST_OP (tree) && tree->opval.op == '[')
1725 return astHasPointer (tree->left);
1727 if (IS_AST_VALUE (tree))
1728 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1730 return astHasPointer (tree->left) ||
1731 astHasPointer (tree->right);
1735 /*-----------------------------------------------------------------*/
1736 /* astHasSymbol - return true if the ast has the given symbol */
1737 /*-----------------------------------------------------------------*/
1739 astHasSymbol (ast * tree, symbol * sym)
1741 if (!tree || IS_AST_LINK (tree))
1744 if (IS_AST_VALUE (tree))
1746 if (IS_AST_SYM_VALUE (tree))
1747 return isSymbolEqual (AST_SYMBOL (tree), sym);
1752 return astHasSymbol (tree->left, sym) ||
1753 astHasSymbol (tree->right, sym);
1756 /*-----------------------------------------------------------------*/
1757 /* astHasDeref - return true if the ast has an indirect access */
1758 /*-----------------------------------------------------------------*/
1760 astHasDeref (ast * tree)
1762 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1765 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1767 return astHasDeref (tree->left) || astHasDeref (tree->right);
1770 /*-----------------------------------------------------------------*/
1771 /* isConformingBody - the loop body has to conform to a set of rules */
1772 /* for the loop to be considered reversible read on for rules */
1773 /*-----------------------------------------------------------------*/
1775 isConformingBody (ast * pbody, symbol * sym, ast * body)
1778 /* we are going to do a pre-order traversal of the
1779 tree && check for the following conditions. (essentially
1780 a set of very shallow tests )
1781 a) the sym passed does not participate in
1782 any arithmetic operation
1783 b) There are no function calls
1784 c) all jumps are within the body
1785 d) address of loop control variable not taken
1786 e) if an assignment has a pointer on the
1787 left hand side make sure right does not have
1788 loop control variable */
1790 /* if we reach the end or a leaf then true */
1791 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1794 /* if anything else is "volatile" */
1795 if (IS_VOLATILE (TETYPE (pbody)))
1798 /* we will walk the body in a pre-order traversal for
1800 switch (pbody->opval.op)
1802 /*------------------------------------------------------------------*/
1804 // if the loopvar is used as an index
1805 /* array op is commutative -- must check both left & right */
1806 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1809 return isConformingBody (pbody->right, sym, body)
1810 && isConformingBody (pbody->left, sym, body);
1812 /*------------------------------------------------------------------*/
1817 /*------------------------------------------------------------------*/
1821 /* sure we are not sym is not modified */
1823 IS_AST_SYM_VALUE (pbody->left) &&
1824 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1828 IS_AST_SYM_VALUE (pbody->right) &&
1829 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1834 /*------------------------------------------------------------------*/
1836 case '*': /* can be unary : if right is null then unary operation */
1841 /* if right is NULL then unary operation */
1842 /*------------------------------------------------------------------*/
1843 /*----------------------------*/
1845 /*----------------------------*/
1848 if (IS_AST_SYM_VALUE (pbody->left) &&
1849 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1852 return isConformingBody (pbody->left, sym, body);
1856 if (astHasSymbol (pbody->left, sym) ||
1857 astHasSymbol (pbody->right, sym))
1862 /*------------------------------------------------------------------*/
1873 if (IS_AST_SYM_VALUE (pbody->left) &&
1874 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1877 if (IS_AST_SYM_VALUE (pbody->right) &&
1878 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1881 return isConformingBody (pbody->left, sym, body) &&
1882 isConformingBody (pbody->right, sym, body);
1890 if (IS_AST_SYM_VALUE (pbody->left) &&
1891 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1893 return isConformingBody (pbody->left, sym, body);
1895 /*------------------------------------------------------------------*/
1907 case SIZEOF: /* evaluate wihout code generation */
1909 if (IS_AST_SYM_VALUE (pbody->left) &&
1910 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1913 if (IS_AST_SYM_VALUE (pbody->right) &&
1914 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1917 return isConformingBody (pbody->left, sym, body) &&
1918 isConformingBody (pbody->right, sym, body);
1920 /*------------------------------------------------------------------*/
1923 /* if left has a pointer & right has loop
1924 control variable then we cannot */
1925 if (astHasPointer (pbody->left) &&
1926 astHasSymbol (pbody->right, sym))
1928 if (astHasVolatile (pbody->left))
1931 if (IS_AST_SYM_VALUE (pbody->left)) {
1932 // if the loopvar has an assignment
1933 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1935 // if the loopvar is used in another (maybe conditional) block
1936 if (astHasSymbol (pbody->right, sym) &&
1937 (pbody->level >= body->level)) {
1942 if (astHasVolatile (pbody->left))
1945 if (astHasDeref(pbody->right)) return FALSE;
1947 return isConformingBody (pbody->left, sym, body) &&
1948 isConformingBody (pbody->right, sym, body);
1959 assert ("Parser should not have generated this\n");
1961 /*------------------------------------------------------------------*/
1962 /*----------------------------*/
1963 /* comma operator */
1964 /*----------------------------*/
1966 return isConformingBody (pbody->left, sym, body) &&
1967 isConformingBody (pbody->right, sym, body);
1969 /*------------------------------------------------------------------*/
1970 /*----------------------------*/
1972 /*----------------------------*/
1974 /* if local & not passed as paramater then ok */
1975 if (sym->level && !astHasSymbol(pbody->right,sym))
1979 /*------------------------------------------------------------------*/
1980 /*----------------------------*/
1981 /* return statement */
1982 /*----------------------------*/
1987 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1992 if (astHasSymbol (pbody->left, sym))
1999 return isConformingBody (pbody->left, sym, body) &&
2000 isConformingBody (pbody->right, sym, body);
2006 /*-----------------------------------------------------------------*/
2007 /* isLoopReversible - takes a for loop as input && returns true */
2008 /* if the for loop is reversible. If yes will set the value of */
2009 /* the loop control var & init value & termination value */
2010 /*-----------------------------------------------------------------*/
2012 isLoopReversible (ast * loop, symbol ** loopCntrl,
2013 ast ** init, ast ** end)
2015 /* if option says don't do it then don't */
2016 if (optimize.noLoopReverse)
2018 /* there are several tests to determine this */
2020 /* for loop has to be of the form
2021 for ( <sym> = <const1> ;
2022 [<sym> < <const2>] ;
2023 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
2025 if (!isLoopCountable (AST_FOR (loop, initExpr),
2026 AST_FOR (loop, condExpr),
2027 AST_FOR (loop, loopExpr),
2028 loopCntrl, init, end))
2031 /* now do some serious checking on the body of the loop
2034 return isConformingBody (loop->left, *loopCntrl, loop->left);
2038 /*-----------------------------------------------------------------*/
2039 /* replLoopSym - replace the loop sym by loop sym -1 */
2040 /*-----------------------------------------------------------------*/
2042 replLoopSym (ast * body, symbol * sym)
2045 if (!body || IS_AST_LINK (body))
2048 if (IS_AST_SYM_VALUE (body))
2051 if (isSymbolEqual (AST_SYMBOL (body), sym))
2055 body->opval.op = '-';
2056 body->left = newAst_VALUE (symbolVal (sym));
2057 body->right = newAst_VALUE (constVal ("1"));
2065 replLoopSym (body->left, sym);
2066 replLoopSym (body->right, sym);
2070 /*-----------------------------------------------------------------*/
2071 /* reverseLoop - do the actual loop reversal */
2072 /*-----------------------------------------------------------------*/
2074 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
2078 /* create the following tree
2083 if (sym) goto for_continue ;
2086 /* put it together piece by piece */
2087 rloop = newNode (NULLOP,
2088 createIf (newAst_VALUE (symbolVal (sym)),
2090 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2093 newAst_VALUE (symbolVal (sym)),
2096 replLoopSym (loop->left, sym);
2097 setAstLineno (rloop, init->lineno);
2099 rloop = newNode (NULLOP,
2101 newAst_VALUE (symbolVal (sym)),
2102 newNode ('-', end, init)),
2103 createLabel (AST_FOR (loop, continueLabel),
2107 newNode (SUB_ASSIGN,
2108 newAst_VALUE (symbolVal (sym)),
2109 newAst_VALUE (constVal ("1"))),
2112 rloop->lineno=init->lineno;
2113 return decorateType (rloop, RESULT_TYPE_NONE);
2117 /*-----------------------------------------------------------------*/
2118 /* searchLitOp - search tree (*ops only) for an ast with literal */
2119 /*-----------------------------------------------------------------*/
2121 searchLitOp (ast *tree, ast **parent, const char *ops)
2125 if (tree && optimize.global_cse)
2127 /* is there a literal operand? */
2129 IS_AST_OP(tree->right) &&
2130 tree->right->right &&
2131 (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1]))
2133 if (IS_LITERAL (RTYPE (tree->right)) !=
2134 IS_LITERAL (LTYPE (tree->right)))
2136 tree->right->decorated = 0;
2137 tree->decorated = 0;
2141 ret = searchLitOp (tree->right, parent, ops);
2146 IS_AST_OP(tree->left) &&
2147 tree->left->right &&
2148 (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1]))
2150 if (IS_LITERAL (RTYPE (tree->left)) !=
2151 IS_LITERAL (LTYPE (tree->left)))
2153 tree->left->decorated = 0;
2154 tree->decorated = 0;
2158 ret = searchLitOp (tree->left, parent, ops);
2166 /*-----------------------------------------------------------------*/
2167 /* getResultFromType */
2168 /*-----------------------------------------------------------------*/
2170 getResultTypeFromType (sym_link *type)
2172 /* type = getSpec (type); */
2174 return RESULT_TYPE_BIT;
2175 if (IS_BITFIELD (type))
2177 int blen = SPEC_BLEN (type);
2180 return RESULT_TYPE_BIT;
2182 return RESULT_TYPE_CHAR;
2183 return RESULT_TYPE_INT;
2186 return RESULT_TYPE_CHAR;
2189 return RESULT_TYPE_INT;
2190 return RESULT_TYPE_OTHER;
2193 /*-----------------------------------------------------------------*/
2194 /* addCast - adds casts to a type specified by RESULT_TYPE */
2195 /*-----------------------------------------------------------------*/
2197 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2200 bool upCasted = FALSE;
2204 case RESULT_TYPE_NONE:
2205 /* if thing smaller than int must be promoted to int */
2207 getSize (tree->etype) >= INTSIZE)
2208 /* promotion not necessary or already an int */
2210 /* char and bits: promote to int */
2211 newLink = newIntLink();
2214 case RESULT_TYPE_BIT:
2216 /* already an int */
2217 bitsForType (tree->etype) >= 16 ||
2218 /* bit to bit operation: don't promote, the code generators
2219 hopefully know everything about promotion rules */
2220 bitsForType (tree->etype) == 1)
2222 newLink = newIntLink();
2225 case RESULT_TYPE_CHAR:
2226 if (IS_CHAR (tree->etype) ||
2227 IS_FLOAT(tree->etype) ||
2228 IS_FIXED(tree->etype))
2230 newLink = newCharLink();
2232 case RESULT_TYPE_INT:
2234 if (getSize (tree->etype) > INTSIZE)
2236 /* warn ("Loosing significant digits"); */
2240 /* char: promote to int */
2242 getSize (tree->etype) >= INTSIZE)
2244 newLink = newIntLink();
2247 case RESULT_TYPE_IFX:
2248 case RESULT_TYPE_OTHER:
2250 /* return type is ifx, long, float: promote char to int */
2251 getSize (tree->etype) >= INTSIZE)
2253 newLink = newIntLink();
2259 tree->decorated = 0;
2260 tree = newNode (CAST, newAst_LINK (newLink), tree);
2261 tree->lineno = tree->right->lineno;
2262 /* keep unsigned type during cast to smaller type,
2263 but not when promoting from char to int */
2265 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2266 return decorateType (tree, resultType);
2269 /*-----------------------------------------------------------------*/
2270 /* resultTypePropagate - decides if resultType can be propagated */
2271 /*-----------------------------------------------------------------*/
2273 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2275 switch (tree->opval.op)
2294 return RESULT_TYPE_NONE;
2298 return RESULT_TYPE_IFX;
2300 return RESULT_TYPE_NONE;
2304 /*-----------------------------------------------------------------*/
2305 /* getLeftResultType - gets type from left branch for propagation */
2306 /*-----------------------------------------------------------------*/
2308 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2310 switch (tree->opval.op)
2314 if (IS_PTR (LTYPE (tree)))
2315 return RESULT_TYPE_NONE;
2317 return getResultTypeFromType (LETYPE (tree));
2319 if (IS_PTR (currFunc->type->next))
2320 return RESULT_TYPE_NONE;
2322 return getResultTypeFromType (currFunc->type->next);
2324 if (!IS_ARRAY (LTYPE (tree)))
2326 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2327 return RESULT_TYPE_CHAR;
2334 /*------------------------------------------------------------------*/
2335 /* gatherImplicitVariables: assigns correct type information to */
2336 /* symbols and values created by replaceAstWithTemporary */
2337 /* and adds the symbols to the declarations list of the */
2338 /* innermost block that contains them */
2339 /*------------------------------------------------------------------*/
2341 gatherImplicitVariables (ast * tree, ast * block)
2346 if (tree->type == EX_OP && tree->opval.op == BLOCK)
2348 /* keep track of containing scope */
2351 if (tree->type == EX_OP && tree->opval.op == '=' &&
2352 tree->left->type == EX_VALUE && tree->left->opval.val->sym)
2354 symbol *assignee = tree->left->opval.val->sym;
2356 /* special case for assignment to compiler-generated temporary variable:
2357 compute type of RHS, and set the symbol's type to match */
2358 if (assignee->type == NULL && assignee->infertype) {
2359 ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
2361 if (dtr != tree->right)
2364 assignee->type = copyLinkChain(TTYPE(dtr));
2365 assignee->etype = getSpec(assignee->type);
2366 SPEC_SCLS (assignee->etype) = S_AUTO;
2367 SPEC_OCLS (assignee->etype) = NULL;
2368 SPEC_EXTR (assignee->etype) = 0;
2369 SPEC_STAT (assignee->etype) = 0;
2370 SPEC_VOLATILE (assignee->etype) = 0;
2371 SPEC_ABSA (assignee->etype) = 0;
2373 wassertl(block != NULL, "implicit variable not contained in block");
2374 wassert(assignee->next == NULL);
2375 if (block != NULL) {
2376 symbol **decl = &(block->values.sym);
2379 wassert(*decl != assignee); /* should not already be in list */
2380 decl = &( (*decl)->next );
2387 if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) &&
2388 tree->opval.val->type == NULL &&
2389 tree->opval.val->sym &&
2390 tree->opval.val->sym->infertype)
2392 /* fixup type of value for compiler-inferred temporary var */
2393 tree->opval.val->type = tree->opval.val->sym->type;
2394 tree->opval.val->etype = tree->opval.val->sym->etype;
2397 gatherImplicitVariables(tree->left, block);
2398 gatherImplicitVariables(tree->right, block);
2401 /*--------------------------------------------------------------------*/
2402 /* decorateType - compute type for this tree, also does type checking.*/
2403 /* This is done bottom up, since type has to flow upwards. */
2404 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2405 /* result is a char and the operand(s) are int's. */
2406 /* It also does constant folding, and parameter checking. */
2407 /*--------------------------------------------------------------------*/
2409 decorateType (ast * tree, RESULT_TYPE resultType)
2413 RESULT_TYPE resultTypeProp;
2418 /* if already has type then do nothing */
2419 if (tree->decorated)
2422 tree->decorated = 1;
2425 /* print the line */
2426 /* if not block & function */
2427 if (tree->type == EX_OP &&
2428 (tree->opval.op != FUNCTION &&
2429 tree->opval.op != BLOCK &&
2430 tree->opval.op != NULLOP))
2432 filename = tree->filename;
2433 lineno = tree->lineno;
2437 /* if any child is an error | this one is an error do nothing */
2438 if (tree->isError ||
2439 (tree->left && tree->left->isError) ||
2440 (tree->right && tree->right->isError))
2443 /*------------------------------------------------------------------*/
2444 /*----------------------------*/
2445 /* leaf has been reached */
2446 /*----------------------------*/
2447 lineno = tree->lineno;
2448 /* if this is of type value */
2449 /* just get the type */
2450 if (tree->type == EX_VALUE)
2453 if (IS_LITERAL (tree->opval.val->etype))
2456 /* if this is a character array then declare it */
2457 if (IS_ARRAY (tree->opval.val->type))
2458 tree->opval.val = stringToSymbol (tree->opval.val);
2460 /* otherwise just copy the type information */
2461 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2465 if (tree->opval.val->sym)
2467 /* if the undefined flag is set then give error message */
2468 if (tree->opval.val->sym->undefined)
2470 werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name);
2472 TTYPE (tree) = TETYPE (tree) =
2473 tree->opval.val->type = tree->opval.val->sym->type =
2474 tree->opval.val->etype = tree->opval.val->sym->etype =
2475 copyLinkChain (INTTYPE);
2477 else if (tree->opval.val->sym->implicit)
2479 /* if implicit i.e. struct/union member then no type */
2480 TTYPE (tree) = TETYPE (tree) = NULL;
2484 /* copy the type from the value into the ast */
2485 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2487 /* and mark the symbol as referenced */
2488 tree->opval.val->sym->isref = 1;
2492 wassert(0); /* unreached: all values are literals or symbols */
2497 /* if type link for the case of cast */
2498 if (tree->type == EX_LINK)
2500 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2508 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2510 if (tree->left && tree->left->type == EX_OPERAND
2511 && (tree->left->opval.op == INC_OP
2512 || tree->left->opval.op == DEC_OP)
2513 && tree->left->left)
2515 tree->left->right = tree->left->left;
2516 tree->left->left = NULL;
2518 if (tree->right && tree->right->type == EX_OPERAND
2519 && (tree->right->opval.op == INC_OP
2520 || tree->right->opval.op == DEC_OP)
2521 && tree->right->left)
2523 tree->right->right = tree->right->left;
2524 tree->right->left = NULL;
2529 /* Before decorating the left branch we've to decide in dependence
2530 upon tree->opval.op, if resultType can be propagated */
2531 resultTypeProp = resultTypePropagate (tree, resultType);
2533 if (tree->opval.op == '?')
2534 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2536 dtl = decorateType (tree->left, resultTypeProp);
2538 /* if an array node, we may need to swap branches */
2539 if (tree->opval.op == '[')
2541 /* determine which is the array & which the index */
2542 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2543 IS_INTEGRAL (LTYPE (tree)))
2545 ast *tempTree = tree->left;
2546 tree->left = tree->right;
2547 tree->right = tempTree;
2551 /* After decorating the left branch there's type information available
2552 in tree->left->?type. If the op is e.g. '=' we extract the type
2553 information from there and propagate it to the right branch. */
2554 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2556 switch (tree->opval.op)
2559 /* delay right side for '?' operator since conditional macro
2560 expansions might rely on this */
2564 /* decorate right side for CALL (parameter list) in processParms();
2565 there is resultType available */
2569 dtr = decorateType (tree->right, resultTypeProp);
2573 /* this is to take care of situations
2574 when the tree gets rewritten */
2575 if (dtl != tree->left)
2577 if (dtr != tree->right)
2579 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2583 /* depending on type of operator do */
2585 switch (tree->opval.op)
2587 /*------------------------------------------------------------------*/
2588 /*----------------------------*/
2590 /*----------------------------*/
2593 /* first check if this is a array or a pointer */
2594 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2596 werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
2597 goto errorTreeReturn;
2600 /* check if the type of the idx */
2601 if (!IS_INTEGRAL (RTYPE (tree)))
2603 werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
2604 goto errorTreeReturn;
2607 /* if the left is an rvalue then error */
2610 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
2611 goto errorTreeReturn;
2614 if (IS_LITERAL (RTYPE (tree)))
2616 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2617 int arraySize = DCL_ELEM (LTYPE (tree));
2618 if (arraySize && arrayIndex >= arraySize)
2620 werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2625 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2626 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2629 /*------------------------------------------------------------------*/
2630 /*----------------------------*/
2632 /*----------------------------*/
2634 /* if this is not a structure */
2635 if (!IS_STRUCT (LTYPE (tree)))
2637 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
2638 goto errorTreeReturn;
2640 TTYPE (tree) = structElemType (LTYPE (tree),
2641 (tree->right->type == EX_VALUE ?
2642 tree->right->opval.val : NULL));
2643 TETYPE (tree) = getSpec (TTYPE (tree));
2646 /*------------------------------------------------------------------*/
2647 /*----------------------------*/
2648 /* struct/union pointer */
2649 /*----------------------------*/
2651 /* if not pointer to a structure */
2652 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2654 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
2655 goto errorTreeReturn;
2658 if (!IS_STRUCT (LTYPE (tree)->next))
2660 werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
2661 goto errorTreeReturn;
2664 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2665 (tree->right->type == EX_VALUE ?
2666 tree->right->opval.val : NULL));
2667 TETYPE (tree) = getSpec (TTYPE (tree));
2669 /* adjust the storage class */
2670 switch (DCL_TYPE(tree->left->ftype)) {
2672 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2675 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2678 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2681 SPEC_SCLS (TETYPE (tree)) = 0;
2684 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2687 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2690 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2693 SPEC_SCLS (TETYPE (tree)) = 0;
2700 /* This breaks with extern declarations, bitfields, and perhaps other */
2701 /* cases (gcse). Let's leave this optimization disabled for now and */
2702 /* ponder if there's a safe way to do this. -- EEP */
2704 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2705 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2707 /* If defined struct type at addr var
2708 then rewrite (&struct var)->member
2710 and define membertype at (addr+offsetof(struct var,member)) temp
2713 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2714 AST_SYMBOL(tree->right));
2716 sym = newSymbol(genSymName (0), 0);
2717 sym->type = TTYPE (tree);
2718 sym->etype = getSpec(sym->type);
2719 sym->lineDef = tree->lineno;
2722 SPEC_STAT (sym->etype) = 1;
2723 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2725 SPEC_ABSA(sym->etype) = 1;
2726 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2729 AST_VALUE (tree) = symbolVal(sym);
2732 tree->type = EX_VALUE;
2740 /*------------------------------------------------------------------*/
2741 /*----------------------------*/
2742 /* ++/-- operation */
2743 /*----------------------------*/
2747 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2748 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2749 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2750 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2759 /*------------------------------------------------------------------*/
2760 /*----------------------------*/
2762 /*----------------------------*/
2763 case '&': /* can be unary */
2764 /* if right is NULL then unary operation */
2765 if (tree->right) /* not an unary operation */
2768 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2770 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2771 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2772 printTypeChain (LTYPE (tree), stderr);
2773 fprintf (stderr, ",");
2774 printTypeChain (RTYPE (tree), stderr);
2775 fprintf (stderr, "\n");
2776 goto errorTreeReturn;
2779 /* if they are both literal */
2780 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2782 tree->type = EX_VALUE;
2783 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2784 valFromType (RETYPE (tree)), '&');
2786 tree->right = tree->left = NULL;
2787 TETYPE (tree) = tree->opval.val->etype;
2788 TTYPE (tree) = tree->opval.val->type;
2792 /* see if this is a GETHBIT operation if yes
2795 ast *otree = optimizeGetHbit (tree, resultType);
2798 return decorateType (otree, RESULT_TYPE_NONE);
2801 /* see if this is a GETABIT operation if yes
2804 ast *otree = optimizeGetAbit (tree, resultType);
2807 return decorateType (otree, RESULT_TYPE_NONE);
2810 /* see if this is a GETBYTE operation if yes
2813 ast *otree = optimizeGetByte (tree, resultType);
2816 return decorateType (otree, RESULT_TYPE_NONE);
2819 /* see if this is a GETWORD operation if yes
2822 ast *otree = optimizeGetWord (tree, resultType);
2825 return decorateType (otree, RESULT_TYPE_NONE);
2828 /* if left is a literal exchange left & right */
2829 if (IS_LITERAL (LTYPE (tree)))
2831 ast *tTree = tree->left;
2832 tree->left = tree->right;
2833 tree->right = tTree;
2836 /* if right is a literal and */
2837 /* we can find a 2nd literal in an and-tree then */
2838 /* rearrange the tree */
2839 if (IS_LITERAL (RTYPE (tree)))
2842 ast *litTree = searchLitOp (tree, &parent, "&");
2846 ast *tTree = litTree->left;
2847 litTree->left = tree->right;
2848 tree->right = tTree;
2849 /* both operands in litTree are literal now */
2850 decorateType (parent, resultType);
2854 LRVAL (tree) = RRVAL (tree) = 1;
2856 TTYPE (tree) = computeType (LTYPE (tree),
2860 TETYPE (tree) = getSpec (TTYPE (tree));
2865 /*------------------------------------------------------------------*/
2866 /*----------------------------*/
2868 /*----------------------------*/
2869 p = newLink (DECLARATOR);
2870 /* if bit field then error */
2871 if (IS_BITVAR (tree->left->etype))
2873 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
2874 goto errorTreeReturn;
2877 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2879 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
2880 goto errorTreeReturn;
2883 if (IS_FUNC (LTYPE (tree)))
2885 // this ought to be ignored
2886 return (tree->left);
2889 if (IS_LITERAL(LTYPE(tree)))
2891 werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
2892 goto errorTreeReturn;
2897 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
2898 goto errorTreeReturn;
2901 DCL_TYPE (p) = POINTER;
2902 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2903 DCL_TYPE (p) = CPOINTER;
2904 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2905 DCL_TYPE (p) = FPOINTER;
2906 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2907 DCL_TYPE (p) = PPOINTER;
2908 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2909 DCL_TYPE (p) = IPOINTER;
2910 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2911 DCL_TYPE (p) = EEPPOINTER;
2912 else if (SPEC_OCLS(tree->left->etype))
2913 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2915 DCL_TYPE (p) = POINTER;
2917 if (IS_AST_SYM_VALUE (tree->left))
2919 AST_SYMBOL (tree->left)->addrtaken = 1;
2920 AST_SYMBOL (tree->left)->allocreq = 1;
2923 p->next = LTYPE (tree);
2925 TETYPE (tree) = getSpec (TTYPE (tree));
2930 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2931 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2933 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2934 AST_SYMBOL(tree->left->right));
2935 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2936 valueFromLit(element->offset));
2939 tree->type = EX_VALUE;
2940 tree->values.literalFromCast = 1;
2946 /*------------------------------------------------------------------*/
2947 /*----------------------------*/
2949 /*----------------------------*/
2951 /* if the rewrite succeeds then don't go any further */
2953 ast *wtree = optimizeRRCRLC (tree);
2955 return decorateType (wtree, RESULT_TYPE_NONE);
2957 wtree = optimizeSWAP (tree);
2959 return decorateType (wtree, RESULT_TYPE_NONE);
2962 /* if left is a literal exchange left & right */
2963 if (IS_LITERAL (LTYPE (tree)))
2965 ast *tTree = tree->left;
2966 tree->left = tree->right;
2967 tree->right = tTree;
2970 /* if right is a literal and */
2971 /* we can find a 2nd literal in an or-tree then */
2972 /* rearrange the tree */
2973 if (IS_LITERAL (RTYPE (tree)))
2976 ast *litTree = searchLitOp (tree, &parent, "|");
2980 ast *tTree = litTree->left;
2981 litTree->left = tree->right;
2982 tree->right = tTree;
2983 /* both operands in tTree are literal now */
2984 decorateType (parent, resultType);
2989 /*------------------------------------------------------------------*/
2990 /*----------------------------*/
2992 /*----------------------------*/
2994 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2996 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
2997 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
2998 printTypeChain (LTYPE (tree), stderr);
2999 fprintf (stderr, ",");
3000 printTypeChain (RTYPE (tree), stderr);
3001 fprintf (stderr, "\n");
3002 goto errorTreeReturn;
3005 /* if they are both literal then rewrite the tree */
3006 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3008 tree->type = EX_VALUE;
3009 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3010 valFromType (RETYPE (tree)),
3012 tree->right = tree->left = NULL;
3013 TETYPE (tree) = tree->opval.val->etype;
3014 TTYPE (tree) = tree->opval.val->type;
3018 /* if left is a literal exchange left & right */
3019 if (IS_LITERAL (LTYPE (tree)))
3021 ast *tTree = tree->left;
3022 tree->left = tree->right;
3023 tree->right = tTree;
3026 /* if right is a literal and */
3027 /* we can find a 2nd literal in a xor-tree then */
3028 /* rearrange the tree */
3029 if (IS_LITERAL (RTYPE (tree)) &&
3030 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3033 ast *litTree = searchLitOp (tree, &parent, "^");
3037 ast *tTree = litTree->left;
3038 litTree->left = tree->right;
3039 tree->right = tTree;
3040 /* both operands in litTree are literal now */
3041 decorateType (parent, resultType);
3045 LRVAL (tree) = RRVAL (tree) = 1;
3047 TTYPE (tree) = computeType (LTYPE (tree),
3051 TETYPE (tree) = getSpec (TTYPE (tree));
3055 /*------------------------------------------------------------------*/
3056 /*----------------------------*/
3058 /*----------------------------*/
3060 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3062 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
3063 goto errorTreeReturn;
3065 /* if they are both literal then */
3066 /* rewrite the tree */
3067 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3069 tree->type = EX_VALUE;
3070 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
3071 valFromType (RETYPE (tree)));
3072 tree->right = tree->left = NULL;
3073 TETYPE (tree) = getSpec (TTYPE (tree) =
3074 tree->opval.val->type);
3078 LRVAL (tree) = RRVAL (tree) = 1;
3080 TETYPE (tree) = getSpec (TTYPE (tree) =
3081 computeType (LTYPE (tree),
3086 /* if right is a literal and */
3087 /* left is also a division by a literal then */
3088 /* rearrange the tree */
3089 if (IS_LITERAL (RTYPE (tree))
3090 /* avoid infinite loop */
3091 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
3094 ast *litTree = searchLitOp (tree, &parent, "/");
3097 if (IS_LITERAL (RTYPE (litTree)))
3101 litTree->right = newNode ('*',
3103 copyAst (tree->right));
3104 litTree->right->lineno = tree->lineno;
3106 tree->right->opval.val = constVal ("1");
3107 decorateType (parent, resultType);
3111 /* litTree->left is literal: no gcse possible.
3112 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3113 this would cause an infinit loop. */
3114 parent->decorated = 1;
3115 decorateType (litTree, resultType);
3122 /*------------------------------------------------------------------*/
3123 /*----------------------------*/
3125 /*----------------------------*/
3127 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3129 werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
3130 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3131 printTypeChain (LTYPE (tree), stderr);
3132 fprintf (stderr, ",");
3133 printTypeChain (RTYPE (tree), stderr);
3134 fprintf (stderr, "\n");
3135 goto errorTreeReturn;
3137 /* if they are both literal then */
3138 /* rewrite the tree */
3139 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3141 tree->type = EX_VALUE;
3142 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3143 valFromType (RETYPE (tree)));
3144 tree->right = tree->left = NULL;
3145 TETYPE (tree) = getSpec (TTYPE (tree) =
3146 tree->opval.val->type);
3149 LRVAL (tree) = RRVAL (tree) = 1;
3150 TETYPE (tree) = getSpec (TTYPE (tree) =
3151 computeType (LTYPE (tree),
3157 /*------------------------------------------------------------------*/
3158 /*----------------------------*/
3159 /* address dereference */
3160 /*----------------------------*/
3161 case '*': /* can be unary : if right is null then unary operation */
3164 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3166 werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
3167 goto errorTreeReturn;
3172 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
3173 goto errorTreeReturn;
3175 if (IS_ADDRESS_OF_OP(tree->left))
3177 /* replace *&obj with obj */
3178 return tree->left->left;
3180 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3181 TETYPE (tree) = getSpec (TTYPE (tree));
3182 /* adjust the storage class */
3183 switch (DCL_TYPE(tree->left->ftype)) {
3185 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3188 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3191 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3194 SPEC_SCLS (TETYPE (tree)) = 0;
3197 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3200 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3203 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3206 SPEC_SCLS (TETYPE (tree)) = 0;
3215 /*------------------------------------------------------------------*/
3216 /*----------------------------*/
3217 /* multiplication */
3218 /*----------------------------*/
3219 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3221 werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
3222 goto errorTreeReturn;
3225 /* if they are both literal then */
3226 /* rewrite the tree */
3227 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3229 tree->type = EX_VALUE;
3230 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3231 valFromType (RETYPE (tree)));
3232 tree->right = tree->left = NULL;
3233 TETYPE (tree) = getSpec (TTYPE (tree) =
3234 tree->opval.val->type);
3238 /* if left is a literal exchange left & right */
3239 if (IS_LITERAL (LTYPE (tree)))
3241 ast *tTree = tree->left;
3242 tree->left = tree->right;
3243 tree->right = tTree;
3246 /* if right is a literal and */
3247 /* we can find a 2nd literal in a mul-tree then */
3248 /* rearrange the tree */
3249 if (IS_LITERAL (RTYPE (tree)))
3252 ast *litTree = searchLitOp (tree, &parent, "*");
3256 ast *tTree = litTree->left;
3257 litTree->left = tree->right;
3258 tree->right = tTree;
3259 /* both operands in litTree are literal now */
3260 decorateType (parent, resultType);
3264 LRVAL (tree) = RRVAL (tree) = 1;
3265 tree->left = addCast (tree->left, resultType, FALSE);
3266 tree->right = addCast (tree->right, resultType, FALSE);
3267 TETYPE (tree) = getSpec (TTYPE (tree) =
3268 computeType (LTYPE (tree),
3275 /*------------------------------------------------------------------*/
3276 /*----------------------------*/
3277 /* unary '+' operator */
3278 /*----------------------------*/
3283 if (!IS_ARITHMETIC (LTYPE (tree)))
3285 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
3286 goto errorTreeReturn;
3289 /* if left is a literal then do it */
3290 if (IS_LITERAL (LTYPE (tree)))
3292 tree->type = EX_VALUE;
3293 tree->opval.val = valFromType (LETYPE (tree));
3295 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3299 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3303 /*------------------------------------------------------------------*/
3304 /*----------------------------*/
3306 /*----------------------------*/
3308 /* this is not a unary operation */
3309 /* if both pointers then problem */
3310 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3311 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3313 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
3314 goto errorTreeReturn;
3317 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3318 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3320 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3321 goto errorTreeReturn;
3324 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3325 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3327 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
3328 goto errorTreeReturn;
3330 /* if they are both literal then */
3331 /* rewrite the tree */
3332 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3334 tree->type = EX_VALUE;
3335 tree->left = addCast (tree->left, resultType, TRUE);
3336 tree->right = addCast (tree->right, resultType, TRUE);
3337 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3338 valFromType (RETYPE (tree)));
3339 tree->right = tree->left = NULL;
3340 TETYPE (tree) = getSpec (TTYPE (tree) =
3341 tree->opval.val->type);
3345 /* if the right is a pointer or left is a literal
3346 xchange left & right */
3347 if (IS_ARRAY (RTYPE (tree)) ||
3348 IS_PTR (RTYPE (tree)) ||
3349 IS_LITERAL (LTYPE (tree)))
3351 ast *tTree = tree->left;
3352 tree->left = tree->right;
3353 tree->right = tTree;
3356 /* if right is a literal and */
3357 /* left is also an addition/subtraction with a literal then */
3358 /* rearrange the tree */
3359 if (IS_LITERAL (RTYPE (tree)))
3361 ast *litTree, *parent;
3362 litTree = searchLitOp (tree, &parent, "+-");
3365 if (litTree->opval.op == '+')
3369 ast *tTree = litTree->left;
3370 litTree->left = tree->right;
3371 tree->right = tree->left;
3374 else if (litTree->opval.op == '-')
3376 if (IS_LITERAL (RTYPE (litTree)))
3380 ast *tTree = litTree->left;
3381 litTree->left = tree->right;
3382 tree->right = tTree;
3388 ast *tTree = litTree->right;
3389 litTree->right = tree->right;
3390 tree->right = tTree;
3391 litTree->opval.op = '+';
3392 tree->opval.op = '-';
3395 decorateType (parent, resultType);
3399 LRVAL (tree) = RRVAL (tree) = 1;
3400 /* if the left is a pointer */
3401 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3402 TETYPE (tree) = getSpec (TTYPE (tree) =
3406 tree->left = addCast (tree->left, resultType, TRUE);
3407 tree->right = addCast (tree->right, resultType, TRUE);
3408 TETYPE (tree) = getSpec (TTYPE (tree) =
3409 computeType (LTYPE (tree),
3417 /*------------------------------------------------------------------*/
3418 /*----------------------------*/
3420 /*----------------------------*/
3421 case '-': /* can be unary */
3422 /* if right is null then unary */
3426 if (!IS_ARITHMETIC (LTYPE (tree)))
3428 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3429 goto errorTreeReturn;
3432 /* if left is a literal then do it */
3433 if (IS_LITERAL (LTYPE (tree)))
3435 tree->type = EX_VALUE;
3436 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3438 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3441 tree->left = addCast (tree->left, resultType, TRUE);
3442 TETYPE (tree) = getSpec (TTYPE (tree) =
3443 computeType (LTYPE (tree),
3451 /*------------------------------------------------------------------*/
3452 /*----------------------------*/
3454 /*----------------------------*/
3456 if (!(IS_PTR (LTYPE (tree)) ||
3457 IS_ARRAY (LTYPE (tree)) ||
3458 IS_ARITHMETIC (LTYPE (tree))))
3460 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3461 goto errorTreeReturn;
3464 if (!(IS_PTR (RTYPE (tree)) ||
3465 IS_ARRAY (RTYPE (tree)) ||
3466 IS_ARITHMETIC (RTYPE (tree))))
3468 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3469 goto errorTreeReturn;
3472 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3473 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3474 IS_INTEGRAL (RTYPE (tree))))
3476 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
3477 goto errorTreeReturn;
3480 /* if they are both literal then */
3481 /* rewrite the tree */
3482 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3484 tree->type = EX_VALUE;
3485 tree->left = addCast (tree->left, resultType, TRUE);
3486 tree->right = addCast (tree->right, resultType, TRUE);
3487 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3488 valFromType (RETYPE (tree)));
3489 tree->right = tree->left = NULL;
3490 TETYPE (tree) = getSpec (TTYPE (tree) =
3491 tree->opval.val->type);
3495 /* if the left & right are equal then zero */
3496 if (isAstEqual (tree->left, tree->right))
3498 tree->type = EX_VALUE;
3499 tree->left = tree->right = NULL;
3500 tree->opval.val = constVal ("0");
3501 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3505 /* if both of them are pointers or arrays then */
3506 /* the result is going to be an integer */
3507 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3508 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3509 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3511 /* if only the left is a pointer */
3512 /* then result is a pointer */
3513 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3514 TETYPE (tree) = getSpec (TTYPE (tree) =
3518 tree->left = addCast (tree->left, resultType, TRUE);
3519 tree->right = addCast (tree->right, resultType, TRUE);
3521 TETYPE (tree) = getSpec (TTYPE (tree) =
3522 computeType (LTYPE (tree),
3528 LRVAL (tree) = RRVAL (tree) = 1;
3530 /* if right is a literal and */
3531 /* left is also an addition/subtraction with a literal then */
3532 /* rearrange the tree */
3533 if (IS_LITERAL (RTYPE (tree))
3534 /* avoid infinite loop */
3535 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
3537 ast *litTree, *litParent;
3538 litTree = searchLitOp (tree, &litParent, "+-");
3541 if (litTree->opval.op == '+')
3545 ast *tTree = litTree->left;
3546 litTree->left = litTree->right;
3547 litTree->right = tree->right;
3548 tree->right = tTree;
3549 tree->opval.op = '+';
3550 litTree->opval.op = '-';
3552 else if (litTree->opval.op == '-')
3554 if (IS_LITERAL (RTYPE (litTree)))
3558 ast *tTree = litTree->left;
3559 litTree->left = tree->right;
3560 tree->right = litParent->left;
3561 litParent->left = tTree;
3562 litTree->opval.op = '+';
3564 tree->decorated = 0;
3565 decorateType (tree, resultType);
3571 ast *tTree = litTree->right;
3572 litTree->right = tree->right;
3573 tree->right = tTree;
3576 decorateType (litParent, resultType);
3581 /*------------------------------------------------------------------*/
3582 /*----------------------------*/
3584 /*----------------------------*/
3586 /* can be only integral type */
3587 if (!IS_INTEGRAL (LTYPE (tree)))
3589 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3590 goto errorTreeReturn;
3593 /* if left is a literal then do it */
3594 if (IS_LITERAL (LTYPE (tree)))
3596 tree->type = EX_VALUE;
3597 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3599 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3600 return addCast (tree, resultType, TRUE);
3603 if (resultType == RESULT_TYPE_BIT &&
3604 IS_UNSIGNED (tree->left->etype) &&
3605 getSize (tree->left->etype) < INTSIZE)
3607 /* promotion rules are responsible for this strange result:
3608 bit -> int -> ~int -> bit
3609 uchar -> int -> ~int -> bit
3611 werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
3613 /* optimize bit-result, even if we optimize a buggy source */
3614 tree->type = EX_VALUE;
3615 tree->opval.val = constVal ("1");
3618 tree->left = addCast (tree->left, resultType, TRUE);
3620 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3623 /*------------------------------------------------------------------*/
3624 /*----------------------------*/
3626 /*----------------------------*/
3628 /* can be pointer */
3629 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3630 !IS_PTR (LTYPE (tree)) &&
3631 !IS_ARRAY (LTYPE (tree)))
3633 werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
3634 goto errorTreeReturn;
3637 /* if left is another '!' */
3638 if (tree->left->opval.op == '!')
3640 /* remove double '!!X' by 'X ? 1 : 0' */
3641 tree->opval.op = '?';
3642 tree->left = tree->left->left;
3643 tree->right = newNode (':',
3644 newAst_VALUE (constVal ("1")),
3645 newAst_VALUE (constVal ("0")));
3646 tree->right->lineno = tree->lineno;
3647 tree->decorated = 0;
3648 return decorateType (tree, resultType);
3651 /* if left is a literal then do it */
3652 if (IS_LITERAL (LTYPE (tree)))
3654 tree->type = EX_VALUE;
3655 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3657 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3661 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3664 /*------------------------------------------------------------------*/
3665 /*----------------------------*/
3667 /*----------------------------*/
3671 TTYPE (tree) = LTYPE (tree);
3672 TETYPE (tree) = LETYPE (tree);
3677 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3681 TTYPE (tree) = TETYPE (tree) = newCharLink();
3685 TTYPE (tree) = TETYPE (tree) = newIntLink();
3690 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3692 werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
3693 werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
3694 printTypeChain (LTYPE (tree), stderr);
3695 fprintf (stderr, ",");
3696 printTypeChain (RTYPE (tree), stderr);
3697 fprintf (stderr, "\n");
3698 goto errorTreeReturn;
3701 /* make smaller type only if it's a LEFT_OP */
3702 if (tree->opval.op == LEFT_OP)
3703 tree->left = addCast (tree->left, resultType, TRUE);
3705 /* if they are both literal then */
3706 /* rewrite the tree */
3707 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3709 tree->type = EX_VALUE;
3710 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3711 valFromType (RETYPE (tree)),
3712 (tree->opval.op == LEFT_OP ? 1 : 0));
3713 tree->right = tree->left = NULL;
3714 TETYPE (tree) = getSpec (TTYPE (tree) =
3715 tree->opval.val->type);
3719 /* see if this is a GETBYTE operation if yes
3722 ast *otree = optimizeGetByte (tree, resultType);
3725 return decorateType (otree, RESULT_TYPE_NONE);
3728 /* see if this is a GETWORD operation if yes
3731 ast *otree = optimizeGetWord (tree, resultType);
3734 return decorateType (otree, RESULT_TYPE_NONE);
3737 LRVAL (tree) = RRVAL (tree) = 1;
3738 if (tree->opval.op == LEFT_OP)
3740 TETYPE (tree) = getSpec (TTYPE (tree) =
3741 computeType (LTYPE (tree),
3748 /* no promotion necessary */
3749 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3750 if (IS_LITERAL (TTYPE (tree)))
3751 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3754 /* if only the right side is a literal & we are
3755 shifting more than size of the left operand then zero */
3756 if (IS_LITERAL (RTYPE (tree)) &&
3757 ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
3758 (getSize (TETYPE (tree)) * 8))
3760 if (tree->opval.op==LEFT_OP ||
3761 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3763 werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
3764 (tree->opval.op == LEFT_OP ? "left" : "right"));
3765 tree->type = EX_VALUE;
3766 tree->left = tree->right = NULL;
3767 tree->opval.val = constVal ("0");
3768 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3775 /*------------------------------------------------------------------*/
3776 /*----------------------------*/
3778 /*----------------------------*/
3779 case CAST: /* change the type */
3780 /* cannot cast to an aggregate type */
3781 if (IS_AGGREGATE (LTYPE (tree)))
3783 werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
3784 goto errorTreeReturn;
3787 /* make sure the type is complete and sane */
3788 changePointer(LTYPE(tree));
3789 checkTypeSanity(LETYPE(tree), "(cast)");
3791 /* if 'from' and 'to' are the same remove the superfluous cast, */
3792 /* this helps other optimizations */
3793 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3798 /* If code memory is read only, then pointers to code memory */
3799 /* implicitly point to constants -- make this explicit */
3801 sym_link *t = LTYPE(tree);
3802 while (t && t->next)
3804 if (IS_CODEPTR(t) && port->mem.code_ro)
3806 if (IS_SPEC(t->next))
3807 SPEC_CONST (t->next) = 1;
3809 DCL_PTR_CONST (t->next) = 1;
3816 /* if the right is a literal replace the tree */
3817 if (IS_LITERAL (RETYPE (tree))) {
3818 if (!IS_PTR (LTYPE (tree))) {
3819 tree->type = EX_VALUE;
3821 valCastLiteral (LTYPE (tree),
3822 floatFromVal (valFromType (RETYPE (tree))));
3825 TTYPE (tree) = tree->opval.val->type;
3826 tree->values.literalFromCast = 1;
3827 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3828 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3829 sym_link *rest = LTYPE(tree)->next;
3830 werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
3831 TTYPE(tree) = newLink(DECLARATOR);
3832 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3833 TTYPE(tree)->next = rest;
3834 tree->left->opval.lnk = TTYPE(tree);
3837 TTYPE (tree) = LTYPE (tree);
3841 TTYPE (tree) = LTYPE (tree);
3845 #if 0 // this is already checked, now this could be explicit
3846 /* if pointer to struct then check names */
3847 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3848 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3849 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3851 werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3852 SPEC_STRUCT(LETYPE(tree))->tag);
3855 if (IS_ADDRESS_OF_OP(tree->right)
3856 && IS_AST_SYM_VALUE (tree->right->left)
3857 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3859 symbol * sym = AST_SYMBOL (tree->right->left);
3860 unsigned int gptype = 0;
3861 unsigned int addr = SPEC_ADDR (sym->etype);
3863 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
3864 || TARGET_IS_PIC16) )
3866 switch (SPEC_SCLS (sym->etype))
3869 gptype = GPTYPE_CODE;
3872 gptype = GPTYPE_FAR;
3876 gptype = GPTYPE_NEAR;
3879 gptype = GPTYPE_XSTACK;
3884 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3885 gptype = GPTYPE_NEAR;
3887 addr |= gptype << (8*(GPTRSIZE - 1));
3890 tree->type = EX_VALUE;
3892 valCastLiteral (LTYPE (tree), addr);
3893 TTYPE (tree) = tree->opval.val->type;
3894 TETYPE (tree) = getSpec (TTYPE (tree));
3897 tree->values.literalFromCast = 1;
3901 /* handle offsetof macro: */
3902 /* #define offsetof(TYPE, MEMBER) \ */
3903 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3904 if (IS_ADDRESS_OF_OP(tree->right)
3905 && IS_AST_OP (tree->right->left)
3906 && tree->right->left->opval.op == PTR_OP
3907 && IS_AST_OP (tree->right->left->left)
3908 && tree->right->left->left->opval.op == CAST
3909 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3911 symbol *element = getStructElement (
3912 SPEC_STRUCT (LETYPE(tree->right->left)),
3913 AST_SYMBOL(tree->right->left->right)
3917 tree->type = EX_VALUE;
3918 tree->opval.val = valCastLiteral (
3921 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3924 TTYPE (tree) = tree->opval.val->type;
3925 TETYPE (tree) = getSpec (TTYPE (tree));
3932 /* if the right is a literal replace the tree */
3933 if (IS_LITERAL (RETYPE (tree))) {
3935 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3936 /* rewrite (type *)litaddr
3938 and define type at litaddr temp
3939 (but only if type's storage class is not generic)
3941 ast *newTree = newNode ('&', NULL, NULL);
3944 TTYPE (newTree) = LTYPE (tree);
3945 TETYPE (newTree) = getSpec(LTYPE (tree));
3947 /* define a global symbol at the casted address*/
3948 sym = newSymbol(genSymName (0), 0);
3949 sym->type = LTYPE (tree)->next;
3951 sym->type = newLink (V_VOID);
3952 sym->etype = getSpec(sym->type);
3953 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3954 sym->lineDef = tree->lineno;
3957 SPEC_STAT (sym->etype) = 1;
3958 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3959 SPEC_ABSA(sym->etype) = 1;
3960 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3963 newTree->left = newAst_VALUE(symbolVal(sym));
3964 newTree->left->lineno = tree->lineno;
3965 LTYPE (newTree) = sym->type;
3966 LETYPE (newTree) = sym->etype;
3967 LLVAL (newTree) = 1;
3968 LRVAL (newTree) = 0;
3969 TLVAL (newTree) = 1;
3973 if (!IS_PTR (LTYPE (tree))) {
3974 tree->type = EX_VALUE;
3976 valCastLiteral (LTYPE (tree),
3977 floatFromVal (valFromType (RTYPE (tree))));
3978 TTYPE (tree) = tree->opval.val->type;
3981 tree->values.literalFromCast = 1;
3982 TETYPE (tree) = getSpec (TTYPE (tree));
3986 TTYPE (tree) = LTYPE (tree);
3990 TETYPE (tree) = getSpec (TTYPE (tree));
3994 /*------------------------------------------------------------------*/
3995 /*----------------------------*/
3996 /* logical &&, || */
3997 /*----------------------------*/
4000 /* each must be arithmetic type or be a pointer */
4001 if (!IS_PTR (LTYPE (tree)) &&
4002 !IS_ARRAY (LTYPE (tree)) &&
4003 !IS_INTEGRAL (LTYPE (tree)))
4005 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4006 goto errorTreeReturn;
4009 if (!IS_PTR (RTYPE (tree)) &&
4010 !IS_ARRAY (RTYPE (tree)) &&
4011 !IS_INTEGRAL (RTYPE (tree)))
4013 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4014 goto errorTreeReturn;
4016 /* if they are both literal then */
4017 /* rewrite the tree */
4018 if (IS_LITERAL (RTYPE (tree)) &&
4019 IS_LITERAL (LTYPE (tree)))
4021 tree->type = EX_VALUE;
4022 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4023 valFromType (RTYPE (tree)),
4025 tree->right = tree->left = NULL;
4026 TETYPE (tree) = getSpec (TTYPE (tree) =
4027 tree->opval.val->type);
4030 LRVAL (tree) = RRVAL (tree) = 1;
4031 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4034 /*------------------------------------------------------------------*/
4035 /*----------------------------*/
4036 /* comparison operators */
4037 /*----------------------------*/
4045 ast *lt = optimizeCompare (tree);
4051 /* if they are pointers they must be castable */
4052 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4054 if (tree->opval.op==EQ_OP &&
4055 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4056 // we cannot cast a gptr to a !gptr: switch the leaves
4057 struct ast *s=tree->left;
4058 tree->left=tree->right;
4061 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4063 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4064 fprintf (stderr, "comparing type ");
4065 printTypeChain (LTYPE (tree), stderr);
4066 fprintf (stderr, "to type ");
4067 printTypeChain (RTYPE (tree), stderr);
4068 fprintf (stderr, "\n");
4069 goto errorTreeReturn;
4072 /* else they should be promotable to one another */
4075 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4076 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4078 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4080 werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
4081 fprintf (stderr, "comparing type ");
4082 printTypeChain (LTYPE (tree), stderr);
4083 fprintf (stderr, "to type ");
4084 printTypeChain (RTYPE (tree), stderr);
4085 fprintf (stderr, "\n");
4086 goto errorTreeReturn;
4091 CCR_RESULT ccr_result = CCR_OK;
4093 /* if left is integral and right is literal
4094 then check constant range */
4095 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4096 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4097 tree->opval.op, FALSE);
4098 if (ccr_result == CCR_OK &&
4099 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4100 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4101 tree->opval.op, TRUE);
4104 case CCR_ALWAYS_TRUE:
4105 case CCR_ALWAYS_FALSE:
4106 if (!options.lessPedantic)
4107 werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
4108 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4109 return decorateType (newAst_VALUE (constVal (
4110 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4118 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4119 if (tree->opval.op == '>' &&
4120 SPEC_USIGN(LETYPE(tree)) &&
4121 IS_LITERAL(RTYPE(tree)) &&
4122 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
4124 if (resultType == RESULT_TYPE_IFX)
4126 /* the parent is an ifx: */
4127 /* if (unsigned value) */
4131 /* (unsigned value) ? 1 : 0 */
4132 tree->opval.op = '?';
4133 tree->right = newNode (':',
4134 newAst_VALUE (constVal ("1")),
4135 tree->right); /* val 0 */
4136 tree->right->lineno = tree->lineno;
4137 tree->right->left->lineno = tree->lineno;
4138 tree->decorated = 0;
4139 return decorateType (tree, resultType);
4142 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4143 if (IS_LITERAL(RTYPE(tree)) &&
4144 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4145 tree->opval.op == EQ_OP &&
4146 resultType == RESULT_TYPE_IFX)
4148 tree->opval.op = '!';
4150 tree->decorated = 0;
4151 return decorateType (tree, resultType);
4154 /* if they are both literal then */
4155 /* rewrite the tree */
4156 if (IS_LITERAL (RTYPE (tree)) &&
4157 IS_LITERAL (LTYPE (tree)))
4159 tree->type = EX_VALUE;
4160 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4161 valFromType (RETYPE (tree)),
4163 tree->right = tree->left = NULL;
4164 TETYPE (tree) = getSpec (TTYPE (tree) =
4165 tree->opval.val->type);
4169 /* if one is 'signed char ' and the other one is 'unsigned char' */
4170 /* it's necessary to promote to int */
4171 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4172 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4174 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4175 if it's possible to use a 'signed char' */
4177 /* is left a 'unsigned char'? */
4178 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4179 /* the value range of a 'unsigned char' is 0...255;
4180 if the actual value is < 128 it can be changed to signed */
4181 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
4183 /* now we've got 2 'signed char'! */
4184 SPEC_USIGN (RETYPE (tree)) = 0;
4186 /* same test for the left operand: */
4187 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4188 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4190 SPEC_USIGN (LETYPE (tree)) = 0;
4194 werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
4195 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4196 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4200 LRVAL (tree) = RRVAL (tree) = 1;
4201 TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4203 /* condition transformations */
4205 unsigned transformedOp = 0;
4207 switch (tree->opval.op)
4209 case '<': /* transform (a < b) to !(a >= b) */
4211 transformedOp = GE_OP;
4213 case '>': /* transform (a > b) to !(a <= b) */
4215 transformedOp = LE_OP;
4217 case LE_OP: /* transform (a <= b) to !(a > b) */
4219 transformedOp = '>';
4221 case GE_OP: /* transform (a >= b) to !(a < b) */
4223 transformedOp = '<';
4225 case NE_OP: /* transform (a != b) to !(a == b) */
4227 transformedOp = EQ_OP;
4229 case EQ_OP: /* transform (a == b) to !(a != b) */
4231 transformedOp = NE_OP;
4238 tree->opval.op = transformedOp;
4239 tree->decorated = 0;
4240 tree = newNode ('!', tree, NULL);
4241 tree->lineno = tree->left->lineno;
4242 return decorateType (tree, resultType);
4248 /*------------------------------------------------------------------*/
4249 /*----------------------------*/
4251 /*----------------------------*/
4252 case SIZEOF: /* evaluate wihout code generation */
4253 /* change the type to a integer */
4255 int size = getSize (tree->right->ftype);
4256 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4257 if (!size && !IS_VOID(tree->right->ftype))
4258 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4260 tree->type = EX_VALUE;
4261 tree->opval.val = constVal (buffer);
4262 tree->right = tree->left = NULL;
4263 TETYPE (tree) = getSpec (TTYPE (tree) =
4264 tree->opval.val->type);
4267 /*------------------------------------------------------------------*/
4268 /*----------------------------*/
4270 /*----------------------------*/
4272 /* return typeof enum value */
4273 tree->type = EX_VALUE;
4276 if (IS_SPEC(tree->right->ftype)) {
4277 switch (SPEC_NOUN(tree->right->ftype)) {
4279 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4280 else typeofv = TYPEOF_INT;
4283 typeofv = TYPEOF_FLOAT;
4286 typeofv = TYPEOF_FIXED16X16;
4289 typeofv = TYPEOF_CHAR;
4292 typeofv = TYPEOF_VOID;
4295 typeofv = TYPEOF_STRUCT;
4298 typeofv = TYPEOF_BITFIELD;
4301 typeofv = TYPEOF_BIT;
4304 typeofv = TYPEOF_SBIT;
4310 switch (DCL_TYPE(tree->right->ftype)) {
4312 typeofv = TYPEOF_POINTER;
4315 typeofv = TYPEOF_FPOINTER;
4318 typeofv = TYPEOF_CPOINTER;
4321 typeofv = TYPEOF_GPOINTER;
4324 typeofv = TYPEOF_PPOINTER;
4327 typeofv = TYPEOF_IPOINTER;
4330 typeofv = TYPEOF_ARRAY;
4333 typeofv = TYPEOF_FUNCTION;
4339 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4340 tree->opval.val = constVal (buffer);
4341 tree->right = tree->left = NULL;
4342 TETYPE (tree) = getSpec (TTYPE (tree) =
4343 tree->opval.val->type);
4346 /*------------------------------------------------------------------*/
4347 /*----------------------------*/
4348 /* conditional operator '?' */
4349 /*----------------------------*/
4351 /* the type is value of the colon operator (on the right) */
4352 assert (IS_COLON_OP (tree->right));
4353 /* if already known then replace the tree : optimizer will do it
4354 but faster to do it here */
4355 if (IS_LITERAL (LTYPE (tree)))
4357 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4358 return decorateType (tree->right->left, resultTypeProp);
4360 return decorateType (tree->right->right, resultTypeProp);
4364 tree->right = decorateType (tree->right, resultTypeProp);
4365 TTYPE (tree) = RTYPE (tree);
4366 TETYPE (tree) = getSpec (TTYPE (tree));
4371 /* if they don't match we have a problem */
4372 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4373 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4375 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
4376 goto errorTreeReturn;
4379 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4380 resultType, tree->opval.op);
4381 TETYPE (tree) = getSpec (TTYPE (tree));
4385 #if 0 // assignment operators are converted by the parser
4386 /*------------------------------------------------------------------*/
4387 /*----------------------------*/
4388 /* assignment operators */
4389 /*----------------------------*/
4392 /* for these it must be both must be integral */
4393 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4394 !IS_ARITHMETIC (RTYPE (tree)))
4396 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4397 goto errorTreeReturn;
4400 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4402 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4403 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4407 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4408 goto errorTreeReturn;
4419 /* for these it must be both must be integral */
4420 if (!IS_INTEGRAL (LTYPE (tree)) ||
4421 !IS_INTEGRAL (RTYPE (tree)))
4423 werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
4424 goto errorTreeReturn;
4427 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4429 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4430 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4434 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4435 goto errorTreeReturn;
4441 /*------------------------------------------------------------------*/
4442 /*----------------------------*/
4444 /*----------------------------*/
4446 if (!(IS_PTR (LTYPE (tree)) ||
4447 IS_ARITHMETIC (LTYPE (tree))))
4449 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4450 goto errorTreeReturn;
4453 if (!(IS_PTR (RTYPE (tree)) ||
4454 IS_ARITHMETIC (RTYPE (tree))))
4456 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
4457 goto errorTreeReturn;
4460 TETYPE (tree) = getSpec (TTYPE (tree) =
4461 computeType (LTYPE (tree),
4466 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4467 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
4471 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
4472 goto errorTreeReturn;
4478 /*------------------------------------------------------------------*/
4479 /*----------------------------*/
4481 /*----------------------------*/
4483 /* this is not a unary operation */
4484 /* if both pointers then problem */
4485 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4487 werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
4488 goto errorTreeReturn;
4491 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4493 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4494 goto errorTreeReturn;
4497 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4499 werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
4500 goto errorTreeReturn;
4503 TETYPE (tree) = getSpec (TTYPE (tree) =
4504 computeType (LTYPE (tree),
4509 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4510 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
4514 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
4515 goto errorTreeReturn;
4518 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4519 tree->opval.op = '=';
4524 /*------------------------------------------------------------------*/
4525 /*----------------------------*/
4526 /* straight assignemnt */
4527 /*----------------------------*/
4529 /* cannot be an aggregate */
4530 if (IS_AGGREGATE (LTYPE (tree)))
4532 werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
4533 goto errorTreeReturn;
4536 /* they should either match or be castable */
4537 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4539 werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
4540 printFromToType(RTYPE(tree),LTYPE(tree));
4543 /* if the left side of the tree is of type void
4544 then report error */
4545 if (IS_VOID (LTYPE (tree)))
4547 werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
4548 printFromToType(RTYPE(tree), LTYPE(tree));
4551 TETYPE (tree) = getSpec (TTYPE (tree) =
4555 if (!tree->initMode ) {
4556 if (IS_CONSTANT(LTYPE(tree)))
4557 werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
4561 werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
4562 goto errorTreeReturn;
4567 /*------------------------------------------------------------------*/
4568 /*----------------------------*/
4569 /* comma operator */
4570 /*----------------------------*/
4572 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4575 /*------------------------------------------------------------------*/
4576 /*----------------------------*/
4578 /*----------------------------*/
4581 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4582 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4584 if (tree->left->opval.op == '*' && !tree->left->right)
4585 tree->left = tree->left->left;
4588 /* require a function or pointer to function */
4589 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4591 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4592 goto errorTreeReturn;
4595 /* if there are parms, make sure that
4596 parms are decorate / process / reverse only once */
4598 !tree->right->decorated)
4603 if (IS_FUNCPTR (LTYPE (tree)))
4605 functype = LTYPE (tree)->next;
4606 processFuncPtrArgs (functype);
4609 functype = LTYPE (tree);
4611 if (processParms (tree->left, FUNC_ARGS(functype),
4612 &tree->right, &parmNumber, TRUE))
4614 goto errorTreeReturn;
4617 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4618 !IFFUNC_ISBUILTIN(functype))
4620 reverseParms (tree->right);
4623 TTYPE (tree) = functype->next;
4624 TETYPE (tree) = getSpec (TTYPE (tree));
4628 /*------------------------------------------------------------------*/
4629 /*----------------------------*/
4630 /* return statement */
4631 /*----------------------------*/
4636 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4638 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4639 printFromToType (RTYPE(tree), currFunc->type->next);
4640 goto errorTreeReturn;
4643 if (IS_VOID (currFunc->type->next)
4645 !IS_VOID (RTYPE (tree)))
4647 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4648 goto errorTreeReturn;
4651 /* if there is going to be a casting required then add it */
4652 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4655 decorateType (newNode (CAST,
4656 newAst_LINK (copyLinkChain (currFunc->type->next)),
4666 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4668 werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
4669 goto errorTreeReturn;
4672 TTYPE (tree) = TETYPE (tree) = NULL;
4675 /*------------------------------------------------------------------*/
4676 /*----------------------------*/
4677 /* switch statement */
4678 /*----------------------------*/
4680 /* the switch value must be an integer */
4681 if (!IS_INTEGRAL (LTYPE (tree)))
4683 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4684 goto errorTreeReturn;
4687 TTYPE (tree) = TETYPE (tree) = NULL;
4690 /*------------------------------------------------------------------*/
4691 /*----------------------------*/
4693 /*----------------------------*/
4695 tree->left = backPatchLabels (tree->left,
4698 TTYPE (tree) = TETYPE (tree) = NULL;
4701 /*------------------------------------------------------------------*/
4702 /*----------------------------*/
4704 /*----------------------------*/
4707 AST_FOR (tree, initExpr) = decorateType (
4708 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4709 AST_FOR (tree, condExpr) = decorateType (
4710 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4711 AST_FOR (tree, loopExpr) = decorateType (
4712 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4714 /* if the for loop is reversible then
4715 reverse it otherwise do what we normally
4721 if (isLoopReversible (tree, &sym, &init, &end))
4722 return reverseLoop (tree, sym, init, end);
4724 return decorateType (createFor (AST_FOR (tree, trueLabel),
4725 AST_FOR (tree, continueLabel),
4726 AST_FOR (tree, falseLabel),
4727 AST_FOR (tree, condLabel),
4728 AST_FOR (tree, initExpr),
4729 AST_FOR (tree, condExpr),
4730 AST_FOR (tree, loopExpr),
4731 tree->left), RESULT_TYPE_NONE);
4734 werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
4735 "node PARAM shouldn't be processed here");
4736 /* but in processParams() */
4739 TTYPE (tree) = TETYPE (tree) = NULL;
4743 /* some error found this tree will be killed */
4745 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4746 tree->opval.op = NULLOP;
4752 /*-----------------------------------------------------------------*/
4753 /* sizeofOp - processes size of operation */
4754 /*-----------------------------------------------------------------*/
4756 sizeofOp (sym_link * type)
4761 /* make sure the type is complete and sane */
4762 checkTypeSanity(type, "(sizeof)");
4764 /* get the size and convert it to character */
4765 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4766 if (!size && !IS_VOID(type))
4767 werror (E_SIZEOF_INCOMPLETE_TYPE);
4769 /* now convert into value */
4770 return constVal (buff);
4774 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4775 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4776 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4777 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4778 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4779 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4780 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4782 /*-----------------------------------------------------------------*/
4783 /* backPatchLabels - change and or not operators to flow control */
4784 /*-----------------------------------------------------------------*/
4786 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4792 /* while-loops insert a label between the IFX and the condition,
4793 therefore look behind the label too */
4794 if (tree->opval.op == LABEL &&
4796 IS_ANDORNOT (tree->right))
4798 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4802 if (!(IS_ANDORNOT (tree)))
4805 /* if this an and */
4808 static int localLbl = 0;
4811 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4812 localLabel = newSymbol (buffer, NestLevel);
4814 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4816 /* if left is already a IFX then just change the if true label in that */
4817 if (!IS_IFX (tree->left))
4818 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4820 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4821 /* right is a IFX then just join */
4822 if (IS_IFX (tree->right))
4823 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4825 tree->right = createLabel (localLabel, tree->right);
4826 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4828 return newNode (NULLOP, tree->left, tree->right);
4831 /* if this is an or operation */
4834 static int localLbl = 0;
4837 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4838 localLabel = newSymbol (buffer, NestLevel);
4840 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4842 /* if left is already a IFX then just change the if true label in that */
4843 if (!IS_IFX (tree->left))
4844 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4846 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4847 /* right is a IFX then just join */
4848 if (IS_IFX (tree->right))
4849 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4851 tree->right = createLabel (localLabel, tree->right);
4852 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4854 return newNode (NULLOP, tree->left, tree->right);
4860 /* call with exchanged labels */
4861 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4863 /* if left isn't already a IFX */
4864 if (!IS_IFX (tree->left))
4866 tree->left = newNode (IFX, tree->left, NULL);
4867 tree->left->trueLabel = falseLabel;
4868 tree->left->falseLabel = trueLabel;
4875 tree->trueLabel = trueLabel;
4876 tree->falseLabel = falseLabel;
4883 /*-----------------------------------------------------------------*/
4884 /* createBlock - create expression tree for block */
4885 /*-----------------------------------------------------------------*/
4887 createBlock (symbol * decl, ast * body)
4891 /* if the block has nothing */
4895 ex = newNode (BLOCK, NULL, body);
4896 ex->values.sym = decl;
4903 /*-----------------------------------------------------------------*/
4904 /* createLabel - creates the expression tree for labels */
4905 /*-----------------------------------------------------------------*/
4907 createLabel (symbol * label, ast * stmnt)
4910 char name[SDCC_NAME_MAX + 1];
4913 /* must create fresh symbol if the symbol name */
4914 /* exists in the symbol table, since there can */
4915 /* be a variable with the same name as the labl */
4916 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4917 (csym->level == label->level))
4918 label = newSymbol (label->name, label->level);
4920 /* change the name before putting it in add _ */
4921 SNPRINTF(name, sizeof(name), "%s", label->name);
4923 /* put the label in the LabelSymbol table */
4924 /* but first check if a label of the same */
4926 if ((csym = findSym (LabelTab, NULL, name)))
4927 werror (E_DUPLICATE_LABEL, label->name);
4929 addSym (LabelTab, label, name, label->level, 0, 0);
4933 label->key = labelKey++;
4934 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4940 /*-----------------------------------------------------------------*/
4941 /* createCase - generates the parsetree for a case statement */
4942 /*-----------------------------------------------------------------*/
4944 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4946 char caseLbl[SDCC_NAME_MAX + 1];
4950 /* if the switch statement does not exist */
4951 /* then case is out of context */
4954 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4958 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4959 /* if not a constant then error */
4960 if (!IS_LITERAL (caseVal->ftype))
4962 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4966 /* if not a integer than error */
4967 if (!IS_INTEGRAL (caseVal->ftype))
4969 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4973 /* find the end of the switch values chain */
4974 if (!(val = swStat->values.switchVals.swVals))
4975 swStat->values.switchVals.swVals = caseVal->opval.val;
4978 /* also order the cases according to value */
4980 int cVal = (int) floatFromVal (caseVal->opval.val);
4981 while (val && (int) floatFromVal (val) < cVal)
4987 /* if we reached the end then */
4990 pval->next = caseVal->opval.val;
4992 else if ((int) floatFromVal (val) == cVal)
4994 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5000 /* we found a value greater than */
5001 /* the current value we must add this */
5002 /* before the value */
5003 caseVal->opval.val->next = val;
5005 /* if this was the first in chain */
5006 if (swStat->values.switchVals.swVals == val)
5007 swStat->values.switchVals.swVals =
5010 pval->next = caseVal->opval.val;
5015 /* create the case label */
5016 SNPRINTF(caseLbl, sizeof(caseLbl),
5018 swStat->values.switchVals.swNum,
5019 (int) floatFromVal (caseVal->opval.val));
5021 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5026 /*-----------------------------------------------------------------*/
5027 /* createDefault - creates the parse tree for the default statement */
5028 /*-----------------------------------------------------------------*/
5030 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5032 char defLbl[SDCC_NAME_MAX + 1];
5034 /* if the switch statement does not exist */
5035 /* then case is out of context */
5038 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5042 if (swStat->values.switchVals.swDefault)
5044 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5049 /* turn on the default flag */
5050 swStat->values.switchVals.swDefault = 1;
5052 /* create the label */
5053 SNPRINTF (defLbl, sizeof(defLbl),
5054 "_default_%d", swStat->values.switchVals.swNum);
5055 return createLabel (newSymbol (defLbl, 0), stmnt);
5058 /*-----------------------------------------------------------------*/
5059 /* createIf - creates the parsetree for the if statement */
5060 /*-----------------------------------------------------------------*/
5062 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5064 static int Lblnum = 0;
5066 symbol *ifTrue, *ifFalse, *ifEnd;
5068 /* if neither exists */
5069 if (!elseBody && !ifBody) {
5070 // if there are no side effects (i++, j() etc)
5071 if (!hasSEFcalls(condAst)) {
5076 /* create the labels */
5077 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5078 ifFalse = newSymbol (buffer, NestLevel);
5079 /* if no else body then end == false */
5084 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5085 ifEnd = newSymbol (buffer, NestLevel);
5088 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5089 ifTrue = newSymbol (buffer, NestLevel);
5093 /* attach the ifTrue label to the top of it body */
5094 ifBody = createLabel (ifTrue, ifBody);
5095 /* attach a goto end to the ifBody if else is present */
5098 ifBody = newNode (NULLOP, ifBody,
5100 newAst_VALUE (symbolVal (ifEnd)),
5102 /* put the elseLabel on the else body */
5103 elseBody = createLabel (ifFalse, elseBody);
5104 /* out the end at the end of the body */
5105 elseBody = newNode (NULLOP,
5107 createLabel (ifEnd, NULL));
5111 ifBody = newNode (NULLOP, ifBody,
5112 createLabel (ifFalse, NULL));
5114 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5115 if (IS_IFX (condAst))
5118 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5120 return newNode (NULLOP, ifTree,
5121 newNode (NULLOP, ifBody, elseBody));
5125 /*-----------------------------------------------------------------*/
5126 /* createDo - creates parse tree for do */
5129 /* _docontinue_n: */
5130 /* condition_expression +-> trueLabel -> _dobody_n */
5132 /* +-> falseLabel-> _dobreak_n */
5134 /*-----------------------------------------------------------------*/
5136 createDo (symbol * trueLabel, symbol * continueLabel,
5137 symbol * falseLabel, ast * condAst, ast * doBody)
5142 /* if the body does not exist then it is simple */
5145 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5146 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5147 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5148 doTree->trueLabel = continueLabel;
5149 doTree->falseLabel = NULL;
5151 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5155 /* otherwise we have a body */
5156 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5158 /* attach the body label to the top */
5159 doBody = createLabel (trueLabel, doBody);
5160 /* attach the continue label to end of body */
5161 doBody = newNode (NULLOP, doBody,
5162 createLabel (continueLabel, NULL));
5164 /* now put the break label at the end */
5165 if (IS_IFX (condAst))
5168 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5170 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5172 /* putting it together */
5173 return newNode (NULLOP, doBody, doTree);
5176 /*-----------------------------------------------------------------*/
5177 /* createFor - creates parse tree for 'for' statement */
5180 /* condExpr +-> trueLabel -> _forbody_n */
5182 /* +-> falseLabel-> _forbreak_n */
5185 /* _forcontinue_n: */
5187 /* goto _forcond_n ; */
5189 /*-----------------------------------------------------------------*/
5191 createFor (symbol * trueLabel, symbol * continueLabel,
5192 symbol * falseLabel, symbol * condLabel,
5193 ast * initExpr, ast * condExpr, ast * loopExpr,
5198 /* if loopexpression not present then we can generate it */
5199 /* the same way as a while */
5201 return newNode (NULLOP, initExpr,
5202 createWhile (trueLabel, continueLabel,
5203 falseLabel, condExpr, forBody));
5204 /* vanilla for statement */
5205 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5207 if (condExpr && !IS_IFX (condExpr))
5208 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5211 /* attach condition label to condition */
5212 condExpr = createLabel (condLabel, condExpr);
5214 /* attach body label to body */
5215 forBody = createLabel (trueLabel, forBody);
5217 /* attach continue to forLoop expression & attach */
5218 /* goto the forcond @ and of loopExpression */
5219 loopExpr = createLabel (continueLabel,
5223 newAst_VALUE (symbolVal (condLabel)),
5225 /* now start putting them together */
5226 forTree = newNode (NULLOP, initExpr, condExpr);
5227 forTree = newNode (NULLOP, forTree, forBody);
5228 forTree = newNode (NULLOP, forTree, loopExpr);
5229 /* finally add the break label */
5230 forTree = newNode (NULLOP, forTree,
5231 createLabel (falseLabel, NULL));
5235 /*-----------------------------------------------------------------*/
5236 /* createWhile - creates parse tree for while statement */
5237 /* the while statement will be created as follows */
5239 /* _while_continue_n: */
5240 /* condition_expression +-> trueLabel -> _while_boby_n */
5242 /* +-> falseLabel -> _while_break_n */
5243 /* _while_body_n: */
5245 /* goto _while_continue_n */
5246 /* _while_break_n: */
5247 /*-----------------------------------------------------------------*/
5249 createWhile (symbol * trueLabel, symbol * continueLabel,
5250 symbol * falseLabel, ast * condExpr, ast * whileBody)
5254 /* put the continue label */
5255 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5256 condExpr = createLabel (continueLabel, condExpr);
5257 condExpr->lineno = 0;
5259 /* put the body label in front of the body */
5260 whileBody = createLabel (trueLabel, whileBody);
5261 whileBody->lineno = 0;
5262 /* put a jump to continue at the end of the body */
5263 /* and put break label at the end of the body */
5264 whileBody = newNode (NULLOP,
5267 newAst_VALUE (symbolVal (continueLabel)),
5268 createLabel (falseLabel, NULL)));
5270 /* put it all together */
5271 if (IS_IFX (condExpr))
5272 whileTree = condExpr;
5275 whileTree = newNode (IFX, condExpr, NULL);
5276 /* put the true & false labels in place */
5277 whileTree->trueLabel = trueLabel;
5278 whileTree->falseLabel = falseLabel;
5281 return newNode (NULLOP, whileTree, whileBody);
5284 /*-----------------------------------------------------------------*/
5285 /* isShiftRightLitVal _BitAndLitVal - helper function */
5286 /*-----------------------------------------------------------------*/
5288 isShiftRightLitVal_BitAndLitVal (ast * tree)
5290 /* if this is not a bit and */
5291 if (!IS_BITAND (tree))
5294 /* will look for tree of the form
5295 ( expr >> litval2) & litval1 */
5296 if (!IS_AST_LIT_VALUE (tree->right))
5299 if (!IS_RIGHT_OP (tree->left))
5302 if (!IS_AST_LIT_VALUE (tree->left->right))
5305 return tree->left->left;
5308 /*-----------------------------------------------------------------*/
5309 /* isBitAndPowOf2 - helper function */
5310 /*-----------------------------------------------------------------*/
5312 isBitAndPow2 (ast * tree)
5314 /* if this is not a bit and */
5315 if (!IS_BITAND (tree))
5318 /* will look for tree of the form
5319 ( expr & (1 << litval) */
5320 if (!IS_AST_LIT_VALUE (tree->right))
5323 return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
5326 /*-----------------------------------------------------------------*/
5327 /* optimizeGetHbit - get highest order bit of the expression */
5328 /*-----------------------------------------------------------------*/
5330 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5335 expr = isShiftRightLitVal_BitAndLitVal(tree);
5338 if ((AST_LIT_VALUE (tree->right) != 1) ||
5339 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5340 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5343 if (!expr && (resultType == RESULT_TYPE_BIT))
5346 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5352 /* make sure the port supports GETHBIT */
5353 if (port->hasExtBitOp
5354 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5357 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5360 /*-----------------------------------------------------------------*/
5361 /* optimizeGetAbit - get a single bit of the expression */
5362 /*-----------------------------------------------------------------*/
5364 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5369 expr = isShiftRightLitVal_BitAndLitVal(tree);
5372 if (AST_LIT_VALUE (tree->right) != 1)
5374 count = tree->left->right;
5376 if (!expr && (resultType == RESULT_TYPE_BIT))
5378 int p2 = isBitAndPow2 (tree);
5382 count = newAst_VALUE (valueFromLit (p2));
5388 /* make sure the port supports GETABIT */
5389 if (port->hasExtBitOp
5390 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5393 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5397 /*-----------------------------------------------------------------*/
5398 /* optimizeGetByte - get a byte of the expression */
5399 /*-----------------------------------------------------------------*/
5401 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5407 expr = isShiftRightLitVal_BitAndLitVal(tree);
5410 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5411 count = tree->left->right;
5412 if (AST_LIT_VALUE (tree->right) != 0xFF)
5415 if (!expr && resultType == RESULT_TYPE_CHAR)
5417 /* if this is a right shift over a multiple of 8 */
5418 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5420 i = (unsigned int) AST_LIT_VALUE (tree->right);
5421 count = tree->right;
5425 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5428 /* make sure the port supports GETBYTE */
5429 if (port->hasExtBitOp
5430 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5433 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5436 /*-----------------------------------------------------------------*/
5437 /* optimizeGetWord - get two bytes of the expression */
5438 /*-----------------------------------------------------------------*/
5440 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5446 expr = isShiftRightLitVal_BitAndLitVal(tree);
5449 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5450 count = tree->left->right;
5451 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5454 if (!expr && resultType == RESULT_TYPE_INT)
5456 /* if this is a right shift over a multiple of 8 */
5457 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5459 i = (unsigned int) AST_LIT_VALUE (tree->right);
5460 count = tree->right;
5464 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5467 /* make sure the port supports GETWORD */
5468 if (port->hasExtBitOp
5469 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5472 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5475 /*-----------------------------------------------------------------*/
5476 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5477 /*-----------------------------------------------------------------*/
5479 optimizeRRCRLC (ast * root)
5481 /* will look for trees of the form
5482 (?expr << 1) | (?expr >> 7) or
5483 (?expr >> 7) | (?expr << 1) will make that
5484 into a RLC : operation ..
5486 (?expr >> 1) | (?expr << 7) or
5487 (?expr << 7) | (?expr >> 1) will make that
5488 into a RRC operation
5489 note : by 7 I mean (number of bits required to hold the
5491 /* if the root operation is not a | operation then not */
5492 if (!IS_BITOR (root))
5495 /* I have to think of a better way to match patterns this sucks */
5496 /* that aside let's start looking for the first case : I use a
5497 negative check a lot to improve the efficiency */
5498 /* (?expr << 1) | (?expr >> 7) */
5499 if (IS_LEFT_OP (root->left) &&
5500 IS_RIGHT_OP (root->right))
5503 if (!SPEC_USIGN (TETYPE (root->left->left)))
5506 if (!IS_AST_LIT_VALUE (root->left->right) ||
5507 !IS_AST_LIT_VALUE (root->right->right))
5510 /* make sure it is the same expression */
5511 if (!isAstEqual (root->left->left,
5515 if (AST_LIT_VALUE (root->left->right) != 1)
5518 if (AST_LIT_VALUE (root->right->right) !=
5519 (getSize (TTYPE (root->left->left)) * 8 - 1))
5522 /* make sure the port supports RLC */
5523 if (port->hasExtBitOp
5524 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5527 /* whew got the first case : create the AST */
5528 return newNode (RLC, root->left->left, NULL);
5532 /* check for second case */
5533 /* (?expr >> 7) | (?expr << 1) */
5534 if (IS_LEFT_OP (root->right) &&
5535 IS_RIGHT_OP (root->left))
5538 if (!SPEC_USIGN (TETYPE (root->left->left)))
5541 if (!IS_AST_LIT_VALUE (root->left->right) ||
5542 !IS_AST_LIT_VALUE (root->right->right))
5545 /* make sure it is the same symbol */
5546 if (!isAstEqual (root->left->left,
5550 if (AST_LIT_VALUE (root->right->right) != 1)
5553 if (AST_LIT_VALUE (root->left->right) !=
5554 (getSize (TTYPE (root->left->left)) * 8 - 1))
5557 /* make sure the port supports RLC */
5558 if (port->hasExtBitOp
5559 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5562 /* whew got the first case : create the AST */
5563 return newNode (RLC, root->left->left, NULL);
5568 /* third case for RRC */
5569 /* (?symbol >> 1) | (?symbol << 7) */
5570 if (IS_LEFT_OP (root->right) &&
5571 IS_RIGHT_OP (root->left))
5574 if (!SPEC_USIGN (TETYPE (root->left->left)))
5577 if (!IS_AST_LIT_VALUE (root->left->right) ||
5578 !IS_AST_LIT_VALUE (root->right->right))
5581 /* make sure it is the same symbol */
5582 if (!isAstEqual (root->left->left,
5586 if (AST_LIT_VALUE (root->left->right) != 1)
5589 if (AST_LIT_VALUE (root->right->right) !=
5590 (getSize (TTYPE (root->left->left)) * 8 - 1))
5593 /* make sure the port supports RRC */
5594 if (port->hasExtBitOp
5595 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5598 /* whew got the first case : create the AST */
5599 return newNode (RRC, root->left->left, NULL);
5603 /* fourth and last case for now */
5604 /* (?symbol << 7) | (?symbol >> 1) */
5605 if (IS_RIGHT_OP (root->right) &&
5606 IS_LEFT_OP (root->left))
5609 if (!SPEC_USIGN (TETYPE (root->left->left)))
5612 if (!IS_AST_LIT_VALUE (root->left->right) ||
5613 !IS_AST_LIT_VALUE (root->right->right))
5616 /* make sure it is the same symbol */
5617 if (!isAstEqual (root->left->left,
5621 if (AST_LIT_VALUE (root->right->right) != 1)
5624 if (AST_LIT_VALUE (root->left->right) !=
5625 (getSize (TTYPE (root->left->left)) * 8 - 1))
5628 /* make sure the port supports RRC */
5629 if (port->hasExtBitOp
5630 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5633 /* whew got the first case : create the AST */
5634 return newNode (RRC, root->left->left, NULL);
5638 /* not found return root */
5642 /*-----------------------------------------------------------------*/
5643 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5644 /*-----------------------------------------------------------------*/
5646 optimizeSWAP (ast * root)
5648 /* will look for trees of the form
5649 (?expr << 4) | (?expr >> 4) or
5650 (?expr >> 4) | (?expr << 4) will make that
5651 into a SWAP : operation ..
5652 note : by 4 I mean (number of bits required to hold the
5654 /* if the root operation is not a | operation then not */
5655 if (!IS_BITOR (root))
5658 /* (?expr << 4) | (?expr >> 4) */
5659 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5660 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5663 if (!SPEC_USIGN (TETYPE (root->left->left)))
5666 if (!IS_AST_LIT_VALUE (root->left->right) ||
5667 !IS_AST_LIT_VALUE (root->right->right))
5670 /* make sure it is the same expression */
5671 if (!isAstEqual (root->left->left,
5675 if (AST_LIT_VALUE (root->left->right) !=
5676 (getSize (TTYPE (root->left->left)) * 4))
5679 if (AST_LIT_VALUE (root->right->right) !=
5680 (getSize (TTYPE (root->left->left)) * 4))
5683 /* make sure the port supports SWAP */
5684 if (port->hasExtBitOp
5685 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5688 /* found it : create the AST */
5689 return newNode (SWAP, root->left->left, NULL);
5693 /* not found return root */
5697 /*-----------------------------------------------------------------*/
5698 /* optimizeCompare - optimizes compares for bit variables */
5699 /*-----------------------------------------------------------------*/
5701 optimizeCompare (ast * root)
5703 ast *optExpr = NULL;
5706 unsigned int litValue;
5708 /* if nothing then return nothing */
5712 /* if not a compare op then do leaves */
5713 if (!IS_COMPARE_OP (root))
5715 root->left = optimizeCompare (root->left);
5716 root->right = optimizeCompare (root->right);
5720 /* if left & right are the same then depending
5721 of the operation do */
5722 if (isAstEqual (root->left, root->right))
5724 switch (root->opval.op)
5729 optExpr = newAst_VALUE (constVal ("0"));
5734 optExpr = newAst_VALUE (constVal ("1"));
5738 return decorateType (optExpr, RESULT_TYPE_NONE);
5741 vleft = (root->left->type == EX_VALUE ?
5742 root->left->opval.val : NULL);
5744 vright = (root->right->type == EX_VALUE ?
5745 root->right->opval.val : NULL);
5747 /* if left is a BITVAR in BITSPACE */
5748 /* and right is a LITERAL then opt- */
5749 /* imize else do nothing */
5750 if (vleft && vright &&
5751 IS_BITVAR (vleft->etype) &&
5752 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5753 IS_LITERAL (vright->etype))
5756 /* if right side > 1 then comparison may never succeed */
5757 if ((litValue = (int) floatFromVal (vright)) > 1)
5759 werror (W_BAD_COMPARE);
5765 switch (root->opval.op)
5767 case '>': /* bit value greater than 1 cannot be */
5768 werror (W_BAD_COMPARE);
5772 case '<': /* bit value < 1 means 0 */
5774 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5777 case LE_OP: /* bit value <= 1 means no check */
5778 optExpr = newAst_VALUE (vright);
5781 case GE_OP: /* bit value >= 1 means only check for = */
5783 optExpr = newAst_VALUE (vleft);
5788 { /* literal is zero */
5789 switch (root->opval.op)
5791 case '<': /* bit value < 0 cannot be */
5792 werror (W_BAD_COMPARE);
5796 case '>': /* bit value > 0 means 1 */
5798 optExpr = newAst_VALUE (vleft);
5801 case LE_OP: /* bit value <= 0 means no check */
5802 case GE_OP: /* bit value >= 0 means no check */
5803 werror (W_BAD_COMPARE);
5807 case EQ_OP: /* bit == 0 means ! of bit */
5808 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5812 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5813 } /* end-of-if of BITVAR */
5818 /*-----------------------------------------------------------------*/
5819 /* addSymToBlock : adds the symbol to the first block we find */
5820 /*-----------------------------------------------------------------*/
5822 addSymToBlock (symbol * sym, ast * tree)
5824 /* reached end of tree or a leaf */
5825 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5829 if (IS_AST_OP (tree) &&
5830 tree->opval.op == BLOCK)
5833 symbol *lsym = copySymbol (sym);
5835 lsym->next = AST_VALUES (tree, sym);
5836 AST_VALUES (tree, sym) = lsym;
5840 addSymToBlock (sym, tree->left);
5841 addSymToBlock (sym, tree->right);
5844 /*-----------------------------------------------------------------*/
5845 /* processRegParms - do processing for register parameters */
5846 /*-----------------------------------------------------------------*/
5848 processRegParms (value * args, ast * body)
5852 if (IS_REGPARM (args->etype))
5853 addSymToBlock (args->sym, body);
5858 /*-----------------------------------------------------------------*/
5859 /* resetParmKey - resets the operandkeys for the symbols */
5860 /*-----------------------------------------------------------------*/
5861 DEFSETFUNC (resetParmKey)
5872 /*-----------------------------------------------------------------*/
5873 /* createFunction - This is the key node that calls the iCode for */
5874 /* generating the code for a function. Note code */
5875 /* is generated function by function, later when */
5876 /* add inter-procedural analysis this will change */
5877 /*-----------------------------------------------------------------*/
5879 createFunction (symbol * name, ast * body)
5885 iCode *piCode = NULL;
5887 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5888 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5890 /* if check function return 0 then some problem */
5891 if (checkFunction (name, NULL) == 0)
5894 /* create a dummy block if none exists */
5896 body = newNode (BLOCK, NULL, NULL);
5900 /* check if the function name already in the symbol table */
5901 if ((csym = findSym (SymbolTab, NULL, name->name)))
5904 /* special case for compiler defined functions
5905 we need to add the name to the publics list : this
5906 actually means we are now compiling the compiler
5910 addSet (&publics, name);
5915 addSymChain (&name);
5916 allocVariables (name);
5918 name->lastLine = lexLineno;
5921 /* set the stack pointer */
5922 stackPtr = -port->stack.direction * port->stack.call_overhead;
5925 if (IFFUNC_ISISR (name->type))
5926 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5928 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5930 if (options.useXstack)
5931 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5933 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5936 fetype = getSpec (name->type); /* get the specifier for the function */
5937 /* if this is a reentrant function then */
5938 if (IFFUNC_ISREENT (name->type))
5941 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5943 /* do processing for parameters that are passed in registers */
5944 processRegParms (FUNC_ARGS(name->type), body);
5946 /* set the stack pointer */
5950 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
5952 /* allocate & autoinit the block variables */
5953 processBlockVars (body, &stack, ALLOCATE);
5955 /* name needs to be mangled */
5956 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5958 body = resolveSymbols (body); /* resolve the symbols */
5959 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5961 /* save the stack information */
5962 if (options.useXstack)
5963 name->xstack = SPEC_STAK (fetype) = stack;
5965 name->stack = SPEC_STAK (fetype) = stack;
5967 ex = newAst_VALUE (symbolVal (name)); /* create name */
5968 ex = newNode (FUNCTION, ex, body);
5969 ex->values.args = FUNC_ARGS(name->type);
5971 if (options.dump_tree) PA(ex);
5974 werror (E_FUNC_NO_CODE, name->name);
5978 /* create the node & generate intermediate code */
5980 codeOutBuf = &code->oBuf;
5981 piCode = iCodeFromAst (ex);
5985 werror (E_FUNC_NO_CODE, name->name);
5989 eBBlockFromiCode (piCode);
5991 /* if there are any statics then do them */
5994 GcurMemmap = statsg;
5995 codeOutBuf = &statsg->oBuf;
5996 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6002 /* dealloc the block variables */
6003 processBlockVars (body, &stack, DEALLOCATE);
6004 outputDebugStackSymbols();
6005 /* deallocate paramaters */
6006 deallocParms (FUNC_ARGS(name->type));
6008 if (IFFUNC_ISREENT (name->type))
6011 /* we are done freeup memory & cleanup */
6013 if (port->reset_labelKey) labelKey = 1;
6015 FUNC_HASBODY(name->type) = 1;
6016 addSet (&operKeyReset, name);
6017 applyToSet (operKeyReset, resetParmKey);
6022 cleanUpLevel (LabelTab, 0);
6023 cleanUpBlock (StructTab, 1);
6024 cleanUpBlock (TypedefTab, 1);
6026 xstack->syms = NULL;
6027 istack->syms = NULL;
6032 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6033 /*-----------------------------------------------------------------*/
6034 /* ast_print : prints the ast (for debugging purposes) */
6035 /*-----------------------------------------------------------------*/
6037 void ast_print (ast * tree, FILE *outfile, int indent)
6042 /* can print only decorated trees */
6043 if (!tree->decorated) return;
6045 /* if any child is an error | this one is an error do nothing */
6046 if (tree->isError ||
6047 (tree->left && tree->left->isError) ||
6048 (tree->right && tree->right->isError)) {
6049 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6053 /* print the line */
6054 /* if not block & function */
6055 if (tree->type == EX_OP &&
6056 (tree->opval.op != FUNCTION &&
6057 tree->opval.op != BLOCK &&
6058 tree->opval.op != NULLOP)) {
6061 if (tree->opval.op == FUNCTION) {
6063 value *args=FUNC_ARGS(tree->left->opval.val->type);
6064 fprintf(outfile,"FUNCTION (%s=%p) type (",
6065 tree->left->opval.val->name, tree);
6066 printTypeChain (tree->left->opval.val->type->next,outfile);
6067 fprintf(outfile,") args (");
6070 fprintf (outfile, ", ");
6072 printTypeChain (args ? args->type : NULL, outfile);
6074 args= args ? args->next : NULL;
6076 fprintf(outfile,")\n");
6077 ast_print(tree->left,outfile,indent);
6078 ast_print(tree->right,outfile,indent);
6081 if (tree->opval.op == BLOCK) {
6082 symbol *decls = tree->values.sym;
6083 INDENT(indent,outfile);
6084 fprintf(outfile,"{\n");
6086 INDENT(indent+2,outfile);
6087 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6088 decls->name, decls);
6089 printTypeChain(decls->type,outfile);
6090 fprintf(outfile,")\n");
6092 decls = decls->next;
6094 ast_print(tree->right,outfile,indent+2);
6095 INDENT(indent,outfile);
6096 fprintf(outfile,"}\n");
6099 if (tree->opval.op == NULLOP) {
6100 ast_print(tree->left,outfile,indent);
6101 ast_print(tree->right,outfile,indent);
6104 INDENT(indent,outfile);
6106 /*------------------------------------------------------------------*/
6107 /*----------------------------*/
6108 /* leaf has been reached */
6109 /*----------------------------*/
6110 /* if this is of type value */
6111 /* just get the type */
6112 if (tree->type == EX_VALUE) {
6114 if (IS_LITERAL (tree->opval.val->etype)) {
6115 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6116 if (SPEC_USIGN (tree->opval.val->etype))
6117 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
6119 fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
6120 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
6121 floatFromVal(tree->opval.val));
6122 } else if (tree->opval.val->sym) {
6123 /* if the undefined flag is set then give error message */
6124 if (tree->opval.val->sym->undefined) {
6125 fprintf(outfile,"UNDEFINED SYMBOL ");
6127 fprintf(outfile,"SYMBOL ");
6129 fprintf(outfile,"(%s=%p @ %p)",
6130 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6133 fprintf(outfile," type (");
6134 printTypeChain(tree->ftype,outfile);
6135 fprintf(outfile,")\n");
6137 fprintf(outfile,"\n");
6142 /* if type link for the case of cast */
6143 if (tree->type == EX_LINK) {
6144 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6145 printTypeChain(tree->opval.lnk,outfile);
6146 fprintf(outfile,")\n");
6151 /* depending on type of operator do */
6153 switch (tree->opval.op) {
6154 /*------------------------------------------------------------------*/
6155 /*----------------------------*/
6157 /*----------------------------*/
6159 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6160 printTypeChain(tree->ftype,outfile);
6161 fprintf(outfile,")\n");
6162 ast_print(tree->left,outfile,indent+2);
6163 ast_print(tree->right,outfile,indent+2);
6166 /*------------------------------------------------------------------*/
6167 /*----------------------------*/
6169 /*----------------------------*/
6171 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6172 printTypeChain(tree->ftype,outfile);
6173 fprintf(outfile,")\n");
6174 ast_print(tree->left,outfile,indent+2);
6175 ast_print(tree->right,outfile,indent+2);
6178 /*------------------------------------------------------------------*/
6179 /*----------------------------*/
6180 /* struct/union pointer */
6181 /*----------------------------*/
6183 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6184 printTypeChain(tree->ftype,outfile);
6185 fprintf(outfile,")\n");
6186 ast_print(tree->left,outfile,indent+2);
6187 ast_print(tree->right,outfile,indent+2);
6190 /*------------------------------------------------------------------*/
6191 /*----------------------------*/
6192 /* ++/-- operation */
6193 /*----------------------------*/
6196 fprintf(outfile,"post-");
6198 fprintf(outfile,"pre-");
6199 fprintf(outfile,"INC_OP (%p) type (",tree);
6200 printTypeChain(tree->ftype,outfile);
6201 fprintf(outfile,")\n");
6202 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6203 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6208 fprintf(outfile,"post-");
6210 fprintf(outfile,"pre-");
6211 fprintf(outfile,"DEC_OP (%p) type (",tree);
6212 printTypeChain(tree->ftype,outfile);
6213 fprintf(outfile,")\n");
6214 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6215 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6218 /*------------------------------------------------------------------*/
6219 /*----------------------------*/
6221 /*----------------------------*/
6224 fprintf(outfile,"& (%p) type (",tree);
6225 printTypeChain(tree->ftype,outfile);
6226 fprintf(outfile,")\n");
6227 ast_print(tree->left,outfile,indent+2);
6228 ast_print(tree->right,outfile,indent+2);
6230 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6231 printTypeChain(tree->ftype,outfile);
6232 fprintf(outfile,")\n");
6233 ast_print(tree->left,outfile,indent+2);
6234 ast_print(tree->right,outfile,indent+2);
6237 /*----------------------------*/
6239 /*----------------------------*/
6241 fprintf(outfile,"OR (%p) type (",tree);
6242 printTypeChain(tree->ftype,outfile);
6243 fprintf(outfile,")\n");
6244 ast_print(tree->left,outfile,indent+2);
6245 ast_print(tree->right,outfile,indent+2);
6247 /*------------------------------------------------------------------*/
6248 /*----------------------------*/
6250 /*----------------------------*/
6252 fprintf(outfile,"XOR (%p) type (",tree);
6253 printTypeChain(tree->ftype,outfile);
6254 fprintf(outfile,")\n");
6255 ast_print(tree->left,outfile,indent+2);
6256 ast_print(tree->right,outfile,indent+2);
6259 /*------------------------------------------------------------------*/
6260 /*----------------------------*/
6262 /*----------------------------*/
6264 fprintf(outfile,"DIV (%p) type (",tree);
6265 printTypeChain(tree->ftype,outfile);
6266 fprintf(outfile,")\n");
6267 ast_print(tree->left,outfile,indent+2);
6268 ast_print(tree->right,outfile,indent+2);
6270 /*------------------------------------------------------------------*/
6271 /*----------------------------*/
6273 /*----------------------------*/
6275 fprintf(outfile,"MOD (%p) type (",tree);
6276 printTypeChain(tree->ftype,outfile);
6277 fprintf(outfile,")\n");
6278 ast_print(tree->left,outfile,indent+2);
6279 ast_print(tree->right,outfile,indent+2);
6282 /*------------------------------------------------------------------*/
6283 /*----------------------------*/
6284 /* address dereference */
6285 /*----------------------------*/
6286 case '*': /* can be unary : if right is null then unary operation */
6288 fprintf(outfile,"DEREF (%p) type (",tree);
6289 printTypeChain(tree->ftype,outfile);
6290 fprintf(outfile,")\n");
6291 ast_print(tree->left,outfile,indent+2);
6294 /*------------------------------------------------------------------*/
6295 /*----------------------------*/
6296 /* multiplication */
6297 /*----------------------------*/
6298 fprintf(outfile,"MULT (%p) type (",tree);
6299 printTypeChain(tree->ftype,outfile);
6300 fprintf(outfile,")\n");
6301 ast_print(tree->left,outfile,indent+2);
6302 ast_print(tree->right,outfile,indent+2);
6306 /*------------------------------------------------------------------*/
6307 /*----------------------------*/
6308 /* unary '+' operator */
6309 /*----------------------------*/
6313 fprintf(outfile,"UPLUS (%p) type (",tree);
6314 printTypeChain(tree->ftype,outfile);
6315 fprintf(outfile,")\n");
6316 ast_print(tree->left,outfile,indent+2);
6318 /*------------------------------------------------------------------*/
6319 /*----------------------------*/
6321 /*----------------------------*/
6322 fprintf(outfile,"ADD (%p) type (",tree);
6323 printTypeChain(tree->ftype,outfile);
6324 fprintf(outfile,")\n");
6325 ast_print(tree->left,outfile,indent+2);
6326 ast_print(tree->right,outfile,indent+2);
6329 /*------------------------------------------------------------------*/
6330 /*----------------------------*/
6332 /*----------------------------*/
6333 case '-': /* can be unary */
6335 fprintf(outfile,"UMINUS (%p) type (",tree);
6336 printTypeChain(tree->ftype,outfile);
6337 fprintf(outfile,")\n");
6338 ast_print(tree->left,outfile,indent+2);
6340 /*------------------------------------------------------------------*/
6341 /*----------------------------*/
6343 /*----------------------------*/
6344 fprintf(outfile,"SUB (%p) type (",tree);
6345 printTypeChain(tree->ftype,outfile);
6346 fprintf(outfile,")\n");
6347 ast_print(tree->left,outfile,indent+2);
6348 ast_print(tree->right,outfile,indent+2);
6351 /*------------------------------------------------------------------*/
6352 /*----------------------------*/
6354 /*----------------------------*/
6356 fprintf(outfile,"COMPL (%p) type (",tree);
6357 printTypeChain(tree->ftype,outfile);
6358 fprintf(outfile,")\n");
6359 ast_print(tree->left,outfile,indent+2);
6361 /*------------------------------------------------------------------*/
6362 /*----------------------------*/
6364 /*----------------------------*/
6366 fprintf(outfile,"NOT (%p) type (",tree);
6367 printTypeChain(tree->ftype,outfile);
6368 fprintf(outfile,")\n");
6369 ast_print(tree->left,outfile,indent+2);
6371 /*------------------------------------------------------------------*/
6372 /*----------------------------*/
6374 /*----------------------------*/
6376 fprintf(outfile,"RRC (%p) type (",tree);
6377 printTypeChain(tree->ftype,outfile);
6378 fprintf(outfile,")\n");
6379 ast_print(tree->left,outfile,indent+2);
6383 fprintf(outfile,"RLC (%p) type (",tree);
6384 printTypeChain(tree->ftype,outfile);
6385 fprintf(outfile,")\n");
6386 ast_print(tree->left,outfile,indent+2);
6389 fprintf(outfile,"SWAP (%p) type (",tree);
6390 printTypeChain(tree->ftype,outfile);
6391 fprintf(outfile,")\n");
6392 ast_print(tree->left,outfile,indent+2);
6395 fprintf(outfile,"GETHBIT (%p) type (",tree);
6396 printTypeChain(tree->ftype,outfile);
6397 fprintf(outfile,")\n");
6398 ast_print(tree->left,outfile,indent+2);
6401 fprintf(outfile,"GETABIT (%p) type (",tree);
6402 printTypeChain(tree->ftype,outfile);
6403 fprintf(outfile,")\n");
6404 ast_print(tree->left,outfile,indent+2);
6405 ast_print(tree->right,outfile,indent+2);
6408 fprintf(outfile,"GETBYTE (%p) type (",tree);
6409 printTypeChain(tree->ftype,outfile);
6410 fprintf(outfile,")\n");
6411 ast_print(tree->left,outfile,indent+2);
6412 ast_print(tree->right,outfile,indent+2);
6415 fprintf(outfile,"GETWORD (%p) type (",tree);
6416 printTypeChain(tree->ftype,outfile);
6417 fprintf(outfile,")\n");
6418 ast_print(tree->left,outfile,indent+2);
6419 ast_print(tree->right,outfile,indent+2);
6422 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6423 printTypeChain(tree->ftype,outfile);
6424 fprintf(outfile,")\n");
6425 ast_print(tree->left,outfile,indent+2);
6426 ast_print(tree->right,outfile,indent+2);
6429 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6430 printTypeChain(tree->ftype,outfile);
6431 fprintf(outfile,")\n");
6432 ast_print(tree->left,outfile,indent+2);
6433 ast_print(tree->right,outfile,indent+2);
6435 /*------------------------------------------------------------------*/
6436 /*----------------------------*/
6438 /*----------------------------*/
6439 case CAST: /* change the type */
6440 fprintf(outfile,"CAST (%p) from type (",tree);
6441 printTypeChain(tree->right->ftype,outfile);
6442 fprintf(outfile,") to type (");
6443 printTypeChain(tree->ftype,outfile);
6444 fprintf(outfile,")\n");
6445 ast_print(tree->right,outfile,indent+2);
6449 fprintf(outfile,"ANDAND (%p) type (",tree);
6450 printTypeChain(tree->ftype,outfile);
6451 fprintf(outfile,")\n");
6452 ast_print(tree->left,outfile,indent+2);
6453 ast_print(tree->right,outfile,indent+2);
6456 fprintf(outfile,"OROR (%p) type (",tree);
6457 printTypeChain(tree->ftype,outfile);
6458 fprintf(outfile,")\n");
6459 ast_print(tree->left,outfile,indent+2);
6460 ast_print(tree->right,outfile,indent+2);
6463 /*------------------------------------------------------------------*/
6464 /*----------------------------*/
6465 /* comparison operators */
6466 /*----------------------------*/
6468 fprintf(outfile,"GT(>) (%p) type (",tree);
6469 printTypeChain(tree->ftype,outfile);
6470 fprintf(outfile,")\n");
6471 ast_print(tree->left,outfile,indent+2);
6472 ast_print(tree->right,outfile,indent+2);
6475 fprintf(outfile,"LT(<) (%p) type (",tree);
6476 printTypeChain(tree->ftype,outfile);
6477 fprintf(outfile,")\n");
6478 ast_print(tree->left,outfile,indent+2);
6479 ast_print(tree->right,outfile,indent+2);
6482 fprintf(outfile,"LE(<=) (%p) type (",tree);
6483 printTypeChain(tree->ftype,outfile);
6484 fprintf(outfile,")\n");
6485 ast_print(tree->left,outfile,indent+2);
6486 ast_print(tree->right,outfile,indent+2);
6489 fprintf(outfile,"GE(>=) (%p) type (",tree);
6490 printTypeChain(tree->ftype,outfile);
6491 fprintf(outfile,")\n");
6492 ast_print(tree->left,outfile,indent+2);
6493 ast_print(tree->right,outfile,indent+2);
6496 fprintf(outfile,"EQ(==) (%p) type (",tree);
6497 printTypeChain(tree->ftype,outfile);
6498 fprintf(outfile,")\n");
6499 ast_print(tree->left,outfile,indent+2);
6500 ast_print(tree->right,outfile,indent+2);
6503 fprintf(outfile,"NE(!=) (%p) type (",tree);
6504 printTypeChain(tree->ftype,outfile);
6505 fprintf(outfile,")\n");
6506 ast_print(tree->left,outfile,indent+2);
6507 ast_print(tree->right,outfile,indent+2);
6508 /*------------------------------------------------------------------*/
6509 /*----------------------------*/
6511 /*----------------------------*/
6512 case SIZEOF: /* evaluate wihout code generation */
6513 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6516 /*------------------------------------------------------------------*/
6517 /*----------------------------*/
6518 /* conditional operator '?' */
6519 /*----------------------------*/
6521 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6522 printTypeChain(tree->ftype,outfile);
6523 fprintf(outfile,")\n");
6524 ast_print(tree->left,outfile,indent+2);
6525 ast_print(tree->right,outfile,indent+2);
6529 fprintf(outfile,"COLON(:) (%p) type (",tree);
6530 printTypeChain(tree->ftype,outfile);
6531 fprintf(outfile,")\n");
6532 ast_print(tree->left,outfile,indent+2);
6533 ast_print(tree->right,outfile,indent+2);
6536 /*------------------------------------------------------------------*/
6537 /*----------------------------*/
6538 /* assignment operators */
6539 /*----------------------------*/
6541 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6542 printTypeChain(tree->ftype,outfile);
6543 fprintf(outfile,")\n");
6544 ast_print(tree->left,outfile,indent+2);
6545 ast_print(tree->right,outfile,indent+2);
6548 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6549 printTypeChain(tree->ftype,outfile);
6550 fprintf(outfile,")\n");
6551 ast_print(tree->left,outfile,indent+2);
6552 ast_print(tree->right,outfile,indent+2);
6555 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6556 printTypeChain(tree->ftype,outfile);
6557 fprintf(outfile,")\n");
6558 ast_print(tree->left,outfile,indent+2);
6559 ast_print(tree->right,outfile,indent+2);
6562 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6563 printTypeChain(tree->ftype,outfile);
6564 fprintf(outfile,")\n");
6565 ast_print(tree->left,outfile,indent+2);
6566 ast_print(tree->right,outfile,indent+2);
6569 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6570 printTypeChain(tree->ftype,outfile);
6571 fprintf(outfile,")\n");
6572 ast_print(tree->left,outfile,indent+2);
6573 ast_print(tree->right,outfile,indent+2);
6576 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6577 printTypeChain(tree->ftype,outfile);
6578 fprintf(outfile,")\n");
6579 ast_print(tree->left,outfile,indent+2);
6580 ast_print(tree->right,outfile,indent+2);
6583 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6584 printTypeChain(tree->ftype,outfile);
6585 fprintf(outfile,")\n");
6586 ast_print(tree->left,outfile,indent+2);
6587 ast_print(tree->right,outfile,indent+2);
6589 /*------------------------------------------------------------------*/
6590 /*----------------------------*/
6592 /*----------------------------*/
6594 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6595 printTypeChain(tree->ftype,outfile);
6596 fprintf(outfile,")\n");
6597 ast_print(tree->left,outfile,indent+2);
6598 ast_print(tree->right,outfile,indent+2);
6600 /*------------------------------------------------------------------*/
6601 /*----------------------------*/
6603 /*----------------------------*/
6605 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6606 printTypeChain(tree->ftype,outfile);
6607 fprintf(outfile,")\n");
6608 ast_print(tree->left,outfile,indent+2);
6609 ast_print(tree->right,outfile,indent+2);
6611 /*------------------------------------------------------------------*/
6612 /*----------------------------*/
6613 /* straight assignemnt */
6614 /*----------------------------*/
6616 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6617 printTypeChain(tree->ftype,outfile);
6618 fprintf(outfile,")\n");
6619 ast_print(tree->left,outfile,indent+2);
6620 ast_print(tree->right,outfile,indent+2);
6622 /*------------------------------------------------------------------*/
6623 /*----------------------------*/
6624 /* comma operator */
6625 /*----------------------------*/
6627 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6628 printTypeChain(tree->ftype,outfile);
6629 fprintf(outfile,")\n");
6630 ast_print(tree->left,outfile,indent+2);
6631 ast_print(tree->right,outfile,indent+2);
6633 /*------------------------------------------------------------------*/
6634 /*----------------------------*/
6636 /*----------------------------*/
6639 fprintf(outfile,"CALL (%p) type (",tree);
6640 printTypeChain(tree->ftype,outfile);
6641 fprintf(outfile,")\n");
6642 ast_print(tree->left,outfile,indent+2);
6643 ast_print(tree->right,outfile,indent+2);
6646 fprintf(outfile,"PARMS\n");
6647 ast_print(tree->left,outfile,indent+2);
6648 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6649 ast_print(tree->right,outfile,indent+2);
6652 /*------------------------------------------------------------------*/
6653 /*----------------------------*/
6654 /* return statement */
6655 /*----------------------------*/
6657 fprintf(outfile,"RETURN (%p) type (",tree);
6659 printTypeChain(tree->right->ftype,outfile);
6661 fprintf(outfile,")\n");
6662 ast_print(tree->right,outfile,indent+2);
6664 /*------------------------------------------------------------------*/
6665 /*----------------------------*/
6666 /* label statement */
6667 /*----------------------------*/
6669 fprintf(outfile,"LABEL (%p)\n",tree);
6670 ast_print(tree->left,outfile,indent+2);
6671 ast_print(tree->right,outfile,indent);
6673 /*------------------------------------------------------------------*/
6674 /*----------------------------*/
6675 /* switch statement */
6676 /*----------------------------*/
6680 fprintf(outfile,"SWITCH (%p) ",tree);
6681 ast_print(tree->left,outfile,0);
6682 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6683 INDENT(indent+2,outfile);
6684 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6685 (int) floatFromVal(val),
6686 tree->values.switchVals.swNum,
6687 (int) floatFromVal(val));
6689 ast_print(tree->right,outfile,indent);
6692 /*------------------------------------------------------------------*/
6693 /*----------------------------*/
6695 /*----------------------------*/
6697 fprintf(outfile,"IF (%p) \n",tree);
6698 ast_print(tree->left,outfile,indent+2);
6699 if (tree->trueLabel) {
6700 INDENT(indent+2,outfile);
6701 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6703 if (tree->falseLabel) {
6704 INDENT(indent+2,outfile);
6705 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6707 ast_print(tree->right,outfile,indent+2);
6709 /*----------------------------*/
6710 /* goto Statement */
6711 /*----------------------------*/
6713 fprintf(outfile,"GOTO (%p) \n",tree);
6714 ast_print(tree->left,outfile,indent+2);
6715 fprintf(outfile,"\n");
6717 /*------------------------------------------------------------------*/
6718 /*----------------------------*/
6720 /*----------------------------*/
6722 fprintf(outfile,"FOR (%p) \n",tree);
6723 if (AST_FOR( tree, initExpr)) {
6724 INDENT(indent+2,outfile);
6725 fprintf(outfile,"INIT EXPR ");
6726 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6728 if (AST_FOR( tree, condExpr)) {
6729 INDENT(indent+2,outfile);
6730 fprintf(outfile,"COND EXPR ");
6731 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6733 if (AST_FOR( tree, loopExpr)) {
6734 INDENT(indent+2,outfile);
6735 fprintf(outfile,"LOOP EXPR ");
6736 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6738 fprintf(outfile,"FOR LOOP BODY \n");
6739 ast_print(tree->left,outfile,indent+2);
6742 fprintf(outfile,"CRITICAL (%p) \n",tree);
6743 ast_print(tree->left,outfile,indent+2);
6751 ast_print(t,stdout,0);
6754 /*-----------------------------------------------------------------*/
6755 /* astErrors : returns non-zero if errors present in tree */
6756 /*-----------------------------------------------------------------*/
6757 int astErrors(ast *t)
6766 if (t->type == EX_VALUE
6767 && t->opval.val->sym
6768 && t->opval.val->sym->undefined)
6771 errors += astErrors(t->left);
6772 errors += astErrors(t->right);