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 ast *createIval (ast *, sym_link *, initList *, ast *);
52 ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 ast *optimizeRRCRLC (ast *);
54 ast *optimizeGetHbit (ast *);
55 ast *backPatchLabels (ast *, symbol *, symbol *);
57 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
62 printTypeChain (tree->ftype, stdout);
67 /*-----------------------------------------------------------------*/
68 /* newAst - creates a fresh node for an expression tree */
69 /*-----------------------------------------------------------------*/
72 newAst (int type, void *op)
75 static int oldLineno = 0;
77 ex = Safe_alloc ( sizeof (ast));
80 ex->lineno = (noLineno ? oldLineno : yylineno);
81 ex->filename = currFname;
82 ex->level = NestLevel;
83 ex->block = currBlockno;
84 ex->initMode = inInitMode;
86 /* depending on the type */
90 ex->opval.val = (value *) op;
93 ex->opval.op = (long) op;
96 ex->opval.lnk = (sym_link *) op;
99 ex->opval.stmnt = (unsigned) op;
107 newAst_ (unsigned type)
110 static int oldLineno = 0;
112 ex = Safe_alloc ( sizeof (ast));
115 ex->lineno = (noLineno ? oldLineno : yylineno);
116 ex->filename = currFname;
117 ex->level = NestLevel;
118 ex->block = currBlockno;
119 ex->initMode = inInitMode;
124 newAst_VALUE (value * val)
126 ast *ex = newAst_ (EX_VALUE);
132 newAst_OP (unsigned op)
134 ast *ex = newAst_ (EX_OP);
140 newAst_LINK (sym_link * val)
142 ast *ex = newAst_ (EX_LINK);
148 newAst_STMNT (unsigned val)
150 ast *ex = newAst_ (EX_STMNT);
151 ex->opval.stmnt = val;
155 /*-----------------------------------------------------------------*/
156 /* newNode - creates a new node */
157 /*-----------------------------------------------------------------*/
159 newNode (long op, ast * left, ast * right)
170 /*-----------------------------------------------------------------*/
171 /* newIfxNode - creates a new Ifx Node */
172 /*-----------------------------------------------------------------*/
174 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
178 /* if this is a literal then we already know the result */
179 if (condAst->etype && IS_LITERAL (condAst->etype))
181 /* then depending on the expression value */
182 if (floatFromVal (condAst->opval.val))
183 ifxNode = newNode (GOTO,
184 newAst_VALUE (symbolVal (trueLabel)),
187 ifxNode = newNode (GOTO,
188 newAst_VALUE (symbolVal (falseLabel)),
193 ifxNode = newNode (IFX, condAst, NULL);
194 ifxNode->trueLabel = trueLabel;
195 ifxNode->falseLabel = falseLabel;
201 /*-----------------------------------------------------------------*/
202 /* copyAstValues - copies value portion of ast if needed */
203 /*-----------------------------------------------------------------*/
205 copyAstValues (ast * dest, ast * src)
207 switch (src->opval.op)
210 dest->values.sym = copySymbolChain (src->values.sym);
214 dest->values.switchVals.swVals =
215 copyValue (src->values.switchVals.swVals);
216 dest->values.switchVals.swDefault =
217 src->values.switchVals.swDefault;
218 dest->values.switchVals.swNum =
219 src->values.switchVals.swNum;
223 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
224 strcpy (dest->values.inlineasm, src->values.inlineasm);
228 dest->values.constlist = copyLiteralList(src->values.constlist);
232 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
233 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
234 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
235 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
236 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
237 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
238 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
243 /*-----------------------------------------------------------------*/
244 /* copyAst - makes a copy of a given astession */
245 /*-----------------------------------------------------------------*/
254 dest = Safe_alloc ( sizeof (ast));
256 dest->type = src->type;
257 dest->lineno = src->lineno;
258 dest->level = src->level;
259 dest->funcName = src->funcName;
261 /* if this is a leaf */
263 if (src->type == EX_VALUE)
265 dest->opval.val = copyValue (src->opval.val);
270 if (src->type == EX_LINK)
272 dest->opval.lnk = copyLinkChain (src->opval.lnk);
276 dest->opval.op = src->opval.op;
278 /* if this is a node that has special values */
279 copyAstValues (dest, src);
282 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
284 dest->trueLabel = copySymbol (src->trueLabel);
285 dest->falseLabel = copySymbol (src->falseLabel);
286 dest->left = copyAst (src->left);
287 dest->right = copyAst (src->right);
293 /*-----------------------------------------------------------------*/
294 /* hasSEFcalls - returns TRUE if tree has a function call */
295 /*-----------------------------------------------------------------*/
297 hasSEFcalls (ast * tree)
302 if (tree->type == EX_OP &&
303 (tree->opval.op == CALL ||
304 tree->opval.op == PCALL ||
305 tree->opval.op == '=' ||
306 tree->opval.op == INC_OP ||
307 tree->opval.op == DEC_OP))
310 return (hasSEFcalls (tree->left) |
311 hasSEFcalls (tree->right));
314 /*-----------------------------------------------------------------*/
315 /* isAstEqual - compares two asts & returns 1 if they are equal */
316 /*-----------------------------------------------------------------*/
318 isAstEqual (ast * t1, ast * t2)
327 if (t1->type != t2->type)
333 if (t1->opval.op != t2->opval.op)
335 return (isAstEqual (t1->left, t2->left) &&
336 isAstEqual (t1->right, t2->right));
340 if (t1->opval.val->sym)
342 if (!t2->opval.val->sym)
345 return isSymbolEqual (t1->opval.val->sym,
350 if (t2->opval.val->sym)
353 return (floatFromVal (t1->opval.val) ==
354 floatFromVal (t2->opval.val));
358 /* only compare these two types */
366 /*-----------------------------------------------------------------*/
367 /* resolveSymbols - resolve symbols from the symbol table */
368 /*-----------------------------------------------------------------*/
370 resolveSymbols (ast * tree)
372 /* walk the entire tree and check for values */
373 /* with symbols if we find one then replace */
374 /* symbol with that from the symbol table */
380 /* if not block & function */
381 if (tree->type == EX_OP &&
382 (tree->opval.op != FUNCTION &&
383 tree->opval.op != BLOCK &&
384 tree->opval.op != NULLOP))
386 filename = tree->filename;
387 lineno = tree->lineno;
390 /* make sure we resolve the true & false labels for ifx */
391 if (tree->type == EX_OP && tree->opval.op == IFX)
397 if ((csym = findSym (LabelTab, tree->trueLabel,
398 tree->trueLabel->name)))
399 tree->trueLabel = csym;
401 werror (E_LABEL_UNDEF, tree->trueLabel->name);
404 if (tree->falseLabel)
406 if ((csym = findSym (LabelTab,
408 tree->falseLabel->name)))
409 tree->falseLabel = csym;
411 werror (E_LABEL_UNDEF, tree->falseLabel->name);
416 /* if this is a label resolve it from the labelTab */
417 if (IS_AST_VALUE (tree) &&
418 tree->opval.val->sym &&
419 tree->opval.val->sym->islbl)
422 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
423 tree->opval.val->sym->name);
426 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
428 tree->opval.val->sym = csym;
430 goto resolveChildren;
433 /* do only for leafs */
434 if (IS_AST_VALUE (tree) &&
435 tree->opval.val->sym &&
436 !tree->opval.val->sym->implicit)
439 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
441 /* if found in the symbol table & they r not the same */
442 if (csym && tree->opval.val->sym != csym)
444 tree->opval.val->sym = csym;
445 tree->opval.val->type = csym->type;
446 tree->opval.val->etype = csym->etype;
449 /* if not found in the symbol table */
450 /* mark it as undefined assume it is */
451 /* an integer in data space */
452 if (!csym && !tree->opval.val->sym->implicit)
455 /* if this is a function name then */
456 /* mark it as returning an int */
459 tree->opval.val->sym->type = newLink ();
460 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
461 tree->opval.val->sym->type->next =
462 tree->opval.val->sym->etype = newIntLink ();
463 tree->opval.val->etype = tree->opval.val->etype;
464 tree->opval.val->type = tree->opval.val->sym->type;
465 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
466 allocVariables (tree->opval.val->sym);
470 tree->opval.val->sym->undefined = 1;
471 tree->opval.val->type =
472 tree->opval.val->etype = newIntLink ();
473 tree->opval.val->sym->type =
474 tree->opval.val->sym->etype = newIntLink ();
480 resolveSymbols (tree->left);
481 resolveSymbols (tree->right);
486 /*-----------------------------------------------------------------*/
487 /* setAstLineno - walks a ast tree & sets the line number */
488 /*-----------------------------------------------------------------*/
490 setAstLineno (ast * tree, int lineno)
495 tree->lineno = lineno;
496 setAstLineno (tree->left, lineno);
497 setAstLineno (tree->right, lineno);
502 /* this functions seems to be superfluous?! kmh */
504 /*-----------------------------------------------------------------*/
505 /* resolveFromTable - will return the symbal table value */
506 /*-----------------------------------------------------------------*/
508 resolveFromTable (value * val)
515 csym = findSymWithLevel (SymbolTab, val->sym);
517 /* if found in the symbol table & they r not the same */
518 if (csym && val->sym != csym &&
519 csym->level == val->sym->level &&
525 val->type = csym->type;
526 val->etype = csym->etype;
533 /*-----------------------------------------------------------------*/
534 /* funcOfType :- function of type with name */
535 /*-----------------------------------------------------------------*/
537 funcOfType (char *name, sym_link * type, sym_link * argType,
541 /* create the symbol */
542 sym = newSymbol (name, 0);
544 /* setup return value */
545 sym->type = newLink ();
546 DCL_TYPE (sym->type) = FUNCTION;
547 sym->type->next = copyLinkChain (type);
548 sym->etype = getSpec (sym->type);
549 FUNC_ISREENT(sym->type) = rent;
551 /* if arguments required */
555 args = FUNC_ARGS(sym->type) = newValue ();
559 args->type = copyLinkChain (argType);
560 args->etype = getSpec (args->type);
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
607 bool rightmost) // double checked?
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 this is a varargs function... */
646 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
651 if (IS_CAST_OP (actParm)
652 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
654 /* Parameter was explicitly typecast; don't touch it. */
658 /* The ternary ('?') operator is weird: the ftype of the
659 * operator is the type of the condition, but it will return a
660 * (possibly) different type.
662 if (IS_TERNARY_OP(actParm))
664 assert(IS_COLON_OP(actParm->right));
665 assert(actParm->right->left);
666 ftype = actParm->right->left->ftype;
670 ftype = actParm->ftype;
673 /* If it's a small integer, upcast to int. */
674 if (IS_INTEGRAL (ftype)
675 && (getSize (ftype) < (unsigned) INTSIZE))
677 newType = newAst_LINK(INTTYPE);
680 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
682 newType = newAst_LINK (copyLinkChain(ftype));
683 DCL_TYPE (newType->opval.lnk) = GPOINTER;
686 if (IS_AGGREGATE (ftype))
688 // jwk: don't we need aggregateToPointer here?
689 newType = newAst_LINK (copyLinkChain (ftype));
690 DCL_TYPE (newType->opval.lnk) = GPOINTER;
694 /* cast required; change this op to a cast. */
695 ast *parmCopy = resolveSymbols (copyAst (actParm));
697 actParm->type = EX_OP;
698 actParm->opval.op = CAST;
699 actParm->left = newType;
700 actParm->right = parmCopy;
701 decorateType (actParm);
703 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
705 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
706 processParms (func, NULL, actParm->right, parmNumber, rightmost));
711 /* if defined parameters ended but actual has not & */
713 if (!defParm && actParm &&
714 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
717 resolveSymbols (actParm);
718 /* if this is a PARAM node then match left & right */
719 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
721 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
722 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
726 /* If we have found a value node by following only right-hand links,
727 * then we know that there are no more values after us.
729 * Therefore, if there are more defined parameters, the caller didn't
732 if (0 && rightmost && defParm->next)
734 werror (E_TOO_FEW_PARMS);
739 /* the parameter type must be at least castable */
740 if (compareType (defParm->type, actParm->ftype) == 0) {
741 werror (E_INCOMPAT_TYPES);
742 fprintf (stderr, "type --> '");
743 printTypeChain (actParm->ftype, stderr);
744 fprintf (stderr, "' ");
745 fprintf (stderr, "assigned to type --> '");
746 printTypeChain (defParm->type, stderr);
747 fprintf (stderr, "'\n");
751 /* if the parameter is castable then add the cast */
752 if (compareType (defParm->type, actParm->ftype) < 0)
754 ast *pTree = resolveSymbols (copyAst (actParm));
756 /* now change the current one to a cast */
757 actParm->type = EX_OP;
758 actParm->opval.op = CAST;
759 actParm->left = newAst_LINK (defParm->type);
760 actParm->right = pTree;
761 actParm->etype = defParm->etype;
762 actParm->ftype = defParm->type;
765 /* make a copy and change the regparm type to the defined parm */
766 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
767 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
771 /*-----------------------------------------------------------------*/
772 /* createIvalType - generates ival for basic types */
773 /*-----------------------------------------------------------------*/
775 createIvalType (ast * sym, sym_link * type, initList * ilist)
779 /* if initList is deep */
780 if (ilist->type == INIT_DEEP)
781 ilist = ilist->init.deep;
783 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
784 return decorateType (newNode ('=', sym, iExpr));
787 /*-----------------------------------------------------------------*/
788 /* createIvalStruct - generates initial value for structures */
789 /*-----------------------------------------------------------------*/
791 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
797 sflds = SPEC_STRUCT (type)->fields;
798 if (ilist->type != INIT_DEEP)
800 werror (E_INIT_STRUCT, "");
804 iloop = ilist->init.deep;
806 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
810 /* if we have come to end */
814 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
815 lAst = decorateType (resolveSymbols (lAst));
816 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
822 /*-----------------------------------------------------------------*/
823 /* createIvalArray - generates code for array initialization */
824 /*-----------------------------------------------------------------*/
826 createIvalArray (ast * sym, sym_link * type, initList * ilist)
830 int lcnt = 0, size = 0;
831 literalList *literalL;
833 /* take care of the special case */
834 /* array of characters can be init */
836 if (IS_CHAR (type->next))
837 if ((rast = createIvalCharPtr (sym,
839 decorateType (resolveSymbols (list2expr (ilist))))))
841 return decorateType (resolveSymbols (rast));
843 /* not the special case */
844 if (ilist->type != INIT_DEEP)
846 werror (E_INIT_STRUCT, "");
850 iloop = ilist->init.deep;
851 lcnt = DCL_ELEM (type);
853 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
857 aSym = decorateType (resolveSymbols(sym));
859 rast = newNode(ARRAYINIT, aSym, NULL);
860 rast->values.constlist = literalL;
862 // Make sure size is set to length of initializer list.
869 if (lcnt && size > lcnt)
871 // Array size was specified, and we have more initializers than needed.
872 char *name=sym->opval.val->sym->name;
873 int lineno=sym->opval.val->sym->lineDef;
875 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
884 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
885 aSym = decorateType (resolveSymbols (aSym));
886 rast = createIval (aSym, type->next, iloop, rast);
887 iloop = (iloop ? iloop->next : NULL);
893 /* no of elements given and we */
894 /* have generated for all of them */
897 // there has to be a better way
898 char *name=sym->opval.val->sym->name;
899 int lineno=sym->opval.val->sym->lineDef;
900 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
907 /* if we have not been given a size */
908 if (!DCL_ELEM (type))
910 DCL_ELEM (type) = size;
913 return decorateType (resolveSymbols (rast));
917 /*-----------------------------------------------------------------*/
918 /* createIvalCharPtr - generates initial values for char pointers */
919 /*-----------------------------------------------------------------*/
921 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
925 /* if this is a pointer & right is a literal array then */
926 /* just assignment will do */
927 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
928 SPEC_SCLS (iexpr->etype) == S_CODE)
929 && IS_ARRAY (iexpr->ftype)))
930 return newNode ('=', sym, iexpr);
932 /* left side is an array so we have to assign each */
934 if ((IS_LITERAL (iexpr->etype) ||
935 SPEC_SCLS (iexpr->etype) == S_CODE)
936 && IS_ARRAY (iexpr->ftype))
938 /* for each character generate an assignment */
939 /* to the array element */
940 char *s = SPEC_CVAL (iexpr->etype).v_char;
945 rast = newNode (NULLOP,
949 newAst_VALUE (valueFromLit ((float) i))),
950 newAst_VALUE (valueFromLit (*s))));
954 rast = newNode (NULLOP,
958 newAst_VALUE (valueFromLit ((float) i))),
959 newAst_VALUE (valueFromLit (*s))));
960 return decorateType (resolveSymbols (rast));
966 /*-----------------------------------------------------------------*/
967 /* createIvalPtr - generates initial value for pointers */
968 /*-----------------------------------------------------------------*/
970 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
976 if (ilist->type == INIT_DEEP)
977 ilist = ilist->init.deep;
979 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
981 /* if character pointer */
982 if (IS_CHAR (type->next))
983 if ((rast = createIvalCharPtr (sym, type, iexpr)))
986 return newNode ('=', sym, iexpr);
989 /*-----------------------------------------------------------------*/
990 /* createIval - generates code for initial value */
991 /*-----------------------------------------------------------------*/
993 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1000 /* if structure then */
1001 if (IS_STRUCT (type))
1002 rast = createIvalStruct (sym, type, ilist);
1004 /* if this is a pointer */
1006 rast = createIvalPtr (sym, type, ilist);
1008 /* if this is an array */
1009 if (IS_ARRAY (type))
1010 rast = createIvalArray (sym, type, ilist);
1012 /* if type is SPECIFIER */
1014 rast = createIvalType (sym, type, ilist);
1017 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1019 return decorateType (resolveSymbols (rast));
1022 /*-----------------------------------------------------------------*/
1023 /* initAggregates - initialises aggregate variables with initv */
1024 /*-----------------------------------------------------------------*/
1026 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1028 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1032 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1034 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1035 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1036 "with -mmcs51 and --model-large");
1040 if (SPEC_OCLS(sym->etype)==xdata &&
1041 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1044 newSym=copySymbol (sym);
1045 SPEC_OCLS(newSym->etype)=code;
1046 sprintf (newSym->name, "%s_init__", sym->name);
1047 sprintf (newSym->rname,"%s_init__", sym->rname);
1048 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1050 // emit it in the static segment
1051 addSet(&statsg->syms, newSym);
1053 // now memcpy() the entire array from cseg
1054 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1055 newAst_VALUE (symbolVal (sym)),
1056 newAst_VALUE (symbolVal (newSym)));
1057 return decorateType(resolveSymbols(ast));
1061 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1064 /*-----------------------------------------------------------------*/
1065 /* gatherAutoInit - creates assignment expressions for initial */
1067 /*-----------------------------------------------------------------*/
1069 gatherAutoInit (symbol * autoChain)
1076 for (sym = autoChain; sym; sym = sym->next)
1079 /* resolve the symbols in the ival */
1081 resolveIvalSym (sym->ival);
1083 /* if this is a static variable & has an */
1084 /* initial value the code needs to be lifted */
1085 /* here to the main portion since they can be */
1086 /* initialised only once at the start */
1087 if (IS_STATIC (sym->etype) && sym->ival &&
1088 SPEC_SCLS (sym->etype) != S_CODE)
1092 // this can only be a constant
1093 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1094 werror (E_CONST_EXPECTED);
1097 /* insert the symbol into the symbol table */
1098 /* with level = 0 & name = rname */
1099 newSym = copySymbol (sym);
1100 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1102 /* now lift the code to main */
1103 if (IS_AGGREGATE (sym->type))
1104 work = initAggregates (sym, sym->ival, NULL);
1106 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1107 list2expr (sym->ival));
1109 setAstLineno (work, sym->lineDef);
1113 staticAutos = newNode (NULLOP, staticAutos, work);
1120 /* if there is an initial value */
1121 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1123 if (IS_AGGREGATE (sym->type))
1124 work = initAggregates (sym, sym->ival, NULL);
1126 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1127 list2expr (sym->ival));
1129 setAstLineno (work, sym->lineDef);
1132 init = newNode (NULLOP, init, work);
1141 /*-----------------------------------------------------------------*/
1142 /* stringToSymbol - creates a symbol from a literal string */
1143 /*-----------------------------------------------------------------*/
1145 stringToSymbol (value * val)
1147 char name[SDCC_NAME_MAX + 1];
1148 static int charLbl = 0;
1151 sprintf (name, "_str_%d", charLbl++);
1152 sym = newSymbol (name, 0); /* make it @ level 0 */
1153 strcpy (sym->rname, name);
1155 /* copy the type from the value passed */
1156 sym->type = copyLinkChain (val->type);
1157 sym->etype = getSpec (sym->type);
1158 /* change to storage class & output class */
1159 SPEC_SCLS (sym->etype) = S_CODE;
1160 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1161 SPEC_STAT (sym->etype) = 1;
1162 /* make the level & block = 0 */
1163 sym->block = sym->level = 0;
1165 /* create an ival */
1166 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1171 allocVariables (sym);
1174 return symbolVal (sym);
1178 /*-----------------------------------------------------------------*/
1179 /* processBlockVars - will go thru the ast looking for block if */
1180 /* a block is found then will allocate the syms */
1181 /* will also gather the auto inits present */
1182 /*-----------------------------------------------------------------*/
1184 processBlockVars (ast * tree, int *stack, int action)
1189 /* if this is a block */
1190 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1194 if (action == ALLOCATE)
1196 *stack += allocVariables (tree->values.sym);
1197 autoInit = gatherAutoInit (tree->values.sym);
1199 /* if there are auto inits then do them */
1201 tree->left = newNode (NULLOP, autoInit, tree->left);
1203 else /* action is deallocate */
1204 deallocLocal (tree->values.sym);
1207 processBlockVars (tree->left, stack, action);
1208 processBlockVars (tree->right, stack, action);
1212 /*-----------------------------------------------------------------*/
1213 /* constExprValue - returns the value of a constant expression */
1214 /* or NULL if it is not a constant expression */
1215 /*-----------------------------------------------------------------*/
1217 constExprValue (ast * cexpr, int check)
1219 cexpr = decorateType (resolveSymbols (cexpr));
1221 /* if this is not a constant then */
1222 if (!IS_LITERAL (cexpr->ftype))
1224 /* then check if this is a literal array
1226 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1227 SPEC_CVAL (cexpr->etype).v_char &&
1228 IS_ARRAY (cexpr->ftype))
1230 value *val = valFromType (cexpr->ftype);
1231 SPEC_SCLS (val->etype) = S_LITERAL;
1232 val->sym = cexpr->opval.val->sym;
1233 val->sym->type = copyLinkChain (cexpr->ftype);
1234 val->sym->etype = getSpec (val->sym->type);
1235 strcpy (val->name, cexpr->opval.val->sym->rname);
1239 /* if we are casting a literal value then */
1240 if (IS_AST_OP (cexpr) &&
1241 cexpr->opval.op == CAST &&
1242 IS_LITERAL (cexpr->left->ftype))
1243 return valCastLiteral (cexpr->ftype,
1244 floatFromVal (cexpr->left->opval.val));
1246 if (IS_AST_VALUE (cexpr))
1247 return cexpr->opval.val;
1250 werror (E_CONST_EXPECTED, "found expression");
1255 /* return the value */
1256 return cexpr->opval.val;
1260 /*-----------------------------------------------------------------*/
1261 /* isLabelInAst - will return true if a given label is found */
1262 /*-----------------------------------------------------------------*/
1264 isLabelInAst (symbol * label, ast * tree)
1266 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1269 if (IS_AST_OP (tree) &&
1270 tree->opval.op == LABEL &&
1271 isSymbolEqual (AST_SYMBOL (tree->left), label))
1274 return isLabelInAst (label, tree->right) &&
1275 isLabelInAst (label, tree->left);
1279 /*-----------------------------------------------------------------*/
1280 /* isLoopCountable - return true if the loop count can be determi- */
1281 /* -ned at compile time . */
1282 /*-----------------------------------------------------------------*/
1284 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1285 symbol ** sym, ast ** init, ast ** end)
1288 /* the loop is considered countable if the following
1289 conditions are true :-
1291 a) initExpr :- <sym> = <const>
1292 b) condExpr :- <sym> < <const1>
1293 c) loopExpr :- <sym> ++
1296 /* first check the initExpr */
1297 if (IS_AST_OP (initExpr) &&
1298 initExpr->opval.op == '=' && /* is assignment */
1299 IS_AST_SYM_VALUE (initExpr->left))
1300 { /* left is a symbol */
1302 *sym = AST_SYMBOL (initExpr->left);
1303 *init = initExpr->right;
1308 /* for now the symbol has to be of
1310 if (!IS_INTEGRAL ((*sym)->type))
1313 /* now check condExpr */
1314 if (IS_AST_OP (condExpr))
1317 switch (condExpr->opval.op)
1320 if (IS_AST_SYM_VALUE (condExpr->left) &&
1321 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1322 IS_AST_LIT_VALUE (condExpr->right))
1324 *end = condExpr->right;
1330 if (IS_AST_OP (condExpr->left) &&
1331 condExpr->left->opval.op == '>' &&
1332 IS_AST_LIT_VALUE (condExpr->left->right) &&
1333 IS_AST_SYM_VALUE (condExpr->left->left) &&
1334 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1337 *end = newNode ('+', condExpr->left->right,
1338 newAst_VALUE (constVal ("1")));
1349 /* check loop expression is of the form <sym>++ */
1350 if (!IS_AST_OP (loopExpr))
1353 /* check if <sym> ++ */
1354 if (loopExpr->opval.op == INC_OP)
1360 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1361 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1368 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1369 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1377 if (loopExpr->opval.op == ADD_ASSIGN)
1380 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1381 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1382 IS_AST_LIT_VALUE (loopExpr->right) &&
1383 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1391 /*-----------------------------------------------------------------*/
1392 /* astHasVolatile - returns true if ast contains any volatile */
1393 /*-----------------------------------------------------------------*/
1395 astHasVolatile (ast * tree)
1400 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1403 if (IS_AST_OP (tree))
1404 return astHasVolatile (tree->left) ||
1405 astHasVolatile (tree->right);
1410 /*-----------------------------------------------------------------*/
1411 /* astHasPointer - return true if the ast contains any ptr variable */
1412 /*-----------------------------------------------------------------*/
1414 astHasPointer (ast * tree)
1419 if (IS_AST_LINK (tree))
1422 /* if we hit an array expression then check
1423 only the left side */
1424 if (IS_AST_OP (tree) && tree->opval.op == '[')
1425 return astHasPointer (tree->left);
1427 if (IS_AST_VALUE (tree))
1428 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1430 return astHasPointer (tree->left) ||
1431 astHasPointer (tree->right);
1435 /*-----------------------------------------------------------------*/
1436 /* astHasSymbol - return true if the ast has the given symbol */
1437 /*-----------------------------------------------------------------*/
1439 astHasSymbol (ast * tree, symbol * sym)
1441 if (!tree || IS_AST_LINK (tree))
1444 if (IS_AST_VALUE (tree))
1446 if (IS_AST_SYM_VALUE (tree))
1447 return isSymbolEqual (AST_SYMBOL (tree), sym);
1452 return astHasSymbol (tree->left, sym) ||
1453 astHasSymbol (tree->right, sym);
1456 /*-----------------------------------------------------------------*/
1457 /* astHasDeref - return true if the ast has an indirect access */
1458 /*-----------------------------------------------------------------*/
1460 astHasDeref (ast * tree)
1462 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1465 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1467 return astHasDeref (tree->left) || astHasDeref (tree->right);
1470 /*-----------------------------------------------------------------*/
1471 /* isConformingBody - the loop body has to conform to a set of rules */
1472 /* for the loop to be considered reversible read on for rules */
1473 /*-----------------------------------------------------------------*/
1475 isConformingBody (ast * pbody, symbol * sym, ast * body)
1478 /* we are going to do a pre-order traversal of the
1479 tree && check for the following conditions. (essentially
1480 a set of very shallow tests )
1481 a) the sym passed does not participate in
1482 any arithmetic operation
1483 b) There are no function calls
1484 c) all jumps are within the body
1485 d) address of loop control variable not taken
1486 e) if an assignment has a pointer on the
1487 left hand side make sure right does not have
1488 loop control variable */
1490 /* if we reach the end or a leaf then true */
1491 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1495 /* if anything else is "volatile" */
1496 if (IS_VOLATILE (TETYPE (pbody)))
1499 /* we will walk the body in a pre-order traversal for
1501 switch (pbody->opval.op)
1503 /*------------------------------------------------------------------*/
1505 return isConformingBody (pbody->right, sym, body);
1507 /*------------------------------------------------------------------*/
1512 /*------------------------------------------------------------------*/
1513 case INC_OP: /* incerement operator unary so left only */
1516 /* sure we are not sym is not modified */
1518 IS_AST_SYM_VALUE (pbody->left) &&
1519 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1523 IS_AST_SYM_VALUE (pbody->right) &&
1524 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1529 /*------------------------------------------------------------------*/
1531 case '*': /* can be unary : if right is null then unary operation */
1536 /* if right is NULL then unary operation */
1537 /*------------------------------------------------------------------*/
1538 /*----------------------------*/
1540 /*----------------------------*/
1543 if (IS_AST_SYM_VALUE (pbody->left) &&
1544 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1547 return isConformingBody (pbody->left, sym, body);
1551 if (astHasSymbol (pbody->left, sym) ||
1552 astHasSymbol (pbody->right, sym))
1557 /*------------------------------------------------------------------*/
1565 if (IS_AST_SYM_VALUE (pbody->left) &&
1566 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1569 if (IS_AST_SYM_VALUE (pbody->right) &&
1570 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1573 return isConformingBody (pbody->left, sym, body) &&
1574 isConformingBody (pbody->right, sym, body);
1581 if (IS_AST_SYM_VALUE (pbody->left) &&
1582 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1584 return isConformingBody (pbody->left, sym, body);
1586 /*------------------------------------------------------------------*/
1598 case SIZEOF: /* evaluate wihout code generation */
1600 return isConformingBody (pbody->left, sym, body) &&
1601 isConformingBody (pbody->right, sym, body);
1603 /*------------------------------------------------------------------*/
1606 /* if left has a pointer & right has loop
1607 control variable then we cannot */
1608 if (astHasPointer (pbody->left) &&
1609 astHasSymbol (pbody->right, sym))
1611 if (astHasVolatile (pbody->left))
1614 if (IS_AST_SYM_VALUE (pbody->left) &&
1615 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1618 if (astHasVolatile (pbody->left))
1621 if (astHasDeref(pbody->right)) return FALSE;
1623 return isConformingBody (pbody->left, sym, body) &&
1624 isConformingBody (pbody->right, sym, body);
1635 assert ("Parser should not have generated this\n");
1637 /*------------------------------------------------------------------*/
1638 /*----------------------------*/
1639 /* comma operator */
1640 /*----------------------------*/
1642 return isConformingBody (pbody->left, sym, body) &&
1643 isConformingBody (pbody->right, sym, body);
1645 /*------------------------------------------------------------------*/
1646 /*----------------------------*/
1648 /*----------------------------*/
1652 /*------------------------------------------------------------------*/
1653 /*----------------------------*/
1654 /* return statement */
1655 /*----------------------------*/
1660 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1665 if (astHasSymbol (pbody->left, sym))
1672 return isConformingBody (pbody->left, sym, body) &&
1673 isConformingBody (pbody->right, sym, body);
1679 /*-----------------------------------------------------------------*/
1680 /* isLoopReversible - takes a for loop as input && returns true */
1681 /* if the for loop is reversible. If yes will set the value of */
1682 /* the loop control var & init value & termination value */
1683 /*-----------------------------------------------------------------*/
1685 isLoopReversible (ast * loop, symbol ** loopCntrl,
1686 ast ** init, ast ** end)
1688 /* if option says don't do it then don't */
1689 if (optimize.noLoopReverse)
1691 /* there are several tests to determine this */
1693 /* for loop has to be of the form
1694 for ( <sym> = <const1> ;
1695 [<sym> < <const2>] ;
1696 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1698 if (!isLoopCountable (AST_FOR (loop, initExpr),
1699 AST_FOR (loop, condExpr),
1700 AST_FOR (loop, loopExpr),
1701 loopCntrl, init, end))
1704 /* now do some serious checking on the body of the loop
1707 return isConformingBody (loop->left, *loopCntrl, loop->left);
1711 /*-----------------------------------------------------------------*/
1712 /* replLoopSym - replace the loop sym by loop sym -1 */
1713 /*-----------------------------------------------------------------*/
1715 replLoopSym (ast * body, symbol * sym)
1718 if (!body || IS_AST_LINK (body))
1721 if (IS_AST_SYM_VALUE (body))
1724 if (isSymbolEqual (AST_SYMBOL (body), sym))
1728 body->opval.op = '-';
1729 body->left = newAst_VALUE (symbolVal (sym));
1730 body->right = newAst_VALUE (constVal ("1"));
1738 replLoopSym (body->left, sym);
1739 replLoopSym (body->right, sym);
1743 /*-----------------------------------------------------------------*/
1744 /* reverseLoop - do the actual loop reversal */
1745 /*-----------------------------------------------------------------*/
1747 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1751 /* create the following tree
1756 if (sym) goto for_continue ;
1759 /* put it together piece by piece */
1760 rloop = newNode (NULLOP,
1761 createIf (newAst_VALUE (symbolVal (sym)),
1763 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1766 newAst_VALUE (symbolVal (sym)),
1769 replLoopSym (loop->left, sym);
1771 rloop = newNode (NULLOP,
1773 newAst_VALUE (symbolVal (sym)),
1774 newNode ('-', end, init)),
1775 createLabel (AST_FOR (loop, continueLabel),
1779 newNode (SUB_ASSIGN,
1780 newAst_VALUE (symbolVal (sym)),
1781 newAst_VALUE (constVal ("1"))),
1784 return decorateType (rloop);
1788 //#define DEMAND_INTEGER_PROMOTION
1790 #ifdef DEMAND_INTEGER_PROMOTION
1792 /*-----------------------------------------------------------------*/
1793 /* walk a tree looking for the leaves. Add a typecast to the given */
1794 /* type to each value leaf node. */
1795 /*-----------------------------------------------------------------*/
1797 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1799 if (!node || IS_CALLOP(node))
1801 /* WTF? We should never get here. */
1805 if (!node->left && !node->right)
1807 /* We're at a leaf; if it's a value, apply the typecast */
1808 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1810 *parentPtr = decorateType (newNode (CAST,
1811 newAst_LINK (copyLinkChain (type)),
1819 pushTypeCastToLeaves (type, node->left, &(node->left));
1823 pushTypeCastToLeaves (type, node->right, &(node->right));
1830 /*-----------------------------------------------------------------*/
1831 /* Given an assignment operation in a tree, determine if the LHS */
1832 /* (the result) has a different (integer) type than the RHS. */
1833 /* If so, walk the RHS and add a typecast to the type of the LHS */
1834 /* to all leaf nodes. */
1835 /*-----------------------------------------------------------------*/
1837 propAsgType (ast * tree)
1839 #ifdef DEMAND_INTEGER_PROMOTION
1840 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
1842 /* Nothing to do here... */
1846 if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
1848 pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
1855 /*-----------------------------------------------------------------*/
1856 /* decorateType - compute type for this tree also does type cheking */
1857 /* this is done bottom up, since type have to flow upwards */
1858 /* it also does constant folding, and paramater checking */
1859 /*-----------------------------------------------------------------*/
1861 decorateType (ast * tree)
1869 /* if already has type then do nothing */
1870 if (tree->decorated)
1873 tree->decorated = 1;
1875 /* print the line */
1876 /* if not block & function */
1877 if (tree->type == EX_OP &&
1878 (tree->opval.op != FUNCTION &&
1879 tree->opval.op != BLOCK &&
1880 tree->opval.op != NULLOP))
1882 filename = tree->filename;
1883 lineno = tree->lineno;
1886 /* if any child is an error | this one is an error do nothing */
1887 if (tree->isError ||
1888 (tree->left && tree->left->isError) ||
1889 (tree->right && tree->right->isError))
1892 /*------------------------------------------------------------------*/
1893 /*----------------------------*/
1894 /* leaf has been reached */
1895 /*----------------------------*/
1896 /* if this is of type value */
1897 /* just get the type */
1898 if (tree->type == EX_VALUE)
1901 if (IS_LITERAL (tree->opval.val->etype))
1904 /* if this is a character array then declare it */
1905 if (IS_ARRAY (tree->opval.val->type))
1906 tree->opval.val = stringToSymbol (tree->opval.val);
1908 /* otherwise just copy the type information */
1909 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1913 if (tree->opval.val->sym)
1915 /* if the undefined flag is set then give error message */
1916 if (tree->opval.val->sym->undefined)
1918 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1920 TTYPE (tree) = TETYPE (tree) =
1921 tree->opval.val->type = tree->opval.val->sym->type =
1922 tree->opval.val->etype = tree->opval.val->sym->etype =
1923 copyLinkChain (INTTYPE);
1928 /* if impilicit i.e. struct/union member then no type */
1929 if (tree->opval.val->sym->implicit)
1930 TTYPE (tree) = TETYPE (tree) = NULL;
1935 /* else copy the type */
1936 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1938 /* and mark it as referenced */
1939 tree->opval.val->sym->isref = 1;
1947 /* if type link for the case of cast */
1948 if (tree->type == EX_LINK)
1950 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1957 dtl = decorateType (tree->left);
1958 dtr = decorateType (tree->right);
1960 /* this is to take care of situations
1961 when the tree gets rewritten */
1962 if (dtl != tree->left)
1964 if (dtr != tree->right)
1968 /* depending on type of operator do */
1970 switch (tree->opval.op)
1972 /*------------------------------------------------------------------*/
1973 /*----------------------------*/
1975 /*----------------------------*/
1978 /* determine which is the array & which the index */
1979 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1982 ast *tempTree = tree->left;
1983 tree->left = tree->right;
1984 tree->right = tempTree;
1987 /* first check if this is a array or a pointer */
1988 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1990 werror (E_NEED_ARRAY_PTR, "[]");
1991 goto errorTreeReturn;
1994 /* check if the type of the idx */
1995 if (!IS_INTEGRAL (RTYPE (tree)))
1997 werror (E_IDX_NOT_INT);
1998 goto errorTreeReturn;
2001 /* if the left is an rvalue then error */
2004 werror (E_LVALUE_REQUIRED, "array access");
2005 goto errorTreeReturn;
2008 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2009 if (IS_PTR(LTYPE(tree))) {
2010 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2014 /*------------------------------------------------------------------*/
2015 /*----------------------------*/
2017 /*----------------------------*/
2019 /* if this is not a structure */
2020 if (!IS_STRUCT (LTYPE (tree)))
2022 werror (E_STRUCT_UNION, ".");
2023 goto errorTreeReturn;
2025 TTYPE (tree) = structElemType (LTYPE (tree),
2026 (tree->right->type == EX_VALUE ?
2027 tree->right->opval.val : NULL));
2028 TETYPE (tree) = getSpec (TTYPE (tree));
2031 /*------------------------------------------------------------------*/
2032 /*----------------------------*/
2033 /* struct/union pointer */
2034 /*----------------------------*/
2036 /* if not pointer to a structure */
2037 if (!IS_PTR (LTYPE (tree)))
2039 werror (E_PTR_REQD);
2040 goto errorTreeReturn;
2043 if (!IS_STRUCT (LTYPE (tree)->next))
2045 werror (E_STRUCT_UNION, "->");
2046 goto errorTreeReturn;
2049 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2050 (tree->right->type == EX_VALUE ?
2051 tree->right->opval.val : NULL));
2052 TETYPE (tree) = getSpec (TTYPE (tree));
2055 /*------------------------------------------------------------------*/
2056 /*----------------------------*/
2057 /* ++/-- operation */
2058 /*----------------------------*/
2059 case INC_OP: /* incerement operator unary so left only */
2062 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2063 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2064 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2065 werror (E_CODE_WRITE, "++/--");
2074 /*------------------------------------------------------------------*/
2075 /*----------------------------*/
2077 /*----------------------------*/
2078 case '&': /* can be unary */
2079 /* if right is NULL then unary operation */
2080 if (tree->right) /* not an unary operation */
2083 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2085 werror (E_BITWISE_OP);
2086 werror (W_CONTINUE, "left & right types are ");
2087 printTypeChain (LTYPE (tree), stderr);
2088 fprintf (stderr, ",");
2089 printTypeChain (RTYPE (tree), stderr);
2090 fprintf (stderr, "\n");
2091 goto errorTreeReturn;
2094 /* if they are both literal */
2095 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2097 tree->type = EX_VALUE;
2098 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2099 valFromType (RETYPE (tree)), '&');
2101 tree->right = tree->left = NULL;
2102 TETYPE (tree) = tree->opval.val->etype;
2103 TTYPE (tree) = tree->opval.val->type;
2107 /* see if this is a GETHBIT operation if yes
2110 ast *otree = optimizeGetHbit (tree);
2113 return decorateType (otree);
2117 // we can't do this because of "(int & 0xff) << 3"
2119 /* if right or left is literal then result of that type */
2120 if (IS_LITERAL (RTYPE (tree)))
2123 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2124 TETYPE (tree) = getSpec (TTYPE (tree));
2125 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2129 if (IS_LITERAL (LTYPE (tree)))
2131 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2132 TETYPE (tree) = getSpec (TTYPE (tree));
2133 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2139 computeType (LTYPE (tree), RTYPE (tree));
2140 TETYPE (tree) = getSpec (TTYPE (tree));
2145 computeType (LTYPE (tree), RTYPE (tree));
2146 TETYPE (tree) = getSpec (TTYPE (tree));
2148 LRVAL (tree) = RRVAL (tree) = 1;
2152 /*------------------------------------------------------------------*/
2153 /*----------------------------*/
2155 /*----------------------------*/
2157 p->class = DECLARATOR;
2158 /* if bit field then error */
2159 if (IS_BITVAR (tree->left->etype))
2161 werror (E_ILLEGAL_ADDR, "addrress of bit variable");
2162 goto errorTreeReturn;
2165 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2167 werror (E_ILLEGAL_ADDR, "address of register variable");
2168 goto errorTreeReturn;
2171 if (IS_FUNC (LTYPE (tree)))
2173 werror (E_ILLEGAL_ADDR, "address of function");
2174 goto errorTreeReturn;
2179 werror (E_LVALUE_REQUIRED, "address of");
2180 goto errorTreeReturn;
2182 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2184 DCL_TYPE (p) = CPOINTER;
2185 DCL_PTR_CONST (p) = port->mem.code_ro;
2187 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2188 DCL_TYPE (p) = FPOINTER;
2189 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2190 DCL_TYPE (p) = PPOINTER;
2191 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2192 DCL_TYPE (p) = IPOINTER;
2193 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2194 DCL_TYPE (p) = EEPPOINTER;
2196 DCL_TYPE (p) = POINTER;
2198 if (IS_AST_SYM_VALUE (tree->left))
2200 AST_SYMBOL (tree->left)->addrtaken = 1;
2201 AST_SYMBOL (tree->left)->allocreq = 1;
2204 p->next = LTYPE (tree);
2206 TETYPE (tree) = getSpec (TTYPE (tree));
2207 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2208 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2213 /*------------------------------------------------------------------*/
2214 /*----------------------------*/
2216 /*----------------------------*/
2218 /* if the rewrite succeeds then don't go any furthur */
2220 ast *wtree = optimizeRRCRLC (tree);
2222 return decorateType (wtree);
2224 /*------------------------------------------------------------------*/
2225 /*----------------------------*/
2227 /*----------------------------*/
2229 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2231 werror (E_BITWISE_OP);
2232 werror (W_CONTINUE, "left & right types are ");
2233 printTypeChain (LTYPE (tree), stderr);
2234 fprintf (stderr, ",");
2235 printTypeChain (RTYPE (tree), stderr);
2236 fprintf (stderr, "\n");
2237 goto errorTreeReturn;
2240 /* if they are both literal then */
2241 /* rewrite the tree */
2242 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2244 tree->type = EX_VALUE;
2245 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2246 valFromType (RETYPE (tree)),
2248 tree->right = tree->left = NULL;
2249 TETYPE (tree) = tree->opval.val->etype;
2250 TTYPE (tree) = tree->opval.val->type;
2253 LRVAL (tree) = RRVAL (tree) = 1;
2254 TETYPE (tree) = getSpec (TTYPE (tree) =
2255 computeType (LTYPE (tree),
2258 /*------------------------------------------------------------------*/
2259 /*----------------------------*/
2261 /*----------------------------*/
2263 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2265 werror (E_INVALID_OP, "divide");
2266 goto errorTreeReturn;
2268 /* if they are both literal then */
2269 /* rewrite the tree */
2270 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2272 tree->type = EX_VALUE;
2273 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2274 valFromType (RETYPE (tree)));
2275 tree->right = tree->left = NULL;
2276 TETYPE (tree) = getSpec (TTYPE (tree) =
2277 tree->opval.val->type);
2280 LRVAL (tree) = RRVAL (tree) = 1;
2281 TETYPE (tree) = getSpec (TTYPE (tree) =
2282 computeType (LTYPE (tree),
2286 /*------------------------------------------------------------------*/
2287 /*----------------------------*/
2289 /*----------------------------*/
2291 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2293 werror (E_BITWISE_OP);
2294 werror (W_CONTINUE, "left & right types are ");
2295 printTypeChain (LTYPE (tree), stderr);
2296 fprintf (stderr, ",");
2297 printTypeChain (RTYPE (tree), stderr);
2298 fprintf (stderr, "\n");
2299 goto errorTreeReturn;
2301 /* if they are both literal then */
2302 /* rewrite the tree */
2303 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2305 tree->type = EX_VALUE;
2306 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2307 valFromType (RETYPE (tree)));
2308 tree->right = tree->left = NULL;
2309 TETYPE (tree) = getSpec (TTYPE (tree) =
2310 tree->opval.val->type);
2313 LRVAL (tree) = RRVAL (tree) = 1;
2314 TETYPE (tree) = getSpec (TTYPE (tree) =
2315 computeType (LTYPE (tree),
2319 /*------------------------------------------------------------------*/
2320 /*----------------------------*/
2321 /* address dereference */
2322 /*----------------------------*/
2323 case '*': /* can be unary : if right is null then unary operation */
2326 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2328 werror (E_PTR_REQD);
2329 goto errorTreeReturn;
2334 werror (E_LVALUE_REQUIRED, "pointer deref");
2335 goto errorTreeReturn;
2337 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2338 LTYPE (tree)->next : NULL);
2339 TETYPE (tree) = getSpec (TTYPE (tree));
2340 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2344 /*------------------------------------------------------------------*/
2345 /*----------------------------*/
2346 /* multiplication */
2347 /*----------------------------*/
2348 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2350 werror (E_INVALID_OP, "multiplication");
2351 goto errorTreeReturn;
2354 /* if they are both literal then */
2355 /* rewrite the tree */
2356 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2358 tree->type = EX_VALUE;
2359 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2360 valFromType (RETYPE (tree)));
2361 tree->right = tree->left = NULL;
2362 TETYPE (tree) = getSpec (TTYPE (tree) =
2363 tree->opval.val->type);
2367 /* if left is a literal exchange left & right */
2368 if (IS_LITERAL (LTYPE (tree)))
2370 ast *tTree = tree->left;
2371 tree->left = tree->right;
2372 tree->right = tTree;
2375 LRVAL (tree) = RRVAL (tree) = 1;
2376 /* promote result to int if left & right are char
2377 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2378 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2379 TETYPE (tree) = getSpec (TTYPE (tree) =
2380 computeType (LTYPE (tree),
2382 SPEC_NOUN(TETYPE(tree)) = V_INT;
2384 TETYPE (tree) = getSpec (TTYPE (tree) =
2385 computeType (LTYPE (tree),
2390 /*------------------------------------------------------------------*/
2391 /*----------------------------*/
2392 /* unary '+' operator */
2393 /*----------------------------*/
2398 if (!IS_INTEGRAL (LTYPE (tree)))
2400 werror (E_UNARY_OP, '+');
2401 goto errorTreeReturn;
2404 /* if left is a literal then do it */
2405 if (IS_LITERAL (LTYPE (tree)))
2407 tree->type = EX_VALUE;
2408 tree->opval.val = valFromType (LETYPE (tree));
2410 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2414 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2418 /*------------------------------------------------------------------*/
2419 /*----------------------------*/
2421 /*----------------------------*/
2423 /* this is not a unary operation */
2424 /* if both pointers then problem */
2425 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2426 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2428 werror (E_PTR_PLUS_PTR);
2429 goto errorTreeReturn;
2432 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2433 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2435 werror (E_PLUS_INVALID, "+");
2436 goto errorTreeReturn;
2439 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2440 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2442 werror (E_PLUS_INVALID, "+");
2443 goto errorTreeReturn;
2445 /* if they are both literal then */
2446 /* rewrite the tree */
2447 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2449 tree->type = EX_VALUE;
2450 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2451 valFromType (RETYPE (tree)));
2452 tree->right = tree->left = NULL;
2453 TETYPE (tree) = getSpec (TTYPE (tree) =
2454 tree->opval.val->type);
2458 /* if the right is a pointer or left is a literal
2459 xchange left & right */
2460 if (IS_ARRAY (RTYPE (tree)) ||
2461 IS_PTR (RTYPE (tree)) ||
2462 IS_LITERAL (LTYPE (tree)))
2464 ast *tTree = tree->left;
2465 tree->left = tree->right;
2466 tree->right = tTree;
2469 LRVAL (tree) = RRVAL (tree) = 1;
2470 /* if the left is a pointer */
2471 if (IS_PTR (LTYPE (tree)))
2472 TETYPE (tree) = getSpec (TTYPE (tree) =
2475 TETYPE (tree) = getSpec (TTYPE (tree) =
2476 computeType (LTYPE (tree),
2480 /*------------------------------------------------------------------*/
2481 /*----------------------------*/
2483 /*----------------------------*/
2484 case '-': /* can be unary */
2485 /* if right is null then unary */
2489 if (!IS_ARITHMETIC (LTYPE (tree)))
2491 werror (E_UNARY_OP, tree->opval.op);
2492 goto errorTreeReturn;
2495 /* if left is a literal then do it */
2496 if (IS_LITERAL (LTYPE (tree)))
2498 tree->type = EX_VALUE;
2499 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2501 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2502 SPEC_USIGN(TETYPE(tree)) = 0;
2506 TTYPE (tree) = LTYPE (tree);
2510 /*------------------------------------------------------------------*/
2511 /*----------------------------*/
2513 /*----------------------------*/
2515 if (!(IS_PTR (LTYPE (tree)) ||
2516 IS_ARRAY (LTYPE (tree)) ||
2517 IS_ARITHMETIC (LTYPE (tree))))
2519 werror (E_PLUS_INVALID, "-");
2520 goto errorTreeReturn;
2523 if (!(IS_PTR (RTYPE (tree)) ||
2524 IS_ARRAY (RTYPE (tree)) ||
2525 IS_ARITHMETIC (RTYPE (tree))))
2527 werror (E_PLUS_INVALID, "-");
2528 goto errorTreeReturn;
2531 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2532 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2533 IS_INTEGRAL (RTYPE (tree))))
2535 werror (E_PLUS_INVALID, "-");
2536 goto errorTreeReturn;
2539 /* if they are both literal then */
2540 /* rewrite the tree */
2541 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2543 tree->type = EX_VALUE;
2544 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2545 valFromType (RETYPE (tree)));
2546 tree->right = tree->left = NULL;
2547 TETYPE (tree) = getSpec (TTYPE (tree) =
2548 tree->opval.val->type);
2552 /* if the left & right are equal then zero */
2553 if (isAstEqual (tree->left, tree->right))
2555 tree->type = EX_VALUE;
2556 tree->left = tree->right = NULL;
2557 tree->opval.val = constVal ("0");
2558 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2562 /* if both of them are pointers or arrays then */
2563 /* the result is going to be an integer */
2564 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2565 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2566 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2568 /* if only the left is a pointer */
2569 /* then result is a pointer */
2570 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2571 TETYPE (tree) = getSpec (TTYPE (tree) =
2574 TETYPE (tree) = getSpec (TTYPE (tree) =
2575 computeType (LTYPE (tree),
2577 LRVAL (tree) = RRVAL (tree) = 1;
2580 /*------------------------------------------------------------------*/
2581 /*----------------------------*/
2583 /*----------------------------*/
2585 /* can be only integral type */
2586 if (!IS_INTEGRAL (LTYPE (tree)))
2588 werror (E_UNARY_OP, tree->opval.op);
2589 goto errorTreeReturn;
2592 /* if left is a literal then do it */
2593 if (IS_LITERAL (LTYPE (tree)))
2595 tree->type = EX_VALUE;
2596 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2598 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2602 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2605 /*------------------------------------------------------------------*/
2606 /*----------------------------*/
2608 /*----------------------------*/
2610 /* can be pointer */
2611 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2612 !IS_PTR (LTYPE (tree)) &&
2613 !IS_ARRAY (LTYPE (tree)))
2615 werror (E_UNARY_OP, tree->opval.op);
2616 goto errorTreeReturn;
2619 /* if left is a literal then do it */
2620 if (IS_LITERAL (LTYPE (tree)))
2622 tree->type = EX_VALUE;
2623 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2625 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2629 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2632 /*------------------------------------------------------------------*/
2633 /*----------------------------*/
2635 /*----------------------------*/
2638 TTYPE (tree) = LTYPE (tree);
2639 TETYPE (tree) = LETYPE (tree);
2643 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2648 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2650 werror (E_SHIFT_OP_INVALID);
2651 werror (W_CONTINUE, "left & right types are ");
2652 printTypeChain (LTYPE (tree), stderr);
2653 fprintf (stderr, ",");
2654 printTypeChain (RTYPE (tree), stderr);
2655 fprintf (stderr, "\n");
2656 goto errorTreeReturn;
2659 /* if they are both literal then */
2660 /* rewrite the tree */
2661 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2663 tree->type = EX_VALUE;
2664 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2665 valFromType (RETYPE (tree)),
2666 (tree->opval.op == LEFT_OP ? 1 : 0));
2667 tree->right = tree->left = NULL;
2668 TETYPE (tree) = getSpec (TTYPE (tree) =
2669 tree->opval.val->type);
2672 /* if only the right side is a literal & we are
2673 shifting more than size of the left operand then zero */
2674 if (IS_LITERAL (RTYPE (tree)) &&
2675 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2676 (getSize (LTYPE (tree)) * 8))
2678 werror (W_SHIFT_CHANGED,
2679 (tree->opval.op == LEFT_OP ? "left" : "right"));
2680 tree->type = EX_VALUE;
2681 tree->left = tree->right = NULL;
2682 tree->opval.val = constVal ("0");
2683 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2686 LRVAL (tree) = RRVAL (tree) = 1;
2687 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2689 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2693 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2697 /*------------------------------------------------------------------*/
2698 /*----------------------------*/
2700 /*----------------------------*/
2701 case CAST: /* change the type */
2702 /* cannot cast to an aggregate type */
2703 if (IS_AGGREGATE (LTYPE (tree)))
2705 werror (E_CAST_ILLEGAL);
2706 goto errorTreeReturn;
2709 /* make sure the type is complete and sane */
2710 checkTypeSanity(LETYPE(tree), "(cast)");
2713 /* if the right is a literal replace the tree */
2714 if (IS_LITERAL (RETYPE (tree))) {
2715 if (!IS_PTR (LTYPE (tree))) {
2716 tree->type = EX_VALUE;
2718 valCastLiteral (LTYPE (tree),
2719 floatFromVal (valFromType (RETYPE (tree))));
2722 TTYPE (tree) = tree->opval.val->type;
2723 tree->values.literalFromCast = 1;
2724 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2725 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2726 sym_link *rest = LTYPE(tree)->next;
2727 werror(W_LITERAL_GENERIC);
2728 TTYPE(tree) = newLink();
2729 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2730 TTYPE(tree)->next = rest;
2731 tree->left->opval.lnk = TTYPE(tree);
2734 TTYPE (tree) = LTYPE (tree);
2738 TTYPE (tree) = LTYPE (tree);
2742 /* if the right is a literal replace the tree */
2743 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2744 tree->type = EX_VALUE;
2746 valCastLiteral (LTYPE (tree),
2747 floatFromVal (valFromType (RETYPE (tree))));
2750 TTYPE (tree) = tree->opval.val->type;
2751 tree->values.literalFromCast = 1;
2753 TTYPE (tree) = LTYPE (tree);
2758 TETYPE (tree) = getSpec (TTYPE (tree));
2762 /*------------------------------------------------------------------*/
2763 /*----------------------------*/
2764 /* logical &&, || */
2765 /*----------------------------*/
2768 /* each must me arithmetic type or be a pointer */
2769 if (!IS_PTR (LTYPE (tree)) &&
2770 !IS_ARRAY (LTYPE (tree)) &&
2771 !IS_INTEGRAL (LTYPE (tree)))
2773 werror (E_COMPARE_OP);
2774 goto errorTreeReturn;
2777 if (!IS_PTR (RTYPE (tree)) &&
2778 !IS_ARRAY (RTYPE (tree)) &&
2779 !IS_INTEGRAL (RTYPE (tree)))
2781 werror (E_COMPARE_OP);
2782 goto errorTreeReturn;
2784 /* if they are both literal then */
2785 /* rewrite the tree */
2786 if (IS_LITERAL (RTYPE (tree)) &&
2787 IS_LITERAL (LTYPE (tree)))
2789 tree->type = EX_VALUE;
2790 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2791 valFromType (RETYPE (tree)),
2793 tree->right = tree->left = NULL;
2794 TETYPE (tree) = getSpec (TTYPE (tree) =
2795 tree->opval.val->type);
2798 LRVAL (tree) = RRVAL (tree) = 1;
2799 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2802 /*------------------------------------------------------------------*/
2803 /*----------------------------*/
2804 /* comparison operators */
2805 /*----------------------------*/
2813 ast *lt = optimizeCompare (tree);
2819 /* if they are pointers they must be castable */
2820 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2822 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2824 werror (E_COMPARE_OP);
2825 fprintf (stderr, "comparing type ");
2826 printTypeChain (LTYPE (tree), stderr);
2827 fprintf (stderr, "to type ");
2828 printTypeChain (RTYPE (tree), stderr);
2829 fprintf (stderr, "\n");
2830 goto errorTreeReturn;
2833 /* else they should be promotable to one another */
2836 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2837 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2839 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2841 werror (E_COMPARE_OP);
2842 fprintf (stderr, "comparing type ");
2843 printTypeChain (LTYPE (tree), stderr);
2844 fprintf (stderr, "to type ");
2845 printTypeChain (RTYPE (tree), stderr);
2846 fprintf (stderr, "\n");
2847 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 = valCompare (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 /*----------------------------*/
2872 /*----------------------------*/
2873 case SIZEOF: /* evaluate wihout code generation */
2874 /* change the type to a integer */
2875 tree->type = EX_VALUE;
2876 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2877 tree->opval.val = constVal (buffer);
2878 tree->right = tree->left = NULL;
2879 TETYPE (tree) = getSpec (TTYPE (tree) =
2880 tree->opval.val->type);
2883 /*------------------------------------------------------------------*/
2884 /*----------------------------*/
2885 /* conditional operator '?' */
2886 /*----------------------------*/
2888 /* the type is value of the colon operator (on the right) */
2889 assert(IS_COLON_OP(tree->right));
2890 /* if already known then replace the tree : optimizer will do it
2891 but faster to do it here */
2892 if (IS_LITERAL (LTYPE(tree))) {
2893 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2894 return tree->right->left ;
2896 return tree->right->right ;
2899 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2900 TETYPE (tree) = getSpec (TTYPE (tree));
2905 /* if they don't match we have a problem */
2906 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2908 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2909 goto errorTreeReturn;
2912 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2913 TETYPE (tree) = getSpec (TTYPE (tree));
2917 /*------------------------------------------------------------------*/
2918 /*----------------------------*/
2919 /* assignment operators */
2920 /*----------------------------*/
2923 /* for these it must be both must be integral */
2924 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2925 !IS_ARITHMETIC (RTYPE (tree)))
2927 werror (E_OPS_INTEGRAL);
2928 goto errorTreeReturn;
2931 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2933 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2934 werror (E_CODE_WRITE, " ");
2938 werror (E_LVALUE_REQUIRED, "*= or /=");
2939 goto errorTreeReturn;
2952 /* for these it must be both must be integral */
2953 if (!IS_INTEGRAL (LTYPE (tree)) ||
2954 !IS_INTEGRAL (RTYPE (tree)))
2956 werror (E_OPS_INTEGRAL);
2957 goto errorTreeReturn;
2960 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2962 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2963 werror (E_CODE_WRITE, " ");
2967 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2968 goto errorTreeReturn;
2976 /*------------------------------------------------------------------*/
2977 /*----------------------------*/
2979 /*----------------------------*/
2981 if (!(IS_PTR (LTYPE (tree)) ||
2982 IS_ARITHMETIC (LTYPE (tree))))
2984 werror (E_PLUS_INVALID, "-=");
2985 goto errorTreeReturn;
2988 if (!(IS_PTR (RTYPE (tree)) ||
2989 IS_ARITHMETIC (RTYPE (tree))))
2991 werror (E_PLUS_INVALID, "-=");
2992 goto errorTreeReturn;
2995 TETYPE (tree) = getSpec (TTYPE (tree) =
2996 computeType (LTYPE (tree),
2999 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3000 werror (E_CODE_WRITE, " ");
3004 werror (E_LVALUE_REQUIRED, "-=");
3005 goto errorTreeReturn;
3013 /*------------------------------------------------------------------*/
3014 /*----------------------------*/
3016 /*----------------------------*/
3018 /* this is not a unary operation */
3019 /* if both pointers then problem */
3020 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3022 werror (E_PTR_PLUS_PTR);
3023 goto errorTreeReturn;
3026 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3028 werror (E_PLUS_INVALID, "+=");
3029 goto errorTreeReturn;
3032 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3034 werror (E_PLUS_INVALID, "+=");
3035 goto errorTreeReturn;
3038 TETYPE (tree) = getSpec (TTYPE (tree) =
3039 computeType (LTYPE (tree),
3042 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3043 werror (E_CODE_WRITE, " ");
3047 werror (E_LVALUE_REQUIRED, "+=");
3048 goto errorTreeReturn;
3051 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3052 tree->opval.op = '=';
3058 /*------------------------------------------------------------------*/
3059 /*----------------------------*/
3060 /* straight assignemnt */
3061 /*----------------------------*/
3063 /* cannot be an aggregate */
3064 if (IS_AGGREGATE (LTYPE (tree)))
3066 werror (E_AGGR_ASSIGN);
3067 goto errorTreeReturn;
3070 /* they should either match or be castable */
3071 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3073 werror (E_TYPE_MISMATCH, "assignment", " ");
3074 fprintf (stderr, "type --> '");
3075 printTypeChain (RTYPE (tree), stderr);
3076 fprintf (stderr, "' ");
3077 fprintf (stderr, "assigned to type --> '");
3078 printTypeChain (LTYPE (tree), stderr);
3079 fprintf (stderr, "'\n");
3080 goto errorTreeReturn;
3083 /* if the left side of the tree is of type void
3084 then report error */
3085 if (IS_VOID (LTYPE (tree)))
3087 werror (E_CAST_ZERO);
3088 fprintf (stderr, "type --> '");
3089 printTypeChain (RTYPE (tree), stderr);
3090 fprintf (stderr, "' ");
3091 fprintf (stderr, "assigned to type --> '");
3092 printTypeChain (LTYPE (tree), stderr);
3093 fprintf (stderr, "'\n");
3096 TETYPE (tree) = getSpec (TTYPE (tree) =
3100 if (!tree->initMode ) {
3101 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3102 werror (E_CODE_WRITE, " ");
3106 werror (E_LVALUE_REQUIRED, "=");
3107 goto errorTreeReturn;
3114 /*------------------------------------------------------------------*/
3115 /*----------------------------*/
3116 /* comma operator */
3117 /*----------------------------*/
3119 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3122 /*------------------------------------------------------------------*/
3123 /*----------------------------*/
3125 /*----------------------------*/
3129 if (processParms (tree->left,
3130 FUNC_ARGS(tree->left->ftype),
3131 tree->right, &parmNumber, TRUE))
3132 goto errorTreeReturn;
3134 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3136 //IFFUNC_ARGS(tree->left->ftype) =
3137 //reverseVal (IFFUNC_ARGS(tree->left->ftype));
3138 reverseParms (tree->right);
3141 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3144 /*------------------------------------------------------------------*/
3145 /*----------------------------*/
3146 /* return statement */
3147 /*----------------------------*/
3152 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3154 werror (W_RETURN_MISMATCH);
3155 fprintf (stderr, "from type '");
3156 printTypeChain (RTYPE(tree), stderr);
3157 fprintf (stderr, "' to type '");
3158 printTypeChain (currFunc->type->next, stderr);
3159 fprintf (stderr, "'\n");
3160 goto errorTreeReturn;
3163 if (IS_VOID (currFunc->type->next)
3165 !IS_VOID (RTYPE (tree)))
3167 werror (E_FUNC_VOID);
3168 goto errorTreeReturn;
3171 /* if there is going to be a casing required then add it */
3172 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3174 #if 0 && defined DEMAND_INTEGER_PROMOTION
3175 if (IS_INTEGRAL (currFunc->type->next))
3177 pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3183 decorateType (newNode (CAST,
3184 newAst_LINK (copyLinkChain (currFunc->type->next)),
3194 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3196 werror (E_VOID_FUNC, currFunc->name);
3197 goto errorTreeReturn;
3200 TTYPE (tree) = TETYPE (tree) = NULL;
3203 /*------------------------------------------------------------------*/
3204 /*----------------------------*/
3205 /* switch statement */
3206 /*----------------------------*/
3208 /* the switch value must be an integer */
3209 if (!IS_INTEGRAL (LTYPE (tree)))
3211 werror (E_SWITCH_NON_INTEGER);
3212 goto errorTreeReturn;
3215 TTYPE (tree) = TETYPE (tree) = NULL;
3218 /*------------------------------------------------------------------*/
3219 /*----------------------------*/
3221 /*----------------------------*/
3223 tree->left = backPatchLabels (tree->left,
3226 TTYPE (tree) = TETYPE (tree) = NULL;
3229 /*------------------------------------------------------------------*/
3230 /*----------------------------*/
3232 /*----------------------------*/
3235 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3236 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3237 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3239 /* if the for loop is reversible then
3240 reverse it otherwise do what we normally
3246 if (isLoopReversible (tree, &sym, &init, &end))
3247 return reverseLoop (tree, sym, init, end);
3249 return decorateType (createFor (AST_FOR (tree, trueLabel),
3250 AST_FOR (tree, continueLabel),
3251 AST_FOR (tree, falseLabel),
3252 AST_FOR (tree, condLabel),
3253 AST_FOR (tree, initExpr),
3254 AST_FOR (tree, condExpr),
3255 AST_FOR (tree, loopExpr),
3259 TTYPE (tree) = TETYPE (tree) = NULL;
3263 /* some error found this tree will be killed */
3265 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3266 tree->opval.op = NULLOP;
3272 /*-----------------------------------------------------------------*/
3273 /* sizeofOp - processes size of operation */
3274 /*-----------------------------------------------------------------*/
3276 sizeofOp (sym_link * type)
3280 /* make sure the type is complete and sane */
3281 checkTypeSanity(type, "(sizeof)");
3283 /* get the size and convert it to character */
3284 sprintf (buff, "%d", getSize (type));
3286 /* now convert into value */
3287 return constVal (buff);
3291 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3292 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3293 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3294 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3295 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3296 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3297 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3299 /*-----------------------------------------------------------------*/
3300 /* backPatchLabels - change and or not operators to flow control */
3301 /*-----------------------------------------------------------------*/
3303 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3309 if (!(IS_ANDORNOT (tree)))
3312 /* if this an and */
3315 static int localLbl = 0;
3318 sprintf (buffer, "_and_%d", localLbl++);
3319 localLabel = newSymbol (buffer, NestLevel);
3321 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3323 /* if left is already a IFX then just change the if true label in that */
3324 if (!IS_IFX (tree->left))
3325 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3327 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3328 /* right is a IFX then just join */
3329 if (IS_IFX (tree->right))
3330 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3332 tree->right = createLabel (localLabel, tree->right);
3333 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3335 return newNode (NULLOP, tree->left, tree->right);
3338 /* if this is an or operation */
3341 static int localLbl = 0;
3344 sprintf (buffer, "_or_%d", localLbl++);
3345 localLabel = newSymbol (buffer, NestLevel);
3347 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3349 /* if left is already a IFX then just change the if true label in that */
3350 if (!IS_IFX (tree->left))
3351 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3353 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3354 /* right is a IFX then just join */
3355 if (IS_IFX (tree->right))
3356 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3358 tree->right = createLabel (localLabel, tree->right);
3359 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3361 return newNode (NULLOP, tree->left, tree->right);
3367 int wasnot = IS_NOT (tree->left);
3368 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3370 /* if the left is already a IFX */
3371 if (!IS_IFX (tree->left))
3372 tree->left = newNode (IFX, tree->left, NULL);
3376 tree->left->trueLabel = trueLabel;
3377 tree->left->falseLabel = falseLabel;
3381 tree->left->trueLabel = falseLabel;
3382 tree->left->falseLabel = trueLabel;
3389 tree->trueLabel = trueLabel;
3390 tree->falseLabel = falseLabel;
3397 /*-----------------------------------------------------------------*/
3398 /* createBlock - create expression tree for block */
3399 /*-----------------------------------------------------------------*/
3401 createBlock (symbol * decl, ast * body)
3405 /* if the block has nothing */
3409 ex = newNode (BLOCK, NULL, body);
3410 ex->values.sym = decl;
3412 ex->right = ex->right;
3418 /*-----------------------------------------------------------------*/
3419 /* createLabel - creates the expression tree for labels */
3420 /*-----------------------------------------------------------------*/
3422 createLabel (symbol * label, ast * stmnt)
3425 char name[SDCC_NAME_MAX + 1];
3428 /* must create fresh symbol if the symbol name */
3429 /* exists in the symbol table, since there can */
3430 /* be a variable with the same name as the labl */
3431 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3432 (csym->level == label->level))
3433 label = newSymbol (label->name, label->level);
3435 /* change the name before putting it in add _ */
3436 sprintf (name, "%s", label->name);
3438 /* put the label in the LabelSymbol table */
3439 /* but first check if a label of the same */
3441 if ((csym = findSym (LabelTab, NULL, name)))
3442 werror (E_DUPLICATE_LABEL, label->name);
3444 addSym (LabelTab, label, name, label->level, 0, 0);
3447 label->key = labelKey++;
3448 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3454 /*-----------------------------------------------------------------*/
3455 /* createCase - generates the parsetree for a case statement */
3456 /*-----------------------------------------------------------------*/
3458 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3460 char caseLbl[SDCC_NAME_MAX + 1];
3464 /* if the switch statement does not exist */
3465 /* then case is out of context */
3468 werror (E_CASE_CONTEXT);
3472 caseVal = decorateType (resolveSymbols (caseVal));
3473 /* if not a constant then error */
3474 if (!IS_LITERAL (caseVal->ftype))
3476 werror (E_CASE_CONSTANT);
3480 /* if not a integer than error */
3481 if (!IS_INTEGRAL (caseVal->ftype))
3483 werror (E_CASE_NON_INTEGER);
3487 /* find the end of the switch values chain */
3488 if (!(val = swStat->values.switchVals.swVals))
3489 swStat->values.switchVals.swVals = caseVal->opval.val;
3492 /* also order the cases according to value */
3494 int cVal = (int) floatFromVal (caseVal->opval.val);
3495 while (val && (int) floatFromVal (val) < cVal)
3501 /* if we reached the end then */
3504 pval->next = caseVal->opval.val;
3508 /* we found a value greater than */
3509 /* the current value we must add this */
3510 /* before the value */
3511 caseVal->opval.val->next = val;
3513 /* if this was the first in chain */
3514 if (swStat->values.switchVals.swVals == val)
3515 swStat->values.switchVals.swVals =
3518 pval->next = caseVal->opval.val;
3523 /* create the case label */
3524 sprintf (caseLbl, "_case_%d_%d",
3525 swStat->values.switchVals.swNum,
3526 (int) floatFromVal (caseVal->opval.val));
3528 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3533 /*-----------------------------------------------------------------*/
3534 /* createDefault - creates the parse tree for the default statement */
3535 /*-----------------------------------------------------------------*/
3537 createDefault (ast * swStat, ast * stmnt)
3539 char defLbl[SDCC_NAME_MAX + 1];
3541 /* if the switch statement does not exist */
3542 /* then case is out of context */
3545 werror (E_CASE_CONTEXT);
3549 /* turn on the default flag */
3550 swStat->values.switchVals.swDefault = 1;
3552 /* create the label */
3553 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3554 return createLabel (newSymbol (defLbl, 0), stmnt);
3557 /*-----------------------------------------------------------------*/
3558 /* createIf - creates the parsetree for the if statement */
3559 /*-----------------------------------------------------------------*/
3561 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3563 static int Lblnum = 0;
3565 symbol *ifTrue, *ifFalse, *ifEnd;
3567 /* if neither exists */
3568 if (!elseBody && !ifBody) {
3569 // if there are no side effects (i++, j() etc)
3570 if (!hasSEFcalls(condAst)) {
3575 /* create the labels */
3576 sprintf (buffer, "_iffalse_%d", Lblnum);
3577 ifFalse = newSymbol (buffer, NestLevel);
3578 /* if no else body then end == false */
3583 sprintf (buffer, "_ifend_%d", Lblnum);
3584 ifEnd = newSymbol (buffer, NestLevel);
3587 sprintf (buffer, "_iftrue_%d", Lblnum);
3588 ifTrue = newSymbol (buffer, NestLevel);
3592 /* attach the ifTrue label to the top of it body */
3593 ifBody = createLabel (ifTrue, ifBody);
3594 /* attach a goto end to the ifBody if else is present */
3597 ifBody = newNode (NULLOP, ifBody,
3599 newAst_VALUE (symbolVal (ifEnd)),
3601 /* put the elseLabel on the else body */
3602 elseBody = createLabel (ifFalse, elseBody);
3603 /* out the end at the end of the body */
3604 elseBody = newNode (NULLOP,
3606 createLabel (ifEnd, NULL));
3610 ifBody = newNode (NULLOP, ifBody,
3611 createLabel (ifFalse, NULL));
3613 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3614 if (IS_IFX (condAst))
3617 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3619 return newNode (NULLOP, ifTree,
3620 newNode (NULLOP, ifBody, elseBody));
3624 /*-----------------------------------------------------------------*/
3625 /* createDo - creates parse tree for do */
3628 /* _docontinue_n: */
3629 /* condition_expression +-> trueLabel -> _dobody_n */
3631 /* +-> falseLabel-> _dobreak_n */
3633 /*-----------------------------------------------------------------*/
3635 createDo (symbol * trueLabel, symbol * continueLabel,
3636 symbol * falseLabel, ast * condAst, ast * doBody)
3641 /* if the body does not exist then it is simple */
3644 condAst = backPatchLabels (condAst, continueLabel, NULL);
3645 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3646 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3647 doTree->trueLabel = continueLabel;
3648 doTree->falseLabel = NULL;
3652 /* otherwise we have a body */
3653 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3655 /* attach the body label to the top */
3656 doBody = createLabel (trueLabel, doBody);
3657 /* attach the continue label to end of body */
3658 doBody = newNode (NULLOP, doBody,
3659 createLabel (continueLabel, NULL));
3661 /* now put the break label at the end */
3662 if (IS_IFX (condAst))
3665 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3667 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3669 /* putting it together */
3670 return newNode (NULLOP, doBody, doTree);
3673 /*-----------------------------------------------------------------*/
3674 /* createFor - creates parse tree for 'for' statement */
3677 /* condExpr +-> trueLabel -> _forbody_n */
3679 /* +-> falseLabel-> _forbreak_n */
3682 /* _forcontinue_n: */
3684 /* goto _forcond_n ; */
3686 /*-----------------------------------------------------------------*/
3688 createFor (symbol * trueLabel, symbol * continueLabel,
3689 symbol * falseLabel, symbol * condLabel,
3690 ast * initExpr, ast * condExpr, ast * loopExpr,
3695 /* if loopexpression not present then we can generate it */
3696 /* the same way as a while */
3698 return newNode (NULLOP, initExpr,
3699 createWhile (trueLabel, continueLabel,
3700 falseLabel, condExpr, forBody));
3701 /* vanilla for statement */
3702 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3704 if (condExpr && !IS_IFX (condExpr))
3705 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3708 /* attach condition label to condition */
3709 condExpr = createLabel (condLabel, condExpr);
3711 /* attach body label to body */
3712 forBody = createLabel (trueLabel, forBody);
3714 /* attach continue to forLoop expression & attach */
3715 /* goto the forcond @ and of loopExpression */
3716 loopExpr = createLabel (continueLabel,
3720 newAst_VALUE (symbolVal (condLabel)),
3722 /* now start putting them together */
3723 forTree = newNode (NULLOP, initExpr, condExpr);
3724 forTree = newNode (NULLOP, forTree, forBody);
3725 forTree = newNode (NULLOP, forTree, loopExpr);
3726 /* finally add the break label */
3727 forTree = newNode (NULLOP, forTree,
3728 createLabel (falseLabel, NULL));
3732 /*-----------------------------------------------------------------*/
3733 /* createWhile - creates parse tree for while statement */
3734 /* the while statement will be created as follows */
3736 /* _while_continue_n: */
3737 /* condition_expression +-> trueLabel -> _while_boby_n */
3739 /* +-> falseLabel -> _while_break_n */
3740 /* _while_body_n: */
3742 /* goto _while_continue_n */
3743 /* _while_break_n: */
3744 /*-----------------------------------------------------------------*/
3746 createWhile (symbol * trueLabel, symbol * continueLabel,
3747 symbol * falseLabel, ast * condExpr, ast * whileBody)
3751 /* put the continue label */
3752 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3753 condExpr = createLabel (continueLabel, condExpr);
3754 condExpr->lineno = 0;
3756 /* put the body label in front of the body */
3757 whileBody = createLabel (trueLabel, whileBody);
3758 whileBody->lineno = 0;
3759 /* put a jump to continue at the end of the body */
3760 /* and put break label at the end of the body */
3761 whileBody = newNode (NULLOP,
3764 newAst_VALUE (symbolVal (continueLabel)),
3765 createLabel (falseLabel, NULL)));
3767 /* put it all together */
3768 if (IS_IFX (condExpr))
3769 whileTree = condExpr;
3772 whileTree = newNode (IFX, condExpr, NULL);
3773 /* put the true & false labels in place */
3774 whileTree->trueLabel = trueLabel;
3775 whileTree->falseLabel = falseLabel;
3778 return newNode (NULLOP, whileTree, whileBody);
3781 /*-----------------------------------------------------------------*/
3782 /* optimizeGetHbit - get highest order bit of the expression */
3783 /*-----------------------------------------------------------------*/
3785 optimizeGetHbit (ast * tree)
3788 /* if this is not a bit and */
3789 if (!IS_BITAND (tree))
3792 /* will look for tree of the form
3793 ( expr >> ((sizeof expr) -1) ) & 1 */
3794 if (!IS_AST_LIT_VALUE (tree->right))
3797 if (AST_LIT_VALUE (tree->right) != 1)
3800 if (!IS_RIGHT_OP (tree->left))
3803 if (!IS_AST_LIT_VALUE (tree->left->right))
3806 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3807 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3810 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3814 /*-----------------------------------------------------------------*/
3815 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3816 /*-----------------------------------------------------------------*/
3818 optimizeRRCRLC (ast * root)
3820 /* will look for trees of the form
3821 (?expr << 1) | (?expr >> 7) or
3822 (?expr >> 7) | (?expr << 1) will make that
3823 into a RLC : operation ..
3825 (?expr >> 1) | (?expr << 7) or
3826 (?expr << 7) | (?expr >> 1) will make that
3827 into a RRC operation
3828 note : by 7 I mean (number of bits required to hold the
3830 /* if the root operations is not a | operation the not */
3831 if (!IS_BITOR (root))
3834 /* I have to think of a better way to match patterns this sucks */
3835 /* that aside let start looking for the first case : I use a the
3836 negative check a lot to improve the efficiency */
3837 /* (?expr << 1) | (?expr >> 7) */
3838 if (IS_LEFT_OP (root->left) &&
3839 IS_RIGHT_OP (root->right))
3842 if (!SPEC_USIGN (TETYPE (root->left->left)))
3845 if (!IS_AST_LIT_VALUE (root->left->right) ||
3846 !IS_AST_LIT_VALUE (root->right->right))
3849 /* make sure it is the same expression */
3850 if (!isAstEqual (root->left->left,
3854 if (AST_LIT_VALUE (root->left->right) != 1)
3857 if (AST_LIT_VALUE (root->right->right) !=
3858 (getSize (TTYPE (root->left->left)) * 8 - 1))
3861 /* whew got the first case : create the AST */
3862 return newNode (RLC, root->left->left, NULL);
3866 /* check for second case */
3867 /* (?expr >> 7) | (?expr << 1) */
3868 if (IS_LEFT_OP (root->right) &&
3869 IS_RIGHT_OP (root->left))
3872 if (!SPEC_USIGN (TETYPE (root->left->left)))
3875 if (!IS_AST_LIT_VALUE (root->left->right) ||
3876 !IS_AST_LIT_VALUE (root->right->right))
3879 /* make sure it is the same symbol */
3880 if (!isAstEqual (root->left->left,
3884 if (AST_LIT_VALUE (root->right->right) != 1)
3887 if (AST_LIT_VALUE (root->left->right) !=
3888 (getSize (TTYPE (root->left->left)) * 8 - 1))
3891 /* whew got the first case : create the AST */
3892 return newNode (RLC, root->left->left, NULL);
3897 /* third case for RRC */
3898 /* (?symbol >> 1) | (?symbol << 7) */
3899 if (IS_LEFT_OP (root->right) &&
3900 IS_RIGHT_OP (root->left))
3903 if (!SPEC_USIGN (TETYPE (root->left->left)))
3906 if (!IS_AST_LIT_VALUE (root->left->right) ||
3907 !IS_AST_LIT_VALUE (root->right->right))
3910 /* make sure it is the same symbol */
3911 if (!isAstEqual (root->left->left,
3915 if (AST_LIT_VALUE (root->left->right) != 1)
3918 if (AST_LIT_VALUE (root->right->right) !=
3919 (getSize (TTYPE (root->left->left)) * 8 - 1))
3922 /* whew got the first case : create the AST */
3923 return newNode (RRC, root->left->left, NULL);
3927 /* fourth and last case for now */
3928 /* (?symbol << 7) | (?symbol >> 1) */
3929 if (IS_RIGHT_OP (root->right) &&
3930 IS_LEFT_OP (root->left))
3933 if (!SPEC_USIGN (TETYPE (root->left->left)))
3936 if (!IS_AST_LIT_VALUE (root->left->right) ||
3937 !IS_AST_LIT_VALUE (root->right->right))
3940 /* make sure it is the same symbol */
3941 if (!isAstEqual (root->left->left,
3945 if (AST_LIT_VALUE (root->right->right) != 1)
3948 if (AST_LIT_VALUE (root->left->right) !=
3949 (getSize (TTYPE (root->left->left)) * 8 - 1))
3952 /* whew got the first case : create the AST */
3953 return newNode (RRC, root->left->left, NULL);
3957 /* not found return root */
3961 /*-----------------------------------------------------------------*/
3962 /* optimizeCompare - otimizes compares for bit variables */
3963 /*-----------------------------------------------------------------*/
3965 optimizeCompare (ast * root)
3967 ast *optExpr = NULL;
3970 unsigned int litValue;
3972 /* if nothing then return nothing */
3976 /* if not a compare op then do leaves */
3977 if (!IS_COMPARE_OP (root))
3979 root->left = optimizeCompare (root->left);
3980 root->right = optimizeCompare (root->right);
3984 /* if left & right are the same then depending
3985 of the operation do */
3986 if (isAstEqual (root->left, root->right))
3988 switch (root->opval.op)
3993 optExpr = newAst_VALUE (constVal ("0"));
3998 optExpr = newAst_VALUE (constVal ("1"));
4002 return decorateType (optExpr);
4005 vleft = (root->left->type == EX_VALUE ?
4006 root->left->opval.val : NULL);
4008 vright = (root->right->type == EX_VALUE ?
4009 root->right->opval.val : NULL);
4011 /* if left is a BITVAR in BITSPACE */
4012 /* and right is a LITERAL then opt- */
4013 /* imize else do nothing */
4014 if (vleft && vright &&
4015 IS_BITVAR (vleft->etype) &&
4016 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4017 IS_LITERAL (vright->etype))
4020 /* if right side > 1 then comparison may never succeed */
4021 if ((litValue = (int) floatFromVal (vright)) > 1)
4023 werror (W_BAD_COMPARE);
4029 switch (root->opval.op)
4031 case '>': /* bit value greater than 1 cannot be */
4032 werror (W_BAD_COMPARE);
4036 case '<': /* bit value < 1 means 0 */
4038 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4041 case LE_OP: /* bit value <= 1 means no check */
4042 optExpr = newAst_VALUE (vright);
4045 case GE_OP: /* bit value >= 1 means only check for = */
4047 optExpr = newAst_VALUE (vleft);
4052 { /* literal is zero */
4053 switch (root->opval.op)
4055 case '<': /* bit value < 0 cannot be */
4056 werror (W_BAD_COMPARE);
4060 case '>': /* bit value > 0 means 1 */
4062 optExpr = newAst_VALUE (vleft);
4065 case LE_OP: /* bit value <= 0 means no check */
4066 case GE_OP: /* bit value >= 0 means no check */
4067 werror (W_BAD_COMPARE);
4071 case EQ_OP: /* bit == 0 means ! of bit */
4072 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4076 return decorateType (resolveSymbols (optExpr));
4077 } /* end-of-if of BITVAR */
4082 /*-----------------------------------------------------------------*/
4083 /* addSymToBlock : adds the symbol to the first block we find */
4084 /*-----------------------------------------------------------------*/
4086 addSymToBlock (symbol * sym, ast * tree)
4088 /* reached end of tree or a leaf */
4089 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4093 if (IS_AST_OP (tree) &&
4094 tree->opval.op == BLOCK)
4097 symbol *lsym = copySymbol (sym);
4099 lsym->next = AST_VALUES (tree, sym);
4100 AST_VALUES (tree, sym) = lsym;
4104 addSymToBlock (sym, tree->left);
4105 addSymToBlock (sym, tree->right);
4108 /*-----------------------------------------------------------------*/
4109 /* processRegParms - do processing for register parameters */
4110 /*-----------------------------------------------------------------*/
4112 processRegParms (value * args, ast * body)
4116 if (IS_REGPARM (args->etype))
4117 addSymToBlock (args->sym, body);
4122 /*-----------------------------------------------------------------*/
4123 /* resetParmKey - resets the operandkeys for the symbols */
4124 /*-----------------------------------------------------------------*/
4125 DEFSETFUNC (resetParmKey)
4136 /*-----------------------------------------------------------------*/
4137 /* createFunction - This is the key node that calls the iCode for */
4138 /* generating the code for a function. Note code */
4139 /* is generated function by function, later when */
4140 /* add inter-procedural analysis this will change */
4141 /*-----------------------------------------------------------------*/
4143 createFunction (symbol * name, ast * body)
4149 iCode *piCode = NULL;
4151 /* if check function return 0 then some problem */
4152 if (checkFunction (name, NULL) == 0)
4155 /* create a dummy block if none exists */
4157 body = newNode (BLOCK, NULL, NULL);
4161 /* check if the function name already in the symbol table */
4162 if ((csym = findSym (SymbolTab, NULL, name->name)))
4165 /* special case for compiler defined functions
4166 we need to add the name to the publics list : this
4167 actually means we are now compiling the compiler
4171 addSet (&publics, name);
4177 allocVariables (name);
4179 name->lastLine = yylineno;
4181 processFuncArgs (currFunc, 0);
4183 /* set the stack pointer */
4184 /* PENDING: check this for the mcs51 */
4185 stackPtr = -port->stack.direction * port->stack.call_overhead;
4186 if (IFFUNC_ISISR (name->type))
4187 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4188 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4189 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4191 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4193 fetype = getSpec (name->type); /* get the specifier for the function */
4194 /* if this is a reentrant function then */
4195 if (IFFUNC_ISREENT (name->type))
4198 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4200 /* do processing for parameters that are passed in registers */
4201 processRegParms (FUNC_ARGS(name->type), body);
4203 /* set the stack pointer */
4207 /* allocate & autoinit the block variables */
4208 processBlockVars (body, &stack, ALLOCATE);
4210 /* save the stack information */
4211 if (options.useXstack)
4212 name->xstack = SPEC_STAK (fetype) = stack;
4214 name->stack = SPEC_STAK (fetype) = stack;
4216 /* name needs to be mangled */
4217 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4219 body = resolveSymbols (body); /* resolve the symbols */
4220 body = decorateType (body); /* propagateType & do semantic checks */
4222 ex = newAst_VALUE (symbolVal (name)); /* create name */
4223 ex = newNode (FUNCTION, ex, body);
4224 ex->values.args = FUNC_ARGS(name->type);
4228 werror (E_FUNC_NO_CODE, name->name);
4232 /* create the node & generate intermediate code */
4234 codeOutFile = code->oFile;
4235 piCode = iCodeFromAst (ex);
4239 werror (E_FUNC_NO_CODE, name->name);
4243 eBBlockFromiCode (piCode);
4245 /* if there are any statics then do them */
4248 GcurMemmap = statsg;
4249 codeOutFile = statsg->oFile;
4250 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4256 /* dealloc the block variables */
4257 processBlockVars (body, &stack, DEALLOCATE);
4258 /* deallocate paramaters */
4259 deallocParms (FUNC_ARGS(name->type));
4261 if (IFFUNC_ISREENT (name->type))
4264 /* we are done freeup memory & cleanup */
4268 FUNC_HASBODY(name->type) = 1;
4269 addSet (&operKeyReset, name);
4270 applyToSet (operKeyReset, resetParmKey);
4273 cdbStructBlock (1, cdbFile);
4275 cleanUpLevel (LabelTab, 0);
4276 cleanUpBlock (StructTab, 1);
4277 cleanUpBlock (TypedefTab, 1);
4279 xstack->syms = NULL;
4280 istack->syms = NULL;
4285 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4286 /*-----------------------------------------------------------------*/
4287 /* ast_print : prints the ast (for debugging purposes) */
4288 /*-----------------------------------------------------------------*/
4290 void ast_print (ast * tree, FILE *outfile, int indent)
4295 /* can print only decorated trees */
4296 if (!tree->decorated) return;
4298 /* if any child is an error | this one is an error do nothing */
4299 if (tree->isError ||
4300 (tree->left && tree->left->isError) ||
4301 (tree->right && tree->right->isError)) {
4302 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4306 /* print the line */
4307 /* if not block & function */
4308 if (tree->type == EX_OP &&
4309 (tree->opval.op != FUNCTION &&
4310 tree->opval.op != BLOCK &&
4311 tree->opval.op != NULLOP)) {
4314 if (tree->opval.op == FUNCTION) {
4315 fprintf(outfile,"FUNCTION (%p) type (",tree);
4316 printTypeChain (tree->ftype,outfile);
4317 fprintf(outfile,")\n");
4318 ast_print(tree->left,outfile,indent+4);
4319 ast_print(tree->right,outfile,indent+4);
4322 if (tree->opval.op == BLOCK) {
4323 symbol *decls = tree->values.sym;
4324 fprintf(outfile,"{\n");
4326 INDENT(indent+4,outfile);
4327 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4328 printTypeChain(decls->type,outfile);
4329 fprintf(outfile,")\n");
4331 decls = decls->next;
4333 ast_print(tree->right,outfile,indent+4);
4334 fprintf(outfile,"}\n");
4337 if (tree->opval.op == NULLOP) {
4338 fprintf(outfile,"\n");
4339 ast_print(tree->left,outfile,indent);
4340 fprintf(outfile,"\n");
4341 ast_print(tree->right,outfile,indent);
4344 INDENT(indent,outfile);
4346 /*------------------------------------------------------------------*/
4347 /*----------------------------*/
4348 /* leaf has been reached */
4349 /*----------------------------*/
4350 /* if this is of type value */
4351 /* just get the type */
4352 if (tree->type == EX_VALUE) {
4354 if (IS_LITERAL (tree->opval.val->etype)) {
4355 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4356 (int) floatFromVal(tree->opval.val),
4357 (int) floatFromVal(tree->opval.val),
4358 floatFromVal(tree->opval.val));
4359 } else if (tree->opval.val->sym) {
4360 /* if the undefined flag is set then give error message */
4361 if (tree->opval.val->sym->undefined) {
4362 fprintf(outfile,"UNDEFINED SYMBOL ");
4364 fprintf(outfile,"SYMBOL ");
4366 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4369 fprintf(outfile," type (");
4370 printTypeChain(tree->ftype,outfile);
4371 fprintf(outfile,")\n");
4373 fprintf(outfile,"\n");
4378 /* if type link for the case of cast */
4379 if (tree->type == EX_LINK) {
4380 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4381 printTypeChain(tree->opval.lnk,outfile);
4382 fprintf(outfile,")\n");
4387 /* depending on type of operator do */
4389 switch (tree->opval.op) {
4390 /*------------------------------------------------------------------*/
4391 /*----------------------------*/
4393 /*----------------------------*/
4395 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4396 printTypeChain(tree->ftype,outfile);
4397 fprintf(outfile,")\n");
4398 ast_print(tree->left,outfile,indent+4);
4399 ast_print(tree->right,outfile,indent+4);
4402 /*------------------------------------------------------------------*/
4403 /*----------------------------*/
4405 /*----------------------------*/
4407 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4408 printTypeChain(tree->ftype,outfile);
4409 fprintf(outfile,")\n");
4410 ast_print(tree->left,outfile,indent+4);
4411 ast_print(tree->right,outfile,indent+4);
4414 /*------------------------------------------------------------------*/
4415 /*----------------------------*/
4416 /* struct/union pointer */
4417 /*----------------------------*/
4419 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4420 printTypeChain(tree->ftype,outfile);
4421 fprintf(outfile,")\n");
4422 ast_print(tree->left,outfile,indent+4);
4423 ast_print(tree->right,outfile,indent+4);
4426 /*------------------------------------------------------------------*/
4427 /*----------------------------*/
4428 /* ++/-- operation */
4429 /*----------------------------*/
4430 case INC_OP: /* incerement operator unary so left only */
4431 fprintf(outfile,"INC_OP (%p) type (",tree);
4432 printTypeChain(tree->ftype,outfile);
4433 fprintf(outfile,")\n");
4434 ast_print(tree->left,outfile,indent+4);
4438 fprintf(outfile,"DEC_OP (%p) type (",tree);
4439 printTypeChain(tree->ftype,outfile);
4440 fprintf(outfile,")\n");
4441 ast_print(tree->left,outfile,indent+4);
4444 /*------------------------------------------------------------------*/
4445 /*----------------------------*/
4447 /*----------------------------*/
4450 fprintf(outfile,"& (%p) type (",tree);
4451 printTypeChain(tree->ftype,outfile);
4452 fprintf(outfile,")\n");
4453 ast_print(tree->left,outfile,indent+4);
4454 ast_print(tree->right,outfile,indent+4);
4456 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+4);
4460 ast_print(tree->right,outfile,indent+4);
4463 /*----------------------------*/
4465 /*----------------------------*/
4467 fprintf(outfile,"OR (%p) type (",tree);
4468 printTypeChain(tree->ftype,outfile);
4469 fprintf(outfile,")\n");
4470 ast_print(tree->left,outfile,indent+4);
4471 ast_print(tree->right,outfile,indent+4);
4473 /*------------------------------------------------------------------*/
4474 /*----------------------------*/
4476 /*----------------------------*/
4478 fprintf(outfile,"XOR (%p) type (",tree);
4479 printTypeChain(tree->ftype,outfile);
4480 fprintf(outfile,")\n");
4481 ast_print(tree->left,outfile,indent+4);
4482 ast_print(tree->right,outfile,indent+4);
4485 /*------------------------------------------------------------------*/
4486 /*----------------------------*/
4488 /*----------------------------*/
4490 fprintf(outfile,"DIV (%p) type (",tree);
4491 printTypeChain(tree->ftype,outfile);
4492 fprintf(outfile,")\n");
4493 ast_print(tree->left,outfile,indent+4);
4494 ast_print(tree->right,outfile,indent+4);
4496 /*------------------------------------------------------------------*/
4497 /*----------------------------*/
4499 /*----------------------------*/
4501 fprintf(outfile,"MOD (%p) type (",tree);
4502 printTypeChain(tree->ftype,outfile);
4503 fprintf(outfile,")\n");
4504 ast_print(tree->left,outfile,indent+4);
4505 ast_print(tree->right,outfile,indent+4);
4508 /*------------------------------------------------------------------*/
4509 /*----------------------------*/
4510 /* address dereference */
4511 /*----------------------------*/
4512 case '*': /* can be unary : if right is null then unary operation */
4514 fprintf(outfile,"DEREF (%p) type (",tree);
4515 printTypeChain(tree->ftype,outfile);
4516 fprintf(outfile,")\n");
4517 ast_print(tree->left,outfile,indent+4);
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4522 /* multiplication */
4523 /*----------------------------*/
4524 fprintf(outfile,"MULT (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+4);
4528 ast_print(tree->right,outfile,indent+4);
4532 /*------------------------------------------------------------------*/
4533 /*----------------------------*/
4534 /* unary '+' operator */
4535 /*----------------------------*/
4539 fprintf(outfile,"UPLUS (%p) type (",tree);
4540 printTypeChain(tree->ftype,outfile);
4541 fprintf(outfile,")\n");
4542 ast_print(tree->left,outfile,indent+4);
4544 /*------------------------------------------------------------------*/
4545 /*----------------------------*/
4547 /*----------------------------*/
4548 fprintf(outfile,"ADD (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+4);
4552 ast_print(tree->right,outfile,indent+4);
4555 /*------------------------------------------------------------------*/
4556 /*----------------------------*/
4558 /*----------------------------*/
4559 case '-': /* can be unary */
4561 fprintf(outfile,"UMINUS (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+4);
4566 /*------------------------------------------------------------------*/
4567 /*----------------------------*/
4569 /*----------------------------*/
4570 fprintf(outfile,"SUB (%p) type (",tree);
4571 printTypeChain(tree->ftype,outfile);
4572 fprintf(outfile,")\n");
4573 ast_print(tree->left,outfile,indent+4);
4574 ast_print(tree->right,outfile,indent+4);
4577 /*------------------------------------------------------------------*/
4578 /*----------------------------*/
4580 /*----------------------------*/
4582 fprintf(outfile,"COMPL (%p) type (",tree);
4583 printTypeChain(tree->ftype,outfile);
4584 fprintf(outfile,")\n");
4585 ast_print(tree->left,outfile,indent+4);
4587 /*------------------------------------------------------------------*/
4588 /*----------------------------*/
4590 /*----------------------------*/
4592 fprintf(outfile,"NOT (%p) type (",tree);
4593 printTypeChain(tree->ftype,outfile);
4594 fprintf(outfile,")\n");
4595 ast_print(tree->left,outfile,indent+4);
4597 /*------------------------------------------------------------------*/
4598 /*----------------------------*/
4600 /*----------------------------*/
4602 fprintf(outfile,"RRC (%p) type (",tree);
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->left,outfile,indent+4);
4609 fprintf(outfile,"RLC (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+4);
4615 fprintf(outfile,"GETHBIT (%p) type (",tree);
4616 printTypeChain(tree->ftype,outfile);
4617 fprintf(outfile,")\n");
4618 ast_print(tree->left,outfile,indent+4);
4621 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4622 printTypeChain(tree->ftype,outfile);
4623 fprintf(outfile,")\n");
4624 ast_print(tree->left,outfile,indent+4);
4625 ast_print(tree->right,outfile,indent+4);
4628 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4629 printTypeChain(tree->ftype,outfile);
4630 fprintf(outfile,")\n");
4631 ast_print(tree->left,outfile,indent+4);
4632 ast_print(tree->right,outfile,indent+4);
4634 /*------------------------------------------------------------------*/
4635 /*----------------------------*/
4637 /*----------------------------*/
4638 case CAST: /* change the type */
4639 fprintf(outfile,"CAST (%p) type (",tree);
4640 printTypeChain(tree->ftype,outfile);
4641 fprintf(outfile,")\n");
4642 ast_print(tree->right,outfile,indent+4);
4646 fprintf(outfile,"ANDAND (%p) type (",tree);
4647 printTypeChain(tree->ftype,outfile);
4648 fprintf(outfile,")\n");
4649 ast_print(tree->left,outfile,indent+4);
4650 ast_print(tree->right,outfile,indent+4);
4653 fprintf(outfile,"OROR (%p) type (",tree);
4654 printTypeChain(tree->ftype,outfile);
4655 fprintf(outfile,")\n");
4656 ast_print(tree->left,outfile,indent+4);
4657 ast_print(tree->right,outfile,indent+4);
4660 /*------------------------------------------------------------------*/
4661 /*----------------------------*/
4662 /* comparison operators */
4663 /*----------------------------*/
4665 fprintf(outfile,"GT(>) (%p) type (",tree);
4666 printTypeChain(tree->ftype,outfile);
4667 fprintf(outfile,")\n");
4668 ast_print(tree->left,outfile,indent+4);
4669 ast_print(tree->right,outfile,indent+4);
4672 fprintf(outfile,"LT(<) (%p) type (",tree);
4673 printTypeChain(tree->ftype,outfile);
4674 fprintf(outfile,")\n");
4675 ast_print(tree->left,outfile,indent+4);
4676 ast_print(tree->right,outfile,indent+4);
4679 fprintf(outfile,"LE(<=) (%p) type (",tree);
4680 printTypeChain(tree->ftype,outfile);
4681 fprintf(outfile,")\n");
4682 ast_print(tree->left,outfile,indent+4);
4683 ast_print(tree->right,outfile,indent+4);
4686 fprintf(outfile,"GE(>=) (%p) type (",tree);
4687 printTypeChain(tree->ftype,outfile);
4688 fprintf(outfile,")\n");
4689 ast_print(tree->left,outfile,indent+4);
4690 ast_print(tree->right,outfile,indent+4);
4693 fprintf(outfile,"EQ(==) (%p) type (",tree);
4694 printTypeChain(tree->ftype,outfile);
4695 fprintf(outfile,")\n");
4696 ast_print(tree->left,outfile,indent+4);
4697 ast_print(tree->right,outfile,indent+4);
4700 fprintf(outfile,"NE(!=) (%p) type (",tree);
4701 printTypeChain(tree->ftype,outfile);
4702 fprintf(outfile,")\n");
4703 ast_print(tree->left,outfile,indent+4);
4704 ast_print(tree->right,outfile,indent+4);
4705 /*------------------------------------------------------------------*/
4706 /*----------------------------*/
4708 /*----------------------------*/
4709 case SIZEOF: /* evaluate wihout code generation */
4710 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4713 /*------------------------------------------------------------------*/
4714 /*----------------------------*/
4715 /* conditional operator '?' */
4716 /*----------------------------*/
4718 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+4);
4722 ast_print(tree->right,outfile,indent+4);
4726 fprintf(outfile,"COLON(:) (%p) type (",tree);
4727 printTypeChain(tree->ftype,outfile);
4728 fprintf(outfile,")\n");
4729 ast_print(tree->left,outfile,indent+4);
4730 ast_print(tree->right,outfile,indent+4);
4733 /*------------------------------------------------------------------*/
4734 /*----------------------------*/
4735 /* assignment operators */
4736 /*----------------------------*/
4738 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4739 printTypeChain(tree->ftype,outfile);
4740 fprintf(outfile,")\n");
4741 ast_print(tree->left,outfile,indent+4);
4742 ast_print(tree->right,outfile,indent+4);
4745 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4746 printTypeChain(tree->ftype,outfile);
4747 fprintf(outfile,")\n");
4748 ast_print(tree->left,outfile,indent+4);
4749 ast_print(tree->right,outfile,indent+4);
4752 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4753 printTypeChain(tree->ftype,outfile);
4754 fprintf(outfile,")\n");
4755 ast_print(tree->left,outfile,indent+4);
4756 ast_print(tree->right,outfile,indent+4);
4759 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4760 printTypeChain(tree->ftype,outfile);
4761 fprintf(outfile,")\n");
4762 ast_print(tree->left,outfile,indent+4);
4763 ast_print(tree->right,outfile,indent+4);
4766 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4767 printTypeChain(tree->ftype,outfile);
4768 fprintf(outfile,")\n");
4769 ast_print(tree->left,outfile,indent+4);
4770 ast_print(tree->right,outfile,indent+4);
4773 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4774 printTypeChain(tree->ftype,outfile);
4775 fprintf(outfile,")\n");
4776 ast_print(tree->left,outfile,indent+4);
4777 ast_print(tree->right,outfile,indent+4);
4780 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4781 printTypeChain(tree->ftype,outfile);
4782 fprintf(outfile,")\n");
4783 ast_print(tree->left,outfile,indent+4);
4784 ast_print(tree->right,outfile,indent+4);
4786 /*------------------------------------------------------------------*/
4787 /*----------------------------*/
4789 /*----------------------------*/
4791 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4792 printTypeChain(tree->ftype,outfile);
4793 fprintf(outfile,")\n");
4794 ast_print(tree->left,outfile,indent+4);
4795 ast_print(tree->right,outfile,indent+4);
4797 /*------------------------------------------------------------------*/
4798 /*----------------------------*/
4800 /*----------------------------*/
4802 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4803 printTypeChain(tree->ftype,outfile);
4804 fprintf(outfile,")\n");
4805 ast_print(tree->left,outfile,indent+4);
4806 ast_print(tree->right,outfile,indent+4);
4808 /*------------------------------------------------------------------*/
4809 /*----------------------------*/
4810 /* straight assignemnt */
4811 /*----------------------------*/
4813 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4814 printTypeChain(tree->ftype,outfile);
4815 fprintf(outfile,")\n");
4816 ast_print(tree->left,outfile,indent+4);
4817 ast_print(tree->right,outfile,indent+4);
4819 /*------------------------------------------------------------------*/
4820 /*----------------------------*/
4821 /* comma operator */
4822 /*----------------------------*/
4824 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4825 printTypeChain(tree->ftype,outfile);
4826 fprintf(outfile,")\n");
4827 ast_print(tree->left,outfile,indent+4);
4828 ast_print(tree->right,outfile,indent+4);
4830 /*------------------------------------------------------------------*/
4831 /*----------------------------*/
4833 /*----------------------------*/
4836 fprintf(outfile,"CALL (%p) type (",tree);
4837 printTypeChain(tree->ftype,outfile);
4838 fprintf(outfile,")\n");
4839 ast_print(tree->left,outfile,indent+4);
4840 ast_print(tree->right,outfile,indent+4);
4843 fprintf(outfile,"PARM ");
4844 ast_print(tree->left,outfile,indent+4);
4845 if (tree->right && !IS_AST_PARAM(tree->right)) {
4846 fprintf(outfile,"PARM ");
4847 ast_print(tree->right,outfile,indent+4);
4850 /*------------------------------------------------------------------*/
4851 /*----------------------------*/
4852 /* return statement */
4853 /*----------------------------*/
4855 fprintf(outfile,"RETURN (%p) type (",tree);
4856 printTypeChain(tree->right->ftype,outfile);
4857 fprintf(outfile,")\n");
4858 ast_print(tree->right,outfile,indent+4);
4860 /*------------------------------------------------------------------*/
4861 /*----------------------------*/
4862 /* label statement */
4863 /*----------------------------*/
4865 fprintf(outfile,"LABEL (%p)",tree);
4866 ast_print(tree->left,outfile,indent+4);
4867 ast_print(tree->right,outfile,indent);
4869 /*------------------------------------------------------------------*/
4870 /*----------------------------*/
4871 /* switch statement */
4872 /*----------------------------*/
4876 fprintf(outfile,"SWITCH (%p) ",tree);
4877 ast_print(tree->left,outfile,0);
4878 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4879 INDENT(indent+4,outfile);
4880 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4881 (int) floatFromVal(val),
4882 tree->values.switchVals.swNum,
4883 (int) floatFromVal(val));
4885 ast_print(tree->right,outfile,indent);
4888 /*------------------------------------------------------------------*/
4889 /*----------------------------*/
4891 /*----------------------------*/
4893 ast_print(tree->left,outfile,indent);
4894 INDENT(indent,outfile);
4895 fprintf(outfile,"IF (%p) \n",tree);
4896 if (tree->trueLabel) {
4897 INDENT(indent,outfile);
4898 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4900 if (tree->falseLabel) {
4901 INDENT(indent,outfile);
4902 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4904 ast_print(tree->right,outfile,indent);
4906 /*------------------------------------------------------------------*/
4907 /*----------------------------*/
4909 /*----------------------------*/
4911 fprintf(outfile,"FOR (%p) \n",tree);
4912 if (AST_FOR( tree, initExpr)) {
4913 INDENT(indent+4,outfile);
4914 fprintf(outfile,"INIT EXPR ");
4915 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4917 if (AST_FOR( tree, condExpr)) {
4918 INDENT(indent+4,outfile);
4919 fprintf(outfile,"COND EXPR ");
4920 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4922 if (AST_FOR( tree, loopExpr)) {
4923 INDENT(indent+4,outfile);
4924 fprintf(outfile,"LOOP EXPR ");
4925 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4927 fprintf(outfile,"FOR LOOP BODY \n");
4928 ast_print(tree->left,outfile,indent+4);
4937 ast_print(t,stdout,1);