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 : lineno);
88 ex->filename = filename;
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 char *name=sym->opval.val->sym->name;
1041 int lineno=sym->opval.val->sym->lineDef;
1042 char *filename=sym->opval.val->sym->fileDef;
1044 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
1053 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
1054 aSym = decorateType (resolveSymbols (aSym), RESULT_TYPE_NONE);
1055 rast = createIval (aSym, type->next, iloop, rast, rootValue);
1056 iloop = (iloop ? iloop->next : NULL);
1062 /* no of elements given and we */
1063 /* have generated for all of them */
1066 // is this a better way? at least it won't crash
1067 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1068 int lineno = iloop->lineno;
1069 char *filename = iloop->filename;
1070 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
1077 /* if we have not been given a size */
1078 if (!DCL_ELEM (type))
1080 /* check, if it's a flexible array */
1081 if (IS_STRUCT (AST_VALUE (rootValue)->type))
1082 AST_SYMBOL(rootValue)->flexArrayLength = size * getSize (type->next);
1084 DCL_ELEM (type) = size;
1087 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1091 /*-----------------------------------------------------------------*/
1092 /* createIvalCharPtr - generates initial values for char pointers */
1093 /*-----------------------------------------------------------------*/
1095 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr, ast *rootVal)
1100 /* if this is a pointer & right is a literal array then */
1101 /* just assignment will do */
1102 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
1103 SPEC_SCLS (iexpr->etype) == S_CODE)
1104 && IS_ARRAY (iexpr->ftype)))
1105 return newNode ('=', sym, iexpr);
1107 /* left side is an array so we have to assign each */
1109 if ((IS_LITERAL (iexpr->etype) ||
1110 SPEC_SCLS (iexpr->etype) == S_CODE)
1111 && IS_ARRAY (iexpr->ftype))
1113 /* for each character generate an assignment */
1114 /* to the array element */
1115 char *s = SPEC_CVAL (iexpr->etype).v_char;
1117 unsigned int symsize = getSize (type);
1119 size = getSize (iexpr->ftype);
1120 if (symsize && size>symsize)
1122 if (size>(symsize+1))
1124 char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
1126 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1132 for (i=0;i<size;i++)
1134 rast = newNode (NULLOP,
1138 newAst_VALUE (valueFromLit ((float) i))),
1139 newAst_VALUE (valueFromLit (*s))));
1143 // now WE don't need iexpr's symbol anymore
1144 freeStringSymbol(AST_SYMBOL(iexpr));
1146 /* if we have not been given a size */
1147 if (!DCL_ELEM (type))
1149 /* check, if it's a flexible array */
1150 if (IS_STRUCT (AST_VALUE (rootVal)->type))
1151 AST_SYMBOL(rootVal)->flexArrayLength = size * getSize (type->next);
1153 DCL_ELEM (type) = size;
1156 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1162 /*-----------------------------------------------------------------*/
1163 /* createIvalPtr - generates initial value for pointers */
1164 /*-----------------------------------------------------------------*/
1166 createIvalPtr (ast * sym, sym_link * type, initList * ilist, ast *rootVal)
1172 if (ilist->type == INIT_DEEP)
1173 ilist = ilist->init.deep;
1175 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_TYPE_NONE);
1177 /* if character pointer */
1178 if (IS_CHAR (type->next))
1179 if ((rast = createIvalCharPtr (sym, type, iexpr, rootVal)))
1182 return newNode ('=', sym, iexpr);
1185 /*-----------------------------------------------------------------*/
1186 /* createIval - generates code for initial value */
1187 /*-----------------------------------------------------------------*/
1189 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid, ast *rootValue)
1196 /* if structure then */
1197 if (IS_STRUCT (type))
1198 rast = createIvalStruct (sym, type, ilist, rootValue);
1200 /* if this is a pointer */
1202 rast = createIvalPtr (sym, type, ilist, rootValue);
1204 /* if this is an array */
1205 if (IS_ARRAY (type))
1206 rast = createIvalArray (sym, type, ilist, rootValue);
1208 /* if type is SPECIFIER */
1210 rast = createIvalType (sym, type, ilist);
1213 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_TYPE_NONE);
1215 return decorateType (resolveSymbols (rast), RESULT_TYPE_NONE);
1218 /*-----------------------------------------------------------------*/
1219 /* initAggregates - initialises aggregate variables with initv */
1220 /*-----------------------------------------------------------------*/
1221 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1222 ast *newAst = newAst_VALUE (symbolVal (sym));
1223 return createIval (newAst, sym->type, ival, wid, newAst);
1226 /*-----------------------------------------------------------------*/
1227 /* gatherAutoInit - creates assignment expressions for initial */
1229 /*-----------------------------------------------------------------*/
1231 gatherAutoInit (symbol * autoChain)
1238 for (sym = autoChain; sym; sym = sym->next)
1241 /* resolve the symbols in the ival */
1243 resolveIvalSym (sym->ival, sym->type);
1246 /* if we are PIC16 port,
1247 * and this is a static,
1248 * and have initial value,
1249 * and not S_CODE, don't emit in gs segment,
1250 * but allow glue.c:pic16emitRegularMap to put symbol
1251 * in idata section */
1252 if(TARGET_IS_PIC16 &&
1253 IS_STATIC (sym->etype) && sym->ival
1254 && SPEC_SCLS(sym->etype) != S_CODE) {
1255 SPEC_SCLS (sym->etype) = S_DATA;
1260 /* if this is a static variable & has an */
1261 /* initial value the code needs to be lifted */
1262 /* here to the main portion since they can be */
1263 /* initialised only once at the start */
1264 if (IS_STATIC (sym->etype) && sym->ival &&
1265 SPEC_SCLS (sym->etype) != S_CODE)
1269 /* insert the symbol into the symbol table */
1270 /* with level = 0 & name = rname */
1271 newSym = copySymbol (sym);
1272 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1274 /* now lift the code to main */
1275 if (IS_AGGREGATE (sym->type)) {
1276 work = initAggregates (sym, sym->ival, NULL);
1278 if (getNelements(sym->type, sym->ival)>1) {
1279 werrorfl (sym->fileDef, sym->lineDef,
1280 W_EXCESS_INITIALIZERS, "scalar",
1283 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1284 list2expr (sym->ival));
1287 setAstLineno (work, sym->lineDef);
1291 staticAutos = newNode (NULLOP, staticAutos, work);
1298 /* if there is an initial value */
1299 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1301 initList *ilist=sym->ival;
1303 while (ilist->type == INIT_DEEP) {
1304 ilist = ilist->init.deep;
1307 /* update lineno for error msg */
1308 lineno=sym->lineDef;
1309 setAstLineno (ilist->init.node, lineno);
1311 if (IS_AGGREGATE (sym->type)) {
1312 work = initAggregates (sym, sym->ival, NULL);
1314 if (getNelements(sym->type, sym->ival)>1) {
1315 werrorfl (sym->fileDef, sym->lineDef,
1316 W_EXCESS_INITIALIZERS, "scalar",
1319 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1320 list2expr (sym->ival));
1324 setAstLineno (work, sym->lineDef);
1328 init = newNode (NULLOP, init, work);
1337 /*-----------------------------------------------------------------*/
1338 /* freeStringSymbol - delete a literal string if no more usage */
1339 /*-----------------------------------------------------------------*/
1340 void freeStringSymbol(symbol *sym) {
1341 /* make sure this is a literal string */
1342 assert (sym->isstrlit);
1343 if (--sym->isstrlit == 0) { // lower the usage count
1344 memmap *segment=SPEC_OCLS(sym->etype);
1346 deleteSetItem(&segment->syms, sym);
1351 /*-----------------------------------------------------------------*/
1352 /* stringToSymbol - creates a symbol from a literal string */
1353 /*-----------------------------------------------------------------*/
1355 stringToSymbol (value * val)
1357 char name[SDCC_NAME_MAX + 1];
1358 static int charLbl = 0;
1363 // have we heard this before?
1364 for (sp=statsg->syms; sp; sp=sp->next) {
1366 size = getSize (sym->type);
1367 if (sym->isstrlit && size == getSize (val->type) &&
1368 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1369 // yes, this is old news. Don't publish it again.
1370 sym->isstrlit++; // but raise the usage count
1371 return symbolVal(sym);
1375 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1376 sym = newSymbol (name, 0); /* make it @ level 0 */
1377 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1379 /* copy the type from the value passed */
1380 sym->type = copyLinkChain (val->type);
1381 sym->etype = getSpec (sym->type);
1382 /* change to storage class & output class */
1383 SPEC_SCLS (sym->etype) = S_CODE;
1384 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1385 SPEC_STAT (sym->etype) = 1;
1386 /* make the level & block = 0 */
1387 sym->block = sym->level = 0;
1389 /* create an ival */
1390 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1395 allocVariables (sym);
1398 return symbolVal (sym);
1402 /*-----------------------------------------------------------------*/
1403 /* processBlockVars - will go thru the ast looking for block if */
1404 /* a block is found then will allocate the syms */
1405 /* will also gather the auto inits present */
1406 /*-----------------------------------------------------------------*/
1408 processBlockVars (ast * tree, int *stack, int action)
1413 /* if this is a block */
1414 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1418 if (action == ALLOCATE)
1420 *stack += allocVariables (tree->values.sym);
1421 autoInit = gatherAutoInit (tree->values.sym);
1423 /* if there are auto inits then do them */
1425 tree->left = newNode (NULLOP, autoInit, tree->left);
1427 else /* action is deallocate */
1428 deallocLocal (tree->values.sym);
1431 processBlockVars (tree->left, stack, action);
1432 processBlockVars (tree->right, stack, action);
1437 /*-------------------------------------------------------------*/
1438 /* constExprTree - returns TRUE if this tree is a constant */
1440 /*-------------------------------------------------------------*/
1441 bool constExprTree (ast *cexpr) {
1447 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1449 switch (cexpr->type)
1452 if (IS_AST_LIT_VALUE(cexpr)) {
1453 // this is a literal
1456 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1457 // a function's address will never change
1460 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1461 // an array's address will never change
1464 if (IS_AST_SYM_VALUE(cexpr) &&
1465 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1466 // a symbol in code space will never change
1467 // This is only for the 'char *s="hallo"' case and will have to leave
1468 //printf(" code space symbol");
1473 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1474 "unexpected link in expression tree\n");
1477 if (cexpr->opval.op==ARRAYINIT) {
1478 // this is a list of literals
1481 if (cexpr->opval.op=='=') {
1482 return constExprTree(cexpr->right);
1484 if (cexpr->opval.op==CAST) {
1485 // cast ignored, maybe we should throw a warning here?
1486 return constExprTree(cexpr->right);
1488 if (cexpr->opval.op=='&') {
1491 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1494 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1499 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1504 /*-----------------------------------------------------------------*/
1505 /* constExprValue - returns the value of a constant expression */
1506 /* or NULL if it is not a constant expression */
1507 /*-----------------------------------------------------------------*/
1509 constExprValue (ast * cexpr, int check)
1511 cexpr = decorateType (resolveSymbols (cexpr), RESULT_TYPE_NONE);
1513 /* if this is not a constant then */
1514 if (!IS_LITERAL (cexpr->ftype))
1516 /* then check if this is a literal array
1518 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1519 SPEC_CVAL (cexpr->etype).v_char &&
1520 IS_ARRAY (cexpr->ftype))
1522 value *val = valFromType (cexpr->ftype);
1523 SPEC_SCLS (val->etype) = S_LITERAL;
1524 val->sym = cexpr->opval.val->sym;
1525 val->sym->type = copyLinkChain (cexpr->ftype);
1526 val->sym->etype = getSpec (val->sym->type);
1527 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1531 /* if we are casting a literal value then */
1532 if (IS_AST_OP (cexpr) &&
1533 cexpr->opval.op == CAST &&
1534 IS_LITERAL (cexpr->right->ftype))
1536 return valCastLiteral (cexpr->ftype,
1537 floatFromVal (cexpr->right->opval.val));
1540 if (IS_AST_VALUE (cexpr))
1542 return cexpr->opval.val;
1546 werror (E_CONST_EXPECTED, "found expression");
1551 /* return the value */
1552 if (IS_AST_VALUE (cexpr))
1554 return cexpr->opval.val;
1559 /*-----------------------------------------------------------------*/
1560 /* isLabelInAst - will return true if a given label is found */
1561 /*-----------------------------------------------------------------*/
1563 isLabelInAst (symbol * label, ast * tree)
1565 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1568 if (IS_AST_OP (tree) &&
1569 tree->opval.op == LABEL &&
1570 isSymbolEqual (AST_SYMBOL (tree->left), label))
1573 return isLabelInAst (label, tree->right) &&
1574 isLabelInAst (label, tree->left);
1578 /*-----------------------------------------------------------------*/
1579 /* isLoopCountable - return true if the loop count can be determi- */
1580 /* -ned at compile time . */
1581 /*-----------------------------------------------------------------*/
1583 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1584 symbol ** sym, ast ** init, ast ** end)
1587 /* the loop is considered countable if the following
1588 conditions are true :-
1590 a) initExpr :- <sym> = <const>
1591 b) condExpr :- <sym> < <const1>
1592 c) loopExpr :- <sym> ++
1595 /* first check the initExpr */
1596 if (IS_AST_OP (initExpr) &&
1597 initExpr->opval.op == '=' && /* is assignment */
1598 IS_AST_SYM_VALUE (initExpr->left))
1599 { /* left is a symbol */
1601 *sym = AST_SYMBOL (initExpr->left);
1602 *init = initExpr->right;
1607 /* don't reverse loop with volatile counter */
1608 if (IS_VOLATILE ((*sym)->type))
1611 /* for now the symbol has to be of
1613 if (!IS_INTEGRAL ((*sym)->type))
1616 /* now check condExpr */
1617 if (IS_AST_OP (condExpr))
1620 switch (condExpr->opval.op)
1623 if (IS_AST_SYM_VALUE (condExpr->left) &&
1624 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1625 IS_AST_LIT_VALUE (condExpr->right))
1627 *end = condExpr->right;
1633 if (IS_AST_OP (condExpr->left) &&
1634 condExpr->left->opval.op == '>' &&
1635 IS_AST_LIT_VALUE (condExpr->left->right) &&
1636 IS_AST_SYM_VALUE (condExpr->left->left) &&
1637 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1640 *end = newNode ('+', condExpr->left->right,
1641 newAst_VALUE (constVal ("1")));
1654 /* check loop expression is of the form <sym>++ */
1655 if (!IS_AST_OP (loopExpr))
1658 /* check if <sym> ++ */
1659 if (loopExpr->opval.op == INC_OP)
1665 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1666 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1673 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1674 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1682 if (loopExpr->opval.op == ADD_ASSIGN)
1685 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1686 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1687 IS_AST_LIT_VALUE (loopExpr->right) &&
1688 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1696 /*-----------------------------------------------------------------*/
1697 /* astHasVolatile - returns true if ast contains any volatile */
1698 /*-----------------------------------------------------------------*/
1700 astHasVolatile (ast * tree)
1705 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1708 if (IS_AST_OP (tree))
1709 return astHasVolatile (tree->left) ||
1710 astHasVolatile (tree->right);
1715 /*-----------------------------------------------------------------*/
1716 /* astHasPointer - return true if the ast contains any ptr variable */
1717 /*-----------------------------------------------------------------*/
1719 astHasPointer (ast * tree)
1724 if (IS_AST_LINK (tree))
1727 /* if we hit an array expression then check
1728 only the left side */
1729 if (IS_AST_OP (tree) && tree->opval.op == '[')
1730 return astHasPointer (tree->left);
1732 if (IS_AST_VALUE (tree))
1733 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1735 return astHasPointer (tree->left) ||
1736 astHasPointer (tree->right);
1740 /*-----------------------------------------------------------------*/
1741 /* astHasSymbol - return true if the ast has the given symbol */
1742 /*-----------------------------------------------------------------*/
1744 astHasSymbol (ast * tree, symbol * sym)
1746 if (!tree || IS_AST_LINK (tree))
1749 if (IS_AST_VALUE (tree))
1751 if (IS_AST_SYM_VALUE (tree))
1752 return isSymbolEqual (AST_SYMBOL (tree), sym);
1757 return astHasSymbol (tree->left, sym) ||
1758 astHasSymbol (tree->right, sym);
1761 /*-----------------------------------------------------------------*/
1762 /* astHasDeref - return true if the ast has an indirect access */
1763 /*-----------------------------------------------------------------*/
1765 astHasDeref (ast * tree)
1767 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1770 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1772 return astHasDeref (tree->left) || astHasDeref (tree->right);
1775 /*-----------------------------------------------------------------*/
1776 /* isConformingBody - the loop body has to conform to a set of rules */
1777 /* for the loop to be considered reversible read on for rules */
1778 /*-----------------------------------------------------------------*/
1780 isConformingBody (ast * pbody, symbol * sym, ast * body)
1783 /* we are going to do a pre-order traversal of the
1784 tree && check for the following conditions. (essentially
1785 a set of very shallow tests )
1786 a) the sym passed does not participate in
1787 any arithmetic operation
1788 b) There are no function calls
1789 c) all jumps are within the body
1790 d) address of loop control variable not taken
1791 e) if an assignment has a pointer on the
1792 left hand side make sure right does not have
1793 loop control variable */
1795 /* if we reach the end or a leaf then true */
1796 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1799 /* if anything else is "volatile" */
1800 if (IS_VOLATILE (TETYPE (pbody)))
1803 /* we will walk the body in a pre-order traversal for
1805 switch (pbody->opval.op)
1807 /*------------------------------------------------------------------*/
1809 // if the loopvar is used as an index
1810 /* array op is commutative -- must check both left & right */
1811 if (astHasSymbol(pbody->right, sym) || astHasSymbol(pbody->left, sym)) {
1814 return isConformingBody (pbody->right, sym, body)
1815 && isConformingBody (pbody->left, sym, body);
1817 /*------------------------------------------------------------------*/
1822 /*------------------------------------------------------------------*/
1826 /* sure we are not sym is not modified */
1828 IS_AST_SYM_VALUE (pbody->left) &&
1829 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1833 IS_AST_SYM_VALUE (pbody->right) &&
1834 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1839 /*------------------------------------------------------------------*/
1841 case '*': /* can be unary : if right is null then unary operation */
1846 /* if right is NULL then unary operation */
1847 /*------------------------------------------------------------------*/
1848 /*----------------------------*/
1850 /*----------------------------*/
1853 if (IS_AST_SYM_VALUE (pbody->left) &&
1854 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1857 return isConformingBody (pbody->left, sym, body);
1861 if (astHasSymbol (pbody->left, sym) ||
1862 astHasSymbol (pbody->right, sym))
1867 /*------------------------------------------------------------------*/
1878 if (IS_AST_SYM_VALUE (pbody->left) &&
1879 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1882 if (IS_AST_SYM_VALUE (pbody->right) &&
1883 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1886 return isConformingBody (pbody->left, sym, body) &&
1887 isConformingBody (pbody->right, sym, body);
1895 if (IS_AST_SYM_VALUE (pbody->left) &&
1896 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1898 return isConformingBody (pbody->left, sym, body);
1900 /*------------------------------------------------------------------*/
1912 case SIZEOF: /* evaluate wihout code generation */
1914 if (IS_AST_SYM_VALUE (pbody->left) &&
1915 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1918 if (IS_AST_SYM_VALUE (pbody->right) &&
1919 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1922 return isConformingBody (pbody->left, sym, body) &&
1923 isConformingBody (pbody->right, sym, body);
1925 /*------------------------------------------------------------------*/
1928 /* if left has a pointer & right has loop
1929 control variable then we cannot */
1930 if (astHasPointer (pbody->left) &&
1931 astHasSymbol (pbody->right, sym))
1933 if (astHasVolatile (pbody->left))
1936 if (IS_AST_SYM_VALUE (pbody->left)) {
1937 // if the loopvar has an assignment
1938 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1940 // if the loopvar is used in another (maybe conditional) block
1941 if (astHasSymbol (pbody->right, sym) &&
1942 (pbody->level >= body->level)) {
1947 if (astHasVolatile (pbody->left))
1950 if (astHasDeref(pbody->right)) return FALSE;
1952 return isConformingBody (pbody->left, sym, body) &&
1953 isConformingBody (pbody->right, sym, body);
1964 assert ("Parser should not have generated this\n");
1966 /*------------------------------------------------------------------*/
1967 /*----------------------------*/
1968 /* comma operator */
1969 /*----------------------------*/
1971 return isConformingBody (pbody->left, sym, body) &&
1972 isConformingBody (pbody->right, sym, body);
1974 /*------------------------------------------------------------------*/
1975 /*----------------------------*/
1977 /*----------------------------*/
1979 /* if local & not passed as paramater then ok */
1980 if (sym->level && !astHasSymbol(pbody->right,sym))
1984 /*------------------------------------------------------------------*/
1985 /*----------------------------*/
1986 /* return statement */
1987 /*----------------------------*/
1992 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1997 if (astHasSymbol (pbody->left, sym))
2004 return isConformingBody (pbody->left, sym, body) &&
2005 isConformingBody (pbody->right, sym, body);
2011 /*-----------------------------------------------------------------*/
2012 /* isLoopReversible - takes a for loop as input && returns true */
2013 /* if the for loop is reversible. If yes will set the value of */
2014 /* the loop control var & init value & termination value */
2015 /*-----------------------------------------------------------------*/
2017 isLoopReversible (ast * loop, symbol ** loopCntrl,
2018 ast ** init, ast ** end)
2020 /* if option says don't do it then don't */
2021 if (optimize.noLoopReverse)
2023 /* there are several tests to determine this */
2025 /* for loop has to be of the form
2026 for ( <sym> = <const1> ;
2027 [<sym> < <const2>] ;
2028 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
2030 if (!isLoopCountable (AST_FOR (loop, initExpr),
2031 AST_FOR (loop, condExpr),
2032 AST_FOR (loop, loopExpr),
2033 loopCntrl, init, end))
2036 /* now do some serious checking on the body of the loop
2039 return isConformingBody (loop->left, *loopCntrl, loop->left);
2043 /*-----------------------------------------------------------------*/
2044 /* replLoopSym - replace the loop sym by loop sym -1 */
2045 /*-----------------------------------------------------------------*/
2047 replLoopSym (ast * body, symbol * sym)
2050 if (!body || IS_AST_LINK (body))
2053 if (IS_AST_SYM_VALUE (body))
2056 if (isSymbolEqual (AST_SYMBOL (body), sym))
2060 body->opval.op = '-';
2061 body->left = newAst_VALUE (symbolVal (sym));
2062 body->right = newAst_VALUE (constVal ("1"));
2070 replLoopSym (body->left, sym);
2071 replLoopSym (body->right, sym);
2075 /*-----------------------------------------------------------------*/
2076 /* reverseLoop - do the actual loop reversal */
2077 /*-----------------------------------------------------------------*/
2079 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
2083 /* create the following tree
2088 if (sym) goto for_continue ;
2091 /* put it together piece by piece */
2092 rloop = newNode (NULLOP,
2093 createIf (newAst_VALUE (symbolVal (sym)),
2095 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
2098 newAst_VALUE (symbolVal (sym)),
2101 replLoopSym (loop->left, sym);
2102 setAstLineno (rloop, init->lineno);
2104 rloop = newNode (NULLOP,
2106 newAst_VALUE (symbolVal (sym)),
2107 newNode ('-', end, init)),
2108 createLabel (AST_FOR (loop, continueLabel),
2112 newNode (SUB_ASSIGN,
2113 newAst_VALUE (symbolVal (sym)),
2114 newAst_VALUE (constVal ("1"))),
2117 rloop->lineno=init->lineno;
2118 return decorateType (rloop, RESULT_TYPE_NONE);
2122 /*-----------------------------------------------------------------*/
2123 /* searchLitOp - search tree (*ops only) for an ast with literal */
2124 /*-----------------------------------------------------------------*/
2126 searchLitOp (ast *tree, ast **parent, const char *ops)
2130 if (tree && optimize.global_cse)
2132 /* is there a literal operand? */
2134 IS_AST_OP(tree->right) &&
2135 tree->right->right &&
2136 (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1]))
2138 if (IS_LITERAL (RTYPE (tree->right)) !=
2139 IS_LITERAL (LTYPE (tree->right)))
2141 tree->right->decorated = 0;
2142 tree->decorated = 0;
2146 ret = searchLitOp (tree->right, parent, ops);
2151 IS_AST_OP(tree->left) &&
2152 tree->left->right &&
2153 (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1]))
2155 if (IS_LITERAL (RTYPE (tree->left)) !=
2156 IS_LITERAL (LTYPE (tree->left)))
2158 tree->left->decorated = 0;
2159 tree->decorated = 0;
2163 ret = searchLitOp (tree->left, parent, ops);
2171 /*-----------------------------------------------------------------*/
2172 /* getResultFromType */
2173 /*-----------------------------------------------------------------*/
2175 getResultTypeFromType (sym_link *type)
2177 /* type = getSpec (type); */
2179 return RESULT_TYPE_BIT;
2180 if (IS_BITFIELD (type))
2182 int blen = SPEC_BLEN (type);
2185 return RESULT_TYPE_BIT;
2187 return RESULT_TYPE_CHAR;
2188 return RESULT_TYPE_INT;
2191 return RESULT_TYPE_CHAR;
2194 return RESULT_TYPE_INT;
2195 return RESULT_TYPE_OTHER;
2198 /*-----------------------------------------------------------------*/
2199 /* addCast - adds casts to a type specified by RESULT_TYPE */
2200 /*-----------------------------------------------------------------*/
2202 addCast (ast *tree, RESULT_TYPE resultType, bool promote)
2205 bool upCasted = FALSE;
2209 case RESULT_TYPE_NONE:
2210 /* if thing smaller than int must be promoted to int */
2212 getSize (tree->etype) >= INTSIZE)
2213 /* promotion not necessary or already an int */
2215 /* char and bits: promote to int */
2216 newLink = newIntLink();
2219 case RESULT_TYPE_BIT:
2221 /* already an int */
2222 bitsForType (tree->etype) >= 16 ||
2223 /* bit to bit operation: don't promote, the code generators
2224 hopefully know everything about promotion rules */
2225 bitsForType (tree->etype) == 1)
2227 newLink = newIntLink();
2230 case RESULT_TYPE_CHAR:
2231 if (IS_CHAR (tree->etype) ||
2232 IS_FLOAT(tree->etype) ||
2233 IS_FIXED(tree->etype))
2235 newLink = newCharLink();
2237 case RESULT_TYPE_INT:
2239 if (getSize (tree->etype) > INTSIZE)
2241 /* warn ("Loosing significant digits"); */
2245 /* char: promote to int */
2247 getSize (tree->etype) >= INTSIZE)
2249 newLink = newIntLink();
2252 case RESULT_TYPE_IFX:
2253 case RESULT_TYPE_OTHER:
2255 /* return type is ifx, long, float: promote char to int */
2256 getSize (tree->etype) >= INTSIZE)
2258 newLink = newIntLink();
2264 tree->decorated = 0;
2265 tree = newNode (CAST, newAst_LINK (newLink), tree);
2266 tree->lineno = tree->right->lineno;
2267 /* keep unsigned type during cast to smaller type,
2268 but not when promoting from char to int */
2270 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2271 return decorateType (tree, resultType);
2274 /*-----------------------------------------------------------------*/
2275 /* resultTypePropagate - decides if resultType can be propagated */
2276 /*-----------------------------------------------------------------*/
2278 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2280 switch (tree->opval.op)
2299 return RESULT_TYPE_NONE;
2303 return RESULT_TYPE_IFX;
2305 return RESULT_TYPE_NONE;
2309 /*-----------------------------------------------------------------*/
2310 /* getLeftResultType - gets type from left branch for propagation */
2311 /*-----------------------------------------------------------------*/
2313 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2315 switch (tree->opval.op)
2319 if (IS_PTR (LTYPE (tree)))
2320 return RESULT_TYPE_NONE;
2322 return getResultTypeFromType (LETYPE (tree));
2324 if (IS_PTR (currFunc->type->next))
2325 return RESULT_TYPE_NONE;
2327 return getResultTypeFromType (currFunc->type->next);
2329 if (!IS_ARRAY (LTYPE (tree)))
2331 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 255)
2332 return RESULT_TYPE_CHAR;
2339 /*------------------------------------------------------------------*/
2340 /* gatherImplicitVariables: assigns correct type information to */
2341 /* symbols and values created by replaceAstWithTemporary */
2342 /* and adds the symbols to the declarations list of the */
2343 /* innermost block that contains them */
2344 /*------------------------------------------------------------------*/
2346 gatherImplicitVariables (ast * tree, ast * block)
2351 if (tree->type == EX_OP && tree->opval.op == BLOCK)
2353 /* keep track of containing scope */
2356 if (tree->type == EX_OP && tree->opval.op == '=' &&
2357 tree->left->type == EX_VALUE && tree->left->opval.val->sym)
2359 symbol *assignee = tree->left->opval.val->sym;
2361 /* special case for assignment to compiler-generated temporary variable:
2362 compute type of RHS, and set the symbol's type to match */
2363 if (assignee->type == NULL && assignee->infertype) {
2364 ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
2366 if (dtr != tree->right)
2369 assignee->type = copyLinkChain(TTYPE(dtr));
2370 assignee->etype = getSpec(assignee->type);
2371 SPEC_SCLS (assignee->etype) = S_AUTO;
2372 SPEC_OCLS (assignee->etype) = NULL;
2373 SPEC_EXTR (assignee->etype) = 0;
2374 SPEC_STAT (assignee->etype) = 0;
2375 SPEC_VOLATILE (assignee->etype) = 0;
2376 SPEC_ABSA (assignee->etype) = 0;
2378 wassertl(block != NULL, "implicit variable not contained in block");
2379 wassert(assignee->next == NULL);
2380 if (block != NULL) {
2381 symbol **decl = &(block->values.sym);
2384 wassert(*decl != assignee); /* should not already be in list */
2385 decl = &( (*decl)->next );
2392 if (tree->type == EX_VALUE && !(IS_LITERAL(tree->opval.val->etype)) &&
2393 tree->opval.val->type == NULL &&
2394 tree->opval.val->sym &&
2395 tree->opval.val->sym->infertype)
2397 /* fixup type of value for compiler-inferred temporary var */
2398 tree->opval.val->type = tree->opval.val->sym->type;
2399 tree->opval.val->etype = tree->opval.val->sym->etype;
2402 gatherImplicitVariables(tree->left, block);
2403 gatherImplicitVariables(tree->right, block);
2406 /*--------------------------------------------------------------------*/
2407 /* decorateType - compute type for this tree, also does type checking.*/
2408 /* This is done bottom up, since type has to flow upwards. */
2409 /* resultType flows top-down and forces e.g. char-arithmetic, if the */
2410 /* result is a char and the operand(s) are int's. */
2411 /* It also does constant folding, and parameter checking. */
2412 /*--------------------------------------------------------------------*/
2414 decorateType (ast * tree, RESULT_TYPE resultType)
2418 RESULT_TYPE resultTypeProp;
2423 /* if already has type then do nothing */
2424 if (tree->decorated)
2427 tree->decorated = 1;
2430 /* print the line */
2431 /* if not block & function */
2432 if (tree->type == EX_OP &&
2433 (tree->opval.op != FUNCTION &&
2434 tree->opval.op != BLOCK &&
2435 tree->opval.op != NULLOP))
2437 filename = tree->filename;
2438 lineno = tree->lineno;
2442 /* if any child is an error | this one is an error do nothing */
2443 if (tree->isError ||
2444 (tree->left && tree->left->isError) ||
2445 (tree->right && tree->right->isError))
2448 /*------------------------------------------------------------------*/
2449 /*----------------------------*/
2450 /* leaf has been reached */
2451 /*----------------------------*/
2452 lineno=tree->lineno;
2453 /* if this is of type value */
2454 /* just get the type */
2455 if (tree->type == EX_VALUE)
2458 if (IS_LITERAL (tree->opval.val->etype))
2461 /* if this is a character array then declare it */
2462 if (IS_ARRAY (tree->opval.val->type))
2463 tree->opval.val = stringToSymbol (tree->opval.val);
2465 /* otherwise just copy the type information */
2466 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2470 if (tree->opval.val->sym)
2472 /* if the undefined flag is set then give error message */
2473 if (tree->opval.val->sym->undefined)
2475 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2477 TTYPE (tree) = TETYPE (tree) =
2478 tree->opval.val->type = tree->opval.val->sym->type =
2479 tree->opval.val->etype = tree->opval.val->sym->etype =
2480 copyLinkChain (INTTYPE);
2482 else if (tree->opval.val->sym->implicit)
2484 /* if implicit i.e. struct/union member then no type */
2485 TTYPE (tree) = TETYPE (tree) = NULL;
2489 /* copy the type from the value into the ast */
2490 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2492 /* and mark the symbol as referenced */
2493 tree->opval.val->sym->isref = 1;
2497 wassert(0); /* unreached: all values are literals or symbols */
2502 /* if type link for the case of cast */
2503 if (tree->type == EX_LINK)
2505 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2513 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2515 if (tree->left && tree->left->type == EX_OPERAND
2516 && (tree->left->opval.op == INC_OP
2517 || tree->left->opval.op == DEC_OP)
2518 && tree->left->left)
2520 tree->left->right = tree->left->left;
2521 tree->left->left = NULL;
2523 if (tree->right && tree->right->type == EX_OPERAND
2524 && (tree->right->opval.op == INC_OP
2525 || tree->right->opval.op == DEC_OP)
2526 && tree->right->left)
2528 tree->right->right = tree->right->left;
2529 tree->right->left = NULL;
2534 /* Before decorating the left branch we've to decide in dependence
2535 upon tree->opval.op, if resultType can be propagated */
2536 resultTypeProp = resultTypePropagate (tree, resultType);
2538 if (tree->opval.op == '?')
2539 dtl = decorateType (tree->left, RESULT_TYPE_IFX);
2541 dtl = decorateType (tree->left, resultTypeProp);
2543 /* if an array node, we may need to swap branches */
2544 if (tree->opval.op == '[')
2546 /* determine which is the array & which the index */
2547 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2548 IS_INTEGRAL (LTYPE (tree)))
2550 ast *tempTree = tree->left;
2551 tree->left = tree->right;
2552 tree->right = tempTree;
2556 /* After decorating the left branch there's type information available
2557 in tree->left->?type. If the op is e.g. '=' we extract the type
2558 information from there and propagate it to the right branch. */
2559 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2561 switch (tree->opval.op)
2564 /* delay right side for '?' operator since conditional macro
2565 expansions might rely on this */
2569 /* decorate right side for CALL (parameter list) in processParms();
2570 there is resultType available */
2574 dtr = decorateType (tree->right, resultTypeProp);
2578 /* this is to take care of situations
2579 when the tree gets rewritten */
2580 if (dtl != tree->left)
2582 if (dtr != tree->right)
2584 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2588 /* depending on type of operator do */
2590 switch (tree->opval.op)
2592 /*------------------------------------------------------------------*/
2593 /*----------------------------*/
2595 /*----------------------------*/
2598 /* first check if this is a array or a pointer */
2599 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2601 werror (E_NEED_ARRAY_PTR, "[]");
2602 goto errorTreeReturn;
2605 /* check if the type of the idx */
2606 if (!IS_INTEGRAL (RTYPE (tree)))
2608 werror (E_IDX_NOT_INT);
2609 goto errorTreeReturn;
2612 /* if the left is an rvalue then error */
2615 werror (E_LVALUE_REQUIRED, "array access");
2616 goto errorTreeReturn;
2619 if (IS_LITERAL (RTYPE (tree)))
2621 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2622 int arraySize = DCL_ELEM (LTYPE (tree));
2623 if (arraySize && arrayIndex >= arraySize)
2625 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2630 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2631 SPEC_CONST (TETYPE (tree)) |= DCL_PTR_CONST (LTYPE (tree));
2634 /*------------------------------------------------------------------*/
2635 /*----------------------------*/
2637 /*----------------------------*/
2639 /* if this is not a structure */
2640 if (!IS_STRUCT (LTYPE (tree)))
2642 werror (E_STRUCT_UNION, ".");
2643 goto errorTreeReturn;
2645 TTYPE (tree) = structElemType (LTYPE (tree),
2646 (tree->right->type == EX_VALUE ?
2647 tree->right->opval.val : NULL));
2648 TETYPE (tree) = getSpec (TTYPE (tree));
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2653 /* struct/union pointer */
2654 /*----------------------------*/
2656 /* if not pointer to a structure */
2657 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2659 werror (E_PTR_REQD);
2660 goto errorTreeReturn;
2663 if (!IS_STRUCT (LTYPE (tree)->next))
2665 werror (E_STRUCT_UNION, "->");
2666 goto errorTreeReturn;
2669 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2670 (tree->right->type == EX_VALUE ?
2671 tree->right->opval.val : NULL));
2672 TETYPE (tree) = getSpec (TTYPE (tree));
2674 /* adjust the storage class */
2675 switch (DCL_TYPE(tree->left->ftype)) {
2677 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2680 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2683 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2686 SPEC_SCLS (TETYPE (tree)) = 0;
2689 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2692 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2695 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2698 SPEC_SCLS (TETYPE (tree)) = 0;
2705 /* This breaks with extern declarations, bitfields, and perhaps other */
2706 /* cases (gcse). Let's leave this optimization disabled for now and */
2707 /* ponder if there's a safe way to do this. -- EEP */
2709 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2710 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2712 /* If defined struct type at addr var
2713 then rewrite (&struct var)->member
2715 and define membertype at (addr+offsetof(struct var,member)) temp
2718 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2719 AST_SYMBOL(tree->right));
2721 sym = newSymbol(genSymName (0), 0);
2722 sym->type = TTYPE (tree);
2723 sym->etype = getSpec(sym->type);
2724 sym->lineDef = tree->lineno;
2727 SPEC_STAT (sym->etype) = 1;
2728 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2730 SPEC_ABSA(sym->etype) = 1;
2731 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2734 AST_VALUE (tree) = symbolVal(sym);
2737 tree->type = EX_VALUE;
2745 /*------------------------------------------------------------------*/
2746 /*----------------------------*/
2747 /* ++/-- operation */
2748 /*----------------------------*/
2752 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2753 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2754 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2755 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2767 /*----------------------------*/
2768 case '&': /* can be unary */
2769 /* if right is NULL then unary operation */
2770 if (tree->right) /* not an unary operation */
2773 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2775 werror (E_BITWISE_OP);
2776 werror (W_CONTINUE, "left & right types are ");
2777 printTypeChain (LTYPE (tree), stderr);
2778 fprintf (stderr, ",");
2779 printTypeChain (RTYPE (tree), stderr);
2780 fprintf (stderr, "\n");
2781 goto errorTreeReturn;
2784 /* if they are both literal */
2785 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2787 tree->type = EX_VALUE;
2788 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2789 valFromType (RETYPE (tree)), '&');
2791 tree->right = tree->left = NULL;
2792 TETYPE (tree) = tree->opval.val->etype;
2793 TTYPE (tree) = tree->opval.val->type;
2797 /* see if this is a GETHBIT operation if yes
2800 ast *otree = optimizeGetHbit (tree, resultType);
2803 return decorateType (otree, RESULT_TYPE_NONE);
2806 /* see if this is a GETABIT operation if yes
2809 ast *otree = optimizeGetAbit (tree, resultType);
2812 return decorateType (otree, RESULT_TYPE_NONE);
2815 /* see if this is a GETBYTE operation if yes
2818 ast *otree = optimizeGetByte (tree, resultType);
2821 return decorateType (otree, RESULT_TYPE_NONE);
2824 /* see if this is a GETWORD operation if yes
2827 ast *otree = optimizeGetWord (tree, resultType);
2830 return decorateType (otree, RESULT_TYPE_NONE);
2833 /* if left is a literal exchange left & right */
2834 if (IS_LITERAL (LTYPE (tree)))
2836 ast *tTree = tree->left;
2837 tree->left = tree->right;
2838 tree->right = tTree;
2841 /* if right is a literal and */
2842 /* we can find a 2nd literal in an and-tree then */
2843 /* rearrange the tree */
2844 if (IS_LITERAL (RTYPE (tree)))
2847 ast *litTree = searchLitOp (tree, &parent, "&");
2851 ast *tTree = litTree->left;
2852 litTree->left = tree->right;
2853 tree->right = tTree;
2854 /* both operands in litTree are literal now */
2855 decorateType (parent, resultType);
2859 LRVAL (tree) = RRVAL (tree) = 1;
2861 TTYPE (tree) = computeType (LTYPE (tree),
2865 TETYPE (tree) = getSpec (TTYPE (tree));
2870 /*------------------------------------------------------------------*/
2871 /*----------------------------*/
2873 /*----------------------------*/
2874 p = newLink (DECLARATOR);
2875 /* if bit field then error */
2876 if (IS_BITVAR (tree->left->etype))
2878 werror (E_ILLEGAL_ADDR, "address of bit variable");
2879 goto errorTreeReturn;
2882 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2884 werror (E_ILLEGAL_ADDR, "address of register variable");
2885 goto errorTreeReturn;
2888 if (IS_FUNC (LTYPE (tree)))
2890 // this ought to be ignored
2891 return (tree->left);
2894 if (IS_LITERAL(LTYPE(tree)))
2896 werror (E_ILLEGAL_ADDR, "address of literal");
2897 goto errorTreeReturn;
2902 werror (E_LVALUE_REQUIRED, "address of");
2903 goto errorTreeReturn;
2906 DCL_TYPE (p) = POINTER;
2907 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2908 DCL_TYPE (p) = CPOINTER;
2909 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2910 DCL_TYPE (p) = FPOINTER;
2911 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2912 DCL_TYPE (p) = PPOINTER;
2913 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2914 DCL_TYPE (p) = IPOINTER;
2915 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2916 DCL_TYPE (p) = EEPPOINTER;
2917 else if (SPEC_OCLS(tree->left->etype))
2918 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2920 DCL_TYPE (p) = POINTER;
2922 if (IS_AST_SYM_VALUE (tree->left))
2924 AST_SYMBOL (tree->left)->addrtaken = 1;
2925 AST_SYMBOL (tree->left)->allocreq = 1;
2928 p->next = LTYPE (tree);
2930 TETYPE (tree) = getSpec (TTYPE (tree));
2935 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2936 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2938 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2939 AST_SYMBOL(tree->left->right));
2940 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2941 valueFromLit(element->offset));
2944 tree->type = EX_VALUE;
2945 tree->values.literalFromCast = 1;
2951 /*------------------------------------------------------------------*/
2952 /*----------------------------*/
2954 /*----------------------------*/
2956 /* if the rewrite succeeds then don't go any further */
2958 ast *wtree = optimizeRRCRLC (tree);
2960 return decorateType (wtree, RESULT_TYPE_NONE);
2962 wtree = optimizeSWAP (tree);
2964 return decorateType (wtree, RESULT_TYPE_NONE);
2967 /* if left is a literal exchange left & right */
2968 if (IS_LITERAL (LTYPE (tree)))
2970 ast *tTree = tree->left;
2971 tree->left = tree->right;
2972 tree->right = tTree;
2975 /* if right is a literal and */
2976 /* we can find a 2nd literal in an or-tree then */
2977 /* rearrange the tree */
2978 if (IS_LITERAL (RTYPE (tree)))
2981 ast *litTree = searchLitOp (tree, &parent, "|");
2985 ast *tTree = litTree->left;
2986 litTree->left = tree->right;
2987 tree->right = tTree;
2988 /* both operands in tTree are literal now */
2989 decorateType (parent, resultType);
2994 /*------------------------------------------------------------------*/
2995 /*----------------------------*/
2997 /*----------------------------*/
2999 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3001 werror (E_BITWISE_OP);
3002 werror (W_CONTINUE, "left & right types are ");
3003 printTypeChain (LTYPE (tree), stderr);
3004 fprintf (stderr, ",");
3005 printTypeChain (RTYPE (tree), stderr);
3006 fprintf (stderr, "\n");
3007 goto errorTreeReturn;
3010 /* if they are both literal then rewrite the tree */
3011 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3013 tree->type = EX_VALUE;
3014 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
3015 valFromType (RETYPE (tree)),
3017 tree->right = tree->left = NULL;
3018 TETYPE (tree) = tree->opval.val->etype;
3019 TTYPE (tree) = tree->opval.val->type;
3023 /* if left is a literal exchange left & right */
3024 if (IS_LITERAL (LTYPE (tree)))
3026 ast *tTree = tree->left;
3027 tree->left = tree->right;
3028 tree->right = tTree;
3031 /* if right is a literal and */
3032 /* we can find a 2nd literal in a xor-tree then */
3033 /* rearrange the tree */
3034 if (IS_LITERAL (RTYPE (tree)) &&
3035 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
3038 ast *litTree = searchLitOp (tree, &parent, "^");
3042 ast *tTree = litTree->left;
3043 litTree->left = tree->right;
3044 tree->right = tTree;
3045 /* both operands in litTree are literal now */
3046 decorateType (parent, resultType);
3050 LRVAL (tree) = RRVAL (tree) = 1;
3052 TTYPE (tree) = computeType (LTYPE (tree),
3056 TETYPE (tree) = getSpec (TTYPE (tree));
3060 /*------------------------------------------------------------------*/
3061 /*----------------------------*/
3063 /*----------------------------*/
3065 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3067 werror (E_INVALID_OP, "divide");
3068 goto errorTreeReturn;
3070 /* if they are both literal then */
3071 /* rewrite the tree */
3072 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3074 tree->type = EX_VALUE;
3075 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
3076 valFromType (RETYPE (tree)));
3077 tree->right = tree->left = NULL;
3078 TETYPE (tree) = getSpec (TTYPE (tree) =
3079 tree->opval.val->type);
3083 LRVAL (tree) = RRVAL (tree) = 1;
3085 TETYPE (tree) = getSpec (TTYPE (tree) =
3086 computeType (LTYPE (tree),
3091 /* if right is a literal and */
3092 /* left is also a division by a literal then */
3093 /* rearrange the tree */
3094 if (IS_LITERAL (RTYPE (tree))
3095 /* avoid infinite loop */
3096 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
3099 ast *litTree = searchLitOp (tree, &parent, "/");
3102 if (IS_LITERAL (RTYPE (litTree)))
3106 litTree->right = newNode ('*',
3108 copyAst (tree->right));
3109 litTree->right->lineno = tree->lineno;
3111 tree->right->opval.val = constVal ("1");
3112 decorateType (parent, resultType);
3116 /* litTree->left is literal: no gcse possible.
3117 We can't call decorateType(parent, RESULT_TYPE_NONE), because
3118 this would cause an infinit loop. */
3119 parent->decorated = 1;
3120 decorateType (litTree, resultType);
3127 /*------------------------------------------------------------------*/
3128 /*----------------------------*/
3130 /*----------------------------*/
3132 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
3134 werror (E_BITWISE_OP);
3135 werror (W_CONTINUE, "left & right types are ");
3136 printTypeChain (LTYPE (tree), stderr);
3137 fprintf (stderr, ",");
3138 printTypeChain (RTYPE (tree), stderr);
3139 fprintf (stderr, "\n");
3140 goto errorTreeReturn;
3142 /* if they are both literal then */
3143 /* rewrite the tree */
3144 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3146 tree->type = EX_VALUE;
3147 tree->opval.val = valMod (valFromType (LETYPE (tree)),
3148 valFromType (RETYPE (tree)));
3149 tree->right = tree->left = NULL;
3150 TETYPE (tree) = getSpec (TTYPE (tree) =
3151 tree->opval.val->type);
3154 LRVAL (tree) = RRVAL (tree) = 1;
3155 TETYPE (tree) = getSpec (TTYPE (tree) =
3156 computeType (LTYPE (tree),
3162 /*------------------------------------------------------------------*/
3163 /*----------------------------*/
3164 /* address dereference */
3165 /*----------------------------*/
3166 case '*': /* can be unary : if right is null then unary operation */
3169 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3171 werror (E_PTR_REQD);
3172 goto errorTreeReturn;
3177 werror (E_LVALUE_REQUIRED, "pointer deref");
3178 goto errorTreeReturn;
3180 if (IS_ADDRESS_OF_OP(tree->left))
3182 /* replace *&obj with obj */
3183 return tree->left->left;
3185 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
3186 TETYPE (tree) = getSpec (TTYPE (tree));
3187 /* adjust the storage class */
3188 switch (DCL_TYPE(tree->left->ftype)) {
3190 SPEC_SCLS(TETYPE(tree)) = S_DATA;
3193 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
3196 SPEC_SCLS(TETYPE(tree)) = S_CODE;
3199 SPEC_SCLS (TETYPE (tree)) = 0;
3202 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
3205 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
3208 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
3211 SPEC_SCLS (TETYPE (tree)) = 0;
3220 /*------------------------------------------------------------------*/
3221 /*----------------------------*/
3222 /* multiplication */
3223 /*----------------------------*/
3224 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
3226 werror (E_INVALID_OP, "multiplication");
3227 goto errorTreeReturn;
3230 /* if they are both literal then */
3231 /* rewrite the tree */
3232 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3234 tree->type = EX_VALUE;
3235 tree->opval.val = valMult (valFromType (LETYPE (tree)),
3236 valFromType (RETYPE (tree)));
3237 tree->right = tree->left = NULL;
3238 TETYPE (tree) = getSpec (TTYPE (tree) =
3239 tree->opval.val->type);
3243 /* if left is a literal exchange left & right */
3244 if (IS_LITERAL (LTYPE (tree)))
3246 ast *tTree = tree->left;
3247 tree->left = tree->right;
3248 tree->right = tTree;
3251 /* if right is a literal and */
3252 /* we can find a 2nd literal in a mul-tree then */
3253 /* rearrange the tree */
3254 if (IS_LITERAL (RTYPE (tree)))
3257 ast *litTree = searchLitOp (tree, &parent, "*");
3261 ast *tTree = litTree->left;
3262 litTree->left = tree->right;
3263 tree->right = tTree;
3264 /* both operands in litTree are literal now */
3265 decorateType (parent, resultType);
3269 LRVAL (tree) = RRVAL (tree) = 1;
3270 tree->left = addCast (tree->left, resultType, FALSE);
3271 tree->right = addCast (tree->right, resultType, FALSE);
3272 TETYPE (tree) = getSpec (TTYPE (tree) =
3273 computeType (LTYPE (tree),
3280 /*------------------------------------------------------------------*/
3281 /*----------------------------*/
3282 /* unary '+' operator */
3283 /*----------------------------*/
3288 if (!IS_ARITHMETIC (LTYPE (tree)))
3290 werror (E_UNARY_OP, '+');
3291 goto errorTreeReturn;
3294 /* if left is a literal then do it */
3295 if (IS_LITERAL (LTYPE (tree)))
3297 tree->type = EX_VALUE;
3298 tree->opval.val = valFromType (LETYPE (tree));
3300 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3304 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3308 /*------------------------------------------------------------------*/
3309 /*----------------------------*/
3311 /*----------------------------*/
3313 /* this is not a unary operation */
3314 /* if both pointers then problem */
3315 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3316 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3318 werror (E_PTR_PLUS_PTR);
3319 goto errorTreeReturn;
3322 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3323 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3325 werror (E_PLUS_INVALID, "+");
3326 goto errorTreeReturn;
3329 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3330 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3332 werror (E_PLUS_INVALID, "+");
3333 goto errorTreeReturn;
3335 /* if they are both literal then */
3336 /* rewrite the tree */
3337 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3339 tree->type = EX_VALUE;
3340 tree->left = addCast (tree->left, resultType, TRUE);
3341 tree->right = addCast (tree->right, resultType, TRUE);
3342 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3343 valFromType (RETYPE (tree)));
3344 tree->right = tree->left = NULL;
3345 TETYPE (tree) = getSpec (TTYPE (tree) =
3346 tree->opval.val->type);
3350 /* if the right is a pointer or left is a literal
3351 xchange left & right */
3352 if (IS_ARRAY (RTYPE (tree)) ||
3353 IS_PTR (RTYPE (tree)) ||
3354 IS_LITERAL (LTYPE (tree)))
3356 ast *tTree = tree->left;
3357 tree->left = tree->right;
3358 tree->right = tTree;
3361 /* if right is a literal and */
3362 /* left is also an addition/subtraction with a literal then */
3363 /* rearrange the tree */
3364 if (IS_LITERAL (RTYPE (tree)))
3366 ast *litTree, *parent;
3367 litTree = searchLitOp (tree, &parent, "+-");
3370 if (litTree->opval.op == '+')
3374 ast *tTree = litTree->left;
3375 litTree->left = tree->right;
3376 tree->right = tree->left;
3379 else if (litTree->opval.op == '-')
3381 if (IS_LITERAL (RTYPE (litTree)))
3385 ast *tTree = litTree->left;
3386 litTree->left = tree->right;
3387 tree->right = tTree;
3393 ast *tTree = litTree->right;
3394 litTree->right = tree->right;
3395 tree->right = tTree;
3396 litTree->opval.op = '+';
3397 tree->opval.op = '-';
3400 decorateType (parent, resultType);
3404 LRVAL (tree) = RRVAL (tree) = 1;
3405 /* if the left is a pointer */
3406 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3407 TETYPE (tree) = getSpec (TTYPE (tree) =
3411 tree->left = addCast (tree->left, resultType, TRUE);
3412 tree->right = addCast (tree->right, resultType, TRUE);
3413 TETYPE (tree) = getSpec (TTYPE (tree) =
3414 computeType (LTYPE (tree),
3422 /*------------------------------------------------------------------*/
3423 /*----------------------------*/
3425 /*----------------------------*/
3426 case '-': /* can be unary */
3427 /* if right is null then unary */
3431 if (!IS_ARITHMETIC (LTYPE (tree)))
3433 werror (E_UNARY_OP, tree->opval.op);
3434 goto errorTreeReturn;
3437 /* if left is a literal then do it */
3438 if (IS_LITERAL (LTYPE (tree)))
3440 tree->type = EX_VALUE;
3441 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3443 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3446 tree->left = addCast (tree->left, resultType, TRUE);
3447 TETYPE (tree) = getSpec (TTYPE (tree) =
3448 computeType (LTYPE (tree),
3456 /*------------------------------------------------------------------*/
3457 /*----------------------------*/
3459 /*----------------------------*/
3461 if (!(IS_PTR (LTYPE (tree)) ||
3462 IS_ARRAY (LTYPE (tree)) ||
3463 IS_ARITHMETIC (LTYPE (tree))))
3465 werror (E_PLUS_INVALID, "-");
3466 goto errorTreeReturn;
3469 if (!(IS_PTR (RTYPE (tree)) ||
3470 IS_ARRAY (RTYPE (tree)) ||
3471 IS_ARITHMETIC (RTYPE (tree))))
3473 werror (E_PLUS_INVALID, "-");
3474 goto errorTreeReturn;
3477 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3478 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3479 IS_INTEGRAL (RTYPE (tree))))
3481 werror (E_PLUS_INVALID, "-");
3482 goto errorTreeReturn;
3485 /* if they are both literal then */
3486 /* rewrite the tree */
3487 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3489 tree->type = EX_VALUE;
3490 tree->left = addCast (tree->left, resultType, TRUE);
3491 tree->right = addCast (tree->right, resultType, TRUE);
3492 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3493 valFromType (RETYPE (tree)));
3494 tree->right = tree->left = NULL;
3495 TETYPE (tree) = getSpec (TTYPE (tree) =
3496 tree->opval.val->type);
3500 /* if the left & right are equal then zero */
3501 if (isAstEqual (tree->left, tree->right))
3503 tree->type = EX_VALUE;
3504 tree->left = tree->right = NULL;
3505 tree->opval.val = constVal ("0");
3506 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3510 /* if both of them are pointers or arrays then */
3511 /* the result is going to be an integer */
3512 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3513 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3514 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3516 /* if only the left is a pointer */
3517 /* then result is a pointer */
3518 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3519 TETYPE (tree) = getSpec (TTYPE (tree) =
3523 tree->left = addCast (tree->left, resultType, TRUE);
3524 tree->right = addCast (tree->right, resultType, TRUE);
3526 TETYPE (tree) = getSpec (TTYPE (tree) =
3527 computeType (LTYPE (tree),
3533 LRVAL (tree) = RRVAL (tree) = 1;
3535 /* if right is a literal and */
3536 /* left is also an addition/subtraction with a literal then */
3537 /* rearrange the tree */
3538 if (IS_LITERAL (RTYPE (tree))
3539 /* avoid infinite loop */
3540 && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
3542 ast *litTree, *litParent;
3543 litTree = searchLitOp (tree, &litParent, "+-");
3546 if (litTree->opval.op == '+')
3550 ast *tTree = litTree->left;
3551 litTree->left = litTree->right;
3552 litTree->right = tree->right;
3553 tree->right = tTree;
3554 tree->opval.op = '+';
3555 litTree->opval.op = '-';
3557 else if (litTree->opval.op == '-')
3559 if (IS_LITERAL (RTYPE (litTree)))
3563 ast *tTree = litTree->left;
3564 litTree->left = tree->right;
3565 tree->right = litParent->left;
3566 litParent->left = tTree;
3567 litTree->opval.op = '+';
3569 tree->decorated = 0;
3570 decorateType (tree, resultType);
3576 ast *tTree = litTree->right;
3577 litTree->right = tree->right;
3578 tree->right = tTree;
3581 decorateType (litParent, resultType);
3586 /*------------------------------------------------------------------*/
3587 /*----------------------------*/
3589 /*----------------------------*/
3591 /* can be only integral type */
3592 if (!IS_INTEGRAL (LTYPE (tree)))
3594 werror (E_UNARY_OP, tree->opval.op);
3595 goto errorTreeReturn;
3598 /* if left is a literal then do it */
3599 if (IS_LITERAL (LTYPE (tree)))
3601 tree->type = EX_VALUE;
3602 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3604 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3605 return addCast (tree, resultType, TRUE);
3608 if (resultType == RESULT_TYPE_BIT &&
3609 IS_UNSIGNED (tree->left->etype) &&
3610 getSize (tree->left->etype) < INTSIZE)
3612 /* promotion rules are responsible for this strange result:
3613 bit -> int -> ~int -> bit
3614 uchar -> int -> ~int -> bit
3616 werror(W_COMPLEMENT);
3618 /* optimize bit-result, even if we optimize a buggy source */
3619 tree->type = EX_VALUE;
3620 tree->opval.val = constVal ("1");
3623 tree->left = addCast (tree->left, resultType, TRUE);
3625 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3628 /*------------------------------------------------------------------*/
3629 /*----------------------------*/
3631 /*----------------------------*/
3633 /* can be pointer */
3634 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3635 !IS_PTR (LTYPE (tree)) &&
3636 !IS_ARRAY (LTYPE (tree)))
3638 werror (E_UNARY_OP, tree->opval.op);
3639 goto errorTreeReturn;
3642 /* if left is another '!' */
3643 if (tree->left->opval.op == '!')
3645 /* remove double '!!X' by 'X ? 1 : 0' */
3646 tree->opval.op = '?';
3647 tree->left = tree->left->left;
3648 tree->right = newNode (':',
3649 newAst_VALUE (constVal ("1")),
3650 newAst_VALUE (constVal ("0")));
3651 tree->right->lineno = tree->lineno;
3652 tree->decorated = 0;
3653 return decorateType (tree, resultType);
3656 /* if left is a literal then do it */
3657 if (IS_LITERAL (LTYPE (tree)))
3659 tree->type = EX_VALUE;
3660 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3662 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3666 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3669 /*------------------------------------------------------------------*/
3670 /*----------------------------*/
3672 /*----------------------------*/
3676 TTYPE (tree) = LTYPE (tree);
3677 TETYPE (tree) = LETYPE (tree);
3682 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
3686 TTYPE (tree) = TETYPE (tree) = newCharLink();
3690 TTYPE (tree) = TETYPE (tree) = newIntLink();
3695 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3697 werror (E_SHIFT_OP_INVALID);
3698 werror (W_CONTINUE, "left & right types are ");
3699 printTypeChain (LTYPE (tree), stderr);
3700 fprintf (stderr, ",");
3701 printTypeChain (RTYPE (tree), stderr);
3702 fprintf (stderr, "\n");
3703 goto errorTreeReturn;
3706 /* make smaller type only if it's a LEFT_OP */
3707 if (tree->opval.op == LEFT_OP)
3708 tree->left = addCast (tree->left, resultType, TRUE);
3710 /* if they are both literal then */
3711 /* rewrite the tree */
3712 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3714 tree->type = EX_VALUE;
3715 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3716 valFromType (RETYPE (tree)),
3717 (tree->opval.op == LEFT_OP ? 1 : 0));
3718 tree->right = tree->left = NULL;
3719 TETYPE (tree) = getSpec (TTYPE (tree) =
3720 tree->opval.val->type);
3724 /* see if this is a GETBYTE operation if yes
3727 ast *otree = optimizeGetByte (tree, resultType);
3730 return decorateType (otree, RESULT_TYPE_NONE);
3733 /* see if this is a GETWORD operation if yes
3736 ast *otree = optimizeGetWord (tree, resultType);
3739 return decorateType (otree, RESULT_TYPE_NONE);
3742 LRVAL (tree) = RRVAL (tree) = 1;
3743 if (tree->opval.op == LEFT_OP)
3745 TETYPE (tree) = getSpec (TTYPE (tree) =
3746 computeType (LTYPE (tree),
3753 /* no promotion necessary */
3754 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3755 if (IS_LITERAL (TTYPE (tree)))
3756 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3759 /* if only the right side is a literal & we are
3760 shifting more than size of the left operand then zero */
3761 if (IS_LITERAL (RTYPE (tree)) &&
3762 ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
3763 (getSize (TETYPE (tree)) * 8))
3765 if (tree->opval.op==LEFT_OP ||
3766 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3768 lineno=tree->lineno;
3769 werror (W_SHIFT_CHANGED,
3770 (tree->opval.op == LEFT_OP ? "left" : "right"));
3771 tree->type = EX_VALUE;
3772 tree->left = tree->right = NULL;
3773 tree->opval.val = constVal ("0");
3774 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3781 /*------------------------------------------------------------------*/
3782 /*----------------------------*/
3784 /*----------------------------*/
3785 case CAST: /* change the type */
3786 /* cannot cast to an aggregate type */
3787 if (IS_AGGREGATE (LTYPE (tree)))
3789 werror (E_CAST_ILLEGAL);
3790 goto errorTreeReturn;
3793 /* make sure the type is complete and sane */
3794 changePointer(LTYPE(tree));
3795 checkTypeSanity(LETYPE(tree), "(cast)");
3797 /* if 'from' and 'to' are the same remove the superfluous cast, */
3798 /* this helps other optimizations */
3799 if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
3804 /* If code memory is read only, then pointers to code memory */
3805 /* implicitly point to constants -- make this explicit */
3807 sym_link *t = LTYPE(tree);
3808 while (t && t->next)
3810 if (IS_CODEPTR(t) && port->mem.code_ro)
3812 if (IS_SPEC(t->next))
3813 SPEC_CONST (t->next) = 1;
3815 DCL_PTR_CONST (t->next) = 1;
3822 /* if the right is a literal replace the tree */
3823 if (IS_LITERAL (RETYPE (tree))) {
3824 if (!IS_PTR (LTYPE (tree))) {
3825 tree->type = EX_VALUE;
3827 valCastLiteral (LTYPE (tree),
3828 floatFromVal (valFromType (RETYPE (tree))));
3831 TTYPE (tree) = tree->opval.val->type;
3832 tree->values.literalFromCast = 1;
3833 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3834 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3835 sym_link *rest = LTYPE(tree)->next;
3836 werror(W_LITERAL_GENERIC);
3837 TTYPE(tree) = newLink(DECLARATOR);
3838 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3839 TTYPE(tree)->next = rest;
3840 tree->left->opval.lnk = TTYPE(tree);
3843 TTYPE (tree) = LTYPE (tree);
3847 TTYPE (tree) = LTYPE (tree);
3851 #if 0 // this is already checked, now this could be explicit
3852 /* if pointer to struct then check names */
3853 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3854 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3855 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3857 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3858 SPEC_STRUCT(LETYPE(tree))->tag);
3861 if (IS_ADDRESS_OF_OP(tree->right)
3862 && IS_AST_SYM_VALUE (tree->right->left)
3863 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3865 symbol * sym = AST_SYMBOL (tree->right->left);
3866 unsigned int gptype = 0;
3867 unsigned int addr = SPEC_ADDR (sym->etype);
3869 if (IS_GENPTR (LTYPE (tree)) && ((GPTRSIZE > FPTRSIZE)
3870 || TARGET_IS_PIC16) )
3872 switch (SPEC_SCLS (sym->etype))
3875 gptype = GPTYPE_CODE;
3878 gptype = GPTYPE_FAR;
3882 gptype = GPTYPE_NEAR;
3885 gptype = GPTYPE_XSTACK;
3890 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3891 gptype = GPTYPE_NEAR;
3893 addr |= gptype << (8*(GPTRSIZE - 1));
3896 tree->type = EX_VALUE;
3898 valCastLiteral (LTYPE (tree), addr);
3899 TTYPE (tree) = tree->opval.val->type;
3900 TETYPE (tree) = getSpec (TTYPE (tree));
3903 tree->values.literalFromCast = 1;
3907 /* handle offsetof macro: */
3908 /* #define offsetof(TYPE, MEMBER) \ */
3909 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3910 if (IS_ADDRESS_OF_OP(tree->right)
3911 && IS_AST_OP (tree->right->left)
3912 && tree->right->left->opval.op == PTR_OP
3913 && IS_AST_OP (tree->right->left->left)
3914 && tree->right->left->left->opval.op == CAST
3915 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3917 symbol *element = getStructElement (
3918 SPEC_STRUCT (LETYPE(tree->right->left)),
3919 AST_SYMBOL(tree->right->left->right)
3923 tree->type = EX_VALUE;
3924 tree->opval.val = valCastLiteral (
3927 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3930 TTYPE (tree) = tree->opval.val->type;
3931 TETYPE (tree) = getSpec (TTYPE (tree));
3938 /* if the right is a literal replace the tree */
3939 if (IS_LITERAL (RETYPE (tree))) {
3941 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3942 /* rewrite (type *)litaddr
3944 and define type at litaddr temp
3945 (but only if type's storage class is not generic)
3947 ast *newTree = newNode ('&', NULL, NULL);
3950 TTYPE (newTree) = LTYPE (tree);
3951 TETYPE (newTree) = getSpec(LTYPE (tree));
3953 /* define a global symbol at the casted address*/
3954 sym = newSymbol(genSymName (0), 0);
3955 sym->type = LTYPE (tree)->next;
3957 sym->type = newLink (V_VOID);
3958 sym->etype = getSpec(sym->type);
3959 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3960 sym->lineDef = tree->lineno;
3963 SPEC_STAT (sym->etype) = 1;
3964 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3965 SPEC_ABSA(sym->etype) = 1;
3966 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3969 newTree->left = newAst_VALUE(symbolVal(sym));
3970 newTree->left->lineno = tree->lineno;
3971 LTYPE (newTree) = sym->type;
3972 LETYPE (newTree) = sym->etype;
3973 LLVAL (newTree) = 1;
3974 LRVAL (newTree) = 0;
3975 TLVAL (newTree) = 1;
3979 if (!IS_PTR (LTYPE (tree))) {
3980 tree->type = EX_VALUE;
3982 valCastLiteral (LTYPE (tree),
3983 floatFromVal (valFromType (RTYPE (tree))));
3984 TTYPE (tree) = tree->opval.val->type;
3987 tree->values.literalFromCast = 1;
3988 TETYPE (tree) = getSpec (TTYPE (tree));
3992 TTYPE (tree) = LTYPE (tree);
3996 TETYPE (tree) = getSpec (TTYPE (tree));
4000 /*------------------------------------------------------------------*/
4001 /*----------------------------*/
4002 /* logical &&, || */
4003 /*----------------------------*/
4006 /* each must be arithmetic type or be a pointer */
4007 if (!IS_PTR (LTYPE (tree)) &&
4008 !IS_ARRAY (LTYPE (tree)) &&
4009 !IS_INTEGRAL (LTYPE (tree)))
4011 werror (E_COMPARE_OP);
4012 goto errorTreeReturn;
4015 if (!IS_PTR (RTYPE (tree)) &&
4016 !IS_ARRAY (RTYPE (tree)) &&
4017 !IS_INTEGRAL (RTYPE (tree)))
4019 werror (E_COMPARE_OP);
4020 goto errorTreeReturn;
4022 /* if they are both literal then */
4023 /* rewrite the tree */
4024 if (IS_LITERAL (RTYPE (tree)) &&
4025 IS_LITERAL (LTYPE (tree)))
4027 tree->type = EX_VALUE;
4028 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4029 valFromType (RTYPE (tree)),
4031 tree->right = tree->left = NULL;
4032 TETYPE (tree) = getSpec (TTYPE (tree) =
4033 tree->opval.val->type);
4036 LRVAL (tree) = RRVAL (tree) = 1;
4037 TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4040 /*------------------------------------------------------------------*/
4041 /*----------------------------*/
4042 /* comparison operators */
4043 /*----------------------------*/
4051 ast *lt = optimizeCompare (tree);
4057 /* if they are pointers they must be castable */
4058 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4060 if (tree->opval.op==EQ_OP &&
4061 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4062 // we cannot cast a gptr to a !gptr: switch the leaves
4063 struct ast *s=tree->left;
4064 tree->left=tree->right;
4067 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4069 werror (E_COMPARE_OP);
4070 fprintf (stderr, "comparing type ");
4071 printTypeChain (LTYPE (tree), stderr);
4072 fprintf (stderr, "to type ");
4073 printTypeChain (RTYPE (tree), stderr);
4074 fprintf (stderr, "\n");
4075 goto errorTreeReturn;
4078 /* else they should be promotable to one another */
4081 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4082 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4084 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4086 werror (E_COMPARE_OP);
4087 fprintf (stderr, "comparing type ");
4088 printTypeChain (LTYPE (tree), stderr);
4089 fprintf (stderr, "to type ");
4090 printTypeChain (RTYPE (tree), stderr);
4091 fprintf (stderr, "\n");
4092 goto errorTreeReturn;
4097 CCR_RESULT ccr_result = CCR_OK;
4099 /* if left is integral and right is literal
4100 then check constant range */
4101 if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4102 ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4103 tree->opval.op, FALSE);
4104 if (ccr_result == CCR_OK &&
4105 IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4106 ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4107 tree->opval.op, TRUE);
4110 case CCR_ALWAYS_TRUE:
4111 case CCR_ALWAYS_FALSE:
4112 if (!options.lessPedantic)
4113 werror (W_COMP_RANGE,
4114 ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4115 return decorateType (newAst_VALUE (constVal (
4116 ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4124 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4125 if (tree->opval.op == '>' &&
4126 SPEC_USIGN(LETYPE(tree)) &&
4127 IS_LITERAL(RTYPE(tree)) &&
4128 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
4130 if (resultType == RESULT_TYPE_IFX)
4132 /* the parent is an ifx: */
4133 /* if (unsigned value) */
4137 /* (unsigned value) ? 1 : 0 */
4138 tree->opval.op = '?';
4139 tree->right = newNode (':',
4140 newAst_VALUE (constVal ("1")),
4141 tree->right); /* val 0 */
4142 tree->right->lineno = tree->lineno;
4143 tree->right->left->lineno = tree->lineno;
4144 tree->decorated = 0;
4145 return decorateType (tree, resultType);
4148 /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4149 if (IS_LITERAL(RTYPE(tree)) &&
4150 floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4151 tree->opval.op == EQ_OP &&
4152 resultType == RESULT_TYPE_IFX)
4154 tree->opval.op = '!';
4156 tree->decorated = 0;
4157 return decorateType (tree, resultType);
4160 /* if they are both literal then */
4161 /* rewrite the tree */
4162 if (IS_LITERAL (RTYPE (tree)) &&
4163 IS_LITERAL (LTYPE (tree)))
4165 tree->type = EX_VALUE;
4166 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4167 valFromType (RETYPE (tree)),
4169 tree->right = tree->left = NULL;
4170 TETYPE (tree) = getSpec (TTYPE (tree) =
4171 tree->opval.val->type);
4175 /* if one is 'signed char ' and the other one is 'unsigned char' */
4176 /* it's necessary to promote to int */
4177 if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4178 (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4180 /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4181 if it's possible to use a 'signed char' */
4183 /* is left a 'unsigned char'? */
4184 if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4185 /* the value range of a 'unsigned char' is 0...255;
4186 if the actual value is < 128 it can be changed to signed */
4187 (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
4189 /* now we've got 2 'signed char'! */
4190 SPEC_USIGN (RETYPE (tree)) = 0;
4192 /* same test for the left operand: */
4193 else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4194 (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4196 SPEC_USIGN (LETYPE (tree)) = 0;
4200 werror (W_CMP_SU_CHAR);
4201 tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4202 tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4206 LRVAL (tree) = RRVAL (tree) = 1;
4207 TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4209 /* condition transformations */
4211 unsigned transformedOp = 0;
4213 switch (tree->opval.op)
4215 case '<': /* transform (a < b) to !(a >= b) */
4217 transformedOp = GE_OP;
4219 case '>': /* transform (a > b) to !(a <= b) */
4221 transformedOp = LE_OP;
4223 case LE_OP: /* transform (a <= b) to !(a > b) */
4225 transformedOp = '>';
4227 case GE_OP: /* transform (a >= b) to !(a < b) */
4229 transformedOp = '<';
4231 case NE_OP: /* transform (a != b) to !(a == b) */
4233 transformedOp = EQ_OP;
4235 case EQ_OP: /* transform (a == b) to !(a != b) */
4237 transformedOp = NE_OP;
4244 tree->opval.op = transformedOp;
4245 tree->decorated = 0;
4246 tree = newNode ('!', tree, NULL);
4247 tree->lineno = tree->left->lineno;
4248 return decorateType (tree, resultType);
4254 /*------------------------------------------------------------------*/
4255 /*----------------------------*/
4257 /*----------------------------*/
4258 case SIZEOF: /* evaluate wihout code generation */
4259 /* change the type to a integer */
4261 int size = getSize (tree->right->ftype);
4262 SNPRINTF(buffer, sizeof(buffer), "%d", size);
4263 if (!size && !IS_VOID(tree->right->ftype))
4264 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4266 tree->type = EX_VALUE;
4267 tree->opval.val = constVal (buffer);
4268 tree->right = tree->left = NULL;
4269 TETYPE (tree) = getSpec (TTYPE (tree) =
4270 tree->opval.val->type);
4273 /*------------------------------------------------------------------*/
4274 /*----------------------------*/
4276 /*----------------------------*/
4278 /* return typeof enum value */
4279 tree->type = EX_VALUE;
4282 if (IS_SPEC(tree->right->ftype)) {
4283 switch (SPEC_NOUN(tree->right->ftype)) {
4285 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4286 else typeofv = TYPEOF_INT;
4289 typeofv = TYPEOF_FLOAT;
4292 typeofv = TYPEOF_FIXED16X16;
4295 typeofv = TYPEOF_CHAR;
4298 typeofv = TYPEOF_VOID;
4301 typeofv = TYPEOF_STRUCT;
4304 typeofv = TYPEOF_BITFIELD;
4307 typeofv = TYPEOF_BIT;
4310 typeofv = TYPEOF_SBIT;
4316 switch (DCL_TYPE(tree->right->ftype)) {
4318 typeofv = TYPEOF_POINTER;
4321 typeofv = TYPEOF_FPOINTER;
4324 typeofv = TYPEOF_CPOINTER;
4327 typeofv = TYPEOF_GPOINTER;
4330 typeofv = TYPEOF_PPOINTER;
4333 typeofv = TYPEOF_IPOINTER;
4336 typeofv = TYPEOF_ARRAY;
4339 typeofv = TYPEOF_FUNCTION;
4345 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4346 tree->opval.val = constVal (buffer);
4347 tree->right = tree->left = NULL;
4348 TETYPE (tree) = getSpec (TTYPE (tree) =
4349 tree->opval.val->type);
4352 /*------------------------------------------------------------------*/
4353 /*----------------------------*/
4354 /* conditional operator '?' */
4355 /*----------------------------*/
4357 /* the type is value of the colon operator (on the right) */
4358 assert (IS_COLON_OP (tree->right));
4359 /* if already known then replace the tree : optimizer will do it
4360 but faster to do it here */
4361 if (IS_LITERAL (LTYPE (tree)))
4363 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4364 return decorateType (tree->right->left, resultTypeProp);
4366 return decorateType (tree->right->right, resultTypeProp);
4370 tree->right = decorateType (tree->right, resultTypeProp);
4371 TTYPE (tree) = RTYPE (tree);
4372 TETYPE (tree) = getSpec (TTYPE (tree));
4377 /* if they don't match we have a problem */
4378 if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4379 (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4381 werror (E_TYPE_MISMATCH, "conditional operator", " ");
4382 goto errorTreeReturn;
4385 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4386 resultType, tree->opval.op);
4387 TETYPE (tree) = getSpec (TTYPE (tree));
4391 #if 0 // assignment operators are converted by the parser
4392 /*------------------------------------------------------------------*/
4393 /*----------------------------*/
4394 /* assignment operators */
4395 /*----------------------------*/
4398 /* for these it must be both must be integral */
4399 if (!IS_ARITHMETIC (LTYPE (tree)) ||
4400 !IS_ARITHMETIC (RTYPE (tree)))
4402 werror (E_OPS_INTEGRAL);
4403 goto errorTreeReturn;
4406 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4408 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4409 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4413 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4414 goto errorTreeReturn;
4425 /* for these it must be both must be integral */
4426 if (!IS_INTEGRAL (LTYPE (tree)) ||
4427 !IS_INTEGRAL (RTYPE (tree)))
4429 werror (E_OPS_INTEGRAL);
4430 goto errorTreeReturn;
4433 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4435 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4436 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4440 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4441 goto errorTreeReturn;
4447 /*------------------------------------------------------------------*/
4448 /*----------------------------*/
4450 /*----------------------------*/
4452 if (!(IS_PTR (LTYPE (tree)) ||
4453 IS_ARITHMETIC (LTYPE (tree))))
4455 werror (E_PLUS_INVALID, "-=");
4456 goto errorTreeReturn;
4459 if (!(IS_PTR (RTYPE (tree)) ||
4460 IS_ARITHMETIC (RTYPE (tree))))
4462 werror (E_PLUS_INVALID, "-=");
4463 goto errorTreeReturn;
4466 TETYPE (tree) = getSpec (TTYPE (tree) =
4467 computeType (LTYPE (tree),
4472 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4473 werror (E_CODE_WRITE, "-=");
4477 werror (E_LVALUE_REQUIRED, "-=");
4478 goto errorTreeReturn;
4484 /*------------------------------------------------------------------*/
4485 /*----------------------------*/
4487 /*----------------------------*/
4489 /* this is not a unary operation */
4490 /* if both pointers then problem */
4491 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4493 werror (E_PTR_PLUS_PTR);
4494 goto errorTreeReturn;
4497 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4499 werror (E_PLUS_INVALID, "+=");
4500 goto errorTreeReturn;
4503 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4505 werror (E_PLUS_INVALID, "+=");
4506 goto errorTreeReturn;
4509 TETYPE (tree) = getSpec (TTYPE (tree) =
4510 computeType (LTYPE (tree),
4515 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4516 werror (E_CODE_WRITE, "+=");
4520 werror (E_LVALUE_REQUIRED, "+=");
4521 goto errorTreeReturn;
4524 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4525 tree->opval.op = '=';
4530 /*------------------------------------------------------------------*/
4531 /*----------------------------*/
4532 /* straight assignemnt */
4533 /*----------------------------*/
4535 /* cannot be an aggregate */
4536 if (IS_AGGREGATE (LTYPE (tree)))
4538 werror (E_AGGR_ASSIGN);
4539 goto errorTreeReturn;
4542 /* they should either match or be castable */
4543 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4545 werror (E_TYPE_MISMATCH, "assignment", " ");
4546 printFromToType(RTYPE(tree),LTYPE(tree));
4549 /* if the left side of the tree is of type void
4550 then report error */
4551 if (IS_VOID (LTYPE (tree)))
4553 werror (E_CAST_ZERO);
4554 printFromToType(RTYPE(tree), LTYPE(tree));
4557 TETYPE (tree) = getSpec (TTYPE (tree) =
4561 if (!tree->initMode ) {
4562 if (IS_CONSTANT(LTYPE(tree)))
4563 werror (E_CODE_WRITE, "=");
4567 werror (E_LVALUE_REQUIRED, "=");
4568 goto errorTreeReturn;
4573 /*------------------------------------------------------------------*/
4574 /*----------------------------*/
4575 /* comma operator */
4576 /*----------------------------*/
4578 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4581 /*------------------------------------------------------------------*/
4582 /*----------------------------*/
4584 /*----------------------------*/
4587 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4588 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4590 if (tree->left->opval.op == '*' && !tree->left->right)
4591 tree->left = tree->left->left;
4594 /* require a function or pointer to function */
4595 if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4597 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4598 goto errorTreeReturn;
4601 /* if there are parms, make sure that
4602 parms are decorate / process / reverse only once */
4604 !tree->right->decorated)
4609 if (IS_FUNCPTR (LTYPE (tree)))
4611 functype = LTYPE (tree)->next;
4612 processFuncPtrArgs (functype);
4615 functype = LTYPE (tree);
4617 if (processParms (tree->left, FUNC_ARGS(functype),
4618 &tree->right, &parmNumber, TRUE))
4620 goto errorTreeReturn;
4623 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4624 !IFFUNC_ISBUILTIN(functype))
4626 reverseParms (tree->right);
4629 TTYPE (tree) = functype->next;
4630 TETYPE (tree) = getSpec (TTYPE (tree));
4634 /*------------------------------------------------------------------*/
4635 /*----------------------------*/
4636 /* return statement */
4637 /*----------------------------*/
4642 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4644 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4645 printFromToType (RTYPE(tree), currFunc->type->next);
4646 goto errorTreeReturn;
4649 if (IS_VOID (currFunc->type->next)
4651 !IS_VOID (RTYPE (tree)))
4653 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4654 goto errorTreeReturn;
4657 /* if there is going to be a casting required then add it */
4658 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4661 decorateType (newNode (CAST,
4662 newAst_LINK (copyLinkChain (currFunc->type->next)),
4672 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4674 werror (W_VOID_FUNC, currFunc->name);
4675 goto errorTreeReturn;
4678 TTYPE (tree) = TETYPE (tree) = NULL;
4681 /*------------------------------------------------------------------*/
4682 /*----------------------------*/
4683 /* switch statement */
4684 /*----------------------------*/
4686 /* the switch value must be an integer */
4687 if (!IS_INTEGRAL (LTYPE (tree)))
4689 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4690 goto errorTreeReturn;
4693 TTYPE (tree) = TETYPE (tree) = NULL;
4696 /*------------------------------------------------------------------*/
4697 /*----------------------------*/
4699 /*----------------------------*/
4701 tree->left = backPatchLabels (tree->left,
4704 TTYPE (tree) = TETYPE (tree) = NULL;
4707 /*------------------------------------------------------------------*/
4708 /*----------------------------*/
4710 /*----------------------------*/
4713 AST_FOR (tree, initExpr) = decorateType (
4714 resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4715 AST_FOR (tree, condExpr) = decorateType (
4716 resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4717 AST_FOR (tree, loopExpr) = decorateType (
4718 resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4720 /* if the for loop is reversible then
4721 reverse it otherwise do what we normally
4727 if (isLoopReversible (tree, &sym, &init, &end))
4728 return reverseLoop (tree, sym, init, end);
4730 return decorateType (createFor (AST_FOR (tree, trueLabel),
4731 AST_FOR (tree, continueLabel),
4732 AST_FOR (tree, falseLabel),
4733 AST_FOR (tree, condLabel),
4734 AST_FOR (tree, initExpr),
4735 AST_FOR (tree, condExpr),
4736 AST_FOR (tree, loopExpr),
4737 tree->left), RESULT_TYPE_NONE);
4740 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4741 "node PARAM shouldn't be processed here");
4742 /* but in processParams() */
4745 TTYPE (tree) = TETYPE (tree) = NULL;
4749 /* some error found this tree will be killed */
4751 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4752 tree->opval.op = NULLOP;
4758 /*-----------------------------------------------------------------*/
4759 /* sizeofOp - processes size of operation */
4760 /*-----------------------------------------------------------------*/
4762 sizeofOp (sym_link * type)
4767 /* make sure the type is complete and sane */
4768 checkTypeSanity(type, "(sizeof)");
4770 /* get the size and convert it to character */
4771 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4772 if (!size && !IS_VOID(type))
4773 werror (E_SIZEOF_INCOMPLETE_TYPE);
4775 /* now convert into value */
4776 return constVal (buff);
4780 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4781 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4782 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4783 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4784 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4785 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4786 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4788 /*-----------------------------------------------------------------*/
4789 /* backPatchLabels - change and or not operators to flow control */
4790 /*-----------------------------------------------------------------*/
4792 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4798 /* while-loops insert a label between the IFX and the condition,
4799 therefore look behind the label too */
4800 if (tree->opval.op == LABEL &&
4802 IS_ANDORNOT (tree->right))
4804 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4808 if (!(IS_ANDORNOT (tree)))
4811 /* if this an and */
4814 static int localLbl = 0;
4817 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4818 localLabel = newSymbol (buffer, NestLevel);
4820 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4822 /* if left is already a IFX then just change the if true label in that */
4823 if (!IS_IFX (tree->left))
4824 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4826 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4827 /* right is a IFX then just join */
4828 if (IS_IFX (tree->right))
4829 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4831 tree->right = createLabel (localLabel, tree->right);
4832 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4834 return newNode (NULLOP, tree->left, tree->right);
4837 /* if this is an or operation */
4840 static int localLbl = 0;
4843 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4844 localLabel = newSymbol (buffer, NestLevel);
4846 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4848 /* if left is already a IFX then just change the if true label in that */
4849 if (!IS_IFX (tree->left))
4850 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4852 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4853 /* right is a IFX then just join */
4854 if (IS_IFX (tree->right))
4855 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4857 tree->right = createLabel (localLabel, tree->right);
4858 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4860 return newNode (NULLOP, tree->left, tree->right);
4866 /* call with exchanged labels */
4867 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4869 /* if left isn't already a IFX */
4870 if (!IS_IFX (tree->left))
4872 tree->left = newNode (IFX, tree->left, NULL);
4873 tree->left->trueLabel = falseLabel;
4874 tree->left->falseLabel = trueLabel;
4881 tree->trueLabel = trueLabel;
4882 tree->falseLabel = falseLabel;
4889 /*-----------------------------------------------------------------*/
4890 /* createBlock - create expression tree for block */
4891 /*-----------------------------------------------------------------*/
4893 createBlock (symbol * decl, ast * body)
4897 /* if the block has nothing */
4901 ex = newNode (BLOCK, NULL, body);
4902 ex->values.sym = decl;
4909 /*-----------------------------------------------------------------*/
4910 /* createLabel - creates the expression tree for labels */
4911 /*-----------------------------------------------------------------*/
4913 createLabel (symbol * label, ast * stmnt)
4916 char name[SDCC_NAME_MAX + 1];
4919 /* must create fresh symbol if the symbol name */
4920 /* exists in the symbol table, since there can */
4921 /* be a variable with the same name as the labl */
4922 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4923 (csym->level == label->level))
4924 label = newSymbol (label->name, label->level);
4926 /* change the name before putting it in add _ */
4927 SNPRINTF(name, sizeof(name), "%s", label->name);
4929 /* put the label in the LabelSymbol table */
4930 /* but first check if a label of the same */
4932 if ((csym = findSym (LabelTab, NULL, name)))
4933 werror (E_DUPLICATE_LABEL, label->name);
4935 addSym (LabelTab, label, name, label->level, 0, 0);
4939 label->key = labelKey++;
4940 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4946 /*-----------------------------------------------------------------*/
4947 /* createCase - generates the parsetree for a case statement */
4948 /*-----------------------------------------------------------------*/
4950 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4952 char caseLbl[SDCC_NAME_MAX + 1];
4956 /* if the switch statement does not exist */
4957 /* then case is out of context */
4960 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4964 caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4965 /* if not a constant then error */
4966 if (!IS_LITERAL (caseVal->ftype))
4968 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4972 /* if not a integer than error */
4973 if (!IS_INTEGRAL (caseVal->ftype))
4975 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4979 /* find the end of the switch values chain */
4980 if (!(val = swStat->values.switchVals.swVals))
4981 swStat->values.switchVals.swVals = caseVal->opval.val;
4984 /* also order the cases according to value */
4986 int cVal = (int) floatFromVal (caseVal->opval.val);
4987 while (val && (int) floatFromVal (val) < cVal)
4993 /* if we reached the end then */
4996 pval->next = caseVal->opval.val;
4998 else if ((int) floatFromVal (val) == cVal)
5000 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5006 /* we found a value greater than */
5007 /* the current value we must add this */
5008 /* before the value */
5009 caseVal->opval.val->next = val;
5011 /* if this was the first in chain */
5012 if (swStat->values.switchVals.swVals == val)
5013 swStat->values.switchVals.swVals =
5016 pval->next = caseVal->opval.val;
5021 /* create the case label */
5022 SNPRINTF(caseLbl, sizeof(caseLbl),
5024 swStat->values.switchVals.swNum,
5025 (int) floatFromVal (caseVal->opval.val));
5027 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5032 /*-----------------------------------------------------------------*/
5033 /* createDefault - creates the parse tree for the default statement */
5034 /*-----------------------------------------------------------------*/
5036 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5038 char defLbl[SDCC_NAME_MAX + 1];
5040 /* if the switch statement does not exist */
5041 /* then case is out of context */
5044 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5048 if (swStat->values.switchVals.swDefault)
5050 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5055 /* turn on the default flag */
5056 swStat->values.switchVals.swDefault = 1;
5058 /* create the label */
5059 SNPRINTF (defLbl, sizeof(defLbl),
5060 "_default_%d", swStat->values.switchVals.swNum);
5061 return createLabel (newSymbol (defLbl, 0), stmnt);
5064 /*-----------------------------------------------------------------*/
5065 /* createIf - creates the parsetree for the if statement */
5066 /*-----------------------------------------------------------------*/
5068 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5070 static int Lblnum = 0;
5072 symbol *ifTrue, *ifFalse, *ifEnd;
5074 /* if neither exists */
5075 if (!elseBody && !ifBody) {
5076 // if there are no side effects (i++, j() etc)
5077 if (!hasSEFcalls(condAst)) {
5082 /* create the labels */
5083 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5084 ifFalse = newSymbol (buffer, NestLevel);
5085 /* if no else body then end == false */
5090 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5091 ifEnd = newSymbol (buffer, NestLevel);
5094 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5095 ifTrue = newSymbol (buffer, NestLevel);
5099 /* attach the ifTrue label to the top of it body */
5100 ifBody = createLabel (ifTrue, ifBody);
5101 /* attach a goto end to the ifBody if else is present */
5104 ifBody = newNode (NULLOP, ifBody,
5106 newAst_VALUE (symbolVal (ifEnd)),
5108 /* put the elseLabel on the else body */
5109 elseBody = createLabel (ifFalse, elseBody);
5110 /* out the end at the end of the body */
5111 elseBody = newNode (NULLOP,
5113 createLabel (ifEnd, NULL));
5117 ifBody = newNode (NULLOP, ifBody,
5118 createLabel (ifFalse, NULL));
5120 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5121 if (IS_IFX (condAst))
5124 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5126 return newNode (NULLOP, ifTree,
5127 newNode (NULLOP, ifBody, elseBody));
5131 /*-----------------------------------------------------------------*/
5132 /* createDo - creates parse tree for do */
5135 /* _docontinue_n: */
5136 /* condition_expression +-> trueLabel -> _dobody_n */
5138 /* +-> falseLabel-> _dobreak_n */
5140 /*-----------------------------------------------------------------*/
5142 createDo (symbol * trueLabel, symbol * continueLabel,
5143 symbol * falseLabel, ast * condAst, ast * doBody)
5148 /* if the body does not exist then it is simple */
5151 condAst = backPatchLabels (condAst, continueLabel, falseLabel);
5152 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5153 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5154 doTree->trueLabel = continueLabel;
5155 doTree->falseLabel = NULL;
5157 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5161 /* otherwise we have a body */
5162 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5164 /* attach the body label to the top */
5165 doBody = createLabel (trueLabel, doBody);
5166 /* attach the continue label to end of body */
5167 doBody = newNode (NULLOP, doBody,
5168 createLabel (continueLabel, NULL));
5170 /* now put the break label at the end */
5171 if (IS_IFX (condAst))
5174 doTree = newIfxNode (condAst, trueLabel, falseLabel);
5176 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5178 /* putting it together */
5179 return newNode (NULLOP, doBody, doTree);
5182 /*-----------------------------------------------------------------*/
5183 /* createFor - creates parse tree for 'for' statement */
5186 /* condExpr +-> trueLabel -> _forbody_n */
5188 /* +-> falseLabel-> _forbreak_n */
5191 /* _forcontinue_n: */
5193 /* goto _forcond_n ; */
5195 /*-----------------------------------------------------------------*/
5197 createFor (symbol * trueLabel, symbol * continueLabel,
5198 symbol * falseLabel, symbol * condLabel,
5199 ast * initExpr, ast * condExpr, ast * loopExpr,
5204 /* if loopexpression not present then we can generate it */
5205 /* the same way as a while */
5207 return newNode (NULLOP, initExpr,
5208 createWhile (trueLabel, continueLabel,
5209 falseLabel, condExpr, forBody));
5210 /* vanilla for statement */
5211 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5213 if (condExpr && !IS_IFX (condExpr))
5214 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5217 /* attach condition label to condition */
5218 condExpr = createLabel (condLabel, condExpr);
5220 /* attach body label to body */
5221 forBody = createLabel (trueLabel, forBody);
5223 /* attach continue to forLoop expression & attach */
5224 /* goto the forcond @ and of loopExpression */
5225 loopExpr = createLabel (continueLabel,
5229 newAst_VALUE (symbolVal (condLabel)),
5231 /* now start putting them together */
5232 forTree = newNode (NULLOP, initExpr, condExpr);
5233 forTree = newNode (NULLOP, forTree, forBody);
5234 forTree = newNode (NULLOP, forTree, loopExpr);
5235 /* finally add the break label */
5236 forTree = newNode (NULLOP, forTree,
5237 createLabel (falseLabel, NULL));
5241 /*-----------------------------------------------------------------*/
5242 /* createWhile - creates parse tree for while statement */
5243 /* the while statement will be created as follows */
5245 /* _while_continue_n: */
5246 /* condition_expression +-> trueLabel -> _while_boby_n */
5248 /* +-> falseLabel -> _while_break_n */
5249 /* _while_body_n: */
5251 /* goto _while_continue_n */
5252 /* _while_break_n: */
5253 /*-----------------------------------------------------------------*/
5255 createWhile (symbol * trueLabel, symbol * continueLabel,
5256 symbol * falseLabel, ast * condExpr, ast * whileBody)
5260 /* put the continue label */
5261 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5262 condExpr = createLabel (continueLabel, condExpr);
5263 condExpr->lineno = 0;
5265 /* put the body label in front of the body */
5266 whileBody = createLabel (trueLabel, whileBody);
5267 whileBody->lineno = 0;
5268 /* put a jump to continue at the end of the body */
5269 /* and put break label at the end of the body */
5270 whileBody = newNode (NULLOP,
5273 newAst_VALUE (symbolVal (continueLabel)),
5274 createLabel (falseLabel, NULL)));
5276 /* put it all together */
5277 if (IS_IFX (condExpr))
5278 whileTree = condExpr;
5281 whileTree = newNode (IFX, condExpr, NULL);
5282 /* put the true & false labels in place */
5283 whileTree->trueLabel = trueLabel;
5284 whileTree->falseLabel = falseLabel;
5287 return newNode (NULLOP, whileTree, whileBody);
5290 /*-----------------------------------------------------------------*/
5291 /* isShiftRightLitVal _BitAndLitVal - helper function */
5292 /*-----------------------------------------------------------------*/
5294 isShiftRightLitVal_BitAndLitVal (ast * tree)
5296 /* if this is not a bit and */
5297 if (!IS_BITAND (tree))
5300 /* will look for tree of the form
5301 ( expr >> litval2) & litval1 */
5302 if (!IS_AST_LIT_VALUE (tree->right))
5305 if (!IS_RIGHT_OP (tree->left))
5308 if (!IS_AST_LIT_VALUE (tree->left->right))
5311 return tree->left->left;
5314 /*-----------------------------------------------------------------*/
5315 /* isBitAndPowOf2 - helper function */
5316 /*-----------------------------------------------------------------*/
5318 isBitAndPow2 (ast * tree)
5320 /* if this is not a bit and */
5321 if (!IS_BITAND (tree))
5324 /* will look for tree of the form
5325 ( expr & (1 << litval) */
5326 if (!IS_AST_LIT_VALUE (tree->right))
5329 return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
5332 /*-----------------------------------------------------------------*/
5333 /* optimizeGetHbit - get highest order bit of the expression */
5334 /*-----------------------------------------------------------------*/
5336 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5341 expr = isShiftRightLitVal_BitAndLitVal(tree);
5344 if ((AST_LIT_VALUE (tree->right) != 1) ||
5345 ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5346 (j = (getSize (TTYPE (expr)) * 8 - 1))))
5349 if (!expr && (resultType == RESULT_TYPE_BIT))
5352 if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5358 /* make sure the port supports GETHBIT */
5359 if (port->hasExtBitOp
5360 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5363 return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5366 /*-----------------------------------------------------------------*/
5367 /* optimizeGetAbit - get a single bit of the expression */
5368 /*-----------------------------------------------------------------*/
5370 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5375 expr = isShiftRightLitVal_BitAndLitVal(tree);
5378 if (AST_LIT_VALUE (tree->right) != 1)
5380 count = tree->left->right;
5382 if (!expr && (resultType == RESULT_TYPE_BIT))
5384 int p2 = isBitAndPow2 (tree);
5388 count = newAst_VALUE (valueFromLit (p2));
5394 /* make sure the port supports GETABIT */
5395 if (port->hasExtBitOp
5396 && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5399 return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5403 /*-----------------------------------------------------------------*/
5404 /* optimizeGetByte - get a byte of the expression */
5405 /*-----------------------------------------------------------------*/
5407 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5413 expr = isShiftRightLitVal_BitAndLitVal(tree);
5416 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5417 count = tree->left->right;
5418 if (AST_LIT_VALUE (tree->right) != 0xFF)
5421 if (!expr && resultType == RESULT_TYPE_CHAR)
5423 /* if this is a right shift over a multiple of 8 */
5424 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5426 i = (unsigned int) AST_LIT_VALUE (tree->right);
5427 count = tree->right;
5431 if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5434 /* make sure the port supports GETBYTE */
5435 if (port->hasExtBitOp
5436 && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5439 return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5442 /*-----------------------------------------------------------------*/
5443 /* optimizeGetWord - get two bytes of the expression */
5444 /*-----------------------------------------------------------------*/
5446 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5452 expr = isShiftRightLitVal_BitAndLitVal(tree);
5455 i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5456 count = tree->left->right;
5457 if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5460 if (!expr && resultType == RESULT_TYPE_INT)
5462 /* if this is a right shift over a multiple of 8 */
5463 if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5465 i = (unsigned int) AST_LIT_VALUE (tree->right);
5466 count = tree->right;
5470 if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5473 /* make sure the port supports GETWORD */
5474 if (port->hasExtBitOp
5475 && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5478 return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5481 /*-----------------------------------------------------------------*/
5482 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
5483 /*-----------------------------------------------------------------*/
5485 optimizeRRCRLC (ast * root)
5487 /* will look for trees of the form
5488 (?expr << 1) | (?expr >> 7) or
5489 (?expr >> 7) | (?expr << 1) will make that
5490 into a RLC : operation ..
5492 (?expr >> 1) | (?expr << 7) or
5493 (?expr << 7) | (?expr >> 1) will make that
5494 into a RRC operation
5495 note : by 7 I mean (number of bits required to hold the
5497 /* if the root operation is not a | operation then not */
5498 if (!IS_BITOR (root))
5501 /* I have to think of a better way to match patterns this sucks */
5502 /* that aside let's start looking for the first case : I use a
5503 negative check a lot to improve the efficiency */
5504 /* (?expr << 1) | (?expr >> 7) */
5505 if (IS_LEFT_OP (root->left) &&
5506 IS_RIGHT_OP (root->right))
5509 if (!SPEC_USIGN (TETYPE (root->left->left)))
5512 if (!IS_AST_LIT_VALUE (root->left->right) ||
5513 !IS_AST_LIT_VALUE (root->right->right))
5516 /* make sure it is the same expression */
5517 if (!isAstEqual (root->left->left,
5521 if (AST_LIT_VALUE (root->left->right) != 1)
5524 if (AST_LIT_VALUE (root->right->right) !=
5525 (getSize (TTYPE (root->left->left)) * 8 - 1))
5528 /* make sure the port supports RLC */
5529 if (port->hasExtBitOp
5530 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5533 /* whew got the first case : create the AST */
5534 return newNode (RLC, root->left->left, NULL);
5538 /* check for second case */
5539 /* (?expr >> 7) | (?expr << 1) */
5540 if (IS_LEFT_OP (root->right) &&
5541 IS_RIGHT_OP (root->left))
5544 if (!SPEC_USIGN (TETYPE (root->left->left)))
5547 if (!IS_AST_LIT_VALUE (root->left->right) ||
5548 !IS_AST_LIT_VALUE (root->right->right))
5551 /* make sure it is the same symbol */
5552 if (!isAstEqual (root->left->left,
5556 if (AST_LIT_VALUE (root->right->right) != 1)
5559 if (AST_LIT_VALUE (root->left->right) !=
5560 (getSize (TTYPE (root->left->left)) * 8 - 1))
5563 /* make sure the port supports RLC */
5564 if (port->hasExtBitOp
5565 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5568 /* whew got the first case : create the AST */
5569 return newNode (RLC, root->left->left, NULL);
5574 /* third case for RRC */
5575 /* (?symbol >> 1) | (?symbol << 7) */
5576 if (IS_LEFT_OP (root->right) &&
5577 IS_RIGHT_OP (root->left))
5580 if (!SPEC_USIGN (TETYPE (root->left->left)))
5583 if (!IS_AST_LIT_VALUE (root->left->right) ||
5584 !IS_AST_LIT_VALUE (root->right->right))
5587 /* make sure it is the same symbol */
5588 if (!isAstEqual (root->left->left,
5592 if (AST_LIT_VALUE (root->left->right) != 1)
5595 if (AST_LIT_VALUE (root->right->right) !=
5596 (getSize (TTYPE (root->left->left)) * 8 - 1))
5599 /* make sure the port supports RRC */
5600 if (port->hasExtBitOp
5601 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5604 /* whew got the first case : create the AST */
5605 return newNode (RRC, root->left->left, NULL);
5609 /* fourth and last case for now */
5610 /* (?symbol << 7) | (?symbol >> 1) */
5611 if (IS_RIGHT_OP (root->right) &&
5612 IS_LEFT_OP (root->left))
5615 if (!SPEC_USIGN (TETYPE (root->left->left)))
5618 if (!IS_AST_LIT_VALUE (root->left->right) ||
5619 !IS_AST_LIT_VALUE (root->right->right))
5622 /* make sure it is the same symbol */
5623 if (!isAstEqual (root->left->left,
5627 if (AST_LIT_VALUE (root->right->right) != 1)
5630 if (AST_LIT_VALUE (root->left->right) !=
5631 (getSize (TTYPE (root->left->left)) * 8 - 1))
5634 /* make sure the port supports RRC */
5635 if (port->hasExtBitOp
5636 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5639 /* whew got the first case : create the AST */
5640 return newNode (RRC, root->left->left, NULL);
5644 /* not found return root */
5648 /*-----------------------------------------------------------------*/
5649 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
5650 /*-----------------------------------------------------------------*/
5652 optimizeSWAP (ast * root)
5654 /* will look for trees of the form
5655 (?expr << 4) | (?expr >> 4) or
5656 (?expr >> 4) | (?expr << 4) will make that
5657 into a SWAP : operation ..
5658 note : by 4 I mean (number of bits required to hold the
5660 /* if the root operation is not a | operation then not */
5661 if (!IS_BITOR (root))
5664 /* (?expr << 4) | (?expr >> 4) */
5665 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5666 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5669 if (!SPEC_USIGN (TETYPE (root->left->left)))
5672 if (!IS_AST_LIT_VALUE (root->left->right) ||
5673 !IS_AST_LIT_VALUE (root->right->right))
5676 /* make sure it is the same expression */
5677 if (!isAstEqual (root->left->left,
5681 if (AST_LIT_VALUE (root->left->right) !=
5682 (getSize (TTYPE (root->left->left)) * 4))
5685 if (AST_LIT_VALUE (root->right->right) !=
5686 (getSize (TTYPE (root->left->left)) * 4))
5689 /* make sure the port supports SWAP */
5690 if (port->hasExtBitOp
5691 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5694 /* found it : create the AST */
5695 return newNode (SWAP, root->left->left, NULL);
5699 /* not found return root */
5703 /*-----------------------------------------------------------------*/
5704 /* optimizeCompare - optimizes compares for bit variables */
5705 /*-----------------------------------------------------------------*/
5707 optimizeCompare (ast * root)
5709 ast *optExpr = NULL;
5712 unsigned int litValue;
5714 /* if nothing then return nothing */
5718 /* if not a compare op then do leaves */
5719 if (!IS_COMPARE_OP (root))
5721 root->left = optimizeCompare (root->left);
5722 root->right = optimizeCompare (root->right);
5726 /* if left & right are the same then depending
5727 of the operation do */
5728 if (isAstEqual (root->left, root->right))
5730 switch (root->opval.op)
5735 optExpr = newAst_VALUE (constVal ("0"));
5740 optExpr = newAst_VALUE (constVal ("1"));
5744 return decorateType (optExpr, RESULT_TYPE_NONE);
5747 vleft = (root->left->type == EX_VALUE ?
5748 root->left->opval.val : NULL);
5750 vright = (root->right->type == EX_VALUE ?
5751 root->right->opval.val : NULL);
5753 /* if left is a BITVAR in BITSPACE */
5754 /* and right is a LITERAL then opt- */
5755 /* imize else do nothing */
5756 if (vleft && vright &&
5757 IS_BITVAR (vleft->etype) &&
5758 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5759 IS_LITERAL (vright->etype))
5762 /* if right side > 1 then comparison may never succeed */
5763 if ((litValue = (int) floatFromVal (vright)) > 1)
5765 werror (W_BAD_COMPARE);
5771 switch (root->opval.op)
5773 case '>': /* bit value greater than 1 cannot be */
5774 werror (W_BAD_COMPARE);
5778 case '<': /* bit value < 1 means 0 */
5780 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5783 case LE_OP: /* bit value <= 1 means no check */
5784 optExpr = newAst_VALUE (vright);
5787 case GE_OP: /* bit value >= 1 means only check for = */
5789 optExpr = newAst_VALUE (vleft);
5794 { /* literal is zero */
5795 switch (root->opval.op)
5797 case '<': /* bit value < 0 cannot be */
5798 werror (W_BAD_COMPARE);
5802 case '>': /* bit value > 0 means 1 */
5804 optExpr = newAst_VALUE (vleft);
5807 case LE_OP: /* bit value <= 0 means no check */
5808 case GE_OP: /* bit value >= 0 means no check */
5809 werror (W_BAD_COMPARE);
5813 case EQ_OP: /* bit == 0 means ! of bit */
5814 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5818 return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5819 } /* end-of-if of BITVAR */
5824 /*-----------------------------------------------------------------*/
5825 /* addSymToBlock : adds the symbol to the first block we find */
5826 /*-----------------------------------------------------------------*/
5828 addSymToBlock (symbol * sym, ast * tree)
5830 /* reached end of tree or a leaf */
5831 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5835 if (IS_AST_OP (tree) &&
5836 tree->opval.op == BLOCK)
5839 symbol *lsym = copySymbol (sym);
5841 lsym->next = AST_VALUES (tree, sym);
5842 AST_VALUES (tree, sym) = lsym;
5846 addSymToBlock (sym, tree->left);
5847 addSymToBlock (sym, tree->right);
5850 /*-----------------------------------------------------------------*/
5851 /* processRegParms - do processing for register parameters */
5852 /*-----------------------------------------------------------------*/
5854 processRegParms (value * args, ast * body)
5858 if (IS_REGPARM (args->etype))
5859 addSymToBlock (args->sym, body);
5864 /*-----------------------------------------------------------------*/
5865 /* resetParmKey - resets the operandkeys for the symbols */
5866 /*-----------------------------------------------------------------*/
5867 DEFSETFUNC (resetParmKey)
5878 /*-----------------------------------------------------------------*/
5879 /* createFunction - This is the key node that calls the iCode for */
5880 /* generating the code for a function. Note code */
5881 /* is generated function by function, later when */
5882 /* add inter-procedural analysis this will change */
5883 /*-----------------------------------------------------------------*/
5885 createFunction (symbol * name, ast * body)
5891 iCode *piCode = NULL;
5893 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5894 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5896 /* if check function return 0 then some problem */
5897 if (checkFunction (name, NULL) == 0)
5900 /* create a dummy block if none exists */
5902 body = newNode (BLOCK, NULL, NULL);
5906 /* check if the function name already in the symbol table */
5907 if ((csym = findSym (SymbolTab, NULL, name->name)))
5910 /* special case for compiler defined functions
5911 we need to add the name to the publics list : this
5912 actually means we are now compiling the compiler
5916 addSet (&publics, name);
5921 addSymChain (&name);
5922 allocVariables (name);
5924 name->lastLine = lineno;
5927 /* set the stack pointer */
5928 stackPtr = -port->stack.direction * port->stack.call_overhead;
5931 if (IFFUNC_ISISR (name->type))
5932 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5934 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5936 if (options.useXstack)
5937 xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5939 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5942 fetype = getSpec (name->type); /* get the specifier for the function */
5943 /* if this is a reentrant function then */
5944 if (IFFUNC_ISREENT (name->type))
5947 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5949 /* do processing for parameters that are passed in registers */
5950 processRegParms (FUNC_ARGS(name->type), body);
5952 /* set the stack pointer */
5956 gatherImplicitVariables (body, NULL); /* move implicit variables into blocks */
5958 /* allocate & autoinit the block variables */
5959 processBlockVars (body, &stack, ALLOCATE);
5961 /* name needs to be mangled */
5962 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5964 body = resolveSymbols (body); /* resolve the symbols */
5965 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5967 /* save the stack information */
5968 if (options.useXstack)
5969 name->xstack = SPEC_STAK (fetype) = stack;
5971 name->stack = SPEC_STAK (fetype) = stack;
5973 ex = newAst_VALUE (symbolVal (name)); /* create name */
5974 ex = newNode (FUNCTION, ex, body);
5975 ex->values.args = FUNC_ARGS(name->type);
5977 if (options.dump_tree) PA(ex);
5980 werror (E_FUNC_NO_CODE, name->name);
5984 /* create the node & generate intermediate code */
5986 codeOutBuf = &code->oBuf;
5987 piCode = iCodeFromAst (ex);
5991 werror (E_FUNC_NO_CODE, name->name);
5995 eBBlockFromiCode (piCode);
5997 /* if there are any statics then do them */
6000 GcurMemmap = statsg;
6001 codeOutBuf = &statsg->oBuf;
6002 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6008 /* dealloc the block variables */
6009 processBlockVars (body, &stack, DEALLOCATE);
6010 outputDebugStackSymbols();
6011 /* deallocate paramaters */
6012 deallocParms (FUNC_ARGS(name->type));
6014 if (IFFUNC_ISREENT (name->type))
6017 /* we are done freeup memory & cleanup */
6019 if (port->reset_labelKey) labelKey = 1;
6021 FUNC_HASBODY(name->type) = 1;
6022 addSet (&operKeyReset, name);
6023 applyToSet (operKeyReset, resetParmKey);
6028 cleanUpLevel (LabelTab, 0);
6029 cleanUpBlock (StructTab, 1);
6030 cleanUpBlock (TypedefTab, 1);
6032 xstack->syms = NULL;
6033 istack->syms = NULL;
6038 #define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6039 /*-----------------------------------------------------------------*/
6040 /* ast_print : prints the ast (for debugging purposes) */
6041 /*-----------------------------------------------------------------*/
6043 void ast_print (ast * tree, FILE *outfile, int indent)
6048 /* can print only decorated trees */
6049 if (!tree->decorated) return;
6051 /* if any child is an error | this one is an error do nothing */
6052 if (tree->isError ||
6053 (tree->left && tree->left->isError) ||
6054 (tree->right && tree->right->isError)) {
6055 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6059 /* print the line */
6060 /* if not block & function */
6061 if (tree->type == EX_OP &&
6062 (tree->opval.op != FUNCTION &&
6063 tree->opval.op != BLOCK &&
6064 tree->opval.op != NULLOP)) {
6067 if (tree->opval.op == FUNCTION) {
6069 value *args=FUNC_ARGS(tree->left->opval.val->type);
6070 fprintf(outfile,"FUNCTION (%s=%p) type (",
6071 tree->left->opval.val->name, tree);
6072 printTypeChain (tree->left->opval.val->type->next,outfile);
6073 fprintf(outfile,") args (");
6076 fprintf (outfile, ", ");
6078 printTypeChain (args ? args->type : NULL, outfile);
6080 args= args ? args->next : NULL;
6082 fprintf(outfile,")\n");
6083 ast_print(tree->left,outfile,indent);
6084 ast_print(tree->right,outfile,indent);
6087 if (tree->opval.op == BLOCK) {
6088 symbol *decls = tree->values.sym;
6089 INDENT(indent,outfile);
6090 fprintf(outfile,"{\n");
6092 INDENT(indent+2,outfile);
6093 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6094 decls->name, decls);
6095 printTypeChain(decls->type,outfile);
6096 fprintf(outfile,")\n");
6098 decls = decls->next;
6100 ast_print(tree->right,outfile,indent+2);
6101 INDENT(indent,outfile);
6102 fprintf(outfile,"}\n");
6105 if (tree->opval.op == NULLOP) {
6106 ast_print(tree->left,outfile,indent);
6107 ast_print(tree->right,outfile,indent);
6110 INDENT(indent,outfile);
6112 /*------------------------------------------------------------------*/
6113 /*----------------------------*/
6114 /* leaf has been reached */
6115 /*----------------------------*/
6116 /* if this is of type value */
6117 /* just get the type */
6118 if (tree->type == EX_VALUE) {
6120 if (IS_LITERAL (tree->opval.val->etype)) {
6121 fprintf(outfile,"CONSTANT (%p) value = ", tree);
6122 if (SPEC_USIGN (tree->opval.val->etype))
6123 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
6125 fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
6126 fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
6127 floatFromVal(tree->opval.val));
6128 } else if (tree->opval.val->sym) {
6129 /* if the undefined flag is set then give error message */
6130 if (tree->opval.val->sym->undefined) {
6131 fprintf(outfile,"UNDEFINED SYMBOL ");
6133 fprintf(outfile,"SYMBOL ");
6135 fprintf(outfile,"(%s=%p @ %p)",
6136 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6139 fprintf(outfile," type (");
6140 printTypeChain(tree->ftype,outfile);
6141 fprintf(outfile,")\n");
6143 fprintf(outfile,"\n");
6148 /* if type link for the case of cast */
6149 if (tree->type == EX_LINK) {
6150 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6151 printTypeChain(tree->opval.lnk,outfile);
6152 fprintf(outfile,")\n");
6157 /* depending on type of operator do */
6159 switch (tree->opval.op) {
6160 /*------------------------------------------------------------------*/
6161 /*----------------------------*/
6163 /*----------------------------*/
6165 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6166 printTypeChain(tree->ftype,outfile);
6167 fprintf(outfile,")\n");
6168 ast_print(tree->left,outfile,indent+2);
6169 ast_print(tree->right,outfile,indent+2);
6172 /*------------------------------------------------------------------*/
6173 /*----------------------------*/
6175 /*----------------------------*/
6177 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6178 printTypeChain(tree->ftype,outfile);
6179 fprintf(outfile,")\n");
6180 ast_print(tree->left,outfile,indent+2);
6181 ast_print(tree->right,outfile,indent+2);
6184 /*------------------------------------------------------------------*/
6185 /*----------------------------*/
6186 /* struct/union pointer */
6187 /*----------------------------*/
6189 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6190 printTypeChain(tree->ftype,outfile);
6191 fprintf(outfile,")\n");
6192 ast_print(tree->left,outfile,indent+2);
6193 ast_print(tree->right,outfile,indent+2);
6196 /*------------------------------------------------------------------*/
6197 /*----------------------------*/
6198 /* ++/-- operation */
6199 /*----------------------------*/
6202 fprintf(outfile,"post-");
6204 fprintf(outfile,"pre-");
6205 fprintf(outfile,"INC_OP (%p) type (",tree);
6206 printTypeChain(tree->ftype,outfile);
6207 fprintf(outfile,")\n");
6208 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6209 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6214 fprintf(outfile,"post-");
6216 fprintf(outfile,"pre-");
6217 fprintf(outfile,"DEC_OP (%p) type (",tree);
6218 printTypeChain(tree->ftype,outfile);
6219 fprintf(outfile,")\n");
6220 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6221 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6224 /*------------------------------------------------------------------*/
6225 /*----------------------------*/
6227 /*----------------------------*/
6230 fprintf(outfile,"& (%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);
6236 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6237 printTypeChain(tree->ftype,outfile);
6238 fprintf(outfile,")\n");
6239 ast_print(tree->left,outfile,indent+2);
6240 ast_print(tree->right,outfile,indent+2);
6243 /*----------------------------*/
6245 /*----------------------------*/
6247 fprintf(outfile,"OR (%p) type (",tree);
6248 printTypeChain(tree->ftype,outfile);
6249 fprintf(outfile,")\n");
6250 ast_print(tree->left,outfile,indent+2);
6251 ast_print(tree->right,outfile,indent+2);
6253 /*------------------------------------------------------------------*/
6254 /*----------------------------*/
6256 /*----------------------------*/
6258 fprintf(outfile,"XOR (%p) type (",tree);
6259 printTypeChain(tree->ftype,outfile);
6260 fprintf(outfile,")\n");
6261 ast_print(tree->left,outfile,indent+2);
6262 ast_print(tree->right,outfile,indent+2);
6265 /*------------------------------------------------------------------*/
6266 /*----------------------------*/
6268 /*----------------------------*/
6270 fprintf(outfile,"DIV (%p) type (",tree);
6271 printTypeChain(tree->ftype,outfile);
6272 fprintf(outfile,")\n");
6273 ast_print(tree->left,outfile,indent+2);
6274 ast_print(tree->right,outfile,indent+2);
6276 /*------------------------------------------------------------------*/
6277 /*----------------------------*/
6279 /*----------------------------*/
6281 fprintf(outfile,"MOD (%p) type (",tree);
6282 printTypeChain(tree->ftype,outfile);
6283 fprintf(outfile,")\n");
6284 ast_print(tree->left,outfile,indent+2);
6285 ast_print(tree->right,outfile,indent+2);
6288 /*------------------------------------------------------------------*/
6289 /*----------------------------*/
6290 /* address dereference */
6291 /*----------------------------*/
6292 case '*': /* can be unary : if right is null then unary operation */
6294 fprintf(outfile,"DEREF (%p) type (",tree);
6295 printTypeChain(tree->ftype,outfile);
6296 fprintf(outfile,")\n");
6297 ast_print(tree->left,outfile,indent+2);
6300 /*------------------------------------------------------------------*/
6301 /*----------------------------*/
6302 /* multiplication */
6303 /*----------------------------*/
6304 fprintf(outfile,"MULT (%p) type (",tree);
6305 printTypeChain(tree->ftype,outfile);
6306 fprintf(outfile,")\n");
6307 ast_print(tree->left,outfile,indent+2);
6308 ast_print(tree->right,outfile,indent+2);
6312 /*------------------------------------------------------------------*/
6313 /*----------------------------*/
6314 /* unary '+' operator */
6315 /*----------------------------*/
6319 fprintf(outfile,"UPLUS (%p) type (",tree);
6320 printTypeChain(tree->ftype,outfile);
6321 fprintf(outfile,")\n");
6322 ast_print(tree->left,outfile,indent+2);
6324 /*------------------------------------------------------------------*/
6325 /*----------------------------*/
6327 /*----------------------------*/
6328 fprintf(outfile,"ADD (%p) type (",tree);
6329 printTypeChain(tree->ftype,outfile);
6330 fprintf(outfile,")\n");
6331 ast_print(tree->left,outfile,indent+2);
6332 ast_print(tree->right,outfile,indent+2);
6335 /*------------------------------------------------------------------*/
6336 /*----------------------------*/
6338 /*----------------------------*/
6339 case '-': /* can be unary */
6341 fprintf(outfile,"UMINUS (%p) type (",tree);
6342 printTypeChain(tree->ftype,outfile);
6343 fprintf(outfile,")\n");
6344 ast_print(tree->left,outfile,indent+2);
6346 /*------------------------------------------------------------------*/
6347 /*----------------------------*/
6349 /*----------------------------*/
6350 fprintf(outfile,"SUB (%p) type (",tree);
6351 printTypeChain(tree->ftype,outfile);
6352 fprintf(outfile,")\n");
6353 ast_print(tree->left,outfile,indent+2);
6354 ast_print(tree->right,outfile,indent+2);
6357 /*------------------------------------------------------------------*/
6358 /*----------------------------*/
6360 /*----------------------------*/
6362 fprintf(outfile,"COMPL (%p) type (",tree);
6363 printTypeChain(tree->ftype,outfile);
6364 fprintf(outfile,")\n");
6365 ast_print(tree->left,outfile,indent+2);
6367 /*------------------------------------------------------------------*/
6368 /*----------------------------*/
6370 /*----------------------------*/
6372 fprintf(outfile,"NOT (%p) type (",tree);
6373 printTypeChain(tree->ftype,outfile);
6374 fprintf(outfile,")\n");
6375 ast_print(tree->left,outfile,indent+2);
6377 /*------------------------------------------------------------------*/
6378 /*----------------------------*/
6380 /*----------------------------*/
6382 fprintf(outfile,"RRC (%p) type (",tree);
6383 printTypeChain(tree->ftype,outfile);
6384 fprintf(outfile,")\n");
6385 ast_print(tree->left,outfile,indent+2);
6389 fprintf(outfile,"RLC (%p) type (",tree);
6390 printTypeChain(tree->ftype,outfile);
6391 fprintf(outfile,")\n");
6392 ast_print(tree->left,outfile,indent+2);
6395 fprintf(outfile,"SWAP (%p) type (",tree);
6396 printTypeChain(tree->ftype,outfile);
6397 fprintf(outfile,")\n");
6398 ast_print(tree->left,outfile,indent+2);
6401 fprintf(outfile,"GETHBIT (%p) type (",tree);
6402 printTypeChain(tree->ftype,outfile);
6403 fprintf(outfile,")\n");
6404 ast_print(tree->left,outfile,indent+2);
6407 fprintf(outfile,"GETABIT (%p) type (",tree);
6408 printTypeChain(tree->ftype,outfile);
6409 fprintf(outfile,")\n");
6410 ast_print(tree->left,outfile,indent+2);
6411 ast_print(tree->right,outfile,indent+2);
6414 fprintf(outfile,"GETBYTE (%p) type (",tree);
6415 printTypeChain(tree->ftype,outfile);
6416 fprintf(outfile,")\n");
6417 ast_print(tree->left,outfile,indent+2);
6418 ast_print(tree->right,outfile,indent+2);
6421 fprintf(outfile,"GETWORD (%p) type (",tree);
6422 printTypeChain(tree->ftype,outfile);
6423 fprintf(outfile,")\n");
6424 ast_print(tree->left,outfile,indent+2);
6425 ast_print(tree->right,outfile,indent+2);
6428 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6429 printTypeChain(tree->ftype,outfile);
6430 fprintf(outfile,")\n");
6431 ast_print(tree->left,outfile,indent+2);
6432 ast_print(tree->right,outfile,indent+2);
6435 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6436 printTypeChain(tree->ftype,outfile);
6437 fprintf(outfile,")\n");
6438 ast_print(tree->left,outfile,indent+2);
6439 ast_print(tree->right,outfile,indent+2);
6441 /*------------------------------------------------------------------*/
6442 /*----------------------------*/
6444 /*----------------------------*/
6445 case CAST: /* change the type */
6446 fprintf(outfile,"CAST (%p) from type (",tree);
6447 printTypeChain(tree->right->ftype,outfile);
6448 fprintf(outfile,") to type (");
6449 printTypeChain(tree->ftype,outfile);
6450 fprintf(outfile,")\n");
6451 ast_print(tree->right,outfile,indent+2);
6455 fprintf(outfile,"ANDAND (%p) type (",tree);
6456 printTypeChain(tree->ftype,outfile);
6457 fprintf(outfile,")\n");
6458 ast_print(tree->left,outfile,indent+2);
6459 ast_print(tree->right,outfile,indent+2);
6462 fprintf(outfile,"OROR (%p) type (",tree);
6463 printTypeChain(tree->ftype,outfile);
6464 fprintf(outfile,")\n");
6465 ast_print(tree->left,outfile,indent+2);
6466 ast_print(tree->right,outfile,indent+2);
6469 /*------------------------------------------------------------------*/
6470 /*----------------------------*/
6471 /* comparison operators */
6472 /*----------------------------*/
6474 fprintf(outfile,"GT(>) (%p) type (",tree);
6475 printTypeChain(tree->ftype,outfile);
6476 fprintf(outfile,")\n");
6477 ast_print(tree->left,outfile,indent+2);
6478 ast_print(tree->right,outfile,indent+2);
6481 fprintf(outfile,"LT(<) (%p) type (",tree);
6482 printTypeChain(tree->ftype,outfile);
6483 fprintf(outfile,")\n");
6484 ast_print(tree->left,outfile,indent+2);
6485 ast_print(tree->right,outfile,indent+2);
6488 fprintf(outfile,"LE(<=) (%p) type (",tree);
6489 printTypeChain(tree->ftype,outfile);
6490 fprintf(outfile,")\n");
6491 ast_print(tree->left,outfile,indent+2);
6492 ast_print(tree->right,outfile,indent+2);
6495 fprintf(outfile,"GE(>=) (%p) type (",tree);
6496 printTypeChain(tree->ftype,outfile);
6497 fprintf(outfile,")\n");
6498 ast_print(tree->left,outfile,indent+2);
6499 ast_print(tree->right,outfile,indent+2);
6502 fprintf(outfile,"EQ(==) (%p) type (",tree);
6503 printTypeChain(tree->ftype,outfile);
6504 fprintf(outfile,")\n");
6505 ast_print(tree->left,outfile,indent+2);
6506 ast_print(tree->right,outfile,indent+2);
6509 fprintf(outfile,"NE(!=) (%p) type (",tree);
6510 printTypeChain(tree->ftype,outfile);
6511 fprintf(outfile,")\n");
6512 ast_print(tree->left,outfile,indent+2);
6513 ast_print(tree->right,outfile,indent+2);
6514 /*------------------------------------------------------------------*/
6515 /*----------------------------*/
6517 /*----------------------------*/
6518 case SIZEOF: /* evaluate wihout code generation */
6519 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6522 /*------------------------------------------------------------------*/
6523 /*----------------------------*/
6524 /* conditional operator '?' */
6525 /*----------------------------*/
6527 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6528 printTypeChain(tree->ftype,outfile);
6529 fprintf(outfile,")\n");
6530 ast_print(tree->left,outfile,indent+2);
6531 ast_print(tree->right,outfile,indent+2);
6535 fprintf(outfile,"COLON(:) (%p) type (",tree);
6536 printTypeChain(tree->ftype,outfile);
6537 fprintf(outfile,")\n");
6538 ast_print(tree->left,outfile,indent+2);
6539 ast_print(tree->right,outfile,indent+2);
6542 /*------------------------------------------------------------------*/
6543 /*----------------------------*/
6544 /* assignment operators */
6545 /*----------------------------*/
6547 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6548 printTypeChain(tree->ftype,outfile);
6549 fprintf(outfile,")\n");
6550 ast_print(tree->left,outfile,indent+2);
6551 ast_print(tree->right,outfile,indent+2);
6554 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6555 printTypeChain(tree->ftype,outfile);
6556 fprintf(outfile,")\n");
6557 ast_print(tree->left,outfile,indent+2);
6558 ast_print(tree->right,outfile,indent+2);
6561 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6562 printTypeChain(tree->ftype,outfile);
6563 fprintf(outfile,")\n");
6564 ast_print(tree->left,outfile,indent+2);
6565 ast_print(tree->right,outfile,indent+2);
6568 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6569 printTypeChain(tree->ftype,outfile);
6570 fprintf(outfile,")\n");
6571 ast_print(tree->left,outfile,indent+2);
6572 ast_print(tree->right,outfile,indent+2);
6575 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6576 printTypeChain(tree->ftype,outfile);
6577 fprintf(outfile,")\n");
6578 ast_print(tree->left,outfile,indent+2);
6579 ast_print(tree->right,outfile,indent+2);
6582 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6583 printTypeChain(tree->ftype,outfile);
6584 fprintf(outfile,")\n");
6585 ast_print(tree->left,outfile,indent+2);
6586 ast_print(tree->right,outfile,indent+2);
6589 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6590 printTypeChain(tree->ftype,outfile);
6591 fprintf(outfile,")\n");
6592 ast_print(tree->left,outfile,indent+2);
6593 ast_print(tree->right,outfile,indent+2);
6595 /*------------------------------------------------------------------*/
6596 /*----------------------------*/
6598 /*----------------------------*/
6600 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6601 printTypeChain(tree->ftype,outfile);
6602 fprintf(outfile,")\n");
6603 ast_print(tree->left,outfile,indent+2);
6604 ast_print(tree->right,outfile,indent+2);
6606 /*------------------------------------------------------------------*/
6607 /*----------------------------*/
6609 /*----------------------------*/
6611 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6612 printTypeChain(tree->ftype,outfile);
6613 fprintf(outfile,")\n");
6614 ast_print(tree->left,outfile,indent+2);
6615 ast_print(tree->right,outfile,indent+2);
6617 /*------------------------------------------------------------------*/
6618 /*----------------------------*/
6619 /* straight assignemnt */
6620 /*----------------------------*/
6622 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6623 printTypeChain(tree->ftype,outfile);
6624 fprintf(outfile,")\n");
6625 ast_print(tree->left,outfile,indent+2);
6626 ast_print(tree->right,outfile,indent+2);
6628 /*------------------------------------------------------------------*/
6629 /*----------------------------*/
6630 /* comma operator */
6631 /*----------------------------*/
6633 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6634 printTypeChain(tree->ftype,outfile);
6635 fprintf(outfile,")\n");
6636 ast_print(tree->left,outfile,indent+2);
6637 ast_print(tree->right,outfile,indent+2);
6639 /*------------------------------------------------------------------*/
6640 /*----------------------------*/
6642 /*----------------------------*/
6645 fprintf(outfile,"CALL (%p) type (",tree);
6646 printTypeChain(tree->ftype,outfile);
6647 fprintf(outfile,")\n");
6648 ast_print(tree->left,outfile,indent+2);
6649 ast_print(tree->right,outfile,indent+2);
6652 fprintf(outfile,"PARMS\n");
6653 ast_print(tree->left,outfile,indent+2);
6654 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6655 ast_print(tree->right,outfile,indent+2);
6658 /*------------------------------------------------------------------*/
6659 /*----------------------------*/
6660 /* return statement */
6661 /*----------------------------*/
6663 fprintf(outfile,"RETURN (%p) type (",tree);
6665 printTypeChain(tree->right->ftype,outfile);
6667 fprintf(outfile,")\n");
6668 ast_print(tree->right,outfile,indent+2);
6670 /*------------------------------------------------------------------*/
6671 /*----------------------------*/
6672 /* label statement */
6673 /*----------------------------*/
6675 fprintf(outfile,"LABEL (%p)\n",tree);
6676 ast_print(tree->left,outfile,indent+2);
6677 ast_print(tree->right,outfile,indent);
6679 /*------------------------------------------------------------------*/
6680 /*----------------------------*/
6681 /* switch statement */
6682 /*----------------------------*/
6686 fprintf(outfile,"SWITCH (%p) ",tree);
6687 ast_print(tree->left,outfile,0);
6688 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6689 INDENT(indent+2,outfile);
6690 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6691 (int) floatFromVal(val),
6692 tree->values.switchVals.swNum,
6693 (int) floatFromVal(val));
6695 ast_print(tree->right,outfile,indent);
6698 /*------------------------------------------------------------------*/
6699 /*----------------------------*/
6701 /*----------------------------*/
6703 fprintf(outfile,"IF (%p) \n",tree);
6704 ast_print(tree->left,outfile,indent+2);
6705 if (tree->trueLabel) {
6706 INDENT(indent+2,outfile);
6707 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6709 if (tree->falseLabel) {
6710 INDENT(indent+2,outfile);
6711 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6713 ast_print(tree->right,outfile,indent+2);
6715 /*----------------------------*/
6716 /* goto Statement */
6717 /*----------------------------*/
6719 fprintf(outfile,"GOTO (%p) \n",tree);
6720 ast_print(tree->left,outfile,indent+2);
6721 fprintf(outfile,"\n");
6723 /*------------------------------------------------------------------*/
6724 /*----------------------------*/
6726 /*----------------------------*/
6728 fprintf(outfile,"FOR (%p) \n",tree);
6729 if (AST_FOR( tree, initExpr)) {
6730 INDENT(indent+2,outfile);
6731 fprintf(outfile,"INIT EXPR ");
6732 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6734 if (AST_FOR( tree, condExpr)) {
6735 INDENT(indent+2,outfile);
6736 fprintf(outfile,"COND EXPR ");
6737 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6739 if (AST_FOR( tree, loopExpr)) {
6740 INDENT(indent+2,outfile);
6741 fprintf(outfile,"LOOP EXPR ");
6742 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6744 fprintf(outfile,"FOR LOOP BODY \n");
6745 ast_print(tree->left,outfile,indent+2);
6748 fprintf(outfile,"CRITICAL (%p) \n",tree);
6749 ast_print(tree->left,outfile,indent+2);
6757 ast_print(t,stdout,0);
6760 /*-----------------------------------------------------------------*/
6761 /* astErrors : returns non-zero if errors present in tree */
6762 /*-----------------------------------------------------------------*/
6763 int astErrors(ast *t)
6772 if (t->type == EX_VALUE
6773 && t->opval.val->sym
6774 && t->opval.val->sym->undefined)
6777 errors += astErrors(t->left);
6778 errors += astErrors(t->right);