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)
3571 /* create the labels */
3572 sprintf (buffer, "_iffalse_%d", Lblnum);
3573 ifFalse = newSymbol (buffer, NestLevel);
3574 /* if no else body then end == false */
3579 sprintf (buffer, "_ifend_%d", Lblnum);
3580 ifEnd = newSymbol (buffer, NestLevel);
3583 sprintf (buffer, "_iftrue_%d", Lblnum);
3584 ifTrue = newSymbol (buffer, NestLevel);
3588 /* attach the ifTrue label to the top of it body */
3589 ifBody = createLabel (ifTrue, ifBody);
3590 /* attach a goto end to the ifBody if else is present */
3593 ifBody = newNode (NULLOP, ifBody,
3595 newAst_VALUE (symbolVal (ifEnd)),
3597 /* put the elseLabel on the else body */
3598 elseBody = createLabel (ifFalse, elseBody);
3599 /* out the end at the end of the body */
3600 elseBody = newNode (NULLOP,
3602 createLabel (ifEnd, NULL));
3606 ifBody = newNode (NULLOP, ifBody,
3607 createLabel (ifFalse, NULL));
3609 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3610 if (IS_IFX (condAst))
3613 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3615 return newNode (NULLOP, ifTree,
3616 newNode (NULLOP, ifBody, elseBody));
3620 /*-----------------------------------------------------------------*/
3621 /* createDo - creates parse tree for do */
3624 /* _docontinue_n: */
3625 /* condition_expression +-> trueLabel -> _dobody_n */
3627 /* +-> falseLabel-> _dobreak_n */
3629 /*-----------------------------------------------------------------*/
3631 createDo (symbol * trueLabel, symbol * continueLabel,
3632 symbol * falseLabel, ast * condAst, ast * doBody)
3637 /* if the body does not exist then it is simple */
3640 condAst = backPatchLabels (condAst, continueLabel, NULL);
3641 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3642 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3643 doTree->trueLabel = continueLabel;
3644 doTree->falseLabel = NULL;
3648 /* otherwise we have a body */
3649 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3651 /* attach the body label to the top */
3652 doBody = createLabel (trueLabel, doBody);
3653 /* attach the continue label to end of body */
3654 doBody = newNode (NULLOP, doBody,
3655 createLabel (continueLabel, NULL));
3657 /* now put the break label at the end */
3658 if (IS_IFX (condAst))
3661 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3663 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3665 /* putting it together */
3666 return newNode (NULLOP, doBody, doTree);
3669 /*-----------------------------------------------------------------*/
3670 /* createFor - creates parse tree for 'for' statement */
3673 /* condExpr +-> trueLabel -> _forbody_n */
3675 /* +-> falseLabel-> _forbreak_n */
3678 /* _forcontinue_n: */
3680 /* goto _forcond_n ; */
3682 /*-----------------------------------------------------------------*/
3684 createFor (symbol * trueLabel, symbol * continueLabel,
3685 symbol * falseLabel, symbol * condLabel,
3686 ast * initExpr, ast * condExpr, ast * loopExpr,
3691 /* if loopexpression not present then we can generate it */
3692 /* the same way as a while */
3694 return newNode (NULLOP, initExpr,
3695 createWhile (trueLabel, continueLabel,
3696 falseLabel, condExpr, forBody));
3697 /* vanilla for statement */
3698 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3700 if (condExpr && !IS_IFX (condExpr))
3701 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3704 /* attach condition label to condition */
3705 condExpr = createLabel (condLabel, condExpr);
3707 /* attach body label to body */
3708 forBody = createLabel (trueLabel, forBody);
3710 /* attach continue to forLoop expression & attach */
3711 /* goto the forcond @ and of loopExpression */
3712 loopExpr = createLabel (continueLabel,
3716 newAst_VALUE (symbolVal (condLabel)),
3718 /* now start putting them together */
3719 forTree = newNode (NULLOP, initExpr, condExpr);
3720 forTree = newNode (NULLOP, forTree, forBody);
3721 forTree = newNode (NULLOP, forTree, loopExpr);
3722 /* finally add the break label */
3723 forTree = newNode (NULLOP, forTree,
3724 createLabel (falseLabel, NULL));
3728 /*-----------------------------------------------------------------*/
3729 /* createWhile - creates parse tree for while statement */
3730 /* the while statement will be created as follows */
3732 /* _while_continue_n: */
3733 /* condition_expression +-> trueLabel -> _while_boby_n */
3735 /* +-> falseLabel -> _while_break_n */
3736 /* _while_body_n: */
3738 /* goto _while_continue_n */
3739 /* _while_break_n: */
3740 /*-----------------------------------------------------------------*/
3742 createWhile (symbol * trueLabel, symbol * continueLabel,
3743 symbol * falseLabel, ast * condExpr, ast * whileBody)
3747 /* put the continue label */
3748 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3749 condExpr = createLabel (continueLabel, condExpr);
3750 condExpr->lineno = 0;
3752 /* put the body label in front of the body */
3753 whileBody = createLabel (trueLabel, whileBody);
3754 whileBody->lineno = 0;
3755 /* put a jump to continue at the end of the body */
3756 /* and put break label at the end of the body */
3757 whileBody = newNode (NULLOP,
3760 newAst_VALUE (symbolVal (continueLabel)),
3761 createLabel (falseLabel, NULL)));
3763 /* put it all together */
3764 if (IS_IFX (condExpr))
3765 whileTree = condExpr;
3768 whileTree = newNode (IFX, condExpr, NULL);
3769 /* put the true & false labels in place */
3770 whileTree->trueLabel = trueLabel;
3771 whileTree->falseLabel = falseLabel;
3774 return newNode (NULLOP, whileTree, whileBody);
3777 /*-----------------------------------------------------------------*/
3778 /* optimizeGetHbit - get highest order bit of the expression */
3779 /*-----------------------------------------------------------------*/
3781 optimizeGetHbit (ast * tree)
3784 /* if this is not a bit and */
3785 if (!IS_BITAND (tree))
3788 /* will look for tree of the form
3789 ( expr >> ((sizeof expr) -1) ) & 1 */
3790 if (!IS_AST_LIT_VALUE (tree->right))
3793 if (AST_LIT_VALUE (tree->right) != 1)
3796 if (!IS_RIGHT_OP (tree->left))
3799 if (!IS_AST_LIT_VALUE (tree->left->right))
3802 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3803 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3806 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3810 /*-----------------------------------------------------------------*/
3811 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3812 /*-----------------------------------------------------------------*/
3814 optimizeRRCRLC (ast * root)
3816 /* will look for trees of the form
3817 (?expr << 1) | (?expr >> 7) or
3818 (?expr >> 7) | (?expr << 1) will make that
3819 into a RLC : operation ..
3821 (?expr >> 1) | (?expr << 7) or
3822 (?expr << 7) | (?expr >> 1) will make that
3823 into a RRC operation
3824 note : by 7 I mean (number of bits required to hold the
3826 /* if the root operations is not a | operation the not */
3827 if (!IS_BITOR (root))
3830 /* I have to think of a better way to match patterns this sucks */
3831 /* that aside let start looking for the first case : I use a the
3832 negative check a lot to improve the efficiency */
3833 /* (?expr << 1) | (?expr >> 7) */
3834 if (IS_LEFT_OP (root->left) &&
3835 IS_RIGHT_OP (root->right))
3838 if (!SPEC_USIGN (TETYPE (root->left->left)))
3841 if (!IS_AST_LIT_VALUE (root->left->right) ||
3842 !IS_AST_LIT_VALUE (root->right->right))
3845 /* make sure it is the same expression */
3846 if (!isAstEqual (root->left->left,
3850 if (AST_LIT_VALUE (root->left->right) != 1)
3853 if (AST_LIT_VALUE (root->right->right) !=
3854 (getSize (TTYPE (root->left->left)) * 8 - 1))
3857 /* whew got the first case : create the AST */
3858 return newNode (RLC, root->left->left, NULL);
3862 /* check for second case */
3863 /* (?expr >> 7) | (?expr << 1) */
3864 if (IS_LEFT_OP (root->right) &&
3865 IS_RIGHT_OP (root->left))
3868 if (!SPEC_USIGN (TETYPE (root->left->left)))
3871 if (!IS_AST_LIT_VALUE (root->left->right) ||
3872 !IS_AST_LIT_VALUE (root->right->right))
3875 /* make sure it is the same symbol */
3876 if (!isAstEqual (root->left->left,
3880 if (AST_LIT_VALUE (root->right->right) != 1)
3883 if (AST_LIT_VALUE (root->left->right) !=
3884 (getSize (TTYPE (root->left->left)) * 8 - 1))
3887 /* whew got the first case : create the AST */
3888 return newNode (RLC, root->left->left, NULL);
3893 /* third case for RRC */
3894 /* (?symbol >> 1) | (?symbol << 7) */
3895 if (IS_LEFT_OP (root->right) &&
3896 IS_RIGHT_OP (root->left))
3899 if (!SPEC_USIGN (TETYPE (root->left->left)))
3902 if (!IS_AST_LIT_VALUE (root->left->right) ||
3903 !IS_AST_LIT_VALUE (root->right->right))
3906 /* make sure it is the same symbol */
3907 if (!isAstEqual (root->left->left,
3911 if (AST_LIT_VALUE (root->left->right) != 1)
3914 if (AST_LIT_VALUE (root->right->right) !=
3915 (getSize (TTYPE (root->left->left)) * 8 - 1))
3918 /* whew got the first case : create the AST */
3919 return newNode (RRC, root->left->left, NULL);
3923 /* fourth and last case for now */
3924 /* (?symbol << 7) | (?symbol >> 1) */
3925 if (IS_RIGHT_OP (root->right) &&
3926 IS_LEFT_OP (root->left))
3929 if (!SPEC_USIGN (TETYPE (root->left->left)))
3932 if (!IS_AST_LIT_VALUE (root->left->right) ||
3933 !IS_AST_LIT_VALUE (root->right->right))
3936 /* make sure it is the same symbol */
3937 if (!isAstEqual (root->left->left,
3941 if (AST_LIT_VALUE (root->right->right) != 1)
3944 if (AST_LIT_VALUE (root->left->right) !=
3945 (getSize (TTYPE (root->left->left)) * 8 - 1))
3948 /* whew got the first case : create the AST */
3949 return newNode (RRC, root->left->left, NULL);
3953 /* not found return root */
3957 /*-----------------------------------------------------------------*/
3958 /* optimizeCompare - otimizes compares for bit variables */
3959 /*-----------------------------------------------------------------*/
3961 optimizeCompare (ast * root)
3963 ast *optExpr = NULL;
3966 unsigned int litValue;
3968 /* if nothing then return nothing */
3972 /* if not a compare op then do leaves */
3973 if (!IS_COMPARE_OP (root))
3975 root->left = optimizeCompare (root->left);
3976 root->right = optimizeCompare (root->right);
3980 /* if left & right are the same then depending
3981 of the operation do */
3982 if (isAstEqual (root->left, root->right))
3984 switch (root->opval.op)
3989 optExpr = newAst_VALUE (constVal ("0"));
3994 optExpr = newAst_VALUE (constVal ("1"));
3998 return decorateType (optExpr);
4001 vleft = (root->left->type == EX_VALUE ?
4002 root->left->opval.val : NULL);
4004 vright = (root->right->type == EX_VALUE ?
4005 root->right->opval.val : NULL);
4007 /* if left is a BITVAR in BITSPACE */
4008 /* and right is a LITERAL then opt- */
4009 /* imize else do nothing */
4010 if (vleft && vright &&
4011 IS_BITVAR (vleft->etype) &&
4012 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4013 IS_LITERAL (vright->etype))
4016 /* if right side > 1 then comparison may never succeed */
4017 if ((litValue = (int) floatFromVal (vright)) > 1)
4019 werror (W_BAD_COMPARE);
4025 switch (root->opval.op)
4027 case '>': /* bit value greater than 1 cannot be */
4028 werror (W_BAD_COMPARE);
4032 case '<': /* bit value < 1 means 0 */
4034 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4037 case LE_OP: /* bit value <= 1 means no check */
4038 optExpr = newAst_VALUE (vright);
4041 case GE_OP: /* bit value >= 1 means only check for = */
4043 optExpr = newAst_VALUE (vleft);
4048 { /* literal is zero */
4049 switch (root->opval.op)
4051 case '<': /* bit value < 0 cannot be */
4052 werror (W_BAD_COMPARE);
4056 case '>': /* bit value > 0 means 1 */
4058 optExpr = newAst_VALUE (vleft);
4061 case LE_OP: /* bit value <= 0 means no check */
4062 case GE_OP: /* bit value >= 0 means no check */
4063 werror (W_BAD_COMPARE);
4067 case EQ_OP: /* bit == 0 means ! of bit */
4068 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4072 return decorateType (resolveSymbols (optExpr));
4073 } /* end-of-if of BITVAR */
4078 /*-----------------------------------------------------------------*/
4079 /* addSymToBlock : adds the symbol to the first block we find */
4080 /*-----------------------------------------------------------------*/
4082 addSymToBlock (symbol * sym, ast * tree)
4084 /* reached end of tree or a leaf */
4085 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4089 if (IS_AST_OP (tree) &&
4090 tree->opval.op == BLOCK)
4093 symbol *lsym = copySymbol (sym);
4095 lsym->next = AST_VALUES (tree, sym);
4096 AST_VALUES (tree, sym) = lsym;
4100 addSymToBlock (sym, tree->left);
4101 addSymToBlock (sym, tree->right);
4104 /*-----------------------------------------------------------------*/
4105 /* processRegParms - do processing for register parameters */
4106 /*-----------------------------------------------------------------*/
4108 processRegParms (value * args, ast * body)
4112 if (IS_REGPARM (args->etype))
4113 addSymToBlock (args->sym, body);
4118 /*-----------------------------------------------------------------*/
4119 /* resetParmKey - resets the operandkeys for the symbols */
4120 /*-----------------------------------------------------------------*/
4121 DEFSETFUNC (resetParmKey)
4132 /*-----------------------------------------------------------------*/
4133 /* createFunction - This is the key node that calls the iCode for */
4134 /* generating the code for a function. Note code */
4135 /* is generated function by function, later when */
4136 /* add inter-procedural analysis this will change */
4137 /*-----------------------------------------------------------------*/
4139 createFunction (symbol * name, ast * body)
4145 iCode *piCode = NULL;
4147 /* if check function return 0 then some problem */
4148 if (checkFunction (name, NULL) == 0)
4151 /* create a dummy block if none exists */
4153 body = newNode (BLOCK, NULL, NULL);
4157 /* check if the function name already in the symbol table */
4158 if ((csym = findSym (SymbolTab, NULL, name->name)))
4161 /* special case for compiler defined functions
4162 we need to add the name to the publics list : this
4163 actually means we are now compiling the compiler
4167 addSet (&publics, name);
4173 allocVariables (name);
4175 name->lastLine = yylineno;
4177 processFuncArgs (currFunc, 0);
4179 /* set the stack pointer */
4180 /* PENDING: check this for the mcs51 */
4181 stackPtr = -port->stack.direction * port->stack.call_overhead;
4182 if (IFFUNC_ISISR (name->type))
4183 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4184 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4185 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4187 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4189 fetype = getSpec (name->type); /* get the specifier for the function */
4190 /* if this is a reentrant function then */
4191 if (IFFUNC_ISREENT (name->type))
4194 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4196 /* do processing for parameters that are passed in registers */
4197 processRegParms (FUNC_ARGS(name->type), body);
4199 /* set the stack pointer */
4203 /* allocate & autoinit the block variables */
4204 processBlockVars (body, &stack, ALLOCATE);
4206 /* save the stack information */
4207 if (options.useXstack)
4208 name->xstack = SPEC_STAK (fetype) = stack;
4210 name->stack = SPEC_STAK (fetype) = stack;
4212 /* name needs to be mangled */
4213 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4215 body = resolveSymbols (body); /* resolve the symbols */
4216 body = decorateType (body); /* propagateType & do semantic checks */
4218 ex = newAst_VALUE (symbolVal (name)); /* create name */
4219 ex = newNode (FUNCTION, ex, body);
4220 ex->values.args = FUNC_ARGS(name->type);
4224 werror (E_FUNC_NO_CODE, name->name);
4228 /* create the node & generate intermediate code */
4230 codeOutFile = code->oFile;
4231 piCode = iCodeFromAst (ex);
4235 werror (E_FUNC_NO_CODE, name->name);
4239 eBBlockFromiCode (piCode);
4241 /* if there are any statics then do them */
4244 GcurMemmap = statsg;
4245 codeOutFile = statsg->oFile;
4246 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4252 /* dealloc the block variables */
4253 processBlockVars (body, &stack, DEALLOCATE);
4254 /* deallocate paramaters */
4255 deallocParms (FUNC_ARGS(name->type));
4257 if (IFFUNC_ISREENT (name->type))
4260 /* we are done freeup memory & cleanup */
4264 FUNC_HASBODY(name->type) = 1;
4265 addSet (&operKeyReset, name);
4266 applyToSet (operKeyReset, resetParmKey);
4269 cdbStructBlock (1, cdbFile);
4271 cleanUpLevel (LabelTab, 0);
4272 cleanUpBlock (StructTab, 1);
4273 cleanUpBlock (TypedefTab, 1);
4275 xstack->syms = NULL;
4276 istack->syms = NULL;
4281 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4282 /*-----------------------------------------------------------------*/
4283 /* ast_print : prints the ast (for debugging purposes) */
4284 /*-----------------------------------------------------------------*/
4286 void ast_print (ast * tree, FILE *outfile, int indent)
4291 /* can print only decorated trees */
4292 if (!tree->decorated) return;
4294 /* if any child is an error | this one is an error do nothing */
4295 if (tree->isError ||
4296 (tree->left && tree->left->isError) ||
4297 (tree->right && tree->right->isError)) {
4298 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4302 /* print the line */
4303 /* if not block & function */
4304 if (tree->type == EX_OP &&
4305 (tree->opval.op != FUNCTION &&
4306 tree->opval.op != BLOCK &&
4307 tree->opval.op != NULLOP)) {
4310 if (tree->opval.op == FUNCTION) {
4311 fprintf(outfile,"FUNCTION (%p) type (",tree);
4312 printTypeChain (tree->ftype,outfile);
4313 fprintf(outfile,")\n");
4314 ast_print(tree->left,outfile,indent+4);
4315 ast_print(tree->right,outfile,indent+4);
4318 if (tree->opval.op == BLOCK) {
4319 symbol *decls = tree->values.sym;
4320 fprintf(outfile,"{\n");
4322 INDENT(indent+4,outfile);
4323 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4324 printTypeChain(decls->type,outfile);
4325 fprintf(outfile,")\n");
4327 decls = decls->next;
4329 ast_print(tree->right,outfile,indent+4);
4330 fprintf(outfile,"}\n");
4333 if (tree->opval.op == NULLOP) {
4334 fprintf(outfile,"\n");
4335 ast_print(tree->left,outfile,indent);
4336 fprintf(outfile,"\n");
4337 ast_print(tree->right,outfile,indent);
4340 INDENT(indent,outfile);
4342 /*------------------------------------------------------------------*/
4343 /*----------------------------*/
4344 /* leaf has been reached */
4345 /*----------------------------*/
4346 /* if this is of type value */
4347 /* just get the type */
4348 if (tree->type == EX_VALUE) {
4350 if (IS_LITERAL (tree->opval.val->etype)) {
4351 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4352 (int) floatFromVal(tree->opval.val),
4353 (int) floatFromVal(tree->opval.val),
4354 floatFromVal(tree->opval.val));
4355 } else if (tree->opval.val->sym) {
4356 /* if the undefined flag is set then give error message */
4357 if (tree->opval.val->sym->undefined) {
4358 fprintf(outfile,"UNDEFINED SYMBOL ");
4360 fprintf(outfile,"SYMBOL ");
4362 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4365 fprintf(outfile," type (");
4366 printTypeChain(tree->ftype,outfile);
4367 fprintf(outfile,")\n");
4369 fprintf(outfile,"\n");
4374 /* if type link for the case of cast */
4375 if (tree->type == EX_LINK) {
4376 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4377 printTypeChain(tree->opval.lnk,outfile);
4378 fprintf(outfile,")\n");
4383 /* depending on type of operator do */
4385 switch (tree->opval.op) {
4386 /*------------------------------------------------------------------*/
4387 /*----------------------------*/
4389 /*----------------------------*/
4391 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4392 printTypeChain(tree->ftype,outfile);
4393 fprintf(outfile,")\n");
4394 ast_print(tree->left,outfile,indent+4);
4395 ast_print(tree->right,outfile,indent+4);
4398 /*------------------------------------------------------------------*/
4399 /*----------------------------*/
4401 /*----------------------------*/
4403 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4404 printTypeChain(tree->ftype,outfile);
4405 fprintf(outfile,")\n");
4406 ast_print(tree->left,outfile,indent+4);
4407 ast_print(tree->right,outfile,indent+4);
4410 /*------------------------------------------------------------------*/
4411 /*----------------------------*/
4412 /* struct/union pointer */
4413 /*----------------------------*/
4415 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4416 printTypeChain(tree->ftype,outfile);
4417 fprintf(outfile,")\n");
4418 ast_print(tree->left,outfile,indent+4);
4419 ast_print(tree->right,outfile,indent+4);
4422 /*------------------------------------------------------------------*/
4423 /*----------------------------*/
4424 /* ++/-- operation */
4425 /*----------------------------*/
4426 case INC_OP: /* incerement operator unary so left only */
4427 fprintf(outfile,"INC_OP (%p) type (",tree);
4428 printTypeChain(tree->ftype,outfile);
4429 fprintf(outfile,")\n");
4430 ast_print(tree->left,outfile,indent+4);
4434 fprintf(outfile,"DEC_OP (%p) type (",tree);
4435 printTypeChain(tree->ftype,outfile);
4436 fprintf(outfile,")\n");
4437 ast_print(tree->left,outfile,indent+4);
4440 /*------------------------------------------------------------------*/
4441 /*----------------------------*/
4443 /*----------------------------*/
4446 fprintf(outfile,"& (%p) type (",tree);
4447 printTypeChain(tree->ftype,outfile);
4448 fprintf(outfile,")\n");
4449 ast_print(tree->left,outfile,indent+4);
4450 ast_print(tree->right,outfile,indent+4);
4452 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4453 printTypeChain(tree->ftype,outfile);
4454 fprintf(outfile,")\n");
4455 ast_print(tree->left,outfile,indent+4);
4456 ast_print(tree->right,outfile,indent+4);
4459 /*----------------------------*/
4461 /*----------------------------*/
4463 fprintf(outfile,"OR (%p) type (",tree);
4464 printTypeChain(tree->ftype,outfile);
4465 fprintf(outfile,")\n");
4466 ast_print(tree->left,outfile,indent+4);
4467 ast_print(tree->right,outfile,indent+4);
4469 /*------------------------------------------------------------------*/
4470 /*----------------------------*/
4472 /*----------------------------*/
4474 fprintf(outfile,"XOR (%p) type (",tree);
4475 printTypeChain(tree->ftype,outfile);
4476 fprintf(outfile,")\n");
4477 ast_print(tree->left,outfile,indent+4);
4478 ast_print(tree->right,outfile,indent+4);
4481 /*------------------------------------------------------------------*/
4482 /*----------------------------*/
4484 /*----------------------------*/
4486 fprintf(outfile,"DIV (%p) type (",tree);
4487 printTypeChain(tree->ftype,outfile);
4488 fprintf(outfile,")\n");
4489 ast_print(tree->left,outfile,indent+4);
4490 ast_print(tree->right,outfile,indent+4);
4492 /*------------------------------------------------------------------*/
4493 /*----------------------------*/
4495 /*----------------------------*/
4497 fprintf(outfile,"MOD (%p) type (",tree);
4498 printTypeChain(tree->ftype,outfile);
4499 fprintf(outfile,")\n");
4500 ast_print(tree->left,outfile,indent+4);
4501 ast_print(tree->right,outfile,indent+4);
4504 /*------------------------------------------------------------------*/
4505 /*----------------------------*/
4506 /* address dereference */
4507 /*----------------------------*/
4508 case '*': /* can be unary : if right is null then unary operation */
4510 fprintf(outfile,"DEREF (%p) type (",tree);
4511 printTypeChain(tree->ftype,outfile);
4512 fprintf(outfile,")\n");
4513 ast_print(tree->left,outfile,indent+4);
4516 /*------------------------------------------------------------------*/
4517 /*----------------------------*/
4518 /* multiplication */
4519 /*----------------------------*/
4520 fprintf(outfile,"MULT (%p) type (",tree);
4521 printTypeChain(tree->ftype,outfile);
4522 fprintf(outfile,")\n");
4523 ast_print(tree->left,outfile,indent+4);
4524 ast_print(tree->right,outfile,indent+4);
4528 /*------------------------------------------------------------------*/
4529 /*----------------------------*/
4530 /* unary '+' operator */
4531 /*----------------------------*/
4535 fprintf(outfile,"UPLUS (%p) type (",tree);
4536 printTypeChain(tree->ftype,outfile);
4537 fprintf(outfile,")\n");
4538 ast_print(tree->left,outfile,indent+4);
4540 /*------------------------------------------------------------------*/
4541 /*----------------------------*/
4543 /*----------------------------*/
4544 fprintf(outfile,"ADD (%p) type (",tree);
4545 printTypeChain(tree->ftype,outfile);
4546 fprintf(outfile,")\n");
4547 ast_print(tree->left,outfile,indent+4);
4548 ast_print(tree->right,outfile,indent+4);
4551 /*------------------------------------------------------------------*/
4552 /*----------------------------*/
4554 /*----------------------------*/
4555 case '-': /* can be unary */
4557 fprintf(outfile,"UMINUS (%p) type (",tree);
4558 printTypeChain(tree->ftype,outfile);
4559 fprintf(outfile,")\n");
4560 ast_print(tree->left,outfile,indent+4);
4562 /*------------------------------------------------------------------*/
4563 /*----------------------------*/
4565 /*----------------------------*/
4566 fprintf(outfile,"SUB (%p) type (",tree);
4567 printTypeChain(tree->ftype,outfile);
4568 fprintf(outfile,")\n");
4569 ast_print(tree->left,outfile,indent+4);
4570 ast_print(tree->right,outfile,indent+4);
4573 /*------------------------------------------------------------------*/
4574 /*----------------------------*/
4576 /*----------------------------*/
4578 fprintf(outfile,"COMPL (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+4);
4583 /*------------------------------------------------------------------*/
4584 /*----------------------------*/
4586 /*----------------------------*/
4588 fprintf(outfile,"NOT (%p) type (",tree);
4589 printTypeChain(tree->ftype,outfile);
4590 fprintf(outfile,")\n");
4591 ast_print(tree->left,outfile,indent+4);
4593 /*------------------------------------------------------------------*/
4594 /*----------------------------*/
4596 /*----------------------------*/
4598 fprintf(outfile,"RRC (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+4);
4605 fprintf(outfile,"RLC (%p) type (",tree);
4606 printTypeChain(tree->ftype,outfile);
4607 fprintf(outfile,")\n");
4608 ast_print(tree->left,outfile,indent+4);
4611 fprintf(outfile,"GETHBIT (%p) type (",tree);
4612 printTypeChain(tree->ftype,outfile);
4613 fprintf(outfile,")\n");
4614 ast_print(tree->left,outfile,indent+4);
4617 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4618 printTypeChain(tree->ftype,outfile);
4619 fprintf(outfile,")\n");
4620 ast_print(tree->left,outfile,indent+4);
4621 ast_print(tree->right,outfile,indent+4);
4624 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+4);
4628 ast_print(tree->right,outfile,indent+4);
4630 /*------------------------------------------------------------------*/
4631 /*----------------------------*/
4633 /*----------------------------*/
4634 case CAST: /* change the type */
4635 fprintf(outfile,"CAST (%p) type (",tree);
4636 printTypeChain(tree->ftype,outfile);
4637 fprintf(outfile,")\n");
4638 ast_print(tree->right,outfile,indent+4);
4642 fprintf(outfile,"ANDAND (%p) type (",tree);
4643 printTypeChain(tree->ftype,outfile);
4644 fprintf(outfile,")\n");
4645 ast_print(tree->left,outfile,indent+4);
4646 ast_print(tree->right,outfile,indent+4);
4649 fprintf(outfile,"OROR (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->left,outfile,indent+4);
4653 ast_print(tree->right,outfile,indent+4);
4656 /*------------------------------------------------------------------*/
4657 /*----------------------------*/
4658 /* comparison operators */
4659 /*----------------------------*/
4661 fprintf(outfile,"GT(>) (%p) type (",tree);
4662 printTypeChain(tree->ftype,outfile);
4663 fprintf(outfile,")\n");
4664 ast_print(tree->left,outfile,indent+4);
4665 ast_print(tree->right,outfile,indent+4);
4668 fprintf(outfile,"LT(<) (%p) type (",tree);
4669 printTypeChain(tree->ftype,outfile);
4670 fprintf(outfile,")\n");
4671 ast_print(tree->left,outfile,indent+4);
4672 ast_print(tree->right,outfile,indent+4);
4675 fprintf(outfile,"LE(<=) (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+4);
4679 ast_print(tree->right,outfile,indent+4);
4682 fprintf(outfile,"GE(>=) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+4);
4686 ast_print(tree->right,outfile,indent+4);
4689 fprintf(outfile,"EQ(==) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+4);
4693 ast_print(tree->right,outfile,indent+4);
4696 fprintf(outfile,"NE(!=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4701 /*------------------------------------------------------------------*/
4702 /*----------------------------*/
4704 /*----------------------------*/
4705 case SIZEOF: /* evaluate wihout code generation */
4706 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4709 /*------------------------------------------------------------------*/
4710 /*----------------------------*/
4711 /* conditional operator '?' */
4712 /*----------------------------*/
4714 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4715 printTypeChain(tree->ftype,outfile);
4716 fprintf(outfile,")\n");
4717 ast_print(tree->left,outfile,indent+4);
4718 ast_print(tree->right,outfile,indent+4);
4722 fprintf(outfile,"COLON(:) (%p) type (",tree);
4723 printTypeChain(tree->ftype,outfile);
4724 fprintf(outfile,")\n");
4725 ast_print(tree->left,outfile,indent+4);
4726 ast_print(tree->right,outfile,indent+4);
4729 /*------------------------------------------------------------------*/
4730 /*----------------------------*/
4731 /* assignment operators */
4732 /*----------------------------*/
4734 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4735 printTypeChain(tree->ftype,outfile);
4736 fprintf(outfile,")\n");
4737 ast_print(tree->left,outfile,indent+4);
4738 ast_print(tree->right,outfile,indent+4);
4741 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4742 printTypeChain(tree->ftype,outfile);
4743 fprintf(outfile,")\n");
4744 ast_print(tree->left,outfile,indent+4);
4745 ast_print(tree->right,outfile,indent+4);
4748 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4749 printTypeChain(tree->ftype,outfile);
4750 fprintf(outfile,")\n");
4751 ast_print(tree->left,outfile,indent+4);
4752 ast_print(tree->right,outfile,indent+4);
4755 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4756 printTypeChain(tree->ftype,outfile);
4757 fprintf(outfile,")\n");
4758 ast_print(tree->left,outfile,indent+4);
4759 ast_print(tree->right,outfile,indent+4);
4762 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4763 printTypeChain(tree->ftype,outfile);
4764 fprintf(outfile,")\n");
4765 ast_print(tree->left,outfile,indent+4);
4766 ast_print(tree->right,outfile,indent+4);
4769 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+4);
4773 ast_print(tree->right,outfile,indent+4);
4776 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+4);
4780 ast_print(tree->right,outfile,indent+4);
4782 /*------------------------------------------------------------------*/
4783 /*----------------------------*/
4785 /*----------------------------*/
4787 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4788 printTypeChain(tree->ftype,outfile);
4789 fprintf(outfile,")\n");
4790 ast_print(tree->left,outfile,indent+4);
4791 ast_print(tree->right,outfile,indent+4);
4793 /*------------------------------------------------------------------*/
4794 /*----------------------------*/
4796 /*----------------------------*/
4798 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->left,outfile,indent+4);
4802 ast_print(tree->right,outfile,indent+4);
4804 /*------------------------------------------------------------------*/
4805 /*----------------------------*/
4806 /* straight assignemnt */
4807 /*----------------------------*/
4809 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4810 printTypeChain(tree->ftype,outfile);
4811 fprintf(outfile,")\n");
4812 ast_print(tree->left,outfile,indent+4);
4813 ast_print(tree->right,outfile,indent+4);
4815 /*------------------------------------------------------------------*/
4816 /*----------------------------*/
4817 /* comma operator */
4818 /*----------------------------*/
4820 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4821 printTypeChain(tree->ftype,outfile);
4822 fprintf(outfile,")\n");
4823 ast_print(tree->left,outfile,indent+4);
4824 ast_print(tree->right,outfile,indent+4);
4826 /*------------------------------------------------------------------*/
4827 /*----------------------------*/
4829 /*----------------------------*/
4832 fprintf(outfile,"CALL (%p) type (",tree);
4833 printTypeChain(tree->ftype,outfile);
4834 fprintf(outfile,")\n");
4835 ast_print(tree->left,outfile,indent+4);
4836 ast_print(tree->right,outfile,indent+4);
4839 fprintf(outfile,"PARM ");
4840 ast_print(tree->left,outfile,indent+4);
4841 if (tree->right && !IS_AST_PARAM(tree->right)) {
4842 fprintf(outfile,"PARM ");
4843 ast_print(tree->right,outfile,indent+4);
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4848 /* return statement */
4849 /*----------------------------*/
4851 fprintf(outfile,"RETURN (%p) type (",tree);
4852 printTypeChain(tree->right->ftype,outfile);
4853 fprintf(outfile,")\n");
4854 ast_print(tree->right,outfile,indent+4);
4856 /*------------------------------------------------------------------*/
4857 /*----------------------------*/
4858 /* label statement */
4859 /*----------------------------*/
4861 fprintf(outfile,"LABEL (%p)",tree);
4862 ast_print(tree->left,outfile,indent+4);
4863 ast_print(tree->right,outfile,indent);
4865 /*------------------------------------------------------------------*/
4866 /*----------------------------*/
4867 /* switch statement */
4868 /*----------------------------*/
4872 fprintf(outfile,"SWITCH (%p) ",tree);
4873 ast_print(tree->left,outfile,0);
4874 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4875 INDENT(indent+4,outfile);
4876 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4877 (int) floatFromVal(val),
4878 tree->values.switchVals.swNum,
4879 (int) floatFromVal(val));
4881 ast_print(tree->right,outfile,indent);
4884 /*------------------------------------------------------------------*/
4885 /*----------------------------*/
4887 /*----------------------------*/
4889 ast_print(tree->left,outfile,indent);
4890 INDENT(indent,outfile);
4891 fprintf(outfile,"IF (%p) \n",tree);
4892 if (tree->trueLabel) {
4893 INDENT(indent,outfile);
4894 fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4896 if (tree->falseLabel) {
4897 INDENT(indent,outfile);
4898 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4900 ast_print(tree->right,outfile,indent);
4902 /*------------------------------------------------------------------*/
4903 /*----------------------------*/
4905 /*----------------------------*/
4907 fprintf(outfile,"FOR (%p) \n",tree);
4908 if (AST_FOR( tree, initExpr)) {
4909 INDENT(indent+4,outfile);
4910 fprintf(outfile,"INIT EXPR ");
4911 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4913 if (AST_FOR( tree, condExpr)) {
4914 INDENT(indent+4,outfile);
4915 fprintf(outfile,"COND EXPR ");
4916 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4918 if (AST_FOR( tree, loopExpr)) {
4919 INDENT(indent+4,outfile);
4920 fprintf(outfile,"LOOP EXPR ");
4921 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4923 fprintf(outfile,"FOR LOOP BODY \n");
4924 ast_print(tree->left,outfile,indent+4);
4933 ast_print(t,stdout,1);