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
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 // jwk: 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);
2066 /*------------------------------------------------------------------*/
2067 /*----------------------------*/
2069 /*----------------------------*/
2071 /* if this is not a structure */
2072 if (!IS_STRUCT (LTYPE (tree)))
2074 werror (E_STRUCT_UNION, ".");
2075 goto errorTreeReturn;
2077 TTYPE (tree) = structElemType (LTYPE (tree),
2078 (tree->right->type == EX_VALUE ?
2079 tree->right->opval.val : NULL));
2080 TETYPE (tree) = getSpec (TTYPE (tree));
2083 /*------------------------------------------------------------------*/
2084 /*----------------------------*/
2085 /* struct/union pointer */
2086 /*----------------------------*/
2088 /* if not pointer to a structure */
2089 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2091 werror (E_PTR_REQD);
2092 goto errorTreeReturn;
2095 if (!IS_STRUCT (LTYPE (tree)->next))
2097 werror (E_STRUCT_UNION, "->");
2098 goto errorTreeReturn;
2101 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2102 (tree->right->type == EX_VALUE ?
2103 tree->right->opval.val : NULL));
2104 TETYPE (tree) = getSpec (TTYPE (tree));
2106 /* adjust the storage class */
2107 switch (DCL_TYPE(tree->left->ftype)) {
2111 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2114 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2119 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2122 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2125 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2135 /*------------------------------------------------------------------*/
2136 /*----------------------------*/
2137 /* ++/-- operation */
2138 /*----------------------------*/
2139 case INC_OP: /* incerement operator unary so left only */
2142 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2143 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2144 if (!tree->initMode && IS_CONSTANT (TTYPE (tree)))
2145 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2154 /*------------------------------------------------------------------*/
2155 /*----------------------------*/
2157 /*----------------------------*/
2158 case '&': /* can be unary */
2159 /* if right is NULL then unary operation */
2160 if (tree->right) /* not an unary operation */
2163 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2165 werror (E_BITWISE_OP);
2166 werror (W_CONTINUE, "left & right types are ");
2167 printTypeChain (LTYPE (tree), stderr);
2168 fprintf (stderr, ",");
2169 printTypeChain (RTYPE (tree), stderr);
2170 fprintf (stderr, "\n");
2171 goto errorTreeReturn;
2174 /* if they are both literal */
2175 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2177 tree->type = EX_VALUE;
2178 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2179 valFromType (RETYPE (tree)), '&');
2181 tree->right = tree->left = NULL;
2182 TETYPE (tree) = tree->opval.val->etype;
2183 TTYPE (tree) = tree->opval.val->type;
2187 /* see if this is a GETHBIT operation if yes
2190 ast *otree = optimizeGetHbit (tree);
2193 return decorateType (otree);
2197 computeType (LTYPE (tree), RTYPE (tree));
2198 TETYPE (tree) = getSpec (TTYPE (tree));
2200 LRVAL (tree) = RRVAL (tree) = 1;
2204 /*------------------------------------------------------------------*/
2205 /*----------------------------*/
2207 /*----------------------------*/
2208 p = newLink (DECLARATOR);
2209 /* if bit field then error */
2210 if (IS_BITVAR (tree->left->etype))
2212 werror (E_ILLEGAL_ADDR, "address of bit variable");
2213 goto errorTreeReturn;
2216 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2218 werror (E_ILLEGAL_ADDR, "address of register variable");
2219 goto errorTreeReturn;
2222 if (IS_FUNC (LTYPE (tree)))
2224 // this ought to be ignored
2225 return (tree->left);
2228 if (IS_LITERAL(LTYPE(tree)))
2230 werror (E_ILLEGAL_ADDR, "address of literal");
2231 goto errorTreeReturn;
2236 werror (E_LVALUE_REQUIRED, "address of");
2237 goto errorTreeReturn;
2239 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2240 DCL_TYPE (p) = CPOINTER;
2241 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2242 DCL_TYPE (p) = FPOINTER;
2243 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2244 DCL_TYPE (p) = PPOINTER;
2245 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2246 DCL_TYPE (p) = IPOINTER;
2247 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2248 DCL_TYPE (p) = EEPPOINTER;
2249 else if (SPEC_OCLS(tree->left->etype))
2250 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2252 DCL_TYPE (p) = POINTER;
2254 if (IS_AST_SYM_VALUE (tree->left))
2256 AST_SYMBOL (tree->left)->addrtaken = 1;
2257 AST_SYMBOL (tree->left)->allocreq = 1;
2260 p->next = LTYPE (tree);
2262 TETYPE (tree) = getSpec (TTYPE (tree));
2267 /*------------------------------------------------------------------*/
2268 /*----------------------------*/
2270 /*----------------------------*/
2272 /* if the rewrite succeeds then don't go any furthur */
2274 ast *wtree = optimizeRRCRLC (tree);
2276 return decorateType (wtree);
2279 /*------------------------------------------------------------------*/
2280 /*----------------------------*/
2282 /*----------------------------*/
2284 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2286 werror (E_BITWISE_OP);
2287 werror (W_CONTINUE, "left & right types are ");
2288 printTypeChain (LTYPE (tree), stderr);
2289 fprintf (stderr, ",");
2290 printTypeChain (RTYPE (tree), stderr);
2291 fprintf (stderr, "\n");
2292 goto errorTreeReturn;
2295 /* if they are both literal then */
2296 /* rewrite the tree */
2297 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2299 tree->type = EX_VALUE;
2300 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2301 valFromType (RETYPE (tree)),
2303 tree->right = tree->left = NULL;
2304 TETYPE (tree) = tree->opval.val->etype;
2305 TTYPE (tree) = tree->opval.val->type;
2308 LRVAL (tree) = RRVAL (tree) = 1;
2309 TETYPE (tree) = getSpec (TTYPE (tree) =
2310 computeType (LTYPE (tree),
2313 /*------------------------------------------------------------------*/
2314 /*----------------------------*/
2316 /*----------------------------*/
2318 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2320 werror (E_INVALID_OP, "divide");
2321 goto errorTreeReturn;
2323 /* if they are both literal then */
2324 /* rewrite the tree */
2325 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2327 tree->type = EX_VALUE;
2328 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2329 valFromType (RETYPE (tree)));
2330 tree->right = tree->left = NULL;
2331 TETYPE (tree) = getSpec (TTYPE (tree) =
2332 tree->opval.val->type);
2335 LRVAL (tree) = RRVAL (tree) = 1;
2336 TETYPE (tree) = getSpec (TTYPE (tree) =
2337 computeType (LTYPE (tree),
2341 /*------------------------------------------------------------------*/
2342 /*----------------------------*/
2344 /*----------------------------*/
2346 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2348 werror (E_BITWISE_OP);
2349 werror (W_CONTINUE, "left & right types are ");
2350 printTypeChain (LTYPE (tree), stderr);
2351 fprintf (stderr, ",");
2352 printTypeChain (RTYPE (tree), stderr);
2353 fprintf (stderr, "\n");
2354 goto errorTreeReturn;
2356 /* if they are both literal then */
2357 /* rewrite the tree */
2358 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2360 tree->type = EX_VALUE;
2361 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2362 valFromType (RETYPE (tree)));
2363 tree->right = tree->left = NULL;
2364 TETYPE (tree) = getSpec (TTYPE (tree) =
2365 tree->opval.val->type);
2368 LRVAL (tree) = RRVAL (tree) = 1;
2369 TETYPE (tree) = getSpec (TTYPE (tree) =
2370 computeType (LTYPE (tree),
2374 /*------------------------------------------------------------------*/
2375 /*----------------------------*/
2376 /* address dereference */
2377 /*----------------------------*/
2378 case '*': /* can be unary : if right is null then unary operation */
2381 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2383 werror (E_PTR_REQD);
2384 goto errorTreeReturn;
2389 werror (E_LVALUE_REQUIRED, "pointer deref");
2390 goto errorTreeReturn;
2392 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2393 LTYPE (tree)->next : NULL);
2394 TETYPE (tree) = getSpec (TTYPE (tree));
2398 /*------------------------------------------------------------------*/
2399 /*----------------------------*/
2400 /* multiplication */
2401 /*----------------------------*/
2402 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2404 werror (E_INVALID_OP, "multiplication");
2405 goto errorTreeReturn;
2408 /* if they are both literal then */
2409 /* rewrite the tree */
2410 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2412 tree->type = EX_VALUE;
2413 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2414 valFromType (RETYPE (tree)));
2415 tree->right = tree->left = NULL;
2416 TETYPE (tree) = getSpec (TTYPE (tree) =
2417 tree->opval.val->type);
2421 /* if left is a literal exchange left & right */
2422 if (IS_LITERAL (LTYPE (tree)))
2424 ast *tTree = tree->left;
2425 tree->left = tree->right;
2426 tree->right = tTree;
2429 LRVAL (tree) = RRVAL (tree) = 1;
2430 TETYPE (tree) = getSpec (TTYPE (tree) =
2431 computeType (LTYPE (tree),
2434 /* promote result to int if left & right are char
2435 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2436 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2437 SPEC_NOUN(TETYPE(tree)) = V_INT;
2442 /*------------------------------------------------------------------*/
2443 /*----------------------------*/
2444 /* unary '+' operator */
2445 /*----------------------------*/
2450 if (!IS_INTEGRAL (LTYPE (tree)))
2452 werror (E_UNARY_OP, '+');
2453 goto errorTreeReturn;
2456 /* if left is a literal then do it */
2457 if (IS_LITERAL (LTYPE (tree)))
2459 tree->type = EX_VALUE;
2460 tree->opval.val = valFromType (LETYPE (tree));
2462 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2466 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2470 /*------------------------------------------------------------------*/
2471 /*----------------------------*/
2473 /*----------------------------*/
2475 /* this is not a unary operation */
2476 /* if both pointers then problem */
2477 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2478 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2480 werror (E_PTR_PLUS_PTR);
2481 goto errorTreeReturn;
2484 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2485 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2487 werror (E_PLUS_INVALID, "+");
2488 goto errorTreeReturn;
2491 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2492 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2494 werror (E_PLUS_INVALID, "+");
2495 goto errorTreeReturn;
2497 /* if they are both literal then */
2498 /* rewrite the tree */
2499 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2501 tree->type = EX_VALUE;
2502 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2503 valFromType (RETYPE (tree)));
2504 tree->right = tree->left = NULL;
2505 TETYPE (tree) = getSpec (TTYPE (tree) =
2506 tree->opval.val->type);
2510 /* if the right is a pointer or left is a literal
2511 xchange left & right */
2512 if (IS_ARRAY (RTYPE (tree)) ||
2513 IS_PTR (RTYPE (tree)) ||
2514 IS_LITERAL (LTYPE (tree)))
2516 ast *tTree = tree->left;
2517 tree->left = tree->right;
2518 tree->right = tTree;
2521 LRVAL (tree) = RRVAL (tree) = 1;
2522 /* if the left is a pointer */
2523 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2524 TETYPE (tree) = getSpec (TTYPE (tree) =
2527 TETYPE (tree) = getSpec (TTYPE (tree) =
2528 computeType (LTYPE (tree),
2532 /*------------------------------------------------------------------*/
2533 /*----------------------------*/
2535 /*----------------------------*/
2536 case '-': /* can be unary */
2537 /* if right is null then unary */
2541 if (!IS_ARITHMETIC (LTYPE (tree)))
2543 werror (E_UNARY_OP, tree->opval.op);
2544 goto errorTreeReturn;
2547 /* if left is a literal then do it */
2548 if (IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2553 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2554 SPEC_USIGN(TETYPE(tree)) = 0;
2558 TTYPE (tree) = LTYPE (tree);
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2565 /*----------------------------*/
2567 if (!(IS_PTR (LTYPE (tree)) ||
2568 IS_ARRAY (LTYPE (tree)) ||
2569 IS_ARITHMETIC (LTYPE (tree))))
2571 werror (E_PLUS_INVALID, "-");
2572 goto errorTreeReturn;
2575 if (!(IS_PTR (RTYPE (tree)) ||
2576 IS_ARRAY (RTYPE (tree)) ||
2577 IS_ARITHMETIC (RTYPE (tree))))
2579 werror (E_PLUS_INVALID, "-");
2580 goto errorTreeReturn;
2583 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2584 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2585 IS_INTEGRAL (RTYPE (tree))))
2587 werror (E_PLUS_INVALID, "-");
2588 goto errorTreeReturn;
2591 /* if they are both literal then */
2592 /* rewrite the tree */
2593 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2595 tree->type = EX_VALUE;
2596 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2597 valFromType (RETYPE (tree)));
2598 tree->right = tree->left = NULL;
2599 TETYPE (tree) = getSpec (TTYPE (tree) =
2600 tree->opval.val->type);
2604 /* if the left & right are equal then zero */
2605 if (isAstEqual (tree->left, tree->right))
2607 tree->type = EX_VALUE;
2608 tree->left = tree->right = NULL;
2609 tree->opval.val = constVal ("0");
2610 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2614 /* if both of them are pointers or arrays then */
2615 /* the result is going to be an integer */
2616 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2617 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2618 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2620 /* if only the left is a pointer */
2621 /* then result is a pointer */
2622 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2623 TETYPE (tree) = getSpec (TTYPE (tree) =
2626 TETYPE (tree) = getSpec (TTYPE (tree) =
2627 computeType (LTYPE (tree),
2629 LRVAL (tree) = RRVAL (tree) = 1;
2632 /*------------------------------------------------------------------*/
2633 /*----------------------------*/
2635 /*----------------------------*/
2637 /* can be only integral type */
2638 if (!IS_INTEGRAL (LTYPE (tree)))
2640 werror (E_UNARY_OP, tree->opval.op);
2641 goto errorTreeReturn;
2644 /* if left is a literal then do it */
2645 if (IS_LITERAL (LTYPE (tree)))
2647 tree->type = EX_VALUE;
2648 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2650 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2654 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2657 /*------------------------------------------------------------------*/
2658 /*----------------------------*/
2660 /*----------------------------*/
2662 /* can be pointer */
2663 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2664 !IS_PTR (LTYPE (tree)) &&
2665 !IS_ARRAY (LTYPE (tree)))
2667 werror (E_UNARY_OP, tree->opval.op);
2668 goto errorTreeReturn;
2671 /* if left is a literal then do it */
2672 if (IS_LITERAL (LTYPE (tree)))
2674 tree->type = EX_VALUE;
2675 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2677 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2681 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2684 /*------------------------------------------------------------------*/
2685 /*----------------------------*/
2687 /*----------------------------*/
2690 TTYPE (tree) = LTYPE (tree);
2691 TETYPE (tree) = LETYPE (tree);
2695 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2700 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2702 werror (E_SHIFT_OP_INVALID);
2703 werror (W_CONTINUE, "left & right types are ");
2704 printTypeChain (LTYPE (tree), stderr);
2705 fprintf (stderr, ",");
2706 printTypeChain (RTYPE (tree), stderr);
2707 fprintf (stderr, "\n");
2708 goto errorTreeReturn;
2711 /* if they are both literal then */
2712 /* rewrite the tree */
2713 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2715 tree->type = EX_VALUE;
2716 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2717 valFromType (RETYPE (tree)),
2718 (tree->opval.op == LEFT_OP ? 1 : 0));
2719 tree->right = tree->left = NULL;
2720 TETYPE (tree) = getSpec (TTYPE (tree) =
2721 tree->opval.val->type);
2725 /* if only the right side is a literal & we are
2726 shifting more than size of the left operand then zero */
2727 if (IS_LITERAL (RTYPE (tree)) &&
2728 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2729 (getSize (LTYPE (tree)) * 8))
2731 if (tree->opval.op==LEFT_OP ||
2732 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2733 lineno=tree->lineno;
2734 werror (W_SHIFT_CHANGED,
2735 (tree->opval.op == LEFT_OP ? "left" : "right"));
2736 tree->type = EX_VALUE;
2737 tree->left = tree->right = NULL;
2738 tree->opval.val = constVal ("0");
2739 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2743 LRVAL (tree) = RRVAL (tree) = 1;
2744 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2746 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2750 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2754 /*------------------------------------------------------------------*/
2755 /*----------------------------*/
2757 /*----------------------------*/
2758 case CAST: /* change the type */
2759 /* cannot cast to an aggregate type */
2760 if (IS_AGGREGATE (LTYPE (tree)))
2762 werror (E_CAST_ILLEGAL);
2763 goto errorTreeReturn;
2766 /* make sure the type is complete and sane */
2767 checkTypeSanity(LETYPE(tree), "(cast)");
2770 /* if the right is a literal replace the tree */
2771 if (IS_LITERAL (RETYPE (tree))) {
2772 if (!IS_PTR (LTYPE (tree))) {
2773 tree->type = EX_VALUE;
2775 valCastLiteral (LTYPE (tree),
2776 floatFromVal (valFromType (RETYPE (tree))));
2779 TTYPE (tree) = tree->opval.val->type;
2780 tree->values.literalFromCast = 1;
2781 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2782 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2783 sym_link *rest = LTYPE(tree)->next;
2784 werror(W_LITERAL_GENERIC);
2785 TTYPE(tree) = newLink(DECLARATOR);
2786 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2787 TTYPE(tree)->next = rest;
2788 tree->left->opval.lnk = TTYPE(tree);
2791 TTYPE (tree) = LTYPE (tree);
2795 TTYPE (tree) = LTYPE (tree);
2799 #if 0 // this is already checked, now this could be explicit
2800 /* if pointer to struct then check names */
2801 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2802 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2803 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2805 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2806 SPEC_STRUCT(LETYPE(tree))->tag);
2809 /* if the right is a literal replace the tree */
2810 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2811 tree->type = EX_VALUE;
2813 valCastLiteral (LTYPE (tree),
2814 floatFromVal (valFromType (RETYPE (tree))));
2817 TTYPE (tree) = tree->opval.val->type;
2818 tree->values.literalFromCast = 1;
2820 TTYPE (tree) = LTYPE (tree);
2824 TETYPE (tree) = getSpec (TTYPE (tree));
2828 /*------------------------------------------------------------------*/
2829 /*----------------------------*/
2830 /* logical &&, || */
2831 /*----------------------------*/
2834 /* each must me arithmetic type or be a pointer */
2835 if (!IS_PTR (LTYPE (tree)) &&
2836 !IS_ARRAY (LTYPE (tree)) &&
2837 !IS_INTEGRAL (LTYPE (tree)))
2839 werror (E_COMPARE_OP);
2840 goto errorTreeReturn;
2843 if (!IS_PTR (RTYPE (tree)) &&
2844 !IS_ARRAY (RTYPE (tree)) &&
2845 !IS_INTEGRAL (RTYPE (tree)))
2847 werror (E_COMPARE_OP);
2848 goto errorTreeReturn;
2850 /* if they are both literal then */
2851 /* rewrite the tree */
2852 if (IS_LITERAL (RTYPE (tree)) &&
2853 IS_LITERAL (LTYPE (tree)))
2855 tree->type = EX_VALUE;
2856 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2857 valFromType (RETYPE (tree)),
2859 tree->right = tree->left = NULL;
2860 TETYPE (tree) = getSpec (TTYPE (tree) =
2861 tree->opval.val->type);
2864 LRVAL (tree) = RRVAL (tree) = 1;
2865 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2868 /*------------------------------------------------------------------*/
2869 /*----------------------------*/
2870 /* comparison operators */
2871 /*----------------------------*/
2879 ast *lt = optimizeCompare (tree);
2885 /* if they are pointers they must be castable */
2886 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2888 if (tree->opval.op==EQ_OP &&
2889 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
2890 // we cannot cast a gptr to a !gptr: switch the leaves
2891 struct ast *s=tree->left;
2892 tree->left=tree->right;
2895 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2897 werror (E_COMPARE_OP);
2898 fprintf (stderr, "comparring type ");
2899 printTypeChain (LTYPE (tree), stderr);
2900 fprintf (stderr, "to type ");
2901 printTypeChain (RTYPE (tree), stderr);
2902 fprintf (stderr, "\n");
2903 goto errorTreeReturn;
2906 /* else they should be promotable to one another */
2909 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2910 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2912 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2914 werror (E_COMPARE_OP);
2915 fprintf (stderr, "comparing type ");
2916 printTypeChain (LTYPE (tree), stderr);
2917 fprintf (stderr, "to type ");
2918 printTypeChain (RTYPE (tree), stderr);
2919 fprintf (stderr, "\n");
2920 goto errorTreeReturn;
2923 /* if unsigned value < 0 then always false */
2924 /* if (unsigned value) > 0 then (unsigned value) */
2925 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2926 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2928 if (tree->opval.op == '<') {
2931 if (tree->opval.op == '>') {
2935 /* if they are both literal then */
2936 /* rewrite the tree */
2937 if (IS_LITERAL (RTYPE (tree)) &&
2938 IS_LITERAL (LTYPE (tree)))
2940 tree->type = EX_VALUE;
2941 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2942 valFromType (RETYPE (tree)),
2944 tree->right = tree->left = NULL;
2945 TETYPE (tree) = getSpec (TTYPE (tree) =
2946 tree->opval.val->type);
2949 LRVAL (tree) = RRVAL (tree) = 1;
2950 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2953 /*------------------------------------------------------------------*/
2954 /*----------------------------*/
2956 /*----------------------------*/
2957 case SIZEOF: /* evaluate wihout code generation */
2958 /* change the type to a integer */
2959 tree->type = EX_VALUE;
2960 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2961 tree->opval.val = constVal (buffer);
2962 tree->right = tree->left = NULL;
2963 TETYPE (tree) = getSpec (TTYPE (tree) =
2964 tree->opval.val->type);
2967 /*------------------------------------------------------------------*/
2968 /*----------------------------*/
2970 /*----------------------------*/
2972 /* return typeof enum value */
2973 tree->type = EX_VALUE;
2976 if (IS_SPEC(tree->right->ftype)) {
2977 switch (SPEC_NOUN(tree->right->ftype)) {
2979 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2980 else typeofv = TYPEOF_INT;
2983 typeofv = TYPEOF_FLOAT;
2986 typeofv = TYPEOF_CHAR;
2989 typeofv = TYPEOF_VOID;
2992 typeofv = TYPEOF_STRUCT;
2995 typeofv = TYPEOF_BIT;
2998 typeofv = TYPEOF_SBIT;
3004 switch (DCL_TYPE(tree->right->ftype)) {
3006 typeofv = TYPEOF_POINTER;
3009 typeofv = TYPEOF_FPOINTER;
3012 typeofv = TYPEOF_CPOINTER;
3015 typeofv = TYPEOF_GPOINTER;
3018 typeofv = TYPEOF_PPOINTER;
3021 typeofv = TYPEOF_IPOINTER;
3024 typeofv = TYPEOF_ARRAY;
3027 typeofv = TYPEOF_FUNCTION;
3033 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3034 tree->opval.val = constVal (buffer);
3035 tree->right = tree->left = NULL;
3036 TETYPE (tree) = getSpec (TTYPE (tree) =
3037 tree->opval.val->type);
3040 /*------------------------------------------------------------------*/
3041 /*----------------------------*/
3042 /* conditional operator '?' */
3043 /*----------------------------*/
3045 /* the type is value of the colon operator (on the right) */
3046 assert(IS_COLON_OP(tree->right));
3047 /* if already known then replace the tree : optimizer will do it
3048 but faster to do it here */
3049 if (IS_LITERAL (LTYPE(tree))) {
3050 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3051 return decorateType(tree->right->left) ;
3053 return decorateType(tree->right->right) ;
3056 tree->right = decorateType(tree->right);
3057 TTYPE (tree) = RTYPE(tree);
3058 TETYPE (tree) = getSpec (TTYPE (tree));
3063 /* if they don't match we have a problem */
3064 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3066 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3067 goto errorTreeReturn;
3070 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3071 TETYPE (tree) = getSpec (TTYPE (tree));
3075 #if 0 // assignment operators are converted by the parser
3076 /*------------------------------------------------------------------*/
3077 /*----------------------------*/
3078 /* assignment operators */
3079 /*----------------------------*/
3082 /* for these it must be both must be integral */
3083 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3084 !IS_ARITHMETIC (RTYPE (tree)))
3086 werror (E_OPS_INTEGRAL);
3087 goto errorTreeReturn;
3090 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3092 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3093 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3097 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3098 goto errorTreeReturn;
3109 /* for these it must be both must be integral */
3110 if (!IS_INTEGRAL (LTYPE (tree)) ||
3111 !IS_INTEGRAL (RTYPE (tree)))
3113 werror (E_OPS_INTEGRAL);
3114 goto errorTreeReturn;
3117 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3119 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3120 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3124 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3125 goto errorTreeReturn;
3131 /*------------------------------------------------------------------*/
3132 /*----------------------------*/
3134 /*----------------------------*/
3136 if (!(IS_PTR (LTYPE (tree)) ||
3137 IS_ARITHMETIC (LTYPE (tree))))
3139 werror (E_PLUS_INVALID, "-=");
3140 goto errorTreeReturn;
3143 if (!(IS_PTR (RTYPE (tree)) ||
3144 IS_ARITHMETIC (RTYPE (tree))))
3146 werror (E_PLUS_INVALID, "-=");
3147 goto errorTreeReturn;
3150 TETYPE (tree) = getSpec (TTYPE (tree) =
3151 computeType (LTYPE (tree),
3154 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3155 werror (E_CODE_WRITE, "-=");
3159 werror (E_LVALUE_REQUIRED, "-=");
3160 goto errorTreeReturn;
3166 /*------------------------------------------------------------------*/
3167 /*----------------------------*/
3169 /*----------------------------*/
3171 /* this is not a unary operation */
3172 /* if both pointers then problem */
3173 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3175 werror (E_PTR_PLUS_PTR);
3176 goto errorTreeReturn;
3179 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3181 werror (E_PLUS_INVALID, "+=");
3182 goto errorTreeReturn;
3185 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3187 werror (E_PLUS_INVALID, "+=");
3188 goto errorTreeReturn;
3191 TETYPE (tree) = getSpec (TTYPE (tree) =
3192 computeType (LTYPE (tree),
3195 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3196 werror (E_CODE_WRITE, "+=");
3200 werror (E_LVALUE_REQUIRED, "+=");
3201 goto errorTreeReturn;
3204 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3205 tree->opval.op = '=';
3210 /*------------------------------------------------------------------*/
3211 /*----------------------------*/
3212 /* straight assignemnt */
3213 /*----------------------------*/
3215 /* cannot be an aggregate */
3216 if (IS_AGGREGATE (LTYPE (tree)))
3218 werror (E_AGGR_ASSIGN);
3219 goto errorTreeReturn;
3222 /* they should either match or be castable */
3223 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3225 werror (E_TYPE_MISMATCH, "assignment", " ");
3226 printFromToType(RTYPE(tree),LTYPE(tree));
3227 //goto errorTreeReturn;
3230 /* if the left side of the tree is of type void
3231 then report error */
3232 if (IS_VOID (LTYPE (tree)))
3234 werror (E_CAST_ZERO);
3235 printFromToType(RTYPE(tree), LTYPE(tree));
3238 TETYPE (tree) = getSpec (TTYPE (tree) =
3242 if (!tree->initMode ) {
3243 if (IS_CONSTANT (LTYPE (tree)))
3244 werror (E_CODE_WRITE, "=");
3248 werror (E_LVALUE_REQUIRED, "=");
3249 goto errorTreeReturn;
3254 /*------------------------------------------------------------------*/
3255 /*----------------------------*/
3256 /* comma operator */
3257 /*----------------------------*/
3259 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3262 /*------------------------------------------------------------------*/
3263 /*----------------------------*/
3265 /*----------------------------*/
3269 if (processParms (tree->left,
3270 FUNC_ARGS(tree->left->ftype),
3271 tree->right, &parmNumber, TRUE)) {
3272 goto errorTreeReturn;
3275 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3276 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3278 //FUNC_ARGS(tree->left->ftype) =
3279 //reverseVal (FUNC_ARGS(tree->left->ftype));
3280 reverseParms (tree->right);
3283 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3286 /*------------------------------------------------------------------*/
3287 /*----------------------------*/
3288 /* return statement */
3289 /*----------------------------*/
3294 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3296 werror (W_RETURN_MISMATCH);
3297 printFromToType (RTYPE(tree), currFunc->type->next);
3298 goto errorTreeReturn;
3301 if (IS_VOID (currFunc->type->next)
3303 !IS_VOID (RTYPE (tree)))
3305 werror (E_FUNC_VOID);
3306 goto errorTreeReturn;
3309 /* if there is going to be a casing required then add it */
3310 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3313 decorateType (newNode (CAST,
3314 newAst_LINK (copyLinkChain (currFunc->type->next)),
3323 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3325 werror (E_VOID_FUNC, currFunc->name);
3326 goto errorTreeReturn;
3329 TTYPE (tree) = TETYPE (tree) = NULL;
3332 /*------------------------------------------------------------------*/
3333 /*----------------------------*/
3334 /* switch statement */
3335 /*----------------------------*/
3337 /* the switch value must be an integer */
3338 if (!IS_INTEGRAL (LTYPE (tree)))
3340 werror (E_SWITCH_NON_INTEGER);
3341 goto errorTreeReturn;
3344 TTYPE (tree) = TETYPE (tree) = NULL;
3347 /*------------------------------------------------------------------*/
3348 /*----------------------------*/
3350 /*----------------------------*/
3352 tree->left = backPatchLabels (tree->left,
3355 TTYPE (tree) = TETYPE (tree) = NULL;
3358 /*------------------------------------------------------------------*/
3359 /*----------------------------*/
3361 /*----------------------------*/
3364 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3365 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3366 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3368 /* if the for loop is reversible then
3369 reverse it otherwise do what we normally
3375 if (isLoopReversible (tree, &sym, &init, &end))
3376 return reverseLoop (tree, sym, init, end);
3378 return decorateType (createFor (AST_FOR (tree, trueLabel),
3379 AST_FOR (tree, continueLabel),
3380 AST_FOR (tree, falseLabel),
3381 AST_FOR (tree, condLabel),
3382 AST_FOR (tree, initExpr),
3383 AST_FOR (tree, condExpr),
3384 AST_FOR (tree, loopExpr),
3388 TTYPE (tree) = TETYPE (tree) = NULL;
3392 /* some error found this tree will be killed */
3394 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3395 tree->opval.op = NULLOP;
3401 /*-----------------------------------------------------------------*/
3402 /* sizeofOp - processes size of operation */
3403 /*-----------------------------------------------------------------*/
3405 sizeofOp (sym_link * type)
3409 /* make sure the type is complete and sane */
3410 checkTypeSanity(type, "(sizeof)");
3412 /* get the size and convert it to character */
3413 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3415 /* now convert into value */
3416 return constVal (buff);
3420 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3421 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3422 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3423 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3424 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3425 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3426 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3428 /*-----------------------------------------------------------------*/
3429 /* backPatchLabels - change and or not operators to flow control */
3430 /*-----------------------------------------------------------------*/
3432 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3438 if (!(IS_ANDORNOT (tree)))
3441 /* if this an and */
3444 static int localLbl = 0;
3447 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3448 localLabel = newSymbol (buffer, NestLevel);
3450 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3452 /* if left is already a IFX then just change the if true label in that */
3453 if (!IS_IFX (tree->left))
3454 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3456 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3457 /* right is a IFX then just join */
3458 if (IS_IFX (tree->right))
3459 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3461 tree->right = createLabel (localLabel, tree->right);
3462 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3464 return newNode (NULLOP, tree->left, tree->right);
3467 /* if this is an or operation */
3470 static int localLbl = 0;
3473 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3474 localLabel = newSymbol (buffer, NestLevel);
3476 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3478 /* if left is already a IFX then just change the if true label in that */
3479 if (!IS_IFX (tree->left))
3480 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3482 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3483 /* right is a IFX then just join */
3484 if (IS_IFX (tree->right))
3485 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3487 tree->right = createLabel (localLabel, tree->right);
3488 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3490 return newNode (NULLOP, tree->left, tree->right);
3496 int wasnot = IS_NOT (tree->left);
3497 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3499 /* if the left is already a IFX */
3500 if (!IS_IFX (tree->left))
3501 tree->left = newNode (IFX, tree->left, NULL);
3505 tree->left->trueLabel = trueLabel;
3506 tree->left->falseLabel = falseLabel;
3510 tree->left->trueLabel = falseLabel;
3511 tree->left->falseLabel = trueLabel;
3518 tree->trueLabel = trueLabel;
3519 tree->falseLabel = falseLabel;
3526 /*-----------------------------------------------------------------*/
3527 /* createBlock - create expression tree for block */
3528 /*-----------------------------------------------------------------*/
3530 createBlock (symbol * decl, ast * body)
3534 /* if the block has nothing */
3538 ex = newNode (BLOCK, NULL, body);
3539 ex->values.sym = decl;
3541 ex->right = ex->right;
3547 /*-----------------------------------------------------------------*/
3548 /* createLabel - creates the expression tree for labels */
3549 /*-----------------------------------------------------------------*/
3551 createLabel (symbol * label, ast * stmnt)
3554 char name[SDCC_NAME_MAX + 1];
3557 /* must create fresh symbol if the symbol name */
3558 /* exists in the symbol table, since there can */
3559 /* be a variable with the same name as the labl */
3560 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3561 (csym->level == label->level))
3562 label = newSymbol (label->name, label->level);
3564 /* change the name before putting it in add _ */
3565 SNPRINTF(name, sizeof(name), "%s", label->name);
3567 /* put the label in the LabelSymbol table */
3568 /* but first check if a label of the same */
3570 if ((csym = findSym (LabelTab, NULL, name)))
3571 werror (E_DUPLICATE_LABEL, label->name);
3573 addSym (LabelTab, label, name, label->level, 0, 0);
3576 label->key = labelKey++;
3577 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3583 /*-----------------------------------------------------------------*/
3584 /* createCase - generates the parsetree for a case statement */
3585 /*-----------------------------------------------------------------*/
3587 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3589 char caseLbl[SDCC_NAME_MAX + 1];
3593 /* if the switch statement does not exist */
3594 /* then case is out of context */
3597 werror (E_CASE_CONTEXT);
3601 caseVal = decorateType (resolveSymbols (caseVal));
3602 /* if not a constant then error */
3603 if (!IS_LITERAL (caseVal->ftype))
3605 werror (E_CASE_CONSTANT);
3609 /* if not a integer than error */
3610 if (!IS_INTEGRAL (caseVal->ftype))
3612 werror (E_CASE_NON_INTEGER);
3616 /* find the end of the switch values chain */
3617 if (!(val = swStat->values.switchVals.swVals))
3618 swStat->values.switchVals.swVals = caseVal->opval.val;
3621 /* also order the cases according to value */
3623 int cVal = (int) floatFromVal (caseVal->opval.val);
3624 while (val && (int) floatFromVal (val) < cVal)
3630 /* if we reached the end then */
3633 pval->next = caseVal->opval.val;
3637 /* we found a value greater than */
3638 /* the current value we must add this */
3639 /* before the value */
3640 caseVal->opval.val->next = val;
3642 /* if this was the first in chain */
3643 if (swStat->values.switchVals.swVals == val)
3644 swStat->values.switchVals.swVals =
3647 pval->next = caseVal->opval.val;
3652 /* create the case label */
3653 SNPRINTF(caseLbl, sizeof(caseLbl),
3655 swStat->values.switchVals.swNum,
3656 (int) floatFromVal (caseVal->opval.val));
3658 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3663 /*-----------------------------------------------------------------*/
3664 /* createDefault - creates the parse tree for the default statement */
3665 /*-----------------------------------------------------------------*/
3667 createDefault (ast * swStat, ast * stmnt)
3669 char defLbl[SDCC_NAME_MAX + 1];
3671 /* if the switch statement does not exist */
3672 /* then case is out of context */
3675 werror (E_CASE_CONTEXT);
3679 /* turn on the default flag */
3680 swStat->values.switchVals.swDefault = 1;
3682 /* create the label */
3683 SNPRINTF (defLbl, sizeof(defLbl),
3684 "_default_%d", swStat->values.switchVals.swNum);
3685 return createLabel (newSymbol (defLbl, 0), stmnt);
3688 /*-----------------------------------------------------------------*/
3689 /* createIf - creates the parsetree for the if statement */
3690 /*-----------------------------------------------------------------*/
3692 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3694 static int Lblnum = 0;
3696 symbol *ifTrue, *ifFalse, *ifEnd;
3698 /* if neither exists */
3699 if (!elseBody && !ifBody) {
3700 // if there are no side effects (i++, j() etc)
3701 if (!hasSEFcalls(condAst)) {
3706 /* create the labels */
3707 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3708 ifFalse = newSymbol (buffer, NestLevel);
3709 /* if no else body then end == false */
3714 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3715 ifEnd = newSymbol (buffer, NestLevel);
3718 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3719 ifTrue = newSymbol (buffer, NestLevel);
3723 /* attach the ifTrue label to the top of it body */
3724 ifBody = createLabel (ifTrue, ifBody);
3725 /* attach a goto end to the ifBody if else is present */
3728 ifBody = newNode (NULLOP, ifBody,
3730 newAst_VALUE (symbolVal (ifEnd)),
3732 /* put the elseLabel on the else body */
3733 elseBody = createLabel (ifFalse, elseBody);
3734 /* out the end at the end of the body */
3735 elseBody = newNode (NULLOP,
3737 createLabel (ifEnd, NULL));
3741 ifBody = newNode (NULLOP, ifBody,
3742 createLabel (ifFalse, NULL));
3744 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3745 if (IS_IFX (condAst))
3748 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3750 return newNode (NULLOP, ifTree,
3751 newNode (NULLOP, ifBody, elseBody));
3755 /*-----------------------------------------------------------------*/
3756 /* createDo - creates parse tree for do */
3759 /* _docontinue_n: */
3760 /* condition_expression +-> trueLabel -> _dobody_n */
3762 /* +-> falseLabel-> _dobreak_n */
3764 /*-----------------------------------------------------------------*/
3766 createDo (symbol * trueLabel, symbol * continueLabel,
3767 symbol * falseLabel, ast * condAst, ast * doBody)
3772 /* if the body does not exist then it is simple */
3775 condAst = backPatchLabels (condAst, continueLabel, NULL);
3776 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3777 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3778 doTree->trueLabel = continueLabel;
3779 doTree->falseLabel = NULL;
3783 /* otherwise we have a body */
3784 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3786 /* attach the body label to the top */
3787 doBody = createLabel (trueLabel, doBody);
3788 /* attach the continue label to end of body */
3789 doBody = newNode (NULLOP, doBody,
3790 createLabel (continueLabel, NULL));
3792 /* now put the break label at the end */
3793 if (IS_IFX (condAst))
3796 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3798 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3800 /* putting it together */
3801 return newNode (NULLOP, doBody, doTree);
3804 /*-----------------------------------------------------------------*/
3805 /* createFor - creates parse tree for 'for' statement */
3808 /* condExpr +-> trueLabel -> _forbody_n */
3810 /* +-> falseLabel-> _forbreak_n */
3813 /* _forcontinue_n: */
3815 /* goto _forcond_n ; */
3817 /*-----------------------------------------------------------------*/
3819 createFor (symbol * trueLabel, symbol * continueLabel,
3820 symbol * falseLabel, symbol * condLabel,
3821 ast * initExpr, ast * condExpr, ast * loopExpr,
3826 /* if loopexpression not present then we can generate it */
3827 /* the same way as a while */
3829 return newNode (NULLOP, initExpr,
3830 createWhile (trueLabel, continueLabel,
3831 falseLabel, condExpr, forBody));
3832 /* vanilla for statement */
3833 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3835 if (condExpr && !IS_IFX (condExpr))
3836 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3839 /* attach condition label to condition */
3840 condExpr = createLabel (condLabel, condExpr);
3842 /* attach body label to body */
3843 forBody = createLabel (trueLabel, forBody);
3845 /* attach continue to forLoop expression & attach */
3846 /* goto the forcond @ and of loopExpression */
3847 loopExpr = createLabel (continueLabel,
3851 newAst_VALUE (symbolVal (condLabel)),
3853 /* now start putting them together */
3854 forTree = newNode (NULLOP, initExpr, condExpr);
3855 forTree = newNode (NULLOP, forTree, forBody);
3856 forTree = newNode (NULLOP, forTree, loopExpr);
3857 /* finally add the break label */
3858 forTree = newNode (NULLOP, forTree,
3859 createLabel (falseLabel, NULL));
3863 /*-----------------------------------------------------------------*/
3864 /* createWhile - creates parse tree for while statement */
3865 /* the while statement will be created as follows */
3867 /* _while_continue_n: */
3868 /* condition_expression +-> trueLabel -> _while_boby_n */
3870 /* +-> falseLabel -> _while_break_n */
3871 /* _while_body_n: */
3873 /* goto _while_continue_n */
3874 /* _while_break_n: */
3875 /*-----------------------------------------------------------------*/
3877 createWhile (symbol * trueLabel, symbol * continueLabel,
3878 symbol * falseLabel, ast * condExpr, ast * whileBody)
3882 /* put the continue label */
3883 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3884 condExpr = createLabel (continueLabel, condExpr);
3885 condExpr->lineno = 0;
3887 /* put the body label in front of the body */
3888 whileBody = createLabel (trueLabel, whileBody);
3889 whileBody->lineno = 0;
3890 /* put a jump to continue at the end of the body */
3891 /* and put break label at the end of the body */
3892 whileBody = newNode (NULLOP,
3895 newAst_VALUE (symbolVal (continueLabel)),
3896 createLabel (falseLabel, NULL)));
3898 /* put it all together */
3899 if (IS_IFX (condExpr))
3900 whileTree = condExpr;
3903 whileTree = newNode (IFX, condExpr, NULL);
3904 /* put the true & false labels in place */
3905 whileTree->trueLabel = trueLabel;
3906 whileTree->falseLabel = falseLabel;
3909 return newNode (NULLOP, whileTree, whileBody);
3912 /*-----------------------------------------------------------------*/
3913 /* optimizeGetHbit - get highest order bit of the expression */
3914 /*-----------------------------------------------------------------*/
3916 optimizeGetHbit (ast * tree)
3919 /* if this is not a bit and */
3920 if (!IS_BITAND (tree))
3923 /* will look for tree of the form
3924 ( expr >> ((sizeof expr) -1) ) & 1 */
3925 if (!IS_AST_LIT_VALUE (tree->right))
3928 if (AST_LIT_VALUE (tree->right) != 1)
3931 if (!IS_RIGHT_OP (tree->left))
3934 if (!IS_AST_LIT_VALUE (tree->left->right))
3937 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3938 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3941 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3945 /*-----------------------------------------------------------------*/
3946 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3947 /*-----------------------------------------------------------------*/
3949 optimizeRRCRLC (ast * root)
3951 /* will look for trees of the form
3952 (?expr << 1) | (?expr >> 7) or
3953 (?expr >> 7) | (?expr << 1) will make that
3954 into a RLC : operation ..
3956 (?expr >> 1) | (?expr << 7) or
3957 (?expr << 7) | (?expr >> 1) will make that
3958 into a RRC operation
3959 note : by 7 I mean (number of bits required to hold the
3961 /* if the root operations is not a | operation the not */
3962 if (!IS_BITOR (root))
3965 /* I have to think of a better way to match patterns this sucks */
3966 /* that aside let start looking for the first case : I use a the
3967 negative check a lot to improve the efficiency */
3968 /* (?expr << 1) | (?expr >> 7) */
3969 if (IS_LEFT_OP (root->left) &&
3970 IS_RIGHT_OP (root->right))
3973 if (!SPEC_USIGN (TETYPE (root->left->left)))
3976 if (!IS_AST_LIT_VALUE (root->left->right) ||
3977 !IS_AST_LIT_VALUE (root->right->right))
3980 /* make sure it is the same expression */
3981 if (!isAstEqual (root->left->left,
3985 if (AST_LIT_VALUE (root->left->right) != 1)
3988 if (AST_LIT_VALUE (root->right->right) !=
3989 (getSize (TTYPE (root->left->left)) * 8 - 1))
3992 /* whew got the first case : create the AST */
3993 return newNode (RLC, root->left->left, NULL);
3997 /* check for second case */
3998 /* (?expr >> 7) | (?expr << 1) */
3999 if (IS_LEFT_OP (root->right) &&
4000 IS_RIGHT_OP (root->left))
4003 if (!SPEC_USIGN (TETYPE (root->left->left)))
4006 if (!IS_AST_LIT_VALUE (root->left->right) ||
4007 !IS_AST_LIT_VALUE (root->right->right))
4010 /* make sure it is the same symbol */
4011 if (!isAstEqual (root->left->left,
4015 if (AST_LIT_VALUE (root->right->right) != 1)
4018 if (AST_LIT_VALUE (root->left->right) !=
4019 (getSize (TTYPE (root->left->left)) * 8 - 1))
4022 /* whew got the first case : create the AST */
4023 return newNode (RLC, root->left->left, NULL);
4028 /* third case for RRC */
4029 /* (?symbol >> 1) | (?symbol << 7) */
4030 if (IS_LEFT_OP (root->right) &&
4031 IS_RIGHT_OP (root->left))
4034 if (!SPEC_USIGN (TETYPE (root->left->left)))
4037 if (!IS_AST_LIT_VALUE (root->left->right) ||
4038 !IS_AST_LIT_VALUE (root->right->right))
4041 /* make sure it is the same symbol */
4042 if (!isAstEqual (root->left->left,
4046 if (AST_LIT_VALUE (root->left->right) != 1)
4049 if (AST_LIT_VALUE (root->right->right) !=
4050 (getSize (TTYPE (root->left->left)) * 8 - 1))
4053 /* whew got the first case : create the AST */
4054 return newNode (RRC, root->left->left, NULL);
4058 /* fourth and last case for now */
4059 /* (?symbol << 7) | (?symbol >> 1) */
4060 if (IS_RIGHT_OP (root->right) &&
4061 IS_LEFT_OP (root->left))
4064 if (!SPEC_USIGN (TETYPE (root->left->left)))
4067 if (!IS_AST_LIT_VALUE (root->left->right) ||
4068 !IS_AST_LIT_VALUE (root->right->right))
4071 /* make sure it is the same symbol */
4072 if (!isAstEqual (root->left->left,
4076 if (AST_LIT_VALUE (root->right->right) != 1)
4079 if (AST_LIT_VALUE (root->left->right) !=
4080 (getSize (TTYPE (root->left->left)) * 8 - 1))
4083 /* whew got the first case : create the AST */
4084 return newNode (RRC, root->left->left, NULL);
4088 /* not found return root */
4092 /*-----------------------------------------------------------------*/
4093 /* optimizeCompare - otimizes compares for bit variables */
4094 /*-----------------------------------------------------------------*/
4096 optimizeCompare (ast * root)
4098 ast *optExpr = NULL;
4101 unsigned int litValue;
4103 /* if nothing then return nothing */
4107 /* if not a compare op then do leaves */
4108 if (!IS_COMPARE_OP (root))
4110 root->left = optimizeCompare (root->left);
4111 root->right = optimizeCompare (root->right);
4115 /* if left & right are the same then depending
4116 of the operation do */
4117 if (isAstEqual (root->left, root->right))
4119 switch (root->opval.op)
4124 optExpr = newAst_VALUE (constVal ("0"));
4129 optExpr = newAst_VALUE (constVal ("1"));
4133 return decorateType (optExpr);
4136 vleft = (root->left->type == EX_VALUE ?
4137 root->left->opval.val : NULL);
4139 vright = (root->right->type == EX_VALUE ?
4140 root->right->opval.val : NULL);
4142 /* if left is a BITVAR in BITSPACE */
4143 /* and right is a LITERAL then opt- */
4144 /* imize else do nothing */
4145 if (vleft && vright &&
4146 IS_BITVAR (vleft->etype) &&
4147 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4148 IS_LITERAL (vright->etype))
4151 /* if right side > 1 then comparison may never succeed */
4152 if ((litValue = (int) floatFromVal (vright)) > 1)
4154 werror (W_BAD_COMPARE);
4160 switch (root->opval.op)
4162 case '>': /* bit value greater than 1 cannot be */
4163 werror (W_BAD_COMPARE);
4167 case '<': /* bit value < 1 means 0 */
4169 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4172 case LE_OP: /* bit value <= 1 means no check */
4173 optExpr = newAst_VALUE (vright);
4176 case GE_OP: /* bit value >= 1 means only check for = */
4178 optExpr = newAst_VALUE (vleft);
4183 { /* literal is zero */
4184 switch (root->opval.op)
4186 case '<': /* bit value < 0 cannot be */
4187 werror (W_BAD_COMPARE);
4191 case '>': /* bit value > 0 means 1 */
4193 optExpr = newAst_VALUE (vleft);
4196 case LE_OP: /* bit value <= 0 means no check */
4197 case GE_OP: /* bit value >= 0 means no check */
4198 werror (W_BAD_COMPARE);
4202 case EQ_OP: /* bit == 0 means ! of bit */
4203 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4207 return decorateType (resolveSymbols (optExpr));
4208 } /* end-of-if of BITVAR */
4213 /*-----------------------------------------------------------------*/
4214 /* addSymToBlock : adds the symbol to the first block we find */
4215 /*-----------------------------------------------------------------*/
4217 addSymToBlock (symbol * sym, ast * tree)
4219 /* reached end of tree or a leaf */
4220 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4224 if (IS_AST_OP (tree) &&
4225 tree->opval.op == BLOCK)
4228 symbol *lsym = copySymbol (sym);
4230 lsym->next = AST_VALUES (tree, sym);
4231 AST_VALUES (tree, sym) = lsym;
4235 addSymToBlock (sym, tree->left);
4236 addSymToBlock (sym, tree->right);
4239 /*-----------------------------------------------------------------*/
4240 /* processRegParms - do processing for register parameters */
4241 /*-----------------------------------------------------------------*/
4243 processRegParms (value * args, ast * body)
4247 if (IS_REGPARM (args->etype))
4248 addSymToBlock (args->sym, body);
4253 /*-----------------------------------------------------------------*/
4254 /* resetParmKey - resets the operandkeys for the symbols */
4255 /*-----------------------------------------------------------------*/
4256 DEFSETFUNC (resetParmKey)
4267 /*-----------------------------------------------------------------*/
4268 /* createFunction - This is the key node that calls the iCode for */
4269 /* generating the code for a function. Note code */
4270 /* is generated function by function, later when */
4271 /* add inter-procedural analysis this will change */
4272 /*-----------------------------------------------------------------*/
4274 createFunction (symbol * name, ast * body)
4280 iCode *piCode = NULL;
4282 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4283 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4285 /* if check function return 0 then some problem */
4286 if (checkFunction (name, NULL) == 0)
4289 /* create a dummy block if none exists */
4291 body = newNode (BLOCK, NULL, NULL);
4295 /* check if the function name already in the symbol table */
4296 if ((csym = findSym (SymbolTab, NULL, name->name)))
4299 /* special case for compiler defined functions
4300 we need to add the name to the publics list : this
4301 actually means we are now compiling the compiler
4305 addSet (&publics, name);
4311 allocVariables (name);
4313 name->lastLine = yylineno;
4316 /* set the stack pointer */
4317 /* PENDING: check this for the mcs51 */
4318 stackPtr = -port->stack.direction * port->stack.call_overhead;
4319 if (IFFUNC_ISISR (name->type))
4320 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4321 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4322 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4324 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4326 fetype = getSpec (name->type); /* get the specifier for the function */
4327 /* if this is a reentrant function then */
4328 if (IFFUNC_ISREENT (name->type))
4331 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4333 /* do processing for parameters that are passed in registers */
4334 processRegParms (FUNC_ARGS(name->type), body);
4336 /* set the stack pointer */
4340 /* allocate & autoinit the block variables */
4341 processBlockVars (body, &stack, ALLOCATE);
4343 /* save the stack information */
4344 if (options.useXstack)
4345 name->xstack = SPEC_STAK (fetype) = stack;
4347 name->stack = SPEC_STAK (fetype) = stack;
4349 /* name needs to be mangled */
4350 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4352 body = resolveSymbols (body); /* resolve the symbols */
4353 body = decorateType (body); /* propagateType & do semantic checks */
4355 ex = newAst_VALUE (symbolVal (name)); /* create name */
4356 ex = newNode (FUNCTION, ex, body);
4357 ex->values.args = FUNC_ARGS(name->type);
4359 if (options.dump_tree) PA(ex);
4362 werror (E_FUNC_NO_CODE, name->name);
4366 /* create the node & generate intermediate code */
4368 codeOutFile = code->oFile;
4369 piCode = iCodeFromAst (ex);
4373 werror (E_FUNC_NO_CODE, name->name);
4377 eBBlockFromiCode (piCode);
4379 /* if there are any statics then do them */
4382 GcurMemmap = statsg;
4383 codeOutFile = statsg->oFile;
4384 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4390 /* dealloc the block variables */
4391 processBlockVars (body, &stack, DEALLOCATE);
4392 /* deallocate paramaters */
4393 deallocParms (FUNC_ARGS(name->type));
4395 if (IFFUNC_ISREENT (name->type))
4398 /* we are done freeup memory & cleanup */
4400 if (port->reset_labelKey) labelKey = 1;
4402 FUNC_HASBODY(name->type) = 1;
4403 addSet (&operKeyReset, name);
4404 applyToSet (operKeyReset, resetParmKey);
4407 cdbStructBlock (1, cdbFile);
4409 cleanUpLevel (LabelTab, 0);
4410 cleanUpBlock (StructTab, 1);
4411 cleanUpBlock (TypedefTab, 1);
4413 xstack->syms = NULL;
4414 istack->syms = NULL;
4419 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4420 /*-----------------------------------------------------------------*/
4421 /* ast_print : prints the ast (for debugging purposes) */
4422 /*-----------------------------------------------------------------*/
4424 void ast_print (ast * tree, FILE *outfile, int indent)
4429 /* can print only decorated trees */
4430 if (!tree->decorated) return;
4432 /* if any child is an error | this one is an error do nothing */
4433 if (tree->isError ||
4434 (tree->left && tree->left->isError) ||
4435 (tree->right && tree->right->isError)) {
4436 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4440 /* print the line */
4441 /* if not block & function */
4442 if (tree->type == EX_OP &&
4443 (tree->opval.op != FUNCTION &&
4444 tree->opval.op != BLOCK &&
4445 tree->opval.op != NULLOP)) {
4448 if (tree->opval.op == FUNCTION) {
4450 value *args=FUNC_ARGS(tree->left->opval.val->type);
4451 fprintf(outfile,"FUNCTION (%s=%p) type (",
4452 tree->left->opval.val->name, tree);
4453 printTypeChain (tree->ftype,outfile);
4454 fprintf(outfile,") args (");
4457 fprintf (outfile, ", ");
4459 printTypeChain (args ? args->type : NULL, outfile);
4461 args= args ? args->next : NULL;
4463 fprintf(outfile,")\n");
4464 ast_print(tree->left,outfile,indent);
4465 ast_print(tree->right,outfile,indent);
4468 if (tree->opval.op == BLOCK) {
4469 symbol *decls = tree->values.sym;
4470 INDENT(indent,outfile);
4471 fprintf(outfile,"{\n");
4473 INDENT(indent+2,outfile);
4474 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4475 decls->name, decls);
4476 printTypeChain(decls->type,outfile);
4477 fprintf(outfile,")\n");
4479 decls = decls->next;
4481 ast_print(tree->right,outfile,indent+2);
4482 INDENT(indent,outfile);
4483 fprintf(outfile,"}\n");
4486 if (tree->opval.op == NULLOP) {
4487 ast_print(tree->left,outfile,indent);
4488 ast_print(tree->right,outfile,indent);
4491 INDENT(indent,outfile);
4493 /*------------------------------------------------------------------*/
4494 /*----------------------------*/
4495 /* leaf has been reached */
4496 /*----------------------------*/
4497 /* if this is of type value */
4498 /* just get the type */
4499 if (tree->type == EX_VALUE) {
4501 if (IS_LITERAL (tree->opval.val->etype)) {
4502 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4503 (int) floatFromVal(tree->opval.val),
4504 (int) floatFromVal(tree->opval.val),
4505 floatFromVal(tree->opval.val));
4506 } else if (tree->opval.val->sym) {
4507 /* if the undefined flag is set then give error message */
4508 if (tree->opval.val->sym->undefined) {
4509 fprintf(outfile,"UNDEFINED SYMBOL ");
4511 fprintf(outfile,"SYMBOL ");
4513 fprintf(outfile,"(%s=%p)",
4514 tree->opval.val->sym->name,tree);
4517 fprintf(outfile," type (");
4518 printTypeChain(tree->ftype,outfile);
4519 fprintf(outfile,")\n");
4521 fprintf(outfile,"\n");
4526 /* if type link for the case of cast */
4527 if (tree->type == EX_LINK) {
4528 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4529 printTypeChain(tree->opval.lnk,outfile);
4530 fprintf(outfile,")\n");
4535 /* depending on type of operator do */
4537 switch (tree->opval.op) {
4538 /*------------------------------------------------------------------*/
4539 /*----------------------------*/
4541 /*----------------------------*/
4543 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+2);
4547 ast_print(tree->right,outfile,indent+2);
4550 /*------------------------------------------------------------------*/
4551 /*----------------------------*/
4553 /*----------------------------*/
4555 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4556 printTypeChain(tree->ftype,outfile);
4557 fprintf(outfile,")\n");
4558 ast_print(tree->left,outfile,indent+2);
4559 ast_print(tree->right,outfile,indent+2);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4564 /* struct/union pointer */
4565 /*----------------------------*/
4567 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4568 printTypeChain(tree->ftype,outfile);
4569 fprintf(outfile,")\n");
4570 ast_print(tree->left,outfile,indent+2);
4571 ast_print(tree->right,outfile,indent+2);
4574 /*------------------------------------------------------------------*/
4575 /*----------------------------*/
4576 /* ++/-- operation */
4577 /*----------------------------*/
4578 case INC_OP: /* incerement operator unary so left only */
4579 fprintf(outfile,"INC_OP (%p) type (",tree);
4580 printTypeChain(tree->ftype,outfile);
4581 fprintf(outfile,")\n");
4582 ast_print(tree->left,outfile,indent+2);
4586 fprintf(outfile,"DEC_OP (%p) type (",tree);
4587 printTypeChain(tree->ftype,outfile);
4588 fprintf(outfile,")\n");
4589 ast_print(tree->left,outfile,indent+2);
4592 /*------------------------------------------------------------------*/
4593 /*----------------------------*/
4595 /*----------------------------*/
4598 fprintf(outfile,"& (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+2);
4602 ast_print(tree->right,outfile,indent+2);
4604 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4605 printTypeChain(tree->ftype,outfile);
4606 fprintf(outfile,")\n");
4607 ast_print(tree->left,outfile,indent+2);
4608 ast_print(tree->right,outfile,indent+2);
4611 /*----------------------------*/
4613 /*----------------------------*/
4615 fprintf(outfile,"OR (%p) type (",tree);
4616 printTypeChain(tree->ftype,outfile);
4617 fprintf(outfile,")\n");
4618 ast_print(tree->left,outfile,indent+2);
4619 ast_print(tree->right,outfile,indent+2);
4621 /*------------------------------------------------------------------*/
4622 /*----------------------------*/
4624 /*----------------------------*/
4626 fprintf(outfile,"XOR (%p) type (",tree);
4627 printTypeChain(tree->ftype,outfile);
4628 fprintf(outfile,")\n");
4629 ast_print(tree->left,outfile,indent+2);
4630 ast_print(tree->right,outfile,indent+2);
4633 /*------------------------------------------------------------------*/
4634 /*----------------------------*/
4636 /*----------------------------*/
4638 fprintf(outfile,"DIV (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+2);
4642 ast_print(tree->right,outfile,indent+2);
4644 /*------------------------------------------------------------------*/
4645 /*----------------------------*/
4647 /*----------------------------*/
4649 fprintf(outfile,"MOD (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->left,outfile,indent+2);
4653 ast_print(tree->right,outfile,indent+2);
4656 /*------------------------------------------------------------------*/
4657 /*----------------------------*/
4658 /* address dereference */
4659 /*----------------------------*/
4660 case '*': /* can be unary : if right is null then unary operation */
4662 fprintf(outfile,"DEREF (%p) type (",tree);
4663 printTypeChain(tree->ftype,outfile);
4664 fprintf(outfile,")\n");
4665 ast_print(tree->left,outfile,indent+2);
4668 /*------------------------------------------------------------------*/
4669 /*----------------------------*/
4670 /* multiplication */
4671 /*----------------------------*/
4672 fprintf(outfile,"MULT (%p) type (",tree);
4673 printTypeChain(tree->ftype,outfile);
4674 fprintf(outfile,")\n");
4675 ast_print(tree->left,outfile,indent+2);
4676 ast_print(tree->right,outfile,indent+2);
4680 /*------------------------------------------------------------------*/
4681 /*----------------------------*/
4682 /* unary '+' operator */
4683 /*----------------------------*/
4687 fprintf(outfile,"UPLUS (%p) type (",tree);
4688 printTypeChain(tree->ftype,outfile);
4689 fprintf(outfile,")\n");
4690 ast_print(tree->left,outfile,indent+2);
4692 /*------------------------------------------------------------------*/
4693 /*----------------------------*/
4695 /*----------------------------*/
4696 fprintf(outfile,"ADD (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+2);
4700 ast_print(tree->right,outfile,indent+2);
4703 /*------------------------------------------------------------------*/
4704 /*----------------------------*/
4706 /*----------------------------*/
4707 case '-': /* can be unary */
4709 fprintf(outfile,"UMINUS (%p) type (",tree);
4710 printTypeChain(tree->ftype,outfile);
4711 fprintf(outfile,")\n");
4712 ast_print(tree->left,outfile,indent+2);
4714 /*------------------------------------------------------------------*/
4715 /*----------------------------*/
4717 /*----------------------------*/
4718 fprintf(outfile,"SUB (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+2);
4722 ast_print(tree->right,outfile,indent+2);
4725 /*------------------------------------------------------------------*/
4726 /*----------------------------*/
4728 /*----------------------------*/
4730 fprintf(outfile,"COMPL (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+2);
4735 /*------------------------------------------------------------------*/
4736 /*----------------------------*/
4738 /*----------------------------*/
4740 fprintf(outfile,"NOT (%p) type (",tree);
4741 printTypeChain(tree->ftype,outfile);
4742 fprintf(outfile,")\n");
4743 ast_print(tree->left,outfile,indent+2);
4745 /*------------------------------------------------------------------*/
4746 /*----------------------------*/
4748 /*----------------------------*/
4750 fprintf(outfile,"RRC (%p) type (",tree);
4751 printTypeChain(tree->ftype,outfile);
4752 fprintf(outfile,")\n");
4753 ast_print(tree->left,outfile,indent+2);
4757 fprintf(outfile,"RLC (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+2);
4763 fprintf(outfile,"GETHBIT (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+2);
4769 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+2);
4773 ast_print(tree->right,outfile,indent+2);
4776 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+2);
4780 ast_print(tree->right,outfile,indent+2);
4782 /*------------------------------------------------------------------*/
4783 /*----------------------------*/
4785 /*----------------------------*/
4786 case CAST: /* change the type */
4787 fprintf(outfile,"CAST (%p) from type (",tree);
4788 printTypeChain(tree->right->ftype,outfile);
4789 fprintf(outfile,") to type (");
4790 printTypeChain(tree->ftype,outfile);
4791 fprintf(outfile,")\n");
4792 ast_print(tree->right,outfile,indent+2);
4796 fprintf(outfile,"ANDAND (%p) type (",tree);
4797 printTypeChain(tree->ftype,outfile);
4798 fprintf(outfile,")\n");
4799 ast_print(tree->left,outfile,indent+2);
4800 ast_print(tree->right,outfile,indent+2);
4803 fprintf(outfile,"OROR (%p) type (",tree);
4804 printTypeChain(tree->ftype,outfile);
4805 fprintf(outfile,")\n");
4806 ast_print(tree->left,outfile,indent+2);
4807 ast_print(tree->right,outfile,indent+2);
4810 /*------------------------------------------------------------------*/
4811 /*----------------------------*/
4812 /* comparison operators */
4813 /*----------------------------*/
4815 fprintf(outfile,"GT(>) (%p) type (",tree);
4816 printTypeChain(tree->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->left,outfile,indent+2);
4819 ast_print(tree->right,outfile,indent+2);
4822 fprintf(outfile,"LT(<) (%p) type (",tree);
4823 printTypeChain(tree->ftype,outfile);
4824 fprintf(outfile,")\n");
4825 ast_print(tree->left,outfile,indent+2);
4826 ast_print(tree->right,outfile,indent+2);
4829 fprintf(outfile,"LE(<=) (%p) type (",tree);
4830 printTypeChain(tree->ftype,outfile);
4831 fprintf(outfile,")\n");
4832 ast_print(tree->left,outfile,indent+2);
4833 ast_print(tree->right,outfile,indent+2);
4836 fprintf(outfile,"GE(>=) (%p) type (",tree);
4837 printTypeChain(tree->ftype,outfile);
4838 fprintf(outfile,")\n");
4839 ast_print(tree->left,outfile,indent+2);
4840 ast_print(tree->right,outfile,indent+2);
4843 fprintf(outfile,"EQ(==) (%p) type (",tree);
4844 printTypeChain(tree->ftype,outfile);
4845 fprintf(outfile,")\n");
4846 ast_print(tree->left,outfile,indent+2);
4847 ast_print(tree->right,outfile,indent+2);
4850 fprintf(outfile,"NE(!=) (%p) type (",tree);
4851 printTypeChain(tree->ftype,outfile);
4852 fprintf(outfile,")\n");
4853 ast_print(tree->left,outfile,indent+2);
4854 ast_print(tree->right,outfile,indent+2);
4855 /*------------------------------------------------------------------*/
4856 /*----------------------------*/
4858 /*----------------------------*/
4859 case SIZEOF: /* evaluate wihout code generation */
4860 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4863 /*------------------------------------------------------------------*/
4864 /*----------------------------*/
4865 /* conditional operator '?' */
4866 /*----------------------------*/
4868 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4869 printTypeChain(tree->ftype,outfile);
4870 fprintf(outfile,")\n");
4871 ast_print(tree->left,outfile,indent+2);
4872 ast_print(tree->right,outfile,indent+2);
4876 fprintf(outfile,"COLON(:) (%p) type (",tree);
4877 printTypeChain(tree->ftype,outfile);
4878 fprintf(outfile,")\n");
4879 ast_print(tree->left,outfile,indent+2);
4880 ast_print(tree->right,outfile,indent+2);
4883 /*------------------------------------------------------------------*/
4884 /*----------------------------*/
4885 /* assignment operators */
4886 /*----------------------------*/
4888 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4889 printTypeChain(tree->ftype,outfile);
4890 fprintf(outfile,")\n");
4891 ast_print(tree->left,outfile,indent+2);
4892 ast_print(tree->right,outfile,indent+2);
4895 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4896 printTypeChain(tree->ftype,outfile);
4897 fprintf(outfile,")\n");
4898 ast_print(tree->left,outfile,indent+2);
4899 ast_print(tree->right,outfile,indent+2);
4902 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4903 printTypeChain(tree->ftype,outfile);
4904 fprintf(outfile,")\n");
4905 ast_print(tree->left,outfile,indent+2);
4906 ast_print(tree->right,outfile,indent+2);
4909 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
4910 printTypeChain(tree->ftype,outfile);
4911 fprintf(outfile,")\n");
4912 ast_print(tree->left,outfile,indent+2);
4913 ast_print(tree->right,outfile,indent+2);
4916 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
4917 printTypeChain(tree->ftype,outfile);
4918 fprintf(outfile,")\n");
4919 ast_print(tree->left,outfile,indent+2);
4920 ast_print(tree->right,outfile,indent+2);
4923 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4924 printTypeChain(tree->ftype,outfile);
4925 fprintf(outfile,")\n");
4926 ast_print(tree->left,outfile,indent+2);
4927 ast_print(tree->right,outfile,indent+2);
4930 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
4931 printTypeChain(tree->ftype,outfile);
4932 fprintf(outfile,")\n");
4933 ast_print(tree->left,outfile,indent+2);
4934 ast_print(tree->right,outfile,indent+2);
4936 /*------------------------------------------------------------------*/
4937 /*----------------------------*/
4939 /*----------------------------*/
4941 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4942 printTypeChain(tree->ftype,outfile);
4943 fprintf(outfile,")\n");
4944 ast_print(tree->left,outfile,indent+2);
4945 ast_print(tree->right,outfile,indent+2);
4947 /*------------------------------------------------------------------*/
4948 /*----------------------------*/
4950 /*----------------------------*/
4952 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4953 printTypeChain(tree->ftype,outfile);
4954 fprintf(outfile,")\n");
4955 ast_print(tree->left,outfile,indent+2);
4956 ast_print(tree->right,outfile,indent+2);
4958 /*------------------------------------------------------------------*/
4959 /*----------------------------*/
4960 /* straight assignemnt */
4961 /*----------------------------*/
4963 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4964 printTypeChain(tree->ftype,outfile);
4965 fprintf(outfile,")\n");
4966 ast_print(tree->left,outfile,indent+2);
4967 ast_print(tree->right,outfile,indent+2);
4969 /*------------------------------------------------------------------*/
4970 /*----------------------------*/
4971 /* comma operator */
4972 /*----------------------------*/
4974 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4975 printTypeChain(tree->ftype,outfile);
4976 fprintf(outfile,")\n");
4977 ast_print(tree->left,outfile,indent+2);
4978 ast_print(tree->right,outfile,indent+2);
4980 /*------------------------------------------------------------------*/
4981 /*----------------------------*/
4983 /*----------------------------*/
4986 fprintf(outfile,"CALL (%p) type (",tree);
4987 printTypeChain(tree->ftype,outfile);
4988 fprintf(outfile,")\n");
4989 ast_print(tree->left,outfile,indent+2);
4990 ast_print(tree->right,outfile,indent+2);
4993 fprintf(outfile,"PARMS\n");
4994 ast_print(tree->left,outfile,indent+2);
4995 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4996 ast_print(tree->right,outfile,indent+2);
4999 /*------------------------------------------------------------------*/
5000 /*----------------------------*/
5001 /* return statement */
5002 /*----------------------------*/
5004 fprintf(outfile,"RETURN (%p) type (",tree);
5006 printTypeChain(tree->right->ftype,outfile);
5008 fprintf(outfile,")\n");
5009 ast_print(tree->right,outfile,indent+2);
5011 /*------------------------------------------------------------------*/
5012 /*----------------------------*/
5013 /* label statement */
5014 /*----------------------------*/
5016 fprintf(outfile,"LABEL (%p)\n",tree);
5017 ast_print(tree->left,outfile,indent+2);
5018 ast_print(tree->right,outfile,indent);
5020 /*------------------------------------------------------------------*/
5021 /*----------------------------*/
5022 /* switch statement */
5023 /*----------------------------*/
5027 fprintf(outfile,"SWITCH (%p) ",tree);
5028 ast_print(tree->left,outfile,0);
5029 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5030 INDENT(indent+2,outfile);
5031 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5032 (int) floatFromVal(val),
5033 tree->values.switchVals.swNum,
5034 (int) floatFromVal(val));
5036 ast_print(tree->right,outfile,indent);
5039 /*------------------------------------------------------------------*/
5040 /*----------------------------*/
5042 /*----------------------------*/
5044 fprintf(outfile,"IF (%p) \n",tree);
5045 ast_print(tree->left,outfile,indent+2);
5046 if (tree->trueLabel) {
5047 INDENT(indent+2,outfile);
5048 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5050 if (tree->falseLabel) {
5051 INDENT(indent+2,outfile);
5052 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5054 ast_print(tree->right,outfile,indent+2);
5056 /*----------------------------*/
5057 /* goto Statement */
5058 /*----------------------------*/
5060 fprintf(outfile,"GOTO (%p) \n",tree);
5061 ast_print(tree->left,outfile,indent+2);
5062 fprintf(outfile,"\n");
5064 /*------------------------------------------------------------------*/
5065 /*----------------------------*/
5067 /*----------------------------*/
5069 fprintf(outfile,"FOR (%p) \n",tree);
5070 if (AST_FOR( tree, initExpr)) {
5071 INDENT(indent+2,outfile);
5072 fprintf(outfile,"INIT EXPR ");
5073 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5075 if (AST_FOR( tree, condExpr)) {
5076 INDENT(indent+2,outfile);
5077 fprintf(outfile,"COND EXPR ");
5078 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5080 if (AST_FOR( tree, loopExpr)) {
5081 INDENT(indent+2,outfile);
5082 fprintf(outfile,"LOOP EXPR ");
5083 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5085 fprintf(outfile,"FOR LOOP BODY \n");
5086 ast_print(tree->left,outfile,indent+2);
5095 ast_print(t,stdout,0);