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 -------------------------------------------------------------------------*/
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
50 symbol *currFunc=NULL;
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeSWAP (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
60 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
65 printTypeChain (tree->ftype, stdout);
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree */
72 /*-----------------------------------------------------------------*/
74 newAst_ (unsigned type)
77 static int oldLineno = 0;
79 ex = Safe_alloc ( sizeof (ast));
82 ex->lineno = (noLineno ? oldLineno : mylineno);
83 ex->filename = currFname;
84 ex->level = NestLevel;
85 ex->block = currBlockno;
86 ex->initMode = inInitMode;
87 ex->seqPoint = seqPointNo;
92 newAst_VALUE (value * val)
94 ast *ex = newAst_ (EX_VALUE);
100 newAst_OP (unsigned op)
102 ast *ex = newAst_ (EX_OP);
108 newAst_LINK (sym_link * val)
110 ast *ex = newAst_ (EX_LINK);
115 /*-----------------------------------------------------------------*/
116 /* newNode - creates a new node */
117 /*-----------------------------------------------------------------*/
119 newNode (long op, ast * left, ast * right)
130 /*-----------------------------------------------------------------*/
131 /* newIfxNode - creates a new Ifx Node */
132 /*-----------------------------------------------------------------*/
134 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
138 /* if this is a literal then we already know the result */
139 if (condAst->etype && IS_LITERAL (condAst->etype))
141 /* then depending on the expression value */
142 if (floatFromVal (condAst->opval.val))
143 ifxNode = newNode (GOTO,
144 newAst_VALUE (symbolVal (trueLabel)),
147 ifxNode = newNode (GOTO,
148 newAst_VALUE (symbolVal (falseLabel)),
153 ifxNode = newNode (IFX, condAst, NULL);
154 ifxNode->trueLabel = trueLabel;
155 ifxNode->falseLabel = falseLabel;
161 /*-----------------------------------------------------------------*/
162 /* copyAstValues - copies value portion of ast if needed */
163 /*-----------------------------------------------------------------*/
165 copyAstValues (ast * dest, ast * src)
167 switch (src->opval.op)
170 dest->values.sym = copySymbolChain (src->values.sym);
174 dest->values.switchVals.swVals =
175 copyValue (src->values.switchVals.swVals);
176 dest->values.switchVals.swDefault =
177 src->values.switchVals.swDefault;
178 dest->values.switchVals.swNum =
179 src->values.switchVals.swNum;
183 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
187 dest->values.constlist = copyLiteralList(src->values.constlist);
191 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
192 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
193 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
194 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
195 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
196 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
197 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
202 /*-----------------------------------------------------------------*/
203 /* copyAst - makes a copy of a given astession */
204 /*-----------------------------------------------------------------*/
213 dest = Safe_alloc ( sizeof (ast));
215 dest->type = src->type;
216 dest->lineno = src->lineno;
217 dest->level = src->level;
218 dest->funcName = src->funcName;
221 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
223 /* if this is a leaf */
225 if (src->type == EX_VALUE)
227 dest->opval.val = copyValue (src->opval.val);
232 if (src->type == EX_LINK)
234 dest->opval.lnk = copyLinkChain (src->opval.lnk);
238 dest->opval.op = src->opval.op;
240 /* if this is a node that has special values */
241 copyAstValues (dest, src);
243 dest->trueLabel = copySymbol (src->trueLabel);
244 dest->falseLabel = copySymbol (src->falseLabel);
245 dest->left = copyAst (src->left);
246 dest->right = copyAst (src->right);
252 /*-----------------------------------------------------------------*/
253 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
254 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
255 /*-----------------------------------------------------------------*/
256 ast *removeIncDecOps (ast * tree) {
258 // traverse the tree and remove inc/dec ops
263 if (tree->type == EX_OP &&
264 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
271 tree->left=removeIncDecOps(tree->left);
272 tree->right=removeIncDecOps(tree->right);
277 /*-----------------------------------------------------------------*/
278 /* removePreIncDecOps: remove for side effects in *_ASSIGN's */
279 /* "*++s += 3" -> "*++s = *++s + 3" */
280 /*-----------------------------------------------------------------*/
281 ast *removePreIncDecOps (ast * tree) {
283 // traverse the tree and remove pre-inc/dec ops
288 if (tree->type == EX_OP &&
289 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
294 tree->left=removePreIncDecOps(tree->left);
295 tree->right=removePreIncDecOps(tree->right);
300 /*-----------------------------------------------------------------*/
301 /* removePostIncDecOps: remove for side effects in *_ASSIGN's */
302 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
303 /*-----------------------------------------------------------------*/
304 ast *removePostIncDecOps (ast * tree) {
306 // traverse the tree and remove pre-inc/dec ops
311 if (tree->type == EX_OP &&
312 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
317 tree->left=removePostIncDecOps(tree->left);
318 tree->right=removePostIncDecOps(tree->right);
323 /*-----------------------------------------------------------------*/
324 /* hasSEFcalls - returns TRUE if tree has a function call */
325 /*-----------------------------------------------------------------*/
327 hasSEFcalls (ast * tree)
332 if (tree->type == EX_OP &&
333 (tree->opval.op == CALL ||
334 tree->opval.op == PCALL ||
335 tree->opval.op == '=' ||
336 tree->opval.op == INC_OP ||
337 tree->opval.op == DEC_OP))
340 return (hasSEFcalls (tree->left) |
341 hasSEFcalls (tree->right));
344 /*-----------------------------------------------------------------*/
345 /* isAstEqual - compares two asts & returns 1 if they are equal */
346 /*-----------------------------------------------------------------*/
348 isAstEqual (ast * t1, ast * t2)
357 if (t1->type != t2->type)
363 if (t1->opval.op != t2->opval.op)
365 return (isAstEqual (t1->left, t2->left) &&
366 isAstEqual (t1->right, t2->right));
370 if (t1->opval.val->sym)
372 if (!t2->opval.val->sym)
375 return isSymbolEqual (t1->opval.val->sym,
380 if (t2->opval.val->sym)
383 return (floatFromVal (t1->opval.val) ==
384 floatFromVal (t2->opval.val));
388 /* only compare these two types */
396 /*-----------------------------------------------------------------*/
397 /* resolveSymbols - resolve symbols from the symbol table */
398 /*-----------------------------------------------------------------*/
400 resolveSymbols (ast * tree)
402 /* walk the entire tree and check for values */
403 /* with symbols if we find one then replace */
404 /* symbol with that from the symbol table */
411 /* if not block & function */
412 if (tree->type == EX_OP &&
413 (tree->opval.op != FUNCTION &&
414 tree->opval.op != BLOCK &&
415 tree->opval.op != NULLOP))
417 filename = tree->filename;
418 lineno = tree->lineno;
422 /* make sure we resolve the true & false labels for ifx */
423 if (tree->type == EX_OP && tree->opval.op == IFX)
429 if ((csym = findSym (LabelTab, tree->trueLabel,
430 tree->trueLabel->name)))
431 tree->trueLabel = csym;
433 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
434 tree->trueLabel->name);
437 if (tree->falseLabel)
439 if ((csym = findSym (LabelTab,
441 tree->falseLabel->name)))
442 tree->falseLabel = csym;
444 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
445 tree->falseLabel->name);
450 /* if this is a label resolve it from the labelTab */
451 if (IS_AST_VALUE (tree) &&
452 tree->opval.val->sym &&
453 tree->opval.val->sym->islbl)
456 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
457 tree->opval.val->sym->name);
460 werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
461 tree->opval.val->sym->name);
463 tree->opval.val->sym = csym;
465 goto resolveChildren;
468 /* do only for leafs */
469 if (IS_AST_VALUE (tree) &&
470 tree->opval.val->sym &&
471 !tree->opval.val->sym->implicit)
474 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
476 /* if found in the symbol table & they r not the same */
477 if (csym && tree->opval.val->sym != csym)
479 tree->opval.val->sym = csym;
480 tree->opval.val->type = csym->type;
481 tree->opval.val->etype = csym->etype;
484 /* if not found in the symbol table */
485 /* mark it as undefined assume it is */
486 /* an integer in data space */
487 if (!csym && !tree->opval.val->sym->implicit)
490 /* if this is a function name then */
491 /* mark it as returning an int */
494 tree->opval.val->sym->type = newLink (DECLARATOR);
495 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
496 tree->opval.val->sym->type->next =
497 tree->opval.val->sym->etype = newIntLink ();
498 tree->opval.val->etype = tree->opval.val->etype;
499 tree->opval.val->type = tree->opval.val->sym->type;
500 werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
501 tree->opval.val->sym->name);
502 //tree->opval.val->sym->undefined = 1;
503 allocVariables (tree->opval.val->sym);
507 tree->opval.val->sym->undefined = 1;
508 tree->opval.val->type =
509 tree->opval.val->etype = newIntLink ();
510 tree->opval.val->sym->type =
511 tree->opval.val->sym->etype = newIntLink ();
517 resolveSymbols (tree->left);
518 resolveSymbols (tree->right);
523 /*-----------------------------------------------------------------*/
524 /* setAstLineno - walks a ast tree & sets the line number */
525 /*-----------------------------------------------------------------*/
526 int setAstLineno (ast * tree, int lineno)
531 tree->lineno = lineno;
532 setAstLineno (tree->left, lineno);
533 setAstLineno (tree->right, lineno);
537 /*-----------------------------------------------------------------*/
538 /* funcOfType :- function of type with name */
539 /*-----------------------------------------------------------------*/
541 funcOfType (char *name, sym_link * type, sym_link * argType,
545 /* create the symbol */
546 sym = newSymbol (name, 0);
548 /* setup return value */
549 sym->type = newLink (DECLARATOR);
550 DCL_TYPE (sym->type) = FUNCTION;
551 sym->type->next = copyLinkChain (type);
552 sym->etype = getSpec (sym->type);
553 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
555 /* if arguments required */
559 args = FUNC_ARGS(sym->type) = newValue ();
563 args->type = copyLinkChain (argType);
564 args->etype = getSpec (args->type);
565 SPEC_EXTR(args->etype)=1;
568 args = args->next = newValue ();
575 allocVariables (sym);
580 /*-----------------------------------------------------------------*/
581 /* funcOfTypeVarg :- function of type with name and argtype */
582 /*-----------------------------------------------------------------*/
584 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
589 /* create the symbol */
590 sym = newSymbol (name, 0);
592 /* setup return value */
593 sym->type = newLink (DECLARATOR);
594 DCL_TYPE (sym->type) = FUNCTION;
595 sym->type->next = typeFromStr(rtype);
596 sym->etype = getSpec (sym->type);
598 /* if arguments required */
601 args = FUNC_ARGS(sym->type) = newValue ();
603 for ( i = 0 ; i < nArgs ; i++ ) {
604 args->type = typeFromStr(atypes[i]);
605 args->etype = getSpec (args->type);
606 SPEC_EXTR(args->etype)=1;
607 if ((i + 1) == nArgs) break;
608 args = args->next = newValue ();
615 allocVariables (sym);
620 /*-----------------------------------------------------------------*/
621 /* reverseParms - will reverse a parameter tree */
622 /*-----------------------------------------------------------------*/
624 reverseParms (ast * ptree)
630 /* top down if we find a nonParm tree then quit */
631 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
634 ptree->left = ptree->right;
635 ptree->right = ttree;
636 reverseParms (ptree->left);
637 reverseParms (ptree->right);
643 /*-----------------------------------------------------------------*/
644 /* processParms - makes sure the parameters are okay and do some */
645 /* processing with them */
646 /*-----------------------------------------------------------------*/
648 processParms (ast *func,
651 int *parmNumber, /* unused, although updated */
654 RESULT_TYPE resultType;
657 /* if none of them exist */
658 if (!defParm && !actParm)
663 if (getenv("DEBUG_SANITY"))
665 fprintf (stderr, "processParms: %s ", defParm->name);
667 /* make sure the type is complete and sane */
668 checkTypeSanity(defParm->etype, defParm->name);
671 if (IS_CODEPTR (func->ftype))
672 functype = func->ftype->next;
674 functype = func->ftype;
676 /* if the function is being called via a pointer & */
677 /* it has not been defined a reentrant then we cannot */
678 /* have parameters */
679 if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
681 werror (W_NONRENT_ARGS);
686 /* if defined parameters ended but actual parameters */
687 /* exist and this is not defined as a variable arg */
688 if (!defParm && actParm && !IFFUNC_HASVARARGS(functype))
690 werror (E_TOO_MANY_PARMS);
694 /* if defined parameters present but no actual parameters */
695 if (defParm && !actParm)
697 werror (E_TOO_FEW_PARMS);
701 /* if this is a PARAM node then match left & right */
702 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
704 actParm->decorated = 1;
705 return (processParms (func, defParm,
706 actParm->left, parmNumber, FALSE) ||
707 processParms (func, defParm ? defParm->next : NULL,
708 actParm->right, parmNumber, rightmost));
710 else if (defParm) /* not vararg */
712 /* If we have found a value node by following only right-hand links,
713 * then we know that there are no more values after us.
715 * Therefore, if there are more defined parameters, the caller didn't
718 if (rightmost && defParm->next)
720 werror (E_TOO_FEW_PARMS);
725 /* decorate parameter */
726 resultType = defParm ? getResultTypeFromType (defParm->etype) :
728 actParm = decorateType (actParm, resultType);
730 if (IS_VOID(actParm->ftype))
732 werror (E_VOID_VALUE_USED);
736 /* If this is a varargs function... */
737 if (!defParm && actParm && IFFUNC_HASVARARGS(functype))
742 if (IS_CAST_OP (actParm)
743 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
745 /* Parameter was explicitly typecast; don't touch it. */
749 ftype = actParm->ftype;
751 /* If it's a char, upcast to int. */
752 if (IS_INTEGRAL (ftype)
753 && (getSize (ftype) < (unsigned) INTSIZE))
755 newType = newAst_LINK(INTTYPE);
758 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
760 newType = newAst_LINK (copyLinkChain(ftype));
761 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
764 if (IS_AGGREGATE (ftype))
766 newType = newAst_LINK (copyLinkChain (ftype));
767 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
772 /* cast required; change this op to a cast. */
773 ast *parmCopy = resolveSymbols (copyAst (actParm));
775 actParm->type = EX_OP;
776 actParm->opval.op = CAST;
777 actParm->left = newType;
778 actParm->right = parmCopy;
779 actParm->decorated = 0; /* force typechecking */
780 decorateType (actParm, RESULT_TYPE_NONE);
785 /* if defined parameters ended but actual has not & */
787 if (!defParm && actParm &&
788 (options.stackAuto || IFFUNC_ISREENT (functype)))
791 resolveSymbols (actParm);
793 /* the parameter type must be at least castable */
794 if (compareType (defParm->type, actParm->ftype) == 0)
796 werror (E_INCOMPAT_TYPES);
797 printFromToType (actParm->ftype, defParm->type);
801 /* if the parameter is castable then add the cast */
802 if (compareType (defParm->type, actParm->ftype) < 0)
806 resultType = getResultTypeFromType (defParm->etype);
807 pTree = resolveSymbols (copyAst (actParm));
809 /* now change the current one to a cast */
810 actParm->type = EX_OP;
811 actParm->opval.op = CAST;
812 actParm->left = newAst_LINK (defParm->type);
813 actParm->right = pTree;
814 actParm->decorated = 0; /* force typechecking */
815 decorateType (actParm, resultType);
818 /* make a copy and change the regparm type to the defined parm */
819 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
820 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
821 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
826 /*-----------------------------------------------------------------*/
827 /* createIvalType - generates ival for basic types */
828 /*-----------------------------------------------------------------*/
830 createIvalType (ast * sym, sym_link * type, initList * ilist)
834 /* if initList is deep */
835 if (ilist->type == INIT_DEEP)
836 ilist = ilist->init.deep;
838 iExpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
839 return decorateType (newNode ('=', sym, iExpr), RESULT_CHECK);
842 /*-----------------------------------------------------------------*/
843 /* createIvalStruct - generates initial value for structures */
844 /*-----------------------------------------------------------------*/
846 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
853 sflds = SPEC_STRUCT (type)->fields;
854 if (ilist->type != INIT_DEEP)
856 werror (E_INIT_STRUCT, "");
860 iloop = ilist->init.deep;
862 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
864 /* if we have come to end */
868 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
869 lAst = decorateType (resolveSymbols (lAst), RESULT_CHECK);
870 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)), RESULT_CHECK);
874 werrorfl (filename, sym->opval.val->sym->lineDef,
875 W_EXCESS_INITIALIZERS, "struct",
876 sym->opval.val->sym->name);
883 /*-----------------------------------------------------------------*/
884 /* createIvalArray - generates code for array initialization */
885 /*-----------------------------------------------------------------*/
887 createIvalArray (ast * sym, sym_link * type, initList * ilist)
891 int lcnt = 0, size = 0;
892 literalList *literalL;
894 /* take care of the special case */
895 /* array of characters can be init */
897 if (IS_CHAR (type->next))
898 if ((rast = createIvalCharPtr (sym,
900 decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK))))
902 return decorateType (resolveSymbols (rast), RESULT_CHECK);
904 /* not the special case */
905 if (ilist->type != INIT_DEEP)
907 werror (E_INIT_STRUCT, "");
911 iloop = ilist->init.deep;
912 lcnt = DCL_ELEM (type);
914 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
918 aSym = decorateType (resolveSymbols(sym), RESULT_CHECK);
920 rast = newNode(ARRAYINIT, aSym, NULL);
921 rast->values.constlist = literalL;
923 // Make sure size is set to length of initializer list.
930 if (lcnt && size > lcnt)
932 // Array size was specified, and we have more initializers than needed.
933 char *name=sym->opval.val->sym->name;
934 int lineno=sym->opval.val->sym->lineDef;
936 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
945 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
946 aSym = decorateType (resolveSymbols (aSym), RESULT_CHECK);
947 rast = createIval (aSym, type->next, iloop, rast);
948 iloop = (iloop ? iloop->next : NULL);
954 /* no of elements given and we */
955 /* have generated for all of them */
958 // there has to be a better way
959 char *name=sym->opval.val->sym->name;
960 int lineno=sym->opval.val->sym->lineDef;
961 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
968 /* if we have not been given a size */
969 if (!DCL_ELEM (type))
971 DCL_ELEM (type) = size;
974 return decorateType (resolveSymbols (rast), RESULT_CHECK);
978 /*-----------------------------------------------------------------*/
979 /* createIvalCharPtr - generates initial values for char pointers */
980 /*-----------------------------------------------------------------*/
982 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
986 /* if this is a pointer & right is a literal array then */
987 /* just assignment will do */
988 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
989 SPEC_SCLS (iexpr->etype) == S_CODE)
990 && IS_ARRAY (iexpr->ftype)))
991 return newNode ('=', sym, iexpr);
993 /* left side is an array so we have to assign each */
995 if ((IS_LITERAL (iexpr->etype) ||
996 SPEC_SCLS (iexpr->etype) == S_CODE)
997 && IS_ARRAY (iexpr->ftype))
999 /* for each character generate an assignment */
1000 /* to the array element */
1001 char *s = SPEC_CVAL (iexpr->etype).v_char;
1003 int size = getSize (iexpr->ftype);
1004 int symsize = getSize (type);
1008 if (size>(symsize+1))
1009 werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1010 "string", sym->opval.val->sym->name);
1014 for (i=0;i<size;i++)
1016 rast = newNode (NULLOP,
1020 newAst_VALUE (valueFromLit ((float) i))),
1021 newAst_VALUE (valueFromLit (*s))));
1025 // now WE don't need iexpr's symbol anymore
1026 freeStringSymbol(AST_SYMBOL(iexpr));
1028 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1034 /*-----------------------------------------------------------------*/
1035 /* createIvalPtr - generates initial value for pointers */
1036 /*-----------------------------------------------------------------*/
1038 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1044 if (ilist->type == INIT_DEEP)
1045 ilist = ilist->init.deep;
1047 iexpr = decorateType (resolveSymbols (list2expr (ilist)), RESULT_CHECK);
1049 /* if character pointer */
1050 if (IS_CHAR (type->next))
1051 if ((rast = createIvalCharPtr (sym, type, iexpr)))
1054 return newNode ('=', sym, iexpr);
1057 /*-----------------------------------------------------------------*/
1058 /* createIval - generates code for initial value */
1059 /*-----------------------------------------------------------------*/
1061 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1068 /* if structure then */
1069 if (IS_STRUCT (type))
1070 rast = createIvalStruct (sym, type, ilist);
1072 /* if this is a pointer */
1074 rast = createIvalPtr (sym, type, ilist);
1076 /* if this is an array */
1077 if (IS_ARRAY (type))
1078 rast = createIvalArray (sym, type, ilist);
1080 /* if type is SPECIFIER */
1082 rast = createIvalType (sym, type, ilist);
1085 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)), RESULT_CHECK);
1087 return decorateType (resolveSymbols (rast), RESULT_CHECK);
1090 /*-----------------------------------------------------------------*/
1091 /* initAggregates - initialises aggregate variables with initv */
1092 /*-----------------------------------------------------------------*/
1093 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1094 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1097 /*-----------------------------------------------------------------*/
1098 /* gatherAutoInit - creates assignment expressions for initial */
1100 /*-----------------------------------------------------------------*/
1102 gatherAutoInit (symbol * autoChain)
1109 for (sym = autoChain; sym; sym = sym->next)
1112 /* resolve the symbols in the ival */
1114 resolveIvalSym (sym->ival, sym->type);
1116 /* if this is a static variable & has an */
1117 /* initial value the code needs to be lifted */
1118 /* here to the main portion since they can be */
1119 /* initialised only once at the start */
1120 if (IS_STATIC (sym->etype) && sym->ival &&
1121 SPEC_SCLS (sym->etype) != S_CODE)
1125 /* insert the symbol into the symbol table */
1126 /* with level = 0 & name = rname */
1127 newSym = copySymbol (sym);
1128 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1130 /* now lift the code to main */
1131 if (IS_AGGREGATE (sym->type)) {
1132 work = initAggregates (sym, sym->ival, NULL);
1134 if (getNelements(sym->type, sym->ival)>1) {
1135 werrorfl (filename, sym->lineDef,
1136 W_EXCESS_INITIALIZERS, "scalar",
1139 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1140 list2expr (sym->ival));
1143 setAstLineno (work, sym->lineDef);
1147 staticAutos = newNode (NULLOP, staticAutos, work);
1154 /* if there is an initial value */
1155 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1157 initList *ilist=sym->ival;
1159 while (ilist->type == INIT_DEEP) {
1160 ilist = ilist->init.deep;
1163 /* update lineno for error msg */
1164 lineno=sym->lineDef;
1165 setAstLineno (ilist->init.node, lineno);
1167 if (IS_AGGREGATE (sym->type)) {
1168 work = initAggregates (sym, sym->ival, NULL);
1170 if (getNelements(sym->type, sym->ival)>1) {
1171 werrorfl (filename, sym->lineDef,
1172 W_EXCESS_INITIALIZERS, "scalar",
1175 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1176 list2expr (sym->ival));
1180 setAstLineno (work, sym->lineDef);
1184 init = newNode (NULLOP, init, work);
1193 /*-----------------------------------------------------------------*/
1194 /* freeStringSymbol - delete a literal string if no more usage */
1195 /*-----------------------------------------------------------------*/
1196 void freeStringSymbol(symbol *sym) {
1197 /* make sure this is a literal string */
1198 assert (sym->isstrlit);
1199 if (--sym->isstrlit == 0) { // lower the usage count
1200 memmap *segment=SPEC_OCLS(sym->etype);
1202 deleteSetItem(&segment->syms, sym);
1207 /*-----------------------------------------------------------------*/
1208 /* stringToSymbol - creates a symbol from a literal string */
1209 /*-----------------------------------------------------------------*/
1211 stringToSymbol (value * val)
1213 char name[SDCC_NAME_MAX + 1];
1214 static int charLbl = 0;
1219 // have we heard this before?
1220 for (sp=statsg->syms; sp; sp=sp->next) {
1222 size = getSize (sym->type);
1223 if (sym->isstrlit && size == getSize (val->type) &&
1224 !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1225 // yes, this is old news. Don't publish it again.
1226 sym->isstrlit++; // but raise the usage count
1227 return symbolVal(sym);
1231 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1232 sym = newSymbol (name, 0); /* make it @ level 0 */
1233 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1235 /* copy the type from the value passed */
1236 sym->type = copyLinkChain (val->type);
1237 sym->etype = getSpec (sym->type);
1238 /* change to storage class & output class */
1239 SPEC_SCLS (sym->etype) = S_CODE;
1240 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1241 SPEC_STAT (sym->etype) = 1;
1242 /* make the level & block = 0 */
1243 sym->block = sym->level = 0;
1245 /* create an ival */
1246 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1251 allocVariables (sym);
1254 return symbolVal (sym);
1258 /*-----------------------------------------------------------------*/
1259 /* processBlockVars - will go thru the ast looking for block if */
1260 /* a block is found then will allocate the syms */
1261 /* will also gather the auto inits present */
1262 /*-----------------------------------------------------------------*/
1264 processBlockVars (ast * tree, int *stack, int action)
1269 /* if this is a block */
1270 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1274 if (action == ALLOCATE)
1276 *stack += allocVariables (tree->values.sym);
1277 autoInit = gatherAutoInit (tree->values.sym);
1279 /* if there are auto inits then do them */
1281 tree->left = newNode (NULLOP, autoInit, tree->left);
1283 else /* action is deallocate */
1284 deallocLocal (tree->values.sym);
1287 processBlockVars (tree->left, stack, action);
1288 processBlockVars (tree->right, stack, action);
1293 /*-------------------------------------------------------------*/
1294 /* constExprTree - returns TRUE if this tree is a constant */
1296 /*-------------------------------------------------------------*/
1297 bool constExprTree (ast *cexpr) {
1303 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1305 switch (cexpr->type)
1308 if (IS_AST_LIT_VALUE(cexpr)) {
1309 // this is a literal
1312 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1313 // a function's address will never change
1316 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1317 // an array's address will never change
1320 if (IS_AST_SYM_VALUE(cexpr) &&
1321 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1322 // a symbol in code space will never change
1323 // This is only for the 'char *s="hallo"' case and will have to leave
1324 //printf(" code space symbol");
1329 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1330 "unexpected link in expression tree\n");
1333 if (cexpr->opval.op==ARRAYINIT) {
1334 // this is a list of literals
1337 if (cexpr->opval.op=='=') {
1338 return constExprTree(cexpr->right);
1340 if (cexpr->opval.op==CAST) {
1341 // cast ignored, maybe we should throw a warning here?
1342 return constExprTree(cexpr->right);
1344 if (cexpr->opval.op=='&') {
1347 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1350 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1355 return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1360 /*-----------------------------------------------------------------*/
1361 /* constExprValue - returns the value of a constant expression */
1362 /* or NULL if it is not a constant expression */
1363 /*-----------------------------------------------------------------*/
1365 constExprValue (ast * cexpr, int check)
1367 cexpr = decorateType (resolveSymbols (cexpr), RESULT_CHECK);
1369 /* if this is not a constant then */
1370 if (!IS_LITERAL (cexpr->ftype))
1372 /* then check if this is a literal array
1374 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1375 SPEC_CVAL (cexpr->etype).v_char &&
1376 IS_ARRAY (cexpr->ftype))
1378 value *val = valFromType (cexpr->ftype);
1379 SPEC_SCLS (val->etype) = S_LITERAL;
1380 val->sym = cexpr->opval.val->sym;
1381 val->sym->type = copyLinkChain (cexpr->ftype);
1382 val->sym->etype = getSpec (val->sym->type);
1383 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1387 /* if we are casting a literal value then */
1388 if (IS_AST_OP (cexpr) &&
1389 cexpr->opval.op == CAST &&
1390 IS_LITERAL (cexpr->right->ftype))
1392 return valCastLiteral (cexpr->ftype,
1393 floatFromVal (cexpr->right->opval.val));
1396 if (IS_AST_VALUE (cexpr))
1398 return cexpr->opval.val;
1402 werror (E_CONST_EXPECTED, "found expression");
1407 /* return the value */
1408 return cexpr->opval.val;
1412 /*-----------------------------------------------------------------*/
1413 /* isLabelInAst - will return true if a given label is found */
1414 /*-----------------------------------------------------------------*/
1416 isLabelInAst (symbol * label, ast * tree)
1418 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1421 if (IS_AST_OP (tree) &&
1422 tree->opval.op == LABEL &&
1423 isSymbolEqual (AST_SYMBOL (tree->left), label))
1426 return isLabelInAst (label, tree->right) &&
1427 isLabelInAst (label, tree->left);
1431 /*-----------------------------------------------------------------*/
1432 /* isLoopCountable - return true if the loop count can be determi- */
1433 /* -ned at compile time . */
1434 /*-----------------------------------------------------------------*/
1436 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1437 symbol ** sym, ast ** init, ast ** end)
1440 /* the loop is considered countable if the following
1441 conditions are true :-
1443 a) initExpr :- <sym> = <const>
1444 b) condExpr :- <sym> < <const1>
1445 c) loopExpr :- <sym> ++
1448 /* first check the initExpr */
1449 if (IS_AST_OP (initExpr) &&
1450 initExpr->opval.op == '=' && /* is assignment */
1451 IS_AST_SYM_VALUE (initExpr->left))
1452 { /* left is a symbol */
1454 *sym = AST_SYMBOL (initExpr->left);
1455 *init = initExpr->right;
1460 /* for now the symbol has to be of
1462 if (!IS_INTEGRAL ((*sym)->type))
1465 /* now check condExpr */
1466 if (IS_AST_OP (condExpr))
1469 switch (condExpr->opval.op)
1472 if (IS_AST_SYM_VALUE (condExpr->left) &&
1473 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1474 IS_AST_LIT_VALUE (condExpr->right))
1476 *end = condExpr->right;
1482 if (IS_AST_OP (condExpr->left) &&
1483 condExpr->left->opval.op == '>' &&
1484 IS_AST_LIT_VALUE (condExpr->left->right) &&
1485 IS_AST_SYM_VALUE (condExpr->left->left) &&
1486 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1489 *end = newNode ('+', condExpr->left->right,
1490 newAst_VALUE (constVal ("1")));
1501 /* check loop expression is of the form <sym>++ */
1502 if (!IS_AST_OP (loopExpr))
1505 /* check if <sym> ++ */
1506 if (loopExpr->opval.op == INC_OP)
1512 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1513 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1520 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1521 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1529 if (loopExpr->opval.op == ADD_ASSIGN)
1532 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1533 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1534 IS_AST_LIT_VALUE (loopExpr->right) &&
1535 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1543 /*-----------------------------------------------------------------*/
1544 /* astHasVolatile - returns true if ast contains any volatile */
1545 /*-----------------------------------------------------------------*/
1547 astHasVolatile (ast * tree)
1552 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1555 if (IS_AST_OP (tree))
1556 return astHasVolatile (tree->left) ||
1557 astHasVolatile (tree->right);
1562 /*-----------------------------------------------------------------*/
1563 /* astHasPointer - return true if the ast contains any ptr variable */
1564 /*-----------------------------------------------------------------*/
1566 astHasPointer (ast * tree)
1571 if (IS_AST_LINK (tree))
1574 /* if we hit an array expression then check
1575 only the left side */
1576 if (IS_AST_OP (tree) && tree->opval.op == '[')
1577 return astHasPointer (tree->left);
1579 if (IS_AST_VALUE (tree))
1580 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1582 return astHasPointer (tree->left) ||
1583 astHasPointer (tree->right);
1587 /*-----------------------------------------------------------------*/
1588 /* astHasSymbol - return true if the ast has the given symbol */
1589 /*-----------------------------------------------------------------*/
1591 astHasSymbol (ast * tree, symbol * sym)
1593 if (!tree || IS_AST_LINK (tree))
1596 if (IS_AST_VALUE (tree))
1598 if (IS_AST_SYM_VALUE (tree))
1599 return isSymbolEqual (AST_SYMBOL (tree), sym);
1604 return astHasSymbol (tree->left, sym) ||
1605 astHasSymbol (tree->right, sym);
1608 /*-----------------------------------------------------------------*/
1609 /* astHasDeref - return true if the ast has an indirect access */
1610 /*-----------------------------------------------------------------*/
1612 astHasDeref (ast * tree)
1614 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1617 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1619 return astHasDeref (tree->left) || astHasDeref (tree->right);
1622 /*-----------------------------------------------------------------*/
1623 /* isConformingBody - the loop body has to conform to a set of rules */
1624 /* for the loop to be considered reversible read on for rules */
1625 /*-----------------------------------------------------------------*/
1627 isConformingBody (ast * pbody, symbol * sym, ast * body)
1630 /* we are going to do a pre-order traversal of the
1631 tree && check for the following conditions. (essentially
1632 a set of very shallow tests )
1633 a) the sym passed does not participate in
1634 any arithmetic operation
1635 b) There are no function calls
1636 c) all jumps are within the body
1637 d) address of loop control variable not taken
1638 e) if an assignment has a pointer on the
1639 left hand side make sure right does not have
1640 loop control variable */
1642 /* if we reach the end or a leaf then true */
1643 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1646 /* if anything else is "volatile" */
1647 if (IS_VOLATILE (TETYPE (pbody)))
1650 /* we will walk the body in a pre-order traversal for
1652 switch (pbody->opval.op)
1654 /*------------------------------------------------------------------*/
1656 // if the loopvar is used as an index
1657 if (astHasSymbol(pbody->right, sym)) {
1660 return isConformingBody (pbody->right, sym, body);
1662 /*------------------------------------------------------------------*/
1667 /*------------------------------------------------------------------*/
1671 /* sure we are not sym is not modified */
1673 IS_AST_SYM_VALUE (pbody->left) &&
1674 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1678 IS_AST_SYM_VALUE (pbody->right) &&
1679 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1684 /*------------------------------------------------------------------*/
1686 case '*': /* can be unary : if right is null then unary operation */
1691 /* if right is NULL then unary operation */
1692 /*------------------------------------------------------------------*/
1693 /*----------------------------*/
1695 /*----------------------------*/
1698 if (IS_AST_SYM_VALUE (pbody->left) &&
1699 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1702 return isConformingBody (pbody->left, sym, body);
1706 if (astHasSymbol (pbody->left, sym) ||
1707 astHasSymbol (pbody->right, sym))
1712 /*------------------------------------------------------------------*/
1720 if (IS_AST_SYM_VALUE (pbody->left) &&
1721 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1724 if (IS_AST_SYM_VALUE (pbody->right) &&
1725 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1728 return isConformingBody (pbody->left, sym, body) &&
1729 isConformingBody (pbody->right, sym, body);
1737 if (IS_AST_SYM_VALUE (pbody->left) &&
1738 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1740 return isConformingBody (pbody->left, sym, body);
1742 /*------------------------------------------------------------------*/
1754 case SIZEOF: /* evaluate wihout code generation */
1756 if (IS_AST_SYM_VALUE (pbody->left) &&
1757 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1760 if (IS_AST_SYM_VALUE (pbody->right) &&
1761 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1764 return isConformingBody (pbody->left, sym, body) &&
1765 isConformingBody (pbody->right, sym, body);
1767 /*------------------------------------------------------------------*/
1770 /* if left has a pointer & right has loop
1771 control variable then we cannot */
1772 if (astHasPointer (pbody->left) &&
1773 astHasSymbol (pbody->right, sym))
1775 if (astHasVolatile (pbody->left))
1778 if (IS_AST_SYM_VALUE (pbody->left)) {
1779 // if the loopvar has an assignment
1780 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1782 // if the loopvar is used in another (maybe conditional) block
1783 if (astHasSymbol (pbody->right, sym) &&
1784 (pbody->level >= body->level)) {
1789 if (astHasVolatile (pbody->left))
1792 if (astHasDeref(pbody->right)) return FALSE;
1794 return isConformingBody (pbody->left, sym, body) &&
1795 isConformingBody (pbody->right, sym, body);
1806 assert ("Parser should not have generated this\n");
1808 /*------------------------------------------------------------------*/
1809 /*----------------------------*/
1810 /* comma operator */
1811 /*----------------------------*/
1813 return isConformingBody (pbody->left, sym, body) &&
1814 isConformingBody (pbody->right, sym, body);
1816 /*------------------------------------------------------------------*/
1817 /*----------------------------*/
1819 /*----------------------------*/
1821 /* if local & not passed as paramater then ok */
1822 if (sym->level && !astHasSymbol(pbody->right,sym))
1826 /*------------------------------------------------------------------*/
1827 /*----------------------------*/
1828 /* return statement */
1829 /*----------------------------*/
1834 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1839 if (astHasSymbol (pbody->left, sym))
1846 return isConformingBody (pbody->left, sym, body) &&
1847 isConformingBody (pbody->right, sym, body);
1853 /*-----------------------------------------------------------------*/
1854 /* isLoopReversible - takes a for loop as input && returns true */
1855 /* if the for loop is reversible. If yes will set the value of */
1856 /* the loop control var & init value & termination value */
1857 /*-----------------------------------------------------------------*/
1859 isLoopReversible (ast * loop, symbol ** loopCntrl,
1860 ast ** init, ast ** end)
1862 /* if option says don't do it then don't */
1863 if (optimize.noLoopReverse)
1865 /* there are several tests to determine this */
1867 /* for loop has to be of the form
1868 for ( <sym> = <const1> ;
1869 [<sym> < <const2>] ;
1870 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1872 if (!isLoopCountable (AST_FOR (loop, initExpr),
1873 AST_FOR (loop, condExpr),
1874 AST_FOR (loop, loopExpr),
1875 loopCntrl, init, end))
1878 /* now do some serious checking on the body of the loop
1881 return isConformingBody (loop->left, *loopCntrl, loop->left);
1885 /*-----------------------------------------------------------------*/
1886 /* replLoopSym - replace the loop sym by loop sym -1 */
1887 /*-----------------------------------------------------------------*/
1889 replLoopSym (ast * body, symbol * sym)
1892 if (!body || IS_AST_LINK (body))
1895 if (IS_AST_SYM_VALUE (body))
1898 if (isSymbolEqual (AST_SYMBOL (body), sym))
1902 body->opval.op = '-';
1903 body->left = newAst_VALUE (symbolVal (sym));
1904 body->right = newAst_VALUE (constVal ("1"));
1912 replLoopSym (body->left, sym);
1913 replLoopSym (body->right, sym);
1917 /*-----------------------------------------------------------------*/
1918 /* reverseLoop - do the actual loop reversal */
1919 /*-----------------------------------------------------------------*/
1921 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1925 /* create the following tree
1930 if (sym) goto for_continue ;
1933 /* put it together piece by piece */
1934 rloop = newNode (NULLOP,
1935 createIf (newAst_VALUE (symbolVal (sym)),
1937 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1940 newAst_VALUE (symbolVal (sym)),
1943 replLoopSym (loop->left, sym);
1944 setAstLineno (rloop, init->lineno);
1946 rloop = newNode (NULLOP,
1948 newAst_VALUE (symbolVal (sym)),
1949 newNode ('-', end, init)),
1950 createLabel (AST_FOR (loop, continueLabel),
1954 newNode (SUB_ASSIGN,
1955 newAst_VALUE (symbolVal (sym)),
1956 newAst_VALUE (constVal ("1"))),
1959 rloop->lineno=init->lineno;
1960 return decorateType (rloop, RESULT_CHECK);
1964 /*-----------------------------------------------------------------*/
1965 /* searchLitOp - search tree (*ops only) for an ast with literal */
1966 /*-----------------------------------------------------------------*/
1968 searchLitOp (ast *tree, ast **parent, const char *ops)
1972 if (tree && optimize.global_cse)
1974 /* is there a literal operand? */
1976 IS_AST_OP(tree->right) &&
1977 tree->right->right &&
1978 (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1980 if (IS_LITERAL (RTYPE (tree->right)) ^
1981 IS_LITERAL (LTYPE (tree->right)))
1983 tree->right->decorated = 0;
1984 tree->decorated = 0;
1988 ret = searchLitOp (tree->right, parent, ops);
1993 IS_AST_OP(tree->left) &&
1994 tree->left->right &&
1995 (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1997 if (IS_LITERAL (RTYPE (tree->left)) ^
1998 IS_LITERAL (LTYPE (tree->left)))
2000 tree->left->decorated = 0;
2001 tree->decorated = 0;
2005 ret = searchLitOp (tree->left, parent, ops);
2013 /*-----------------------------------------------------------------*/
2014 /* getResultFromType */
2015 /*-----------------------------------------------------------------*/
2017 getResultTypeFromType (sym_link *type)
2019 /* type = getSpec (type); */
2020 if (IS_BITVAR (type))
2021 return RESULT_TYPE_BIT;
2022 if (IS_BITFIELD (type))
2023 return RESULT_TYPE_CHAR;
2025 return RESULT_TYPE_CHAR;
2028 return RESULT_TYPE_INT;
2029 return RESULT_TYPE_OTHER;
2032 /*-----------------------------------------------------------------*/
2033 /* addCast - adds casts to a type specified by RESULT_TYPE */
2034 /*-----------------------------------------------------------------*/
2036 addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
2039 bool upCasted = FALSE;
2043 case RESULT_TYPE_NONE:
2044 /* char: promote to int */
2046 getSize (tree->etype) >= INTSIZE)
2048 newLink = newIntLink();
2051 case RESULT_TYPE_CHAR:
2052 if (getSize (tree->etype) <= 1)
2054 newLink = newCharLink();
2056 case RESULT_TYPE_INT:
2058 if (getSize (tree->etype) > INTSIZE)
2060 /* warn ("Loosing significant digits"); */
2064 /* char: promote to int */
2066 getSize (tree->etype) >= INTSIZE)
2068 newLink = newIntLink();
2071 case RESULT_TYPE_OTHER:
2074 /* return type is long, float: promote char to int */
2075 if (getSize (tree->etype) >= INTSIZE)
2077 newLink = newIntLink();
2083 tree->decorated = 0;
2084 tree = newNode (CAST, newAst_LINK (newLink), tree);
2085 /* keep unsigned type during cast to smaller type,
2086 but not when promoting from char to int */
2088 SPEC_USIGN (tree->left->opval.lnk) = IS_UNSIGNED (tree->right->etype) ? 1 : 0;
2089 return decorateType (tree, resultType);
2092 /*-----------------------------------------------------------------*/
2093 /* resultTypePropagate - decides if resultType can be propagated */
2094 /*-----------------------------------------------------------------*/
2096 resultTypePropagate (ast *tree, RESULT_TYPE resultType)
2098 switch (tree->opval.op)
2109 return RESULT_TYPE_NONE;
2113 return RESULT_TYPE_NONE;
2117 /*-----------------------------------------------------------------*/
2118 /* getLeftResultType - gets type from left branch for propagation */
2119 /*-----------------------------------------------------------------*/
2121 getLeftResultType (ast *tree, RESULT_TYPE resultType)
2123 switch (tree->opval.op)
2127 if (IS_PTR (LTYPE (tree)))
2128 return RESULT_TYPE_NONE;
2130 return getResultTypeFromType (LETYPE (tree));
2132 if (IS_PTR (currFunc->type->next))
2133 return RESULT_TYPE_NONE;
2135 return getResultTypeFromType (currFunc->type->next);
2137 if (!IS_ARRAY (LTYPE (tree)))
2139 if (DCL_ELEM (LTYPE (tree)) > 0 && DCL_ELEM (LTYPE (tree)) <= 256)
2140 return RESULT_TYPE_CHAR;
2147 /*--------------------------------------------------------------------*/
2148 /* decorateType - compute type for this tree, also does type checking.*/
2149 /* This is done bottom up, since type has to flow upwards. */
2150 /* resultType flows top-down and forces e.g. char-arithmetik, if the */
2151 /* result is a char and the operand(s) are int's. */
2152 /* It also does constant folding, and parameter checking. */
2153 /*--------------------------------------------------------------------*/
2155 decorateType (ast * tree, RESULT_TYPE resultType)
2159 RESULT_TYPE resultTypeProp;
2164 /* if already has type then do nothing */
2165 if (tree->decorated)
2168 tree->decorated = 1;
2171 /* print the line */
2172 /* if not block & function */
2173 if (tree->type == EX_OP &&
2174 (tree->opval.op != FUNCTION &&
2175 tree->opval.op != BLOCK &&
2176 tree->opval.op != NULLOP))
2178 filename = tree->filename;
2179 lineno = tree->lineno;
2183 /* if any child is an error | this one is an error do nothing */
2184 if (tree->isError ||
2185 (tree->left && tree->left->isError) ||
2186 (tree->right && tree->right->isError))
2189 /*------------------------------------------------------------------*/
2190 /*----------------------------*/
2191 /* leaf has been reached */
2192 /*----------------------------*/
2193 lineno=tree->lineno;
2194 /* if this is of type value */
2195 /* just get the type */
2196 if (tree->type == EX_VALUE)
2199 if (IS_LITERAL (tree->opval.val->etype))
2202 /* if this is a character array then declare it */
2203 if (IS_ARRAY (tree->opval.val->type))
2204 tree->opval.val = stringToSymbol (tree->opval.val);
2206 /* otherwise just copy the type information */
2207 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2211 if (tree->opval.val->sym)
2213 /* if the undefined flag is set then give error message */
2214 if (tree->opval.val->sym->undefined)
2216 werror (E_ID_UNDEF, tree->opval.val->sym->name);
2218 TTYPE (tree) = TETYPE (tree) =
2219 tree->opval.val->type = tree->opval.val->sym->type =
2220 tree->opval.val->etype = tree->opval.val->sym->etype =
2221 copyLinkChain (INTTYPE);
2226 /* if impilicit i.e. struct/union member then no type */
2227 if (tree->opval.val->sym->implicit)
2228 TTYPE (tree) = TETYPE (tree) = NULL;
2233 /* else copy the type */
2234 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2236 /* and mark it as referenced */
2237 tree->opval.val->sym->isref = 1;
2245 /* if type link for the case of cast */
2246 if (tree->type == EX_LINK)
2248 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2256 if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2258 if (tree->left && tree->left->type == EX_OPERAND
2259 && (tree->left->opval.op == INC_OP
2260 || tree->left->opval.op == DEC_OP)
2261 && tree->left->left)
2263 tree->left->right = tree->left->left;
2264 tree->left->left = NULL;
2266 if (tree->right && tree->right->type == EX_OPERAND
2267 && (tree->right->opval.op == INC_OP
2268 || tree->right->opval.op == DEC_OP)
2269 && tree->right->left)
2271 tree->right->right = tree->right->left;
2272 tree->right->left = NULL;
2277 /* Before decorating the left branch we've to decide in dependence
2278 upon tree->opval.op, if resultType can be propagated */
2279 resultTypeProp = resultTypePropagate (tree, resultType);
2281 dtl = decorateType (tree->left, resultTypeProp);
2283 /* if an array node, we may need to swap branches */
2284 if (tree->opval.op == '[')
2286 /* determine which is the array & which the index */
2287 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) &&
2288 IS_INTEGRAL (LTYPE (tree)))
2290 ast *tempTree = tree->left;
2291 tree->left = tree->right;
2292 tree->right = tempTree;
2296 /* After decorating the left branch there's type information available
2297 in tree->left->?type. If the op is e.g. '=' we extract the type
2298 information from there and propagate it to the right branch. */
2299 resultTypeProp = getLeftResultType (tree, resultTypeProp);
2301 switch (tree->opval.op)
2304 /* delay right side for '?' operator since conditional macro
2305 expansions might rely on this */
2309 /* decorate right side for CALL (parameter list) in processParms();
2310 there is resultType available */
2314 dtr = decorateType (tree->right, resultTypeProp);
2318 /* this is to take care of situations
2319 when the tree gets rewritten */
2320 if (dtl != tree->left)
2322 if (dtr != tree->right)
2324 if ((dtl && dtl->isError) || (dtr && dtr->isError))
2328 /* depending on type of operator do */
2330 switch (tree->opval.op)
2332 /*------------------------------------------------------------------*/
2333 /*----------------------------*/
2335 /*----------------------------*/
2338 /* first check if this is a array or a pointer */
2339 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2341 werror (E_NEED_ARRAY_PTR, "[]");
2342 goto errorTreeReturn;
2345 /* check if the type of the idx */
2346 if (!IS_INTEGRAL (RTYPE (tree)))
2348 werror (E_IDX_NOT_INT);
2349 goto errorTreeReturn;
2352 /* if the left is an rvalue then error */
2355 werror (E_LVALUE_REQUIRED, "array access");
2356 goto errorTreeReturn;
2359 if (IS_LITERAL (RTYPE (tree)))
2361 int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
2362 int arraySize = DCL_ELEM (LTYPE (tree));
2363 if (arraySize && arrayIndex >= arraySize)
2365 werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
2370 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2373 /*------------------------------------------------------------------*/
2374 /*----------------------------*/
2376 /*----------------------------*/
2378 /* if this is not a structure */
2379 if (!IS_STRUCT (LTYPE (tree)))
2381 werror (E_STRUCT_UNION, ".");
2382 goto errorTreeReturn;
2384 TTYPE (tree) = structElemType (LTYPE (tree),
2385 (tree->right->type == EX_VALUE ?
2386 tree->right->opval.val : NULL));
2387 TETYPE (tree) = getSpec (TTYPE (tree));
2390 /*------------------------------------------------------------------*/
2391 /*----------------------------*/
2392 /* struct/union pointer */
2393 /*----------------------------*/
2395 /* if not pointer to a structure */
2396 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2398 werror (E_PTR_REQD);
2399 goto errorTreeReturn;
2402 if (!IS_STRUCT (LTYPE (tree)->next))
2404 werror (E_STRUCT_UNION, "->");
2405 goto errorTreeReturn;
2408 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2409 (tree->right->type == EX_VALUE ?
2410 tree->right->opval.val : NULL));
2411 TETYPE (tree) = getSpec (TTYPE (tree));
2413 /* adjust the storage class */
2414 switch (DCL_TYPE(tree->left->ftype)) {
2416 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2419 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2422 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2425 SPEC_SCLS (TETYPE (tree)) = 0;
2428 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2431 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2434 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2437 SPEC_SCLS (TETYPE (tree)) = 0;
2444 /* This breaks with extern declarations, bitfields, and perhaps other */
2445 /* cases (gcse). Let's leave this optimization disabled for now and */
2446 /* ponder if there's a safe way to do this. -- EEP */
2448 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2449 && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2451 /* If defined struct type at addr var
2452 then rewrite (&struct var)->member
2454 and define membertype at (addr+offsetof(struct var,member)) temp
2457 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2458 AST_SYMBOL(tree->right));
2460 sym = newSymbol(genSymName (0), 0);
2461 sym->type = TTYPE (tree);
2462 sym->etype = getSpec(sym->type);
2463 sym->lineDef = tree->lineno;
2466 SPEC_STAT (sym->etype) = 1;
2467 SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2469 SPEC_ABSA(sym->etype) = 1;
2470 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2473 AST_VALUE (tree) = symbolVal(sym);
2476 tree->type = EX_VALUE;
2484 /*------------------------------------------------------------------*/
2485 /*----------------------------*/
2486 /* ++/-- operation */
2487 /*----------------------------*/
2491 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2492 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2493 if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2494 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2503 /*------------------------------------------------------------------*/
2504 /*----------------------------*/
2506 /*----------------------------*/
2507 case '&': /* can be unary */
2508 /* if right is NULL then unary operation */
2509 if (tree->right) /* not an unary operation */
2512 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2514 werror (E_BITWISE_OP);
2515 werror (W_CONTINUE, "left & right types are ");
2516 printTypeChain (LTYPE (tree), stderr);
2517 fprintf (stderr, ",");
2518 printTypeChain (RTYPE (tree), stderr);
2519 fprintf (stderr, "\n");
2520 goto errorTreeReturn;
2523 /* if they are both literal */
2524 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2526 tree->type = EX_VALUE;
2527 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2528 valFromType (RETYPE (tree)), '&');
2530 tree->right = tree->left = NULL;
2531 TETYPE (tree) = tree->opval.val->etype;
2532 TTYPE (tree) = tree->opval.val->type;
2536 /* see if this is a GETHBIT operation if yes
2539 ast *otree = optimizeGetHbit (tree);
2542 return decorateType (otree, RESULT_CHECK);
2545 tree->left = addCast (tree->left, resultType, FALSE);
2546 tree->right = addCast (tree->right, resultType, FALSE);
2547 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
2548 TETYPE (tree) = getSpec (TTYPE (tree));
2550 /* if left is a literal exchange left & right */
2551 if (IS_LITERAL (LTYPE (tree)))
2553 ast *tTree = tree->left;
2554 tree->left = tree->right;
2555 tree->right = tTree;
2558 /* if right is a literal and */
2559 /* we can find a 2nd literal in a and-tree then */
2560 /* rearrange the tree */
2561 if (IS_LITERAL (RTYPE (tree)))
2564 ast *litTree = searchLitOp (tree, &parent, "&");
2567 ast *tTree = litTree->left;
2568 litTree->left = tree->right;
2569 tree->right = tTree;
2570 /* both operands in tTree are literal now */
2571 decorateType (parent, RESULT_CHECK);
2575 LRVAL (tree) = RRVAL (tree) = 1;
2580 /*------------------------------------------------------------------*/
2581 /*----------------------------*/
2583 /*----------------------------*/
2584 p = newLink (DECLARATOR);
2585 /* if bit field then error */
2586 if (IS_BITVAR (tree->left->etype))
2588 werror (E_ILLEGAL_ADDR, "address of bit variable");
2589 goto errorTreeReturn;
2592 if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2594 werror (E_ILLEGAL_ADDR, "address of register variable");
2595 goto errorTreeReturn;
2598 if (IS_FUNC (LTYPE (tree)))
2600 // this ought to be ignored
2601 return (tree->left);
2604 if (IS_LITERAL(LTYPE(tree)))
2606 werror (E_ILLEGAL_ADDR, "address of literal");
2607 goto errorTreeReturn;
2612 werror (E_LVALUE_REQUIRED, "address of");
2613 goto errorTreeReturn;
2616 DCL_TYPE (p) = POINTER;
2617 else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2618 DCL_TYPE (p) = CPOINTER;
2619 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2620 DCL_TYPE (p) = FPOINTER;
2621 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2622 DCL_TYPE (p) = PPOINTER;
2623 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2624 DCL_TYPE (p) = IPOINTER;
2625 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2626 DCL_TYPE (p) = EEPPOINTER;
2627 else if (SPEC_OCLS(tree->left->etype))
2628 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2630 DCL_TYPE (p) = POINTER;
2632 if (IS_AST_SYM_VALUE (tree->left))
2634 AST_SYMBOL (tree->left)->addrtaken = 1;
2635 AST_SYMBOL (tree->left)->allocreq = 1;
2638 p->next = LTYPE (tree);
2640 TETYPE (tree) = getSpec (TTYPE (tree));
2645 if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2646 && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2648 symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2649 AST_SYMBOL(tree->left->right));
2650 AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2651 valueFromLit(element->offset));
2654 tree->type = EX_VALUE;
2655 tree->values.literalFromCast = 1;
2661 /*------------------------------------------------------------------*/
2662 /*----------------------------*/
2664 /*----------------------------*/
2666 /* if the rewrite succeeds then don't go any furthur */
2668 ast *wtree = optimizeRRCRLC (tree);
2670 return decorateType (wtree, RESULT_CHECK);
2672 wtree = optimizeSWAP (tree);
2674 return decorateType (wtree, RESULT_CHECK);
2677 /* if left is a literal exchange left & right */
2678 if (IS_LITERAL (LTYPE (tree)))
2680 ast *tTree = tree->left;
2681 tree->left = tree->right;
2682 tree->right = tTree;
2685 /* if right is a literal and */
2686 /* we can find a 2nd literal in a or-tree then */
2687 /* rearrange the tree */
2688 if (IS_LITERAL (RTYPE (tree)))
2691 ast *litTree = searchLitOp (tree, &parent, "|");
2694 ast *tTree = litTree->left;
2695 litTree->left = tree->right;
2696 tree->right = tTree;
2697 /* both operands in tTree are literal now */
2698 decorateType (parent, RESULT_CHECK);
2703 /*------------------------------------------------------------------*/
2704 /*----------------------------*/
2706 /*----------------------------*/
2708 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2710 werror (E_BITWISE_OP);
2711 werror (W_CONTINUE, "left & right types are ");
2712 printTypeChain (LTYPE (tree), stderr);
2713 fprintf (stderr, ",");
2714 printTypeChain (RTYPE (tree), stderr);
2715 fprintf (stderr, "\n");
2716 goto errorTreeReturn;
2719 /* if they are both literal then */
2720 /* rewrite the tree */
2721 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2723 tree->type = EX_VALUE;
2724 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2725 valFromType (RETYPE (tree)),
2727 tree->right = tree->left = NULL;
2728 TETYPE (tree) = tree->opval.val->etype;
2729 TTYPE (tree) = tree->opval.val->type;
2733 /* if left is a literal exchange left & right */
2734 if (IS_LITERAL (LTYPE (tree)))
2736 ast *tTree = tree->left;
2737 tree->left = tree->right;
2738 tree->right = tTree;
2741 /* if right is a literal and */
2742 /* we can find a 2nd literal in a xor-tree then */
2743 /* rearrange the tree */
2744 if (IS_LITERAL (RTYPE (tree)) &&
2745 tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2748 ast *litTree = searchLitOp (tree, &parent, "^");
2751 ast *tTree = litTree->left;
2752 litTree->left = tree->right;
2753 tree->right = tTree;
2754 /* both operands in litTree are literal now */
2755 decorateType (parent, RESULT_CHECK);
2759 LRVAL (tree) = RRVAL (tree) = 1;
2760 tree->left = addCast (tree->left, resultType, FALSE);
2761 tree->right = addCast (tree->right, resultType, FALSE);
2762 TETYPE (tree) = getSpec (TTYPE (tree) =
2763 computeType (LTYPE (tree),
2769 /*------------------------------------------------------------------*/
2770 /*----------------------------*/
2772 /*----------------------------*/
2774 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2776 werror (E_INVALID_OP, "divide");
2777 goto errorTreeReturn;
2779 /* if they are both literal then */
2780 /* rewrite the tree */
2781 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2783 tree->type = EX_VALUE;
2784 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2785 valFromType (RETYPE (tree)));
2786 tree->right = tree->left = NULL;
2787 TETYPE (tree) = getSpec (TTYPE (tree) =
2788 tree->opval.val->type);
2792 LRVAL (tree) = RRVAL (tree) = 1;
2793 TETYPE (tree) = getSpec (TTYPE (tree) =
2794 computeType (LTYPE (tree),
2796 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2798 /* if right is a literal and */
2799 /* left is also a division by a literal then */
2800 /* rearrange the tree */
2801 if (IS_LITERAL (RTYPE (tree))
2802 /* avoid infinite loop */
2803 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2806 ast *litTree = searchLitOp (tree, &parent, "/");
2809 if (IS_LITERAL (RTYPE (litTree)))
2812 litTree->right = newNode ('*', litTree->right, tree->right);
2813 litTree->right->lineno = tree->lineno;
2815 tree->right->opval.val = constVal ("1");
2816 decorateType (parent, RESULT_CHECK);
2820 /* litTree->left is literal: no gcse possible.
2821 We can't call decorateType(parent, RESULT_CHECK), because
2822 this would cause an infinit loop. */
2823 parent->decorated = 1;
2824 decorateType (litTree, RESULT_CHECK);
2831 /*------------------------------------------------------------------*/
2832 /*----------------------------*/
2834 /*----------------------------*/
2836 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2838 werror (E_BITWISE_OP);
2839 werror (W_CONTINUE, "left & right types are ");
2840 printTypeChain (LTYPE (tree), stderr);
2841 fprintf (stderr, ",");
2842 printTypeChain (RTYPE (tree), stderr);
2843 fprintf (stderr, "\n");
2844 goto errorTreeReturn;
2846 /* if they are both literal then */
2847 /* rewrite the tree */
2848 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2850 tree->type = EX_VALUE;
2851 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2852 valFromType (RETYPE (tree)));
2853 tree->right = tree->left = NULL;
2854 TETYPE (tree) = getSpec (TTYPE (tree) =
2855 tree->opval.val->type);
2858 LRVAL (tree) = RRVAL (tree) = 1;
2859 TETYPE (tree) = getSpec (TTYPE (tree) =
2860 computeType (LTYPE (tree),
2862 ! (IS_UNSIGNED (LTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)))));
2865 /*------------------------------------------------------------------*/
2866 /*----------------------------*/
2867 /* address dereference */
2868 /*----------------------------*/
2869 case '*': /* can be unary : if right is null then unary operation */
2872 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2874 werror (E_PTR_REQD);
2875 goto errorTreeReturn;
2880 werror (E_LVALUE_REQUIRED, "pointer deref");
2881 goto errorTreeReturn;
2883 if (IS_ADDRESS_OF_OP(tree->left))
2885 /* replace *&obj with obj */
2886 return tree->left->left;
2888 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2889 TETYPE (tree) = getSpec (TTYPE (tree));
2890 /* adjust the storage class */
2891 switch (DCL_TYPE(tree->left->ftype)) {
2893 SPEC_SCLS(TETYPE(tree)) = S_DATA;
2896 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2899 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2902 SPEC_SCLS (TETYPE (tree)) = 0;
2905 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2908 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2911 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2914 SPEC_SCLS (TETYPE (tree)) = 0;
2923 /*------------------------------------------------------------------*/
2924 /*----------------------------*/
2925 /* multiplication */
2926 /*----------------------------*/
2927 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2929 werror (E_INVALID_OP, "multiplication");
2930 goto errorTreeReturn;
2933 /* if they are both literal then */
2934 /* rewrite the tree */
2935 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2937 tree->type = EX_VALUE;
2938 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2939 valFromType (RETYPE (tree)));
2940 tree->right = tree->left = NULL;
2941 TETYPE (tree) = getSpec (TTYPE (tree) =
2942 tree->opval.val->type);
2946 /* if left is a literal exchange left & right */
2947 if (IS_LITERAL (LTYPE (tree)))
2949 ast *tTree = tree->left;
2950 tree->left = tree->right;
2951 tree->right = tTree;
2954 /* if right is a literal and */
2955 /* we can find a 2nd literal in a mul-tree then */
2956 /* rearrange the tree */
2957 if (IS_LITERAL (RTYPE (tree)))
2960 ast *litTree = searchLitOp (tree, &parent, "*");
2963 ast *tTree = litTree->left;
2964 litTree->left = tree->right;
2965 tree->right = tTree;
2966 /* both operands in litTree are literal now */
2967 decorateType (parent, RESULT_CHECK);
2971 LRVAL (tree) = RRVAL (tree) = 1;
2972 tree->left = addCast (tree->left, resultType, FALSE);
2973 tree->right = addCast (tree->right, resultType, FALSE);
2974 TETYPE (tree) = getSpec (TTYPE (tree) =
2975 computeType (LTYPE (tree),
2977 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
2981 /*------------------------------------------------------------------*/
2982 /*----------------------------*/
2983 /* unary '+' operator */
2984 /*----------------------------*/
2989 if (!IS_ARITHMETIC (LTYPE (tree)))
2991 werror (E_UNARY_OP, '+');
2992 goto errorTreeReturn;
2995 /* if left is a literal then do it */
2996 if (IS_LITERAL (LTYPE (tree)))
2998 tree->type = EX_VALUE;
2999 tree->opval.val = valFromType (LETYPE (tree));
3001 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3005 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3009 /*------------------------------------------------------------------*/
3010 /*----------------------------*/
3012 /*----------------------------*/
3014 /* this is not a unary operation */
3015 /* if both pointers then problem */
3016 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3017 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
3019 werror (E_PTR_PLUS_PTR);
3020 goto errorTreeReturn;
3023 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3024 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
3026 werror (E_PLUS_INVALID, "+");
3027 goto errorTreeReturn;
3030 if (!IS_ARITHMETIC (RTYPE (tree)) &&
3031 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
3033 werror (E_PLUS_INVALID, "+");
3034 goto errorTreeReturn;
3036 /* if they are both literal then */
3037 /* rewrite the tree */
3038 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3040 tree->type = EX_VALUE;
3041 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
3042 valFromType (RETYPE (tree)));
3043 tree->right = tree->left = NULL;
3044 TETYPE (tree) = getSpec (TTYPE (tree) =
3045 tree->opval.val->type);
3049 /* if the right is a pointer or left is a literal
3050 xchange left & right */
3051 if (IS_ARRAY (RTYPE (tree)) ||
3052 IS_PTR (RTYPE (tree)) ||
3053 IS_LITERAL (LTYPE (tree)))
3055 ast *tTree = tree->left;
3056 tree->left = tree->right;
3057 tree->right = tTree;
3060 /* if right is a literal and */
3061 /* left is also an addition/subtraction with a literal then */
3062 /* rearrange the tree */
3063 if (IS_LITERAL (RTYPE (tree)))
3065 ast *litTree, *parent;
3066 litTree = searchLitOp (tree, &parent, "+-");
3069 if (litTree->opval.op == '+')
3072 ast *tTree = litTree->left;
3073 litTree->left = tree->right;
3074 tree->right = tree->left;
3077 else if (litTree->opval.op == '-')
3079 if (IS_LITERAL (RTYPE (litTree)))
3082 ast *tTree = litTree->left;
3083 litTree->left = tree->right;
3084 tree->right = tTree;
3089 ast *tTree = litTree->right;
3090 litTree->right = tree->right;
3091 tree->right = tTree;
3092 litTree->opval.op = '+';
3093 tree->opval.op = '-';
3096 decorateType (parent, RESULT_CHECK);
3100 LRVAL (tree) = RRVAL (tree) = 1;
3101 /* if the left is a pointer */
3102 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
3103 TETYPE (tree) = getSpec (TTYPE (tree) =
3107 tree->left = addCast (tree->left, resultType, TRUE);
3108 tree->right = addCast (tree->right, resultType, TRUE);
3109 TETYPE (tree) = getSpec (TTYPE (tree) =
3110 computeType (LTYPE (tree),
3112 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3117 /*------------------------------------------------------------------*/
3118 /*----------------------------*/
3120 /*----------------------------*/
3121 case '-': /* can be unary */
3122 /* if right is null then unary */
3126 if (!IS_ARITHMETIC (LTYPE (tree)))
3128 werror (E_UNARY_OP, tree->opval.op);
3129 goto errorTreeReturn;
3132 /* if left is a literal then do it */
3133 if (IS_LITERAL (LTYPE (tree)))
3135 tree->type = EX_VALUE;
3136 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
3138 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3139 SPEC_USIGN(TETYPE(tree)) = 0;
3143 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3147 /*------------------------------------------------------------------*/
3148 /*----------------------------*/
3150 /*----------------------------*/
3152 if (!(IS_PTR (LTYPE (tree)) ||
3153 IS_ARRAY (LTYPE (tree)) ||
3154 IS_ARITHMETIC (LTYPE (tree))))
3156 werror (E_PLUS_INVALID, "-");
3157 goto errorTreeReturn;
3160 if (!(IS_PTR (RTYPE (tree)) ||
3161 IS_ARRAY (RTYPE (tree)) ||
3162 IS_ARITHMETIC (RTYPE (tree))))
3164 werror (E_PLUS_INVALID, "-");
3165 goto errorTreeReturn;
3168 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
3169 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
3170 IS_INTEGRAL (RTYPE (tree))))
3172 werror (E_PLUS_INVALID, "-");
3173 goto errorTreeReturn;
3176 /* if they are both literal then */
3177 /* rewrite the tree */
3178 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3180 tree->type = EX_VALUE;
3181 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3182 valFromType (RETYPE (tree)));
3183 tree->right = tree->left = NULL;
3184 TETYPE (tree) = getSpec (TTYPE (tree) =
3185 tree->opval.val->type);
3189 /* if the left & right are equal then zero */
3190 if (isAstEqual (tree->left, tree->right))
3192 tree->type = EX_VALUE;
3193 tree->left = tree->right = NULL;
3194 tree->opval.val = constVal ("0");
3195 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3199 /* if both of them are pointers or arrays then */
3200 /* the result is going to be an integer */
3201 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3202 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3203 TETYPE (tree) = TTYPE (tree) = newIntLink ();
3205 /* if only the left is a pointer */
3206 /* then result is a pointer */
3207 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3208 TETYPE (tree) = getSpec (TTYPE (tree) =
3212 tree->left = addCast (tree->left, resultType, TRUE);
3213 tree->right = addCast (tree->right, resultType, TRUE);
3214 TETYPE (tree) = getSpec (TTYPE (tree) =
3215 computeType (LTYPE (tree),
3217 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3220 LRVAL (tree) = RRVAL (tree) = 1;
3222 /* if right is a literal and */
3223 /* left is also an addition/subtraction with a literal then */
3224 /* rearrange the tree */
3225 if (IS_LITERAL (RTYPE (tree))
3226 /* avoid infinite loop */
3227 && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3229 ast *litTree, *litParent;
3230 litTree = searchLitOp (tree, &litParent, "+-");
3233 if (litTree->opval.op == '+')
3236 litTree->right = newNode ('-', litTree->right, tree->right);
3237 litTree->right->lineno = tree->lineno;
3239 tree->right->opval.val = constVal ("0");
3241 else if (litTree->opval.op == '-')
3243 if (IS_LITERAL (RTYPE (litTree)))
3246 litTree->right = newNode ('+', tree->right, litTree->right);
3247 litTree->right->lineno = tree->lineno;
3249 tree->right->opval.val = constVal ("0");
3254 ast *tTree = litTree->right;
3255 litTree->right = tree->right;
3256 tree->right = tTree;
3259 decorateType (litParent, RESULT_CHECK);
3264 /*------------------------------------------------------------------*/
3265 /*----------------------------*/
3267 /*----------------------------*/
3269 /* can be only integral type */
3270 if (!IS_INTEGRAL (LTYPE (tree)))
3272 werror (E_UNARY_OP, tree->opval.op);
3273 goto errorTreeReturn;
3276 /* if left is a literal then do it */
3277 if (IS_LITERAL (LTYPE (tree)))
3279 tree->type = EX_VALUE;
3280 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3282 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3286 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3289 /*------------------------------------------------------------------*/
3290 /*----------------------------*/
3292 /*----------------------------*/
3294 /* can be pointer */
3295 if (!IS_ARITHMETIC (LTYPE (tree)) &&
3296 !IS_PTR (LTYPE (tree)) &&
3297 !IS_ARRAY (LTYPE (tree)))
3299 werror (E_UNARY_OP, tree->opval.op);
3300 goto errorTreeReturn;
3303 /* if left is a literal then do it */
3304 if (IS_LITERAL (LTYPE (tree)))
3306 tree->type = EX_VALUE;
3307 tree->opval.val = valNot (valFromType (LETYPE (tree)));
3309 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3313 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3316 /*------------------------------------------------------------------*/
3317 /*----------------------------*/
3319 /*----------------------------*/
3323 TTYPE (tree) = LTYPE (tree);
3324 TETYPE (tree) = LETYPE (tree);
3328 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3333 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3335 werror (E_SHIFT_OP_INVALID);
3336 werror (W_CONTINUE, "left & right types are ");
3337 printTypeChain (LTYPE (tree), stderr);
3338 fprintf (stderr, ",");
3339 printTypeChain (RTYPE (tree), stderr);
3340 fprintf (stderr, "\n");
3341 goto errorTreeReturn;
3344 /* if they are both literal then */
3345 /* rewrite the tree */
3346 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3348 tree->type = EX_VALUE;
3349 tree->opval.val = valShift (valFromType (LETYPE (tree)),
3350 valFromType (RETYPE (tree)),
3351 (tree->opval.op == LEFT_OP ? 1 : 0));
3352 tree->right = tree->left = NULL;
3353 TETYPE (tree) = getSpec (TTYPE (tree) =
3354 tree->opval.val->type);
3358 LRVAL (tree) = RRVAL (tree) = 1;
3359 if (tree->opval.op == LEFT_OP)
3361 tree->left = addCast (tree->left, resultType, TRUE);
3362 TETYPE (tree) = getSpec (TTYPE (tree) =
3363 computeType (LTYPE (tree),
3365 resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
3369 /* no promotion necessary */
3370 TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3371 if (IS_LITERAL (TTYPE (tree)))
3372 SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3375 /* if only the right side is a literal & we are
3376 shifting more than size of the left operand then zero */
3377 if (IS_LITERAL (RTYPE (tree)) &&
3378 ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3379 (getSize (TETYPE (tree)) * 8))
3381 if (tree->opval.op==LEFT_OP ||
3382 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3384 lineno=tree->lineno;
3385 werror (W_SHIFT_CHANGED,
3386 (tree->opval.op == LEFT_OP ? "left" : "right"));
3387 tree->type = EX_VALUE;
3388 tree->left = tree->right = NULL;
3389 tree->opval.val = constVal ("0");
3390 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3397 /*------------------------------------------------------------------*/
3398 /*----------------------------*/
3400 /*----------------------------*/
3401 case CAST: /* change the type */
3402 /* cannot cast to an aggregate type */
3403 if (IS_AGGREGATE (LTYPE (tree)))
3405 werror (E_CAST_ILLEGAL);
3406 goto errorTreeReturn;
3409 /* make sure the type is complete and sane */
3410 checkTypeSanity(LETYPE(tree), "(cast)");
3412 /* If code memory is read only, then pointers to code memory */
3413 /* implicitly point to constants -- make this explicit */
3415 sym_link *t = LTYPE(tree);
3416 while (t && t->next)
3418 if (IS_CODEPTR(t) && port->mem.code_ro)
3420 if (IS_SPEC(t->next))
3421 SPEC_CONST (t->next) = 1;
3423 DCL_PTR_CONST (t->next) = 1;
3430 /* if the right is a literal replace the tree */
3431 if (IS_LITERAL (RETYPE (tree))) {
3432 if (!IS_PTR (LTYPE (tree))) {
3433 tree->type = EX_VALUE;
3435 valCastLiteral (LTYPE (tree),
3436 floatFromVal (valFromType (RETYPE (tree))));
3439 TTYPE (tree) = tree->opval.val->type;
3440 tree->values.literalFromCast = 1;
3441 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3442 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
3443 sym_link *rest = LTYPE(tree)->next;
3444 werror(W_LITERAL_GENERIC);
3445 TTYPE(tree) = newLink(DECLARATOR);
3446 DCL_TYPE(TTYPE(tree)) = FPOINTER;
3447 TTYPE(tree)->next = rest;
3448 tree->left->opval.lnk = TTYPE(tree);
3451 TTYPE (tree) = LTYPE (tree);
3455 TTYPE (tree) = LTYPE (tree);
3459 #if 0 // this is already checked, now this could be explicit
3460 /* if pointer to struct then check names */
3461 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3462 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3463 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3465 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3466 SPEC_STRUCT(LETYPE(tree))->tag);
3469 if (IS_ADDRESS_OF_OP(tree->right)
3470 && IS_AST_SYM_VALUE (tree->right->left)
3471 && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3473 tree->type = EX_VALUE;
3475 valCastLiteral (LTYPE (tree),
3476 SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3477 TTYPE (tree) = tree->opval.val->type;
3478 TETYPE (tree) = getSpec (TTYPE (tree));
3481 tree->values.literalFromCast = 1;
3485 /* handle offsetof macro: */
3486 /* #define offsetof(TYPE, MEMBER) \ */
3487 /* ((unsigned) &((TYPE *)0)->MEMBER) */
3488 if (IS_ADDRESS_OF_OP(tree->right)
3489 && IS_AST_OP (tree->right->left)
3490 && tree->right->left->opval.op == PTR_OP
3491 && IS_AST_OP (tree->right->left->left)
3492 && tree->right->left->left->opval.op == CAST
3493 && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3495 symbol *element = getStructElement (
3496 SPEC_STRUCT (LETYPE(tree->right->left)),
3497 AST_SYMBOL(tree->right->left->right)
3501 tree->type = EX_VALUE;
3502 tree->opval.val = valCastLiteral (
3505 + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3508 TTYPE (tree) = tree->opval.val->type;
3509 TETYPE (tree) = getSpec (TTYPE (tree));
3516 /* if the right is a literal replace the tree */
3517 if (IS_LITERAL (RETYPE (tree))) {
3519 if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3520 /* rewrite (type *)litaddr
3522 and define type at litaddr temp
3523 (but only if type's storage class is not generic)
3525 ast *newTree = newNode ('&', NULL, NULL);
3528 TTYPE (newTree) = LTYPE (tree);
3529 TETYPE (newTree) = getSpec(LTYPE (tree));
3531 /* define a global symbol at the casted address*/
3532 sym = newSymbol(genSymName (0), 0);
3533 sym->type = LTYPE (tree)->next;
3535 sym->type = newLink (V_VOID);
3536 sym->etype = getSpec(sym->type);
3537 SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3538 sym->lineDef = tree->lineno;
3541 SPEC_STAT (sym->etype) = 1;
3542 SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3543 SPEC_ABSA(sym->etype) = 1;
3544 addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3547 newTree->left = newAst_VALUE(symbolVal(sym));
3548 newTree->left->lineno = tree->lineno;
3549 LTYPE (newTree) = sym->type;
3550 LETYPE (newTree) = sym->etype;
3551 LLVAL (newTree) = 1;
3552 LRVAL (newTree) = 0;
3553 TLVAL (newTree) = 1;
3557 if (!IS_PTR (LTYPE (tree))) {
3558 tree->type = EX_VALUE;
3560 valCastLiteral (LTYPE (tree),
3561 floatFromVal (valFromType (RTYPE (tree))));
3562 TTYPE (tree) = tree->opval.val->type;
3565 tree->values.literalFromCast = 1;
3566 TETYPE (tree) = getSpec (TTYPE (tree));
3570 TTYPE (tree) = LTYPE (tree);
3574 TETYPE (tree) = getSpec (TTYPE (tree));
3578 /*------------------------------------------------------------------*/
3579 /*----------------------------*/
3580 /* logical &&, || */
3581 /*----------------------------*/
3584 /* each must me arithmetic type or be a pointer */
3585 if (!IS_PTR (LTYPE (tree)) &&
3586 !IS_ARRAY (LTYPE (tree)) &&
3587 !IS_INTEGRAL (LTYPE (tree)))
3589 werror (E_COMPARE_OP);
3590 goto errorTreeReturn;
3593 if (!IS_PTR (RTYPE (tree)) &&
3594 !IS_ARRAY (RTYPE (tree)) &&
3595 !IS_INTEGRAL (RTYPE (tree)))
3597 werror (E_COMPARE_OP);
3598 goto errorTreeReturn;
3600 /* if they are both literal then */
3601 /* rewrite the tree */
3602 if (IS_LITERAL (RTYPE (tree)) &&
3603 IS_LITERAL (LTYPE (tree)))
3605 tree->type = EX_VALUE;
3606 tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3607 valFromType (RTYPE (tree)),
3609 tree->right = tree->left = NULL;
3610 TETYPE (tree) = getSpec (TTYPE (tree) =
3611 tree->opval.val->type);
3614 LRVAL (tree) = RRVAL (tree) = 1;
3615 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3618 /*------------------------------------------------------------------*/
3619 /*----------------------------*/
3620 /* comparison operators */
3621 /*----------------------------*/
3629 ast *lt = optimizeCompare (tree);
3635 /* if they are pointers they must be castable */
3636 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3638 if (tree->opval.op==EQ_OP &&
3639 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3640 // we cannot cast a gptr to a !gptr: switch the leaves
3641 struct ast *s=tree->left;
3642 tree->left=tree->right;
3645 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3647 werror (E_COMPARE_OP);
3648 fprintf (stderr, "comparing type ");
3649 printTypeChain (LTYPE (tree), stderr);
3650 fprintf (stderr, "to type ");
3651 printTypeChain (RTYPE (tree), stderr);
3652 fprintf (stderr, "\n");
3653 goto errorTreeReturn;
3656 /* else they should be promotable to one another */
3659 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3660 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3662 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3664 werror (E_COMPARE_OP);
3665 fprintf (stderr, "comparing type ");
3666 printTypeChain (LTYPE (tree), stderr);
3667 fprintf (stderr, "to type ");
3668 printTypeChain (RTYPE (tree), stderr);
3669 fprintf (stderr, "\n");
3670 goto errorTreeReturn;
3673 /* if unsigned value < 0 then always false */
3674 /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3675 if (SPEC_USIGN(LETYPE(tree)) &&
3676 !IS_CHAR(LETYPE(tree)) && /* promotion to signed int */
3677 IS_LITERAL(RTYPE(tree)) &&
3678 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3680 if (tree->opval.op == '<')
3684 if (tree->opval.op == '>')
3686 /* if the parent is an ifx, then we could do */
3687 /* return tree->left; */
3688 tree->opval.op = '?';
3689 tree->right = newNode (':',
3690 newAst_VALUE (constVal ("1")),
3691 tree->right); /* val 0 */
3692 tree->right->lineno = tree->lineno;
3693 tree->right->left->lineno = tree->lineno;
3694 decorateType (tree->right, RESULT_CHECK);
3697 /* if they are both literal then */
3698 /* rewrite the tree */
3699 if (IS_LITERAL (RTYPE (tree)) &&
3700 IS_LITERAL (LTYPE (tree)))
3702 tree->type = EX_VALUE;
3703 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3704 valFromType (RETYPE (tree)),
3706 tree->right = tree->left = NULL;
3707 TETYPE (tree) = getSpec (TTYPE (tree) =
3708 tree->opval.val->type);
3711 LRVAL (tree) = RRVAL (tree) = 1;
3712 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3715 /*------------------------------------------------------------------*/
3716 /*----------------------------*/
3718 /*----------------------------*/
3719 case SIZEOF: /* evaluate wihout code generation */
3720 /* change the type to a integer */
3722 int size = getSize (tree->right->ftype);
3723 SNPRINTF(buffer, sizeof(buffer), "%d", size);
3724 if (!size && !IS_VOID(tree->right->ftype))
3725 werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
3727 tree->type = EX_VALUE;
3728 tree->opval.val = constVal (buffer);
3729 tree->right = tree->left = NULL;
3730 TETYPE (tree) = getSpec (TTYPE (tree) =
3731 tree->opval.val->type);
3734 /*------------------------------------------------------------------*/
3735 /*----------------------------*/
3737 /*----------------------------*/
3739 /* return typeof enum value */
3740 tree->type = EX_VALUE;
3743 if (IS_SPEC(tree->right->ftype)) {
3744 switch (SPEC_NOUN(tree->right->ftype)) {
3746 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3747 else typeofv = TYPEOF_INT;
3750 typeofv = TYPEOF_FLOAT;
3753 typeofv = TYPEOF_CHAR;
3756 typeofv = TYPEOF_VOID;
3759 typeofv = TYPEOF_STRUCT;
3762 typeofv = TYPEOF_BITFIELD;
3765 typeofv = TYPEOF_BIT;
3768 typeofv = TYPEOF_SBIT;
3774 switch (DCL_TYPE(tree->right->ftype)) {
3776 typeofv = TYPEOF_POINTER;
3779 typeofv = TYPEOF_FPOINTER;
3782 typeofv = TYPEOF_CPOINTER;
3785 typeofv = TYPEOF_GPOINTER;
3788 typeofv = TYPEOF_PPOINTER;
3791 typeofv = TYPEOF_IPOINTER;
3794 typeofv = TYPEOF_ARRAY;
3797 typeofv = TYPEOF_FUNCTION;
3803 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3804 tree->opval.val = constVal (buffer);
3805 tree->right = tree->left = NULL;
3806 TETYPE (tree) = getSpec (TTYPE (tree) =
3807 tree->opval.val->type);
3810 /*------------------------------------------------------------------*/
3811 /*----------------------------*/
3812 /* conditional operator '?' */
3813 /*----------------------------*/
3815 /* the type is value of the colon operator (on the right) */
3816 assert (IS_COLON_OP (tree->right));
3817 /* if already known then replace the tree : optimizer will do it
3818 but faster to do it here */
3819 if (IS_LITERAL (LTYPE (tree)))
3821 if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
3822 return decorateType (tree->right->left, resultTypeProp);
3824 return decorateType (tree->right->right, resultTypeProp);
3828 tree->right = decorateType (tree->right, resultTypeProp);
3829 TTYPE (tree) = RTYPE (tree);
3830 TETYPE (tree) = getSpec (TTYPE (tree));
3835 /* if they don't match we have a problem */
3836 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3838 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3839 goto errorTreeReturn;
3842 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3843 TETYPE (tree) = getSpec (TTYPE (tree));
3847 #if 0 // assignment operators are converted by the parser
3848 /*------------------------------------------------------------------*/
3849 /*----------------------------*/
3850 /* assignment operators */
3851 /*----------------------------*/
3854 /* for these it must be both must be integral */
3855 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3856 !IS_ARITHMETIC (RTYPE (tree)))
3858 werror (E_OPS_INTEGRAL);
3859 goto errorTreeReturn;
3862 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3864 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3865 werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3869 werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3870 goto errorTreeReturn;
3881 /* for these it must be both must be integral */
3882 if (!IS_INTEGRAL (LTYPE (tree)) ||
3883 !IS_INTEGRAL (RTYPE (tree)))
3885 werror (E_OPS_INTEGRAL);
3886 goto errorTreeReturn;
3889 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3891 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3892 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3896 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3897 goto errorTreeReturn;
3903 /*------------------------------------------------------------------*/
3904 /*----------------------------*/
3906 /*----------------------------*/
3908 if (!(IS_PTR (LTYPE (tree)) ||
3909 IS_ARITHMETIC (LTYPE (tree))))
3911 werror (E_PLUS_INVALID, "-=");
3912 goto errorTreeReturn;
3915 if (!(IS_PTR (RTYPE (tree)) ||
3916 IS_ARITHMETIC (RTYPE (tree))))
3918 werror (E_PLUS_INVALID, "-=");
3919 goto errorTreeReturn;
3922 TETYPE (tree) = getSpec (TTYPE (tree) =
3923 computeType (LTYPE (tree),
3927 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3928 werror (E_CODE_WRITE, "-=");
3932 werror (E_LVALUE_REQUIRED, "-=");
3933 goto errorTreeReturn;
3939 /*------------------------------------------------------------------*/
3940 /*----------------------------*/
3942 /*----------------------------*/
3944 /* this is not a unary operation */
3945 /* if both pointers then problem */
3946 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3948 werror (E_PTR_PLUS_PTR);
3949 goto errorTreeReturn;
3952 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3954 werror (E_PLUS_INVALID, "+=");
3955 goto errorTreeReturn;
3958 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3960 werror (E_PLUS_INVALID, "+=");
3961 goto errorTreeReturn;
3964 TETYPE (tree) = getSpec (TTYPE (tree) =
3965 computeType (LTYPE (tree),
3969 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3970 werror (E_CODE_WRITE, "+=");
3974 werror (E_LVALUE_REQUIRED, "+=");
3975 goto errorTreeReturn;
3978 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_CHECK);
3979 tree->opval.op = '=';
3984 /*------------------------------------------------------------------*/
3985 /*----------------------------*/
3986 /* straight assignemnt */
3987 /*----------------------------*/
3989 /* cannot be an aggregate */
3990 if (IS_AGGREGATE (LTYPE (tree)))
3992 werror (E_AGGR_ASSIGN);
3993 goto errorTreeReturn;
3996 /* they should either match or be castable */
3997 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3999 werror (E_TYPE_MISMATCH, "assignment", " ");
4000 printFromToType(RTYPE(tree),LTYPE(tree));
4003 /* if the left side of the tree is of type void
4004 then report error */
4005 if (IS_VOID (LTYPE (tree)))
4007 werror (E_CAST_ZERO);
4008 printFromToType(RTYPE(tree), LTYPE(tree));
4011 TETYPE (tree) = getSpec (TTYPE (tree) =
4015 if (!tree->initMode ) {
4016 if (IS_CONSTANT(LTYPE(tree)))
4017 werror (E_CODE_WRITE, "=");
4021 werror (E_LVALUE_REQUIRED, "=");
4022 goto errorTreeReturn;
4027 /*------------------------------------------------------------------*/
4028 /*----------------------------*/
4029 /* comma operator */
4030 /*----------------------------*/
4032 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4035 /*------------------------------------------------------------------*/
4036 /*----------------------------*/
4038 /*----------------------------*/
4041 /* undo any explicit pointer derefernce; PCALL will handle it instead */
4042 if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4044 if (tree->left->opval.op == '*' && !tree->left->right)
4045 tree->left = tree->left->left;
4048 /* require a function or pointer to function */
4049 if (!IS_FUNC (LTYPE (tree))
4050 && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
4052 werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4053 goto errorTreeReturn;
4060 if (IS_CODEPTR(LTYPE(tree)))
4061 functype = LTYPE (tree)->next;
4063 functype = LTYPE (tree);
4065 if (processParms (tree->left, FUNC_ARGS(functype),
4066 tree->right, &parmNumber, TRUE)) {
4067 goto errorTreeReturn;
4070 if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4071 !IFFUNC_ISBUILTIN(functype))
4073 reverseParms (tree->right);
4076 TTYPE (tree) = functype->next;
4077 TETYPE (tree) = getSpec (TTYPE (tree));
4081 /*------------------------------------------------------------------*/
4082 /*----------------------------*/
4083 /* return statement */
4084 /*----------------------------*/
4089 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4091 werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4092 printFromToType (RTYPE(tree), currFunc->type->next);
4093 goto errorTreeReturn;
4096 if (IS_VOID (currFunc->type->next)
4098 !IS_VOID (RTYPE (tree)))
4100 werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4101 goto errorTreeReturn;
4104 /* if there is going to be a casting required then add it */
4105 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4108 decorateType (newNode (CAST,
4109 newAst_LINK (copyLinkChain (currFunc->type->next)),
4119 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4121 werror (W_VOID_FUNC, currFunc->name);
4122 goto errorTreeReturn;
4125 TTYPE (tree) = TETYPE (tree) = NULL;
4128 /*------------------------------------------------------------------*/
4129 /*----------------------------*/
4130 /* switch statement */
4131 /*----------------------------*/
4133 /* the switch value must be an integer */
4134 if (!IS_INTEGRAL (LTYPE (tree)))
4136 werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4137 goto errorTreeReturn;
4140 TTYPE (tree) = TETYPE (tree) = NULL;
4143 /*------------------------------------------------------------------*/
4144 /*----------------------------*/
4146 /*----------------------------*/
4148 tree->left = backPatchLabels (tree->left,
4151 TTYPE (tree) = TETYPE (tree) = NULL;
4154 /*------------------------------------------------------------------*/
4155 /*----------------------------*/
4157 /*----------------------------*/
4160 decorateType (resolveSymbols (AST_FOR (tree, initExpr)), RESULT_CHECK);
4161 decorateType (resolveSymbols (AST_FOR (tree, condExpr)), RESULT_CHECK);
4162 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_CHECK);
4164 /* if the for loop is reversible then
4165 reverse it otherwise do what we normally
4171 if (isLoopReversible (tree, &sym, &init, &end))
4172 return reverseLoop (tree, sym, init, end);
4174 return decorateType (createFor (AST_FOR (tree, trueLabel),
4175 AST_FOR (tree, continueLabel),
4176 AST_FOR (tree, falseLabel),
4177 AST_FOR (tree, condLabel),
4178 AST_FOR (tree, initExpr),
4179 AST_FOR (tree, condExpr),
4180 AST_FOR (tree, loopExpr),
4181 tree->left), RESULT_CHECK);
4184 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4185 "node PARAM shouldn't be processed here");
4186 /* but in processParams() */
4189 TTYPE (tree) = TETYPE (tree) = NULL;
4193 /* some error found this tree will be killed */
4195 TTYPE (tree) = TETYPE (tree) = newCharLink ();
4196 tree->opval.op = NULLOP;
4202 /*-----------------------------------------------------------------*/
4203 /* sizeofOp - processes size of operation */
4204 /*-----------------------------------------------------------------*/
4206 sizeofOp (sym_link * type)
4211 /* make sure the type is complete and sane */
4212 checkTypeSanity(type, "(sizeof)");
4214 /* get the size and convert it to character */
4215 SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4216 if (!size && !IS_VOID(type))
4217 werror (E_SIZEOF_INCOMPLETE_TYPE);
4219 /* now convert into value */
4220 return constVal (buff);
4224 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4225 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
4226 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4227 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4228 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4229 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
4230 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
4232 /*-----------------------------------------------------------------*/
4233 /* backPatchLabels - change and or not operators to flow control */
4234 /*-----------------------------------------------------------------*/
4236 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4242 if (!(IS_ANDORNOT (tree)))
4245 /* if this an and */
4248 static int localLbl = 0;
4251 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4252 localLabel = newSymbol (buffer, NestLevel);
4254 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4256 /* if left is already a IFX then just change the if true label in that */
4257 if (!IS_IFX (tree->left))
4258 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4260 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4261 /* right is a IFX then just join */
4262 if (IS_IFX (tree->right))
4263 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4265 tree->right = createLabel (localLabel, tree->right);
4266 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4268 return newNode (NULLOP, tree->left, tree->right);
4271 /* if this is an or operation */
4274 static int localLbl = 0;
4277 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4278 localLabel = newSymbol (buffer, NestLevel);
4280 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4282 /* if left is already a IFX then just change the if true label in that */
4283 if (!IS_IFX (tree->left))
4284 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4286 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4287 /* right is a IFX then just join */
4288 if (IS_IFX (tree->right))
4289 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4291 tree->right = createLabel (localLabel, tree->right);
4292 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4294 return newNode (NULLOP, tree->left, tree->right);
4300 int wasnot = IS_NOT (tree->left);
4301 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4303 /* if the left is already a IFX */
4304 if (!IS_IFX (tree->left))
4305 tree->left = newNode (IFX, tree->left, NULL);
4309 tree->left->trueLabel = trueLabel;
4310 tree->left->falseLabel = falseLabel;
4314 tree->left->trueLabel = falseLabel;
4315 tree->left->falseLabel = trueLabel;
4322 tree->trueLabel = trueLabel;
4323 tree->falseLabel = falseLabel;
4330 /*-----------------------------------------------------------------*/
4331 /* createBlock - create expression tree for block */
4332 /*-----------------------------------------------------------------*/
4334 createBlock (symbol * decl, ast * body)
4338 /* if the block has nothing */
4342 ex = newNode (BLOCK, NULL, body);
4343 ex->values.sym = decl;
4345 ex->right = ex->right;
4351 /*-----------------------------------------------------------------*/
4352 /* createLabel - creates the expression tree for labels */
4353 /*-----------------------------------------------------------------*/
4355 createLabel (symbol * label, ast * stmnt)
4358 char name[SDCC_NAME_MAX + 1];
4361 /* must create fresh symbol if the symbol name */
4362 /* exists in the symbol table, since there can */
4363 /* be a variable with the same name as the labl */
4364 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4365 (csym->level == label->level))
4366 label = newSymbol (label->name, label->level);
4368 /* change the name before putting it in add _ */
4369 SNPRINTF(name, sizeof(name), "%s", label->name);
4371 /* put the label in the LabelSymbol table */
4372 /* but first check if a label of the same */
4374 if ((csym = findSym (LabelTab, NULL, name)))
4375 werror (E_DUPLICATE_LABEL, label->name);
4377 addSym (LabelTab, label, name, label->level, 0, 0);
4380 label->key = labelKey++;
4381 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4387 /*-----------------------------------------------------------------*/
4388 /* createCase - generates the parsetree for a case statement */
4389 /*-----------------------------------------------------------------*/
4391 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4393 char caseLbl[SDCC_NAME_MAX + 1];
4397 /* if the switch statement does not exist */
4398 /* then case is out of context */
4401 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4405 caseVal = decorateType (resolveSymbols (caseVal), RESULT_CHECK);
4406 /* if not a constant then error */
4407 if (!IS_LITERAL (caseVal->ftype))
4409 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4413 /* if not a integer than error */
4414 if (!IS_INTEGRAL (caseVal->ftype))
4416 werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4420 /* find the end of the switch values chain */
4421 if (!(val = swStat->values.switchVals.swVals))
4422 swStat->values.switchVals.swVals = caseVal->opval.val;
4425 /* also order the cases according to value */
4427 int cVal = (int) floatFromVal (caseVal->opval.val);
4428 while (val && (int) floatFromVal (val) < cVal)
4434 /* if we reached the end then */
4437 pval->next = caseVal->opval.val;
4439 else if ((int) floatFromVal (val) == cVal)
4441 werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4447 /* we found a value greater than */
4448 /* the current value we must add this */
4449 /* before the value */
4450 caseVal->opval.val->next = val;
4452 /* if this was the first in chain */
4453 if (swStat->values.switchVals.swVals == val)
4454 swStat->values.switchVals.swVals =
4457 pval->next = caseVal->opval.val;
4462 /* create the case label */
4463 SNPRINTF(caseLbl, sizeof(caseLbl),
4465 swStat->values.switchVals.swNum,
4466 (int) floatFromVal (caseVal->opval.val));
4468 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4473 /*-----------------------------------------------------------------*/
4474 /* createDefault - creates the parse tree for the default statement */
4475 /*-----------------------------------------------------------------*/
4477 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4479 char defLbl[SDCC_NAME_MAX + 1];
4481 /* if the switch statement does not exist */
4482 /* then case is out of context */
4485 werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4489 if (swStat->values.switchVals.swDefault)
4491 werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4496 /* turn on the default flag */
4497 swStat->values.switchVals.swDefault = 1;
4499 /* create the label */
4500 SNPRINTF (defLbl, sizeof(defLbl),
4501 "_default_%d", swStat->values.switchVals.swNum);
4502 return createLabel (newSymbol (defLbl, 0), stmnt);
4505 /*-----------------------------------------------------------------*/
4506 /* createIf - creates the parsetree for the if statement */
4507 /*-----------------------------------------------------------------*/
4509 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4511 static int Lblnum = 0;
4513 symbol *ifTrue, *ifFalse, *ifEnd;
4515 /* if neither exists */
4516 if (!elseBody && !ifBody) {
4517 // if there are no side effects (i++, j() etc)
4518 if (!hasSEFcalls(condAst)) {
4523 /* create the labels */
4524 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4525 ifFalse = newSymbol (buffer, NestLevel);
4526 /* if no else body then end == false */
4531 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4532 ifEnd = newSymbol (buffer, NestLevel);
4535 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4536 ifTrue = newSymbol (buffer, NestLevel);
4540 /* attach the ifTrue label to the top of it body */
4541 ifBody = createLabel (ifTrue, ifBody);
4542 /* attach a goto end to the ifBody if else is present */
4545 ifBody = newNode (NULLOP, ifBody,
4547 newAst_VALUE (symbolVal (ifEnd)),
4549 /* put the elseLabel on the else body */
4550 elseBody = createLabel (ifFalse, elseBody);
4551 /* out the end at the end of the body */
4552 elseBody = newNode (NULLOP,
4554 createLabel (ifEnd, NULL));
4558 ifBody = newNode (NULLOP, ifBody,
4559 createLabel (ifFalse, NULL));
4561 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4562 if (IS_IFX (condAst))
4565 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4567 return newNode (NULLOP, ifTree,
4568 newNode (NULLOP, ifBody, elseBody));
4572 /*-----------------------------------------------------------------*/
4573 /* createDo - creates parse tree for do */
4576 /* _docontinue_n: */
4577 /* condition_expression +-> trueLabel -> _dobody_n */
4579 /* +-> falseLabel-> _dobreak_n */
4581 /*-----------------------------------------------------------------*/
4583 createDo (symbol * trueLabel, symbol * continueLabel,
4584 symbol * falseLabel, ast * condAst, ast * doBody)
4589 /* if the body does not exist then it is simple */
4592 condAst = backPatchLabels (condAst, continueLabel, NULL);
4593 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4594 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4595 doTree->trueLabel = continueLabel;
4596 doTree->falseLabel = NULL;
4600 /* otherwise we have a body */
4601 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4603 /* attach the body label to the top */
4604 doBody = createLabel (trueLabel, doBody);
4605 /* attach the continue label to end of body */
4606 doBody = newNode (NULLOP, doBody,
4607 createLabel (continueLabel, NULL));
4609 /* now put the break label at the end */
4610 if (IS_IFX (condAst))
4613 doTree = newIfxNode (condAst, trueLabel, falseLabel);
4615 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4617 /* putting it together */
4618 return newNode (NULLOP, doBody, doTree);
4621 /*-----------------------------------------------------------------*/
4622 /* createFor - creates parse tree for 'for' statement */
4625 /* condExpr +-> trueLabel -> _forbody_n */
4627 /* +-> falseLabel-> _forbreak_n */
4630 /* _forcontinue_n: */
4632 /* goto _forcond_n ; */
4634 /*-----------------------------------------------------------------*/
4636 createFor (symbol * trueLabel, symbol * continueLabel,
4637 symbol * falseLabel, symbol * condLabel,
4638 ast * initExpr, ast * condExpr, ast * loopExpr,
4643 /* if loopexpression not present then we can generate it */
4644 /* the same way as a while */
4646 return newNode (NULLOP, initExpr,
4647 createWhile (trueLabel, continueLabel,
4648 falseLabel, condExpr, forBody));
4649 /* vanilla for statement */
4650 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4652 if (condExpr && !IS_IFX (condExpr))
4653 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4656 /* attach condition label to condition */
4657 condExpr = createLabel (condLabel, condExpr);
4659 /* attach body label to body */
4660 forBody = createLabel (trueLabel, forBody);
4662 /* attach continue to forLoop expression & attach */
4663 /* goto the forcond @ and of loopExpression */
4664 loopExpr = createLabel (continueLabel,
4668 newAst_VALUE (symbolVal (condLabel)),
4670 /* now start putting them together */
4671 forTree = newNode (NULLOP, initExpr, condExpr);
4672 forTree = newNode (NULLOP, forTree, forBody);
4673 forTree = newNode (NULLOP, forTree, loopExpr);
4674 /* finally add the break label */
4675 forTree = newNode (NULLOP, forTree,
4676 createLabel (falseLabel, NULL));
4680 /*-----------------------------------------------------------------*/
4681 /* createWhile - creates parse tree for while statement */
4682 /* the while statement will be created as follows */
4684 /* _while_continue_n: */
4685 /* condition_expression +-> trueLabel -> _while_boby_n */
4687 /* +-> falseLabel -> _while_break_n */
4688 /* _while_body_n: */
4690 /* goto _while_continue_n */
4691 /* _while_break_n: */
4692 /*-----------------------------------------------------------------*/
4694 createWhile (symbol * trueLabel, symbol * continueLabel,
4695 symbol * falseLabel, ast * condExpr, ast * whileBody)
4699 /* put the continue label */
4700 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4701 condExpr = createLabel (continueLabel, condExpr);
4702 condExpr->lineno = 0;
4704 /* put the body label in front of the body */
4705 whileBody = createLabel (trueLabel, whileBody);
4706 whileBody->lineno = 0;
4707 /* put a jump to continue at the end of the body */
4708 /* and put break label at the end of the body */
4709 whileBody = newNode (NULLOP,
4712 newAst_VALUE (symbolVal (continueLabel)),
4713 createLabel (falseLabel, NULL)));
4715 /* put it all together */
4716 if (IS_IFX (condExpr))
4717 whileTree = condExpr;
4720 whileTree = newNode (IFX, condExpr, NULL);
4721 /* put the true & false labels in place */
4722 whileTree->trueLabel = trueLabel;
4723 whileTree->falseLabel = falseLabel;
4726 return newNode (NULLOP, whileTree, whileBody);
4729 /*-----------------------------------------------------------------*/
4730 /* optimizeGetHbit - get highest order bit of the expression */
4731 /*-----------------------------------------------------------------*/
4733 optimizeGetHbit (ast * tree)
4736 /* if this is not a bit and */
4737 if (!IS_BITAND (tree))
4740 /* will look for tree of the form
4741 ( expr >> ((sizeof expr) -1) ) & 1 */
4742 if (!IS_AST_LIT_VALUE (tree->right))
4745 if (AST_LIT_VALUE (tree->right) != 1)
4748 if (!IS_RIGHT_OP (tree->left))
4751 if (!IS_AST_LIT_VALUE (tree->left->right))
4754 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4755 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4758 /* make sure the port supports GETHBIT */
4759 if (port->hasExtBitOp
4760 && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4763 return decorateType (newNode (GETHBIT, tree->left->left, NULL), RESULT_CHECK);
4767 /*-----------------------------------------------------------------*/
4768 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
4769 /*-----------------------------------------------------------------*/
4771 optimizeRRCRLC (ast * root)
4773 /* will look for trees of the form
4774 (?expr << 1) | (?expr >> 7) or
4775 (?expr >> 7) | (?expr << 1) will make that
4776 into a RLC : operation ..
4778 (?expr >> 1) | (?expr << 7) or
4779 (?expr << 7) | (?expr >> 1) will make that
4780 into a RRC operation
4781 note : by 7 I mean (number of bits required to hold the
4783 /* if the root operations is not a | operation the not */
4784 if (!IS_BITOR (root))
4787 /* I have to think of a better way to match patterns this sucks */
4788 /* that aside let start looking for the first case : I use a the
4789 negative check a lot to improve the efficiency */
4790 /* (?expr << 1) | (?expr >> 7) */
4791 if (IS_LEFT_OP (root->left) &&
4792 IS_RIGHT_OP (root->right))
4795 if (!SPEC_USIGN (TETYPE (root->left->left)))
4798 if (!IS_AST_LIT_VALUE (root->left->right) ||
4799 !IS_AST_LIT_VALUE (root->right->right))
4802 /* make sure it is the same expression */
4803 if (!isAstEqual (root->left->left,
4807 if (AST_LIT_VALUE (root->left->right) != 1)
4810 if (AST_LIT_VALUE (root->right->right) !=
4811 (getSize (TTYPE (root->left->left)) * 8 - 1))
4814 /* make sure the port supports RLC */
4815 if (port->hasExtBitOp
4816 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4819 /* whew got the first case : create the AST */
4820 return newNode (RLC, root->left->left, NULL);
4824 /* check for second case */
4825 /* (?expr >> 7) | (?expr << 1) */
4826 if (IS_LEFT_OP (root->right) &&
4827 IS_RIGHT_OP (root->left))
4830 if (!SPEC_USIGN (TETYPE (root->left->left)))
4833 if (!IS_AST_LIT_VALUE (root->left->right) ||
4834 !IS_AST_LIT_VALUE (root->right->right))
4837 /* make sure it is the same symbol */
4838 if (!isAstEqual (root->left->left,
4842 if (AST_LIT_VALUE (root->right->right) != 1)
4845 if (AST_LIT_VALUE (root->left->right) !=
4846 (getSize (TTYPE (root->left->left)) * 8 - 1))
4849 /* make sure the port supports RLC */
4850 if (port->hasExtBitOp
4851 && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4854 /* whew got the first case : create the AST */
4855 return newNode (RLC, root->left->left, NULL);
4860 /* third case for RRC */
4861 /* (?symbol >> 1) | (?symbol << 7) */
4862 if (IS_LEFT_OP (root->right) &&
4863 IS_RIGHT_OP (root->left))
4866 if (!SPEC_USIGN (TETYPE (root->left->left)))
4869 if (!IS_AST_LIT_VALUE (root->left->right) ||
4870 !IS_AST_LIT_VALUE (root->right->right))
4873 /* make sure it is the same symbol */
4874 if (!isAstEqual (root->left->left,
4878 if (AST_LIT_VALUE (root->left->right) != 1)
4881 if (AST_LIT_VALUE (root->right->right) !=
4882 (getSize (TTYPE (root->left->left)) * 8 - 1))
4885 /* make sure the port supports RRC */
4886 if (port->hasExtBitOp
4887 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4890 /* whew got the first case : create the AST */
4891 return newNode (RRC, root->left->left, NULL);
4895 /* fourth and last case for now */
4896 /* (?symbol << 7) | (?symbol >> 1) */
4897 if (IS_RIGHT_OP (root->right) &&
4898 IS_LEFT_OP (root->left))
4901 if (!SPEC_USIGN (TETYPE (root->left->left)))
4904 if (!IS_AST_LIT_VALUE (root->left->right) ||
4905 !IS_AST_LIT_VALUE (root->right->right))
4908 /* make sure it is the same symbol */
4909 if (!isAstEqual (root->left->left,
4913 if (AST_LIT_VALUE (root->right->right) != 1)
4916 if (AST_LIT_VALUE (root->left->right) !=
4917 (getSize (TTYPE (root->left->left)) * 8 - 1))
4920 /* make sure the port supports RRC */
4921 if (port->hasExtBitOp
4922 && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4925 /* whew got the first case : create the AST */
4926 return newNode (RRC, root->left->left, NULL);
4930 /* not found return root */
4934 /*-----------------------------------------------------------------*/
4935 /* optimizeSWAP :- optimize for nibble/byte/word swaps */
4936 /*-----------------------------------------------------------------*/
4938 optimizeSWAP (ast * root)
4940 /* will look for trees of the form
4941 (?expr << 4) | (?expr >> 4) or
4942 (?expr >> 4) | (?expr << 4) will make that
4943 into a SWAP : operation ..
4944 note : by 4 I mean (number of bits required to hold the
4946 /* if the root operations is not a | operation the not */
4947 if (!IS_BITOR (root))
4950 /* (?expr << 4) | (?expr >> 4) */
4951 if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4952 || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4955 if (!SPEC_USIGN (TETYPE (root->left->left)))
4958 if (!IS_AST_LIT_VALUE (root->left->right) ||
4959 !IS_AST_LIT_VALUE (root->right->right))
4962 /* make sure it is the same expression */
4963 if (!isAstEqual (root->left->left,
4967 if (AST_LIT_VALUE (root->left->right) !=
4968 (getSize (TTYPE (root->left->left)) * 4))
4971 if (AST_LIT_VALUE (root->right->right) !=
4972 (getSize (TTYPE (root->left->left)) * 4))
4975 /* make sure the port supports SWAP */
4976 if (port->hasExtBitOp
4977 && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4980 /* found it : create the AST */
4981 return newNode (SWAP, root->left->left, NULL);
4985 /* not found return root */
4989 /*-----------------------------------------------------------------*/
4990 /* optimizeCompare - otimizes compares for bit variables */
4991 /*-----------------------------------------------------------------*/
4993 optimizeCompare (ast * root)
4995 ast *optExpr = NULL;
4998 unsigned int litValue;
5000 /* if nothing then return nothing */
5004 /* if not a compare op then do leaves */
5005 if (!IS_COMPARE_OP (root))
5007 root->left = optimizeCompare (root->left);
5008 root->right = optimizeCompare (root->right);
5012 /* if left & right are the same then depending
5013 of the operation do */
5014 if (isAstEqual (root->left, root->right))
5016 switch (root->opval.op)
5021 optExpr = newAst_VALUE (constVal ("0"));
5026 optExpr = newAst_VALUE (constVal ("1"));
5030 return decorateType (optExpr, RESULT_CHECK);
5033 vleft = (root->left->type == EX_VALUE ?
5034 root->left->opval.val : NULL);
5036 vright = (root->right->type == EX_VALUE ?
5037 root->right->opval.val : NULL);
5039 /* if left is a BITVAR in BITSPACE */
5040 /* and right is a LITERAL then opt- */
5041 /* imize else do nothing */
5042 if (vleft && vright &&
5043 IS_BITVAR (vleft->etype) &&
5044 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5045 IS_LITERAL (vright->etype))
5048 /* if right side > 1 then comparison may never succeed */
5049 if ((litValue = (int) floatFromVal (vright)) > 1)
5051 werror (W_BAD_COMPARE);
5057 switch (root->opval.op)
5059 case '>': /* bit value greater than 1 cannot be */
5060 werror (W_BAD_COMPARE);
5064 case '<': /* bit value < 1 means 0 */
5066 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5069 case LE_OP: /* bit value <= 1 means no check */
5070 optExpr = newAst_VALUE (vright);
5073 case GE_OP: /* bit value >= 1 means only check for = */
5075 optExpr = newAst_VALUE (vleft);
5080 { /* literal is zero */
5081 switch (root->opval.op)
5083 case '<': /* bit value < 0 cannot be */
5084 werror (W_BAD_COMPARE);
5088 case '>': /* bit value > 0 means 1 */
5090 optExpr = newAst_VALUE (vleft);
5093 case LE_OP: /* bit value <= 0 means no check */
5094 case GE_OP: /* bit value >= 0 means no check */
5095 werror (W_BAD_COMPARE);
5099 case EQ_OP: /* bit == 0 means ! of bit */
5100 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5104 return decorateType (resolveSymbols (optExpr), RESULT_CHECK);
5105 } /* end-of-if of BITVAR */
5110 /*-----------------------------------------------------------------*/
5111 /* addSymToBlock : adds the symbol to the first block we find */
5112 /*-----------------------------------------------------------------*/
5114 addSymToBlock (symbol * sym, ast * tree)
5116 /* reached end of tree or a leaf */
5117 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5121 if (IS_AST_OP (tree) &&
5122 tree->opval.op == BLOCK)
5125 symbol *lsym = copySymbol (sym);
5127 lsym->next = AST_VALUES (tree, sym);
5128 AST_VALUES (tree, sym) = lsym;
5132 addSymToBlock (sym, tree->left);
5133 addSymToBlock (sym, tree->right);
5136 /*-----------------------------------------------------------------*/
5137 /* processRegParms - do processing for register parameters */
5138 /*-----------------------------------------------------------------*/
5140 processRegParms (value * args, ast * body)
5144 if (IS_REGPARM (args->etype))
5145 addSymToBlock (args->sym, body);
5150 /*-----------------------------------------------------------------*/
5151 /* resetParmKey - resets the operandkeys for the symbols */
5152 /*-----------------------------------------------------------------*/
5153 DEFSETFUNC (resetParmKey)
5164 /*-----------------------------------------------------------------*/
5165 /* createFunction - This is the key node that calls the iCode for */
5166 /* generating the code for a function. Note code */
5167 /* is generated function by function, later when */
5168 /* add inter-procedural analysis this will change */
5169 /*-----------------------------------------------------------------*/
5171 createFunction (symbol * name, ast * body)
5177 iCode *piCode = NULL;
5179 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5180 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5182 /* if check function return 0 then some problem */
5183 if (checkFunction (name, NULL) == 0)
5186 /* create a dummy block if none exists */
5188 body = newNode (BLOCK, NULL, NULL);
5192 /* check if the function name already in the symbol table */
5193 if ((csym = findSym (SymbolTab, NULL, name->name)))
5196 /* special case for compiler defined functions
5197 we need to add the name to the publics list : this
5198 actually means we are now compiling the compiler
5202 addSet (&publics, name);
5208 allocVariables (name);
5210 name->lastLine = mylineno;
5213 /* set the stack pointer */
5214 /* PENDING: check this for the mcs51 */
5215 stackPtr = -port->stack.direction * port->stack.call_overhead;
5216 if (IFFUNC_ISISR (name->type))
5217 stackPtr -= port->stack.direction * port->stack.isr_overhead;
5218 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5219 stackPtr -= port->stack.direction * port->stack.reent_overhead;
5221 xstackPtr = -port->stack.direction * port->stack.call_overhead;
5223 fetype = getSpec (name->type); /* get the specifier for the function */
5224 /* if this is a reentrant function then */
5225 if (IFFUNC_ISREENT (name->type))
5228 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
5230 /* do processing for parameters that are passed in registers */
5231 processRegParms (FUNC_ARGS(name->type), body);
5233 /* set the stack pointer */
5237 /* allocate & autoinit the block variables */
5238 processBlockVars (body, &stack, ALLOCATE);
5240 /* save the stack information */
5241 if (options.useXstack)
5242 name->xstack = SPEC_STAK (fetype) = stack;
5244 name->stack = SPEC_STAK (fetype) = stack;
5246 /* name needs to be mangled */
5247 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5249 body = resolveSymbols (body); /* resolve the symbols */
5250 body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5253 ex = newAst_VALUE (symbolVal (name)); /* create name */
5254 ex = newNode (FUNCTION, ex, body);
5255 ex->values.args = FUNC_ARGS(name->type);
5257 if (options.dump_tree) PA(ex);
5260 werror (E_FUNC_NO_CODE, name->name);
5264 /* create the node & generate intermediate code */
5266 codeOutFile = code->oFile;
5267 piCode = iCodeFromAst (ex);
5271 werror (E_FUNC_NO_CODE, name->name);
5275 eBBlockFromiCode (piCode);
5277 /* if there are any statics then do them */
5280 GcurMemmap = statsg;
5281 codeOutFile = statsg->oFile;
5282 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_CHECK)));
5288 /* dealloc the block variables */
5289 processBlockVars (body, &stack, DEALLOCATE);
5290 outputDebugStackSymbols();
5291 /* deallocate paramaters */
5292 deallocParms (FUNC_ARGS(name->type));
5294 if (IFFUNC_ISREENT (name->type))
5297 /* we are done freeup memory & cleanup */
5299 if (port->reset_labelKey) labelKey = 1;
5301 FUNC_HASBODY(name->type) = 1;
5302 addSet (&operKeyReset, name);
5303 applyToSet (operKeyReset, resetParmKey);
5308 cleanUpLevel (LabelTab, 0);
5309 cleanUpBlock (StructTab, 1);
5310 cleanUpBlock (TypedefTab, 1);
5312 xstack->syms = NULL;
5313 istack->syms = NULL;
5318 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5319 /*-----------------------------------------------------------------*/
5320 /* ast_print : prints the ast (for debugging purposes) */
5321 /*-----------------------------------------------------------------*/
5323 void ast_print (ast * tree, FILE *outfile, int indent)
5328 /* can print only decorated trees */
5329 if (!tree->decorated) return;
5331 /* if any child is an error | this one is an error do nothing */
5332 if (tree->isError ||
5333 (tree->left && tree->left->isError) ||
5334 (tree->right && tree->right->isError)) {
5335 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5339 /* print the line */
5340 /* if not block & function */
5341 if (tree->type == EX_OP &&
5342 (tree->opval.op != FUNCTION &&
5343 tree->opval.op != BLOCK &&
5344 tree->opval.op != NULLOP)) {
5347 if (tree->opval.op == FUNCTION) {
5349 value *args=FUNC_ARGS(tree->left->opval.val->type);
5350 fprintf(outfile,"FUNCTION (%s=%p) type (",
5351 tree->left->opval.val->name, tree);
5352 printTypeChain (tree->left->opval.val->type->next,outfile);
5353 fprintf(outfile,") args (");
5356 fprintf (outfile, ", ");
5358 printTypeChain (args ? args->type : NULL, outfile);
5360 args= args ? args->next : NULL;
5362 fprintf(outfile,")\n");
5363 ast_print(tree->left,outfile,indent);
5364 ast_print(tree->right,outfile,indent);
5367 if (tree->opval.op == BLOCK) {
5368 symbol *decls = tree->values.sym;
5369 INDENT(indent,outfile);
5370 fprintf(outfile,"{\n");
5372 INDENT(indent+2,outfile);
5373 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5374 decls->name, decls);
5375 printTypeChain(decls->type,outfile);
5376 fprintf(outfile,")\n");
5378 decls = decls->next;
5380 ast_print(tree->right,outfile,indent+2);
5381 INDENT(indent,outfile);
5382 fprintf(outfile,"}\n");
5385 if (tree->opval.op == NULLOP) {
5386 ast_print(tree->left,outfile,indent);
5387 ast_print(tree->right,outfile,indent);
5390 INDENT(indent,outfile);
5392 /*------------------------------------------------------------------*/
5393 /*----------------------------*/
5394 /* leaf has been reached */
5395 /*----------------------------*/
5396 /* if this is of type value */
5397 /* just get the type */
5398 if (tree->type == EX_VALUE) {
5400 if (IS_LITERAL (tree->opval.val->etype)) {
5401 fprintf(outfile,"CONSTANT (%p) value = ", tree);
5402 if (SPEC_USIGN (tree->opval.val->etype))
5403 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5405 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5406 fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5407 floatFromVal(tree->opval.val));
5408 } else if (tree->opval.val->sym) {
5409 /* if the undefined flag is set then give error message */
5410 if (tree->opval.val->sym->undefined) {
5411 fprintf(outfile,"UNDEFINED SYMBOL ");
5413 fprintf(outfile,"SYMBOL ");
5415 fprintf(outfile,"(%s=%p)",
5416 tree->opval.val->sym->name,tree);
5419 fprintf(outfile," type (");
5420 printTypeChain(tree->ftype,outfile);
5421 fprintf(outfile,")\n");
5423 fprintf(outfile,"\n");
5428 /* if type link for the case of cast */
5429 if (tree->type == EX_LINK) {
5430 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5431 printTypeChain(tree->opval.lnk,outfile);
5432 fprintf(outfile,")\n");
5437 /* depending on type of operator do */
5439 switch (tree->opval.op) {
5440 /*------------------------------------------------------------------*/
5441 /*----------------------------*/
5443 /*----------------------------*/
5445 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5446 printTypeChain(tree->ftype,outfile);
5447 fprintf(outfile,")\n");
5448 ast_print(tree->left,outfile,indent+2);
5449 ast_print(tree->right,outfile,indent+2);
5452 /*------------------------------------------------------------------*/
5453 /*----------------------------*/
5455 /*----------------------------*/
5457 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5458 printTypeChain(tree->ftype,outfile);
5459 fprintf(outfile,")\n");
5460 ast_print(tree->left,outfile,indent+2);
5461 ast_print(tree->right,outfile,indent+2);
5464 /*------------------------------------------------------------------*/
5465 /*----------------------------*/
5466 /* struct/union pointer */
5467 /*----------------------------*/
5469 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5470 printTypeChain(tree->ftype,outfile);
5471 fprintf(outfile,")\n");
5472 ast_print(tree->left,outfile,indent+2);
5473 ast_print(tree->right,outfile,indent+2);
5476 /*------------------------------------------------------------------*/
5477 /*----------------------------*/
5478 /* ++/-- operation */
5479 /*----------------------------*/
5482 fprintf(outfile,"post-");
5484 fprintf(outfile,"pre-");
5485 fprintf(outfile,"INC_OP (%p) type (",tree);
5486 printTypeChain(tree->ftype,outfile);
5487 fprintf(outfile,")\n");
5488 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5489 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5494 fprintf(outfile,"post-");
5496 fprintf(outfile,"pre-");
5497 fprintf(outfile,"DEC_OP (%p) type (",tree);
5498 printTypeChain(tree->ftype,outfile);
5499 fprintf(outfile,")\n");
5500 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5501 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5504 /*------------------------------------------------------------------*/
5505 /*----------------------------*/
5507 /*----------------------------*/
5510 fprintf(outfile,"& (%p) type (",tree);
5511 printTypeChain(tree->ftype,outfile);
5512 fprintf(outfile,")\n");
5513 ast_print(tree->left,outfile,indent+2);
5514 ast_print(tree->right,outfile,indent+2);
5516 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5517 printTypeChain(tree->ftype,outfile);
5518 fprintf(outfile,")\n");
5519 ast_print(tree->left,outfile,indent+2);
5520 ast_print(tree->right,outfile,indent+2);
5523 /*----------------------------*/
5525 /*----------------------------*/
5527 fprintf(outfile,"OR (%p) type (",tree);
5528 printTypeChain(tree->ftype,outfile);
5529 fprintf(outfile,")\n");
5530 ast_print(tree->left,outfile,indent+2);
5531 ast_print(tree->right,outfile,indent+2);
5533 /*------------------------------------------------------------------*/
5534 /*----------------------------*/
5536 /*----------------------------*/
5538 fprintf(outfile,"XOR (%p) type (",tree);
5539 printTypeChain(tree->ftype,outfile);
5540 fprintf(outfile,")\n");
5541 ast_print(tree->left,outfile,indent+2);
5542 ast_print(tree->right,outfile,indent+2);
5545 /*------------------------------------------------------------------*/
5546 /*----------------------------*/
5548 /*----------------------------*/
5550 fprintf(outfile,"DIV (%p) type (",tree);
5551 printTypeChain(tree->ftype,outfile);
5552 fprintf(outfile,")\n");
5553 ast_print(tree->left,outfile,indent+2);
5554 ast_print(tree->right,outfile,indent+2);
5556 /*------------------------------------------------------------------*/
5557 /*----------------------------*/
5559 /*----------------------------*/
5561 fprintf(outfile,"MOD (%p) type (",tree);
5562 printTypeChain(tree->ftype,outfile);
5563 fprintf(outfile,")\n");
5564 ast_print(tree->left,outfile,indent+2);
5565 ast_print(tree->right,outfile,indent+2);
5568 /*------------------------------------------------------------------*/
5569 /*----------------------------*/
5570 /* address dereference */
5571 /*----------------------------*/
5572 case '*': /* can be unary : if right is null then unary operation */
5574 fprintf(outfile,"DEREF (%p) type (",tree);
5575 printTypeChain(tree->ftype,outfile);
5576 fprintf(outfile,")\n");
5577 ast_print(tree->left,outfile,indent+2);
5580 /*------------------------------------------------------------------*/
5581 /*----------------------------*/
5582 /* multiplication */
5583 /*----------------------------*/
5584 fprintf(outfile,"MULT (%p) type (",tree);
5585 printTypeChain(tree->ftype,outfile);
5586 fprintf(outfile,")\n");
5587 ast_print(tree->left,outfile,indent+2);
5588 ast_print(tree->right,outfile,indent+2);
5592 /*------------------------------------------------------------------*/
5593 /*----------------------------*/
5594 /* unary '+' operator */
5595 /*----------------------------*/
5599 fprintf(outfile,"UPLUS (%p) type (",tree);
5600 printTypeChain(tree->ftype,outfile);
5601 fprintf(outfile,")\n");
5602 ast_print(tree->left,outfile,indent+2);
5604 /*------------------------------------------------------------------*/
5605 /*----------------------------*/
5607 /*----------------------------*/
5608 fprintf(outfile,"ADD (%p) type (",tree);
5609 printTypeChain(tree->ftype,outfile);
5610 fprintf(outfile,")\n");
5611 ast_print(tree->left,outfile,indent+2);
5612 ast_print(tree->right,outfile,indent+2);
5615 /*------------------------------------------------------------------*/
5616 /*----------------------------*/
5618 /*----------------------------*/
5619 case '-': /* can be unary */
5621 fprintf(outfile,"UMINUS (%p) type (",tree);
5622 printTypeChain(tree->ftype,outfile);
5623 fprintf(outfile,")\n");
5624 ast_print(tree->left,outfile,indent+2);
5626 /*------------------------------------------------------------------*/
5627 /*----------------------------*/
5629 /*----------------------------*/
5630 fprintf(outfile,"SUB (%p) type (",tree);
5631 printTypeChain(tree->ftype,outfile);
5632 fprintf(outfile,")\n");
5633 ast_print(tree->left,outfile,indent+2);
5634 ast_print(tree->right,outfile,indent+2);
5637 /*------------------------------------------------------------------*/
5638 /*----------------------------*/
5640 /*----------------------------*/
5642 fprintf(outfile,"COMPL (%p) type (",tree);
5643 printTypeChain(tree->ftype,outfile);
5644 fprintf(outfile,")\n");
5645 ast_print(tree->left,outfile,indent+2);
5647 /*------------------------------------------------------------------*/
5648 /*----------------------------*/
5650 /*----------------------------*/
5652 fprintf(outfile,"NOT (%p) type (",tree);
5653 printTypeChain(tree->ftype,outfile);
5654 fprintf(outfile,")\n");
5655 ast_print(tree->left,outfile,indent+2);
5657 /*------------------------------------------------------------------*/
5658 /*----------------------------*/
5660 /*----------------------------*/
5662 fprintf(outfile,"RRC (%p) type (",tree);
5663 printTypeChain(tree->ftype,outfile);
5664 fprintf(outfile,")\n");
5665 ast_print(tree->left,outfile,indent+2);
5669 fprintf(outfile,"RLC (%p) type (",tree);
5670 printTypeChain(tree->ftype,outfile);
5671 fprintf(outfile,")\n");
5672 ast_print(tree->left,outfile,indent+2);
5675 fprintf(outfile,"SWAP (%p) type (",tree);
5676 printTypeChain(tree->ftype,outfile);
5677 fprintf(outfile,")\n");
5678 ast_print(tree->left,outfile,indent+2);
5681 fprintf(outfile,"GETHBIT (%p) type (",tree);
5682 printTypeChain(tree->ftype,outfile);
5683 fprintf(outfile,")\n");
5684 ast_print(tree->left,outfile,indent+2);
5687 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5688 printTypeChain(tree->ftype,outfile);
5689 fprintf(outfile,")\n");
5690 ast_print(tree->left,outfile,indent+2);
5691 ast_print(tree->right,outfile,indent+2);
5694 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5695 printTypeChain(tree->ftype,outfile);
5696 fprintf(outfile,")\n");
5697 ast_print(tree->left,outfile,indent+2);
5698 ast_print(tree->right,outfile,indent+2);
5700 /*------------------------------------------------------------------*/
5701 /*----------------------------*/
5703 /*----------------------------*/
5704 case CAST: /* change the type */
5705 fprintf(outfile,"CAST (%p) from type (",tree);
5706 printTypeChain(tree->right->ftype,outfile);
5707 fprintf(outfile,") to type (");
5708 printTypeChain(tree->ftype,outfile);
5709 fprintf(outfile,")\n");
5710 ast_print(tree->right,outfile,indent+2);
5714 fprintf(outfile,"ANDAND (%p) type (",tree);
5715 printTypeChain(tree->ftype,outfile);
5716 fprintf(outfile,")\n");
5717 ast_print(tree->left,outfile,indent+2);
5718 ast_print(tree->right,outfile,indent+2);
5721 fprintf(outfile,"OROR (%p) type (",tree);
5722 printTypeChain(tree->ftype,outfile);
5723 fprintf(outfile,")\n");
5724 ast_print(tree->left,outfile,indent+2);
5725 ast_print(tree->right,outfile,indent+2);
5728 /*------------------------------------------------------------------*/
5729 /*----------------------------*/
5730 /* comparison operators */
5731 /*----------------------------*/
5733 fprintf(outfile,"GT(>) (%p) type (",tree);
5734 printTypeChain(tree->ftype,outfile);
5735 fprintf(outfile,")\n");
5736 ast_print(tree->left,outfile,indent+2);
5737 ast_print(tree->right,outfile,indent+2);
5740 fprintf(outfile,"LT(<) (%p) type (",tree);
5741 printTypeChain(tree->ftype,outfile);
5742 fprintf(outfile,")\n");
5743 ast_print(tree->left,outfile,indent+2);
5744 ast_print(tree->right,outfile,indent+2);
5747 fprintf(outfile,"LE(<=) (%p) type (",tree);
5748 printTypeChain(tree->ftype,outfile);
5749 fprintf(outfile,")\n");
5750 ast_print(tree->left,outfile,indent+2);
5751 ast_print(tree->right,outfile,indent+2);
5754 fprintf(outfile,"GE(>=) (%p) type (",tree);
5755 printTypeChain(tree->ftype,outfile);
5756 fprintf(outfile,")\n");
5757 ast_print(tree->left,outfile,indent+2);
5758 ast_print(tree->right,outfile,indent+2);
5761 fprintf(outfile,"EQ(==) (%p) type (",tree);
5762 printTypeChain(tree->ftype,outfile);
5763 fprintf(outfile,")\n");
5764 ast_print(tree->left,outfile,indent+2);
5765 ast_print(tree->right,outfile,indent+2);
5768 fprintf(outfile,"NE(!=) (%p) type (",tree);
5769 printTypeChain(tree->ftype,outfile);
5770 fprintf(outfile,")\n");
5771 ast_print(tree->left,outfile,indent+2);
5772 ast_print(tree->right,outfile,indent+2);
5773 /*------------------------------------------------------------------*/
5774 /*----------------------------*/
5776 /*----------------------------*/
5777 case SIZEOF: /* evaluate wihout code generation */
5778 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5781 /*------------------------------------------------------------------*/
5782 /*----------------------------*/
5783 /* conditional operator '?' */
5784 /*----------------------------*/
5786 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5787 printTypeChain(tree->ftype,outfile);
5788 fprintf(outfile,")\n");
5789 ast_print(tree->left,outfile,indent+2);
5790 ast_print(tree->right,outfile,indent+2);
5794 fprintf(outfile,"COLON(:) (%p) type (",tree);
5795 printTypeChain(tree->ftype,outfile);
5796 fprintf(outfile,")\n");
5797 ast_print(tree->left,outfile,indent+2);
5798 ast_print(tree->right,outfile,indent+2);
5801 /*------------------------------------------------------------------*/
5802 /*----------------------------*/
5803 /* assignment operators */
5804 /*----------------------------*/
5806 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5807 printTypeChain(tree->ftype,outfile);
5808 fprintf(outfile,")\n");
5809 ast_print(tree->left,outfile,indent+2);
5810 ast_print(tree->right,outfile,indent+2);
5813 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5814 printTypeChain(tree->ftype,outfile);
5815 fprintf(outfile,")\n");
5816 ast_print(tree->left,outfile,indent+2);
5817 ast_print(tree->right,outfile,indent+2);
5820 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5821 printTypeChain(tree->ftype,outfile);
5822 fprintf(outfile,")\n");
5823 ast_print(tree->left,outfile,indent+2);
5824 ast_print(tree->right,outfile,indent+2);
5827 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5828 printTypeChain(tree->ftype,outfile);
5829 fprintf(outfile,")\n");
5830 ast_print(tree->left,outfile,indent+2);
5831 ast_print(tree->right,outfile,indent+2);
5834 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5835 printTypeChain(tree->ftype,outfile);
5836 fprintf(outfile,")\n");
5837 ast_print(tree->left,outfile,indent+2);
5838 ast_print(tree->right,outfile,indent+2);
5841 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5842 printTypeChain(tree->ftype,outfile);
5843 fprintf(outfile,")\n");
5844 ast_print(tree->left,outfile,indent+2);
5845 ast_print(tree->right,outfile,indent+2);
5848 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5849 printTypeChain(tree->ftype,outfile);
5850 fprintf(outfile,")\n");
5851 ast_print(tree->left,outfile,indent+2);
5852 ast_print(tree->right,outfile,indent+2);
5854 /*------------------------------------------------------------------*/
5855 /*----------------------------*/
5857 /*----------------------------*/
5859 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5860 printTypeChain(tree->ftype,outfile);
5861 fprintf(outfile,")\n");
5862 ast_print(tree->left,outfile,indent+2);
5863 ast_print(tree->right,outfile,indent+2);
5865 /*------------------------------------------------------------------*/
5866 /*----------------------------*/
5868 /*----------------------------*/
5870 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5871 printTypeChain(tree->ftype,outfile);
5872 fprintf(outfile,")\n");
5873 ast_print(tree->left,outfile,indent+2);
5874 ast_print(tree->right,outfile,indent+2);
5876 /*------------------------------------------------------------------*/
5877 /*----------------------------*/
5878 /* straight assignemnt */
5879 /*----------------------------*/
5881 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5882 printTypeChain(tree->ftype,outfile);
5883 fprintf(outfile,")\n");
5884 ast_print(tree->left,outfile,indent+2);
5885 ast_print(tree->right,outfile,indent+2);
5887 /*------------------------------------------------------------------*/
5888 /*----------------------------*/
5889 /* comma operator */
5890 /*----------------------------*/
5892 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5893 printTypeChain(tree->ftype,outfile);
5894 fprintf(outfile,")\n");
5895 ast_print(tree->left,outfile,indent+2);
5896 ast_print(tree->right,outfile,indent+2);
5898 /*------------------------------------------------------------------*/
5899 /*----------------------------*/
5901 /*----------------------------*/
5904 fprintf(outfile,"CALL (%p) type (",tree);
5905 printTypeChain(tree->ftype,outfile);
5906 fprintf(outfile,")\n");
5907 ast_print(tree->left,outfile,indent+2);
5908 ast_print(tree->right,outfile,indent+2);
5911 fprintf(outfile,"PARMS\n");
5912 ast_print(tree->left,outfile,indent+2);
5913 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5914 ast_print(tree->right,outfile,indent+2);
5917 /*------------------------------------------------------------------*/
5918 /*----------------------------*/
5919 /* return statement */
5920 /*----------------------------*/
5922 fprintf(outfile,"RETURN (%p) type (",tree);
5924 printTypeChain(tree->right->ftype,outfile);
5926 fprintf(outfile,")\n");
5927 ast_print(tree->right,outfile,indent+2);
5929 /*------------------------------------------------------------------*/
5930 /*----------------------------*/
5931 /* label statement */
5932 /*----------------------------*/
5934 fprintf(outfile,"LABEL (%p)\n",tree);
5935 ast_print(tree->left,outfile,indent+2);
5936 ast_print(tree->right,outfile,indent);
5938 /*------------------------------------------------------------------*/
5939 /*----------------------------*/
5940 /* switch statement */
5941 /*----------------------------*/
5945 fprintf(outfile,"SWITCH (%p) ",tree);
5946 ast_print(tree->left,outfile,0);
5947 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5948 INDENT(indent+2,outfile);
5949 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5950 (int) floatFromVal(val),
5951 tree->values.switchVals.swNum,
5952 (int) floatFromVal(val));
5954 ast_print(tree->right,outfile,indent);
5957 /*------------------------------------------------------------------*/
5958 /*----------------------------*/
5960 /*----------------------------*/
5962 fprintf(outfile,"IF (%p) \n",tree);
5963 ast_print(tree->left,outfile,indent+2);
5964 if (tree->trueLabel) {
5965 INDENT(indent+2,outfile);
5966 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5968 if (tree->falseLabel) {
5969 INDENT(indent+2,outfile);
5970 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5972 ast_print(tree->right,outfile,indent+2);
5974 /*----------------------------*/
5975 /* goto Statement */
5976 /*----------------------------*/
5978 fprintf(outfile,"GOTO (%p) \n",tree);
5979 ast_print(tree->left,outfile,indent+2);
5980 fprintf(outfile,"\n");
5982 /*------------------------------------------------------------------*/
5983 /*----------------------------*/
5985 /*----------------------------*/
5987 fprintf(outfile,"FOR (%p) \n",tree);
5988 if (AST_FOR( tree, initExpr)) {
5989 INDENT(indent+2,outfile);
5990 fprintf(outfile,"INIT EXPR ");
5991 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5993 if (AST_FOR( tree, condExpr)) {
5994 INDENT(indent+2,outfile);
5995 fprintf(outfile,"COND EXPR ");
5996 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5998 if (AST_FOR( tree, loopExpr)) {
5999 INDENT(indent+2,outfile);
6000 fprintf(outfile,"LOOP EXPR ");
6001 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6003 fprintf(outfile,"FOR LOOP BODY \n");
6004 ast_print(tree->left,outfile,indent+2);
6007 fprintf(outfile,"CRITICAL (%p) \n",tree);
6008 ast_print(tree->left,outfile,indent+2);
6016 ast_print(t,stdout,0);
6021 /*-----------------------------------------------------------------*/
6022 /* astErrors : returns non-zero if errors present in tree */
6023 /*-----------------------------------------------------------------*/
6024 int astErrors(ast *t)
6033 if (t->type == EX_VALUE
6034 && t->opval.val->sym
6035 && t->opval.val->sym->undefined)
6038 errors += astErrors(t->left);
6039 errors += astErrors(t->right);