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 *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
59 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
64 printTypeChain (tree->ftype, stdout);
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree */
71 /*-----------------------------------------------------------------*/
73 newAst_ (unsigned type)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
90 newAst_VALUE (value * val)
92 ast *ex = newAst_ (EX_VALUE);
98 newAst_OP (unsigned op)
100 ast *ex = newAst_ (EX_OP);
106 newAst_LINK (sym_link * val)
108 ast *ex = newAst_ (EX_LINK);
114 newAst_STMNT (unsigned val)
116 ast *ex = newAst_ (EX_STMNT);
117 ex->opval.stmnt = val;
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node */
123 /*-----------------------------------------------------------------*/
125 newNode (long op, ast * left, ast * right)
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node */
138 /*-----------------------------------------------------------------*/
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
144 /* if this is a literal then we already know the result */
145 if (condAst->etype && IS_LITERAL (condAst->etype))
147 /* then depending on the expression value */
148 if (floatFromVal (condAst->opval.val))
149 ifxNode = newNode (GOTO,
150 newAst_VALUE (symbolVal (trueLabel)),
153 ifxNode = newNode (GOTO,
154 newAst_VALUE (symbolVal (falseLabel)),
159 ifxNode = newNode (IFX, condAst, NULL);
160 ifxNode->trueLabel = trueLabel;
161 ifxNode->falseLabel = falseLabel;
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed */
169 /*-----------------------------------------------------------------*/
171 copyAstValues (ast * dest, ast * src)
173 switch (src->opval.op)
176 dest->values.sym = copySymbolChain (src->values.sym);
180 dest->values.switchVals.swVals =
181 copyValue (src->values.switchVals.swVals);
182 dest->values.switchVals.swDefault =
183 src->values.switchVals.swDefault;
184 dest->values.switchVals.swNum =
185 src->values.switchVals.swNum;
189 dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
193 dest->values.constlist = copyLiteralList(src->values.constlist);
197 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
198 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
199 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
200 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
201 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
202 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
203 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
208 /*-----------------------------------------------------------------*/
209 /* copyAst - makes a copy of a given astession */
210 /*-----------------------------------------------------------------*/
219 dest = Safe_alloc ( sizeof (ast));
221 dest->type = src->type;
222 dest->lineno = src->lineno;
223 dest->level = src->level;
224 dest->funcName = src->funcName;
227 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
229 /* if this is a leaf */
231 if (src->type == EX_VALUE)
233 dest->opval.val = copyValue (src->opval.val);
238 if (src->type == EX_LINK)
240 dest->opval.lnk = copyLinkChain (src->opval.lnk);
244 dest->opval.op = src->opval.op;
246 /* if this is a node that has special values */
247 copyAstValues (dest, src);
249 dest->trueLabel = copySymbol (src->trueLabel);
250 dest->falseLabel = copySymbol (src->falseLabel);
251 dest->left = copyAst (src->left);
252 dest->right = copyAst (src->right);
258 /*-----------------------------------------------------------------*/
259 /* removeIncDecOps: remove for side effects in *_ASSIGN's */
260 /* "*s++ += 3" -> "*s++ = *s++ + 3" */
261 /*-----------------------------------------------------------------*/
262 ast *removeIncDecOps (ast * tree) {
264 // traverse the tree and remove inc/dec ops
269 if (tree->type == EX_OP &&
270 (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
277 tree->left=removeIncDecOps(tree->left);
278 tree->right=removeIncDecOps(tree->right);
283 /*-----------------------------------------------------------------*/
284 /* hasSEFcalls - returns TRUE if tree has a function call */
285 /*-----------------------------------------------------------------*/
287 hasSEFcalls (ast * tree)
292 if (tree->type == EX_OP &&
293 (tree->opval.op == CALL ||
294 tree->opval.op == PCALL ||
295 tree->opval.op == '=' ||
296 tree->opval.op == INC_OP ||
297 tree->opval.op == DEC_OP))
300 return (hasSEFcalls (tree->left) |
301 hasSEFcalls (tree->right));
304 /*-----------------------------------------------------------------*/
305 /* isAstEqual - compares two asts & returns 1 if they are equal */
306 /*-----------------------------------------------------------------*/
308 isAstEqual (ast * t1, ast * t2)
317 if (t1->type != t2->type)
323 if (t1->opval.op != t2->opval.op)
325 return (isAstEqual (t1->left, t2->left) &&
326 isAstEqual (t1->right, t2->right));
330 if (t1->opval.val->sym)
332 if (!t2->opval.val->sym)
335 return isSymbolEqual (t1->opval.val->sym,
340 if (t2->opval.val->sym)
343 return (floatFromVal (t1->opval.val) ==
344 floatFromVal (t2->opval.val));
348 /* only compare these two types */
356 /*-----------------------------------------------------------------*/
357 /* resolveSymbols - resolve symbols from the symbol table */
358 /*-----------------------------------------------------------------*/
360 resolveSymbols (ast * tree)
362 /* walk the entire tree and check for values */
363 /* with symbols if we find one then replace */
364 /* symbol with that from the symbol table */
371 /* if not block & function */
372 if (tree->type == EX_OP &&
373 (tree->opval.op != FUNCTION &&
374 tree->opval.op != BLOCK &&
375 tree->opval.op != NULLOP))
377 filename = tree->filename;
378 lineno = tree->lineno;
382 /* make sure we resolve the true & false labels for ifx */
383 if (tree->type == EX_OP && tree->opval.op == IFX)
389 if ((csym = findSym (LabelTab, tree->trueLabel,
390 tree->trueLabel->name)))
391 tree->trueLabel = csym;
393 werror (E_LABEL_UNDEF, tree->trueLabel->name);
396 if (tree->falseLabel)
398 if ((csym = findSym (LabelTab,
400 tree->falseLabel->name)))
401 tree->falseLabel = csym;
403 werror (E_LABEL_UNDEF, tree->falseLabel->name);
408 /* if this is a label resolve it from the labelTab */
409 if (IS_AST_VALUE (tree) &&
410 tree->opval.val->sym &&
411 tree->opval.val->sym->islbl)
414 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
415 tree->opval.val->sym->name);
418 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
420 tree->opval.val->sym = csym;
422 goto resolveChildren;
425 /* do only for leafs */
426 if (IS_AST_VALUE (tree) &&
427 tree->opval.val->sym &&
428 !tree->opval.val->sym->implicit)
431 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
433 /* if found in the symbol table & they r not the same */
434 if (csym && tree->opval.val->sym != csym)
436 tree->opval.val->sym = csym;
437 tree->opval.val->type = csym->type;
438 tree->opval.val->etype = csym->etype;
441 /* if not found in the symbol table */
442 /* mark it as undefined assume it is */
443 /* an integer in data space */
444 if (!csym && !tree->opval.val->sym->implicit)
447 /* if this is a function name then */
448 /* mark it as returning an int */
451 tree->opval.val->sym->type = newLink (DECLARATOR);
452 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
453 tree->opval.val->sym->type->next =
454 tree->opval.val->sym->etype = newIntLink ();
455 tree->opval.val->etype = tree->opval.val->etype;
456 tree->opval.val->type = tree->opval.val->sym->type;
457 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
458 allocVariables (tree->opval.val->sym);
462 tree->opval.val->sym->undefined = 1;
463 tree->opval.val->type =
464 tree->opval.val->etype = newIntLink ();
465 tree->opval.val->sym->type =
466 tree->opval.val->sym->etype = newIntLink ();
472 resolveSymbols (tree->left);
473 resolveSymbols (tree->right);
478 /*-----------------------------------------------------------------*/
479 /* setAstLineno - walks a ast tree & sets the line number */
480 /*-----------------------------------------------------------------*/
481 int setAstLineno (ast * tree, int lineno)
486 tree->lineno = lineno;
487 setAstLineno (tree->left, lineno);
488 setAstLineno (tree->right, lineno);
492 /*-----------------------------------------------------------------*/
493 /* funcOfType :- function of type with name */
494 /*-----------------------------------------------------------------*/
496 funcOfType (char *name, sym_link * type, sym_link * argType,
500 /* create the symbol */
501 sym = newSymbol (name, 0);
503 /* setup return value */
504 sym->type = newLink (DECLARATOR);
505 DCL_TYPE (sym->type) = FUNCTION;
506 sym->type->next = copyLinkChain (type);
507 sym->etype = getSpec (sym->type);
508 FUNC_ISREENT(sym->type) = rent ? 1 : 0;
510 /* if arguments required */
514 args = FUNC_ARGS(sym->type) = newValue ();
518 args->type = copyLinkChain (argType);
519 args->etype = getSpec (args->type);
520 SPEC_EXTR(args->etype)=1;
523 args = args->next = newValue ();
530 allocVariables (sym);
535 /*-----------------------------------------------------------------*/
536 /* funcOfTypeVarg :- function of type with name and argtype */
537 /*-----------------------------------------------------------------*/
539 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
544 /* create the symbol */
545 sym = newSymbol (name, 0);
547 /* setup return value */
548 sym->type = newLink (DECLARATOR);
549 DCL_TYPE (sym->type) = FUNCTION;
550 sym->type->next = typeFromStr(rtype);
551 sym->etype = getSpec (sym->type);
553 /* if arguments required */
556 args = FUNC_ARGS(sym->type) = newValue ();
558 for ( i = 0 ; i < nArgs ; i++ ) {
559 args->type = typeFromStr(atypes[i]);
560 args->etype = getSpec (args->type);
561 SPEC_EXTR(args->etype)=1;
562 if ((i + 1) == nArgs) break;
563 args = args->next = newValue ();
570 allocVariables (sym);
575 /*-----------------------------------------------------------------*/
576 /* reverseParms - will reverse a parameter tree */
577 /*-----------------------------------------------------------------*/
579 reverseParms (ast * ptree)
585 /* top down if we find a nonParm tree then quit */
586 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
589 ptree->left = ptree->right;
590 ptree->right = ttree;
591 reverseParms (ptree->left);
592 reverseParms (ptree->right);
598 /*-----------------------------------------------------------------*/
599 /* processParms - makes sure the parameters are okay and do some */
600 /* processing with them */
601 /*-----------------------------------------------------------------*/
603 processParms (ast * func,
606 int *parmNumber, // unused, although updated
609 /* if none of them exist */
610 if (!defParm && !actParm)
614 if (getenv("DEBUG_SANITY")) {
615 fprintf (stderr, "processParms: %s ", defParm->name);
617 /* make sure the type is complete and sane */
618 checkTypeSanity(defParm->etype, defParm->name);
621 /* if the function is being called via a pointer & */
622 /* it has not been defined a reentrant then we cannot */
623 /* have parameters */
624 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
626 werror (W_NONRENT_ARGS);
630 /* if defined parameters ended but actual parameters */
631 /* exist and this is not defined as a variable arg */
632 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
634 werror (E_TOO_MANY_PARMS);
638 /* if defined parameters present but no actual parameters */
639 if (defParm && !actParm)
641 werror (E_TOO_FEW_PARMS);
645 if (IS_VOID(actParm->ftype)) {
646 werror (E_VOID_VALUE_USED);
650 /* If this is a varargs function... */
651 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
656 if (IS_CAST_OP (actParm)
657 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
659 /* Parameter was explicitly typecast; don't touch it. */
663 ftype = actParm->ftype;
665 /* If it's a small integer, upcast to int. */
666 if (IS_INTEGRAL (ftype)
667 && (getSize (ftype) < (unsigned) INTSIZE))
669 if (IS_AST_OP(actParm) &&
670 (actParm->opval.op == LEFT_OP ||
671 actParm->opval.op == '*' ||
672 actParm->opval.op == '+' ||
673 actParm->opval.op == '-') &&
675 // we should cast an operand instead of the result
676 actParm->decorated = 0;
677 actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
679 actParm = decorateType(actParm);
681 newType = newAst_LINK(INTTYPE);
685 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
687 newType = newAst_LINK (copyLinkChain(ftype));
688 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
691 if (IS_AGGREGATE (ftype))
693 newType = newAst_LINK (copyLinkChain (ftype));
694 DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
698 /* cast required; change this op to a cast. */
699 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
701 actParm->type = EX_OP;
702 actParm->opval.op = CAST;
703 actParm->left = newType;
704 actParm->right = parmCopy;
705 decorateType (actParm);
707 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
709 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
710 processParms (func, NULL, actParm->right, parmNumber, rightmost));
715 /* if defined parameters ended but actual has not & */
717 if (!defParm && actParm &&
718 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
721 resolveSymbols (actParm);
722 /* if this is a PARAM node then match left & right */
723 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
725 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
726 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
730 /* If we have found a value node by following only right-hand links,
731 * then we know that there are no more values after us.
733 * Therefore, if there are more defined parameters, the caller didn't
736 if (rightmost && defParm->next)
738 werror (E_TOO_FEW_PARMS);
743 /* the parameter type must be at least castable */
744 if (compareType (defParm->type, actParm->ftype) == 0) {
745 werror (E_INCOMPAT_TYPES);
746 printFromToType (actParm->ftype, defParm->type);
750 /* if the parameter is castable then add the cast */
751 if (compareType (defParm->type, actParm->ftype) < 0)
753 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
755 /* now change the current one to a cast */
756 actParm->type = EX_OP;
757 actParm->opval.op = CAST;
758 actParm->left = newAst_LINK (defParm->type);
759 actParm->right = pTree;
760 actParm->etype = defParm->etype;
761 actParm->ftype = defParm->type;
762 actParm->decorated=0; /* force typechecking */
763 decorateType (actParm);
766 /* make a copy and change the regparm type to the defined parm */
767 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
768 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
769 SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
773 /*-----------------------------------------------------------------*/
774 /* createIvalType - generates ival for basic types */
775 /*-----------------------------------------------------------------*/
777 createIvalType (ast * sym, sym_link * type, initList * ilist)
781 /* if initList is deep */
782 if (ilist->type == INIT_DEEP)
783 ilist = ilist->init.deep;
785 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
786 return decorateType (newNode ('=', sym, iExpr));
789 /*-----------------------------------------------------------------*/
790 /* createIvalStruct - generates initial value for structures */
791 /*-----------------------------------------------------------------*/
793 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
800 sflds = SPEC_STRUCT (type)->fields;
801 if (ilist->type != INIT_DEEP)
803 werror (E_INIT_STRUCT, "");
807 iloop = ilist->init.deep;
809 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
811 /* if we have come to end */
815 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
816 lAst = decorateType (resolveSymbols (lAst));
817 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
821 werror (W_EXCESS_INITIALIZERS, "struct",
822 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
829 /*-----------------------------------------------------------------*/
830 /* createIvalArray - generates code for array initialization */
831 /*-----------------------------------------------------------------*/
833 createIvalArray (ast * sym, sym_link * type, initList * ilist)
837 int lcnt = 0, size = 0;
838 literalList *literalL;
840 /* take care of the special case */
841 /* array of characters can be init */
843 if (IS_CHAR (type->next))
844 if ((rast = createIvalCharPtr (sym,
846 decorateType (resolveSymbols (list2expr (ilist))))))
848 return decorateType (resolveSymbols (rast));
850 /* not the special case */
851 if (ilist->type != INIT_DEEP)
853 werror (E_INIT_STRUCT, "");
857 iloop = ilist->init.deep;
858 lcnt = DCL_ELEM (type);
860 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
864 aSym = decorateType (resolveSymbols(sym));
866 rast = newNode(ARRAYINIT, aSym, NULL);
867 rast->values.constlist = literalL;
869 // Make sure size is set to length of initializer list.
876 if (lcnt && size > lcnt)
878 // Array size was specified, and we have more initializers than needed.
879 char *name=sym->opval.val->sym->name;
880 int lineno=sym->opval.val->sym->lineDef;
882 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
891 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
892 aSym = decorateType (resolveSymbols (aSym));
893 rast = createIval (aSym, type->next, iloop, rast);
894 iloop = (iloop ? iloop->next : NULL);
900 /* no of elements given and we */
901 /* have generated for all of them */
904 // there has to be a better way
905 char *name=sym->opval.val->sym->name;
906 int lineno=sym->opval.val->sym->lineDef;
907 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
914 /* if we have not been given a size */
915 if (!DCL_ELEM (type))
917 DCL_ELEM (type) = size;
920 return decorateType (resolveSymbols (rast));
924 /*-----------------------------------------------------------------*/
925 /* createIvalCharPtr - generates initial values for char pointers */
926 /*-----------------------------------------------------------------*/
928 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
932 /* if this is a pointer & right is a literal array then */
933 /* just assignment will do */
934 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
935 SPEC_SCLS (iexpr->etype) == S_CODE)
936 && IS_ARRAY (iexpr->ftype)))
937 return newNode ('=', sym, iexpr);
939 /* left side is an array so we have to assign each */
941 if ((IS_LITERAL (iexpr->etype) ||
942 SPEC_SCLS (iexpr->etype) == S_CODE)
943 && IS_ARRAY (iexpr->ftype))
945 /* for each character generate an assignment */
946 /* to the array element */
947 char *s = SPEC_CVAL (iexpr->etype).v_char;
952 rast = newNode (NULLOP,
956 newAst_VALUE (valueFromLit ((float) i))),
957 newAst_VALUE (valueFromLit (*s))));
961 rast = newNode (NULLOP,
965 newAst_VALUE (valueFromLit ((float) i))),
966 newAst_VALUE (valueFromLit (*s))));
968 // now WE don't need iexpr's symbol anymore
969 freeStringSymbol(AST_SYMBOL(iexpr));
971 return decorateType (resolveSymbols (rast));
977 /*-----------------------------------------------------------------*/
978 /* createIvalPtr - generates initial value for pointers */
979 /*-----------------------------------------------------------------*/
981 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
987 if (ilist->type == INIT_DEEP)
988 ilist = ilist->init.deep;
990 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
992 /* if character pointer */
993 if (IS_CHAR (type->next))
994 if ((rast = createIvalCharPtr (sym, type, iexpr)))
997 return newNode ('=', sym, iexpr);
1000 /*-----------------------------------------------------------------*/
1001 /* createIval - generates code for initial value */
1002 /*-----------------------------------------------------------------*/
1004 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1011 /* if structure then */
1012 if (IS_STRUCT (type))
1013 rast = createIvalStruct (sym, type, ilist);
1015 /* if this is a pointer */
1017 rast = createIvalPtr (sym, type, ilist);
1019 /* if this is an array */
1020 if (IS_ARRAY (type))
1021 rast = createIvalArray (sym, type, ilist);
1023 /* if type is SPECIFIER */
1025 rast = createIvalType (sym, type, ilist);
1028 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1030 return decorateType (resolveSymbols (rast));
1033 /*-----------------------------------------------------------------*/
1034 /* initAggregates - initialises aggregate variables with initv */
1035 /*-----------------------------------------------------------------*/
1036 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1037 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1040 /*-----------------------------------------------------------------*/
1041 /* gatherAutoInit - creates assignment expressions for initial */
1043 /*-----------------------------------------------------------------*/
1045 gatherAutoInit (symbol * autoChain)
1052 for (sym = autoChain; sym; sym = sym->next)
1055 /* resolve the symbols in the ival */
1057 resolveIvalSym (sym->ival);
1059 /* if this is a static variable & has an */
1060 /* initial value the code needs to be lifted */
1061 /* here to the main portion since they can be */
1062 /* initialised only once at the start */
1063 if (IS_STATIC (sym->etype) && sym->ival &&
1064 SPEC_SCLS (sym->etype) != S_CODE)
1068 /* insert the symbol into the symbol table */
1069 /* with level = 0 & name = rname */
1070 newSym = copySymbol (sym);
1071 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1073 /* now lift the code to main */
1074 if (IS_AGGREGATE (sym->type)) {
1075 work = initAggregates (sym, sym->ival, NULL);
1077 if (getNelements(sym->type, sym->ival)>1) {
1078 werror (W_EXCESS_INITIALIZERS, "scalar",
1079 sym->name, sym->lineDef);
1081 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1082 list2expr (sym->ival));
1085 setAstLineno (work, sym->lineDef);
1089 staticAutos = newNode (NULLOP, staticAutos, work);
1096 /* if there is an initial value */
1097 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1099 initList *ilist=sym->ival;
1101 while (ilist->type == INIT_DEEP) {
1102 ilist = ilist->init.deep;
1105 /* update lineno for error msg */
1106 lineno=sym->lineDef;
1107 setAstLineno (ilist->init.node, lineno);
1109 if (IS_AGGREGATE (sym->type)) {
1110 work = initAggregates (sym, sym->ival, NULL);
1112 if (getNelements(sym->type, sym->ival)>1) {
1113 werror (W_EXCESS_INITIALIZERS, "scalar",
1114 sym->name, sym->lineDef);
1116 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1117 list2expr (sym->ival));
1121 setAstLineno (work, sym->lineDef);
1125 init = newNode (NULLOP, init, work);
1134 /*-----------------------------------------------------------------*/
1135 /* freeStringSymbol - delete a literal string if no more usage */
1136 /*-----------------------------------------------------------------*/
1137 void freeStringSymbol(symbol *sym) {
1138 /* make sure this is a literal string */
1139 assert (sym->isstrlit);
1140 if (--sym->isstrlit == 0) { // lower the usage count
1141 memmap *segment=SPEC_OCLS(sym->etype);
1143 deleteSetItem(&segment->syms, sym);
1148 /*-----------------------------------------------------------------*/
1149 /* stringToSymbol - creates a symbol from a literal string */
1150 /*-----------------------------------------------------------------*/
1152 stringToSymbol (value * val)
1154 char name[SDCC_NAME_MAX + 1];
1155 static int charLbl = 0;
1159 // have we heard this before?
1160 for (sp=statsg->syms; sp; sp=sp->next) {
1162 if (sym->isstrlit &&
1163 !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
1164 // yes, this is old news. Don't publish it again.
1165 sym->isstrlit++; // but raise the usage count
1166 return symbolVal(sym);
1170 SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1171 sym = newSymbol (name, 0); /* make it @ level 0 */
1172 strncpyz (sym->rname, name, SDCC_NAME_MAX);
1174 /* copy the type from the value passed */
1175 sym->type = copyLinkChain (val->type);
1176 sym->etype = getSpec (sym->type);
1177 /* change to storage class & output class */
1178 SPEC_SCLS (sym->etype) = S_CODE;
1179 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1180 SPEC_STAT (sym->etype) = 1;
1181 /* make the level & block = 0 */
1182 sym->block = sym->level = 0;
1184 /* create an ival */
1185 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1190 allocVariables (sym);
1193 return symbolVal (sym);
1197 /*-----------------------------------------------------------------*/
1198 /* processBlockVars - will go thru the ast looking for block if */
1199 /* a block is found then will allocate the syms */
1200 /* will also gather the auto inits present */
1201 /*-----------------------------------------------------------------*/
1203 processBlockVars (ast * tree, int *stack, int action)
1208 /* if this is a block */
1209 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1213 if (action == ALLOCATE)
1215 *stack += allocVariables (tree->values.sym);
1216 autoInit = gatherAutoInit (tree->values.sym);
1218 /* if there are auto inits then do them */
1220 tree->left = newNode (NULLOP, autoInit, tree->left);
1222 else /* action is deallocate */
1223 deallocLocal (tree->values.sym);
1226 processBlockVars (tree->left, stack, action);
1227 processBlockVars (tree->right, stack, action);
1231 /*-------------------------------------------------------------*/
1232 /* constExprTree - returns TRUE if this tree is a constant */
1234 /*-------------------------------------------------------------*/
1235 bool constExprTree (ast *cexpr) {
1241 cexpr = decorateType (resolveSymbols (cexpr));
1243 switch (cexpr->type)
1246 if (IS_AST_LIT_VALUE(cexpr)) {
1247 // this is a literal
1250 if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1251 // a function's address will never change
1254 if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1255 // an array's address will never change
1258 if (IS_AST_SYM_VALUE(cexpr) &&
1259 IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1260 // a symbol in code space will never change
1261 // This is only for the 'char *s="hallo"' case and will have to leave
1266 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1267 "unexpected link in expression tree\n");
1270 if (cexpr->opval.op==ARRAYINIT) {
1271 // this is a list of literals
1274 if (cexpr->opval.op=='=') {
1275 return constExprTree(cexpr->right);
1277 if (cexpr->opval.op==CAST) {
1278 // cast ignored, maybe we should throw a warning here?
1279 return constExprTree(cexpr->right);
1281 if (cexpr->opval.op=='&') {
1284 if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1287 if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1294 /*-----------------------------------------------------------------*/
1295 /* constExprValue - returns the value of a constant expression */
1296 /* or NULL if it is not a constant expression */
1297 /*-----------------------------------------------------------------*/
1299 constExprValue (ast * cexpr, int check)
1301 cexpr = decorateType (resolveSymbols (cexpr));
1303 /* if this is not a constant then */
1304 if (!IS_LITERAL (cexpr->ftype))
1306 /* then check if this is a literal array
1308 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1309 SPEC_CVAL (cexpr->etype).v_char &&
1310 IS_ARRAY (cexpr->ftype))
1312 value *val = valFromType (cexpr->ftype);
1313 SPEC_SCLS (val->etype) = S_LITERAL;
1314 val->sym = cexpr->opval.val->sym;
1315 val->sym->type = copyLinkChain (cexpr->ftype);
1316 val->sym->etype = getSpec (val->sym->type);
1317 strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1321 /* if we are casting a literal value then */
1322 if (IS_AST_OP (cexpr) &&
1323 cexpr->opval.op == CAST &&
1324 IS_LITERAL (cexpr->right->ftype))
1325 return valCastLiteral (cexpr->ftype,
1326 floatFromVal (cexpr->right->opval.val));
1328 if (IS_AST_VALUE (cexpr))
1329 return cexpr->opval.val;
1332 werror (E_CONST_EXPECTED, "found expression");
1337 /* return the value */
1338 return cexpr->opval.val;
1342 /*-----------------------------------------------------------------*/
1343 /* isLabelInAst - will return true if a given label is found */
1344 /*-----------------------------------------------------------------*/
1346 isLabelInAst (symbol * label, ast * tree)
1348 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1351 if (IS_AST_OP (tree) &&
1352 tree->opval.op == LABEL &&
1353 isSymbolEqual (AST_SYMBOL (tree->left), label))
1356 return isLabelInAst (label, tree->right) &&
1357 isLabelInAst (label, tree->left);
1361 /*-----------------------------------------------------------------*/
1362 /* isLoopCountable - return true if the loop count can be determi- */
1363 /* -ned at compile time . */
1364 /*-----------------------------------------------------------------*/
1366 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1367 symbol ** sym, ast ** init, ast ** end)
1370 /* the loop is considered countable if the following
1371 conditions are true :-
1373 a) initExpr :- <sym> = <const>
1374 b) condExpr :- <sym> < <const1>
1375 c) loopExpr :- <sym> ++
1378 /* first check the initExpr */
1379 if (IS_AST_OP (initExpr) &&
1380 initExpr->opval.op == '=' && /* is assignment */
1381 IS_AST_SYM_VALUE (initExpr->left))
1382 { /* left is a symbol */
1384 *sym = AST_SYMBOL (initExpr->left);
1385 *init = initExpr->right;
1390 /* for now the symbol has to be of
1392 if (!IS_INTEGRAL ((*sym)->type))
1395 /* now check condExpr */
1396 if (IS_AST_OP (condExpr))
1399 switch (condExpr->opval.op)
1402 if (IS_AST_SYM_VALUE (condExpr->left) &&
1403 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1404 IS_AST_LIT_VALUE (condExpr->right))
1406 *end = condExpr->right;
1412 if (IS_AST_OP (condExpr->left) &&
1413 condExpr->left->opval.op == '>' &&
1414 IS_AST_LIT_VALUE (condExpr->left->right) &&
1415 IS_AST_SYM_VALUE (condExpr->left->left) &&
1416 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1419 *end = newNode ('+', condExpr->left->right,
1420 newAst_VALUE (constVal ("1")));
1431 /* check loop expression is of the form <sym>++ */
1432 if (!IS_AST_OP (loopExpr))
1435 /* check if <sym> ++ */
1436 if (loopExpr->opval.op == INC_OP)
1442 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1443 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1450 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1451 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1459 if (loopExpr->opval.op == ADD_ASSIGN)
1462 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1463 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1464 IS_AST_LIT_VALUE (loopExpr->right) &&
1465 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1473 /*-----------------------------------------------------------------*/
1474 /* astHasVolatile - returns true if ast contains any volatile */
1475 /*-----------------------------------------------------------------*/
1477 astHasVolatile (ast * tree)
1482 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1485 if (IS_AST_OP (tree))
1486 return astHasVolatile (tree->left) ||
1487 astHasVolatile (tree->right);
1492 /*-----------------------------------------------------------------*/
1493 /* astHasPointer - return true if the ast contains any ptr variable */
1494 /*-----------------------------------------------------------------*/
1496 astHasPointer (ast * tree)
1501 if (IS_AST_LINK (tree))
1504 /* if we hit an array expression then check
1505 only the left side */
1506 if (IS_AST_OP (tree) && tree->opval.op == '[')
1507 return astHasPointer (tree->left);
1509 if (IS_AST_VALUE (tree))
1510 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1512 return astHasPointer (tree->left) ||
1513 astHasPointer (tree->right);
1517 /*-----------------------------------------------------------------*/
1518 /* astHasSymbol - return true if the ast has the given symbol */
1519 /*-----------------------------------------------------------------*/
1521 astHasSymbol (ast * tree, symbol * sym)
1523 if (!tree || IS_AST_LINK (tree))
1526 if (IS_AST_VALUE (tree))
1528 if (IS_AST_SYM_VALUE (tree))
1529 return isSymbolEqual (AST_SYMBOL (tree), sym);
1534 return astHasSymbol (tree->left, sym) ||
1535 astHasSymbol (tree->right, sym);
1538 /*-----------------------------------------------------------------*/
1539 /* astHasDeref - return true if the ast has an indirect access */
1540 /*-----------------------------------------------------------------*/
1542 astHasDeref (ast * tree)
1544 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1547 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1549 return astHasDeref (tree->left) || astHasDeref (tree->right);
1552 /*-----------------------------------------------------------------*/
1553 /* isConformingBody - the loop body has to conform to a set of rules */
1554 /* for the loop to be considered reversible read on for rules */
1555 /*-----------------------------------------------------------------*/
1557 isConformingBody (ast * pbody, symbol * sym, ast * body)
1560 /* we are going to do a pre-order traversal of the
1561 tree && check for the following conditions. (essentially
1562 a set of very shallow tests )
1563 a) the sym passed does not participate in
1564 any arithmetic operation
1565 b) There are no function calls
1566 c) all jumps are within the body
1567 d) address of loop control variable not taken
1568 e) if an assignment has a pointer on the
1569 left hand side make sure right does not have
1570 loop control variable */
1572 /* if we reach the end or a leaf then true */
1573 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1576 /* if anything else is "volatile" */
1577 if (IS_VOLATILE (TETYPE (pbody)))
1580 /* we will walk the body in a pre-order traversal for
1582 switch (pbody->opval.op)
1584 /*------------------------------------------------------------------*/
1586 // if the loopvar is used as an index
1587 if (astHasSymbol(pbody->right, sym)) {
1590 return isConformingBody (pbody->right, sym, body);
1592 /*------------------------------------------------------------------*/
1597 /*------------------------------------------------------------------*/
1598 case INC_OP: /* incerement operator unary so left only */
1601 /* sure we are not sym is not modified */
1603 IS_AST_SYM_VALUE (pbody->left) &&
1604 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1608 IS_AST_SYM_VALUE (pbody->right) &&
1609 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1614 /*------------------------------------------------------------------*/
1616 case '*': /* can be unary : if right is null then unary operation */
1621 /* if right is NULL then unary operation */
1622 /*------------------------------------------------------------------*/
1623 /*----------------------------*/
1625 /*----------------------------*/
1628 if (IS_AST_SYM_VALUE (pbody->left) &&
1629 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1632 return isConformingBody (pbody->left, sym, body);
1636 if (astHasSymbol (pbody->left, sym) ||
1637 astHasSymbol (pbody->right, sym))
1642 /*------------------------------------------------------------------*/
1650 if (IS_AST_SYM_VALUE (pbody->left) &&
1651 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1654 if (IS_AST_SYM_VALUE (pbody->right) &&
1655 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1658 return isConformingBody (pbody->left, sym, body) &&
1659 isConformingBody (pbody->right, sym, body);
1666 if (IS_AST_SYM_VALUE (pbody->left) &&
1667 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1669 return isConformingBody (pbody->left, sym, body);
1671 /*------------------------------------------------------------------*/
1683 case SIZEOF: /* evaluate wihout code generation */
1685 return isConformingBody (pbody->left, sym, body) &&
1686 isConformingBody (pbody->right, sym, body);
1688 /*------------------------------------------------------------------*/
1691 /* if left has a pointer & right has loop
1692 control variable then we cannot */
1693 if (astHasPointer (pbody->left) &&
1694 astHasSymbol (pbody->right, sym))
1696 if (astHasVolatile (pbody->left))
1699 if (IS_AST_SYM_VALUE (pbody->left)) {
1700 // if the loopvar has an assignment
1701 if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1703 // if the loopvar is used in another (maybe conditional) block
1704 if (astHasSymbol (pbody->right, sym) &&
1705 (pbody->level > body->level)) {
1710 if (astHasVolatile (pbody->left))
1713 if (astHasDeref(pbody->right)) return FALSE;
1715 return isConformingBody (pbody->left, sym, body) &&
1716 isConformingBody (pbody->right, sym, body);
1727 assert ("Parser should not have generated this\n");
1729 /*------------------------------------------------------------------*/
1730 /*----------------------------*/
1731 /* comma operator */
1732 /*----------------------------*/
1734 return isConformingBody (pbody->left, sym, body) &&
1735 isConformingBody (pbody->right, sym, body);
1737 /*------------------------------------------------------------------*/
1738 /*----------------------------*/
1740 /*----------------------------*/
1742 /* if local & not passed as paramater then ok */
1743 if (sym->level && !astHasSymbol(pbody->right,sym))
1747 /*------------------------------------------------------------------*/
1748 /*----------------------------*/
1749 /* return statement */
1750 /*----------------------------*/
1755 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1760 if (astHasSymbol (pbody->left, sym))
1767 return isConformingBody (pbody->left, sym, body) &&
1768 isConformingBody (pbody->right, sym, body);
1774 /*-----------------------------------------------------------------*/
1775 /* isLoopReversible - takes a for loop as input && returns true */
1776 /* if the for loop is reversible. If yes will set the value of */
1777 /* the loop control var & init value & termination value */
1778 /*-----------------------------------------------------------------*/
1780 isLoopReversible (ast * loop, symbol ** loopCntrl,
1781 ast ** init, ast ** end)
1783 /* if option says don't do it then don't */
1784 if (optimize.noLoopReverse)
1786 /* there are several tests to determine this */
1788 /* for loop has to be of the form
1789 for ( <sym> = <const1> ;
1790 [<sym> < <const2>] ;
1791 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1793 if (!isLoopCountable (AST_FOR (loop, initExpr),
1794 AST_FOR (loop, condExpr),
1795 AST_FOR (loop, loopExpr),
1796 loopCntrl, init, end))
1799 /* now do some serious checking on the body of the loop
1802 return isConformingBody (loop->left, *loopCntrl, loop->left);
1806 /*-----------------------------------------------------------------*/
1807 /* replLoopSym - replace the loop sym by loop sym -1 */
1808 /*-----------------------------------------------------------------*/
1810 replLoopSym (ast * body, symbol * sym)
1813 if (!body || IS_AST_LINK (body))
1816 if (IS_AST_SYM_VALUE (body))
1819 if (isSymbolEqual (AST_SYMBOL (body), sym))
1823 body->opval.op = '-';
1824 body->left = newAst_VALUE (symbolVal (sym));
1825 body->right = newAst_VALUE (constVal ("1"));
1833 replLoopSym (body->left, sym);
1834 replLoopSym (body->right, sym);
1838 /*-----------------------------------------------------------------*/
1839 /* reverseLoop - do the actual loop reversal */
1840 /*-----------------------------------------------------------------*/
1842 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1846 /* create the following tree
1851 if (sym) goto for_continue ;
1854 /* put it together piece by piece */
1855 rloop = newNode (NULLOP,
1856 createIf (newAst_VALUE (symbolVal (sym)),
1858 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1861 newAst_VALUE (symbolVal (sym)),
1864 replLoopSym (loop->left, sym);
1865 setAstLineno (rloop, init->lineno);
1867 rloop = newNode (NULLOP,
1869 newAst_VALUE (symbolVal (sym)),
1870 newNode ('-', end, init)),
1871 createLabel (AST_FOR (loop, continueLabel),
1875 newNode (SUB_ASSIGN,
1876 newAst_VALUE (symbolVal (sym)),
1877 newAst_VALUE (constVal ("1"))),
1880 rloop->lineno=init->lineno;
1881 return decorateType (rloop);
1885 /*-----------------------------------------------------------------*/
1886 /* decorateType - compute type for this tree also does type cheking */
1887 /* this is done bottom up, since type have to flow upwards */
1888 /* it also does constant folding, and paramater checking */
1889 /*-----------------------------------------------------------------*/
1891 decorateType (ast * tree)
1899 /* if already has type then do nothing */
1900 if (tree->decorated)
1903 tree->decorated = 1;
1906 /* print the line */
1907 /* if not block & function */
1908 if (tree->type == EX_OP &&
1909 (tree->opval.op != FUNCTION &&
1910 tree->opval.op != BLOCK &&
1911 tree->opval.op != NULLOP))
1913 filename = tree->filename;
1914 lineno = tree->lineno;
1918 /* if any child is an error | this one is an error do nothing */
1919 if (tree->isError ||
1920 (tree->left && tree->left->isError) ||
1921 (tree->right && tree->right->isError))
1924 /*------------------------------------------------------------------*/
1925 /*----------------------------*/
1926 /* leaf has been reached */
1927 /*----------------------------*/
1928 lineno=tree->lineno;
1929 /* if this is of type value */
1930 /* just get the type */
1931 if (tree->type == EX_VALUE)
1934 if (IS_LITERAL (tree->opval.val->etype))
1937 /* if this is a character array then declare it */
1938 if (IS_ARRAY (tree->opval.val->type))
1939 tree->opval.val = stringToSymbol (tree->opval.val);
1941 /* otherwise just copy the type information */
1942 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1946 if (tree->opval.val->sym)
1948 /* if the undefined flag is set then give error message */
1949 if (tree->opval.val->sym->undefined)
1951 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1953 TTYPE (tree) = TETYPE (tree) =
1954 tree->opval.val->type = tree->opval.val->sym->type =
1955 tree->opval.val->etype = tree->opval.val->sym->etype =
1956 copyLinkChain (INTTYPE);
1961 /* if impilicit i.e. struct/union member then no type */
1962 if (tree->opval.val->sym->implicit)
1963 TTYPE (tree) = TETYPE (tree) = NULL;
1968 /* else copy the type */
1969 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1971 /* and mark it as referenced */
1972 tree->opval.val->sym->isref = 1;
1980 /* if type link for the case of cast */
1981 if (tree->type == EX_LINK)
1983 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1990 dtl = decorateType (tree->left);
1991 /* delay right side for '?' operator since conditional macro expansions might
1993 dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1995 /* this is to take care of situations
1996 when the tree gets rewritten */
1997 if (dtl != tree->left)
1999 if (dtr != tree->right)
2002 if (IS_AST_OP(tree) &&
2003 (tree->opval.op == CAST || tree->opval.op == '=') &&
2004 (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2005 (getSize(RTYPE(tree)) < INTSIZE)) {
2006 // this is a cast/assign to a bigger type
2007 if (IS_AST_OP(tree->right) &&
2008 IS_INTEGRAL(tree->right->ftype) &&
2009 (tree->right->opval.op == LEFT_OP ||
2010 tree->right->opval.op == '*' ||
2011 tree->right->opval.op == '+' ||
2012 tree->right->opval.op == '-') &&
2013 tree->right->right) {
2014 // we should cast an operand instead of the result
2015 tree->right->decorated = 0;
2016 tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2018 tree->right = decorateType(tree->right);
2023 /* depending on type of operator do */
2025 switch (tree->opval.op)
2027 /*------------------------------------------------------------------*/
2028 /*----------------------------*/
2030 /*----------------------------*/
2033 /* determine which is the array & which the index */
2034 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2037 ast *tempTree = tree->left;
2038 tree->left = tree->right;
2039 tree->right = tempTree;
2042 /* first check if this is a array or a pointer */
2043 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2045 werror (E_NEED_ARRAY_PTR, "[]");
2046 goto errorTreeReturn;
2049 /* check if the type of the idx */
2050 if (!IS_INTEGRAL (RTYPE (tree)))
2052 werror (E_IDX_NOT_INT);
2053 goto errorTreeReturn;
2056 /* if the left is an rvalue then error */
2059 werror (E_LVALUE_REQUIRED, "array access");
2060 goto errorTreeReturn;
2063 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2064 if (IS_PTR(LTYPE(tree))) {
2065 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2069 /*------------------------------------------------------------------*/
2070 /*----------------------------*/
2072 /*----------------------------*/
2074 /* if this is not a structure */
2075 if (!IS_STRUCT (LTYPE (tree)))
2077 werror (E_STRUCT_UNION, ".");
2078 goto errorTreeReturn;
2080 TTYPE (tree) = structElemType (LTYPE (tree),
2081 (tree->right->type == EX_VALUE ?
2082 tree->right->opval.val : NULL));
2083 TETYPE (tree) = getSpec (TTYPE (tree));
2086 /*------------------------------------------------------------------*/
2087 /*----------------------------*/
2088 /* struct/union pointer */
2089 /*----------------------------*/
2091 /* if not pointer to a structure */
2092 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2094 werror (E_PTR_REQD);
2095 goto errorTreeReturn;
2098 if (!IS_STRUCT (LTYPE (tree)->next))
2100 werror (E_STRUCT_UNION, "->");
2101 goto errorTreeReturn;
2104 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2105 (tree->right->type == EX_VALUE ?
2106 tree->right->opval.val : NULL));
2107 TETYPE (tree) = getSpec (TTYPE (tree));
2109 /* adjust the storage class */
2110 switch (DCL_TYPE(tree->left->ftype)) {
2114 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2117 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2122 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2125 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2128 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2138 /*------------------------------------------------------------------*/
2139 /*----------------------------*/
2140 /* ++/-- operation */
2141 /*----------------------------*/
2142 case INC_OP: /* incerement operator unary so left only */
2145 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2146 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2147 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2148 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2157 /*------------------------------------------------------------------*/
2158 /*----------------------------*/
2160 /*----------------------------*/
2161 case '&': /* can be unary */
2162 /* if right is NULL then unary operation */
2163 if (tree->right) /* not an unary operation */
2166 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2168 werror (E_BITWISE_OP);
2169 werror (W_CONTINUE, "left & right types are ");
2170 printTypeChain (LTYPE (tree), stderr);
2171 fprintf (stderr, ",");
2172 printTypeChain (RTYPE (tree), stderr);
2173 fprintf (stderr, "\n");
2174 goto errorTreeReturn;
2177 /* if they are both literal */
2178 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2180 tree->type = EX_VALUE;
2181 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2182 valFromType (RETYPE (tree)), '&');
2184 tree->right = tree->left = NULL;
2185 TETYPE (tree) = tree->opval.val->etype;
2186 TTYPE (tree) = tree->opval.val->type;
2190 /* see if this is a GETHBIT operation if yes
2193 ast *otree = optimizeGetHbit (tree);
2196 return decorateType (otree);
2200 computeType (LTYPE (tree), RTYPE (tree));
2201 TETYPE (tree) = getSpec (TTYPE (tree));
2203 LRVAL (tree) = RRVAL (tree) = 1;
2207 /*------------------------------------------------------------------*/
2208 /*----------------------------*/
2210 /*----------------------------*/
2211 p = newLink (DECLARATOR);
2212 /* if bit field then error */
2213 if (IS_BITVAR (tree->left->etype))
2215 werror (E_ILLEGAL_ADDR, "address of bit variable");
2216 goto errorTreeReturn;
2219 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2221 werror (E_ILLEGAL_ADDR, "address of register variable");
2222 goto errorTreeReturn;
2225 if (IS_FUNC (LTYPE (tree)))
2227 // this ought to be ignored
2228 return (tree->left);
2231 if (IS_LITERAL(LTYPE(tree)))
2233 werror (E_ILLEGAL_ADDR, "address of literal");
2234 goto errorTreeReturn;
2239 werror (E_LVALUE_REQUIRED, "address of");
2240 goto errorTreeReturn;
2242 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2244 DCL_TYPE (p) = CPOINTER;
2245 DCL_PTR_CONST (p) = port->mem.code_ro;
2247 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2248 DCL_TYPE (p) = FPOINTER;
2249 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2250 DCL_TYPE (p) = PPOINTER;
2251 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2252 DCL_TYPE (p) = IPOINTER;
2253 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2254 DCL_TYPE (p) = EEPPOINTER;
2255 else if (SPEC_OCLS(tree->left->etype))
2256 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2258 DCL_TYPE (p) = POINTER;
2260 if (IS_AST_SYM_VALUE (tree->left))
2262 AST_SYMBOL (tree->left)->addrtaken = 1;
2263 AST_SYMBOL (tree->left)->allocreq = 1;
2266 p->next = LTYPE (tree);
2268 TETYPE (tree) = getSpec (TTYPE (tree));
2269 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2270 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2275 /*------------------------------------------------------------------*/
2276 /*----------------------------*/
2278 /*----------------------------*/
2280 /* if the rewrite succeeds then don't go any furthur */
2282 ast *wtree = optimizeRRCRLC (tree);
2284 return decorateType (wtree);
2287 /*------------------------------------------------------------------*/
2288 /*----------------------------*/
2290 /*----------------------------*/
2292 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2294 werror (E_BITWISE_OP);
2295 werror (W_CONTINUE, "left & right types are ");
2296 printTypeChain (LTYPE (tree), stderr);
2297 fprintf (stderr, ",");
2298 printTypeChain (RTYPE (tree), stderr);
2299 fprintf (stderr, "\n");
2300 goto errorTreeReturn;
2303 /* if they are both literal then */
2304 /* rewrite the tree */
2305 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2307 tree->type = EX_VALUE;
2308 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2309 valFromType (RETYPE (tree)),
2311 tree->right = tree->left = NULL;
2312 TETYPE (tree) = tree->opval.val->etype;
2313 TTYPE (tree) = tree->opval.val->type;
2316 LRVAL (tree) = RRVAL (tree) = 1;
2317 TETYPE (tree) = getSpec (TTYPE (tree) =
2318 computeType (LTYPE (tree),
2321 /*------------------------------------------------------------------*/
2322 /*----------------------------*/
2324 /*----------------------------*/
2326 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2328 werror (E_INVALID_OP, "divide");
2329 goto errorTreeReturn;
2331 /* if they are both literal then */
2332 /* rewrite the tree */
2333 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2335 tree->type = EX_VALUE;
2336 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2337 valFromType (RETYPE (tree)));
2338 tree->right = tree->left = NULL;
2339 TETYPE (tree) = getSpec (TTYPE (tree) =
2340 tree->opval.val->type);
2343 LRVAL (tree) = RRVAL (tree) = 1;
2344 TETYPE (tree) = getSpec (TTYPE (tree) =
2345 computeType (LTYPE (tree),
2349 /*------------------------------------------------------------------*/
2350 /*----------------------------*/
2352 /*----------------------------*/
2354 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2356 werror (E_BITWISE_OP);
2357 werror (W_CONTINUE, "left & right types are ");
2358 printTypeChain (LTYPE (tree), stderr);
2359 fprintf (stderr, ",");
2360 printTypeChain (RTYPE (tree), stderr);
2361 fprintf (stderr, "\n");
2362 goto errorTreeReturn;
2364 /* if they are both literal then */
2365 /* rewrite the tree */
2366 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2368 tree->type = EX_VALUE;
2369 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2370 valFromType (RETYPE (tree)));
2371 tree->right = tree->left = NULL;
2372 TETYPE (tree) = getSpec (TTYPE (tree) =
2373 tree->opval.val->type);
2376 LRVAL (tree) = RRVAL (tree) = 1;
2377 TETYPE (tree) = getSpec (TTYPE (tree) =
2378 computeType (LTYPE (tree),
2382 /*------------------------------------------------------------------*/
2383 /*----------------------------*/
2384 /* address dereference */
2385 /*----------------------------*/
2386 case '*': /* can be unary : if right is null then unary operation */
2389 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2391 werror (E_PTR_REQD);
2392 goto errorTreeReturn;
2397 werror (E_LVALUE_REQUIRED, "pointer deref");
2398 goto errorTreeReturn;
2400 TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2401 TETYPE (tree) = getSpec (TTYPE (tree));
2402 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2406 /*------------------------------------------------------------------*/
2407 /*----------------------------*/
2408 /* multiplication */
2409 /*----------------------------*/
2410 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2412 werror (E_INVALID_OP, "multiplication");
2413 goto errorTreeReturn;
2416 /* if they are both literal then */
2417 /* rewrite the tree */
2418 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2420 tree->type = EX_VALUE;
2421 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2422 valFromType (RETYPE (tree)));
2423 tree->right = tree->left = NULL;
2424 TETYPE (tree) = getSpec (TTYPE (tree) =
2425 tree->opval.val->type);
2429 /* if left is a literal exchange left & right */
2430 if (IS_LITERAL (LTYPE (tree)))
2432 ast *tTree = tree->left;
2433 tree->left = tree->right;
2434 tree->right = tTree;
2437 LRVAL (tree) = RRVAL (tree) = 1;
2438 TETYPE (tree) = getSpec (TTYPE (tree) =
2439 computeType (LTYPE (tree),
2442 /* promote result to int if left & right are char
2443 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2444 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2445 SPEC_NOUN(TETYPE(tree)) = V_INT;
2450 /*------------------------------------------------------------------*/
2451 /*----------------------------*/
2452 /* unary '+' operator */
2453 /*----------------------------*/
2458 if (!IS_INTEGRAL (LTYPE (tree)))
2460 werror (E_UNARY_OP, '+');
2461 goto errorTreeReturn;
2464 /* if left is a literal then do it */
2465 if (IS_LITERAL (LTYPE (tree)))
2467 tree->type = EX_VALUE;
2468 tree->opval.val = valFromType (LETYPE (tree));
2470 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2474 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2478 /*------------------------------------------------------------------*/
2479 /*----------------------------*/
2481 /*----------------------------*/
2483 /* this is not a unary operation */
2484 /* if both pointers then problem */
2485 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2486 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2488 werror (E_PTR_PLUS_PTR);
2489 goto errorTreeReturn;
2492 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2493 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2495 werror (E_PLUS_INVALID, "+");
2496 goto errorTreeReturn;
2499 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2500 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2502 werror (E_PLUS_INVALID, "+");
2503 goto errorTreeReturn;
2505 /* if they are both literal then */
2506 /* rewrite the tree */
2507 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2509 tree->type = EX_VALUE;
2510 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2511 valFromType (RETYPE (tree)));
2512 tree->right = tree->left = NULL;
2513 TETYPE (tree) = getSpec (TTYPE (tree) =
2514 tree->opval.val->type);
2518 /* if the right is a pointer or left is a literal
2519 xchange left & right */
2520 if (IS_ARRAY (RTYPE (tree)) ||
2521 IS_PTR (RTYPE (tree)) ||
2522 IS_LITERAL (LTYPE (tree)))
2524 ast *tTree = tree->left;
2525 tree->left = tree->right;
2526 tree->right = tTree;
2529 LRVAL (tree) = RRVAL (tree) = 1;
2530 /* if the left is a pointer */
2531 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2532 TETYPE (tree) = getSpec (TTYPE (tree) =
2535 TETYPE (tree) = getSpec (TTYPE (tree) =
2536 computeType (LTYPE (tree),
2540 /*------------------------------------------------------------------*/
2541 /*----------------------------*/
2543 /*----------------------------*/
2544 case '-': /* can be unary */
2545 /* if right is null then unary */
2549 if (!IS_ARITHMETIC (LTYPE (tree)))
2551 werror (E_UNARY_OP, tree->opval.op);
2552 goto errorTreeReturn;
2555 /* if left is a literal then do it */
2556 if (IS_LITERAL (LTYPE (tree)))
2558 tree->type = EX_VALUE;
2559 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2561 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2562 SPEC_USIGN(TETYPE(tree)) = 0;
2566 TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2570 /*------------------------------------------------------------------*/
2571 /*----------------------------*/
2573 /*----------------------------*/
2575 if (!(IS_PTR (LTYPE (tree)) ||
2576 IS_ARRAY (LTYPE (tree)) ||
2577 IS_ARITHMETIC (LTYPE (tree))))
2579 werror (E_PLUS_INVALID, "-");
2580 goto errorTreeReturn;
2583 if (!(IS_PTR (RTYPE (tree)) ||
2584 IS_ARRAY (RTYPE (tree)) ||
2585 IS_ARITHMETIC (RTYPE (tree))))
2587 werror (E_PLUS_INVALID, "-");
2588 goto errorTreeReturn;
2591 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2592 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2593 IS_INTEGRAL (RTYPE (tree))))
2595 werror (E_PLUS_INVALID, "-");
2596 goto errorTreeReturn;
2599 /* if they are both literal then */
2600 /* rewrite the tree */
2601 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2603 tree->type = EX_VALUE;
2604 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2605 valFromType (RETYPE (tree)));
2606 tree->right = tree->left = NULL;
2607 TETYPE (tree) = getSpec (TTYPE (tree) =
2608 tree->opval.val->type);
2612 /* if the left & right are equal then zero */
2613 if (isAstEqual (tree->left, tree->right))
2615 tree->type = EX_VALUE;
2616 tree->left = tree->right = NULL;
2617 tree->opval.val = constVal ("0");
2618 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2622 /* if both of them are pointers or arrays then */
2623 /* the result is going to be an integer */
2624 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2625 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2626 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2628 /* if only the left is a pointer */
2629 /* then result is a pointer */
2630 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2631 TETYPE (tree) = getSpec (TTYPE (tree) =
2634 TETYPE (tree) = getSpec (TTYPE (tree) =
2635 computeType (LTYPE (tree),
2637 LRVAL (tree) = RRVAL (tree) = 1;
2640 /*------------------------------------------------------------------*/
2641 /*----------------------------*/
2643 /*----------------------------*/
2645 /* can be only integral type */
2646 if (!IS_INTEGRAL (LTYPE (tree)))
2648 werror (E_UNARY_OP, tree->opval.op);
2649 goto errorTreeReturn;
2652 /* if left is a literal then do it */
2653 if (IS_LITERAL (LTYPE (tree)))
2655 tree->type = EX_VALUE;
2656 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2658 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2662 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2665 /*------------------------------------------------------------------*/
2666 /*----------------------------*/
2668 /*----------------------------*/
2670 /* can be pointer */
2671 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2672 !IS_PTR (LTYPE (tree)) &&
2673 !IS_ARRAY (LTYPE (tree)))
2675 werror (E_UNARY_OP, tree->opval.op);
2676 goto errorTreeReturn;
2679 /* if left is a literal then do it */
2680 if (IS_LITERAL (LTYPE (tree)))
2682 tree->type = EX_VALUE;
2683 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2685 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2689 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2692 /*------------------------------------------------------------------*/
2693 /*----------------------------*/
2695 /*----------------------------*/
2698 TTYPE (tree) = LTYPE (tree);
2699 TETYPE (tree) = LETYPE (tree);
2703 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2708 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2710 werror (E_SHIFT_OP_INVALID);
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 = valShift (valFromType (LETYPE (tree)),
2725 valFromType (RETYPE (tree)),
2726 (tree->opval.op == LEFT_OP ? 1 : 0));
2727 tree->right = tree->left = NULL;
2728 TETYPE (tree) = getSpec (TTYPE (tree) =
2729 tree->opval.val->type);
2733 /* if only the right side is a literal & we are
2734 shifting more than size of the left operand then zero */
2735 if (IS_LITERAL (RTYPE (tree)) &&
2736 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2737 (getSize (LTYPE (tree)) * 8))
2739 if (tree->opval.op==LEFT_OP ||
2740 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2741 lineno=tree->lineno;
2742 werror (W_SHIFT_CHANGED,
2743 (tree->opval.op == LEFT_OP ? "left" : "right"));
2744 tree->type = EX_VALUE;
2745 tree->left = tree->right = NULL;
2746 tree->opval.val = constVal ("0");
2747 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2751 LRVAL (tree) = RRVAL (tree) = 1;
2752 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2754 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2758 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2762 /*------------------------------------------------------------------*/
2763 /*----------------------------*/
2765 /*----------------------------*/
2766 case CAST: /* change the type */
2767 /* cannot cast to an aggregate type */
2768 if (IS_AGGREGATE (LTYPE (tree)))
2770 werror (E_CAST_ILLEGAL);
2771 goto errorTreeReturn;
2774 /* make sure the type is complete and sane */
2775 checkTypeSanity(LETYPE(tree), "(cast)");
2778 /* if the right is a literal replace the tree */
2779 if (IS_LITERAL (RETYPE (tree))) {
2780 if (!IS_PTR (LTYPE (tree))) {
2781 tree->type = EX_VALUE;
2783 valCastLiteral (LTYPE (tree),
2784 floatFromVal (valFromType (RETYPE (tree))));
2787 TTYPE (tree) = tree->opval.val->type;
2788 tree->values.literalFromCast = 1;
2789 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2790 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2791 sym_link *rest = LTYPE(tree)->next;
2792 werror(W_LITERAL_GENERIC);
2793 TTYPE(tree) = newLink(DECLARATOR);
2794 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2795 TTYPE(tree)->next = rest;
2796 tree->left->opval.lnk = TTYPE(tree);
2799 TTYPE (tree) = LTYPE (tree);
2803 TTYPE (tree) = LTYPE (tree);
2807 #if 0 // this is already checked, now this could be explicit
2808 /* if pointer to struct then check names */
2809 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2810 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2811 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2813 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2814 SPEC_STRUCT(LETYPE(tree))->tag);
2817 /* if the right is a literal replace the tree */
2818 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2819 tree->type = EX_VALUE;
2821 valCastLiteral (LTYPE (tree),
2822 floatFromVal (valFromType (RETYPE (tree))));
2825 TTYPE (tree) = tree->opval.val->type;
2826 tree->values.literalFromCast = 1;
2828 TTYPE (tree) = LTYPE (tree);
2832 TETYPE (tree) = getSpec (TTYPE (tree));
2836 /*------------------------------------------------------------------*/
2837 /*----------------------------*/
2838 /* logical &&, || */
2839 /*----------------------------*/
2842 /* each must me arithmetic type or be a pointer */
2843 if (!IS_PTR (LTYPE (tree)) &&
2844 !IS_ARRAY (LTYPE (tree)) &&
2845 !IS_INTEGRAL (LTYPE (tree)))
2847 werror (E_COMPARE_OP);
2848 goto errorTreeReturn;
2851 if (!IS_PTR (RTYPE (tree)) &&
2852 !IS_ARRAY (RTYPE (tree)) &&
2853 !IS_INTEGRAL (RTYPE (tree)))
2855 werror (E_COMPARE_OP);
2856 goto errorTreeReturn;
2858 /* if they are both literal then */
2859 /* rewrite the tree */
2860 if (IS_LITERAL (RTYPE (tree)) &&
2861 IS_LITERAL (LTYPE (tree)))
2863 tree->type = EX_VALUE;
2864 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2865 valFromType (RETYPE (tree)),
2867 tree->right = tree->left = NULL;
2868 TETYPE (tree) = getSpec (TTYPE (tree) =
2869 tree->opval.val->type);
2872 LRVAL (tree) = RRVAL (tree) = 1;
2873 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2876 /*------------------------------------------------------------------*/
2877 /*----------------------------*/
2878 /* comparison operators */
2879 /*----------------------------*/
2887 ast *lt = optimizeCompare (tree);
2893 /* if they are pointers they must be castable */
2894 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2896 if (tree->opval.op==EQ_OP &&
2897 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
2898 // we cannot cast a gptr to a !gptr: switch the leaves
2899 struct ast *s=tree->left;
2900 tree->left=tree->right;
2903 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2905 werror (E_COMPARE_OP);
2906 fprintf (stderr, "comparring type ");
2907 printTypeChain (LTYPE (tree), stderr);
2908 fprintf (stderr, "to type ");
2909 printTypeChain (RTYPE (tree), stderr);
2910 fprintf (stderr, "\n");
2911 goto errorTreeReturn;
2914 /* else they should be promotable to one another */
2917 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2918 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2920 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2922 werror (E_COMPARE_OP);
2923 fprintf (stderr, "comparing type ");
2924 printTypeChain (LTYPE (tree), stderr);
2925 fprintf (stderr, "to type ");
2926 printTypeChain (RTYPE (tree), stderr);
2927 fprintf (stderr, "\n");
2928 goto errorTreeReturn;
2931 /* if unsigned value < 0 then always false */
2932 /* if (unsigned value) > 0 then (unsigned value) */
2933 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2934 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2936 if (tree->opval.op == '<') {
2939 if (tree->opval.op == '>') {
2943 /* if they are both literal then */
2944 /* rewrite the tree */
2945 if (IS_LITERAL (RTYPE (tree)) &&
2946 IS_LITERAL (LTYPE (tree)))
2948 tree->type = EX_VALUE;
2949 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2950 valFromType (RETYPE (tree)),
2952 tree->right = tree->left = NULL;
2953 TETYPE (tree) = getSpec (TTYPE (tree) =
2954 tree->opval.val->type);
2957 LRVAL (tree) = RRVAL (tree) = 1;
2958 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2961 /*------------------------------------------------------------------*/
2962 /*----------------------------*/
2964 /*----------------------------*/
2965 case SIZEOF: /* evaluate wihout code generation */
2966 /* change the type to a integer */
2967 tree->type = EX_VALUE;
2968 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2969 tree->opval.val = constVal (buffer);
2970 tree->right = tree->left = NULL;
2971 TETYPE (tree) = getSpec (TTYPE (tree) =
2972 tree->opval.val->type);
2975 /*------------------------------------------------------------------*/
2976 /*----------------------------*/
2978 /*----------------------------*/
2980 /* return typeof enum value */
2981 tree->type = EX_VALUE;
2984 if (IS_SPEC(tree->right->ftype)) {
2985 switch (SPEC_NOUN(tree->right->ftype)) {
2987 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2988 else typeofv = TYPEOF_INT;
2991 typeofv = TYPEOF_FLOAT;
2994 typeofv = TYPEOF_CHAR;
2997 typeofv = TYPEOF_VOID;
3000 typeofv = TYPEOF_STRUCT;
3003 typeofv = TYPEOF_BIT;
3006 typeofv = TYPEOF_SBIT;
3012 switch (DCL_TYPE(tree->right->ftype)) {
3014 typeofv = TYPEOF_POINTER;
3017 typeofv = TYPEOF_FPOINTER;
3020 typeofv = TYPEOF_CPOINTER;
3023 typeofv = TYPEOF_GPOINTER;
3026 typeofv = TYPEOF_PPOINTER;
3029 typeofv = TYPEOF_IPOINTER;
3032 typeofv = TYPEOF_ARRAY;
3035 typeofv = TYPEOF_FUNCTION;
3041 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3042 tree->opval.val = constVal (buffer);
3043 tree->right = tree->left = NULL;
3044 TETYPE (tree) = getSpec (TTYPE (tree) =
3045 tree->opval.val->type);
3048 /*------------------------------------------------------------------*/
3049 /*----------------------------*/
3050 /* conditional operator '?' */
3051 /*----------------------------*/
3053 /* the type is value of the colon operator (on the right) */
3054 assert(IS_COLON_OP(tree->right));
3055 /* if already known then replace the tree : optimizer will do it
3056 but faster to do it here */
3057 if (IS_LITERAL (LTYPE(tree))) {
3058 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3059 return decorateType(tree->right->left) ;
3061 return decorateType(tree->right->right) ;
3064 tree->right = decorateType(tree->right);
3065 TTYPE (tree) = RTYPE(tree);
3066 TETYPE (tree) = getSpec (TTYPE (tree));
3071 /* if they don't match we have a problem */
3072 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3074 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3075 goto errorTreeReturn;
3078 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3079 TETYPE (tree) = getSpec (TTYPE (tree));
3083 #if 0 // assignment operators are converted by the parser
3084 /*------------------------------------------------------------------*/
3085 /*----------------------------*/
3086 /* assignment operators */
3087 /*----------------------------*/
3090 /* for these it must be both must be integral */
3091 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3092 !IS_ARITHMETIC (RTYPE (tree)))
3094 werror (E_OPS_INTEGRAL);
3095 goto errorTreeReturn;
3098 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3100 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3101 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3105 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3106 goto errorTreeReturn;
3117 /* for these it must be both must be integral */
3118 if (!IS_INTEGRAL (LTYPE (tree)) ||
3119 !IS_INTEGRAL (RTYPE (tree)))
3121 werror (E_OPS_INTEGRAL);
3122 goto errorTreeReturn;
3125 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3127 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3128 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3132 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3133 goto errorTreeReturn;
3139 /*------------------------------------------------------------------*/
3140 /*----------------------------*/
3142 /*----------------------------*/
3144 if (!(IS_PTR (LTYPE (tree)) ||
3145 IS_ARITHMETIC (LTYPE (tree))))
3147 werror (E_PLUS_INVALID, "-=");
3148 goto errorTreeReturn;
3151 if (!(IS_PTR (RTYPE (tree)) ||
3152 IS_ARITHMETIC (RTYPE (tree))))
3154 werror (E_PLUS_INVALID, "-=");
3155 goto errorTreeReturn;
3158 TETYPE (tree) = getSpec (TTYPE (tree) =
3159 computeType (LTYPE (tree),
3162 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3163 werror (E_CODE_WRITE, "-=");
3167 werror (E_LVALUE_REQUIRED, "-=");
3168 goto errorTreeReturn;
3174 /*------------------------------------------------------------------*/
3175 /*----------------------------*/
3177 /*----------------------------*/
3179 /* this is not a unary operation */
3180 /* if both pointers then problem */
3181 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3183 werror (E_PTR_PLUS_PTR);
3184 goto errorTreeReturn;
3187 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3189 werror (E_PLUS_INVALID, "+=");
3190 goto errorTreeReturn;
3193 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3195 werror (E_PLUS_INVALID, "+=");
3196 goto errorTreeReturn;
3199 TETYPE (tree) = getSpec (TTYPE (tree) =
3200 computeType (LTYPE (tree),
3203 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3204 werror (E_CODE_WRITE, "+=");
3208 werror (E_LVALUE_REQUIRED, "+=");
3209 goto errorTreeReturn;
3212 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3213 tree->opval.op = '=';
3218 /*------------------------------------------------------------------*/
3219 /*----------------------------*/
3220 /* straight assignemnt */
3221 /*----------------------------*/
3223 /* cannot be an aggregate */
3224 if (IS_AGGREGATE (LTYPE (tree)))
3226 werror (E_AGGR_ASSIGN);
3227 goto errorTreeReturn;
3230 /* they should either match or be castable */
3231 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3233 werror (E_TYPE_MISMATCH, "assignment", " ");
3234 printFromToType(RTYPE(tree),LTYPE(tree));
3235 //goto errorTreeReturn;
3238 /* if the left side of the tree is of type void
3239 then report error */
3240 if (IS_VOID (LTYPE (tree)))
3242 werror (E_CAST_ZERO);
3243 printFromToType(RTYPE(tree), LTYPE(tree));
3246 TETYPE (tree) = getSpec (TTYPE (tree) =
3250 if (!tree->initMode ) {
3251 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3252 werror (E_CODE_WRITE, "=");
3256 werror (E_LVALUE_REQUIRED, "=");
3257 goto errorTreeReturn;
3262 /*------------------------------------------------------------------*/
3263 /*----------------------------*/
3264 /* comma operator */
3265 /*----------------------------*/
3267 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3270 /*------------------------------------------------------------------*/
3271 /*----------------------------*/
3273 /*----------------------------*/
3277 if (processParms (tree->left,
3278 FUNC_ARGS(tree->left->ftype),
3279 tree->right, &parmNumber, TRUE)) {
3280 goto errorTreeReturn;
3283 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3284 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3286 //FUNC_ARGS(tree->left->ftype) =
3287 //reverseVal (FUNC_ARGS(tree->left->ftype));
3288 reverseParms (tree->right);
3291 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3294 /*------------------------------------------------------------------*/
3295 /*----------------------------*/
3296 /* return statement */
3297 /*----------------------------*/
3302 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3304 werror (W_RETURN_MISMATCH);
3305 printFromToType (RTYPE(tree), currFunc->type->next);
3306 goto errorTreeReturn;
3309 if (IS_VOID (currFunc->type->next)
3311 !IS_VOID (RTYPE (tree)))
3313 werror (E_FUNC_VOID);
3314 goto errorTreeReturn;
3317 /* if there is going to be a casing required then add it */
3318 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3321 decorateType (newNode (CAST,
3322 newAst_LINK (copyLinkChain (currFunc->type->next)),
3331 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3333 werror (W_VOID_FUNC, currFunc->name);
3334 goto errorTreeReturn;
3337 TTYPE (tree) = TETYPE (tree) = NULL;
3340 /*------------------------------------------------------------------*/
3341 /*----------------------------*/
3342 /* switch statement */
3343 /*----------------------------*/
3345 /* the switch value must be an integer */
3346 if (!IS_INTEGRAL (LTYPE (tree)))
3348 werror (E_SWITCH_NON_INTEGER);
3349 goto errorTreeReturn;
3352 TTYPE (tree) = TETYPE (tree) = NULL;
3355 /*------------------------------------------------------------------*/
3356 /*----------------------------*/
3358 /*----------------------------*/
3360 tree->left = backPatchLabels (tree->left,
3363 TTYPE (tree) = TETYPE (tree) = NULL;
3366 /*------------------------------------------------------------------*/
3367 /*----------------------------*/
3369 /*----------------------------*/
3372 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3373 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3374 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3376 /* if the for loop is reversible then
3377 reverse it otherwise do what we normally
3383 if (isLoopReversible (tree, &sym, &init, &end))
3384 return reverseLoop (tree, sym, init, end);
3386 return decorateType (createFor (AST_FOR (tree, trueLabel),
3387 AST_FOR (tree, continueLabel),
3388 AST_FOR (tree, falseLabel),
3389 AST_FOR (tree, condLabel),
3390 AST_FOR (tree, initExpr),
3391 AST_FOR (tree, condExpr),
3392 AST_FOR (tree, loopExpr),
3396 TTYPE (tree) = TETYPE (tree) = NULL;
3400 /* some error found this tree will be killed */
3402 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3403 tree->opval.op = NULLOP;
3409 /*-----------------------------------------------------------------*/
3410 /* sizeofOp - processes size of operation */
3411 /*-----------------------------------------------------------------*/
3413 sizeofOp (sym_link * type)
3417 /* make sure the type is complete and sane */
3418 checkTypeSanity(type, "(sizeof)");
3420 /* get the size and convert it to character */
3421 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3423 /* now convert into value */
3424 return constVal (buff);
3428 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3429 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3430 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3431 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3432 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3433 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3434 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3436 /*-----------------------------------------------------------------*/
3437 /* backPatchLabels - change and or not operators to flow control */
3438 /*-----------------------------------------------------------------*/
3440 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3446 if (!(IS_ANDORNOT (tree)))
3449 /* if this an and */
3452 static int localLbl = 0;
3455 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3456 localLabel = newSymbol (buffer, NestLevel);
3458 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3460 /* if left is already a IFX then just change the if true label in that */
3461 if (!IS_IFX (tree->left))
3462 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3464 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3465 /* right is a IFX then just join */
3466 if (IS_IFX (tree->right))
3467 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3469 tree->right = createLabel (localLabel, tree->right);
3470 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3472 return newNode (NULLOP, tree->left, tree->right);
3475 /* if this is an or operation */
3478 static int localLbl = 0;
3481 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3482 localLabel = newSymbol (buffer, NestLevel);
3484 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3486 /* if left is already a IFX then just change the if true label in that */
3487 if (!IS_IFX (tree->left))
3488 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3490 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3491 /* right is a IFX then just join */
3492 if (IS_IFX (tree->right))
3493 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3495 tree->right = createLabel (localLabel, tree->right);
3496 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3498 return newNode (NULLOP, tree->left, tree->right);
3504 int wasnot = IS_NOT (tree->left);
3505 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3507 /* if the left is already a IFX */
3508 if (!IS_IFX (tree->left))
3509 tree->left = newNode (IFX, tree->left, NULL);
3513 tree->left->trueLabel = trueLabel;
3514 tree->left->falseLabel = falseLabel;
3518 tree->left->trueLabel = falseLabel;
3519 tree->left->falseLabel = trueLabel;
3526 tree->trueLabel = trueLabel;
3527 tree->falseLabel = falseLabel;
3534 /*-----------------------------------------------------------------*/
3535 /* createBlock - create expression tree for block */
3536 /*-----------------------------------------------------------------*/
3538 createBlock (symbol * decl, ast * body)
3542 /* if the block has nothing */
3546 ex = newNode (BLOCK, NULL, body);
3547 ex->values.sym = decl;
3549 ex->right = ex->right;
3555 /*-----------------------------------------------------------------*/
3556 /* createLabel - creates the expression tree for labels */
3557 /*-----------------------------------------------------------------*/
3559 createLabel (symbol * label, ast * stmnt)
3562 char name[SDCC_NAME_MAX + 1];
3565 /* must create fresh symbol if the symbol name */
3566 /* exists in the symbol table, since there can */
3567 /* be a variable with the same name as the labl */
3568 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3569 (csym->level == label->level))
3570 label = newSymbol (label->name, label->level);
3572 /* change the name before putting it in add _ */
3573 SNPRINTF(name, sizeof(name), "%s", label->name);
3575 /* put the label in the LabelSymbol table */
3576 /* but first check if a label of the same */
3578 if ((csym = findSym (LabelTab, NULL, name)))
3579 werror (E_DUPLICATE_LABEL, label->name);
3581 addSym (LabelTab, label, name, label->level, 0, 0);
3584 label->key = labelKey++;
3585 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3591 /*-----------------------------------------------------------------*/
3592 /* createCase - generates the parsetree for a case statement */
3593 /*-----------------------------------------------------------------*/
3595 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3597 char caseLbl[SDCC_NAME_MAX + 1];
3601 /* if the switch statement does not exist */
3602 /* then case is out of context */
3605 werror (E_CASE_CONTEXT);
3609 caseVal = decorateType (resolveSymbols (caseVal));
3610 /* if not a constant then error */
3611 if (!IS_LITERAL (caseVal->ftype))
3613 werror (E_CASE_CONSTANT);
3617 /* if not a integer than error */
3618 if (!IS_INTEGRAL (caseVal->ftype))
3620 werror (E_CASE_NON_INTEGER);
3624 /* find the end of the switch values chain */
3625 if (!(val = swStat->values.switchVals.swVals))
3626 swStat->values.switchVals.swVals = caseVal->opval.val;
3629 /* also order the cases according to value */
3631 int cVal = (int) floatFromVal (caseVal->opval.val);
3632 while (val && (int) floatFromVal (val) < cVal)
3638 /* if we reached the end then */
3641 pval->next = caseVal->opval.val;
3645 /* we found a value greater than */
3646 /* the current value we must add this */
3647 /* before the value */
3648 caseVal->opval.val->next = val;
3650 /* if this was the first in chain */
3651 if (swStat->values.switchVals.swVals == val)
3652 swStat->values.switchVals.swVals =
3655 pval->next = caseVal->opval.val;
3660 /* create the case label */
3661 SNPRINTF(caseLbl, sizeof(caseLbl),
3663 swStat->values.switchVals.swNum,
3664 (int) floatFromVal (caseVal->opval.val));
3666 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3671 /*-----------------------------------------------------------------*/
3672 /* createDefault - creates the parse tree for the default statement */
3673 /*-----------------------------------------------------------------*/
3675 createDefault (ast * swStat, ast * stmnt)
3677 char defLbl[SDCC_NAME_MAX + 1];
3679 /* if the switch statement does not exist */
3680 /* then case is out of context */
3683 werror (E_CASE_CONTEXT);
3687 /* turn on the default flag */
3688 swStat->values.switchVals.swDefault = 1;
3690 /* create the label */
3691 SNPRINTF (defLbl, sizeof(defLbl),
3692 "_default_%d", swStat->values.switchVals.swNum);
3693 return createLabel (newSymbol (defLbl, 0), stmnt);
3696 /*-----------------------------------------------------------------*/
3697 /* createIf - creates the parsetree for the if statement */
3698 /*-----------------------------------------------------------------*/
3700 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3702 static int Lblnum = 0;
3704 symbol *ifTrue, *ifFalse, *ifEnd;
3706 /* if neither exists */
3707 if (!elseBody && !ifBody) {
3708 // if there are no side effects (i++, j() etc)
3709 if (!hasSEFcalls(condAst)) {
3714 /* create the labels */
3715 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3716 ifFalse = newSymbol (buffer, NestLevel);
3717 /* if no else body then end == false */
3722 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3723 ifEnd = newSymbol (buffer, NestLevel);
3726 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3727 ifTrue = newSymbol (buffer, NestLevel);
3731 /* attach the ifTrue label to the top of it body */
3732 ifBody = createLabel (ifTrue, ifBody);
3733 /* attach a goto end to the ifBody if else is present */
3736 ifBody = newNode (NULLOP, ifBody,
3738 newAst_VALUE (symbolVal (ifEnd)),
3740 /* put the elseLabel on the else body */
3741 elseBody = createLabel (ifFalse, elseBody);
3742 /* out the end at the end of the body */
3743 elseBody = newNode (NULLOP,
3745 createLabel (ifEnd, NULL));
3749 ifBody = newNode (NULLOP, ifBody,
3750 createLabel (ifFalse, NULL));
3752 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3753 if (IS_IFX (condAst))
3756 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3758 return newNode (NULLOP, ifTree,
3759 newNode (NULLOP, ifBody, elseBody));
3763 /*-----------------------------------------------------------------*/
3764 /* createDo - creates parse tree for do */
3767 /* _docontinue_n: */
3768 /* condition_expression +-> trueLabel -> _dobody_n */
3770 /* +-> falseLabel-> _dobreak_n */
3772 /*-----------------------------------------------------------------*/
3774 createDo (symbol * trueLabel, symbol * continueLabel,
3775 symbol * falseLabel, ast * condAst, ast * doBody)
3780 /* if the body does not exist then it is simple */
3783 condAst = backPatchLabels (condAst, continueLabel, NULL);
3784 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3785 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3786 doTree->trueLabel = continueLabel;
3787 doTree->falseLabel = NULL;
3791 /* otherwise we have a body */
3792 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3794 /* attach the body label to the top */
3795 doBody = createLabel (trueLabel, doBody);
3796 /* attach the continue label to end of body */
3797 doBody = newNode (NULLOP, doBody,
3798 createLabel (continueLabel, NULL));
3800 /* now put the break label at the end */
3801 if (IS_IFX (condAst))
3804 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3806 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3808 /* putting it together */
3809 return newNode (NULLOP, doBody, doTree);
3812 /*-----------------------------------------------------------------*/
3813 /* createFor - creates parse tree for 'for' statement */
3816 /* condExpr +-> trueLabel -> _forbody_n */
3818 /* +-> falseLabel-> _forbreak_n */
3821 /* _forcontinue_n: */
3823 /* goto _forcond_n ; */
3825 /*-----------------------------------------------------------------*/
3827 createFor (symbol * trueLabel, symbol * continueLabel,
3828 symbol * falseLabel, symbol * condLabel,
3829 ast * initExpr, ast * condExpr, ast * loopExpr,
3834 /* if loopexpression not present then we can generate it */
3835 /* the same way as a while */
3837 return newNode (NULLOP, initExpr,
3838 createWhile (trueLabel, continueLabel,
3839 falseLabel, condExpr, forBody));
3840 /* vanilla for statement */
3841 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3843 if (condExpr && !IS_IFX (condExpr))
3844 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3847 /* attach condition label to condition */
3848 condExpr = createLabel (condLabel, condExpr);
3850 /* attach body label to body */
3851 forBody = createLabel (trueLabel, forBody);
3853 /* attach continue to forLoop expression & attach */
3854 /* goto the forcond @ and of loopExpression */
3855 loopExpr = createLabel (continueLabel,
3859 newAst_VALUE (symbolVal (condLabel)),
3861 /* now start putting them together */
3862 forTree = newNode (NULLOP, initExpr, condExpr);
3863 forTree = newNode (NULLOP, forTree, forBody);
3864 forTree = newNode (NULLOP, forTree, loopExpr);
3865 /* finally add the break label */
3866 forTree = newNode (NULLOP, forTree,
3867 createLabel (falseLabel, NULL));
3871 /*-----------------------------------------------------------------*/
3872 /* createWhile - creates parse tree for while statement */
3873 /* the while statement will be created as follows */
3875 /* _while_continue_n: */
3876 /* condition_expression +-> trueLabel -> _while_boby_n */
3878 /* +-> falseLabel -> _while_break_n */
3879 /* _while_body_n: */
3881 /* goto _while_continue_n */
3882 /* _while_break_n: */
3883 /*-----------------------------------------------------------------*/
3885 createWhile (symbol * trueLabel, symbol * continueLabel,
3886 symbol * falseLabel, ast * condExpr, ast * whileBody)
3890 /* put the continue label */
3891 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3892 condExpr = createLabel (continueLabel, condExpr);
3893 condExpr->lineno = 0;
3895 /* put the body label in front of the body */
3896 whileBody = createLabel (trueLabel, whileBody);
3897 whileBody->lineno = 0;
3898 /* put a jump to continue at the end of the body */
3899 /* and put break label at the end of the body */
3900 whileBody = newNode (NULLOP,
3903 newAst_VALUE (symbolVal (continueLabel)),
3904 createLabel (falseLabel, NULL)));
3906 /* put it all together */
3907 if (IS_IFX (condExpr))
3908 whileTree = condExpr;
3911 whileTree = newNode (IFX, condExpr, NULL);
3912 /* put the true & false labels in place */
3913 whileTree->trueLabel = trueLabel;
3914 whileTree->falseLabel = falseLabel;
3917 return newNode (NULLOP, whileTree, whileBody);
3920 /*-----------------------------------------------------------------*/
3921 /* optimizeGetHbit - get highest order bit of the expression */
3922 /*-----------------------------------------------------------------*/
3924 optimizeGetHbit (ast * tree)
3927 /* if this is not a bit and */
3928 if (!IS_BITAND (tree))
3931 /* will look for tree of the form
3932 ( expr >> ((sizeof expr) -1) ) & 1 */
3933 if (!IS_AST_LIT_VALUE (tree->right))
3936 if (AST_LIT_VALUE (tree->right) != 1)
3939 if (!IS_RIGHT_OP (tree->left))
3942 if (!IS_AST_LIT_VALUE (tree->left->right))
3945 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3946 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3949 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3953 /*-----------------------------------------------------------------*/
3954 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3955 /*-----------------------------------------------------------------*/
3957 optimizeRRCRLC (ast * root)
3959 /* will look for trees of the form
3960 (?expr << 1) | (?expr >> 7) or
3961 (?expr >> 7) | (?expr << 1) will make that
3962 into a RLC : operation ..
3964 (?expr >> 1) | (?expr << 7) or
3965 (?expr << 7) | (?expr >> 1) will make that
3966 into a RRC operation
3967 note : by 7 I mean (number of bits required to hold the
3969 /* if the root operations is not a | operation the not */
3970 if (!IS_BITOR (root))
3973 /* I have to think of a better way to match patterns this sucks */
3974 /* that aside let start looking for the first case : I use a the
3975 negative check a lot to improve the efficiency */
3976 /* (?expr << 1) | (?expr >> 7) */
3977 if (IS_LEFT_OP (root->left) &&
3978 IS_RIGHT_OP (root->right))
3981 if (!SPEC_USIGN (TETYPE (root->left->left)))
3984 if (!IS_AST_LIT_VALUE (root->left->right) ||
3985 !IS_AST_LIT_VALUE (root->right->right))
3988 /* make sure it is the same expression */
3989 if (!isAstEqual (root->left->left,
3993 if (AST_LIT_VALUE (root->left->right) != 1)
3996 if (AST_LIT_VALUE (root->right->right) !=
3997 (getSize (TTYPE (root->left->left)) * 8 - 1))
4000 /* whew got the first case : create the AST */
4001 return newNode (RLC, root->left->left, NULL);
4005 /* check for second case */
4006 /* (?expr >> 7) | (?expr << 1) */
4007 if (IS_LEFT_OP (root->right) &&
4008 IS_RIGHT_OP (root->left))
4011 if (!SPEC_USIGN (TETYPE (root->left->left)))
4014 if (!IS_AST_LIT_VALUE (root->left->right) ||
4015 !IS_AST_LIT_VALUE (root->right->right))
4018 /* make sure it is the same symbol */
4019 if (!isAstEqual (root->left->left,
4023 if (AST_LIT_VALUE (root->right->right) != 1)
4026 if (AST_LIT_VALUE (root->left->right) !=
4027 (getSize (TTYPE (root->left->left)) * 8 - 1))
4030 /* whew got the first case : create the AST */
4031 return newNode (RLC, root->left->left, NULL);
4036 /* third case for RRC */
4037 /* (?symbol >> 1) | (?symbol << 7) */
4038 if (IS_LEFT_OP (root->right) &&
4039 IS_RIGHT_OP (root->left))
4042 if (!SPEC_USIGN (TETYPE (root->left->left)))
4045 if (!IS_AST_LIT_VALUE (root->left->right) ||
4046 !IS_AST_LIT_VALUE (root->right->right))
4049 /* make sure it is the same symbol */
4050 if (!isAstEqual (root->left->left,
4054 if (AST_LIT_VALUE (root->left->right) != 1)
4057 if (AST_LIT_VALUE (root->right->right) !=
4058 (getSize (TTYPE (root->left->left)) * 8 - 1))
4061 /* whew got the first case : create the AST */
4062 return newNode (RRC, root->left->left, NULL);
4066 /* fourth and last case for now */
4067 /* (?symbol << 7) | (?symbol >> 1) */
4068 if (IS_RIGHT_OP (root->right) &&
4069 IS_LEFT_OP (root->left))
4072 if (!SPEC_USIGN (TETYPE (root->left->left)))
4075 if (!IS_AST_LIT_VALUE (root->left->right) ||
4076 !IS_AST_LIT_VALUE (root->right->right))
4079 /* make sure it is the same symbol */
4080 if (!isAstEqual (root->left->left,
4084 if (AST_LIT_VALUE (root->right->right) != 1)
4087 if (AST_LIT_VALUE (root->left->right) !=
4088 (getSize (TTYPE (root->left->left)) * 8 - 1))
4091 /* whew got the first case : create the AST */
4092 return newNode (RRC, root->left->left, NULL);
4096 /* not found return root */
4100 /*-----------------------------------------------------------------*/
4101 /* optimizeCompare - otimizes compares for bit variables */
4102 /*-----------------------------------------------------------------*/
4104 optimizeCompare (ast * root)
4106 ast *optExpr = NULL;
4109 unsigned int litValue;
4111 /* if nothing then return nothing */
4115 /* if not a compare op then do leaves */
4116 if (!IS_COMPARE_OP (root))
4118 root->left = optimizeCompare (root->left);
4119 root->right = optimizeCompare (root->right);
4123 /* if left & right are the same then depending
4124 of the operation do */
4125 if (isAstEqual (root->left, root->right))
4127 switch (root->opval.op)
4132 optExpr = newAst_VALUE (constVal ("0"));
4137 optExpr = newAst_VALUE (constVal ("1"));
4141 return decorateType (optExpr);
4144 vleft = (root->left->type == EX_VALUE ?
4145 root->left->opval.val : NULL);
4147 vright = (root->right->type == EX_VALUE ?
4148 root->right->opval.val : NULL);
4150 /* if left is a BITVAR in BITSPACE */
4151 /* and right is a LITERAL then opt- */
4152 /* imize else do nothing */
4153 if (vleft && vright &&
4154 IS_BITVAR (vleft->etype) &&
4155 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4156 IS_LITERAL (vright->etype))
4159 /* if right side > 1 then comparison may never succeed */
4160 if ((litValue = (int) floatFromVal (vright)) > 1)
4162 werror (W_BAD_COMPARE);
4168 switch (root->opval.op)
4170 case '>': /* bit value greater than 1 cannot be */
4171 werror (W_BAD_COMPARE);
4175 case '<': /* bit value < 1 means 0 */
4177 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4180 case LE_OP: /* bit value <= 1 means no check */
4181 optExpr = newAst_VALUE (vright);
4184 case GE_OP: /* bit value >= 1 means only check for = */
4186 optExpr = newAst_VALUE (vleft);
4191 { /* literal is zero */
4192 switch (root->opval.op)
4194 case '<': /* bit value < 0 cannot be */
4195 werror (W_BAD_COMPARE);
4199 case '>': /* bit value > 0 means 1 */
4201 optExpr = newAst_VALUE (vleft);
4204 case LE_OP: /* bit value <= 0 means no check */
4205 case GE_OP: /* bit value >= 0 means no check */
4206 werror (W_BAD_COMPARE);
4210 case EQ_OP: /* bit == 0 means ! of bit */
4211 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4215 return decorateType (resolveSymbols (optExpr));
4216 } /* end-of-if of BITVAR */
4221 /*-----------------------------------------------------------------*/
4222 /* addSymToBlock : adds the symbol to the first block we find */
4223 /*-----------------------------------------------------------------*/
4225 addSymToBlock (symbol * sym, ast * tree)
4227 /* reached end of tree or a leaf */
4228 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4232 if (IS_AST_OP (tree) &&
4233 tree->opval.op == BLOCK)
4236 symbol *lsym = copySymbol (sym);
4238 lsym->next = AST_VALUES (tree, sym);
4239 AST_VALUES (tree, sym) = lsym;
4243 addSymToBlock (sym, tree->left);
4244 addSymToBlock (sym, tree->right);
4247 /*-----------------------------------------------------------------*/
4248 /* processRegParms - do processing for register parameters */
4249 /*-----------------------------------------------------------------*/
4251 processRegParms (value * args, ast * body)
4255 if (IS_REGPARM (args->etype))
4256 addSymToBlock (args->sym, body);
4261 /*-----------------------------------------------------------------*/
4262 /* resetParmKey - resets the operandkeys for the symbols */
4263 /*-----------------------------------------------------------------*/
4264 DEFSETFUNC (resetParmKey)
4275 /*-----------------------------------------------------------------*/
4276 /* createFunction - This is the key node that calls the iCode for */
4277 /* generating the code for a function. Note code */
4278 /* is generated function by function, later when */
4279 /* add inter-procedural analysis this will change */
4280 /*-----------------------------------------------------------------*/
4282 createFunction (symbol * name, ast * body)
4288 iCode *piCode = NULL;
4290 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4291 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4293 /* if check function return 0 then some problem */
4294 if (checkFunction (name, NULL) == 0)
4297 /* create a dummy block if none exists */
4299 body = newNode (BLOCK, NULL, NULL);
4303 /* check if the function name already in the symbol table */
4304 if ((csym = findSym (SymbolTab, NULL, name->name)))
4307 /* special case for compiler defined functions
4308 we need to add the name to the publics list : this
4309 actually means we are now compiling the compiler
4313 addSet (&publics, name);
4319 allocVariables (name);
4321 name->lastLine = yylineno;
4324 /* set the stack pointer */
4325 /* PENDING: check this for the mcs51 */
4326 stackPtr = -port->stack.direction * port->stack.call_overhead;
4327 if (IFFUNC_ISISR (name->type))
4328 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4329 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4330 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4332 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4334 fetype = getSpec (name->type); /* get the specifier for the function */
4335 /* if this is a reentrant function then */
4336 if (IFFUNC_ISREENT (name->type))
4339 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4341 /* do processing for parameters that are passed in registers */
4342 processRegParms (FUNC_ARGS(name->type), body);
4344 /* set the stack pointer */
4348 /* allocate & autoinit the block variables */
4349 processBlockVars (body, &stack, ALLOCATE);
4351 /* save the stack information */
4352 if (options.useXstack)
4353 name->xstack = SPEC_STAK (fetype) = stack;
4355 name->stack = SPEC_STAK (fetype) = stack;
4357 /* name needs to be mangled */
4358 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4360 body = resolveSymbols (body); /* resolve the symbols */
4361 body = decorateType (body); /* propagateType & do semantic checks */
4363 ex = newAst_VALUE (symbolVal (name)); /* create name */
4364 ex = newNode (FUNCTION, ex, body);
4365 ex->values.args = FUNC_ARGS(name->type);
4367 if (options.dump_tree) PA(ex);
4370 werror (E_FUNC_NO_CODE, name->name);
4374 /* create the node & generate intermediate code */
4376 codeOutFile = code->oFile;
4377 piCode = iCodeFromAst (ex);
4381 werror (E_FUNC_NO_CODE, name->name);
4385 eBBlockFromiCode (piCode);
4387 /* if there are any statics then do them */
4390 GcurMemmap = statsg;
4391 codeOutFile = statsg->oFile;
4392 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4398 /* dealloc the block variables */
4399 processBlockVars (body, &stack, DEALLOCATE);
4400 outputDebugStackSymbols();
4401 /* deallocate paramaters */
4402 deallocParms (FUNC_ARGS(name->type));
4404 if (IFFUNC_ISREENT (name->type))
4407 /* we are done freeup memory & cleanup */
4409 if (port->reset_labelKey) labelKey = 1;
4411 FUNC_HASBODY(name->type) = 1;
4412 addSet (&operKeyReset, name);
4413 applyToSet (operKeyReset, resetParmKey);
4418 cleanUpLevel (LabelTab, 0);
4419 cleanUpBlock (StructTab, 1);
4420 cleanUpBlock (TypedefTab, 1);
4422 xstack->syms = NULL;
4423 istack->syms = NULL;
4428 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4429 /*-----------------------------------------------------------------*/
4430 /* ast_print : prints the ast (for debugging purposes) */
4431 /*-----------------------------------------------------------------*/
4433 void ast_print (ast * tree, FILE *outfile, int indent)
4438 /* can print only decorated trees */
4439 if (!tree->decorated) return;
4441 /* if any child is an error | this one is an error do nothing */
4442 if (tree->isError ||
4443 (tree->left && tree->left->isError) ||
4444 (tree->right && tree->right->isError)) {
4445 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4449 /* print the line */
4450 /* if not block & function */
4451 if (tree->type == EX_OP &&
4452 (tree->opval.op != FUNCTION &&
4453 tree->opval.op != BLOCK &&
4454 tree->opval.op != NULLOP)) {
4457 if (tree->opval.op == FUNCTION) {
4459 value *args=FUNC_ARGS(tree->left->opval.val->type);
4460 fprintf(outfile,"FUNCTION (%s=%p) type (",
4461 tree->left->opval.val->name, tree);
4462 printTypeChain (tree->left->opval.val->type->next,outfile);
4463 fprintf(outfile,") args (");
4466 fprintf (outfile, ", ");
4468 printTypeChain (args ? args->type : NULL, outfile);
4470 args= args ? args->next : NULL;
4472 fprintf(outfile,")\n");
4473 ast_print(tree->left,outfile,indent);
4474 ast_print(tree->right,outfile,indent);
4477 if (tree->opval.op == BLOCK) {
4478 symbol *decls = tree->values.sym;
4479 INDENT(indent,outfile);
4480 fprintf(outfile,"{\n");
4482 INDENT(indent+2,outfile);
4483 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4484 decls->name, decls);
4485 printTypeChain(decls->type,outfile);
4486 fprintf(outfile,")\n");
4488 decls = decls->next;
4490 ast_print(tree->right,outfile,indent+2);
4491 INDENT(indent,outfile);
4492 fprintf(outfile,"}\n");
4495 if (tree->opval.op == NULLOP) {
4496 ast_print(tree->left,outfile,indent);
4497 ast_print(tree->right,outfile,indent);
4500 INDENT(indent,outfile);
4502 /*------------------------------------------------------------------*/
4503 /*----------------------------*/
4504 /* leaf has been reached */
4505 /*----------------------------*/
4506 /* if this is of type value */
4507 /* just get the type */
4508 if (tree->type == EX_VALUE) {
4510 if (IS_LITERAL (tree->opval.val->etype)) {
4511 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4512 (int) floatFromVal(tree->opval.val),
4513 (int) floatFromVal(tree->opval.val),
4514 floatFromVal(tree->opval.val));
4515 } else if (tree->opval.val->sym) {
4516 /* if the undefined flag is set then give error message */
4517 if (tree->opval.val->sym->undefined) {
4518 fprintf(outfile,"UNDEFINED SYMBOL ");
4520 fprintf(outfile,"SYMBOL ");
4522 fprintf(outfile,"(%s=%p)",
4523 tree->opval.val->sym->name,tree);
4526 fprintf(outfile," type (");
4527 printTypeChain(tree->ftype,outfile);
4528 fprintf(outfile,")\n");
4530 fprintf(outfile,"\n");
4535 /* if type link for the case of cast */
4536 if (tree->type == EX_LINK) {
4537 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4538 printTypeChain(tree->opval.lnk,outfile);
4539 fprintf(outfile,")\n");
4544 /* depending on type of operator do */
4546 switch (tree->opval.op) {
4547 /*------------------------------------------------------------------*/
4548 /*----------------------------*/
4550 /*----------------------------*/
4552 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4553 printTypeChain(tree->ftype,outfile);
4554 fprintf(outfile,")\n");
4555 ast_print(tree->left,outfile,indent+2);
4556 ast_print(tree->right,outfile,indent+2);
4559 /*------------------------------------------------------------------*/
4560 /*----------------------------*/
4562 /*----------------------------*/
4564 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4565 printTypeChain(tree->ftype,outfile);
4566 fprintf(outfile,")\n");
4567 ast_print(tree->left,outfile,indent+2);
4568 ast_print(tree->right,outfile,indent+2);
4571 /*------------------------------------------------------------------*/
4572 /*----------------------------*/
4573 /* struct/union pointer */
4574 /*----------------------------*/
4576 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4577 printTypeChain(tree->ftype,outfile);
4578 fprintf(outfile,")\n");
4579 ast_print(tree->left,outfile,indent+2);
4580 ast_print(tree->right,outfile,indent+2);
4583 /*------------------------------------------------------------------*/
4584 /*----------------------------*/
4585 /* ++/-- operation */
4586 /*----------------------------*/
4587 case INC_OP: /* incerement operator unary so left only */
4588 fprintf(outfile,"INC_OP (%p) type (",tree);
4589 printTypeChain(tree->ftype,outfile);
4590 fprintf(outfile,")\n");
4591 ast_print(tree->left,outfile,indent+2);
4595 fprintf(outfile,"DEC_OP (%p) type (",tree);
4596 printTypeChain(tree->ftype,outfile);
4597 fprintf(outfile,")\n");
4598 ast_print(tree->left,outfile,indent+2);
4601 /*------------------------------------------------------------------*/
4602 /*----------------------------*/
4604 /*----------------------------*/
4607 fprintf(outfile,"& (%p) type (",tree);
4608 printTypeChain(tree->ftype,outfile);
4609 fprintf(outfile,")\n");
4610 ast_print(tree->left,outfile,indent+2);
4611 ast_print(tree->right,outfile,indent+2);
4613 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4614 printTypeChain(tree->ftype,outfile);
4615 fprintf(outfile,")\n");
4616 ast_print(tree->left,outfile,indent+2);
4617 ast_print(tree->right,outfile,indent+2);
4620 /*----------------------------*/
4622 /*----------------------------*/
4624 fprintf(outfile,"OR (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+2);
4628 ast_print(tree->right,outfile,indent+2);
4630 /*------------------------------------------------------------------*/
4631 /*----------------------------*/
4633 /*----------------------------*/
4635 fprintf(outfile,"XOR (%p) type (",tree);
4636 printTypeChain(tree->ftype,outfile);
4637 fprintf(outfile,")\n");
4638 ast_print(tree->left,outfile,indent+2);
4639 ast_print(tree->right,outfile,indent+2);
4642 /*------------------------------------------------------------------*/
4643 /*----------------------------*/
4645 /*----------------------------*/
4647 fprintf(outfile,"DIV (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+2);
4651 ast_print(tree->right,outfile,indent+2);
4653 /*------------------------------------------------------------------*/
4654 /*----------------------------*/
4656 /*----------------------------*/
4658 fprintf(outfile,"MOD (%p) type (",tree);
4659 printTypeChain(tree->ftype,outfile);
4660 fprintf(outfile,")\n");
4661 ast_print(tree->left,outfile,indent+2);
4662 ast_print(tree->right,outfile,indent+2);
4665 /*------------------------------------------------------------------*/
4666 /*----------------------------*/
4667 /* address dereference */
4668 /*----------------------------*/
4669 case '*': /* can be unary : if right is null then unary operation */
4671 fprintf(outfile,"DEREF (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+2);
4677 /*------------------------------------------------------------------*/
4678 /*----------------------------*/
4679 /* multiplication */
4680 /*----------------------------*/
4681 fprintf(outfile,"MULT (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->left,outfile,indent+2);
4685 ast_print(tree->right,outfile,indent+2);
4689 /*------------------------------------------------------------------*/
4690 /*----------------------------*/
4691 /* unary '+' operator */
4692 /*----------------------------*/
4696 fprintf(outfile,"UPLUS (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+2);
4701 /*------------------------------------------------------------------*/
4702 /*----------------------------*/
4704 /*----------------------------*/
4705 fprintf(outfile,"ADD (%p) type (",tree);
4706 printTypeChain(tree->ftype,outfile);
4707 fprintf(outfile,")\n");
4708 ast_print(tree->left,outfile,indent+2);
4709 ast_print(tree->right,outfile,indent+2);
4712 /*------------------------------------------------------------------*/
4713 /*----------------------------*/
4715 /*----------------------------*/
4716 case '-': /* can be unary */
4718 fprintf(outfile,"UMINUS (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+2);
4723 /*------------------------------------------------------------------*/
4724 /*----------------------------*/
4726 /*----------------------------*/
4727 fprintf(outfile,"SUB (%p) type (",tree);
4728 printTypeChain(tree->ftype,outfile);
4729 fprintf(outfile,")\n");
4730 ast_print(tree->left,outfile,indent+2);
4731 ast_print(tree->right,outfile,indent+2);
4734 /*------------------------------------------------------------------*/
4735 /*----------------------------*/
4737 /*----------------------------*/
4739 fprintf(outfile,"COMPL (%p) type (",tree);
4740 printTypeChain(tree->ftype,outfile);
4741 fprintf(outfile,")\n");
4742 ast_print(tree->left,outfile,indent+2);
4744 /*------------------------------------------------------------------*/
4745 /*----------------------------*/
4747 /*----------------------------*/
4749 fprintf(outfile,"NOT (%p) type (",tree);
4750 printTypeChain(tree->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->left,outfile,indent+2);
4754 /*------------------------------------------------------------------*/
4755 /*----------------------------*/
4757 /*----------------------------*/
4759 fprintf(outfile,"RRC (%p) type (",tree);
4760 printTypeChain(tree->ftype,outfile);
4761 fprintf(outfile,")\n");
4762 ast_print(tree->left,outfile,indent+2);
4766 fprintf(outfile,"RLC (%p) type (",tree);
4767 printTypeChain(tree->ftype,outfile);
4768 fprintf(outfile,")\n");
4769 ast_print(tree->left,outfile,indent+2);
4772 fprintf(outfile,"GETHBIT (%p) type (",tree);
4773 printTypeChain(tree->ftype,outfile);
4774 fprintf(outfile,")\n");
4775 ast_print(tree->left,outfile,indent+2);
4778 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4779 printTypeChain(tree->ftype,outfile);
4780 fprintf(outfile,")\n");
4781 ast_print(tree->left,outfile,indent+2);
4782 ast_print(tree->right,outfile,indent+2);
4785 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4786 printTypeChain(tree->ftype,outfile);
4787 fprintf(outfile,")\n");
4788 ast_print(tree->left,outfile,indent+2);
4789 ast_print(tree->right,outfile,indent+2);
4791 /*------------------------------------------------------------------*/
4792 /*----------------------------*/
4794 /*----------------------------*/
4795 case CAST: /* change the type */
4796 fprintf(outfile,"CAST (%p) from type (",tree);
4797 printTypeChain(tree->right->ftype,outfile);
4798 fprintf(outfile,") to type (");
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->right,outfile,indent+2);
4805 fprintf(outfile,"ANDAND (%p) type (",tree);
4806 printTypeChain(tree->ftype,outfile);
4807 fprintf(outfile,")\n");
4808 ast_print(tree->left,outfile,indent+2);
4809 ast_print(tree->right,outfile,indent+2);
4812 fprintf(outfile,"OROR (%p) type (",tree);
4813 printTypeChain(tree->ftype,outfile);
4814 fprintf(outfile,")\n");
4815 ast_print(tree->left,outfile,indent+2);
4816 ast_print(tree->right,outfile,indent+2);
4819 /*------------------------------------------------------------------*/
4820 /*----------------------------*/
4821 /* comparison operators */
4822 /*----------------------------*/
4824 fprintf(outfile,"GT(>) (%p) type (",tree);
4825 printTypeChain(tree->ftype,outfile);
4826 fprintf(outfile,")\n");
4827 ast_print(tree->left,outfile,indent+2);
4828 ast_print(tree->right,outfile,indent+2);
4831 fprintf(outfile,"LT(<) (%p) type (",tree);
4832 printTypeChain(tree->ftype,outfile);
4833 fprintf(outfile,")\n");
4834 ast_print(tree->left,outfile,indent+2);
4835 ast_print(tree->right,outfile,indent+2);
4838 fprintf(outfile,"LE(<=) (%p) type (",tree);
4839 printTypeChain(tree->ftype,outfile);
4840 fprintf(outfile,")\n");
4841 ast_print(tree->left,outfile,indent+2);
4842 ast_print(tree->right,outfile,indent+2);
4845 fprintf(outfile,"GE(>=) (%p) type (",tree);
4846 printTypeChain(tree->ftype,outfile);
4847 fprintf(outfile,")\n");
4848 ast_print(tree->left,outfile,indent+2);
4849 ast_print(tree->right,outfile,indent+2);
4852 fprintf(outfile,"EQ(==) (%p) type (",tree);
4853 printTypeChain(tree->ftype,outfile);
4854 fprintf(outfile,")\n");
4855 ast_print(tree->left,outfile,indent+2);
4856 ast_print(tree->right,outfile,indent+2);
4859 fprintf(outfile,"NE(!=) (%p) type (",tree);
4860 printTypeChain(tree->ftype,outfile);
4861 fprintf(outfile,")\n");
4862 ast_print(tree->left,outfile,indent+2);
4863 ast_print(tree->right,outfile,indent+2);
4864 /*------------------------------------------------------------------*/
4865 /*----------------------------*/
4867 /*----------------------------*/
4868 case SIZEOF: /* evaluate wihout code generation */
4869 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4872 /*------------------------------------------------------------------*/
4873 /*----------------------------*/
4874 /* conditional operator '?' */
4875 /*----------------------------*/
4877 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4878 printTypeChain(tree->ftype,outfile);
4879 fprintf(outfile,")\n");
4880 ast_print(tree->left,outfile,indent+2);
4881 ast_print(tree->right,outfile,indent+2);
4885 fprintf(outfile,"COLON(:) (%p) type (",tree);
4886 printTypeChain(tree->ftype,outfile);
4887 fprintf(outfile,")\n");
4888 ast_print(tree->left,outfile,indent+2);
4889 ast_print(tree->right,outfile,indent+2);
4892 /*------------------------------------------------------------------*/
4893 /*----------------------------*/
4894 /* assignment operators */
4895 /*----------------------------*/
4897 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4898 printTypeChain(tree->ftype,outfile);
4899 fprintf(outfile,")\n");
4900 ast_print(tree->left,outfile,indent+2);
4901 ast_print(tree->right,outfile,indent+2);
4904 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4905 printTypeChain(tree->ftype,outfile);
4906 fprintf(outfile,")\n");
4907 ast_print(tree->left,outfile,indent+2);
4908 ast_print(tree->right,outfile,indent+2);
4911 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4912 printTypeChain(tree->ftype,outfile);
4913 fprintf(outfile,")\n");
4914 ast_print(tree->left,outfile,indent+2);
4915 ast_print(tree->right,outfile,indent+2);
4918 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
4919 printTypeChain(tree->ftype,outfile);
4920 fprintf(outfile,")\n");
4921 ast_print(tree->left,outfile,indent+2);
4922 ast_print(tree->right,outfile,indent+2);
4925 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
4926 printTypeChain(tree->ftype,outfile);
4927 fprintf(outfile,")\n");
4928 ast_print(tree->left,outfile,indent+2);
4929 ast_print(tree->right,outfile,indent+2);
4932 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4933 printTypeChain(tree->ftype,outfile);
4934 fprintf(outfile,")\n");
4935 ast_print(tree->left,outfile,indent+2);
4936 ast_print(tree->right,outfile,indent+2);
4939 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
4940 printTypeChain(tree->ftype,outfile);
4941 fprintf(outfile,")\n");
4942 ast_print(tree->left,outfile,indent+2);
4943 ast_print(tree->right,outfile,indent+2);
4945 /*------------------------------------------------------------------*/
4946 /*----------------------------*/
4948 /*----------------------------*/
4950 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4951 printTypeChain(tree->ftype,outfile);
4952 fprintf(outfile,")\n");
4953 ast_print(tree->left,outfile,indent+2);
4954 ast_print(tree->right,outfile,indent+2);
4956 /*------------------------------------------------------------------*/
4957 /*----------------------------*/
4959 /*----------------------------*/
4961 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4962 printTypeChain(tree->ftype,outfile);
4963 fprintf(outfile,")\n");
4964 ast_print(tree->left,outfile,indent+2);
4965 ast_print(tree->right,outfile,indent+2);
4967 /*------------------------------------------------------------------*/
4968 /*----------------------------*/
4969 /* straight assignemnt */
4970 /*----------------------------*/
4972 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4973 printTypeChain(tree->ftype,outfile);
4974 fprintf(outfile,")\n");
4975 ast_print(tree->left,outfile,indent+2);
4976 ast_print(tree->right,outfile,indent+2);
4978 /*------------------------------------------------------------------*/
4979 /*----------------------------*/
4980 /* comma operator */
4981 /*----------------------------*/
4983 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4984 printTypeChain(tree->ftype,outfile);
4985 fprintf(outfile,")\n");
4986 ast_print(tree->left,outfile,indent+2);
4987 ast_print(tree->right,outfile,indent+2);
4989 /*------------------------------------------------------------------*/
4990 /*----------------------------*/
4992 /*----------------------------*/
4995 fprintf(outfile,"CALL (%p) type (",tree);
4996 printTypeChain(tree->ftype,outfile);
4997 fprintf(outfile,")\n");
4998 ast_print(tree->left,outfile,indent+2);
4999 ast_print(tree->right,outfile,indent+2);
5002 fprintf(outfile,"PARMS\n");
5003 ast_print(tree->left,outfile,indent+2);
5004 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5005 ast_print(tree->right,outfile,indent+2);
5008 /*------------------------------------------------------------------*/
5009 /*----------------------------*/
5010 /* return statement */
5011 /*----------------------------*/
5013 fprintf(outfile,"RETURN (%p) type (",tree);
5015 printTypeChain(tree->right->ftype,outfile);
5017 fprintf(outfile,")\n");
5018 ast_print(tree->right,outfile,indent+2);
5020 /*------------------------------------------------------------------*/
5021 /*----------------------------*/
5022 /* label statement */
5023 /*----------------------------*/
5025 fprintf(outfile,"LABEL (%p)\n",tree);
5026 ast_print(tree->left,outfile,indent+2);
5027 ast_print(tree->right,outfile,indent);
5029 /*------------------------------------------------------------------*/
5030 /*----------------------------*/
5031 /* switch statement */
5032 /*----------------------------*/
5036 fprintf(outfile,"SWITCH (%p) ",tree);
5037 ast_print(tree->left,outfile,0);
5038 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5039 INDENT(indent+2,outfile);
5040 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5041 (int) floatFromVal(val),
5042 tree->values.switchVals.swNum,
5043 (int) floatFromVal(val));
5045 ast_print(tree->right,outfile,indent);
5048 /*------------------------------------------------------------------*/
5049 /*----------------------------*/
5051 /*----------------------------*/
5053 fprintf(outfile,"IF (%p) \n",tree);
5054 ast_print(tree->left,outfile,indent+2);
5055 if (tree->trueLabel) {
5056 INDENT(indent+2,outfile);
5057 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5059 if (tree->falseLabel) {
5060 INDENT(indent+2,outfile);
5061 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5063 ast_print(tree->right,outfile,indent+2);
5065 /*----------------------------*/
5066 /* goto Statement */
5067 /*----------------------------*/
5069 fprintf(outfile,"GOTO (%p) \n",tree);
5070 ast_print(tree->left,outfile,indent+2);
5071 fprintf(outfile,"\n");
5073 /*------------------------------------------------------------------*/
5074 /*----------------------------*/
5076 /*----------------------------*/
5078 fprintf(outfile,"FOR (%p) \n",tree);
5079 if (AST_FOR( tree, initExpr)) {
5080 INDENT(indent+2,outfile);
5081 fprintf(outfile,"INIT EXPR ");
5082 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5084 if (AST_FOR( tree, condExpr)) {
5085 INDENT(indent+2,outfile);
5086 fprintf(outfile,"COND EXPR ");
5087 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5089 if (AST_FOR( tree, loopExpr)) {
5090 INDENT(indent+2,outfile);
5091 fprintf(outfile,"LOOP EXPR ");
5092 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5094 fprintf(outfile,"FOR LOOP BODY \n");
5095 ast_print(tree->left,outfile,indent+2);
5104 ast_print(t,stdout,0);