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 ();
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 ();
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 ();
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);
2064 if (IS_PTR(LTYPE(tree))) {
2065 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2069 /*------------------------------------------------------------------*/
2070 /*----------------------------*/
2072 /*----------------------------*/
2074 /* if this is not a structure */
2075 if (!IS_STRUCT (LTYPE (tree)))
2077 werror (E_STRUCT_UNION, ".");
2078 goto errorTreeReturn;
2080 TTYPE (tree) = structElemType (LTYPE (tree),
2081 (tree->right->type == EX_VALUE ?
2082 tree->right->opval.val : NULL));
2083 TETYPE (tree) = getSpec (TTYPE (tree));
2086 /*------------------------------------------------------------------*/
2087 /*----------------------------*/
2088 /* struct/union pointer */
2089 /*----------------------------*/
2091 /* if not pointer to a structure */
2092 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2094 werror (E_PTR_REQD);
2095 goto errorTreeReturn;
2098 if (!IS_STRUCT (LTYPE (tree)->next))
2100 werror (E_STRUCT_UNION, "->");
2101 goto errorTreeReturn;
2104 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2105 (tree->right->type == EX_VALUE ?
2106 tree->right->opval.val : NULL));
2107 TETYPE (tree) = getSpec (TTYPE (tree));
2109 /* adjust the storage class */
2110 switch (DCL_TYPE(tree->left->ftype)) {
2114 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2117 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2122 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2125 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2128 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2138 /*------------------------------------------------------------------*/
2139 /*----------------------------*/
2140 /* ++/-- operation */
2141 /*----------------------------*/
2142 case INC_OP: /* incerement operator unary so left only */
2145 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2146 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2147 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2148 werror (E_CODE_WRITE, "++/--");
2157 /*------------------------------------------------------------------*/
2158 /*----------------------------*/
2160 /*----------------------------*/
2161 case '&': /* can be unary */
2162 /* if right is NULL then unary operation */
2163 if (tree->right) /* not an unary operation */
2166 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2168 werror (E_BITWISE_OP);
2169 werror (W_CONTINUE, "left & right types are ");
2170 printTypeChain (LTYPE (tree), stderr);
2171 fprintf (stderr, ",");
2172 printTypeChain (RTYPE (tree), stderr);
2173 fprintf (stderr, "\n");
2174 goto errorTreeReturn;
2177 /* if they are both literal */
2178 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2180 tree->type = EX_VALUE;
2181 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2182 valFromType (RETYPE (tree)), '&');
2184 tree->right = tree->left = NULL;
2185 TETYPE (tree) = tree->opval.val->etype;
2186 TTYPE (tree) = tree->opval.val->type;
2190 /* see if this is a GETHBIT operation if yes
2193 ast *otree = optimizeGetHbit (tree);
2196 return decorateType (otree);
2200 computeType (LTYPE (tree), RTYPE (tree));
2201 TETYPE (tree) = getSpec (TTYPE (tree));
2203 LRVAL (tree) = RRVAL (tree) = 1;
2207 /*------------------------------------------------------------------*/
2208 /*----------------------------*/
2210 /*----------------------------*/
2212 p->class = DECLARATOR;
2213 /* if bit field then error */
2214 if (IS_BITVAR (tree->left->etype))
2216 werror (E_ILLEGAL_ADDR, "address of bit variable");
2217 goto errorTreeReturn;
2220 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2222 werror (E_ILLEGAL_ADDR, "address of register variable");
2223 goto errorTreeReturn;
2226 if (IS_FUNC (LTYPE (tree)))
2228 // this ought to be ignored
2229 return (tree->left);
2232 if (IS_LITERAL(LTYPE(tree)))
2234 werror (E_ILLEGAL_ADDR, "address of literal");
2235 goto errorTreeReturn;
2240 werror (E_LVALUE_REQUIRED, "address of");
2241 goto errorTreeReturn;
2243 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2245 DCL_TYPE (p) = CPOINTER;
2246 DCL_PTR_CONST (p) = port->mem.code_ro;
2248 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2249 DCL_TYPE (p) = FPOINTER;
2250 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2251 DCL_TYPE (p) = PPOINTER;
2252 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2253 DCL_TYPE (p) = IPOINTER;
2254 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2255 DCL_TYPE (p) = EEPPOINTER;
2256 else if (SPEC_OCLS(tree->left->etype))
2257 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2259 DCL_TYPE (p) = POINTER;
2261 if (IS_AST_SYM_VALUE (tree->left))
2263 AST_SYMBOL (tree->left)->addrtaken = 1;
2264 AST_SYMBOL (tree->left)->allocreq = 1;
2267 p->next = LTYPE (tree);
2269 TETYPE (tree) = getSpec (TTYPE (tree));
2270 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2271 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2276 /*------------------------------------------------------------------*/
2277 /*----------------------------*/
2279 /*----------------------------*/
2281 /* if the rewrite succeeds then don't go any furthur */
2283 ast *wtree = optimizeRRCRLC (tree);
2285 return decorateType (wtree);
2288 /*------------------------------------------------------------------*/
2289 /*----------------------------*/
2291 /*----------------------------*/
2293 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2295 werror (E_BITWISE_OP);
2296 werror (W_CONTINUE, "left & right types are ");
2297 printTypeChain (LTYPE (tree), stderr);
2298 fprintf (stderr, ",");
2299 printTypeChain (RTYPE (tree), stderr);
2300 fprintf (stderr, "\n");
2301 goto errorTreeReturn;
2304 /* if they are both literal then */
2305 /* rewrite the tree */
2306 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2308 tree->type = EX_VALUE;
2309 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2310 valFromType (RETYPE (tree)),
2312 tree->right = tree->left = NULL;
2313 TETYPE (tree) = tree->opval.val->etype;
2314 TTYPE (tree) = tree->opval.val->type;
2317 LRVAL (tree) = RRVAL (tree) = 1;
2318 TETYPE (tree) = getSpec (TTYPE (tree) =
2319 computeType (LTYPE (tree),
2322 /*------------------------------------------------------------------*/
2323 /*----------------------------*/
2325 /*----------------------------*/
2327 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2329 werror (E_INVALID_OP, "divide");
2330 goto errorTreeReturn;
2332 /* if they are both literal then */
2333 /* rewrite the tree */
2334 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2336 tree->type = EX_VALUE;
2337 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2338 valFromType (RETYPE (tree)));
2339 tree->right = tree->left = NULL;
2340 TETYPE (tree) = getSpec (TTYPE (tree) =
2341 tree->opval.val->type);
2344 LRVAL (tree) = RRVAL (tree) = 1;
2345 TETYPE (tree) = getSpec (TTYPE (tree) =
2346 computeType (LTYPE (tree),
2350 /*------------------------------------------------------------------*/
2351 /*----------------------------*/
2353 /*----------------------------*/
2355 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2357 werror (E_BITWISE_OP);
2358 werror (W_CONTINUE, "left & right types are ");
2359 printTypeChain (LTYPE (tree), stderr);
2360 fprintf (stderr, ",");
2361 printTypeChain (RTYPE (tree), stderr);
2362 fprintf (stderr, "\n");
2363 goto errorTreeReturn;
2365 /* if they are both literal then */
2366 /* rewrite the tree */
2367 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2369 tree->type = EX_VALUE;
2370 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2371 valFromType (RETYPE (tree)));
2372 tree->right = tree->left = NULL;
2373 TETYPE (tree) = getSpec (TTYPE (tree) =
2374 tree->opval.val->type);
2377 LRVAL (tree) = RRVAL (tree) = 1;
2378 TETYPE (tree) = getSpec (TTYPE (tree) =
2379 computeType (LTYPE (tree),
2383 /*------------------------------------------------------------------*/
2384 /*----------------------------*/
2385 /* address dereference */
2386 /*----------------------------*/
2387 case '*': /* can be unary : if right is null then unary operation */
2390 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2392 werror (E_PTR_REQD);
2393 goto errorTreeReturn;
2398 werror (E_LVALUE_REQUIRED, "pointer deref");
2399 goto errorTreeReturn;
2401 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2402 LTYPE (tree)->next : NULL);
2403 TETYPE (tree) = getSpec (TTYPE (tree));
2404 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2408 /*------------------------------------------------------------------*/
2409 /*----------------------------*/
2410 /* multiplication */
2411 /*----------------------------*/
2412 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2414 werror (E_INVALID_OP, "multiplication");
2415 goto errorTreeReturn;
2418 /* if they are both literal then */
2419 /* rewrite the tree */
2420 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2422 tree->type = EX_VALUE;
2423 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2424 valFromType (RETYPE (tree)));
2425 tree->right = tree->left = NULL;
2426 TETYPE (tree) = getSpec (TTYPE (tree) =
2427 tree->opval.val->type);
2431 /* if left is a literal exchange left & right */
2432 if (IS_LITERAL (LTYPE (tree)))
2434 ast *tTree = tree->left;
2435 tree->left = tree->right;
2436 tree->right = tTree;
2439 LRVAL (tree) = RRVAL (tree) = 1;
2440 TETYPE (tree) = getSpec (TTYPE (tree) =
2441 computeType (LTYPE (tree),
2444 /* promote result to int if left & right are char
2445 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2446 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2447 SPEC_NOUN(TETYPE(tree)) = V_INT;
2452 /*------------------------------------------------------------------*/
2453 /*----------------------------*/
2454 /* unary '+' operator */
2455 /*----------------------------*/
2460 if (!IS_INTEGRAL (LTYPE (tree)))
2462 werror (E_UNARY_OP, '+');
2463 goto errorTreeReturn;
2466 /* if left is a literal then do it */
2467 if (IS_LITERAL (LTYPE (tree)))
2469 tree->type = EX_VALUE;
2470 tree->opval.val = valFromType (LETYPE (tree));
2472 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2476 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2480 /*------------------------------------------------------------------*/
2481 /*----------------------------*/
2483 /*----------------------------*/
2485 /* this is not a unary operation */
2486 /* if both pointers then problem */
2487 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2488 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2490 werror (E_PTR_PLUS_PTR);
2491 goto errorTreeReturn;
2494 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2495 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2497 werror (E_PLUS_INVALID, "+");
2498 goto errorTreeReturn;
2501 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2502 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2504 werror (E_PLUS_INVALID, "+");
2505 goto errorTreeReturn;
2507 /* if they are both literal then */
2508 /* rewrite the tree */
2509 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2511 tree->type = EX_VALUE;
2512 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2513 valFromType (RETYPE (tree)));
2514 tree->right = tree->left = NULL;
2515 TETYPE (tree) = getSpec (TTYPE (tree) =
2516 tree->opval.val->type);
2520 /* if the right is a pointer or left is a literal
2521 xchange left & right */
2522 if (IS_ARRAY (RTYPE (tree)) ||
2523 IS_PTR (RTYPE (tree)) ||
2524 IS_LITERAL (LTYPE (tree)))
2526 ast *tTree = tree->left;
2527 tree->left = tree->right;
2528 tree->right = tTree;
2531 LRVAL (tree) = RRVAL (tree) = 1;
2532 /* if the left is a pointer */
2533 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2534 TETYPE (tree) = getSpec (TTYPE (tree) =
2537 TETYPE (tree) = getSpec (TTYPE (tree) =
2538 computeType (LTYPE (tree),
2542 /*------------------------------------------------------------------*/
2543 /*----------------------------*/
2545 /*----------------------------*/
2546 case '-': /* can be unary */
2547 /* if right is null then unary */
2551 if (!IS_ARITHMETIC (LTYPE (tree)))
2553 werror (E_UNARY_OP, tree->opval.op);
2554 goto errorTreeReturn;
2557 /* if left is a literal then do it */
2558 if (IS_LITERAL (LTYPE (tree)))
2560 tree->type = EX_VALUE;
2561 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2563 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2564 SPEC_USIGN(TETYPE(tree)) = 0;
2568 TTYPE (tree) = LTYPE (tree);
2572 /*------------------------------------------------------------------*/
2573 /*----------------------------*/
2575 /*----------------------------*/
2577 if (!(IS_PTR (LTYPE (tree)) ||
2578 IS_ARRAY (LTYPE (tree)) ||
2579 IS_ARITHMETIC (LTYPE (tree))))
2581 werror (E_PLUS_INVALID, "-");
2582 goto errorTreeReturn;
2585 if (!(IS_PTR (RTYPE (tree)) ||
2586 IS_ARRAY (RTYPE (tree)) ||
2587 IS_ARITHMETIC (RTYPE (tree))))
2589 werror (E_PLUS_INVALID, "-");
2590 goto errorTreeReturn;
2593 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2594 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2595 IS_INTEGRAL (RTYPE (tree))))
2597 werror (E_PLUS_INVALID, "-");
2598 goto errorTreeReturn;
2601 /* if they are both literal then */
2602 /* rewrite the tree */
2603 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2605 tree->type = EX_VALUE;
2606 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2607 valFromType (RETYPE (tree)));
2608 tree->right = tree->left = NULL;
2609 TETYPE (tree) = getSpec (TTYPE (tree) =
2610 tree->opval.val->type);
2614 /* if the left & right are equal then zero */
2615 if (isAstEqual (tree->left, tree->right))
2617 tree->type = EX_VALUE;
2618 tree->left = tree->right = NULL;
2619 tree->opval.val = constVal ("0");
2620 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2624 /* if both of them are pointers or arrays then */
2625 /* the result is going to be an integer */
2626 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2627 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2628 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2630 /* if only the left is a pointer */
2631 /* then result is a pointer */
2632 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2633 TETYPE (tree) = getSpec (TTYPE (tree) =
2636 TETYPE (tree) = getSpec (TTYPE (tree) =
2637 computeType (LTYPE (tree),
2639 LRVAL (tree) = RRVAL (tree) = 1;
2642 /*------------------------------------------------------------------*/
2643 /*----------------------------*/
2645 /*----------------------------*/
2647 /* can be only integral type */
2648 if (!IS_INTEGRAL (LTYPE (tree)))
2650 werror (E_UNARY_OP, tree->opval.op);
2651 goto errorTreeReturn;
2654 /* if left is a literal then do it */
2655 if (IS_LITERAL (LTYPE (tree)))
2657 tree->type = EX_VALUE;
2658 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2660 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2664 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2667 /*------------------------------------------------------------------*/
2668 /*----------------------------*/
2670 /*----------------------------*/
2672 /* can be pointer */
2673 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2674 !IS_PTR (LTYPE (tree)) &&
2675 !IS_ARRAY (LTYPE (tree)))
2677 werror (E_UNARY_OP, tree->opval.op);
2678 goto errorTreeReturn;
2681 /* if left is a literal then do it */
2682 if (IS_LITERAL (LTYPE (tree)))
2684 tree->type = EX_VALUE;
2685 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2687 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2691 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2694 /*------------------------------------------------------------------*/
2695 /*----------------------------*/
2697 /*----------------------------*/
2700 TTYPE (tree) = LTYPE (tree);
2701 TETYPE (tree) = LETYPE (tree);
2705 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2710 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2712 werror (E_SHIFT_OP_INVALID);
2713 werror (W_CONTINUE, "left & right types are ");
2714 printTypeChain (LTYPE (tree), stderr);
2715 fprintf (stderr, ",");
2716 printTypeChain (RTYPE (tree), stderr);
2717 fprintf (stderr, "\n");
2718 goto errorTreeReturn;
2721 /* if they are both literal then */
2722 /* rewrite the tree */
2723 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2725 tree->type = EX_VALUE;
2726 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2727 valFromType (RETYPE (tree)),
2728 (tree->opval.op == LEFT_OP ? 1 : 0));
2729 tree->right = tree->left = NULL;
2730 TETYPE (tree) = getSpec (TTYPE (tree) =
2731 tree->opval.val->type);
2735 /* if only the right side is a literal & we are
2736 shifting more than size of the left operand then zero */
2737 if (IS_LITERAL (RTYPE (tree)) &&
2738 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2739 (getSize (LTYPE (tree)) * 8))
2741 if (tree->opval.op==LEFT_OP ||
2742 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2743 lineno=tree->lineno;
2744 werror (W_SHIFT_CHANGED,
2745 (tree->opval.op == LEFT_OP ? "left" : "right"));
2746 tree->type = EX_VALUE;
2747 tree->left = tree->right = NULL;
2748 tree->opval.val = constVal ("0");
2749 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2753 LRVAL (tree) = RRVAL (tree) = 1;
2754 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2756 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2760 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2764 /*------------------------------------------------------------------*/
2765 /*----------------------------*/
2767 /*----------------------------*/
2768 case CAST: /* change the type */
2769 /* cannot cast to an aggregate type */
2770 if (IS_AGGREGATE (LTYPE (tree)))
2772 werror (E_CAST_ILLEGAL);
2773 goto errorTreeReturn;
2776 /* make sure the type is complete and sane */
2777 checkTypeSanity(LETYPE(tree), "(cast)");
2780 /* if the right is a literal replace the tree */
2781 if (IS_LITERAL (RETYPE (tree))) {
2782 if (!IS_PTR (LTYPE (tree))) {
2783 tree->type = EX_VALUE;
2785 valCastLiteral (LTYPE (tree),
2786 floatFromVal (valFromType (RETYPE (tree))));
2789 TTYPE (tree) = tree->opval.val->type;
2790 tree->values.literalFromCast = 1;
2791 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2792 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2793 sym_link *rest = LTYPE(tree)->next;
2794 werror(W_LITERAL_GENERIC);
2795 TTYPE(tree) = newLink();
2796 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2797 TTYPE(tree)->next = rest;
2798 tree->left->opval.lnk = TTYPE(tree);
2801 TTYPE (tree) = LTYPE (tree);
2805 TTYPE (tree) = LTYPE (tree);
2809 #if 0 // this is already checked, now this could be explicit
2810 /* if pointer to struct then check names */
2811 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2812 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2813 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2815 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2816 SPEC_STRUCT(LETYPE(tree))->tag);
2819 /* if the right is a literal replace the tree */
2820 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2821 tree->type = EX_VALUE;
2823 valCastLiteral (LTYPE (tree),
2824 floatFromVal (valFromType (RETYPE (tree))));
2827 TTYPE (tree) = tree->opval.val->type;
2828 tree->values.literalFromCast = 1;
2830 TTYPE (tree) = LTYPE (tree);
2834 TETYPE (tree) = getSpec (TTYPE (tree));
2838 /*------------------------------------------------------------------*/
2839 /*----------------------------*/
2840 /* logical &&, || */
2841 /*----------------------------*/
2844 /* each must me arithmetic type or be a pointer */
2845 if (!IS_PTR (LTYPE (tree)) &&
2846 !IS_ARRAY (LTYPE (tree)) &&
2847 !IS_INTEGRAL (LTYPE (tree)))
2849 werror (E_COMPARE_OP);
2850 goto errorTreeReturn;
2853 if (!IS_PTR (RTYPE (tree)) &&
2854 !IS_ARRAY (RTYPE (tree)) &&
2855 !IS_INTEGRAL (RTYPE (tree)))
2857 werror (E_COMPARE_OP);
2858 goto errorTreeReturn;
2860 /* if they are both literal then */
2861 /* rewrite the tree */
2862 if (IS_LITERAL (RTYPE (tree)) &&
2863 IS_LITERAL (LTYPE (tree)))
2865 tree->type = EX_VALUE;
2866 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2867 valFromType (RETYPE (tree)),
2869 tree->right = tree->left = NULL;
2870 TETYPE (tree) = getSpec (TTYPE (tree) =
2871 tree->opval.val->type);
2874 LRVAL (tree) = RRVAL (tree) = 1;
2875 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2878 /*------------------------------------------------------------------*/
2879 /*----------------------------*/
2880 /* comparison operators */
2881 /*----------------------------*/
2889 ast *lt = optimizeCompare (tree);
2895 /* if they are pointers they must be castable */
2896 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2898 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2900 werror (E_COMPARE_OP);
2901 fprintf (stderr, "comparing type ");
2902 printTypeChain (LTYPE (tree), stderr);
2903 fprintf (stderr, "to type ");
2904 printTypeChain (RTYPE (tree), stderr);
2905 fprintf (stderr, "\n");
2906 goto errorTreeReturn;
2909 /* else they should be promotable to one another */
2912 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2913 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2915 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2917 werror (E_COMPARE_OP);
2918 fprintf (stderr, "comparing type ");
2919 printTypeChain (LTYPE (tree), stderr);
2920 fprintf (stderr, "to type ");
2921 printTypeChain (RTYPE (tree), stderr);
2922 fprintf (stderr, "\n");
2923 goto errorTreeReturn;
2926 /* if unsigned value < 0 then always false */
2927 /* if (unsigned value) > 0 then (unsigned value) */
2928 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2929 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2931 if (tree->opval.op == '<') {
2934 if (tree->opval.op == '>') {
2938 /* if they are both literal then */
2939 /* rewrite the tree */
2940 if (IS_LITERAL (RTYPE (tree)) &&
2941 IS_LITERAL (LTYPE (tree)))
2943 tree->type = EX_VALUE;
2944 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2945 valFromType (RETYPE (tree)),
2947 tree->right = tree->left = NULL;
2948 TETYPE (tree) = getSpec (TTYPE (tree) =
2949 tree->opval.val->type);
2952 LRVAL (tree) = RRVAL (tree) = 1;
2953 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2956 /*------------------------------------------------------------------*/
2957 /*----------------------------*/
2959 /*----------------------------*/
2960 case SIZEOF: /* evaluate wihout code generation */
2961 /* change the type to a integer */
2962 tree->type = EX_VALUE;
2963 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2964 tree->opval.val = constVal (buffer);
2965 tree->right = tree->left = NULL;
2966 TETYPE (tree) = getSpec (TTYPE (tree) =
2967 tree->opval.val->type);
2970 /*------------------------------------------------------------------*/
2971 /*----------------------------*/
2973 /*----------------------------*/
2975 /* return typeof enum value */
2976 tree->type = EX_VALUE;
2979 if (IS_SPEC(tree->right->ftype)) {
2980 switch (SPEC_NOUN(tree->right->ftype)) {
2982 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2983 else typeofv = TYPEOF_INT;
2986 typeofv = TYPEOF_FLOAT;
2989 typeofv = TYPEOF_CHAR;
2992 typeofv = TYPEOF_VOID;
2995 typeofv = TYPEOF_STRUCT;
2998 typeofv = TYPEOF_BIT;
3001 typeofv = TYPEOF_SBIT;
3007 switch (DCL_TYPE(tree->right->ftype)) {
3009 typeofv = TYPEOF_POINTER;
3012 typeofv = TYPEOF_FPOINTER;
3015 typeofv = TYPEOF_CPOINTER;
3018 typeofv = TYPEOF_GPOINTER;
3021 typeofv = TYPEOF_PPOINTER;
3024 typeofv = TYPEOF_IPOINTER;
3027 typeofv = TYPEOF_ARRAY;
3030 typeofv = TYPEOF_FUNCTION;
3036 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3037 tree->opval.val = constVal (buffer);
3038 tree->right = tree->left = NULL;
3039 TETYPE (tree) = getSpec (TTYPE (tree) =
3040 tree->opval.val->type);
3043 /*------------------------------------------------------------------*/
3044 /*----------------------------*/
3045 /* conditional operator '?' */
3046 /*----------------------------*/
3048 /* the type is value of the colon operator (on the right) */
3049 assert(IS_COLON_OP(tree->right));
3050 /* if already known then replace the tree : optimizer will do it
3051 but faster to do it here */
3052 if (IS_LITERAL (LTYPE(tree))) {
3053 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3054 return decorateType(tree->right->left) ;
3056 return decorateType(tree->right->right) ;
3059 tree->right = decorateType(tree->right);
3060 TTYPE (tree) = RTYPE(tree);
3061 TETYPE (tree) = getSpec (TTYPE (tree));
3066 /* if they don't match we have a problem */
3067 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3069 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3070 goto errorTreeReturn;
3073 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3074 TETYPE (tree) = getSpec (TTYPE (tree));
3078 #if 0 // assignment operators are converted by the parser
3079 /*------------------------------------------------------------------*/
3080 /*----------------------------*/
3081 /* assignment operators */
3082 /*----------------------------*/
3085 /* for these it must be both must be integral */
3086 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3087 !IS_ARITHMETIC (RTYPE (tree)))
3089 werror (E_OPS_INTEGRAL);
3090 goto errorTreeReturn;
3093 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3095 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3096 werror (E_CODE_WRITE, " ");
3100 werror (E_LVALUE_REQUIRED, "*= or /=");
3101 goto errorTreeReturn;
3112 /* for these it must be both must be integral */
3113 if (!IS_INTEGRAL (LTYPE (tree)) ||
3114 !IS_INTEGRAL (RTYPE (tree)))
3116 werror (E_OPS_INTEGRAL);
3117 goto errorTreeReturn;
3120 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3122 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3123 werror (E_CODE_WRITE, " ");
3127 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3128 goto errorTreeReturn;
3134 /*------------------------------------------------------------------*/
3135 /*----------------------------*/
3137 /*----------------------------*/
3139 if (!(IS_PTR (LTYPE (tree)) ||
3140 IS_ARITHMETIC (LTYPE (tree))))
3142 werror (E_PLUS_INVALID, "-=");
3143 goto errorTreeReturn;
3146 if (!(IS_PTR (RTYPE (tree)) ||
3147 IS_ARITHMETIC (RTYPE (tree))))
3149 werror (E_PLUS_INVALID, "-=");
3150 goto errorTreeReturn;
3153 TETYPE (tree) = getSpec (TTYPE (tree) =
3154 computeType (LTYPE (tree),
3157 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3158 werror (E_CODE_WRITE, " ");
3162 werror (E_LVALUE_REQUIRED, "-=");
3163 goto errorTreeReturn;
3169 /*------------------------------------------------------------------*/
3170 /*----------------------------*/
3172 /*----------------------------*/
3174 /* this is not a unary operation */
3175 /* if both pointers then problem */
3176 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3178 werror (E_PTR_PLUS_PTR);
3179 goto errorTreeReturn;
3182 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3184 werror (E_PLUS_INVALID, "+=");
3185 goto errorTreeReturn;
3188 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3190 werror (E_PLUS_INVALID, "+=");
3191 goto errorTreeReturn;
3194 TETYPE (tree) = getSpec (TTYPE (tree) =
3195 computeType (LTYPE (tree),
3198 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3199 werror (E_CODE_WRITE, " ");
3203 werror (E_LVALUE_REQUIRED, "+=");
3204 goto errorTreeReturn;
3207 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3208 tree->opval.op = '=';
3213 /*------------------------------------------------------------------*/
3214 /*----------------------------*/
3215 /* straight assignemnt */
3216 /*----------------------------*/
3218 /* cannot be an aggregate */
3219 if (IS_AGGREGATE (LTYPE (tree)))
3221 werror (E_AGGR_ASSIGN);
3222 goto errorTreeReturn;
3225 /* they should either match or be castable */
3226 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3228 werror (E_TYPE_MISMATCH, "assignment", " ");
3229 printFromToType(RTYPE(tree),LTYPE(tree));
3230 //goto errorTreeReturn;
3233 /* if the left side of the tree is of type void
3234 then report error */
3235 if (IS_VOID (LTYPE (tree)))
3237 werror (E_CAST_ZERO);
3238 printFromToType(RTYPE(tree), LTYPE(tree));
3241 TETYPE (tree) = getSpec (TTYPE (tree) =
3245 if (!tree->initMode ) {
3246 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3247 werror (E_CODE_WRITE, " ");
3251 werror (E_LVALUE_REQUIRED, "=");
3252 goto errorTreeReturn;
3257 /*------------------------------------------------------------------*/
3258 /*----------------------------*/
3259 /* comma operator */
3260 /*----------------------------*/
3262 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3265 /*------------------------------------------------------------------*/
3266 /*----------------------------*/
3268 /*----------------------------*/
3272 if (processParms (tree->left,
3273 FUNC_ARGS(tree->left->ftype),
3274 tree->right, &parmNumber, TRUE)) {
3275 goto errorTreeReturn;
3278 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3279 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3281 //FUNC_ARGS(tree->left->ftype) =
3282 //reverseVal (FUNC_ARGS(tree->left->ftype));
3283 reverseParms (tree->right);
3286 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3289 /*------------------------------------------------------------------*/
3290 /*----------------------------*/
3291 /* return statement */
3292 /*----------------------------*/
3297 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3299 werror (W_RETURN_MISMATCH);
3300 printFromToType (RTYPE(tree), currFunc->type->next);
3301 goto errorTreeReturn;
3304 if (IS_VOID (currFunc->type->next)
3306 !IS_VOID (RTYPE (tree)))
3308 werror (E_FUNC_VOID);
3309 goto errorTreeReturn;
3312 /* if there is going to be a casing required then add it */
3313 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3316 decorateType (newNode (CAST,
3317 newAst_LINK (copyLinkChain (currFunc->type->next)),
3326 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3328 werror (E_VOID_FUNC, currFunc->name);
3329 goto errorTreeReturn;
3332 TTYPE (tree) = TETYPE (tree) = NULL;
3335 /*------------------------------------------------------------------*/
3336 /*----------------------------*/
3337 /* switch statement */
3338 /*----------------------------*/
3340 /* the switch value must be an integer */
3341 if (!IS_INTEGRAL (LTYPE (tree)))
3343 werror (E_SWITCH_NON_INTEGER);
3344 goto errorTreeReturn;
3347 TTYPE (tree) = TETYPE (tree) = NULL;
3350 /*------------------------------------------------------------------*/
3351 /*----------------------------*/
3353 /*----------------------------*/
3355 tree->left = backPatchLabels (tree->left,
3358 TTYPE (tree) = TETYPE (tree) = NULL;
3361 /*------------------------------------------------------------------*/
3362 /*----------------------------*/
3364 /*----------------------------*/
3367 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3368 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3369 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3371 /* if the for loop is reversible then
3372 reverse it otherwise do what we normally
3378 if (isLoopReversible (tree, &sym, &init, &end))
3379 return reverseLoop (tree, sym, init, end);
3381 return decorateType (createFor (AST_FOR (tree, trueLabel),
3382 AST_FOR (tree, continueLabel),
3383 AST_FOR (tree, falseLabel),
3384 AST_FOR (tree, condLabel),
3385 AST_FOR (tree, initExpr),
3386 AST_FOR (tree, condExpr),
3387 AST_FOR (tree, loopExpr),
3391 TTYPE (tree) = TETYPE (tree) = NULL;
3395 /* some error found this tree will be killed */
3397 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3398 tree->opval.op = NULLOP;
3404 /*-----------------------------------------------------------------*/
3405 /* sizeofOp - processes size of operation */
3406 /*-----------------------------------------------------------------*/
3408 sizeofOp (sym_link * type)
3412 /* make sure the type is complete and sane */
3413 checkTypeSanity(type, "(sizeof)");
3415 /* get the size and convert it to character */
3416 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3418 /* now convert into value */
3419 return constVal (buff);
3423 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3424 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3425 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3426 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3427 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3428 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3429 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3431 /*-----------------------------------------------------------------*/
3432 /* backPatchLabels - change and or not operators to flow control */
3433 /*-----------------------------------------------------------------*/
3435 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3441 if (!(IS_ANDORNOT (tree)))
3444 /* if this an and */
3447 static int localLbl = 0;
3450 SNPRINTF(buffer, sizeof(buffer), "_and_%d", localLbl++);
3451 localLabel = newSymbol (buffer, NestLevel);
3453 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3455 /* if left is already a IFX then just change the if true label in that */
3456 if (!IS_IFX (tree->left))
3457 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3459 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3460 /* right is a IFX then just join */
3461 if (IS_IFX (tree->right))
3462 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3464 tree->right = createLabel (localLabel, tree->right);
3465 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3467 return newNode (NULLOP, tree->left, tree->right);
3470 /* if this is an or operation */
3473 static int localLbl = 0;
3476 SNPRINTF(buffer, sizeof(buffer), "_or_%d", localLbl++);
3477 localLabel = newSymbol (buffer, NestLevel);
3479 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3481 /* if left is already a IFX then just change the if true label in that */
3482 if (!IS_IFX (tree->left))
3483 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3485 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3486 /* right is a IFX then just join */
3487 if (IS_IFX (tree->right))
3488 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3490 tree->right = createLabel (localLabel, tree->right);
3491 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3493 return newNode (NULLOP, tree->left, tree->right);
3499 int wasnot = IS_NOT (tree->left);
3500 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3502 /* if the left is already a IFX */
3503 if (!IS_IFX (tree->left))
3504 tree->left = newNode (IFX, tree->left, NULL);
3508 tree->left->trueLabel = trueLabel;
3509 tree->left->falseLabel = falseLabel;
3513 tree->left->trueLabel = falseLabel;
3514 tree->left->falseLabel = trueLabel;
3521 tree->trueLabel = trueLabel;
3522 tree->falseLabel = falseLabel;
3529 /*-----------------------------------------------------------------*/
3530 /* createBlock - create expression tree for block */
3531 /*-----------------------------------------------------------------*/
3533 createBlock (symbol * decl, ast * body)
3537 /* if the block has nothing */
3541 ex = newNode (BLOCK, NULL, body);
3542 ex->values.sym = decl;
3544 ex->right = ex->right;
3550 /*-----------------------------------------------------------------*/
3551 /* createLabel - creates the expression tree for labels */
3552 /*-----------------------------------------------------------------*/
3554 createLabel (symbol * label, ast * stmnt)
3557 char name[SDCC_NAME_MAX + 1];
3560 /* must create fresh symbol if the symbol name */
3561 /* exists in the symbol table, since there can */
3562 /* be a variable with the same name as the labl */
3563 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3564 (csym->level == label->level))
3565 label = newSymbol (label->name, label->level);
3567 /* change the name before putting it in add _ */
3568 SNPRINTF(name, sizeof(name), "%s", label->name);
3570 /* put the label in the LabelSymbol table */
3571 /* but first check if a label of the same */
3573 if ((csym = findSym (LabelTab, NULL, name)))
3574 werror (E_DUPLICATE_LABEL, label->name);
3576 addSym (LabelTab, label, name, label->level, 0, 0);
3579 label->key = labelKey++;
3580 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3586 /*-----------------------------------------------------------------*/
3587 /* createCase - generates the parsetree for a case statement */
3588 /*-----------------------------------------------------------------*/
3590 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3592 char caseLbl[SDCC_NAME_MAX + 1];
3596 /* if the switch statement does not exist */
3597 /* then case is out of context */
3600 werror (E_CASE_CONTEXT);
3604 caseVal = decorateType (resolveSymbols (caseVal));
3605 /* if not a constant then error */
3606 if (!IS_LITERAL (caseVal->ftype))
3608 werror (E_CASE_CONSTANT);
3612 /* if not a integer than error */
3613 if (!IS_INTEGRAL (caseVal->ftype))
3615 werror (E_CASE_NON_INTEGER);
3619 /* find the end of the switch values chain */
3620 if (!(val = swStat->values.switchVals.swVals))
3621 swStat->values.switchVals.swVals = caseVal->opval.val;
3624 /* also order the cases according to value */
3626 int cVal = (int) floatFromVal (caseVal->opval.val);
3627 while (val && (int) floatFromVal (val) < cVal)
3633 /* if we reached the end then */
3636 pval->next = caseVal->opval.val;
3640 /* we found a value greater than */
3641 /* the current value we must add this */
3642 /* before the value */
3643 caseVal->opval.val->next = val;
3645 /* if this was the first in chain */
3646 if (swStat->values.switchVals.swVals == val)
3647 swStat->values.switchVals.swVals =
3650 pval->next = caseVal->opval.val;
3655 /* create the case label */
3656 SNPRINTF(caseLbl, sizeof(caseLbl),
3658 swStat->values.switchVals.swNum,
3659 (int) floatFromVal (caseVal->opval.val));
3661 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3666 /*-----------------------------------------------------------------*/
3667 /* createDefault - creates the parse tree for the default statement */
3668 /*-----------------------------------------------------------------*/
3670 createDefault (ast * swStat, ast * stmnt)
3672 char defLbl[SDCC_NAME_MAX + 1];
3674 /* if the switch statement does not exist */
3675 /* then case is out of context */
3678 werror (E_CASE_CONTEXT);
3682 /* turn on the default flag */
3683 swStat->values.switchVals.swDefault = 1;
3685 /* create the label */
3686 SNPRINTF (defLbl, sizeof(defLbl),
3687 "_default_%d", swStat->values.switchVals.swNum);
3688 return createLabel (newSymbol (defLbl, 0), stmnt);
3691 /*-----------------------------------------------------------------*/
3692 /* createIf - creates the parsetree for the if statement */
3693 /*-----------------------------------------------------------------*/
3695 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3697 static int Lblnum = 0;
3699 symbol *ifTrue, *ifFalse, *ifEnd;
3701 /* if neither exists */
3702 if (!elseBody && !ifBody) {
3703 // if there are no side effects (i++, j() etc)
3704 if (!hasSEFcalls(condAst)) {
3709 /* create the labels */
3710 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3711 ifFalse = newSymbol (buffer, NestLevel);
3712 /* if no else body then end == false */
3717 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3718 ifEnd = newSymbol (buffer, NestLevel);
3721 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3722 ifTrue = newSymbol (buffer, NestLevel);
3726 /* attach the ifTrue label to the top of it body */
3727 ifBody = createLabel (ifTrue, ifBody);
3728 /* attach a goto end to the ifBody if else is present */
3731 ifBody = newNode (NULLOP, ifBody,
3733 newAst_VALUE (symbolVal (ifEnd)),
3735 /* put the elseLabel on the else body */
3736 elseBody = createLabel (ifFalse, elseBody);
3737 /* out the end at the end of the body */
3738 elseBody = newNode (NULLOP,
3740 createLabel (ifEnd, NULL));
3744 ifBody = newNode (NULLOP, ifBody,
3745 createLabel (ifFalse, NULL));
3747 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3748 if (IS_IFX (condAst))
3751 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3753 return newNode (NULLOP, ifTree,
3754 newNode (NULLOP, ifBody, elseBody));
3758 /*-----------------------------------------------------------------*/
3759 /* createDo - creates parse tree for do */
3762 /* _docontinue_n: */
3763 /* condition_expression +-> trueLabel -> _dobody_n */
3765 /* +-> falseLabel-> _dobreak_n */
3767 /*-----------------------------------------------------------------*/
3769 createDo (symbol * trueLabel, symbol * continueLabel,
3770 symbol * falseLabel, ast * condAst, ast * doBody)
3775 /* if the body does not exist then it is simple */
3778 condAst = backPatchLabels (condAst, continueLabel, NULL);
3779 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3780 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3781 doTree->trueLabel = continueLabel;
3782 doTree->falseLabel = NULL;
3786 /* otherwise we have a body */
3787 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3789 /* attach the body label to the top */
3790 doBody = createLabel (trueLabel, doBody);
3791 /* attach the continue label to end of body */
3792 doBody = newNode (NULLOP, doBody,
3793 createLabel (continueLabel, NULL));
3795 /* now put the break label at the end */
3796 if (IS_IFX (condAst))
3799 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3801 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3803 /* putting it together */
3804 return newNode (NULLOP, doBody, doTree);
3807 /*-----------------------------------------------------------------*/
3808 /* createFor - creates parse tree for 'for' statement */
3811 /* condExpr +-> trueLabel -> _forbody_n */
3813 /* +-> falseLabel-> _forbreak_n */
3816 /* _forcontinue_n: */
3818 /* goto _forcond_n ; */
3820 /*-----------------------------------------------------------------*/
3822 createFor (symbol * trueLabel, symbol * continueLabel,
3823 symbol * falseLabel, symbol * condLabel,
3824 ast * initExpr, ast * condExpr, ast * loopExpr,
3829 /* if loopexpression not present then we can generate it */
3830 /* the same way as a while */
3832 return newNode (NULLOP, initExpr,
3833 createWhile (trueLabel, continueLabel,
3834 falseLabel, condExpr, forBody));
3835 /* vanilla for statement */
3836 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3838 if (condExpr && !IS_IFX (condExpr))
3839 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3842 /* attach condition label to condition */
3843 condExpr = createLabel (condLabel, condExpr);
3845 /* attach body label to body */
3846 forBody = createLabel (trueLabel, forBody);
3848 /* attach continue to forLoop expression & attach */
3849 /* goto the forcond @ and of loopExpression */
3850 loopExpr = createLabel (continueLabel,
3854 newAst_VALUE (symbolVal (condLabel)),
3856 /* now start putting them together */
3857 forTree = newNode (NULLOP, initExpr, condExpr);
3858 forTree = newNode (NULLOP, forTree, forBody);
3859 forTree = newNode (NULLOP, forTree, loopExpr);
3860 /* finally add the break label */
3861 forTree = newNode (NULLOP, forTree,
3862 createLabel (falseLabel, NULL));
3866 /*-----------------------------------------------------------------*/
3867 /* createWhile - creates parse tree for while statement */
3868 /* the while statement will be created as follows */
3870 /* _while_continue_n: */
3871 /* condition_expression +-> trueLabel -> _while_boby_n */
3873 /* +-> falseLabel -> _while_break_n */
3874 /* _while_body_n: */
3876 /* goto _while_continue_n */
3877 /* _while_break_n: */
3878 /*-----------------------------------------------------------------*/
3880 createWhile (symbol * trueLabel, symbol * continueLabel,
3881 symbol * falseLabel, ast * condExpr, ast * whileBody)
3885 /* put the continue label */
3886 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3887 condExpr = createLabel (continueLabel, condExpr);
3888 condExpr->lineno = 0;
3890 /* put the body label in front of the body */
3891 whileBody = createLabel (trueLabel, whileBody);
3892 whileBody->lineno = 0;
3893 /* put a jump to continue at the end of the body */
3894 /* and put break label at the end of the body */
3895 whileBody = newNode (NULLOP,
3898 newAst_VALUE (symbolVal (continueLabel)),
3899 createLabel (falseLabel, NULL)));
3901 /* put it all together */
3902 if (IS_IFX (condExpr))
3903 whileTree = condExpr;
3906 whileTree = newNode (IFX, condExpr, NULL);
3907 /* put the true & false labels in place */
3908 whileTree->trueLabel = trueLabel;
3909 whileTree->falseLabel = falseLabel;
3912 return newNode (NULLOP, whileTree, whileBody);
3915 /*-----------------------------------------------------------------*/
3916 /* optimizeGetHbit - get highest order bit of the expression */
3917 /*-----------------------------------------------------------------*/
3919 optimizeGetHbit (ast * tree)
3922 /* if this is not a bit and */
3923 if (!IS_BITAND (tree))
3926 /* will look for tree of the form
3927 ( expr >> ((sizeof expr) -1) ) & 1 */
3928 if (!IS_AST_LIT_VALUE (tree->right))
3931 if (AST_LIT_VALUE (tree->right) != 1)
3934 if (!IS_RIGHT_OP (tree->left))
3937 if (!IS_AST_LIT_VALUE (tree->left->right))
3940 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3941 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3944 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3948 /*-----------------------------------------------------------------*/
3949 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3950 /*-----------------------------------------------------------------*/
3952 optimizeRRCRLC (ast * root)
3954 /* will look for trees of the form
3955 (?expr << 1) | (?expr >> 7) or
3956 (?expr >> 7) | (?expr << 1) will make that
3957 into a RLC : operation ..
3959 (?expr >> 1) | (?expr << 7) or
3960 (?expr << 7) | (?expr >> 1) will make that
3961 into a RRC operation
3962 note : by 7 I mean (number of bits required to hold the
3964 /* if the root operations is not a | operation the not */
3965 if (!IS_BITOR (root))
3968 /* I have to think of a better way to match patterns this sucks */
3969 /* that aside let start looking for the first case : I use a the
3970 negative check a lot to improve the efficiency */
3971 /* (?expr << 1) | (?expr >> 7) */
3972 if (IS_LEFT_OP (root->left) &&
3973 IS_RIGHT_OP (root->right))
3976 if (!SPEC_USIGN (TETYPE (root->left->left)))
3979 if (!IS_AST_LIT_VALUE (root->left->right) ||
3980 !IS_AST_LIT_VALUE (root->right->right))
3983 /* make sure it is the same expression */
3984 if (!isAstEqual (root->left->left,
3988 if (AST_LIT_VALUE (root->left->right) != 1)
3991 if (AST_LIT_VALUE (root->right->right) !=
3992 (getSize (TTYPE (root->left->left)) * 8 - 1))
3995 /* whew got the first case : create the AST */
3996 return newNode (RLC, root->left->left, NULL);
4000 /* check for second case */
4001 /* (?expr >> 7) | (?expr << 1) */
4002 if (IS_LEFT_OP (root->right) &&
4003 IS_RIGHT_OP (root->left))
4006 if (!SPEC_USIGN (TETYPE (root->left->left)))
4009 if (!IS_AST_LIT_VALUE (root->left->right) ||
4010 !IS_AST_LIT_VALUE (root->right->right))
4013 /* make sure it is the same symbol */
4014 if (!isAstEqual (root->left->left,
4018 if (AST_LIT_VALUE (root->right->right) != 1)
4021 if (AST_LIT_VALUE (root->left->right) !=
4022 (getSize (TTYPE (root->left->left)) * 8 - 1))
4025 /* whew got the first case : create the AST */
4026 return newNode (RLC, root->left->left, NULL);
4031 /* third case for RRC */
4032 /* (?symbol >> 1) | (?symbol << 7) */
4033 if (IS_LEFT_OP (root->right) &&
4034 IS_RIGHT_OP (root->left))
4037 if (!SPEC_USIGN (TETYPE (root->left->left)))
4040 if (!IS_AST_LIT_VALUE (root->left->right) ||
4041 !IS_AST_LIT_VALUE (root->right->right))
4044 /* make sure it is the same symbol */
4045 if (!isAstEqual (root->left->left,
4049 if (AST_LIT_VALUE (root->left->right) != 1)
4052 if (AST_LIT_VALUE (root->right->right) !=
4053 (getSize (TTYPE (root->left->left)) * 8 - 1))
4056 /* whew got the first case : create the AST */
4057 return newNode (RRC, root->left->left, NULL);
4061 /* fourth and last case for now */
4062 /* (?symbol << 7) | (?symbol >> 1) */
4063 if (IS_RIGHT_OP (root->right) &&
4064 IS_LEFT_OP (root->left))
4067 if (!SPEC_USIGN (TETYPE (root->left->left)))
4070 if (!IS_AST_LIT_VALUE (root->left->right) ||
4071 !IS_AST_LIT_VALUE (root->right->right))
4074 /* make sure it is the same symbol */
4075 if (!isAstEqual (root->left->left,
4079 if (AST_LIT_VALUE (root->right->right) != 1)
4082 if (AST_LIT_VALUE (root->left->right) !=
4083 (getSize (TTYPE (root->left->left)) * 8 - 1))
4086 /* whew got the first case : create the AST */
4087 return newNode (RRC, root->left->left, NULL);
4091 /* not found return root */
4095 /*-----------------------------------------------------------------*/
4096 /* optimizeCompare - otimizes compares for bit variables */
4097 /*-----------------------------------------------------------------*/
4099 optimizeCompare (ast * root)
4101 ast *optExpr = NULL;
4104 unsigned int litValue;
4106 /* if nothing then return nothing */
4110 /* if not a compare op then do leaves */
4111 if (!IS_COMPARE_OP (root))
4113 root->left = optimizeCompare (root->left);
4114 root->right = optimizeCompare (root->right);
4118 /* if left & right are the same then depending
4119 of the operation do */
4120 if (isAstEqual (root->left, root->right))
4122 switch (root->opval.op)
4127 optExpr = newAst_VALUE (constVal ("0"));
4132 optExpr = newAst_VALUE (constVal ("1"));
4136 return decorateType (optExpr);
4139 vleft = (root->left->type == EX_VALUE ?
4140 root->left->opval.val : NULL);
4142 vright = (root->right->type == EX_VALUE ?
4143 root->right->opval.val : NULL);
4145 /* if left is a BITVAR in BITSPACE */
4146 /* and right is a LITERAL then opt- */
4147 /* imize else do nothing */
4148 if (vleft && vright &&
4149 IS_BITVAR (vleft->etype) &&
4150 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4151 IS_LITERAL (vright->etype))
4154 /* if right side > 1 then comparison may never succeed */
4155 if ((litValue = (int) floatFromVal (vright)) > 1)
4157 werror (W_BAD_COMPARE);
4163 switch (root->opval.op)
4165 case '>': /* bit value greater than 1 cannot be */
4166 werror (W_BAD_COMPARE);
4170 case '<': /* bit value < 1 means 0 */
4172 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4175 case LE_OP: /* bit value <= 1 means no check */
4176 optExpr = newAst_VALUE (vright);
4179 case GE_OP: /* bit value >= 1 means only check for = */
4181 optExpr = newAst_VALUE (vleft);
4186 { /* literal is zero */
4187 switch (root->opval.op)
4189 case '<': /* bit value < 0 cannot be */
4190 werror (W_BAD_COMPARE);
4194 case '>': /* bit value > 0 means 1 */
4196 optExpr = newAst_VALUE (vleft);
4199 case LE_OP: /* bit value <= 0 means no check */
4200 case GE_OP: /* bit value >= 0 means no check */
4201 werror (W_BAD_COMPARE);
4205 case EQ_OP: /* bit == 0 means ! of bit */
4206 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4210 return decorateType (resolveSymbols (optExpr));
4211 } /* end-of-if of BITVAR */
4216 /*-----------------------------------------------------------------*/
4217 /* addSymToBlock : adds the symbol to the first block we find */
4218 /*-----------------------------------------------------------------*/
4220 addSymToBlock (symbol * sym, ast * tree)
4222 /* reached end of tree or a leaf */
4223 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4227 if (IS_AST_OP (tree) &&
4228 tree->opval.op == BLOCK)
4231 symbol *lsym = copySymbol (sym);
4233 lsym->next = AST_VALUES (tree, sym);
4234 AST_VALUES (tree, sym) = lsym;
4238 addSymToBlock (sym, tree->left);
4239 addSymToBlock (sym, tree->right);
4242 /*-----------------------------------------------------------------*/
4243 /* processRegParms - do processing for register parameters */
4244 /*-----------------------------------------------------------------*/
4246 processRegParms (value * args, ast * body)
4250 if (IS_REGPARM (args->etype))
4251 addSymToBlock (args->sym, body);
4256 /*-----------------------------------------------------------------*/
4257 /* resetParmKey - resets the operandkeys for the symbols */
4258 /*-----------------------------------------------------------------*/
4259 DEFSETFUNC (resetParmKey)
4270 /*-----------------------------------------------------------------*/
4271 /* createFunction - This is the key node that calls the iCode for */
4272 /* generating the code for a function. Note code */
4273 /* is generated function by function, later when */
4274 /* add inter-procedural analysis this will change */
4275 /*-----------------------------------------------------------------*/
4277 createFunction (symbol * name, ast * body)
4283 iCode *piCode = NULL;
4285 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4286 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4288 /* if check function return 0 then some problem */
4289 if (checkFunction (name, NULL) == 0)
4292 /* create a dummy block if none exists */
4294 body = newNode (BLOCK, NULL, NULL);
4298 /* check if the function name already in the symbol table */
4299 if ((csym = findSym (SymbolTab, NULL, name->name)))
4302 /* special case for compiler defined functions
4303 we need to add the name to the publics list : this
4304 actually means we are now compiling the compiler
4308 addSet (&publics, name);
4314 allocVariables (name);
4316 name->lastLine = yylineno;
4319 /* set the stack pointer */
4320 /* PENDING: check this for the mcs51 */
4321 stackPtr = -port->stack.direction * port->stack.call_overhead;
4322 if (IFFUNC_ISISR (name->type))
4323 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4324 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4325 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4327 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4329 fetype = getSpec (name->type); /* get the specifier for the function */
4330 /* if this is a reentrant function then */
4331 if (IFFUNC_ISREENT (name->type))
4334 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4336 /* do processing for parameters that are passed in registers */
4337 processRegParms (FUNC_ARGS(name->type), body);
4339 /* set the stack pointer */
4343 /* allocate & autoinit the block variables */
4344 processBlockVars (body, &stack, ALLOCATE);
4346 /* save the stack information */
4347 if (options.useXstack)
4348 name->xstack = SPEC_STAK (fetype) = stack;
4350 name->stack = SPEC_STAK (fetype) = stack;
4352 /* name needs to be mangled */
4353 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4355 body = resolveSymbols (body); /* resolve the symbols */
4356 body = decorateType (body); /* propagateType & do semantic checks */
4358 ex = newAst_VALUE (symbolVal (name)); /* create name */
4359 ex = newNode (FUNCTION, ex, body);
4360 ex->values.args = FUNC_ARGS(name->type);
4362 if (options.dump_tree) PA(ex);
4365 werror (E_FUNC_NO_CODE, name->name);
4369 /* create the node & generate intermediate code */
4371 codeOutFile = code->oFile;
4372 piCode = iCodeFromAst (ex);
4376 werror (E_FUNC_NO_CODE, name->name);
4380 eBBlockFromiCode (piCode);
4382 /* if there are any statics then do them */
4385 GcurMemmap = statsg;
4386 codeOutFile = statsg->oFile;
4387 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4393 /* dealloc the block variables */
4394 processBlockVars (body, &stack, DEALLOCATE);
4395 /* deallocate paramaters */
4396 deallocParms (FUNC_ARGS(name->type));
4398 if (IFFUNC_ISREENT (name->type))
4401 /* we are done freeup memory & cleanup */
4403 if (port->reset_labelKey) labelKey = 1;
4405 FUNC_HASBODY(name->type) = 1;
4406 addSet (&operKeyReset, name);
4407 applyToSet (operKeyReset, resetParmKey);
4410 cdbStructBlock (1, cdbFile);
4412 cleanUpLevel (LabelTab, 0);
4413 cleanUpBlock (StructTab, 1);
4414 cleanUpBlock (TypedefTab, 1);
4416 xstack->syms = NULL;
4417 istack->syms = NULL;
4422 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4423 /*-----------------------------------------------------------------*/
4424 /* ast_print : prints the ast (for debugging purposes) */
4425 /*-----------------------------------------------------------------*/
4427 void ast_print (ast * tree, FILE *outfile, int indent)
4432 /* can print only decorated trees */
4433 if (!tree->decorated) return;
4435 /* if any child is an error | this one is an error do nothing */
4436 if (tree->isError ||
4437 (tree->left && tree->left->isError) ||
4438 (tree->right && tree->right->isError)) {
4439 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4443 /* print the line */
4444 /* if not block & function */
4445 if (tree->type == EX_OP &&
4446 (tree->opval.op != FUNCTION &&
4447 tree->opval.op != BLOCK &&
4448 tree->opval.op != NULLOP)) {
4451 if (tree->opval.op == FUNCTION) {
4453 value *args=FUNC_ARGS(tree->left->opval.val->type);
4454 fprintf(outfile,"FUNCTION (%s=%p) type (",
4455 tree->left->opval.val->name, tree);
4456 printTypeChain (tree->ftype,outfile);
4457 fprintf(outfile,") args (");
4460 fprintf (outfile, ", ");
4462 printTypeChain (args ? args->type : NULL, outfile);
4464 args= args ? args->next : NULL;
4466 fprintf(outfile,")\n");
4467 ast_print(tree->left,outfile,indent);
4468 ast_print(tree->right,outfile,indent);
4471 if (tree->opval.op == BLOCK) {
4472 symbol *decls = tree->values.sym;
4473 INDENT(indent,outfile);
4474 fprintf(outfile,"{\n");
4476 INDENT(indent+2,outfile);
4477 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4478 decls->name, decls);
4479 printTypeChain(decls->type,outfile);
4480 fprintf(outfile,")\n");
4482 decls = decls->next;
4484 ast_print(tree->right,outfile,indent+2);
4485 INDENT(indent,outfile);
4486 fprintf(outfile,"}\n");
4489 if (tree->opval.op == NULLOP) {
4490 fprintf(outfile,"\n");
4491 ast_print(tree->left,outfile,indent);
4492 fprintf(outfile,"\n");
4493 ast_print(tree->right,outfile,indent);
4496 INDENT(indent,outfile);
4498 /*------------------------------------------------------------------*/
4499 /*----------------------------*/
4500 /* leaf has been reached */
4501 /*----------------------------*/
4502 /* if this is of type value */
4503 /* just get the type */
4504 if (tree->type == EX_VALUE) {
4506 if (IS_LITERAL (tree->opval.val->etype)) {
4507 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4508 (int) floatFromVal(tree->opval.val),
4509 (int) floatFromVal(tree->opval.val),
4510 floatFromVal(tree->opval.val));
4511 } else if (tree->opval.val->sym) {
4512 /* if the undefined flag is set then give error message */
4513 if (tree->opval.val->sym->undefined) {
4514 fprintf(outfile,"UNDEFINED SYMBOL ");
4516 fprintf(outfile,"SYMBOL ");
4518 fprintf(outfile,"(%s=%p)",
4519 tree->opval.val->sym->name,tree);
4522 fprintf(outfile," type (");
4523 printTypeChain(tree->ftype,outfile);
4524 fprintf(outfile,")\n");
4526 fprintf(outfile,"\n");
4531 /* if type link for the case of cast */
4532 if (tree->type == EX_LINK) {
4533 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4534 printTypeChain(tree->opval.lnk,outfile);
4535 fprintf(outfile,")\n");
4540 /* depending on type of operator do */
4542 switch (tree->opval.op) {
4543 /*------------------------------------------------------------------*/
4544 /*----------------------------*/
4546 /*----------------------------*/
4548 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+2);
4552 ast_print(tree->right,outfile,indent+2);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4558 /*----------------------------*/
4560 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4561 printTypeChain(tree->ftype,outfile);
4562 fprintf(outfile,")\n");
4563 ast_print(tree->left,outfile,indent+2);
4564 ast_print(tree->right,outfile,indent+2);
4567 /*------------------------------------------------------------------*/
4568 /*----------------------------*/
4569 /* struct/union pointer */
4570 /*----------------------------*/
4572 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4573 printTypeChain(tree->ftype,outfile);
4574 fprintf(outfile,")\n");
4575 ast_print(tree->left,outfile,indent+2);
4576 ast_print(tree->right,outfile,indent+2);
4579 /*------------------------------------------------------------------*/
4580 /*----------------------------*/
4581 /* ++/-- operation */
4582 /*----------------------------*/
4583 case INC_OP: /* incerement operator unary so left only */
4584 fprintf(outfile,"INC_OP (%p) type (",tree);
4585 printTypeChain(tree->ftype,outfile);
4586 fprintf(outfile,")\n");
4587 ast_print(tree->left,outfile,indent+2);
4591 fprintf(outfile,"DEC_OP (%p) type (",tree);
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->left,outfile,indent+2);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4600 /*----------------------------*/
4603 fprintf(outfile,"& (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+2);
4607 ast_print(tree->right,outfile,indent+2);
4609 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+2);
4613 ast_print(tree->right,outfile,indent+2);
4616 /*----------------------------*/
4618 /*----------------------------*/
4620 fprintf(outfile,"OR (%p) type (",tree);
4621 printTypeChain(tree->ftype,outfile);
4622 fprintf(outfile,")\n");
4623 ast_print(tree->left,outfile,indent+2);
4624 ast_print(tree->right,outfile,indent+2);
4626 /*------------------------------------------------------------------*/
4627 /*----------------------------*/
4629 /*----------------------------*/
4631 fprintf(outfile,"XOR (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+2);
4635 ast_print(tree->right,outfile,indent+2);
4638 /*------------------------------------------------------------------*/
4639 /*----------------------------*/
4641 /*----------------------------*/
4643 fprintf(outfile,"DIV (%p) type (",tree);
4644 printTypeChain(tree->ftype,outfile);
4645 fprintf(outfile,")\n");
4646 ast_print(tree->left,outfile,indent+2);
4647 ast_print(tree->right,outfile,indent+2);
4649 /*------------------------------------------------------------------*/
4650 /*----------------------------*/
4652 /*----------------------------*/
4654 fprintf(outfile,"MOD (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+2);
4658 ast_print(tree->right,outfile,indent+2);
4661 /*------------------------------------------------------------------*/
4662 /*----------------------------*/
4663 /* address dereference */
4664 /*----------------------------*/
4665 case '*': /* can be unary : if right is null then unary operation */
4667 fprintf(outfile,"DEREF (%p) type (",tree);
4668 printTypeChain(tree->ftype,outfile);
4669 fprintf(outfile,")\n");
4670 ast_print(tree->left,outfile,indent+2);
4673 /*------------------------------------------------------------------*/
4674 /*----------------------------*/
4675 /* multiplication */
4676 /*----------------------------*/
4677 fprintf(outfile,"MULT (%p) type (",tree);
4678 printTypeChain(tree->ftype,outfile);
4679 fprintf(outfile,")\n");
4680 ast_print(tree->left,outfile,indent+2);
4681 ast_print(tree->right,outfile,indent+2);
4685 /*------------------------------------------------------------------*/
4686 /*----------------------------*/
4687 /* unary '+' operator */
4688 /*----------------------------*/
4692 fprintf(outfile,"UPLUS (%p) type (",tree);
4693 printTypeChain(tree->ftype,outfile);
4694 fprintf(outfile,")\n");
4695 ast_print(tree->left,outfile,indent+2);
4697 /*------------------------------------------------------------------*/
4698 /*----------------------------*/
4700 /*----------------------------*/
4701 fprintf(outfile,"ADD (%p) type (",tree);
4702 printTypeChain(tree->ftype,outfile);
4703 fprintf(outfile,")\n");
4704 ast_print(tree->left,outfile,indent+2);
4705 ast_print(tree->right,outfile,indent+2);
4708 /*------------------------------------------------------------------*/
4709 /*----------------------------*/
4711 /*----------------------------*/
4712 case '-': /* can be unary */
4714 fprintf(outfile,"UMINUS (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+2);
4719 /*------------------------------------------------------------------*/
4720 /*----------------------------*/
4722 /*----------------------------*/
4723 fprintf(outfile,"SUB (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+2);
4727 ast_print(tree->right,outfile,indent+2);
4730 /*------------------------------------------------------------------*/
4731 /*----------------------------*/
4733 /*----------------------------*/
4735 fprintf(outfile,"COMPL (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+2);
4740 /*------------------------------------------------------------------*/
4741 /*----------------------------*/
4743 /*----------------------------*/
4745 fprintf(outfile,"NOT (%p) type (",tree);
4746 printTypeChain(tree->ftype,outfile);
4747 fprintf(outfile,")\n");
4748 ast_print(tree->left,outfile,indent+2);
4750 /*------------------------------------------------------------------*/
4751 /*----------------------------*/
4753 /*----------------------------*/
4755 fprintf(outfile,"RRC (%p) type (",tree);
4756 printTypeChain(tree->ftype,outfile);
4757 fprintf(outfile,")\n");
4758 ast_print(tree->left,outfile,indent+2);
4762 fprintf(outfile,"RLC (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+2);
4768 fprintf(outfile,"GETHBIT (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+2);
4774 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4775 printTypeChain(tree->ftype,outfile);
4776 fprintf(outfile,")\n");
4777 ast_print(tree->left,outfile,indent+2);
4778 ast_print(tree->right,outfile,indent+2);
4781 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4782 printTypeChain(tree->ftype,outfile);
4783 fprintf(outfile,")\n");
4784 ast_print(tree->left,outfile,indent+2);
4785 ast_print(tree->right,outfile,indent+2);
4787 /*------------------------------------------------------------------*/
4788 /*----------------------------*/
4790 /*----------------------------*/
4791 case CAST: /* change the type */
4792 fprintf(outfile,"CAST (%p) from type (",tree);
4793 printTypeChain(tree->right->ftype,outfile);
4794 fprintf(outfile,") to type (");
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->right,outfile,indent+2);
4801 fprintf(outfile,"ANDAND (%p) type (",tree);
4802 printTypeChain(tree->ftype,outfile);
4803 fprintf(outfile,")\n");
4804 ast_print(tree->left,outfile,indent+2);
4805 ast_print(tree->right,outfile,indent+2);
4808 fprintf(outfile,"OROR (%p) type (",tree);
4809 printTypeChain(tree->ftype,outfile);
4810 fprintf(outfile,")\n");
4811 ast_print(tree->left,outfile,indent+2);
4812 ast_print(tree->right,outfile,indent+2);
4815 /*------------------------------------------------------------------*/
4816 /*----------------------------*/
4817 /* comparison operators */
4818 /*----------------------------*/
4820 fprintf(outfile,"GT(>) (%p) type (",tree);
4821 printTypeChain(tree->ftype,outfile);
4822 fprintf(outfile,")\n");
4823 ast_print(tree->left,outfile,indent+2);
4824 ast_print(tree->right,outfile,indent+2);
4827 fprintf(outfile,"LT(<) (%p) type (",tree);
4828 printTypeChain(tree->ftype,outfile);
4829 fprintf(outfile,")\n");
4830 ast_print(tree->left,outfile,indent+2);
4831 ast_print(tree->right,outfile,indent+2);
4834 fprintf(outfile,"LE(<=) (%p) type (",tree);
4835 printTypeChain(tree->ftype,outfile);
4836 fprintf(outfile,")\n");
4837 ast_print(tree->left,outfile,indent+2);
4838 ast_print(tree->right,outfile,indent+2);
4841 fprintf(outfile,"GE(>=) (%p) type (",tree);
4842 printTypeChain(tree->ftype,outfile);
4843 fprintf(outfile,")\n");
4844 ast_print(tree->left,outfile,indent+2);
4845 ast_print(tree->right,outfile,indent+2);
4848 fprintf(outfile,"EQ(==) (%p) type (",tree);
4849 printTypeChain(tree->ftype,outfile);
4850 fprintf(outfile,")\n");
4851 ast_print(tree->left,outfile,indent+2);
4852 ast_print(tree->right,outfile,indent+2);
4855 fprintf(outfile,"NE(!=) (%p) type (",tree);
4856 printTypeChain(tree->ftype,outfile);
4857 fprintf(outfile,")\n");
4858 ast_print(tree->left,outfile,indent+2);
4859 ast_print(tree->right,outfile,indent+2);
4860 /*------------------------------------------------------------------*/
4861 /*----------------------------*/
4863 /*----------------------------*/
4864 case SIZEOF: /* evaluate wihout code generation */
4865 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4868 /*------------------------------------------------------------------*/
4869 /*----------------------------*/
4870 /* conditional operator '?' */
4871 /*----------------------------*/
4873 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4874 printTypeChain(tree->ftype,outfile);
4875 fprintf(outfile,")\n");
4876 ast_print(tree->left,outfile,indent+2);
4877 ast_print(tree->right,outfile,indent+2);
4881 fprintf(outfile,"COLON(:) (%p) type (",tree);
4882 printTypeChain(tree->ftype,outfile);
4883 fprintf(outfile,")\n");
4884 ast_print(tree->left,outfile,indent+2);
4885 ast_print(tree->right,outfile,indent+2);
4888 /*------------------------------------------------------------------*/
4889 /*----------------------------*/
4890 /* assignment operators */
4891 /*----------------------------*/
4893 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4894 printTypeChain(tree->ftype,outfile);
4895 fprintf(outfile,")\n");
4896 ast_print(tree->left,outfile,indent+2);
4897 ast_print(tree->right,outfile,indent+2);
4900 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4901 printTypeChain(tree->ftype,outfile);
4902 fprintf(outfile,")\n");
4903 ast_print(tree->left,outfile,indent+2);
4904 ast_print(tree->right,outfile,indent+2);
4907 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4908 printTypeChain(tree->ftype,outfile);
4909 fprintf(outfile,")\n");
4910 ast_print(tree->left,outfile,indent+2);
4911 ast_print(tree->right,outfile,indent+2);
4914 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4915 printTypeChain(tree->ftype,outfile);
4916 fprintf(outfile,")\n");
4917 ast_print(tree->left,outfile,indent+2);
4918 ast_print(tree->right,outfile,indent+2);
4921 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4922 printTypeChain(tree->ftype,outfile);
4923 fprintf(outfile,")\n");
4924 ast_print(tree->left,outfile,indent+2);
4925 ast_print(tree->right,outfile,indent+2);
4928 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4929 printTypeChain(tree->ftype,outfile);
4930 fprintf(outfile,")\n");
4931 ast_print(tree->left,outfile,indent+2);
4932 ast_print(tree->right,outfile,indent+2);
4935 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4936 printTypeChain(tree->ftype,outfile);
4937 fprintf(outfile,")\n");
4938 ast_print(tree->left,outfile,indent+2);
4939 ast_print(tree->right,outfile,indent+2);
4941 /*------------------------------------------------------------------*/
4942 /*----------------------------*/
4944 /*----------------------------*/
4946 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4947 printTypeChain(tree->ftype,outfile);
4948 fprintf(outfile,")\n");
4949 ast_print(tree->left,outfile,indent+2);
4950 ast_print(tree->right,outfile,indent+2);
4952 /*------------------------------------------------------------------*/
4953 /*----------------------------*/
4955 /*----------------------------*/
4957 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4958 printTypeChain(tree->ftype,outfile);
4959 fprintf(outfile,")\n");
4960 ast_print(tree->left,outfile,indent+2);
4961 ast_print(tree->right,outfile,indent+2);
4963 /*------------------------------------------------------------------*/
4964 /*----------------------------*/
4965 /* straight assignemnt */
4966 /*----------------------------*/
4968 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4969 printTypeChain(tree->ftype,outfile);
4970 fprintf(outfile,")\n");
4971 ast_print(tree->left,outfile,indent+2);
4972 ast_print(tree->right,outfile,indent+2);
4974 /*------------------------------------------------------------------*/
4975 /*----------------------------*/
4976 /* comma operator */
4977 /*----------------------------*/
4979 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4980 printTypeChain(tree->ftype,outfile);
4981 fprintf(outfile,")\n");
4982 ast_print(tree->left,outfile,indent+2);
4983 ast_print(tree->right,outfile,indent+2);
4985 /*------------------------------------------------------------------*/
4986 /*----------------------------*/
4988 /*----------------------------*/
4991 fprintf(outfile,"CALL (%p) type (",tree);
4992 printTypeChain(tree->ftype,outfile);
4993 fprintf(outfile,")\n");
4994 ast_print(tree->left,outfile,indent+2);
4995 ast_print(tree->right,outfile,indent+2);
4998 fprintf(outfile,"PARMS\n");
4999 ast_print(tree->left,outfile,indent+2);
5000 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5001 ast_print(tree->right,outfile,indent+2);
5004 /*------------------------------------------------------------------*/
5005 /*----------------------------*/
5006 /* return statement */
5007 /*----------------------------*/
5009 fprintf(outfile,"RETURN (%p) type (",tree);
5011 printTypeChain(tree->right->ftype,outfile);
5013 fprintf(outfile,")\n");
5014 ast_print(tree->right,outfile,indent+2);
5016 /*------------------------------------------------------------------*/
5017 /*----------------------------*/
5018 /* label statement */
5019 /*----------------------------*/
5021 fprintf(outfile,"LABEL (%p)\n",tree);
5022 ast_print(tree->left,outfile,indent+2);
5023 ast_print(tree->right,outfile,indent);
5025 /*------------------------------------------------------------------*/
5026 /*----------------------------*/
5027 /* switch statement */
5028 /*----------------------------*/
5032 fprintf(outfile,"SWITCH (%p) ",tree);
5033 ast_print(tree->left,outfile,0);
5034 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5035 INDENT(indent+2,outfile);
5036 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5037 (int) floatFromVal(val),
5038 tree->values.switchVals.swNum,
5039 (int) floatFromVal(val));
5041 ast_print(tree->right,outfile,indent);
5044 /*------------------------------------------------------------------*/
5045 /*----------------------------*/
5047 /*----------------------------*/
5049 fprintf(outfile,"IF (%p) \n",tree);
5050 ast_print(tree->left,outfile,indent+2);
5051 if (tree->trueLabel) {
5052 INDENT(indent,outfile);
5053 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5055 if (tree->falseLabel) {
5056 INDENT(indent,outfile);
5057 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5059 ast_print(tree->right,outfile,indent+2);
5061 /*------------------------------------------------------------------*/
5062 /*----------------------------*/
5064 /*----------------------------*/
5066 fprintf(outfile,"FOR (%p) \n",tree);
5067 if (AST_FOR( tree, initExpr)) {
5068 INDENT(indent+2,outfile);
5069 fprintf(outfile,"INIT EXPR ");
5070 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5072 if (AST_FOR( tree, condExpr)) {
5073 INDENT(indent+2,outfile);
5074 fprintf(outfile,"COND EXPR ");
5075 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5077 if (AST_FOR( tree, loopExpr)) {
5078 INDENT(indent+2,outfile);
5079 fprintf(outfile,"LOOP EXPR ");
5080 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5082 fprintf(outfile,"FOR LOOP BODY \n");
5083 ast_print(tree->left,outfile,indent+2);
5092 ast_print(t,stdout,0);