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);
2066 /*------------------------------------------------------------------*/
2067 /*----------------------------*/
2069 /*----------------------------*/
2071 /* if this is not a structure */
2072 if (!IS_STRUCT (LTYPE (tree)))
2074 werror (E_STRUCT_UNION, ".");
2075 goto errorTreeReturn;
2077 TTYPE (tree) = structElemType (LTYPE (tree),
2078 (tree->right->type == EX_VALUE ?
2079 tree->right->opval.val : NULL));
2080 TETYPE (tree) = getSpec (TTYPE (tree));
2083 /*------------------------------------------------------------------*/
2084 /*----------------------------*/
2085 /* struct/union pointer */
2086 /*----------------------------*/
2088 /* if not pointer to a structure */
2089 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2091 werror (E_PTR_REQD);
2092 goto errorTreeReturn;
2095 if (!IS_STRUCT (LTYPE (tree)->next))
2097 werror (E_STRUCT_UNION, "->");
2098 goto errorTreeReturn;
2101 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2102 (tree->right->type == EX_VALUE ?
2103 tree->right->opval.val : NULL));
2104 TETYPE (tree) = getSpec (TTYPE (tree));
2106 /* adjust the storage class */
2107 switch (DCL_TYPE(tree->left->ftype)) {
2111 SPEC_SCLS(TETYPE(tree)) = S_XDATA;
2114 SPEC_SCLS(TETYPE(tree)) = S_CODE;
2119 SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
2122 SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2125 SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2135 /*------------------------------------------------------------------*/
2136 /*----------------------------*/
2137 /* ++/-- operation */
2138 /*----------------------------*/
2139 case INC_OP: /* incerement operator unary so left only */
2142 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2143 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2144 if (!tree->initMode && IS_CONSTANT (TTYPE (tree)))
2145 werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2154 /*------------------------------------------------------------------*/
2155 /*----------------------------*/
2157 /*----------------------------*/
2158 case '&': /* can be unary */
2159 /* if right is NULL then unary operation */
2160 if (tree->right) /* not an unary operation */
2163 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2165 werror (E_BITWISE_OP);
2166 werror (W_CONTINUE, "left & right types are ");
2167 printTypeChain (LTYPE (tree), stderr);
2168 fprintf (stderr, ",");
2169 printTypeChain (RTYPE (tree), stderr);
2170 fprintf (stderr, "\n");
2171 goto errorTreeReturn;
2174 /* if they are both literal */
2175 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2177 tree->type = EX_VALUE;
2178 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2179 valFromType (RETYPE (tree)), '&');
2181 tree->right = tree->left = NULL;
2182 TETYPE (tree) = tree->opval.val->etype;
2183 TTYPE (tree) = tree->opval.val->type;
2187 /* see if this is a GETHBIT operation if yes
2190 ast *otree = optimizeGetHbit (tree);
2193 return decorateType (otree);
2197 computeType (LTYPE (tree), RTYPE (tree));
2198 TETYPE (tree) = getSpec (TTYPE (tree));
2200 LRVAL (tree) = RRVAL (tree) = 1;
2204 /*------------------------------------------------------------------*/
2205 /*----------------------------*/
2207 /*----------------------------*/
2209 p->class = DECLARATOR;
2210 /* if bit field then error */
2211 if (IS_BITVAR (tree->left->etype))
2213 werror (E_ILLEGAL_ADDR, "address of bit variable");
2214 goto errorTreeReturn;
2217 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2219 werror (E_ILLEGAL_ADDR, "address of register variable");
2220 goto errorTreeReturn;
2223 if (IS_FUNC (LTYPE (tree)))
2225 // this ought to be ignored
2226 return (tree->left);
2229 if (IS_LITERAL(LTYPE(tree)))
2231 werror (E_ILLEGAL_ADDR, "address of literal");
2232 goto errorTreeReturn;
2237 werror (E_LVALUE_REQUIRED, "address of");
2238 goto errorTreeReturn;
2240 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2241 DCL_TYPE (p) = CPOINTER;
2242 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2243 DCL_TYPE (p) = FPOINTER;
2244 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2245 DCL_TYPE (p) = PPOINTER;
2246 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2247 DCL_TYPE (p) = IPOINTER;
2248 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2249 DCL_TYPE (p) = EEPPOINTER;
2250 else if (SPEC_OCLS(tree->left->etype))
2251 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2253 DCL_TYPE (p) = POINTER;
2255 if (IS_AST_SYM_VALUE (tree->left))
2257 AST_SYMBOL (tree->left)->addrtaken = 1;
2258 AST_SYMBOL (tree->left)->allocreq = 1;
2261 p->next = LTYPE (tree);
2263 TETYPE (tree) = getSpec (TTYPE (tree));
2268 /*------------------------------------------------------------------*/
2269 /*----------------------------*/
2271 /*----------------------------*/
2273 /* if the rewrite succeeds then don't go any furthur */
2275 ast *wtree = optimizeRRCRLC (tree);
2277 return decorateType (wtree);
2280 /*------------------------------------------------------------------*/
2281 /*----------------------------*/
2283 /*----------------------------*/
2285 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2287 werror (E_BITWISE_OP);
2288 werror (W_CONTINUE, "left & right types are ");
2289 printTypeChain (LTYPE (tree), stderr);
2290 fprintf (stderr, ",");
2291 printTypeChain (RTYPE (tree), stderr);
2292 fprintf (stderr, "\n");
2293 goto errorTreeReturn;
2296 /* if they are both literal then */
2297 /* rewrite the tree */
2298 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2300 tree->type = EX_VALUE;
2301 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2302 valFromType (RETYPE (tree)),
2304 tree->right = tree->left = NULL;
2305 TETYPE (tree) = tree->opval.val->etype;
2306 TTYPE (tree) = tree->opval.val->type;
2309 LRVAL (tree) = RRVAL (tree) = 1;
2310 TETYPE (tree) = getSpec (TTYPE (tree) =
2311 computeType (LTYPE (tree),
2314 /*------------------------------------------------------------------*/
2315 /*----------------------------*/
2317 /*----------------------------*/
2319 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2321 werror (E_INVALID_OP, "divide");
2322 goto errorTreeReturn;
2324 /* if they are both literal then */
2325 /* rewrite the tree */
2326 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2328 tree->type = EX_VALUE;
2329 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2330 valFromType (RETYPE (tree)));
2331 tree->right = tree->left = NULL;
2332 TETYPE (tree) = getSpec (TTYPE (tree) =
2333 tree->opval.val->type);
2336 LRVAL (tree) = RRVAL (tree) = 1;
2337 TETYPE (tree) = getSpec (TTYPE (tree) =
2338 computeType (LTYPE (tree),
2342 /*------------------------------------------------------------------*/
2343 /*----------------------------*/
2345 /*----------------------------*/
2347 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2349 werror (E_BITWISE_OP);
2350 werror (W_CONTINUE, "left & right types are ");
2351 printTypeChain (LTYPE (tree), stderr);
2352 fprintf (stderr, ",");
2353 printTypeChain (RTYPE (tree), stderr);
2354 fprintf (stderr, "\n");
2355 goto errorTreeReturn;
2357 /* if they are both literal then */
2358 /* rewrite the tree */
2359 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2361 tree->type = EX_VALUE;
2362 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2363 valFromType (RETYPE (tree)));
2364 tree->right = tree->left = NULL;
2365 TETYPE (tree) = getSpec (TTYPE (tree) =
2366 tree->opval.val->type);
2369 LRVAL (tree) = RRVAL (tree) = 1;
2370 TETYPE (tree) = getSpec (TTYPE (tree) =
2371 computeType (LTYPE (tree),
2375 /*------------------------------------------------------------------*/
2376 /*----------------------------*/
2377 /* address dereference */
2378 /*----------------------------*/
2379 case '*': /* can be unary : if right is null then unary operation */
2382 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2384 werror (E_PTR_REQD);
2385 goto errorTreeReturn;
2390 werror (E_LVALUE_REQUIRED, "pointer deref");
2391 goto errorTreeReturn;
2393 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2394 LTYPE (tree)->next : NULL);
2395 TETYPE (tree) = getSpec (TTYPE (tree));
2399 /*------------------------------------------------------------------*/
2400 /*----------------------------*/
2401 /* multiplication */
2402 /*----------------------------*/
2403 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2405 werror (E_INVALID_OP, "multiplication");
2406 goto errorTreeReturn;
2409 /* if they are both literal then */
2410 /* rewrite the tree */
2411 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2413 tree->type = EX_VALUE;
2414 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2415 valFromType (RETYPE (tree)));
2416 tree->right = tree->left = NULL;
2417 TETYPE (tree) = getSpec (TTYPE (tree) =
2418 tree->opval.val->type);
2422 /* if left is a literal exchange left & right */
2423 if (IS_LITERAL (LTYPE (tree)))
2425 ast *tTree = tree->left;
2426 tree->left = tree->right;
2427 tree->right = tTree;
2430 LRVAL (tree) = RRVAL (tree) = 1;
2431 TETYPE (tree) = getSpec (TTYPE (tree) =
2432 computeType (LTYPE (tree),
2435 /* promote result to int if left & right are char
2436 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2437 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2438 SPEC_NOUN(TETYPE(tree)) = V_INT;
2443 /*------------------------------------------------------------------*/
2444 /*----------------------------*/
2445 /* unary '+' operator */
2446 /*----------------------------*/
2451 if (!IS_INTEGRAL (LTYPE (tree)))
2453 werror (E_UNARY_OP, '+');
2454 goto errorTreeReturn;
2457 /* if left is a literal then do it */
2458 if (IS_LITERAL (LTYPE (tree)))
2460 tree->type = EX_VALUE;
2461 tree->opval.val = valFromType (LETYPE (tree));
2463 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2467 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2471 /*------------------------------------------------------------------*/
2472 /*----------------------------*/
2474 /*----------------------------*/
2476 /* this is not a unary operation */
2477 /* if both pointers then problem */
2478 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2479 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2481 werror (E_PTR_PLUS_PTR);
2482 goto errorTreeReturn;
2485 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2486 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2488 werror (E_PLUS_INVALID, "+");
2489 goto errorTreeReturn;
2492 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2493 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2495 werror (E_PLUS_INVALID, "+");
2496 goto errorTreeReturn;
2498 /* if they are both literal then */
2499 /* rewrite the tree */
2500 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2502 tree->type = EX_VALUE;
2503 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2504 valFromType (RETYPE (tree)));
2505 tree->right = tree->left = NULL;
2506 TETYPE (tree) = getSpec (TTYPE (tree) =
2507 tree->opval.val->type);
2511 /* if the right is a pointer or left is a literal
2512 xchange left & right */
2513 if (IS_ARRAY (RTYPE (tree)) ||
2514 IS_PTR (RTYPE (tree)) ||
2515 IS_LITERAL (LTYPE (tree)))
2517 ast *tTree = tree->left;
2518 tree->left = tree->right;
2519 tree->right = tTree;
2522 LRVAL (tree) = RRVAL (tree) = 1;
2523 /* if the left is a pointer */
2524 if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2525 TETYPE (tree) = getSpec (TTYPE (tree) =
2528 TETYPE (tree) = getSpec (TTYPE (tree) =
2529 computeType (LTYPE (tree),
2533 /*------------------------------------------------------------------*/
2534 /*----------------------------*/
2536 /*----------------------------*/
2537 case '-': /* can be unary */
2538 /* if right is null then unary */
2542 if (!IS_ARITHMETIC (LTYPE (tree)))
2544 werror (E_UNARY_OP, tree->opval.op);
2545 goto errorTreeReturn;
2548 /* if left is a literal then do it */
2549 if (IS_LITERAL (LTYPE (tree)))
2551 tree->type = EX_VALUE;
2552 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2554 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2555 SPEC_USIGN(TETYPE(tree)) = 0;
2559 TTYPE (tree) = LTYPE (tree);
2563 /*------------------------------------------------------------------*/
2564 /*----------------------------*/
2566 /*----------------------------*/
2568 if (!(IS_PTR (LTYPE (tree)) ||
2569 IS_ARRAY (LTYPE (tree)) ||
2570 IS_ARITHMETIC (LTYPE (tree))))
2572 werror (E_PLUS_INVALID, "-");
2573 goto errorTreeReturn;
2576 if (!(IS_PTR (RTYPE (tree)) ||
2577 IS_ARRAY (RTYPE (tree)) ||
2578 IS_ARITHMETIC (RTYPE (tree))))
2580 werror (E_PLUS_INVALID, "-");
2581 goto errorTreeReturn;
2584 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2585 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2586 IS_INTEGRAL (RTYPE (tree))))
2588 werror (E_PLUS_INVALID, "-");
2589 goto errorTreeReturn;
2592 /* if they are both literal then */
2593 /* rewrite the tree */
2594 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2596 tree->type = EX_VALUE;
2597 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2598 valFromType (RETYPE (tree)));
2599 tree->right = tree->left = NULL;
2600 TETYPE (tree) = getSpec (TTYPE (tree) =
2601 tree->opval.val->type);
2605 /* if the left & right are equal then zero */
2606 if (isAstEqual (tree->left, tree->right))
2608 tree->type = EX_VALUE;
2609 tree->left = tree->right = NULL;
2610 tree->opval.val = constVal ("0");
2611 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2615 /* if both of them are pointers or arrays then */
2616 /* the result is going to be an integer */
2617 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2618 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2619 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2621 /* if only the left is a pointer */
2622 /* then result is a pointer */
2623 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2624 TETYPE (tree) = getSpec (TTYPE (tree) =
2627 TETYPE (tree) = getSpec (TTYPE (tree) =
2628 computeType (LTYPE (tree),
2630 LRVAL (tree) = RRVAL (tree) = 1;
2633 /*------------------------------------------------------------------*/
2634 /*----------------------------*/
2636 /*----------------------------*/
2638 /* can be only integral type */
2639 if (!IS_INTEGRAL (LTYPE (tree)))
2641 werror (E_UNARY_OP, tree->opval.op);
2642 goto errorTreeReturn;
2645 /* if left is a literal then do it */
2646 if (IS_LITERAL (LTYPE (tree)))
2648 tree->type = EX_VALUE;
2649 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2651 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2655 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2658 /*------------------------------------------------------------------*/
2659 /*----------------------------*/
2661 /*----------------------------*/
2663 /* can be pointer */
2664 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2665 !IS_PTR (LTYPE (tree)) &&
2666 !IS_ARRAY (LTYPE (tree)))
2668 werror (E_UNARY_OP, tree->opval.op);
2669 goto errorTreeReturn;
2672 /* if left is a literal then do it */
2673 if (IS_LITERAL (LTYPE (tree)))
2675 tree->type = EX_VALUE;
2676 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2678 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2682 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2685 /*------------------------------------------------------------------*/
2686 /*----------------------------*/
2688 /*----------------------------*/
2691 TTYPE (tree) = LTYPE (tree);
2692 TETYPE (tree) = LETYPE (tree);
2696 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2701 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2703 werror (E_SHIFT_OP_INVALID);
2704 werror (W_CONTINUE, "left & right types are ");
2705 printTypeChain (LTYPE (tree), stderr);
2706 fprintf (stderr, ",");
2707 printTypeChain (RTYPE (tree), stderr);
2708 fprintf (stderr, "\n");
2709 goto errorTreeReturn;
2712 /* if they are both literal then */
2713 /* rewrite the tree */
2714 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2716 tree->type = EX_VALUE;
2717 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2718 valFromType (RETYPE (tree)),
2719 (tree->opval.op == LEFT_OP ? 1 : 0));
2720 tree->right = tree->left = NULL;
2721 TETYPE (tree) = getSpec (TTYPE (tree) =
2722 tree->opval.val->type);
2726 /* if only the right side is a literal & we are
2727 shifting more than size of the left operand then zero */
2728 if (IS_LITERAL (RTYPE (tree)) &&
2729 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2730 (getSize (LTYPE (tree)) * 8))
2732 if (tree->opval.op==LEFT_OP ||
2733 (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
2734 lineno=tree->lineno;
2735 werror (W_SHIFT_CHANGED,
2736 (tree->opval.op == LEFT_OP ? "left" : "right"));
2737 tree->type = EX_VALUE;
2738 tree->left = tree->right = NULL;
2739 tree->opval.val = constVal ("0");
2740 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2744 LRVAL (tree) = RRVAL (tree) = 1;
2745 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2747 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2751 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2755 /*------------------------------------------------------------------*/
2756 /*----------------------------*/
2758 /*----------------------------*/
2759 case CAST: /* change the type */
2760 /* cannot cast to an aggregate type */
2761 if (IS_AGGREGATE (LTYPE (tree)))
2763 werror (E_CAST_ILLEGAL);
2764 goto errorTreeReturn;
2767 /* make sure the type is complete and sane */
2768 checkTypeSanity(LETYPE(tree), "(cast)");
2771 /* if the right is a literal replace the tree */
2772 if (IS_LITERAL (RETYPE (tree))) {
2773 if (!IS_PTR (LTYPE (tree))) {
2774 tree->type = EX_VALUE;
2776 valCastLiteral (LTYPE (tree),
2777 floatFromVal (valFromType (RETYPE (tree))));
2780 TTYPE (tree) = tree->opval.val->type;
2781 tree->values.literalFromCast = 1;
2782 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2783 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2784 sym_link *rest = LTYPE(tree)->next;
2785 werror(W_LITERAL_GENERIC);
2786 TTYPE(tree) = newLink();
2787 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2788 TTYPE(tree)->next = rest;
2789 tree->left->opval.lnk = TTYPE(tree);
2792 TTYPE (tree) = LTYPE (tree);
2796 TTYPE (tree) = LTYPE (tree);
2800 #if 0 // this is already checked, now this could be explicit
2801 /* if pointer to struct then check names */
2802 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2803 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2804 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
2806 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
2807 SPEC_STRUCT(LETYPE(tree))->tag);
2810 /* if the right is a literal replace the tree */
2811 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2812 tree->type = EX_VALUE;
2814 valCastLiteral (LTYPE (tree),
2815 floatFromVal (valFromType (RETYPE (tree))));
2818 TTYPE (tree) = tree->opval.val->type;
2819 tree->values.literalFromCast = 1;
2821 TTYPE (tree) = LTYPE (tree);
2825 TETYPE (tree) = getSpec (TTYPE (tree));
2829 /*------------------------------------------------------------------*/
2830 /*----------------------------*/
2831 /* logical &&, || */
2832 /*----------------------------*/
2835 /* each must me arithmetic type or be a pointer */
2836 if (!IS_PTR (LTYPE (tree)) &&
2837 !IS_ARRAY (LTYPE (tree)) &&
2838 !IS_INTEGRAL (LTYPE (tree)))
2840 werror (E_COMPARE_OP);
2841 goto errorTreeReturn;
2844 if (!IS_PTR (RTYPE (tree)) &&
2845 !IS_ARRAY (RTYPE (tree)) &&
2846 !IS_INTEGRAL (RTYPE (tree)))
2848 werror (E_COMPARE_OP);
2849 goto errorTreeReturn;
2851 /* if they are both literal then */
2852 /* rewrite the tree */
2853 if (IS_LITERAL (RTYPE (tree)) &&
2854 IS_LITERAL (LTYPE (tree)))
2856 tree->type = EX_VALUE;
2857 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2858 valFromType (RETYPE (tree)),
2860 tree->right = tree->left = NULL;
2861 TETYPE (tree) = getSpec (TTYPE (tree) =
2862 tree->opval.val->type);
2865 LRVAL (tree) = RRVAL (tree) = 1;
2866 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2869 /*------------------------------------------------------------------*/
2870 /*----------------------------*/
2871 /* comparison operators */
2872 /*----------------------------*/
2880 ast *lt = optimizeCompare (tree);
2886 /* if they are pointers they must be castable */
2887 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2889 if (tree->opval.op==EQ_OP &&
2890 !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
2891 // we cannot cast a gptr to a !gptr: switch the leaves
2892 struct ast *s=tree->left;
2893 tree->left=tree->right;
2896 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2898 werror (E_COMPARE_OP);
2899 fprintf (stderr, "comparring type ");
2900 printTypeChain (LTYPE (tree), stderr);
2901 fprintf (stderr, "to type ");
2902 printTypeChain (RTYPE (tree), stderr);
2903 fprintf (stderr, "\n");
2904 goto errorTreeReturn;
2907 /* else they should be promotable to one another */
2910 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2911 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2913 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2915 werror (E_COMPARE_OP);
2916 fprintf (stderr, "comparing type ");
2917 printTypeChain (LTYPE (tree), stderr);
2918 fprintf (stderr, "to type ");
2919 printTypeChain (RTYPE (tree), stderr);
2920 fprintf (stderr, "\n");
2921 goto errorTreeReturn;
2924 /* if unsigned value < 0 then always false */
2925 /* if (unsigned value) > 0 then (unsigned value) */
2926 if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
2927 ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2929 if (tree->opval.op == '<') {
2932 if (tree->opval.op == '>') {
2936 /* if they are both literal then */
2937 /* rewrite the tree */
2938 if (IS_LITERAL (RTYPE (tree)) &&
2939 IS_LITERAL (LTYPE (tree)))
2941 tree->type = EX_VALUE;
2942 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2943 valFromType (RETYPE (tree)),
2945 tree->right = tree->left = NULL;
2946 TETYPE (tree) = getSpec (TTYPE (tree) =
2947 tree->opval.val->type);
2950 LRVAL (tree) = RRVAL (tree) = 1;
2951 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2954 /*------------------------------------------------------------------*/
2955 /*----------------------------*/
2957 /*----------------------------*/
2958 case SIZEOF: /* evaluate wihout code generation */
2959 /* change the type to a integer */
2960 tree->type = EX_VALUE;
2961 SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
2962 tree->opval.val = constVal (buffer);
2963 tree->right = tree->left = NULL;
2964 TETYPE (tree) = getSpec (TTYPE (tree) =
2965 tree->opval.val->type);
2968 /*------------------------------------------------------------------*/
2969 /*----------------------------*/
2971 /*----------------------------*/
2973 /* return typeof enum value */
2974 tree->type = EX_VALUE;
2977 if (IS_SPEC(tree->right->ftype)) {
2978 switch (SPEC_NOUN(tree->right->ftype)) {
2980 if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2981 else typeofv = TYPEOF_INT;
2984 typeofv = TYPEOF_FLOAT;
2987 typeofv = TYPEOF_CHAR;
2990 typeofv = TYPEOF_VOID;
2993 typeofv = TYPEOF_STRUCT;
2996 typeofv = TYPEOF_BIT;
2999 typeofv = TYPEOF_SBIT;
3005 switch (DCL_TYPE(tree->right->ftype)) {
3007 typeofv = TYPEOF_POINTER;
3010 typeofv = TYPEOF_FPOINTER;
3013 typeofv = TYPEOF_CPOINTER;
3016 typeofv = TYPEOF_GPOINTER;
3019 typeofv = TYPEOF_PPOINTER;
3022 typeofv = TYPEOF_IPOINTER;
3025 typeofv = TYPEOF_ARRAY;
3028 typeofv = TYPEOF_FUNCTION;
3034 SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3035 tree->opval.val = constVal (buffer);
3036 tree->right = tree->left = NULL;
3037 TETYPE (tree) = getSpec (TTYPE (tree) =
3038 tree->opval.val->type);
3041 /*------------------------------------------------------------------*/
3042 /*----------------------------*/
3043 /* conditional operator '?' */
3044 /*----------------------------*/
3046 /* the type is value of the colon operator (on the right) */
3047 assert(IS_COLON_OP(tree->right));
3048 /* if already known then replace the tree : optimizer will do it
3049 but faster to do it here */
3050 if (IS_LITERAL (LTYPE(tree))) {
3051 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3052 return decorateType(tree->right->left) ;
3054 return decorateType(tree->right->right) ;
3057 tree->right = decorateType(tree->right);
3058 TTYPE (tree) = RTYPE(tree);
3059 TETYPE (tree) = getSpec (TTYPE (tree));
3064 /* if they don't match we have a problem */
3065 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3067 werror (E_TYPE_MISMATCH, "conditional operator", " ");
3068 goto errorTreeReturn;
3071 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
3072 TETYPE (tree) = getSpec (TTYPE (tree));
3076 #if 0 // assignment operators are converted by the parser
3077 /*------------------------------------------------------------------*/
3078 /*----------------------------*/
3079 /* assignment operators */
3080 /*----------------------------*/
3083 /* for these it must be both must be integral */
3084 if (!IS_ARITHMETIC (LTYPE (tree)) ||
3085 !IS_ARITHMETIC (RTYPE (tree)))
3087 werror (E_OPS_INTEGRAL);
3088 goto errorTreeReturn;
3091 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3093 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3094 werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3098 werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3099 goto errorTreeReturn;
3110 /* for these it must be both must be integral */
3111 if (!IS_INTEGRAL (LTYPE (tree)) ||
3112 !IS_INTEGRAL (RTYPE (tree)))
3114 werror (E_OPS_INTEGRAL);
3115 goto errorTreeReturn;
3118 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3120 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3121 werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3125 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3126 goto errorTreeReturn;
3132 /*------------------------------------------------------------------*/
3133 /*----------------------------*/
3135 /*----------------------------*/
3137 if (!(IS_PTR (LTYPE (tree)) ||
3138 IS_ARITHMETIC (LTYPE (tree))))
3140 werror (E_PLUS_INVALID, "-=");
3141 goto errorTreeReturn;
3144 if (!(IS_PTR (RTYPE (tree)) ||
3145 IS_ARITHMETIC (RTYPE (tree))))
3147 werror (E_PLUS_INVALID, "-=");
3148 goto errorTreeReturn;
3151 TETYPE (tree) = getSpec (TTYPE (tree) =
3152 computeType (LTYPE (tree),
3155 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3156 werror (E_CODE_WRITE, "-=");
3160 werror (E_LVALUE_REQUIRED, "-=");
3161 goto errorTreeReturn;
3167 /*------------------------------------------------------------------*/
3168 /*----------------------------*/
3170 /*----------------------------*/
3172 /* this is not a unary operation */
3173 /* if both pointers then problem */
3174 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3176 werror (E_PTR_PLUS_PTR);
3177 goto errorTreeReturn;
3180 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3182 werror (E_PLUS_INVALID, "+=");
3183 goto errorTreeReturn;
3186 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3188 werror (E_PLUS_INVALID, "+=");
3189 goto errorTreeReturn;
3192 TETYPE (tree) = getSpec (TTYPE (tree) =
3193 computeType (LTYPE (tree),
3196 if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3197 werror (E_CODE_WRITE, "+=");
3201 werror (E_LVALUE_REQUIRED, "+=");
3202 goto errorTreeReturn;
3205 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3206 tree->opval.op = '=';
3211 /*------------------------------------------------------------------*/
3212 /*----------------------------*/
3213 /* straight assignemnt */
3214 /*----------------------------*/
3216 /* cannot be an aggregate */
3217 if (IS_AGGREGATE (LTYPE (tree)))
3219 werror (E_AGGR_ASSIGN);
3220 goto errorTreeReturn;
3223 /* they should either match or be castable */
3224 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3226 werror (E_TYPE_MISMATCH, "assignment", " ");
3227 printFromToType(RTYPE(tree),LTYPE(tree));
3228 //goto errorTreeReturn;
3231 /* if the left side of the tree is of type void
3232 then report error */
3233 if (IS_VOID (LTYPE (tree)))
3235 werror (E_CAST_ZERO);
3236 printFromToType(RTYPE(tree), LTYPE(tree));
3239 TETYPE (tree) = getSpec (TTYPE (tree) =
3243 if (!tree->initMode ) {
3244 if (IS_CONSTANT (LTYPE (tree)))
3245 werror (E_CODE_WRITE, "=");
3249 werror (E_LVALUE_REQUIRED, "=");
3250 goto errorTreeReturn;
3255 /*------------------------------------------------------------------*/
3256 /*----------------------------*/
3257 /* comma operator */
3258 /*----------------------------*/
3260 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3263 /*------------------------------------------------------------------*/
3264 /*----------------------------*/
3266 /*----------------------------*/
3270 if (processParms (tree->left,
3271 FUNC_ARGS(tree->left->ftype),
3272 tree->right, &parmNumber, TRUE)) {
3273 goto errorTreeReturn;
3276 if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
3277 !IFFUNC_ISBUILTIN(LTYPE(tree)))
3279 //FUNC_ARGS(tree->left->ftype) =
3280 //reverseVal (FUNC_ARGS(tree->left->ftype));
3281 reverseParms (tree->right);
3284 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3287 /*------------------------------------------------------------------*/
3288 /*----------------------------*/
3289 /* return statement */
3290 /*----------------------------*/
3295 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3297 werror (W_RETURN_MISMATCH);
3298 printFromToType (RTYPE(tree), currFunc->type->next);
3299 goto errorTreeReturn;
3302 if (IS_VOID (currFunc->type->next)
3304 !IS_VOID (RTYPE (tree)))
3306 werror (E_FUNC_VOID);
3307 goto errorTreeReturn;
3310 /* if there is going to be a casing required then add it */
3311 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3314 decorateType (newNode (CAST,
3315 newAst_LINK (copyLinkChain (currFunc->type->next)),
3324 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3326 werror (E_VOID_FUNC, currFunc->name);
3327 goto errorTreeReturn;
3330 TTYPE (tree) = TETYPE (tree) = NULL;
3333 /*------------------------------------------------------------------*/
3334 /*----------------------------*/
3335 /* switch statement */
3336 /*----------------------------*/
3338 /* the switch value must be an integer */
3339 if (!IS_INTEGRAL (LTYPE (tree)))
3341 werror (E_SWITCH_NON_INTEGER);
3342 goto errorTreeReturn;
3345 TTYPE (tree) = TETYPE (tree) = NULL;
3348 /*------------------------------------------------------------------*/
3349 /*----------------------------*/
3351 /*----------------------------*/
3353 tree->left = backPatchLabels (tree->left,
3356 TTYPE (tree) = TETYPE (tree) = NULL;
3359 /*------------------------------------------------------------------*/
3360 /*----------------------------*/
3362 /*----------------------------*/
3365 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3366 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3367 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3369 /* if the for loop is reversible then
3370 reverse it otherwise do what we normally
3376 if (isLoopReversible (tree, &sym, &init, &end))
3377 return reverseLoop (tree, sym, init, end);
3379 return decorateType (createFor (AST_FOR (tree, trueLabel),
3380 AST_FOR (tree, continueLabel),
3381 AST_FOR (tree, falseLabel),
3382 AST_FOR (tree, condLabel),
3383 AST_FOR (tree, initExpr),
3384 AST_FOR (tree, condExpr),
3385 AST_FOR (tree, loopExpr),
3389 TTYPE (tree) = TETYPE (tree) = NULL;
3393 /* some error found this tree will be killed */
3395 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3396 tree->opval.op = NULLOP;
3402 /*-----------------------------------------------------------------*/
3403 /* sizeofOp - processes size of operation */
3404 /*-----------------------------------------------------------------*/
3406 sizeofOp (sym_link * type)
3410 /* make sure the type is complete and sane */
3411 checkTypeSanity(type, "(sizeof)");
3413 /* get the size and convert it to character */
3414 SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3416 /* now convert into value */
3417 return constVal (buff);
3421 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3422 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3423 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3424 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3425 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3426 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3427 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3429 /*-----------------------------------------------------------------*/
3430 /* backPatchLabels - change and or not operators to flow control */
3431 /*-----------------------------------------------------------------*/
3433 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3439 if (!(IS_ANDORNOT (tree)))
3442 /* if this an and */
3445 static int localLbl = 0;
3448 SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
3449 localLabel = newSymbol (buffer, NestLevel);
3451 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3453 /* if left is already a IFX then just change the if true label in that */
3454 if (!IS_IFX (tree->left))
3455 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3457 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3458 /* right is a IFX then just join */
3459 if (IS_IFX (tree->right))
3460 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3462 tree->right = createLabel (localLabel, tree->right);
3463 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3465 return newNode (NULLOP, tree->left, tree->right);
3468 /* if this is an or operation */
3471 static int localLbl = 0;
3474 SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
3475 localLabel = newSymbol (buffer, NestLevel);
3477 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3479 /* if left is already a IFX then just change the if true label in that */
3480 if (!IS_IFX (tree->left))
3481 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3483 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3484 /* right is a IFX then just join */
3485 if (IS_IFX (tree->right))
3486 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3488 tree->right = createLabel (localLabel, tree->right);
3489 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3491 return newNode (NULLOP, tree->left, tree->right);
3497 int wasnot = IS_NOT (tree->left);
3498 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3500 /* if the left is already a IFX */
3501 if (!IS_IFX (tree->left))
3502 tree->left = newNode (IFX, tree->left, NULL);
3506 tree->left->trueLabel = trueLabel;
3507 tree->left->falseLabel = falseLabel;
3511 tree->left->trueLabel = falseLabel;
3512 tree->left->falseLabel = trueLabel;
3519 tree->trueLabel = trueLabel;
3520 tree->falseLabel = falseLabel;
3527 /*-----------------------------------------------------------------*/
3528 /* createBlock - create expression tree for block */
3529 /*-----------------------------------------------------------------*/
3531 createBlock (symbol * decl, ast * body)
3535 /* if the block has nothing */
3539 ex = newNode (BLOCK, NULL, body);
3540 ex->values.sym = decl;
3542 ex->right = ex->right;
3548 /*-----------------------------------------------------------------*/
3549 /* createLabel - creates the expression tree for labels */
3550 /*-----------------------------------------------------------------*/
3552 createLabel (symbol * label, ast * stmnt)
3555 char name[SDCC_NAME_MAX + 1];
3558 /* must create fresh symbol if the symbol name */
3559 /* exists in the symbol table, since there can */
3560 /* be a variable with the same name as the labl */
3561 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3562 (csym->level == label->level))
3563 label = newSymbol (label->name, label->level);
3565 /* change the name before putting it in add _ */
3566 SNPRINTF(name, sizeof(name), "%s", label->name);
3568 /* put the label in the LabelSymbol table */
3569 /* but first check if a label of the same */
3571 if ((csym = findSym (LabelTab, NULL, name)))
3572 werror (E_DUPLICATE_LABEL, label->name);
3574 addSym (LabelTab, label, name, label->level, 0, 0);
3577 label->key = labelKey++;
3578 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3584 /*-----------------------------------------------------------------*/
3585 /* createCase - generates the parsetree for a case statement */
3586 /*-----------------------------------------------------------------*/
3588 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3590 char caseLbl[SDCC_NAME_MAX + 1];
3594 /* if the switch statement does not exist */
3595 /* then case is out of context */
3598 werror (E_CASE_CONTEXT);
3602 caseVal = decorateType (resolveSymbols (caseVal));
3603 /* if not a constant then error */
3604 if (!IS_LITERAL (caseVal->ftype))
3606 werror (E_CASE_CONSTANT);
3610 /* if not a integer than error */
3611 if (!IS_INTEGRAL (caseVal->ftype))
3613 werror (E_CASE_NON_INTEGER);
3617 /* find the end of the switch values chain */
3618 if (!(val = swStat->values.switchVals.swVals))
3619 swStat->values.switchVals.swVals = caseVal->opval.val;
3622 /* also order the cases according to value */
3624 int cVal = (int) floatFromVal (caseVal->opval.val);
3625 while (val && (int) floatFromVal (val) < cVal)
3631 /* if we reached the end then */
3634 pval->next = caseVal->opval.val;
3638 /* we found a value greater than */
3639 /* the current value we must add this */
3640 /* before the value */
3641 caseVal->opval.val->next = val;
3643 /* if this was the first in chain */
3644 if (swStat->values.switchVals.swVals == val)
3645 swStat->values.switchVals.swVals =
3648 pval->next = caseVal->opval.val;
3653 /* create the case label */
3654 SNPRINTF(caseLbl, sizeof(caseLbl),
3656 swStat->values.switchVals.swNum,
3657 (int) floatFromVal (caseVal->opval.val));
3659 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3664 /*-----------------------------------------------------------------*/
3665 /* createDefault - creates the parse tree for the default statement */
3666 /*-----------------------------------------------------------------*/
3668 createDefault (ast * swStat, ast * stmnt)
3670 char defLbl[SDCC_NAME_MAX + 1];
3672 /* if the switch statement does not exist */
3673 /* then case is out of context */
3676 werror (E_CASE_CONTEXT);
3680 /* turn on the default flag */
3681 swStat->values.switchVals.swDefault = 1;
3683 /* create the label */
3684 SNPRINTF (defLbl, sizeof(defLbl),
3685 "_default_%d", swStat->values.switchVals.swNum);
3686 return createLabel (newSymbol (defLbl, 0), stmnt);
3689 /*-----------------------------------------------------------------*/
3690 /* createIf - creates the parsetree for the if statement */
3691 /*-----------------------------------------------------------------*/
3693 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3695 static int Lblnum = 0;
3697 symbol *ifTrue, *ifFalse, *ifEnd;
3699 /* if neither exists */
3700 if (!elseBody && !ifBody) {
3701 // if there are no side effects (i++, j() etc)
3702 if (!hasSEFcalls(condAst)) {
3707 /* create the labels */
3708 SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
3709 ifFalse = newSymbol (buffer, NestLevel);
3710 /* if no else body then end == false */
3715 SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
3716 ifEnd = newSymbol (buffer, NestLevel);
3719 SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
3720 ifTrue = newSymbol (buffer, NestLevel);
3724 /* attach the ifTrue label to the top of it body */
3725 ifBody = createLabel (ifTrue, ifBody);
3726 /* attach a goto end to the ifBody if else is present */
3729 ifBody = newNode (NULLOP, ifBody,
3731 newAst_VALUE (symbolVal (ifEnd)),
3733 /* put the elseLabel on the else body */
3734 elseBody = createLabel (ifFalse, elseBody);
3735 /* out the end at the end of the body */
3736 elseBody = newNode (NULLOP,
3738 createLabel (ifEnd, NULL));
3742 ifBody = newNode (NULLOP, ifBody,
3743 createLabel (ifFalse, NULL));
3745 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3746 if (IS_IFX (condAst))
3749 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3751 return newNode (NULLOP, ifTree,
3752 newNode (NULLOP, ifBody, elseBody));
3756 /*-----------------------------------------------------------------*/
3757 /* createDo - creates parse tree for do */
3760 /* _docontinue_n: */
3761 /* condition_expression +-> trueLabel -> _dobody_n */
3763 /* +-> falseLabel-> _dobreak_n */
3765 /*-----------------------------------------------------------------*/
3767 createDo (symbol * trueLabel, symbol * continueLabel,
3768 symbol * falseLabel, ast * condAst, ast * doBody)
3773 /* if the body does not exist then it is simple */
3776 condAst = backPatchLabels (condAst, continueLabel, NULL);
3777 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3778 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3779 doTree->trueLabel = continueLabel;
3780 doTree->falseLabel = NULL;
3784 /* otherwise we have a body */
3785 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3787 /* attach the body label to the top */
3788 doBody = createLabel (trueLabel, doBody);
3789 /* attach the continue label to end of body */
3790 doBody = newNode (NULLOP, doBody,
3791 createLabel (continueLabel, NULL));
3793 /* now put the break label at the end */
3794 if (IS_IFX (condAst))
3797 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3799 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3801 /* putting it together */
3802 return newNode (NULLOP, doBody, doTree);
3805 /*-----------------------------------------------------------------*/
3806 /* createFor - creates parse tree for 'for' statement */
3809 /* condExpr +-> trueLabel -> _forbody_n */
3811 /* +-> falseLabel-> _forbreak_n */
3814 /* _forcontinue_n: */
3816 /* goto _forcond_n ; */
3818 /*-----------------------------------------------------------------*/
3820 createFor (symbol * trueLabel, symbol * continueLabel,
3821 symbol * falseLabel, symbol * condLabel,
3822 ast * initExpr, ast * condExpr, ast * loopExpr,
3827 /* if loopexpression not present then we can generate it */
3828 /* the same way as a while */
3830 return newNode (NULLOP, initExpr,
3831 createWhile (trueLabel, continueLabel,
3832 falseLabel, condExpr, forBody));
3833 /* vanilla for statement */
3834 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3836 if (condExpr && !IS_IFX (condExpr))
3837 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3840 /* attach condition label to condition */
3841 condExpr = createLabel (condLabel, condExpr);
3843 /* attach body label to body */
3844 forBody = createLabel (trueLabel, forBody);
3846 /* attach continue to forLoop expression & attach */
3847 /* goto the forcond @ and of loopExpression */
3848 loopExpr = createLabel (continueLabel,
3852 newAst_VALUE (symbolVal (condLabel)),
3854 /* now start putting them together */
3855 forTree = newNode (NULLOP, initExpr, condExpr);
3856 forTree = newNode (NULLOP, forTree, forBody);
3857 forTree = newNode (NULLOP, forTree, loopExpr);
3858 /* finally add the break label */
3859 forTree = newNode (NULLOP, forTree,
3860 createLabel (falseLabel, NULL));
3864 /*-----------------------------------------------------------------*/
3865 /* createWhile - creates parse tree for while statement */
3866 /* the while statement will be created as follows */
3868 /* _while_continue_n: */
3869 /* condition_expression +-> trueLabel -> _while_boby_n */
3871 /* +-> falseLabel -> _while_break_n */
3872 /* _while_body_n: */
3874 /* goto _while_continue_n */
3875 /* _while_break_n: */
3876 /*-----------------------------------------------------------------*/
3878 createWhile (symbol * trueLabel, symbol * continueLabel,
3879 symbol * falseLabel, ast * condExpr, ast * whileBody)
3883 /* put the continue label */
3884 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3885 condExpr = createLabel (continueLabel, condExpr);
3886 condExpr->lineno = 0;
3888 /* put the body label in front of the body */
3889 whileBody = createLabel (trueLabel, whileBody);
3890 whileBody->lineno = 0;
3891 /* put a jump to continue at the end of the body */
3892 /* and put break label at the end of the body */
3893 whileBody = newNode (NULLOP,
3896 newAst_VALUE (symbolVal (continueLabel)),
3897 createLabel (falseLabel, NULL)));
3899 /* put it all together */
3900 if (IS_IFX (condExpr))
3901 whileTree = condExpr;
3904 whileTree = newNode (IFX, condExpr, NULL);
3905 /* put the true & false labels in place */
3906 whileTree->trueLabel = trueLabel;
3907 whileTree->falseLabel = falseLabel;
3910 return newNode (NULLOP, whileTree, whileBody);
3913 /*-----------------------------------------------------------------*/
3914 /* optimizeGetHbit - get highest order bit of the expression */
3915 /*-----------------------------------------------------------------*/
3917 optimizeGetHbit (ast * tree)
3920 /* if this is not a bit and */
3921 if (!IS_BITAND (tree))
3924 /* will look for tree of the form
3925 ( expr >> ((sizeof expr) -1) ) & 1 */
3926 if (!IS_AST_LIT_VALUE (tree->right))
3929 if (AST_LIT_VALUE (tree->right) != 1)
3932 if (!IS_RIGHT_OP (tree->left))
3935 if (!IS_AST_LIT_VALUE (tree->left->right))
3938 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3939 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3942 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3946 /*-----------------------------------------------------------------*/
3947 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3948 /*-----------------------------------------------------------------*/
3950 optimizeRRCRLC (ast * root)
3952 /* will look for trees of the form
3953 (?expr << 1) | (?expr >> 7) or
3954 (?expr >> 7) | (?expr << 1) will make that
3955 into a RLC : operation ..
3957 (?expr >> 1) | (?expr << 7) or
3958 (?expr << 7) | (?expr >> 1) will make that
3959 into a RRC operation
3960 note : by 7 I mean (number of bits required to hold the
3962 /* if the root operations is not a | operation the not */
3963 if (!IS_BITOR (root))
3966 /* I have to think of a better way to match patterns this sucks */
3967 /* that aside let start looking for the first case : I use a the
3968 negative check a lot to improve the efficiency */
3969 /* (?expr << 1) | (?expr >> 7) */
3970 if (IS_LEFT_OP (root->left) &&
3971 IS_RIGHT_OP (root->right))
3974 if (!SPEC_USIGN (TETYPE (root->left->left)))
3977 if (!IS_AST_LIT_VALUE (root->left->right) ||
3978 !IS_AST_LIT_VALUE (root->right->right))
3981 /* make sure it is the same expression */
3982 if (!isAstEqual (root->left->left,
3986 if (AST_LIT_VALUE (root->left->right) != 1)
3989 if (AST_LIT_VALUE (root->right->right) !=
3990 (getSize (TTYPE (root->left->left)) * 8 - 1))
3993 /* whew got the first case : create the AST */
3994 return newNode (RLC, root->left->left, NULL);
3998 /* check for second case */
3999 /* (?expr >> 7) | (?expr << 1) */
4000 if (IS_LEFT_OP (root->right) &&
4001 IS_RIGHT_OP (root->left))
4004 if (!SPEC_USIGN (TETYPE (root->left->left)))
4007 if (!IS_AST_LIT_VALUE (root->left->right) ||
4008 !IS_AST_LIT_VALUE (root->right->right))
4011 /* make sure it is the same symbol */
4012 if (!isAstEqual (root->left->left,
4016 if (AST_LIT_VALUE (root->right->right) != 1)
4019 if (AST_LIT_VALUE (root->left->right) !=
4020 (getSize (TTYPE (root->left->left)) * 8 - 1))
4023 /* whew got the first case : create the AST */
4024 return newNode (RLC, root->left->left, NULL);
4029 /* third case for RRC */
4030 /* (?symbol >> 1) | (?symbol << 7) */
4031 if (IS_LEFT_OP (root->right) &&
4032 IS_RIGHT_OP (root->left))
4035 if (!SPEC_USIGN (TETYPE (root->left->left)))
4038 if (!IS_AST_LIT_VALUE (root->left->right) ||
4039 !IS_AST_LIT_VALUE (root->right->right))
4042 /* make sure it is the same symbol */
4043 if (!isAstEqual (root->left->left,
4047 if (AST_LIT_VALUE (root->left->right) != 1)
4050 if (AST_LIT_VALUE (root->right->right) !=
4051 (getSize (TTYPE (root->left->left)) * 8 - 1))
4054 /* whew got the first case : create the AST */
4055 return newNode (RRC, root->left->left, NULL);
4059 /* fourth and last case for now */
4060 /* (?symbol << 7) | (?symbol >> 1) */
4061 if (IS_RIGHT_OP (root->right) &&
4062 IS_LEFT_OP (root->left))
4065 if (!SPEC_USIGN (TETYPE (root->left->left)))
4068 if (!IS_AST_LIT_VALUE (root->left->right) ||
4069 !IS_AST_LIT_VALUE (root->right->right))
4072 /* make sure it is the same symbol */
4073 if (!isAstEqual (root->left->left,
4077 if (AST_LIT_VALUE (root->right->right) != 1)
4080 if (AST_LIT_VALUE (root->left->right) !=
4081 (getSize (TTYPE (root->left->left)) * 8 - 1))
4084 /* whew got the first case : create the AST */
4085 return newNode (RRC, root->left->left, NULL);
4089 /* not found return root */
4093 /*-----------------------------------------------------------------*/
4094 /* optimizeCompare - otimizes compares for bit variables */
4095 /*-----------------------------------------------------------------*/
4097 optimizeCompare (ast * root)
4099 ast *optExpr = NULL;
4102 unsigned int litValue;
4104 /* if nothing then return nothing */
4108 /* if not a compare op then do leaves */
4109 if (!IS_COMPARE_OP (root))
4111 root->left = optimizeCompare (root->left);
4112 root->right = optimizeCompare (root->right);
4116 /* if left & right are the same then depending
4117 of the operation do */
4118 if (isAstEqual (root->left, root->right))
4120 switch (root->opval.op)
4125 optExpr = newAst_VALUE (constVal ("0"));
4130 optExpr = newAst_VALUE (constVal ("1"));
4134 return decorateType (optExpr);
4137 vleft = (root->left->type == EX_VALUE ?
4138 root->left->opval.val : NULL);
4140 vright = (root->right->type == EX_VALUE ?
4141 root->right->opval.val : NULL);
4143 /* if left is a BITVAR in BITSPACE */
4144 /* and right is a LITERAL then opt- */
4145 /* imize else do nothing */
4146 if (vleft && vright &&
4147 IS_BITVAR (vleft->etype) &&
4148 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4149 IS_LITERAL (vright->etype))
4152 /* if right side > 1 then comparison may never succeed */
4153 if ((litValue = (int) floatFromVal (vright)) > 1)
4155 werror (W_BAD_COMPARE);
4161 switch (root->opval.op)
4163 case '>': /* bit value greater than 1 cannot be */
4164 werror (W_BAD_COMPARE);
4168 case '<': /* bit value < 1 means 0 */
4170 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4173 case LE_OP: /* bit value <= 1 means no check */
4174 optExpr = newAst_VALUE (vright);
4177 case GE_OP: /* bit value >= 1 means only check for = */
4179 optExpr = newAst_VALUE (vleft);
4184 { /* literal is zero */
4185 switch (root->opval.op)
4187 case '<': /* bit value < 0 cannot be */
4188 werror (W_BAD_COMPARE);
4192 case '>': /* bit value > 0 means 1 */
4194 optExpr = newAst_VALUE (vleft);
4197 case LE_OP: /* bit value <= 0 means no check */
4198 case GE_OP: /* bit value >= 0 means no check */
4199 werror (W_BAD_COMPARE);
4203 case EQ_OP: /* bit == 0 means ! of bit */
4204 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4208 return decorateType (resolveSymbols (optExpr));
4209 } /* end-of-if of BITVAR */
4214 /*-----------------------------------------------------------------*/
4215 /* addSymToBlock : adds the symbol to the first block we find */
4216 /*-----------------------------------------------------------------*/
4218 addSymToBlock (symbol * sym, ast * tree)
4220 /* reached end of tree or a leaf */
4221 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4225 if (IS_AST_OP (tree) &&
4226 tree->opval.op == BLOCK)
4229 symbol *lsym = copySymbol (sym);
4231 lsym->next = AST_VALUES (tree, sym);
4232 AST_VALUES (tree, sym) = lsym;
4236 addSymToBlock (sym, tree->left);
4237 addSymToBlock (sym, tree->right);
4240 /*-----------------------------------------------------------------*/
4241 /* processRegParms - do processing for register parameters */
4242 /*-----------------------------------------------------------------*/
4244 processRegParms (value * args, ast * body)
4248 if (IS_REGPARM (args->etype))
4249 addSymToBlock (args->sym, body);
4254 /*-----------------------------------------------------------------*/
4255 /* resetParmKey - resets the operandkeys for the symbols */
4256 /*-----------------------------------------------------------------*/
4257 DEFSETFUNC (resetParmKey)
4268 /*-----------------------------------------------------------------*/
4269 /* createFunction - This is the key node that calls the iCode for */
4270 /* generating the code for a function. Note code */
4271 /* is generated function by function, later when */
4272 /* add inter-procedural analysis this will change */
4273 /*-----------------------------------------------------------------*/
4275 createFunction (symbol * name, ast * body)
4281 iCode *piCode = NULL;
4283 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4284 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4286 /* if check function return 0 then some problem */
4287 if (checkFunction (name, NULL) == 0)
4290 /* create a dummy block if none exists */
4292 body = newNode (BLOCK, NULL, NULL);
4296 /* check if the function name already in the symbol table */
4297 if ((csym = findSym (SymbolTab, NULL, name->name)))
4300 /* special case for compiler defined functions
4301 we need to add the name to the publics list : this
4302 actually means we are now compiling the compiler
4306 addSet (&publics, name);
4312 allocVariables (name);
4314 name->lastLine = yylineno;
4317 /* set the stack pointer */
4318 /* PENDING: check this for the mcs51 */
4319 stackPtr = -port->stack.direction * port->stack.call_overhead;
4320 if (IFFUNC_ISISR (name->type))
4321 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4322 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4323 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4325 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4327 fetype = getSpec (name->type); /* get the specifier for the function */
4328 /* if this is a reentrant function then */
4329 if (IFFUNC_ISREENT (name->type))
4332 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4334 /* do processing for parameters that are passed in registers */
4335 processRegParms (FUNC_ARGS(name->type), body);
4337 /* set the stack pointer */
4341 /* allocate & autoinit the block variables */
4342 processBlockVars (body, &stack, ALLOCATE);
4344 /* save the stack information */
4345 if (options.useXstack)
4346 name->xstack = SPEC_STAK (fetype) = stack;
4348 name->stack = SPEC_STAK (fetype) = stack;
4350 /* name needs to be mangled */
4351 SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
4353 body = resolveSymbols (body); /* resolve the symbols */
4354 body = decorateType (body); /* propagateType & do semantic checks */
4356 ex = newAst_VALUE (symbolVal (name)); /* create name */
4357 ex = newNode (FUNCTION, ex, body);
4358 ex->values.args = FUNC_ARGS(name->type);
4360 if (options.dump_tree) PA(ex);
4363 werror (E_FUNC_NO_CODE, name->name);
4367 /* create the node & generate intermediate code */
4369 codeOutFile = code->oFile;
4370 piCode = iCodeFromAst (ex);
4374 werror (E_FUNC_NO_CODE, name->name);
4378 eBBlockFromiCode (piCode);
4380 /* if there are any statics then do them */
4383 GcurMemmap = statsg;
4384 codeOutFile = statsg->oFile;
4385 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4391 /* dealloc the block variables */
4392 processBlockVars (body, &stack, DEALLOCATE);
4393 /* deallocate paramaters */
4394 deallocParms (FUNC_ARGS(name->type));
4396 if (IFFUNC_ISREENT (name->type))
4399 /* we are done freeup memory & cleanup */
4401 if (port->reset_labelKey) labelKey = 1;
4403 FUNC_HASBODY(name->type) = 1;
4404 addSet (&operKeyReset, name);
4405 applyToSet (operKeyReset, resetParmKey);
4408 cdbStructBlock (1, cdbFile);
4410 cleanUpLevel (LabelTab, 0);
4411 cleanUpBlock (StructTab, 1);
4412 cleanUpBlock (TypedefTab, 1);
4414 xstack->syms = NULL;
4415 istack->syms = NULL;
4420 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
4421 /*-----------------------------------------------------------------*/
4422 /* ast_print : prints the ast (for debugging purposes) */
4423 /*-----------------------------------------------------------------*/
4425 void ast_print (ast * tree, FILE *outfile, int indent)
4430 /* can print only decorated trees */
4431 if (!tree->decorated) return;
4433 /* if any child is an error | this one is an error do nothing */
4434 if (tree->isError ||
4435 (tree->left && tree->left->isError) ||
4436 (tree->right && tree->right->isError)) {
4437 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4441 /* print the line */
4442 /* if not block & function */
4443 if (tree->type == EX_OP &&
4444 (tree->opval.op != FUNCTION &&
4445 tree->opval.op != BLOCK &&
4446 tree->opval.op != NULLOP)) {
4449 if (tree->opval.op == FUNCTION) {
4451 value *args=FUNC_ARGS(tree->left->opval.val->type);
4452 fprintf(outfile,"FUNCTION (%s=%p) type (",
4453 tree->left->opval.val->name, tree);
4454 printTypeChain (tree->ftype,outfile);
4455 fprintf(outfile,") args (");
4458 fprintf (outfile, ", ");
4460 printTypeChain (args ? args->type : NULL, outfile);
4462 args= args ? args->next : NULL;
4464 fprintf(outfile,")\n");
4465 ast_print(tree->left,outfile,indent);
4466 ast_print(tree->right,outfile,indent);
4469 if (tree->opval.op == BLOCK) {
4470 symbol *decls = tree->values.sym;
4471 INDENT(indent,outfile);
4472 fprintf(outfile,"{\n");
4474 INDENT(indent+2,outfile);
4475 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4476 decls->name, decls);
4477 printTypeChain(decls->type,outfile);
4478 fprintf(outfile,")\n");
4480 decls = decls->next;
4482 ast_print(tree->right,outfile,indent+2);
4483 INDENT(indent,outfile);
4484 fprintf(outfile,"}\n");
4487 if (tree->opval.op == NULLOP) {
4488 ast_print(tree->left,outfile,indent);
4489 ast_print(tree->right,outfile,indent);
4492 INDENT(indent,outfile);
4494 /*------------------------------------------------------------------*/
4495 /*----------------------------*/
4496 /* leaf has been reached */
4497 /*----------------------------*/
4498 /* if this is of type value */
4499 /* just get the type */
4500 if (tree->type == EX_VALUE) {
4502 if (IS_LITERAL (tree->opval.val->etype)) {
4503 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4504 (int) floatFromVal(tree->opval.val),
4505 (int) floatFromVal(tree->opval.val),
4506 floatFromVal(tree->opval.val));
4507 } else if (tree->opval.val->sym) {
4508 /* if the undefined flag is set then give error message */
4509 if (tree->opval.val->sym->undefined) {
4510 fprintf(outfile,"UNDEFINED SYMBOL ");
4512 fprintf(outfile,"SYMBOL ");
4514 fprintf(outfile,"(%s=%p)",
4515 tree->opval.val->sym->name,tree);
4518 fprintf(outfile," type (");
4519 printTypeChain(tree->ftype,outfile);
4520 fprintf(outfile,")\n");
4522 fprintf(outfile,"\n");
4527 /* if type link for the case of cast */
4528 if (tree->type == EX_LINK) {
4529 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4530 printTypeChain(tree->opval.lnk,outfile);
4531 fprintf(outfile,")\n");
4536 /* depending on type of operator do */
4538 switch (tree->opval.op) {
4539 /*------------------------------------------------------------------*/
4540 /*----------------------------*/
4542 /*----------------------------*/
4544 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4545 printTypeChain(tree->ftype,outfile);
4546 fprintf(outfile,")\n");
4547 ast_print(tree->left,outfile,indent+2);
4548 ast_print(tree->right,outfile,indent+2);
4551 /*------------------------------------------------------------------*/
4552 /*----------------------------*/
4554 /*----------------------------*/
4556 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4557 printTypeChain(tree->ftype,outfile);
4558 fprintf(outfile,")\n");
4559 ast_print(tree->left,outfile,indent+2);
4560 ast_print(tree->right,outfile,indent+2);
4563 /*------------------------------------------------------------------*/
4564 /*----------------------------*/
4565 /* struct/union pointer */
4566 /*----------------------------*/
4568 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+2);
4572 ast_print(tree->right,outfile,indent+2);
4575 /*------------------------------------------------------------------*/
4576 /*----------------------------*/
4577 /* ++/-- operation */
4578 /*----------------------------*/
4579 case INC_OP: /* incerement operator unary so left only */
4580 fprintf(outfile,"INC_OP (%p) type (",tree);
4581 printTypeChain(tree->ftype,outfile);
4582 fprintf(outfile,")\n");
4583 ast_print(tree->left,outfile,indent+2);
4587 fprintf(outfile,"DEC_OP (%p) type (",tree);
4588 printTypeChain(tree->ftype,outfile);
4589 fprintf(outfile,")\n");
4590 ast_print(tree->left,outfile,indent+2);
4593 /*------------------------------------------------------------------*/
4594 /*----------------------------*/
4596 /*----------------------------*/
4599 fprintf(outfile,"& (%p) type (",tree);
4600 printTypeChain(tree->ftype,outfile);
4601 fprintf(outfile,")\n");
4602 ast_print(tree->left,outfile,indent+2);
4603 ast_print(tree->right,outfile,indent+2);
4605 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4606 printTypeChain(tree->ftype,outfile);
4607 fprintf(outfile,")\n");
4608 ast_print(tree->left,outfile,indent+2);
4609 ast_print(tree->right,outfile,indent+2);
4612 /*----------------------------*/
4614 /*----------------------------*/
4616 fprintf(outfile,"OR (%p) type (",tree);
4617 printTypeChain(tree->ftype,outfile);
4618 fprintf(outfile,")\n");
4619 ast_print(tree->left,outfile,indent+2);
4620 ast_print(tree->right,outfile,indent+2);
4622 /*------------------------------------------------------------------*/
4623 /*----------------------------*/
4625 /*----------------------------*/
4627 fprintf(outfile,"XOR (%p) type (",tree);
4628 printTypeChain(tree->ftype,outfile);
4629 fprintf(outfile,")\n");
4630 ast_print(tree->left,outfile,indent+2);
4631 ast_print(tree->right,outfile,indent+2);
4634 /*------------------------------------------------------------------*/
4635 /*----------------------------*/
4637 /*----------------------------*/
4639 fprintf(outfile,"DIV (%p) type (",tree);
4640 printTypeChain(tree->ftype,outfile);
4641 fprintf(outfile,")\n");
4642 ast_print(tree->left,outfile,indent+2);
4643 ast_print(tree->right,outfile,indent+2);
4645 /*------------------------------------------------------------------*/
4646 /*----------------------------*/
4648 /*----------------------------*/
4650 fprintf(outfile,"MOD (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+2);
4654 ast_print(tree->right,outfile,indent+2);
4657 /*------------------------------------------------------------------*/
4658 /*----------------------------*/
4659 /* address dereference */
4660 /*----------------------------*/
4661 case '*': /* can be unary : if right is null then unary operation */
4663 fprintf(outfile,"DEREF (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+2);
4669 /*------------------------------------------------------------------*/
4670 /*----------------------------*/
4671 /* multiplication */
4672 /*----------------------------*/
4673 fprintf(outfile,"MULT (%p) type (",tree);
4674 printTypeChain(tree->ftype,outfile);
4675 fprintf(outfile,")\n");
4676 ast_print(tree->left,outfile,indent+2);
4677 ast_print(tree->right,outfile,indent+2);
4681 /*------------------------------------------------------------------*/
4682 /*----------------------------*/
4683 /* unary '+' operator */
4684 /*----------------------------*/
4688 fprintf(outfile,"UPLUS (%p) type (",tree);
4689 printTypeChain(tree->ftype,outfile);
4690 fprintf(outfile,")\n");
4691 ast_print(tree->left,outfile,indent+2);
4693 /*------------------------------------------------------------------*/
4694 /*----------------------------*/
4696 /*----------------------------*/
4697 fprintf(outfile,"ADD (%p) type (",tree);
4698 printTypeChain(tree->ftype,outfile);
4699 fprintf(outfile,")\n");
4700 ast_print(tree->left,outfile,indent+2);
4701 ast_print(tree->right,outfile,indent+2);
4704 /*------------------------------------------------------------------*/
4705 /*----------------------------*/
4707 /*----------------------------*/
4708 case '-': /* can be unary */
4710 fprintf(outfile,"UMINUS (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+2);
4715 /*------------------------------------------------------------------*/
4716 /*----------------------------*/
4718 /*----------------------------*/
4719 fprintf(outfile,"SUB (%p) type (",tree);
4720 printTypeChain(tree->ftype,outfile);
4721 fprintf(outfile,")\n");
4722 ast_print(tree->left,outfile,indent+2);
4723 ast_print(tree->right,outfile,indent+2);
4726 /*------------------------------------------------------------------*/
4727 /*----------------------------*/
4729 /*----------------------------*/
4731 fprintf(outfile,"COMPL (%p) type (",tree);
4732 printTypeChain(tree->ftype,outfile);
4733 fprintf(outfile,")\n");
4734 ast_print(tree->left,outfile,indent+2);
4736 /*------------------------------------------------------------------*/
4737 /*----------------------------*/
4739 /*----------------------------*/
4741 fprintf(outfile,"NOT (%p) type (",tree);
4742 printTypeChain(tree->ftype,outfile);
4743 fprintf(outfile,")\n");
4744 ast_print(tree->left,outfile,indent+2);
4746 /*------------------------------------------------------------------*/
4747 /*----------------------------*/
4749 /*----------------------------*/
4751 fprintf(outfile,"RRC (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+2);
4758 fprintf(outfile,"RLC (%p) type (",tree);
4759 printTypeChain(tree->ftype,outfile);
4760 fprintf(outfile,")\n");
4761 ast_print(tree->left,outfile,indent+2);
4764 fprintf(outfile,"GETHBIT (%p) type (",tree);
4765 printTypeChain(tree->ftype,outfile);
4766 fprintf(outfile,")\n");
4767 ast_print(tree->left,outfile,indent+2);
4770 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4771 printTypeChain(tree->ftype,outfile);
4772 fprintf(outfile,")\n");
4773 ast_print(tree->left,outfile,indent+2);
4774 ast_print(tree->right,outfile,indent+2);
4777 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4778 printTypeChain(tree->ftype,outfile);
4779 fprintf(outfile,")\n");
4780 ast_print(tree->left,outfile,indent+2);
4781 ast_print(tree->right,outfile,indent+2);
4783 /*------------------------------------------------------------------*/
4784 /*----------------------------*/
4786 /*----------------------------*/
4787 case CAST: /* change the type */
4788 fprintf(outfile,"CAST (%p) from type (",tree);
4789 printTypeChain(tree->right->ftype,outfile);
4790 fprintf(outfile,") to type (");
4791 printTypeChain(tree->ftype,outfile);
4792 fprintf(outfile,")\n");
4793 ast_print(tree->right,outfile,indent+2);
4797 fprintf(outfile,"ANDAND (%p) type (",tree);
4798 printTypeChain(tree->ftype,outfile);
4799 fprintf(outfile,")\n");
4800 ast_print(tree->left,outfile,indent+2);
4801 ast_print(tree->right,outfile,indent+2);
4804 fprintf(outfile,"OROR (%p) type (",tree);
4805 printTypeChain(tree->ftype,outfile);
4806 fprintf(outfile,")\n");
4807 ast_print(tree->left,outfile,indent+2);
4808 ast_print(tree->right,outfile,indent+2);
4811 /*------------------------------------------------------------------*/
4812 /*----------------------------*/
4813 /* comparison operators */
4814 /*----------------------------*/
4816 fprintf(outfile,"GT(>) (%p) type (",tree);
4817 printTypeChain(tree->ftype,outfile);
4818 fprintf(outfile,")\n");
4819 ast_print(tree->left,outfile,indent+2);
4820 ast_print(tree->right,outfile,indent+2);
4823 fprintf(outfile,"LT(<) (%p) type (",tree);
4824 printTypeChain(tree->ftype,outfile);
4825 fprintf(outfile,")\n");
4826 ast_print(tree->left,outfile,indent+2);
4827 ast_print(tree->right,outfile,indent+2);
4830 fprintf(outfile,"LE(<=) (%p) type (",tree);
4831 printTypeChain(tree->ftype,outfile);
4832 fprintf(outfile,")\n");
4833 ast_print(tree->left,outfile,indent+2);
4834 ast_print(tree->right,outfile,indent+2);
4837 fprintf(outfile,"GE(>=) (%p) type (",tree);
4838 printTypeChain(tree->ftype,outfile);
4839 fprintf(outfile,")\n");
4840 ast_print(tree->left,outfile,indent+2);
4841 ast_print(tree->right,outfile,indent+2);
4844 fprintf(outfile,"EQ(==) (%p) type (",tree);
4845 printTypeChain(tree->ftype,outfile);
4846 fprintf(outfile,")\n");
4847 ast_print(tree->left,outfile,indent+2);
4848 ast_print(tree->right,outfile,indent+2);
4851 fprintf(outfile,"NE(!=) (%p) type (",tree);
4852 printTypeChain(tree->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->left,outfile,indent+2);
4855 ast_print(tree->right,outfile,indent+2);
4856 /*------------------------------------------------------------------*/
4857 /*----------------------------*/
4859 /*----------------------------*/
4860 case SIZEOF: /* evaluate wihout code generation */
4861 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4864 /*------------------------------------------------------------------*/
4865 /*----------------------------*/
4866 /* conditional operator '?' */
4867 /*----------------------------*/
4869 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4870 printTypeChain(tree->ftype,outfile);
4871 fprintf(outfile,")\n");
4872 ast_print(tree->left,outfile,indent+2);
4873 ast_print(tree->right,outfile,indent+2);
4877 fprintf(outfile,"COLON(:) (%p) type (",tree);
4878 printTypeChain(tree->ftype,outfile);
4879 fprintf(outfile,")\n");
4880 ast_print(tree->left,outfile,indent+2);
4881 ast_print(tree->right,outfile,indent+2);
4884 /*------------------------------------------------------------------*/
4885 /*----------------------------*/
4886 /* assignment operators */
4887 /*----------------------------*/
4889 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4890 printTypeChain(tree->ftype,outfile);
4891 fprintf(outfile,")\n");
4892 ast_print(tree->left,outfile,indent+2);
4893 ast_print(tree->right,outfile,indent+2);
4896 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4897 printTypeChain(tree->ftype,outfile);
4898 fprintf(outfile,")\n");
4899 ast_print(tree->left,outfile,indent+2);
4900 ast_print(tree->right,outfile,indent+2);
4903 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4904 printTypeChain(tree->ftype,outfile);
4905 fprintf(outfile,")\n");
4906 ast_print(tree->left,outfile,indent+2);
4907 ast_print(tree->right,outfile,indent+2);
4910 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
4911 printTypeChain(tree->ftype,outfile);
4912 fprintf(outfile,")\n");
4913 ast_print(tree->left,outfile,indent+2);
4914 ast_print(tree->right,outfile,indent+2);
4917 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
4918 printTypeChain(tree->ftype,outfile);
4919 fprintf(outfile,")\n");
4920 ast_print(tree->left,outfile,indent+2);
4921 ast_print(tree->right,outfile,indent+2);
4924 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4925 printTypeChain(tree->ftype,outfile);
4926 fprintf(outfile,")\n");
4927 ast_print(tree->left,outfile,indent+2);
4928 ast_print(tree->right,outfile,indent+2);
4931 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
4932 printTypeChain(tree->ftype,outfile);
4933 fprintf(outfile,")\n");
4934 ast_print(tree->left,outfile,indent+2);
4935 ast_print(tree->right,outfile,indent+2);
4937 /*------------------------------------------------------------------*/
4938 /*----------------------------*/
4940 /*----------------------------*/
4942 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4943 printTypeChain(tree->ftype,outfile);
4944 fprintf(outfile,")\n");
4945 ast_print(tree->left,outfile,indent+2);
4946 ast_print(tree->right,outfile,indent+2);
4948 /*------------------------------------------------------------------*/
4949 /*----------------------------*/
4951 /*----------------------------*/
4953 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4954 printTypeChain(tree->ftype,outfile);
4955 fprintf(outfile,")\n");
4956 ast_print(tree->left,outfile,indent+2);
4957 ast_print(tree->right,outfile,indent+2);
4959 /*------------------------------------------------------------------*/
4960 /*----------------------------*/
4961 /* straight assignemnt */
4962 /*----------------------------*/
4964 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4965 printTypeChain(tree->ftype,outfile);
4966 fprintf(outfile,")\n");
4967 ast_print(tree->left,outfile,indent+2);
4968 ast_print(tree->right,outfile,indent+2);
4970 /*------------------------------------------------------------------*/
4971 /*----------------------------*/
4972 /* comma operator */
4973 /*----------------------------*/
4975 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4976 printTypeChain(tree->ftype,outfile);
4977 fprintf(outfile,")\n");
4978 ast_print(tree->left,outfile,indent+2);
4979 ast_print(tree->right,outfile,indent+2);
4981 /*------------------------------------------------------------------*/
4982 /*----------------------------*/
4984 /*----------------------------*/
4987 fprintf(outfile,"CALL (%p) type (",tree);
4988 printTypeChain(tree->ftype,outfile);
4989 fprintf(outfile,")\n");
4990 ast_print(tree->left,outfile,indent+2);
4991 ast_print(tree->right,outfile,indent+2);
4994 fprintf(outfile,"PARMS\n");
4995 ast_print(tree->left,outfile,indent+2);
4996 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4997 ast_print(tree->right,outfile,indent+2);
5000 /*------------------------------------------------------------------*/
5001 /*----------------------------*/
5002 /* return statement */
5003 /*----------------------------*/
5005 fprintf(outfile,"RETURN (%p) type (",tree);
5007 printTypeChain(tree->right->ftype,outfile);
5009 fprintf(outfile,")\n");
5010 ast_print(tree->right,outfile,indent+2);
5012 /*------------------------------------------------------------------*/
5013 /*----------------------------*/
5014 /* label statement */
5015 /*----------------------------*/
5017 fprintf(outfile,"LABEL (%p)\n",tree);
5018 ast_print(tree->left,outfile,indent+2);
5019 ast_print(tree->right,outfile,indent);
5021 /*------------------------------------------------------------------*/
5022 /*----------------------------*/
5023 /* switch statement */
5024 /*----------------------------*/
5028 fprintf(outfile,"SWITCH (%p) ",tree);
5029 ast_print(tree->left,outfile,0);
5030 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5031 INDENT(indent+2,outfile);
5032 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5033 (int) floatFromVal(val),
5034 tree->values.switchVals.swNum,
5035 (int) floatFromVal(val));
5037 ast_print(tree->right,outfile,indent);
5040 /*------------------------------------------------------------------*/
5041 /*----------------------------*/
5043 /*----------------------------*/
5045 fprintf(outfile,"IF (%p) \n",tree);
5046 ast_print(tree->left,outfile,indent+2);
5047 if (tree->trueLabel) {
5048 INDENT(indent+2,outfile);
5049 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5051 if (tree->falseLabel) {
5052 INDENT(indent+2,outfile);
5053 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5055 ast_print(tree->right,outfile,indent+2);
5057 /*----------------------------*/
5058 /* goto Statement */
5059 /*----------------------------*/
5061 fprintf(outfile,"GOTO (%p) \n",tree);
5062 ast_print(tree->left,outfile,indent+2);
5063 fprintf(outfile,"\n");
5065 /*------------------------------------------------------------------*/
5066 /*----------------------------*/
5068 /*----------------------------*/
5070 fprintf(outfile,"FOR (%p) \n",tree);
5071 if (AST_FOR( tree, initExpr)) {
5072 INDENT(indent+2,outfile);
5073 fprintf(outfile,"INIT EXPR ");
5074 ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5076 if (AST_FOR( tree, condExpr)) {
5077 INDENT(indent+2,outfile);
5078 fprintf(outfile,"COND EXPR ");
5079 ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5081 if (AST_FOR( tree, loopExpr)) {
5082 INDENT(indent+2,outfile);
5083 fprintf(outfile,"LOOP EXPR ");
5084 ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5086 fprintf(outfile,"FOR LOOP BODY \n");
5087 ast_print(tree->left,outfile,indent+2);
5096 ast_print(t,stdout,0);