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 *);
58 memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
63 printTypeChain (tree->ftype, stdout);
68 /*-----------------------------------------------------------------*/
69 /* newAst - creates a fresh node for an expression tree */
70 /*-----------------------------------------------------------------*/
73 newAst (int type, void *op)
76 static int oldLineno = 0;
78 ex = Safe_alloc ( sizeof (ast));
81 ex->lineno = (noLineno ? oldLineno : yylineno);
82 ex->filename = currFname;
83 ex->level = NestLevel;
84 ex->block = currBlockno;
85 ex->initMode = inInitMode;
87 /* depending on the type */
91 ex->opval.val = (value *) op;
94 ex->opval.op = (long) op;
97 ex->opval.lnk = (sym_link *) op;
100 ex->opval.stmnt = (unsigned) op;
108 newAst_ (unsigned type)
111 static int oldLineno = 0;
113 ex = Safe_alloc ( sizeof (ast));
116 ex->lineno = (noLineno ? oldLineno : yylineno);
117 ex->filename = currFname;
118 ex->level = NestLevel;
119 ex->block = currBlockno;
120 ex->initMode = inInitMode;
125 newAst_VALUE (value * val)
127 ast *ex = newAst_ (EX_VALUE);
133 newAst_OP (unsigned op)
135 ast *ex = newAst_ (EX_OP);
141 newAst_LINK (sym_link * val)
143 ast *ex = newAst_ (EX_LINK);
149 newAst_STMNT (unsigned val)
151 ast *ex = newAst_ (EX_STMNT);
152 ex->opval.stmnt = val;
156 /*-----------------------------------------------------------------*/
157 /* newNode - creates a new node */
158 /*-----------------------------------------------------------------*/
160 newNode (long op, ast * left, ast * right)
171 /*-----------------------------------------------------------------*/
172 /* newIfxNode - creates a new Ifx Node */
173 /*-----------------------------------------------------------------*/
175 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
179 /* if this is a literal then we already know the result */
180 if (condAst->etype && IS_LITERAL (condAst->etype))
182 /* then depending on the expression value */
183 if (floatFromVal (condAst->opval.val))
184 ifxNode = newNode (GOTO,
185 newAst_VALUE (symbolVal (trueLabel)),
188 ifxNode = newNode (GOTO,
189 newAst_VALUE (symbolVal (falseLabel)),
194 ifxNode = newNode (IFX, condAst, NULL);
195 ifxNode->trueLabel = trueLabel;
196 ifxNode->falseLabel = falseLabel;
202 /*-----------------------------------------------------------------*/
203 /* copyAstValues - copies value portion of ast if needed */
204 /*-----------------------------------------------------------------*/
206 copyAstValues (ast * dest, ast * src)
208 switch (src->opval.op)
211 dest->values.sym = copySymbolChain (src->values.sym);
215 dest->values.switchVals.swVals =
216 copyValue (src->values.switchVals.swVals);
217 dest->values.switchVals.swDefault =
218 src->values.switchVals.swDefault;
219 dest->values.switchVals.swNum =
220 src->values.switchVals.swNum;
224 dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
225 strcpy (dest->values.inlineasm, src->values.inlineasm);
229 dest->values.constlist = copyLiteralList(src->values.constlist);
233 AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
234 AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
235 AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
236 AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
237 AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
238 AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
239 AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
244 /*-----------------------------------------------------------------*/
245 /* copyAst - makes a copy of a given astession */
246 /*-----------------------------------------------------------------*/
255 dest = Safe_alloc ( sizeof (ast));
257 dest->type = src->type;
258 dest->lineno = src->lineno;
259 dest->level = src->level;
260 dest->funcName = src->funcName;
262 /* if this is a leaf */
264 if (src->type == EX_VALUE)
266 dest->opval.val = copyValue (src->opval.val);
271 if (src->type == EX_LINK)
273 dest->opval.lnk = copyLinkChain (src->opval.lnk);
277 dest->opval.op = src->opval.op;
279 /* if this is a node that has special values */
280 copyAstValues (dest, src);
283 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
285 dest->trueLabel = copySymbol (src->trueLabel);
286 dest->falseLabel = copySymbol (src->falseLabel);
287 dest->left = copyAst (src->left);
288 dest->right = copyAst (src->right);
294 /*-----------------------------------------------------------------*/
295 /* hasSEFcalls - returns TRUE if tree has a function call */
296 /*-----------------------------------------------------------------*/
298 hasSEFcalls (ast * tree)
303 if (tree->type == EX_OP &&
304 (tree->opval.op == CALL ||
305 tree->opval.op == PCALL ||
306 tree->opval.op == '=' ||
307 tree->opval.op == INC_OP ||
308 tree->opval.op == DEC_OP))
311 return (hasSEFcalls (tree->left) |
312 hasSEFcalls (tree->right));
315 /*-----------------------------------------------------------------*/
316 /* isAstEqual - compares two asts & returns 1 if they are equal */
317 /*-----------------------------------------------------------------*/
319 isAstEqual (ast * t1, ast * t2)
328 if (t1->type != t2->type)
334 if (t1->opval.op != t2->opval.op)
336 return (isAstEqual (t1->left, t2->left) &&
337 isAstEqual (t1->right, t2->right));
341 if (t1->opval.val->sym)
343 if (!t2->opval.val->sym)
346 return isSymbolEqual (t1->opval.val->sym,
351 if (t2->opval.val->sym)
354 return (floatFromVal (t1->opval.val) ==
355 floatFromVal (t2->opval.val));
359 /* only compare these two types */
367 /*-----------------------------------------------------------------*/
368 /* resolveSymbols - resolve symbols from the symbol table */
369 /*-----------------------------------------------------------------*/
371 resolveSymbols (ast * tree)
373 /* walk the entire tree and check for values */
374 /* with symbols if we find one then replace */
375 /* symbol with that from the symbol table */
381 /* if not block & function */
382 if (tree->type == EX_OP &&
383 (tree->opval.op != FUNCTION &&
384 tree->opval.op != BLOCK &&
385 tree->opval.op != NULLOP))
387 filename = tree->filename;
388 lineno = tree->lineno;
391 /* make sure we resolve the true & false labels for ifx */
392 if (tree->type == EX_OP && tree->opval.op == IFX)
398 if ((csym = findSym (LabelTab, tree->trueLabel,
399 tree->trueLabel->name)))
400 tree->trueLabel = csym;
402 werror (E_LABEL_UNDEF, tree->trueLabel->name);
405 if (tree->falseLabel)
407 if ((csym = findSym (LabelTab,
409 tree->falseLabel->name)))
410 tree->falseLabel = csym;
412 werror (E_LABEL_UNDEF, tree->falseLabel->name);
417 /* if this is a label resolve it from the labelTab */
418 if (IS_AST_VALUE (tree) &&
419 tree->opval.val->sym &&
420 tree->opval.val->sym->islbl)
423 symbol *csym = findSym (LabelTab, tree->opval.val->sym,
424 tree->opval.val->sym->name);
427 werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
429 tree->opval.val->sym = csym;
431 goto resolveChildren;
434 /* do only for leafs */
435 if (IS_AST_VALUE (tree) &&
436 tree->opval.val->sym &&
437 !tree->opval.val->sym->implicit)
440 symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
442 /* if found in the symbol table & they r not the same */
443 if (csym && tree->opval.val->sym != csym)
445 tree->opval.val->sym = csym;
446 tree->opval.val->type = csym->type;
447 tree->opval.val->etype = csym->etype;
450 /* if not found in the symbol table */
451 /* mark it as undefined assume it is */
452 /* an integer in data space */
453 if (!csym && !tree->opval.val->sym->implicit)
456 /* if this is a function name then */
457 /* mark it as returning an int */
460 tree->opval.val->sym->type = newLink ();
461 DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
462 tree->opval.val->sym->type->next =
463 tree->opval.val->sym->etype = newIntLink ();
464 tree->opval.val->etype = tree->opval.val->etype;
465 tree->opval.val->type = tree->opval.val->sym->type;
466 werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
467 allocVariables (tree->opval.val->sym);
471 tree->opval.val->sym->undefined = 1;
472 tree->opval.val->type =
473 tree->opval.val->etype = newIntLink ();
474 tree->opval.val->sym->type =
475 tree->opval.val->sym->etype = newIntLink ();
481 resolveSymbols (tree->left);
482 resolveSymbols (tree->right);
487 /*-----------------------------------------------------------------*/
488 /* setAstLineno - walks a ast tree & sets the line number */
489 /*-----------------------------------------------------------------*/
491 setAstLineno (ast * tree, int lineno)
496 tree->lineno = lineno;
497 setAstLineno (tree->left, lineno);
498 setAstLineno (tree->right, lineno);
503 /* this functions seems to be superfluous?! kmh */
505 /*-----------------------------------------------------------------*/
506 /* resolveFromTable - will return the symbal table value */
507 /*-----------------------------------------------------------------*/
509 resolveFromTable (value * val)
516 csym = findSymWithLevel (SymbolTab, val->sym);
518 /* if found in the symbol table & they r not the same */
519 if (csym && val->sym != csym &&
520 csym->level == val->sym->level &&
526 val->type = csym->type;
527 val->etype = csym->etype;
534 /*-----------------------------------------------------------------*/
535 /* funcOfType :- function of type with name */
536 /*-----------------------------------------------------------------*/
538 funcOfType (char *name, sym_link * type, sym_link * argType,
542 /* create the symbol */
543 sym = newSymbol (name, 0);
545 /* setup return value */
546 sym->type = newLink ();
547 DCL_TYPE (sym->type) = FUNCTION;
548 sym->type->next = copyLinkChain (type);
549 sym->etype = getSpec (sym->type);
550 FUNC_ISREENT(sym->type) = rent;
552 /* if arguments required */
556 args = FUNC_ARGS(sym->type) = newValue ();
560 args->type = copyLinkChain (argType);
561 args->etype = getSpec (args->type);
564 args = args->next = newValue ();
571 allocVariables (sym);
576 /*-----------------------------------------------------------------*/
577 /* reverseParms - will reverse a parameter tree */
578 /*-----------------------------------------------------------------*/
580 reverseParms (ast * ptree)
586 /* top down if we find a nonParm tree then quit */
587 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
590 ptree->left = ptree->right;
591 ptree->right = ttree;
592 reverseParms (ptree->left);
593 reverseParms (ptree->right);
599 /*-----------------------------------------------------------------*/
600 /* processParms - makes sure the parameters are okay and do some */
601 /* processing with them */
602 /*-----------------------------------------------------------------*/
604 processParms (ast * func,
607 int *parmNumber, // unused, although updated
608 bool rightmost) // double checked?
610 /* if none of them exist */
611 if (!defParm && !actParm)
615 if (getenv("DEBUG_SANITY")) {
616 fprintf (stderr, "processParms: %s ", defParm->name);
618 /* make sure the type is complete and sane */
619 checkTypeSanity(defParm->etype, defParm->name);
622 /* if the function is being called via a pointer & */
623 /* it has not been defined a reentrant then we cannot */
624 /* have parameters */
625 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
627 werror (W_NONRENT_ARGS);
631 /* if defined parameters ended but actual parameters */
632 /* exist and this is not defined as a variable arg */
633 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
635 werror (E_TOO_MANY_PARMS);
639 /* if defined parameters present but no actual parameters */
640 if (defParm && !actParm)
642 werror (E_TOO_FEW_PARMS);
646 /* If this is a varargs function... */
647 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
652 if (IS_CAST_OP (actParm)
653 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
655 /* Parameter was explicitly typecast; don't touch it. */
659 /* The ternary ('?') operator is weird: the ftype of the
660 * operator is the type of the condition, but it will return a
661 * (possibly) different type.
663 if (IS_TERNARY_OP(actParm))
665 assert(IS_COLON_OP(actParm->right));
666 assert(actParm->right->left);
667 ftype = actParm->right->left->ftype;
671 ftype = actParm->ftype;
674 /* If it's a small integer, upcast to int. */
675 if (IS_INTEGRAL (ftype)
676 && (getSize (ftype) < (unsigned) INTSIZE))
678 newType = newAst_LINK(INTTYPE);
681 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
683 newType = newAst_LINK (copyLinkChain(ftype));
684 DCL_TYPE (newType->opval.lnk) = GPOINTER;
687 if (IS_AGGREGATE (ftype))
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 printFromToType (actParm->ftype, defParm->type);
746 /* if the parameter is castable then add the cast */
747 if (compareType (defParm->type, actParm->ftype) < 0)
749 ast *pTree = resolveSymbols (copyAst (actParm));
751 /* now change the current one to a cast */
752 actParm->type = EX_OP;
753 actParm->opval.op = CAST;
754 actParm->left = newAst_LINK (defParm->type);
755 actParm->right = pTree;
756 actParm->etype = defParm->etype;
757 actParm->ftype = defParm->type;
760 /* make a copy and change the regparm type to the defined parm */
761 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
762 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
766 /*-----------------------------------------------------------------*/
767 /* createIvalType - generates ival for basic types */
768 /*-----------------------------------------------------------------*/
770 createIvalType (ast * sym, sym_link * type, initList * ilist)
774 /* if initList is deep */
775 if (ilist->type == INIT_DEEP)
776 ilist = ilist->init.deep;
778 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
779 return decorateType (newNode ('=', sym, iExpr));
782 /*-----------------------------------------------------------------*/
783 /* createIvalStruct - generates initial value for structures */
784 /*-----------------------------------------------------------------*/
786 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
793 sflds = SPEC_STRUCT (type)->fields;
794 if (ilist->type != INIT_DEEP)
796 werror (E_INIT_STRUCT, "");
800 iloop = ilist->init.deep;
802 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
804 /* if we have come to end */
808 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
809 lAst = decorateType (resolveSymbols (lAst));
810 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
816 /*-----------------------------------------------------------------*/
817 /* createIvalArray - generates code for array initialization */
818 /*-----------------------------------------------------------------*/
820 createIvalArray (ast * sym, sym_link * type, initList * ilist)
824 int lcnt = 0, size = 0;
825 literalList *literalL;
827 /* take care of the special case */
828 /* array of characters can be init */
830 if (IS_CHAR (type->next))
831 if ((rast = createIvalCharPtr (sym,
833 decorateType (resolveSymbols (list2expr (ilist))))))
835 return decorateType (resolveSymbols (rast));
837 /* not the special case */
838 if (ilist->type != INIT_DEEP)
840 werror (E_INIT_STRUCT, "");
844 iloop = ilist->init.deep;
845 lcnt = DCL_ELEM (type);
847 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
851 aSym = decorateType (resolveSymbols(sym));
853 rast = newNode(ARRAYINIT, aSym, NULL);
854 rast->values.constlist = literalL;
856 // Make sure size is set to length of initializer list.
863 if (lcnt && size > lcnt)
865 // Array size was specified, and we have more initializers than needed.
866 char *name=sym->opval.val->sym->name;
867 int lineno=sym->opval.val->sym->lineDef;
869 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
878 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
879 aSym = decorateType (resolveSymbols (aSym));
880 rast = createIval (aSym, type->next, iloop, rast);
881 iloop = (iloop ? iloop->next : NULL);
887 /* no of elements given and we */
888 /* have generated for all of them */
891 // there has to be a better way
892 char *name=sym->opval.val->sym->name;
893 int lineno=sym->opval.val->sym->lineDef;
894 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
901 /* if we have not been given a size */
902 if (!DCL_ELEM (type))
904 DCL_ELEM (type) = size;
907 return decorateType (resolveSymbols (rast));
911 /*-----------------------------------------------------------------*/
912 /* createIvalCharPtr - generates initial values for char pointers */
913 /*-----------------------------------------------------------------*/
915 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
919 /* if this is a pointer & right is a literal array then */
920 /* just assignment will do */
921 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
922 SPEC_SCLS (iexpr->etype) == S_CODE)
923 && IS_ARRAY (iexpr->ftype)))
924 return newNode ('=', sym, iexpr);
926 /* left side is an array so we have to assign each */
928 if ((IS_LITERAL (iexpr->etype) ||
929 SPEC_SCLS (iexpr->etype) == S_CODE)
930 && IS_ARRAY (iexpr->ftype))
932 /* for each character generate an assignment */
933 /* to the array element */
934 char *s = SPEC_CVAL (iexpr->etype).v_char;
939 rast = newNode (NULLOP,
943 newAst_VALUE (valueFromLit ((float) i))),
944 newAst_VALUE (valueFromLit (*s))));
948 rast = newNode (NULLOP,
952 newAst_VALUE (valueFromLit ((float) i))),
953 newAst_VALUE (valueFromLit (*s))));
954 return decorateType (resolveSymbols (rast));
960 /*-----------------------------------------------------------------*/
961 /* createIvalPtr - generates initial value for pointers */
962 /*-----------------------------------------------------------------*/
964 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
970 if (ilist->type == INIT_DEEP)
971 ilist = ilist->init.deep;
973 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
975 /* if character pointer */
976 if (IS_CHAR (type->next))
977 if ((rast = createIvalCharPtr (sym, type, iexpr)))
980 return newNode ('=', sym, iexpr);
983 /*-----------------------------------------------------------------*/
984 /* createIval - generates code for initial value */
985 /*-----------------------------------------------------------------*/
987 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
994 /* if structure then */
995 if (IS_STRUCT (type))
996 rast = createIvalStruct (sym, type, ilist);
998 /* if this is a pointer */
1000 rast = createIvalPtr (sym, type, ilist);
1002 /* if this is an array */
1003 if (IS_ARRAY (type))
1004 rast = createIvalArray (sym, type, ilist);
1006 /* if type is SPECIFIER */
1008 rast = createIvalType (sym, type, ilist);
1011 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1013 return decorateType (resolveSymbols (rast));
1016 /*-----------------------------------------------------------------*/
1017 /* initAggregates - initialises aggregate variables with initv */
1018 /*-----------------------------------------------------------------*/
1020 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1022 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1026 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1028 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1029 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1030 "with -mmcs51 and --model-large");
1034 if (SPEC_OCLS(sym->etype)==xdata &&
1035 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1038 newSym=copySymbol (sym);
1039 SPEC_OCLS(newSym->etype)=code;
1040 sprintf (newSym->name, "%s_init__", sym->name);
1041 sprintf (newSym->rname,"%s_init__", sym->rname);
1042 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1044 // emit it in the static segment
1045 addSet(&statsg->syms, newSym);
1047 // now memcpy() the entire array from cseg
1048 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1049 newAst_VALUE (symbolVal (sym)),
1050 newAst_VALUE (symbolVal (newSym)));
1051 return decorateType(resolveSymbols(ast));
1055 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1058 /*-----------------------------------------------------------------*/
1059 /* gatherAutoInit - creates assignment expressions for initial */
1061 /*-----------------------------------------------------------------*/
1063 gatherAutoInit (symbol * autoChain)
1070 for (sym = autoChain; sym; sym = sym->next)
1073 /* resolve the symbols in the ival */
1075 resolveIvalSym (sym->ival);
1077 /* if this is a static variable & has an */
1078 /* initial value the code needs to be lifted */
1079 /* here to the main portion since they can be */
1080 /* initialised only once at the start */
1081 if (IS_STATIC (sym->etype) && sym->ival &&
1082 SPEC_SCLS (sym->etype) != S_CODE)
1086 // this can only be a constant
1087 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1088 werror (E_CONST_EXPECTED);
1091 /* insert the symbol into the symbol table */
1092 /* with level = 0 & name = rname */
1093 newSym = copySymbol (sym);
1094 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1096 /* now lift the code to main */
1097 if (IS_AGGREGATE (sym->type))
1098 work = initAggregates (sym, sym->ival, NULL);
1100 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1101 list2expr (sym->ival));
1103 setAstLineno (work, sym->lineDef);
1107 staticAutos = newNode (NULLOP, staticAutos, work);
1114 /* if there is an initial value */
1115 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1117 if (IS_AGGREGATE (sym->type))
1118 work = initAggregates (sym, sym->ival, NULL);
1120 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1121 list2expr (sym->ival));
1123 setAstLineno (work, sym->lineDef);
1126 init = newNode (NULLOP, init, work);
1135 /*-----------------------------------------------------------------*/
1136 /* stringToSymbol - creates a symbol from a literal string */
1137 /*-----------------------------------------------------------------*/
1139 stringToSymbol (value * val)
1141 char name[SDCC_NAME_MAX + 1];
1142 static int charLbl = 0;
1145 sprintf (name, "_str_%d", charLbl++);
1146 sym = newSymbol (name, 0); /* make it @ level 0 */
1147 strcpy (sym->rname, name);
1149 /* copy the type from the value passed */
1150 sym->type = copyLinkChain (val->type);
1151 sym->etype = getSpec (sym->type);
1152 /* change to storage class & output class */
1153 SPEC_SCLS (sym->etype) = S_CODE;
1154 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1155 SPEC_STAT (sym->etype) = 1;
1156 /* make the level & block = 0 */
1157 sym->block = sym->level = 0;
1159 /* create an ival */
1160 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1165 allocVariables (sym);
1168 return symbolVal (sym);
1172 /*-----------------------------------------------------------------*/
1173 /* processBlockVars - will go thru the ast looking for block if */
1174 /* a block is found then will allocate the syms */
1175 /* will also gather the auto inits present */
1176 /*-----------------------------------------------------------------*/
1178 processBlockVars (ast * tree, int *stack, int action)
1183 /* if this is a block */
1184 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1188 if (action == ALLOCATE)
1190 *stack += allocVariables (tree->values.sym);
1191 autoInit = gatherAutoInit (tree->values.sym);
1193 /* if there are auto inits then do them */
1195 tree->left = newNode (NULLOP, autoInit, tree->left);
1197 else /* action is deallocate */
1198 deallocLocal (tree->values.sym);
1201 processBlockVars (tree->left, stack, action);
1202 processBlockVars (tree->right, stack, action);
1206 /*-----------------------------------------------------------------*/
1207 /* constExprValue - returns the value of a constant expression */
1208 /* or NULL if it is not a constant expression */
1209 /*-----------------------------------------------------------------*/
1211 constExprValue (ast * cexpr, int check)
1213 cexpr = decorateType (resolveSymbols (cexpr));
1215 /* if this is not a constant then */
1216 if (!IS_LITERAL (cexpr->ftype))
1218 /* then check if this is a literal array
1220 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1221 SPEC_CVAL (cexpr->etype).v_char &&
1222 IS_ARRAY (cexpr->ftype))
1224 value *val = valFromType (cexpr->ftype);
1225 SPEC_SCLS (val->etype) = S_LITERAL;
1226 val->sym = cexpr->opval.val->sym;
1227 val->sym->type = copyLinkChain (cexpr->ftype);
1228 val->sym->etype = getSpec (val->sym->type);
1229 strcpy (val->name, cexpr->opval.val->sym->rname);
1233 /* if we are casting a literal value then */
1234 if (IS_AST_OP (cexpr) &&
1235 cexpr->opval.op == CAST &&
1236 IS_LITERAL (cexpr->left->ftype))
1237 return valCastLiteral (cexpr->ftype,
1238 floatFromVal (cexpr->left->opval.val));
1240 if (IS_AST_VALUE (cexpr))
1241 return cexpr->opval.val;
1244 werror (E_CONST_EXPECTED, "found expression");
1249 /* return the value */
1250 return cexpr->opval.val;
1254 /*-----------------------------------------------------------------*/
1255 /* isLabelInAst - will return true if a given label is found */
1256 /*-----------------------------------------------------------------*/
1258 isLabelInAst (symbol * label, ast * tree)
1260 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1263 if (IS_AST_OP (tree) &&
1264 tree->opval.op == LABEL &&
1265 isSymbolEqual (AST_SYMBOL (tree->left), label))
1268 return isLabelInAst (label, tree->right) &&
1269 isLabelInAst (label, tree->left);
1273 /*-----------------------------------------------------------------*/
1274 /* isLoopCountable - return true if the loop count can be determi- */
1275 /* -ned at compile time . */
1276 /*-----------------------------------------------------------------*/
1278 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1279 symbol ** sym, ast ** init, ast ** end)
1282 /* the loop is considered countable if the following
1283 conditions are true :-
1285 a) initExpr :- <sym> = <const>
1286 b) condExpr :- <sym> < <const1>
1287 c) loopExpr :- <sym> ++
1290 /* first check the initExpr */
1291 if (IS_AST_OP (initExpr) &&
1292 initExpr->opval.op == '=' && /* is assignment */
1293 IS_AST_SYM_VALUE (initExpr->left))
1294 { /* left is a symbol */
1296 *sym = AST_SYMBOL (initExpr->left);
1297 *init = initExpr->right;
1302 /* for now the symbol has to be of
1304 if (!IS_INTEGRAL ((*sym)->type))
1307 /* now check condExpr */
1308 if (IS_AST_OP (condExpr))
1311 switch (condExpr->opval.op)
1314 if (IS_AST_SYM_VALUE (condExpr->left) &&
1315 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1316 IS_AST_LIT_VALUE (condExpr->right))
1318 *end = condExpr->right;
1324 if (IS_AST_OP (condExpr->left) &&
1325 condExpr->left->opval.op == '>' &&
1326 IS_AST_LIT_VALUE (condExpr->left->right) &&
1327 IS_AST_SYM_VALUE (condExpr->left->left) &&
1328 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1331 *end = newNode ('+', condExpr->left->right,
1332 newAst_VALUE (constVal ("1")));
1343 /* check loop expression is of the form <sym>++ */
1344 if (!IS_AST_OP (loopExpr))
1347 /* check if <sym> ++ */
1348 if (loopExpr->opval.op == INC_OP)
1354 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1355 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1362 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1363 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1371 if (loopExpr->opval.op == ADD_ASSIGN)
1374 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1375 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1376 IS_AST_LIT_VALUE (loopExpr->right) &&
1377 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1385 /*-----------------------------------------------------------------*/
1386 /* astHasVolatile - returns true if ast contains any volatile */
1387 /*-----------------------------------------------------------------*/
1389 astHasVolatile (ast * tree)
1394 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1397 if (IS_AST_OP (tree))
1398 return astHasVolatile (tree->left) ||
1399 astHasVolatile (tree->right);
1404 /*-----------------------------------------------------------------*/
1405 /* astHasPointer - return true if the ast contains any ptr variable */
1406 /*-----------------------------------------------------------------*/
1408 astHasPointer (ast * tree)
1413 if (IS_AST_LINK (tree))
1416 /* if we hit an array expression then check
1417 only the left side */
1418 if (IS_AST_OP (tree) && tree->opval.op == '[')
1419 return astHasPointer (tree->left);
1421 if (IS_AST_VALUE (tree))
1422 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1424 return astHasPointer (tree->left) ||
1425 astHasPointer (tree->right);
1429 /*-----------------------------------------------------------------*/
1430 /* astHasSymbol - return true if the ast has the given symbol */
1431 /*-----------------------------------------------------------------*/
1433 astHasSymbol (ast * tree, symbol * sym)
1435 if (!tree || IS_AST_LINK (tree))
1438 if (IS_AST_VALUE (tree))
1440 if (IS_AST_SYM_VALUE (tree))
1441 return isSymbolEqual (AST_SYMBOL (tree), sym);
1446 return astHasSymbol (tree->left, sym) ||
1447 astHasSymbol (tree->right, sym);
1450 /*-----------------------------------------------------------------*/
1451 /* astHasDeref - return true if the ast has an indirect access */
1452 /*-----------------------------------------------------------------*/
1454 astHasDeref (ast * tree)
1456 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1459 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1461 return astHasDeref (tree->left) || astHasDeref (tree->right);
1464 /*-----------------------------------------------------------------*/
1465 /* isConformingBody - the loop body has to conform to a set of rules */
1466 /* for the loop to be considered reversible read on for rules */
1467 /*-----------------------------------------------------------------*/
1469 isConformingBody (ast * pbody, symbol * sym, ast * body)
1472 /* we are going to do a pre-order traversal of the
1473 tree && check for the following conditions. (essentially
1474 a set of very shallow tests )
1475 a) the sym passed does not participate in
1476 any arithmetic operation
1477 b) There are no function calls
1478 c) all jumps are within the body
1479 d) address of loop control variable not taken
1480 e) if an assignment has a pointer on the
1481 left hand side make sure right does not have
1482 loop control variable */
1484 /* if we reach the end or a leaf then true */
1485 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1489 /* if anything else is "volatile" */
1490 if (IS_VOLATILE (TETYPE (pbody)))
1493 /* we will walk the body in a pre-order traversal for
1495 switch (pbody->opval.op)
1497 /*------------------------------------------------------------------*/
1499 return isConformingBody (pbody->right, sym, body);
1501 /*------------------------------------------------------------------*/
1506 /*------------------------------------------------------------------*/
1507 case INC_OP: /* incerement operator unary so left only */
1510 /* sure we are not sym is not modified */
1512 IS_AST_SYM_VALUE (pbody->left) &&
1513 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1517 IS_AST_SYM_VALUE (pbody->right) &&
1518 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1523 /*------------------------------------------------------------------*/
1525 case '*': /* can be unary : if right is null then unary operation */
1530 /* if right is NULL then unary operation */
1531 /*------------------------------------------------------------------*/
1532 /*----------------------------*/
1534 /*----------------------------*/
1537 if (IS_AST_SYM_VALUE (pbody->left) &&
1538 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1541 return isConformingBody (pbody->left, sym, body);
1545 if (astHasSymbol (pbody->left, sym) ||
1546 astHasSymbol (pbody->right, sym))
1551 /*------------------------------------------------------------------*/
1559 if (IS_AST_SYM_VALUE (pbody->left) &&
1560 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1563 if (IS_AST_SYM_VALUE (pbody->right) &&
1564 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1567 return isConformingBody (pbody->left, sym, body) &&
1568 isConformingBody (pbody->right, sym, body);
1575 if (IS_AST_SYM_VALUE (pbody->left) &&
1576 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1578 return isConformingBody (pbody->left, sym, body);
1580 /*------------------------------------------------------------------*/
1592 case SIZEOF: /* evaluate wihout code generation */
1594 return isConformingBody (pbody->left, sym, body) &&
1595 isConformingBody (pbody->right, sym, body);
1597 /*------------------------------------------------------------------*/
1600 /* if left has a pointer & right has loop
1601 control variable then we cannot */
1602 if (astHasPointer (pbody->left) &&
1603 astHasSymbol (pbody->right, sym))
1605 if (astHasVolatile (pbody->left))
1608 if (IS_AST_SYM_VALUE (pbody->left) &&
1609 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1612 if (astHasVolatile (pbody->left))
1615 if (astHasDeref(pbody->right)) return FALSE;
1617 return isConformingBody (pbody->left, sym, body) &&
1618 isConformingBody (pbody->right, sym, body);
1629 assert ("Parser should not have generated this\n");
1631 /*------------------------------------------------------------------*/
1632 /*----------------------------*/
1633 /* comma operator */
1634 /*----------------------------*/
1636 return isConformingBody (pbody->left, sym, body) &&
1637 isConformingBody (pbody->right, sym, body);
1639 /*------------------------------------------------------------------*/
1640 /*----------------------------*/
1642 /*----------------------------*/
1646 /*------------------------------------------------------------------*/
1647 /*----------------------------*/
1648 /* return statement */
1649 /*----------------------------*/
1654 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1659 if (astHasSymbol (pbody->left, sym))
1666 return isConformingBody (pbody->left, sym, body) &&
1667 isConformingBody (pbody->right, sym, body);
1673 /*-----------------------------------------------------------------*/
1674 /* isLoopReversible - takes a for loop as input && returns true */
1675 /* if the for loop is reversible. If yes will set the value of */
1676 /* the loop control var & init value & termination value */
1677 /*-----------------------------------------------------------------*/
1679 isLoopReversible (ast * loop, symbol ** loopCntrl,
1680 ast ** init, ast ** end)
1682 /* if option says don't do it then don't */
1683 if (optimize.noLoopReverse)
1685 /* there are several tests to determine this */
1687 /* for loop has to be of the form
1688 for ( <sym> = <const1> ;
1689 [<sym> < <const2>] ;
1690 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1692 if (!isLoopCountable (AST_FOR (loop, initExpr),
1693 AST_FOR (loop, condExpr),
1694 AST_FOR (loop, loopExpr),
1695 loopCntrl, init, end))
1698 /* now do some serious checking on the body of the loop
1701 return isConformingBody (loop->left, *loopCntrl, loop->left);
1705 /*-----------------------------------------------------------------*/
1706 /* replLoopSym - replace the loop sym by loop sym -1 */
1707 /*-----------------------------------------------------------------*/
1709 replLoopSym (ast * body, symbol * sym)
1712 if (!body || IS_AST_LINK (body))
1715 if (IS_AST_SYM_VALUE (body))
1718 if (isSymbolEqual (AST_SYMBOL (body), sym))
1722 body->opval.op = '-';
1723 body->left = newAst_VALUE (symbolVal (sym));
1724 body->right = newAst_VALUE (constVal ("1"));
1732 replLoopSym (body->left, sym);
1733 replLoopSym (body->right, sym);
1737 /*-----------------------------------------------------------------*/
1738 /* reverseLoop - do the actual loop reversal */
1739 /*-----------------------------------------------------------------*/
1741 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1745 /* create the following tree
1750 if (sym) goto for_continue ;
1753 /* put it together piece by piece */
1754 rloop = newNode (NULLOP,
1755 createIf (newAst_VALUE (symbolVal (sym)),
1757 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1760 newAst_VALUE (symbolVal (sym)),
1763 replLoopSym (loop->left, sym);
1765 rloop = newNode (NULLOP,
1767 newAst_VALUE (symbolVal (sym)),
1768 newNode ('-', end, init)),
1769 createLabel (AST_FOR (loop, continueLabel),
1773 newNode (SUB_ASSIGN,
1774 newAst_VALUE (symbolVal (sym)),
1775 newAst_VALUE (constVal ("1"))),
1778 return decorateType (rloop);
1782 //#define DEMAND_INTEGER_PROMOTION
1784 #ifdef DEMAND_INTEGER_PROMOTION
1786 /*-----------------------------------------------------------------*/
1787 /* walk a tree looking for the leaves. Add a typecast to the given */
1788 /* type to each value leaf node. */
1789 /*-----------------------------------------------------------------*/
1791 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1793 if (!node || IS_CALLOP(node))
1795 /* WTF? We should never get here. */
1799 if (!node->left && !node->right)
1801 /* We're at a leaf; if it's a value, apply the typecast */
1802 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1804 *parentPtr = decorateType (newNode (CAST,
1805 newAst_LINK (copyLinkChain (type)),
1813 pushTypeCastToLeaves (type, node->left, &(node->left));
1817 pushTypeCastToLeaves (type, node->right, &(node->right));
1824 /*-----------------------------------------------------------------*/
1825 /* decorateType - compute type for this tree also does type cheking */
1826 /* this is done bottom up, since type have to flow upwards */
1827 /* it also does constant folding, and paramater checking */
1828 /*-----------------------------------------------------------------*/
1830 decorateType (ast * tree)
1838 /* if already has type then do nothing */
1839 if (tree->decorated)
1842 tree->decorated = 1;
1844 /* print the line */
1845 /* if not block & function */
1846 if (tree->type == EX_OP &&
1847 (tree->opval.op != FUNCTION &&
1848 tree->opval.op != BLOCK &&
1849 tree->opval.op != NULLOP))
1851 filename = tree->filename;
1852 lineno = tree->lineno;
1855 /* if any child is an error | this one is an error do nothing */
1856 if (tree->isError ||
1857 (tree->left && tree->left->isError) ||
1858 (tree->right && tree->right->isError))
1861 /*------------------------------------------------------------------*/
1862 /*----------------------------*/
1863 /* leaf has been reached */
1864 /*----------------------------*/
1865 /* if this is of type value */
1866 /* just get the type */
1867 if (tree->type == EX_VALUE)
1870 if (IS_LITERAL (tree->opval.val->etype))
1873 /* if this is a character array then declare it */
1874 if (IS_ARRAY (tree->opval.val->type))
1875 tree->opval.val = stringToSymbol (tree->opval.val);
1877 /* otherwise just copy the type information */
1878 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1882 if (tree->opval.val->sym)
1884 /* if the undefined flag is set then give error message */
1885 if (tree->opval.val->sym->undefined)
1887 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1889 TTYPE (tree) = TETYPE (tree) =
1890 tree->opval.val->type = tree->opval.val->sym->type =
1891 tree->opval.val->etype = tree->opval.val->sym->etype =
1892 copyLinkChain (INTTYPE);
1897 /* if impilicit i.e. struct/union member then no type */
1898 if (tree->opval.val->sym->implicit)
1899 TTYPE (tree) = TETYPE (tree) = NULL;
1904 /* else copy the type */
1905 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1907 /* and mark it as referenced */
1908 tree->opval.val->sym->isref = 1;
1916 /* if type link for the case of cast */
1917 if (tree->type == EX_LINK)
1919 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1926 dtl = decorateType (tree->left);
1927 dtr = decorateType (tree->right);
1929 /* this is to take care of situations
1930 when the tree gets rewritten */
1931 if (dtl != tree->left)
1933 if (dtr != tree->right)
1937 /* depending on type of operator do */
1939 switch (tree->opval.op)
1941 /*------------------------------------------------------------------*/
1942 /*----------------------------*/
1944 /*----------------------------*/
1947 /* determine which is the array & which the index */
1948 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1951 ast *tempTree = tree->left;
1952 tree->left = tree->right;
1953 tree->right = tempTree;
1956 /* first check if this is a array or a pointer */
1957 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1959 werror (E_NEED_ARRAY_PTR, "[]");
1960 goto errorTreeReturn;
1963 /* check if the type of the idx */
1964 if (!IS_INTEGRAL (RTYPE (tree)))
1966 werror (E_IDX_NOT_INT);
1967 goto errorTreeReturn;
1970 /* if the left is an rvalue then error */
1973 werror (E_LVALUE_REQUIRED, "array access");
1974 goto errorTreeReturn;
1977 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1978 if (IS_PTR(LTYPE(tree))) {
1979 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1983 /*------------------------------------------------------------------*/
1984 /*----------------------------*/
1986 /*----------------------------*/
1988 /* if this is not a structure */
1989 if (!IS_STRUCT (LTYPE (tree)))
1991 werror (E_STRUCT_UNION, ".");
1992 goto errorTreeReturn;
1994 TTYPE (tree) = structElemType (LTYPE (tree),
1995 (tree->right->type == EX_VALUE ?
1996 tree->right->opval.val : NULL));
1997 TETYPE (tree) = getSpec (TTYPE (tree));
2000 /*------------------------------------------------------------------*/
2001 /*----------------------------*/
2002 /* struct/union pointer */
2003 /*----------------------------*/
2005 /* if not pointer to a structure */
2006 if (!IS_PTR (LTYPE (tree)))
2008 werror (E_PTR_REQD);
2009 goto errorTreeReturn;
2012 if (!IS_STRUCT (LTYPE (tree)->next))
2014 werror (E_STRUCT_UNION, "->");
2015 goto errorTreeReturn;
2018 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2019 (tree->right->type == EX_VALUE ?
2020 tree->right->opval.val : NULL));
2021 TETYPE (tree) = getSpec (TTYPE (tree));
2024 /*------------------------------------------------------------------*/
2025 /*----------------------------*/
2026 /* ++/-- operation */
2027 /*----------------------------*/
2028 case INC_OP: /* incerement operator unary so left only */
2031 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2032 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2033 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2034 werror (E_CODE_WRITE, "++/--");
2043 /*------------------------------------------------------------------*/
2044 /*----------------------------*/
2046 /*----------------------------*/
2047 case '&': /* can be unary */
2048 /* if right is NULL then unary operation */
2049 if (tree->right) /* not an unary operation */
2052 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2054 werror (E_BITWISE_OP);
2055 werror (W_CONTINUE, "left & right types are ");
2056 printTypeChain (LTYPE (tree), stderr);
2057 fprintf (stderr, ",");
2058 printTypeChain (RTYPE (tree), stderr);
2059 fprintf (stderr, "\n");
2060 goto errorTreeReturn;
2063 /* if they are both literal */
2064 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2066 tree->type = EX_VALUE;
2067 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2068 valFromType (RETYPE (tree)), '&');
2070 tree->right = tree->left = NULL;
2071 TETYPE (tree) = tree->opval.val->etype;
2072 TTYPE (tree) = tree->opval.val->type;
2076 /* see if this is a GETHBIT operation if yes
2079 ast *otree = optimizeGetHbit (tree);
2082 return decorateType (otree);
2086 // we can't do this because of "(int & 0xff) << 3"
2088 /* if right or left is literal then result of that type */
2089 if (IS_LITERAL (RTYPE (tree)))
2092 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2093 TETYPE (tree) = getSpec (TTYPE (tree));
2094 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2098 if (IS_LITERAL (LTYPE (tree)))
2100 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2101 TETYPE (tree) = getSpec (TTYPE (tree));
2102 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2108 computeType (LTYPE (tree), RTYPE (tree));
2109 TETYPE (tree) = getSpec (TTYPE (tree));
2114 computeType (LTYPE (tree), RTYPE (tree));
2115 TETYPE (tree) = getSpec (TTYPE (tree));
2117 LRVAL (tree) = RRVAL (tree) = 1;
2121 /*------------------------------------------------------------------*/
2122 /*----------------------------*/
2124 /*----------------------------*/
2126 p->class = DECLARATOR;
2127 /* if bit field then error */
2128 if (IS_BITVAR (tree->left->etype))
2130 werror (E_ILLEGAL_ADDR, "address of bit variable");
2131 goto errorTreeReturn;
2134 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2136 werror (E_ILLEGAL_ADDR, "address of register variable");
2137 goto errorTreeReturn;
2140 if (IS_FUNC (LTYPE (tree)))
2142 werror (E_ILLEGAL_ADDR, "address of function");
2143 goto errorTreeReturn;
2146 if (IS_LITERAL(LTYPE(tree)))
2148 werror (E_ILLEGAL_ADDR, "address of literal");
2149 goto errorTreeReturn;
2154 werror (E_LVALUE_REQUIRED, "address of");
2155 goto errorTreeReturn;
2157 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2159 DCL_TYPE (p) = CPOINTER;
2160 DCL_PTR_CONST (p) = port->mem.code_ro;
2162 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2163 DCL_TYPE (p) = FPOINTER;
2164 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2165 DCL_TYPE (p) = PPOINTER;
2166 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2167 DCL_TYPE (p) = IPOINTER;
2168 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2169 DCL_TYPE (p) = EEPPOINTER;
2171 DCL_TYPE (p) = POINTER;
2173 if (IS_AST_SYM_VALUE (tree->left))
2175 AST_SYMBOL (tree->left)->addrtaken = 1;
2176 AST_SYMBOL (tree->left)->allocreq = 1;
2179 p->next = LTYPE (tree);
2181 TETYPE (tree) = getSpec (TTYPE (tree));
2182 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2183 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2188 /*------------------------------------------------------------------*/
2189 /*----------------------------*/
2191 /*----------------------------*/
2193 /* if the rewrite succeeds then don't go any furthur */
2195 ast *wtree = optimizeRRCRLC (tree);
2197 return decorateType (wtree);
2199 /*------------------------------------------------------------------*/
2200 /*----------------------------*/
2202 /*----------------------------*/
2204 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2206 werror (E_BITWISE_OP);
2207 werror (W_CONTINUE, "left & right types are ");
2208 printTypeChain (LTYPE (tree), stderr);
2209 fprintf (stderr, ",");
2210 printTypeChain (RTYPE (tree), stderr);
2211 fprintf (stderr, "\n");
2212 goto errorTreeReturn;
2215 /* if they are both literal then */
2216 /* rewrite the tree */
2217 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2219 tree->type = EX_VALUE;
2220 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2221 valFromType (RETYPE (tree)),
2223 tree->right = tree->left = NULL;
2224 TETYPE (tree) = tree->opval.val->etype;
2225 TTYPE (tree) = tree->opval.val->type;
2228 LRVAL (tree) = RRVAL (tree) = 1;
2229 TETYPE (tree) = getSpec (TTYPE (tree) =
2230 computeType (LTYPE (tree),
2233 /*------------------------------------------------------------------*/
2234 /*----------------------------*/
2236 /*----------------------------*/
2238 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2240 werror (E_INVALID_OP, "divide");
2241 goto errorTreeReturn;
2243 /* if they are both literal then */
2244 /* rewrite the tree */
2245 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2247 tree->type = EX_VALUE;
2248 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2249 valFromType (RETYPE (tree)));
2250 tree->right = tree->left = NULL;
2251 TETYPE (tree) = getSpec (TTYPE (tree) =
2252 tree->opval.val->type);
2255 LRVAL (tree) = RRVAL (tree) = 1;
2256 TETYPE (tree) = getSpec (TTYPE (tree) =
2257 computeType (LTYPE (tree),
2261 /*------------------------------------------------------------------*/
2262 /*----------------------------*/
2264 /*----------------------------*/
2266 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2268 werror (E_BITWISE_OP);
2269 werror (W_CONTINUE, "left & right types are ");
2270 printTypeChain (LTYPE (tree), stderr);
2271 fprintf (stderr, ",");
2272 printTypeChain (RTYPE (tree), stderr);
2273 fprintf (stderr, "\n");
2274 goto errorTreeReturn;
2276 /* if they are both literal then */
2277 /* rewrite the tree */
2278 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2280 tree->type = EX_VALUE;
2281 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2282 valFromType (RETYPE (tree)));
2283 tree->right = tree->left = NULL;
2284 TETYPE (tree) = getSpec (TTYPE (tree) =
2285 tree->opval.val->type);
2288 LRVAL (tree) = RRVAL (tree) = 1;
2289 TETYPE (tree) = getSpec (TTYPE (tree) =
2290 computeType (LTYPE (tree),
2294 /*------------------------------------------------------------------*/
2295 /*----------------------------*/
2296 /* address dereference */
2297 /*----------------------------*/
2298 case '*': /* can be unary : if right is null then unary operation */
2301 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2303 werror (E_PTR_REQD);
2304 goto errorTreeReturn;
2309 werror (E_LVALUE_REQUIRED, "pointer deref");
2310 goto errorTreeReturn;
2312 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2313 LTYPE (tree)->next : NULL);
2314 TETYPE (tree) = getSpec (TTYPE (tree));
2315 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2319 /*------------------------------------------------------------------*/
2320 /*----------------------------*/
2321 /* multiplication */
2322 /*----------------------------*/
2323 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2325 werror (E_INVALID_OP, "multiplication");
2326 goto errorTreeReturn;
2329 /* if they are both literal then */
2330 /* rewrite the tree */
2331 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2333 tree->type = EX_VALUE;
2334 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2335 valFromType (RETYPE (tree)));
2336 tree->right = tree->left = NULL;
2337 TETYPE (tree) = getSpec (TTYPE (tree) =
2338 tree->opval.val->type);
2342 /* if left is a literal exchange left & right */
2343 if (IS_LITERAL (LTYPE (tree)))
2345 ast *tTree = tree->left;
2346 tree->left = tree->right;
2347 tree->right = tTree;
2350 LRVAL (tree) = RRVAL (tree) = 1;
2351 /* promote result to int if left & right are char
2352 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2353 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2354 TETYPE (tree) = getSpec (TTYPE (tree) =
2355 computeType (LTYPE (tree),
2357 SPEC_NOUN(TETYPE(tree)) = V_INT;
2359 TETYPE (tree) = getSpec (TTYPE (tree) =
2360 computeType (LTYPE (tree),
2365 /*------------------------------------------------------------------*/
2366 /*----------------------------*/
2367 /* unary '+' operator */
2368 /*----------------------------*/
2373 if (!IS_INTEGRAL (LTYPE (tree)))
2375 werror (E_UNARY_OP, '+');
2376 goto errorTreeReturn;
2379 /* if left is a literal then do it */
2380 if (IS_LITERAL (LTYPE (tree)))
2382 tree->type = EX_VALUE;
2383 tree->opval.val = valFromType (LETYPE (tree));
2385 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2389 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2393 /*------------------------------------------------------------------*/
2394 /*----------------------------*/
2396 /*----------------------------*/
2398 /* this is not a unary operation */
2399 /* if both pointers then problem */
2400 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2401 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2403 werror (E_PTR_PLUS_PTR);
2404 goto errorTreeReturn;
2407 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2408 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2410 werror (E_PLUS_INVALID, "+");
2411 goto errorTreeReturn;
2414 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2415 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2417 werror (E_PLUS_INVALID, "+");
2418 goto errorTreeReturn;
2420 /* if they are both literal then */
2421 /* rewrite the tree */
2422 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2424 tree->type = EX_VALUE;
2425 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2426 valFromType (RETYPE (tree)));
2427 tree->right = tree->left = NULL;
2428 TETYPE (tree) = getSpec (TTYPE (tree) =
2429 tree->opval.val->type);
2433 /* if the right is a pointer or left is a literal
2434 xchange left & right */
2435 if (IS_ARRAY (RTYPE (tree)) ||
2436 IS_PTR (RTYPE (tree)) ||
2437 IS_LITERAL (LTYPE (tree)))
2439 ast *tTree = tree->left;
2440 tree->left = tree->right;
2441 tree->right = tTree;
2444 LRVAL (tree) = RRVAL (tree) = 1;
2445 /* if the left is a pointer */
2446 if (IS_PTR (LTYPE (tree)))
2447 TETYPE (tree) = getSpec (TTYPE (tree) =
2450 TETYPE (tree) = getSpec (TTYPE (tree) =
2451 computeType (LTYPE (tree),
2455 /*------------------------------------------------------------------*/
2456 /*----------------------------*/
2458 /*----------------------------*/
2459 case '-': /* can be unary */
2460 /* if right is null then unary */
2464 if (!IS_ARITHMETIC (LTYPE (tree)))
2466 werror (E_UNARY_OP, tree->opval.op);
2467 goto errorTreeReturn;
2470 /* if left is a literal then do it */
2471 if (IS_LITERAL (LTYPE (tree)))
2473 tree->type = EX_VALUE;
2474 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2476 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2477 SPEC_USIGN(TETYPE(tree)) = 0;
2481 TTYPE (tree) = LTYPE (tree);
2485 /*------------------------------------------------------------------*/
2486 /*----------------------------*/
2488 /*----------------------------*/
2490 if (!(IS_PTR (LTYPE (tree)) ||
2491 IS_ARRAY (LTYPE (tree)) ||
2492 IS_ARITHMETIC (LTYPE (tree))))
2494 werror (E_PLUS_INVALID, "-");
2495 goto errorTreeReturn;
2498 if (!(IS_PTR (RTYPE (tree)) ||
2499 IS_ARRAY (RTYPE (tree)) ||
2500 IS_ARITHMETIC (RTYPE (tree))))
2502 werror (E_PLUS_INVALID, "-");
2503 goto errorTreeReturn;
2506 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2507 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2508 IS_INTEGRAL (RTYPE (tree))))
2510 werror (E_PLUS_INVALID, "-");
2511 goto errorTreeReturn;
2514 /* if they are both literal then */
2515 /* rewrite the tree */
2516 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2518 tree->type = EX_VALUE;
2519 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2520 valFromType (RETYPE (tree)));
2521 tree->right = tree->left = NULL;
2522 TETYPE (tree) = getSpec (TTYPE (tree) =
2523 tree->opval.val->type);
2527 /* if the left & right are equal then zero */
2528 if (isAstEqual (tree->left, tree->right))
2530 tree->type = EX_VALUE;
2531 tree->left = tree->right = NULL;
2532 tree->opval.val = constVal ("0");
2533 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2537 /* if both of them are pointers or arrays then */
2538 /* the result is going to be an integer */
2539 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2540 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2541 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2543 /* if only the left is a pointer */
2544 /* then result is a pointer */
2545 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2546 TETYPE (tree) = getSpec (TTYPE (tree) =
2549 TETYPE (tree) = getSpec (TTYPE (tree) =
2550 computeType (LTYPE (tree),
2552 LRVAL (tree) = RRVAL (tree) = 1;
2555 /*------------------------------------------------------------------*/
2556 /*----------------------------*/
2558 /*----------------------------*/
2560 /* can be only integral type */
2561 if (!IS_INTEGRAL (LTYPE (tree)))
2563 werror (E_UNARY_OP, tree->opval.op);
2564 goto errorTreeReturn;
2567 /* if left is a literal then do it */
2568 if (IS_LITERAL (LTYPE (tree)))
2570 tree->type = EX_VALUE;
2571 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2573 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2577 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2580 /*------------------------------------------------------------------*/
2581 /*----------------------------*/
2583 /*----------------------------*/
2585 /* can be pointer */
2586 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2587 !IS_PTR (LTYPE (tree)) &&
2588 !IS_ARRAY (LTYPE (tree)))
2590 werror (E_UNARY_OP, tree->opval.op);
2591 goto errorTreeReturn;
2594 /* if left is a literal then do it */
2595 if (IS_LITERAL (LTYPE (tree)))
2597 tree->type = EX_VALUE;
2598 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2600 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2604 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2607 /*------------------------------------------------------------------*/
2608 /*----------------------------*/
2610 /*----------------------------*/
2613 TTYPE (tree) = LTYPE (tree);
2614 TETYPE (tree) = LETYPE (tree);
2618 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2623 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2625 werror (E_SHIFT_OP_INVALID);
2626 werror (W_CONTINUE, "left & right types are ");
2627 printTypeChain (LTYPE (tree), stderr);
2628 fprintf (stderr, ",");
2629 printTypeChain (RTYPE (tree), stderr);
2630 fprintf (stderr, "\n");
2631 goto errorTreeReturn;
2634 /* if they are both literal then */
2635 /* rewrite the tree */
2636 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2638 tree->type = EX_VALUE;
2639 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2640 valFromType (RETYPE (tree)),
2641 (tree->opval.op == LEFT_OP ? 1 : 0));
2642 tree->right = tree->left = NULL;
2643 TETYPE (tree) = getSpec (TTYPE (tree) =
2644 tree->opval.val->type);
2647 /* if only the right side is a literal & we are
2648 shifting more than size of the left operand then zero */
2649 if (IS_LITERAL (RTYPE (tree)) &&
2650 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2651 (getSize (LTYPE (tree)) * 8))
2653 werror (W_SHIFT_CHANGED,
2654 (tree->opval.op == LEFT_OP ? "left" : "right"));
2655 tree->type = EX_VALUE;
2656 tree->left = tree->right = NULL;
2657 tree->opval.val = constVal ("0");
2658 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2661 LRVAL (tree) = RRVAL (tree) = 1;
2662 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2664 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2668 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2672 /*------------------------------------------------------------------*/
2673 /*----------------------------*/
2675 /*----------------------------*/
2676 case CAST: /* change the type */
2677 /* cannot cast to an aggregate type */
2678 if (IS_AGGREGATE (LTYPE (tree)))
2680 werror (E_CAST_ILLEGAL);
2681 goto errorTreeReturn;
2684 /* make sure the type is complete and sane */
2685 checkTypeSanity(LETYPE(tree), "(cast)");
2688 /* if the right is a literal replace the tree */
2689 if (IS_LITERAL (RETYPE (tree))) {
2690 if (!IS_PTR (LTYPE (tree))) {
2691 tree->type = EX_VALUE;
2693 valCastLiteral (LTYPE (tree),
2694 floatFromVal (valFromType (RETYPE (tree))));
2697 TTYPE (tree) = tree->opval.val->type;
2698 tree->values.literalFromCast = 1;
2699 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2700 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2701 sym_link *rest = LTYPE(tree)->next;
2702 werror(W_LITERAL_GENERIC);
2703 TTYPE(tree) = newLink();
2704 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2705 TTYPE(tree)->next = rest;
2706 tree->left->opval.lnk = TTYPE(tree);
2709 TTYPE (tree) = LTYPE (tree);
2713 TTYPE (tree) = LTYPE (tree);
2717 /* if the right is a literal replace the tree */
2718 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2719 tree->type = EX_VALUE;
2721 valCastLiteral (LTYPE (tree),
2722 floatFromVal (valFromType (RETYPE (tree))));
2725 TTYPE (tree) = tree->opval.val->type;
2726 tree->values.literalFromCast = 1;
2728 TTYPE (tree) = LTYPE (tree);
2733 TETYPE (tree) = getSpec (TTYPE (tree));
2737 /*------------------------------------------------------------------*/
2738 /*----------------------------*/
2739 /* logical &&, || */
2740 /*----------------------------*/
2743 /* each must me arithmetic type or be a pointer */
2744 if (!IS_PTR (LTYPE (tree)) &&
2745 !IS_ARRAY (LTYPE (tree)) &&
2746 !IS_INTEGRAL (LTYPE (tree)))
2748 werror (E_COMPARE_OP);
2749 goto errorTreeReturn;
2752 if (!IS_PTR (RTYPE (tree)) &&
2753 !IS_ARRAY (RTYPE (tree)) &&
2754 !IS_INTEGRAL (RTYPE (tree)))
2756 werror (E_COMPARE_OP);
2757 goto errorTreeReturn;
2759 /* if they are both literal then */
2760 /* rewrite the tree */
2761 if (IS_LITERAL (RTYPE (tree)) &&
2762 IS_LITERAL (LTYPE (tree)))
2764 tree->type = EX_VALUE;
2765 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2766 valFromType (RETYPE (tree)),
2768 tree->right = tree->left = NULL;
2769 TETYPE (tree) = getSpec (TTYPE (tree) =
2770 tree->opval.val->type);
2773 LRVAL (tree) = RRVAL (tree) = 1;
2774 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2777 /*------------------------------------------------------------------*/
2778 /*----------------------------*/
2779 /* comparison operators */
2780 /*----------------------------*/
2788 ast *lt = optimizeCompare (tree);
2794 /* if they are pointers they must be castable */
2795 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2797 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2799 werror (E_COMPARE_OP);
2800 fprintf (stderr, "comparing type ");
2801 printTypeChain (LTYPE (tree), stderr);
2802 fprintf (stderr, "to type ");
2803 printTypeChain (RTYPE (tree), stderr);
2804 fprintf (stderr, "\n");
2805 goto errorTreeReturn;
2808 /* else they should be promotable to one another */
2811 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2812 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2814 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2816 werror (E_COMPARE_OP);
2817 fprintf (stderr, "comparing type ");
2818 printTypeChain (LTYPE (tree), stderr);
2819 fprintf (stderr, "to type ");
2820 printTypeChain (RTYPE (tree), stderr);
2821 fprintf (stderr, "\n");
2822 goto errorTreeReturn;
2826 /* if they are both literal then */
2827 /* rewrite the tree */
2828 if (IS_LITERAL (RTYPE (tree)) &&
2829 IS_LITERAL (LTYPE (tree)))
2831 tree->type = EX_VALUE;
2832 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2833 valFromType (RETYPE (tree)),
2835 tree->right = tree->left = NULL;
2836 TETYPE (tree) = getSpec (TTYPE (tree) =
2837 tree->opval.val->type);
2840 LRVAL (tree) = RRVAL (tree) = 1;
2841 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2844 /*------------------------------------------------------------------*/
2845 /*----------------------------*/
2847 /*----------------------------*/
2848 case SIZEOF: /* evaluate wihout code generation */
2849 /* change the type to a integer */
2850 tree->type = EX_VALUE;
2851 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2852 tree->opval.val = constVal (buffer);
2853 tree->right = tree->left = NULL;
2854 TETYPE (tree) = getSpec (TTYPE (tree) =
2855 tree->opval.val->type);
2858 /*------------------------------------------------------------------*/
2859 /*----------------------------*/
2860 /* conditional operator '?' */
2861 /*----------------------------*/
2863 /* the type is value of the colon operator (on the right) */
2864 assert(IS_COLON_OP(tree->right));
2865 /* if already known then replace the tree : optimizer will do it
2866 but faster to do it here */
2867 if (IS_LITERAL (LTYPE(tree))) {
2868 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2869 return tree->right->left ;
2871 return tree->right->right ;
2874 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2875 TETYPE (tree) = getSpec (TTYPE (tree));
2880 /* if they don't match we have a problem */
2881 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2883 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2884 goto errorTreeReturn;
2887 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2888 TETYPE (tree) = getSpec (TTYPE (tree));
2892 /*------------------------------------------------------------------*/
2893 /*----------------------------*/
2894 /* assignment operators */
2895 /*----------------------------*/
2898 /* for these it must be both must be integral */
2899 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2900 !IS_ARITHMETIC (RTYPE (tree)))
2902 werror (E_OPS_INTEGRAL);
2903 goto errorTreeReturn;
2906 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2908 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2909 werror (E_CODE_WRITE, " ");
2913 werror (E_LVALUE_REQUIRED, "*= or /=");
2914 goto errorTreeReturn;
2925 /* for these it must be both must be integral */
2926 if (!IS_INTEGRAL (LTYPE (tree)) ||
2927 !IS_INTEGRAL (RTYPE (tree)))
2929 werror (E_OPS_INTEGRAL);
2930 goto errorTreeReturn;
2933 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2935 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2936 werror (E_CODE_WRITE, " ");
2940 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2941 goto errorTreeReturn;
2947 /*------------------------------------------------------------------*/
2948 /*----------------------------*/
2950 /*----------------------------*/
2952 if (!(IS_PTR (LTYPE (tree)) ||
2953 IS_ARITHMETIC (LTYPE (tree))))
2955 werror (E_PLUS_INVALID, "-=");
2956 goto errorTreeReturn;
2959 if (!(IS_PTR (RTYPE (tree)) ||
2960 IS_ARITHMETIC (RTYPE (tree))))
2962 werror (E_PLUS_INVALID, "-=");
2963 goto errorTreeReturn;
2966 TETYPE (tree) = getSpec (TTYPE (tree) =
2967 computeType (LTYPE (tree),
2970 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2971 werror (E_CODE_WRITE, " ");
2975 werror (E_LVALUE_REQUIRED, "-=");
2976 goto errorTreeReturn;
2982 /*------------------------------------------------------------------*/
2983 /*----------------------------*/
2985 /*----------------------------*/
2987 /* this is not a unary operation */
2988 /* if both pointers then problem */
2989 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2991 werror (E_PTR_PLUS_PTR);
2992 goto errorTreeReturn;
2995 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2997 werror (E_PLUS_INVALID, "+=");
2998 goto errorTreeReturn;
3001 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3003 werror (E_PLUS_INVALID, "+=");
3004 goto errorTreeReturn;
3007 TETYPE (tree) = getSpec (TTYPE (tree) =
3008 computeType (LTYPE (tree),
3011 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3012 werror (E_CODE_WRITE, " ");
3016 werror (E_LVALUE_REQUIRED, "+=");
3017 goto errorTreeReturn;
3020 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3021 tree->opval.op = '=';
3025 /*------------------------------------------------------------------*/
3026 /*----------------------------*/
3027 /* straight assignemnt */
3028 /*----------------------------*/
3030 /* cannot be an aggregate */
3031 if (IS_AGGREGATE (LTYPE (tree)))
3033 werror (E_AGGR_ASSIGN);
3034 goto errorTreeReturn;
3037 /* they should either match or be castable */
3038 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3040 werror (E_TYPE_MISMATCH, "assignment", " ");
3041 fprintf (stderr, "type --> '");
3042 printTypeChain (RTYPE (tree), stderr);
3043 fprintf (stderr, "' ");
3044 fprintf (stderr, "assigned to type --> '");
3045 printTypeChain (LTYPE (tree), stderr);
3046 fprintf (stderr, "'\n");
3047 goto errorTreeReturn;
3050 /* if the left side of the tree is of type void
3051 then report error */
3052 if (IS_VOID (LTYPE (tree)))
3054 werror (E_CAST_ZERO);
3055 printFromToType(RTYPE(tree), LTYPE(tree));
3058 TETYPE (tree) = getSpec (TTYPE (tree) =
3062 if (!tree->initMode ) {
3063 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3064 werror (E_CODE_WRITE, " ");
3068 werror (E_LVALUE_REQUIRED, "=");
3069 goto errorTreeReturn;
3074 /*------------------------------------------------------------------*/
3075 /*----------------------------*/
3076 /* comma operator */
3077 /*----------------------------*/
3079 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3082 /*------------------------------------------------------------------*/
3083 /*----------------------------*/
3085 /*----------------------------*/
3089 if (processParms (tree->left,
3090 FUNC_ARGS(tree->left->ftype),
3091 tree->right, &parmNumber, TRUE))
3092 goto errorTreeReturn;
3094 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3096 //IFFUNC_ARGS(tree->left->ftype) =
3097 //reverseVal (IFFUNC_ARGS(tree->left->ftype));
3098 reverseParms (tree->right);
3101 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3104 /*------------------------------------------------------------------*/
3105 /*----------------------------*/
3106 /* return statement */
3107 /*----------------------------*/
3112 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3114 werror (W_RETURN_MISMATCH);
3115 printFromToType (RTYPE(tree), currFunc->type->next);
3116 goto errorTreeReturn;
3119 if (IS_VOID (currFunc->type->next)
3121 !IS_VOID (RTYPE (tree)))
3123 werror (E_FUNC_VOID);
3124 goto errorTreeReturn;
3127 /* if there is going to be a casing required then add it */
3128 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3131 decorateType (newNode (CAST,
3132 newAst_LINK (copyLinkChain (currFunc->type->next)),
3141 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3143 werror (E_VOID_FUNC, currFunc->name);
3144 goto errorTreeReturn;
3147 TTYPE (tree) = TETYPE (tree) = NULL;
3150 /*------------------------------------------------------------------*/
3151 /*----------------------------*/
3152 /* switch statement */
3153 /*----------------------------*/
3155 /* the switch value must be an integer */
3156 if (!IS_INTEGRAL (LTYPE (tree)))
3158 werror (E_SWITCH_NON_INTEGER);
3159 goto errorTreeReturn;
3162 TTYPE (tree) = TETYPE (tree) = NULL;
3165 /*------------------------------------------------------------------*/
3166 /*----------------------------*/
3168 /*----------------------------*/
3170 tree->left = backPatchLabels (tree->left,
3173 TTYPE (tree) = TETYPE (tree) = NULL;
3176 /*------------------------------------------------------------------*/
3177 /*----------------------------*/
3179 /*----------------------------*/
3182 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3183 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3184 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3186 /* if the for loop is reversible then
3187 reverse it otherwise do what we normally
3193 if (isLoopReversible (tree, &sym, &init, &end))
3194 return reverseLoop (tree, sym, init, end);
3196 return decorateType (createFor (AST_FOR (tree, trueLabel),
3197 AST_FOR (tree, continueLabel),
3198 AST_FOR (tree, falseLabel),
3199 AST_FOR (tree, condLabel),
3200 AST_FOR (tree, initExpr),
3201 AST_FOR (tree, condExpr),
3202 AST_FOR (tree, loopExpr),
3206 TTYPE (tree) = TETYPE (tree) = NULL;
3210 /* some error found this tree will be killed */
3212 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3213 tree->opval.op = NULLOP;
3219 /*-----------------------------------------------------------------*/
3220 /* sizeofOp - processes size of operation */
3221 /*-----------------------------------------------------------------*/
3223 sizeofOp (sym_link * type)
3227 /* make sure the type is complete and sane */
3228 checkTypeSanity(type, "(sizeof)");
3230 /* get the size and convert it to character */
3231 sprintf (buff, "%d", getSize (type));
3233 /* now convert into value */
3234 return constVal (buff);
3238 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3239 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3240 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3241 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3242 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3243 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3244 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3246 /*-----------------------------------------------------------------*/
3247 /* backPatchLabels - change and or not operators to flow control */
3248 /*-----------------------------------------------------------------*/
3250 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3256 if (!(IS_ANDORNOT (tree)))
3259 /* if this an and */
3262 static int localLbl = 0;
3265 sprintf (buffer, "_and_%d", localLbl++);
3266 localLabel = newSymbol (buffer, NestLevel);
3268 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3270 /* if left is already a IFX then just change the if true label in that */
3271 if (!IS_IFX (tree->left))
3272 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3274 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3275 /* right is a IFX then just join */
3276 if (IS_IFX (tree->right))
3277 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3279 tree->right = createLabel (localLabel, tree->right);
3280 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3282 return newNode (NULLOP, tree->left, tree->right);
3285 /* if this is an or operation */
3288 static int localLbl = 0;
3291 sprintf (buffer, "_or_%d", localLbl++);
3292 localLabel = newSymbol (buffer, NestLevel);
3294 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3296 /* if left is already a IFX then just change the if true label in that */
3297 if (!IS_IFX (tree->left))
3298 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3300 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3301 /* right is a IFX then just join */
3302 if (IS_IFX (tree->right))
3303 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3305 tree->right = createLabel (localLabel, tree->right);
3306 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3308 return newNode (NULLOP, tree->left, tree->right);
3314 int wasnot = IS_NOT (tree->left);
3315 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3317 /* if the left is already a IFX */
3318 if (!IS_IFX (tree->left))
3319 tree->left = newNode (IFX, tree->left, NULL);
3323 tree->left->trueLabel = trueLabel;
3324 tree->left->falseLabel = falseLabel;
3328 tree->left->trueLabel = falseLabel;
3329 tree->left->falseLabel = trueLabel;
3336 tree->trueLabel = trueLabel;
3337 tree->falseLabel = falseLabel;
3344 /*-----------------------------------------------------------------*/
3345 /* createBlock - create expression tree for block */
3346 /*-----------------------------------------------------------------*/
3348 createBlock (symbol * decl, ast * body)
3352 /* if the block has nothing */
3356 ex = newNode (BLOCK, NULL, body);
3357 ex->values.sym = decl;
3359 ex->right = ex->right;
3365 /*-----------------------------------------------------------------*/
3366 /* createLabel - creates the expression tree for labels */
3367 /*-----------------------------------------------------------------*/
3369 createLabel (symbol * label, ast * stmnt)
3372 char name[SDCC_NAME_MAX + 1];
3375 /* must create fresh symbol if the symbol name */
3376 /* exists in the symbol table, since there can */
3377 /* be a variable with the same name as the labl */
3378 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3379 (csym->level == label->level))
3380 label = newSymbol (label->name, label->level);
3382 /* change the name before putting it in add _ */
3383 sprintf (name, "%s", label->name);
3385 /* put the label in the LabelSymbol table */
3386 /* but first check if a label of the same */
3388 if ((csym = findSym (LabelTab, NULL, name)))
3389 werror (E_DUPLICATE_LABEL, label->name);
3391 addSym (LabelTab, label, name, label->level, 0, 0);
3394 label->key = labelKey++;
3395 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3401 /*-----------------------------------------------------------------*/
3402 /* createCase - generates the parsetree for a case statement */
3403 /*-----------------------------------------------------------------*/
3405 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3407 char caseLbl[SDCC_NAME_MAX + 1];
3411 /* if the switch statement does not exist */
3412 /* then case is out of context */
3415 werror (E_CASE_CONTEXT);
3419 caseVal = decorateType (resolveSymbols (caseVal));
3420 /* if not a constant then error */
3421 if (!IS_LITERAL (caseVal->ftype))
3423 werror (E_CASE_CONSTANT);
3427 /* if not a integer than error */
3428 if (!IS_INTEGRAL (caseVal->ftype))
3430 werror (E_CASE_NON_INTEGER);
3434 /* find the end of the switch values chain */
3435 if (!(val = swStat->values.switchVals.swVals))
3436 swStat->values.switchVals.swVals = caseVal->opval.val;
3439 /* also order the cases according to value */
3441 int cVal = (int) floatFromVal (caseVal->opval.val);
3442 while (val && (int) floatFromVal (val) < cVal)
3448 /* if we reached the end then */
3451 pval->next = caseVal->opval.val;
3455 /* we found a value greater than */
3456 /* the current value we must add this */
3457 /* before the value */
3458 caseVal->opval.val->next = val;
3460 /* if this was the first in chain */
3461 if (swStat->values.switchVals.swVals == val)
3462 swStat->values.switchVals.swVals =
3465 pval->next = caseVal->opval.val;
3470 /* create the case label */
3471 sprintf (caseLbl, "_case_%d_%d",
3472 swStat->values.switchVals.swNum,
3473 (int) floatFromVal (caseVal->opval.val));
3475 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3480 /*-----------------------------------------------------------------*/
3481 /* createDefault - creates the parse tree for the default statement */
3482 /*-----------------------------------------------------------------*/
3484 createDefault (ast * swStat, ast * stmnt)
3486 char defLbl[SDCC_NAME_MAX + 1];
3488 /* if the switch statement does not exist */
3489 /* then case is out of context */
3492 werror (E_CASE_CONTEXT);
3496 /* turn on the default flag */
3497 swStat->values.switchVals.swDefault = 1;
3499 /* create the label */
3500 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3501 return createLabel (newSymbol (defLbl, 0), stmnt);
3504 /*-----------------------------------------------------------------*/
3505 /* createIf - creates the parsetree for the if statement */
3506 /*-----------------------------------------------------------------*/
3508 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3510 static int Lblnum = 0;
3512 symbol *ifTrue, *ifFalse, *ifEnd;
3514 /* if neither exists */
3515 if (!elseBody && !ifBody) {
3516 // if there are no side effects (i++, j() etc)
3517 if (!hasSEFcalls(condAst)) {
3522 /* create the labels */
3523 sprintf (buffer, "_iffalse_%d", Lblnum);
3524 ifFalse = newSymbol (buffer, NestLevel);
3525 /* if no else body then end == false */
3530 sprintf (buffer, "_ifend_%d", Lblnum);
3531 ifEnd = newSymbol (buffer, NestLevel);
3534 sprintf (buffer, "_iftrue_%d", Lblnum);
3535 ifTrue = newSymbol (buffer, NestLevel);
3539 /* attach the ifTrue label to the top of it body */
3540 ifBody = createLabel (ifTrue, ifBody);
3541 /* attach a goto end to the ifBody if else is present */
3544 ifBody = newNode (NULLOP, ifBody,
3546 newAst_VALUE (symbolVal (ifEnd)),
3548 /* put the elseLabel on the else body */
3549 elseBody = createLabel (ifFalse, elseBody);
3550 /* out the end at the end of the body */
3551 elseBody = newNode (NULLOP,
3553 createLabel (ifEnd, NULL));
3557 ifBody = newNode (NULLOP, ifBody,
3558 createLabel (ifFalse, NULL));
3560 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3561 if (IS_IFX (condAst))
3564 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3566 return newNode (NULLOP, ifTree,
3567 newNode (NULLOP, ifBody, elseBody));
3571 /*-----------------------------------------------------------------*/
3572 /* createDo - creates parse tree for do */
3575 /* _docontinue_n: */
3576 /* condition_expression +-> trueLabel -> _dobody_n */
3578 /* +-> falseLabel-> _dobreak_n */
3580 /*-----------------------------------------------------------------*/
3582 createDo (symbol * trueLabel, symbol * continueLabel,
3583 symbol * falseLabel, ast * condAst, ast * doBody)
3588 /* if the body does not exist then it is simple */
3591 condAst = backPatchLabels (condAst, continueLabel, NULL);
3592 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3593 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3594 doTree->trueLabel = continueLabel;
3595 doTree->falseLabel = NULL;
3599 /* otherwise we have a body */
3600 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3602 /* attach the body label to the top */
3603 doBody = createLabel (trueLabel, doBody);
3604 /* attach the continue label to end of body */
3605 doBody = newNode (NULLOP, doBody,
3606 createLabel (continueLabel, NULL));
3608 /* now put the break label at the end */
3609 if (IS_IFX (condAst))
3612 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3614 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3616 /* putting it together */
3617 return newNode (NULLOP, doBody, doTree);
3620 /*-----------------------------------------------------------------*/
3621 /* createFor - creates parse tree for 'for' statement */
3624 /* condExpr +-> trueLabel -> _forbody_n */
3626 /* +-> falseLabel-> _forbreak_n */
3629 /* _forcontinue_n: */
3631 /* goto _forcond_n ; */
3633 /*-----------------------------------------------------------------*/
3635 createFor (symbol * trueLabel, symbol * continueLabel,
3636 symbol * falseLabel, symbol * condLabel,
3637 ast * initExpr, ast * condExpr, ast * loopExpr,
3642 /* if loopexpression not present then we can generate it */
3643 /* the same way as a while */
3645 return newNode (NULLOP, initExpr,
3646 createWhile (trueLabel, continueLabel,
3647 falseLabel, condExpr, forBody));
3648 /* vanilla for statement */
3649 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3651 if (condExpr && !IS_IFX (condExpr))
3652 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3655 /* attach condition label to condition */
3656 condExpr = createLabel (condLabel, condExpr);
3658 /* attach body label to body */
3659 forBody = createLabel (trueLabel, forBody);
3661 /* attach continue to forLoop expression & attach */
3662 /* goto the forcond @ and of loopExpression */
3663 loopExpr = createLabel (continueLabel,
3667 newAst_VALUE (symbolVal (condLabel)),
3669 /* now start putting them together */
3670 forTree = newNode (NULLOP, initExpr, condExpr);
3671 forTree = newNode (NULLOP, forTree, forBody);
3672 forTree = newNode (NULLOP, forTree, loopExpr);
3673 /* finally add the break label */
3674 forTree = newNode (NULLOP, forTree,
3675 createLabel (falseLabel, NULL));
3679 /*-----------------------------------------------------------------*/
3680 /* createWhile - creates parse tree for while statement */
3681 /* the while statement will be created as follows */
3683 /* _while_continue_n: */
3684 /* condition_expression +-> trueLabel -> _while_boby_n */
3686 /* +-> falseLabel -> _while_break_n */
3687 /* _while_body_n: */
3689 /* goto _while_continue_n */
3690 /* _while_break_n: */
3691 /*-----------------------------------------------------------------*/
3693 createWhile (symbol * trueLabel, symbol * continueLabel,
3694 symbol * falseLabel, ast * condExpr, ast * whileBody)
3698 /* put the continue label */
3699 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3700 condExpr = createLabel (continueLabel, condExpr);
3701 condExpr->lineno = 0;
3703 /* put the body label in front of the body */
3704 whileBody = createLabel (trueLabel, whileBody);
3705 whileBody->lineno = 0;
3706 /* put a jump to continue at the end of the body */
3707 /* and put break label at the end of the body */
3708 whileBody = newNode (NULLOP,
3711 newAst_VALUE (symbolVal (continueLabel)),
3712 createLabel (falseLabel, NULL)));
3714 /* put it all together */
3715 if (IS_IFX (condExpr))
3716 whileTree = condExpr;
3719 whileTree = newNode (IFX, condExpr, NULL);
3720 /* put the true & false labels in place */
3721 whileTree->trueLabel = trueLabel;
3722 whileTree->falseLabel = falseLabel;
3725 return newNode (NULLOP, whileTree, whileBody);
3728 /*-----------------------------------------------------------------*/
3729 /* optimizeGetHbit - get highest order bit of the expression */
3730 /*-----------------------------------------------------------------*/
3732 optimizeGetHbit (ast * tree)
3735 /* if this is not a bit and */
3736 if (!IS_BITAND (tree))
3739 /* will look for tree of the form
3740 ( expr >> ((sizeof expr) -1) ) & 1 */
3741 if (!IS_AST_LIT_VALUE (tree->right))
3744 if (AST_LIT_VALUE (tree->right) != 1)
3747 if (!IS_RIGHT_OP (tree->left))
3750 if (!IS_AST_LIT_VALUE (tree->left->right))
3753 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3754 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3757 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3761 /*-----------------------------------------------------------------*/
3762 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3763 /*-----------------------------------------------------------------*/
3765 optimizeRRCRLC (ast * root)
3767 /* will look for trees of the form
3768 (?expr << 1) | (?expr >> 7) or
3769 (?expr >> 7) | (?expr << 1) will make that
3770 into a RLC : operation ..
3772 (?expr >> 1) | (?expr << 7) or
3773 (?expr << 7) | (?expr >> 1) will make that
3774 into a RRC operation
3775 note : by 7 I mean (number of bits required to hold the
3777 /* if the root operations is not a | operation the not */
3778 if (!IS_BITOR (root))
3781 /* I have to think of a better way to match patterns this sucks */
3782 /* that aside let start looking for the first case : I use a the
3783 negative check a lot to improve the efficiency */
3784 /* (?expr << 1) | (?expr >> 7) */
3785 if (IS_LEFT_OP (root->left) &&
3786 IS_RIGHT_OP (root->right))
3789 if (!SPEC_USIGN (TETYPE (root->left->left)))
3792 if (!IS_AST_LIT_VALUE (root->left->right) ||
3793 !IS_AST_LIT_VALUE (root->right->right))
3796 /* make sure it is the same expression */
3797 if (!isAstEqual (root->left->left,
3801 if (AST_LIT_VALUE (root->left->right) != 1)
3804 if (AST_LIT_VALUE (root->right->right) !=
3805 (getSize (TTYPE (root->left->left)) * 8 - 1))
3808 /* whew got the first case : create the AST */
3809 return newNode (RLC, root->left->left, NULL);
3813 /* check for second case */
3814 /* (?expr >> 7) | (?expr << 1) */
3815 if (IS_LEFT_OP (root->right) &&
3816 IS_RIGHT_OP (root->left))
3819 if (!SPEC_USIGN (TETYPE (root->left->left)))
3822 if (!IS_AST_LIT_VALUE (root->left->right) ||
3823 !IS_AST_LIT_VALUE (root->right->right))
3826 /* make sure it is the same symbol */
3827 if (!isAstEqual (root->left->left,
3831 if (AST_LIT_VALUE (root->right->right) != 1)
3834 if (AST_LIT_VALUE (root->left->right) !=
3835 (getSize (TTYPE (root->left->left)) * 8 - 1))
3838 /* whew got the first case : create the AST */
3839 return newNode (RLC, root->left->left, NULL);
3844 /* third case for RRC */
3845 /* (?symbol >> 1) | (?symbol << 7) */
3846 if (IS_LEFT_OP (root->right) &&
3847 IS_RIGHT_OP (root->left))
3850 if (!SPEC_USIGN (TETYPE (root->left->left)))
3853 if (!IS_AST_LIT_VALUE (root->left->right) ||
3854 !IS_AST_LIT_VALUE (root->right->right))
3857 /* make sure it is the same symbol */
3858 if (!isAstEqual (root->left->left,
3862 if (AST_LIT_VALUE (root->left->right) != 1)
3865 if (AST_LIT_VALUE (root->right->right) !=
3866 (getSize (TTYPE (root->left->left)) * 8 - 1))
3869 /* whew got the first case : create the AST */
3870 return newNode (RRC, root->left->left, NULL);
3874 /* fourth and last case for now */
3875 /* (?symbol << 7) | (?symbol >> 1) */
3876 if (IS_RIGHT_OP (root->right) &&
3877 IS_LEFT_OP (root->left))
3880 if (!SPEC_USIGN (TETYPE (root->left->left)))
3883 if (!IS_AST_LIT_VALUE (root->left->right) ||
3884 !IS_AST_LIT_VALUE (root->right->right))
3887 /* make sure it is the same symbol */
3888 if (!isAstEqual (root->left->left,
3892 if (AST_LIT_VALUE (root->right->right) != 1)
3895 if (AST_LIT_VALUE (root->left->right) !=
3896 (getSize (TTYPE (root->left->left)) * 8 - 1))
3899 /* whew got the first case : create the AST */
3900 return newNode (RRC, root->left->left, NULL);
3904 /* not found return root */
3908 /*-----------------------------------------------------------------*/
3909 /* optimizeCompare - otimizes compares for bit variables */
3910 /*-----------------------------------------------------------------*/
3912 optimizeCompare (ast * root)
3914 ast *optExpr = NULL;
3917 unsigned int litValue;
3919 /* if nothing then return nothing */
3923 /* if not a compare op then do leaves */
3924 if (!IS_COMPARE_OP (root))
3926 root->left = optimizeCompare (root->left);
3927 root->right = optimizeCompare (root->right);
3931 /* if left & right are the same then depending
3932 of the operation do */
3933 if (isAstEqual (root->left, root->right))
3935 switch (root->opval.op)
3940 optExpr = newAst_VALUE (constVal ("0"));
3945 optExpr = newAst_VALUE (constVal ("1"));
3949 return decorateType (optExpr);
3952 vleft = (root->left->type == EX_VALUE ?
3953 root->left->opval.val : NULL);
3955 vright = (root->right->type == EX_VALUE ?
3956 root->right->opval.val : NULL);
3958 /* if left is a BITVAR in BITSPACE */
3959 /* and right is a LITERAL then opt- */
3960 /* imize else do nothing */
3961 if (vleft && vright &&
3962 IS_BITVAR (vleft->etype) &&
3963 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3964 IS_LITERAL (vright->etype))
3967 /* if right side > 1 then comparison may never succeed */
3968 if ((litValue = (int) floatFromVal (vright)) > 1)
3970 werror (W_BAD_COMPARE);
3976 switch (root->opval.op)
3978 case '>': /* bit value greater than 1 cannot be */
3979 werror (W_BAD_COMPARE);
3983 case '<': /* bit value < 1 means 0 */
3985 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3988 case LE_OP: /* bit value <= 1 means no check */
3989 optExpr = newAst_VALUE (vright);
3992 case GE_OP: /* bit value >= 1 means only check for = */
3994 optExpr = newAst_VALUE (vleft);
3999 { /* literal is zero */
4000 switch (root->opval.op)
4002 case '<': /* bit value < 0 cannot be */
4003 werror (W_BAD_COMPARE);
4007 case '>': /* bit value > 0 means 1 */
4009 optExpr = newAst_VALUE (vleft);
4012 case LE_OP: /* bit value <= 0 means no check */
4013 case GE_OP: /* bit value >= 0 means no check */
4014 werror (W_BAD_COMPARE);
4018 case EQ_OP: /* bit == 0 means ! of bit */
4019 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4023 return decorateType (resolveSymbols (optExpr));
4024 } /* end-of-if of BITVAR */
4029 /*-----------------------------------------------------------------*/
4030 /* addSymToBlock : adds the symbol to the first block we find */
4031 /*-----------------------------------------------------------------*/
4033 addSymToBlock (symbol * sym, ast * tree)
4035 /* reached end of tree or a leaf */
4036 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4040 if (IS_AST_OP (tree) &&
4041 tree->opval.op == BLOCK)
4044 symbol *lsym = copySymbol (sym);
4046 lsym->next = AST_VALUES (tree, sym);
4047 AST_VALUES (tree, sym) = lsym;
4051 addSymToBlock (sym, tree->left);
4052 addSymToBlock (sym, tree->right);
4055 /*-----------------------------------------------------------------*/
4056 /* processRegParms - do processing for register parameters */
4057 /*-----------------------------------------------------------------*/
4059 processRegParms (value * args, ast * body)
4063 if (IS_REGPARM (args->etype))
4064 addSymToBlock (args->sym, body);
4069 /*-----------------------------------------------------------------*/
4070 /* resetParmKey - resets the operandkeys for the symbols */
4071 /*-----------------------------------------------------------------*/
4072 DEFSETFUNC (resetParmKey)
4083 /*-----------------------------------------------------------------*/
4084 /* createFunction - This is the key node that calls the iCode for */
4085 /* generating the code for a function. Note code */
4086 /* is generated function by function, later when */
4087 /* add inter-procedural analysis this will change */
4088 /*-----------------------------------------------------------------*/
4090 createFunction (symbol * name, ast * body)
4096 iCode *piCode = NULL;
4098 /* if check function return 0 then some problem */
4099 if (checkFunction (name, NULL) == 0)
4102 /* create a dummy block if none exists */
4104 body = newNode (BLOCK, NULL, NULL);
4108 /* check if the function name already in the symbol table */
4109 if ((csym = findSym (SymbolTab, NULL, name->name)))
4112 /* special case for compiler defined functions
4113 we need to add the name to the publics list : this
4114 actually means we are now compiling the compiler
4118 addSet (&publics, name);
4124 allocVariables (name);
4126 name->lastLine = yylineno;
4128 processFuncArgs (currFunc, 0);
4130 /* set the stack pointer */
4131 /* PENDING: check this for the mcs51 */
4132 stackPtr = -port->stack.direction * port->stack.call_overhead;
4133 if (IFFUNC_ISISR (name->type))
4134 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4135 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4136 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4138 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4140 fetype = getSpec (name->type); /* get the specifier for the function */
4141 /* if this is a reentrant function then */
4142 if (IFFUNC_ISREENT (name->type))
4145 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4147 /* do processing for parameters that are passed in registers */
4148 processRegParms (FUNC_ARGS(name->type), body);
4150 /* set the stack pointer */
4154 /* allocate & autoinit the block variables */
4155 processBlockVars (body, &stack, ALLOCATE);
4157 /* save the stack information */
4158 if (options.useXstack)
4159 name->xstack = SPEC_STAK (fetype) = stack;
4161 name->stack = SPEC_STAK (fetype) = stack;
4163 /* name needs to be mangled */
4164 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4166 body = resolveSymbols (body); /* resolve the symbols */
4167 body = decorateType (body); /* propagateType & do semantic checks */
4169 ex = newAst_VALUE (symbolVal (name)); /* create name */
4170 ex = newNode (FUNCTION, ex, body);
4171 ex->values.args = FUNC_ARGS(name->type);
4173 if (options.dump_tree) PA(ex);
4176 werror (E_FUNC_NO_CODE, name->name);
4180 /* create the node & generate intermediate code */
4182 codeOutFile = code->oFile;
4183 piCode = iCodeFromAst (ex);
4187 werror (E_FUNC_NO_CODE, name->name);
4191 eBBlockFromiCode (piCode);
4193 /* if there are any statics then do them */
4196 GcurMemmap = statsg;
4197 codeOutFile = statsg->oFile;
4198 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4204 /* dealloc the block variables */
4205 processBlockVars (body, &stack, DEALLOCATE);
4206 /* deallocate paramaters */
4207 deallocParms (FUNC_ARGS(name->type));
4209 if (IFFUNC_ISREENT (name->type))
4212 /* we are done freeup memory & cleanup */
4216 FUNC_HASBODY(name->type) = 1;
4217 addSet (&operKeyReset, name);
4218 applyToSet (operKeyReset, resetParmKey);
4221 cdbStructBlock (1, cdbFile);
4223 cleanUpLevel (LabelTab, 0);
4224 cleanUpBlock (StructTab, 1);
4225 cleanUpBlock (TypedefTab, 1);
4227 xstack->syms = NULL;
4228 istack->syms = NULL;
4233 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4234 /*-----------------------------------------------------------------*/
4235 /* ast_print : prints the ast (for debugging purposes) */
4236 /*-----------------------------------------------------------------*/
4238 void ast_print (ast * tree, FILE *outfile, int indent)
4243 /* can print only decorated trees */
4244 if (!tree->decorated) return;
4246 /* if any child is an error | this one is an error do nothing */
4247 if (tree->isError ||
4248 (tree->left && tree->left->isError) ||
4249 (tree->right && tree->right->isError)) {
4250 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4254 /* print the line */
4255 /* if not block & function */
4256 if (tree->type == EX_OP &&
4257 (tree->opval.op != FUNCTION &&
4258 tree->opval.op != BLOCK &&
4259 tree->opval.op != NULLOP)) {
4262 if (tree->opval.op == FUNCTION) {
4263 fprintf(outfile,"FUNCTION (%p) type (",tree);
4264 printTypeChain (tree->ftype,outfile);
4265 fprintf(outfile,")\n");
4266 ast_print(tree->left,outfile,indent+4);
4267 ast_print(tree->right,outfile,indent+4);
4270 if (tree->opval.op == BLOCK) {
4271 symbol *decls = tree->values.sym;
4272 INDENT(indent+4,outfile);
4273 fprintf(outfile,"{\n");
4275 INDENT(indent+4,outfile);
4276 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4277 printTypeChain(decls->type,outfile);
4278 fprintf(outfile,")\n");
4280 decls = decls->next;
4282 ast_print(tree->right,outfile,indent+4);
4283 INDENT(indent+4,outfile);
4284 fprintf(outfile,"}\n");
4287 if (tree->opval.op == NULLOP) {
4288 fprintf(outfile,"\n");
4289 ast_print(tree->left,outfile,indent);
4290 fprintf(outfile,"\n");
4291 ast_print(tree->right,outfile,indent);
4294 INDENT(indent,outfile);
4296 /*------------------------------------------------------------------*/
4297 /*----------------------------*/
4298 /* leaf has been reached */
4299 /*----------------------------*/
4300 /* if this is of type value */
4301 /* just get the type */
4302 if (tree->type == EX_VALUE) {
4304 if (IS_LITERAL (tree->opval.val->etype)) {
4305 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4306 (int) floatFromVal(tree->opval.val),
4307 (int) floatFromVal(tree->opval.val),
4308 floatFromVal(tree->opval.val));
4309 } else if (tree->opval.val->sym) {
4310 /* if the undefined flag is set then give error message */
4311 if (tree->opval.val->sym->undefined) {
4312 fprintf(outfile,"UNDEFINED SYMBOL ");
4314 fprintf(outfile,"SYMBOL ");
4316 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4319 fprintf(outfile," type (");
4320 printTypeChain(tree->ftype,outfile);
4321 fprintf(outfile,")\n");
4323 fprintf(outfile,"\n");
4328 /* if type link for the case of cast */
4329 if (tree->type == EX_LINK) {
4330 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4331 printTypeChain(tree->opval.lnk,outfile);
4332 fprintf(outfile,")\n");
4337 /* depending on type of operator do */
4339 switch (tree->opval.op) {
4340 /*------------------------------------------------------------------*/
4341 /*----------------------------*/
4343 /*----------------------------*/
4345 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4346 printTypeChain(tree->ftype,outfile);
4347 fprintf(outfile,")\n");
4348 ast_print(tree->left,outfile,indent+4);
4349 ast_print(tree->right,outfile,indent+4);
4352 /*------------------------------------------------------------------*/
4353 /*----------------------------*/
4355 /*----------------------------*/
4357 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4358 printTypeChain(tree->ftype,outfile);
4359 fprintf(outfile,")\n");
4360 ast_print(tree->left,outfile,indent+4);
4361 ast_print(tree->right,outfile,indent+4);
4364 /*------------------------------------------------------------------*/
4365 /*----------------------------*/
4366 /* struct/union pointer */
4367 /*----------------------------*/
4369 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4370 printTypeChain(tree->ftype,outfile);
4371 fprintf(outfile,")\n");
4372 ast_print(tree->left,outfile,indent+4);
4373 ast_print(tree->right,outfile,indent+4);
4376 /*------------------------------------------------------------------*/
4377 /*----------------------------*/
4378 /* ++/-- operation */
4379 /*----------------------------*/
4380 case INC_OP: /* incerement operator unary so left only */
4381 fprintf(outfile,"INC_OP (%p) type (",tree);
4382 printTypeChain(tree->ftype,outfile);
4383 fprintf(outfile,")\n");
4384 ast_print(tree->left,outfile,indent+4);
4388 fprintf(outfile,"DEC_OP (%p) type (",tree);
4389 printTypeChain(tree->ftype,outfile);
4390 fprintf(outfile,")\n");
4391 ast_print(tree->left,outfile,indent+4);
4394 /*------------------------------------------------------------------*/
4395 /*----------------------------*/
4397 /*----------------------------*/
4400 fprintf(outfile,"& (%p) type (",tree);
4401 printTypeChain(tree->ftype,outfile);
4402 fprintf(outfile,")\n");
4403 ast_print(tree->left,outfile,indent+4);
4404 ast_print(tree->right,outfile,indent+4);
4406 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4407 printTypeChain(tree->ftype,outfile);
4408 fprintf(outfile,")\n");
4409 ast_print(tree->left,outfile,indent+4);
4410 ast_print(tree->right,outfile,indent+4);
4413 /*----------------------------*/
4415 /*----------------------------*/
4417 fprintf(outfile,"OR (%p) type (",tree);
4418 printTypeChain(tree->ftype,outfile);
4419 fprintf(outfile,")\n");
4420 ast_print(tree->left,outfile,indent+4);
4421 ast_print(tree->right,outfile,indent+4);
4423 /*------------------------------------------------------------------*/
4424 /*----------------------------*/
4426 /*----------------------------*/
4428 fprintf(outfile,"XOR (%p) type (",tree);
4429 printTypeChain(tree->ftype,outfile);
4430 fprintf(outfile,")\n");
4431 ast_print(tree->left,outfile,indent+4);
4432 ast_print(tree->right,outfile,indent+4);
4435 /*------------------------------------------------------------------*/
4436 /*----------------------------*/
4438 /*----------------------------*/
4440 fprintf(outfile,"DIV (%p) type (",tree);
4441 printTypeChain(tree->ftype,outfile);
4442 fprintf(outfile,")\n");
4443 ast_print(tree->left,outfile,indent+4);
4444 ast_print(tree->right,outfile,indent+4);
4446 /*------------------------------------------------------------------*/
4447 /*----------------------------*/
4449 /*----------------------------*/
4451 fprintf(outfile,"MOD (%p) type (",tree);
4452 printTypeChain(tree->ftype,outfile);
4453 fprintf(outfile,")\n");
4454 ast_print(tree->left,outfile,indent+4);
4455 ast_print(tree->right,outfile,indent+4);
4458 /*------------------------------------------------------------------*/
4459 /*----------------------------*/
4460 /* address dereference */
4461 /*----------------------------*/
4462 case '*': /* can be unary : if right is null then unary operation */
4464 fprintf(outfile,"DEREF (%p) type (",tree);
4465 printTypeChain(tree->ftype,outfile);
4466 fprintf(outfile,")\n");
4467 ast_print(tree->left,outfile,indent+4);
4470 /*------------------------------------------------------------------*/
4471 /*----------------------------*/
4472 /* multiplication */
4473 /*----------------------------*/
4474 fprintf(outfile,"MULT (%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);
4482 /*------------------------------------------------------------------*/
4483 /*----------------------------*/
4484 /* unary '+' operator */
4485 /*----------------------------*/
4489 fprintf(outfile,"UPLUS (%p) type (",tree);
4490 printTypeChain(tree->ftype,outfile);
4491 fprintf(outfile,")\n");
4492 ast_print(tree->left,outfile,indent+4);
4494 /*------------------------------------------------------------------*/
4495 /*----------------------------*/
4497 /*----------------------------*/
4498 fprintf(outfile,"ADD (%p) type (",tree);
4499 printTypeChain(tree->ftype,outfile);
4500 fprintf(outfile,")\n");
4501 ast_print(tree->left,outfile,indent+4);
4502 ast_print(tree->right,outfile,indent+4);
4505 /*------------------------------------------------------------------*/
4506 /*----------------------------*/
4508 /*----------------------------*/
4509 case '-': /* can be unary */
4511 fprintf(outfile,"UMINUS (%p) type (",tree);
4512 printTypeChain(tree->ftype,outfile);
4513 fprintf(outfile,")\n");
4514 ast_print(tree->left,outfile,indent+4);
4516 /*------------------------------------------------------------------*/
4517 /*----------------------------*/
4519 /*----------------------------*/
4520 fprintf(outfile,"SUB (%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);
4527 /*------------------------------------------------------------------*/
4528 /*----------------------------*/
4530 /*----------------------------*/
4532 fprintf(outfile,"COMPL (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+4);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4540 /*----------------------------*/
4542 fprintf(outfile,"NOT (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->left,outfile,indent+4);
4547 /*------------------------------------------------------------------*/
4548 /*----------------------------*/
4550 /*----------------------------*/
4552 fprintf(outfile,"RRC (%p) type (",tree);
4553 printTypeChain(tree->ftype,outfile);
4554 fprintf(outfile,")\n");
4555 ast_print(tree->left,outfile,indent+4);
4559 fprintf(outfile,"RLC (%p) type (",tree);
4560 printTypeChain(tree->ftype,outfile);
4561 fprintf(outfile,")\n");
4562 ast_print(tree->left,outfile,indent+4);
4565 fprintf(outfile,"GETHBIT (%p) type (",tree);
4566 printTypeChain(tree->ftype,outfile);
4567 fprintf(outfile,")\n");
4568 ast_print(tree->left,outfile,indent+4);
4571 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+4);
4575 ast_print(tree->right,outfile,indent+4);
4578 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+4);
4582 ast_print(tree->right,outfile,indent+4);
4584 /*------------------------------------------------------------------*/
4585 /*----------------------------*/
4587 /*----------------------------*/
4588 case CAST: /* change the type */
4589 fprintf(outfile,"CAST (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->right,outfile,indent+4);
4596 fprintf(outfile,"ANDAND (%p) type (",tree);
4597 printTypeChain(tree->ftype,outfile);
4598 fprintf(outfile,")\n");
4599 ast_print(tree->left,outfile,indent+4);
4600 ast_print(tree->right,outfile,indent+4);
4603 fprintf(outfile,"OROR (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+4);
4607 ast_print(tree->right,outfile,indent+4);
4610 /*------------------------------------------------------------------*/
4611 /*----------------------------*/
4612 /* comparison operators */
4613 /*----------------------------*/
4615 fprintf(outfile,"GT(>) (%p) type (",tree);
4616 printTypeChain(tree->ftype,outfile);
4617 fprintf(outfile,")\n");
4618 ast_print(tree->left,outfile,indent+4);
4619 ast_print(tree->right,outfile,indent+4);
4622 fprintf(outfile,"LT(<) (%p) type (",tree);
4623 printTypeChain(tree->ftype,outfile);
4624 fprintf(outfile,")\n");
4625 ast_print(tree->left,outfile,indent+4);
4626 ast_print(tree->right,outfile,indent+4);
4629 fprintf(outfile,"LE(<=) (%p) type (",tree);
4630 printTypeChain(tree->ftype,outfile);
4631 fprintf(outfile,")\n");
4632 ast_print(tree->left,outfile,indent+4);
4633 ast_print(tree->right,outfile,indent+4);
4636 fprintf(outfile,"GE(>=) (%p) type (",tree);
4637 printTypeChain(tree->ftype,outfile);
4638 fprintf(outfile,")\n");
4639 ast_print(tree->left,outfile,indent+4);
4640 ast_print(tree->right,outfile,indent+4);
4643 fprintf(outfile,"EQ(==) (%p) type (",tree);
4644 printTypeChain(tree->ftype,outfile);
4645 fprintf(outfile,")\n");
4646 ast_print(tree->left,outfile,indent+4);
4647 ast_print(tree->right,outfile,indent+4);
4650 fprintf(outfile,"NE(!=) (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+4);
4654 ast_print(tree->right,outfile,indent+4);
4655 /*------------------------------------------------------------------*/
4656 /*----------------------------*/
4658 /*----------------------------*/
4659 case SIZEOF: /* evaluate wihout code generation */
4660 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4663 /*------------------------------------------------------------------*/
4664 /*----------------------------*/
4665 /* conditional operator '?' */
4666 /*----------------------------*/
4668 fprintf(outfile,"QUEST(?) (%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);
4676 fprintf(outfile,"COLON(:) (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+4);
4680 ast_print(tree->right,outfile,indent+4);
4683 /*------------------------------------------------------------------*/
4684 /*----------------------------*/
4685 /* assignment operators */
4686 /*----------------------------*/
4688 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4689 printTypeChain(tree->ftype,outfile);
4690 fprintf(outfile,")\n");
4691 ast_print(tree->left,outfile,indent+4);
4692 ast_print(tree->right,outfile,indent+4);
4695 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->left,outfile,indent+4);
4699 ast_print(tree->right,outfile,indent+4);
4702 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4703 printTypeChain(tree->ftype,outfile);
4704 fprintf(outfile,")\n");
4705 ast_print(tree->left,outfile,indent+4);
4706 ast_print(tree->right,outfile,indent+4);
4709 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4710 printTypeChain(tree->ftype,outfile);
4711 fprintf(outfile,")\n");
4712 ast_print(tree->left,outfile,indent+4);
4713 ast_print(tree->right,outfile,indent+4);
4716 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4717 printTypeChain(tree->ftype,outfile);
4718 fprintf(outfile,")\n");
4719 ast_print(tree->left,outfile,indent+4);
4720 ast_print(tree->right,outfile,indent+4);
4723 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+4);
4727 ast_print(tree->right,outfile,indent+4);
4730 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+4);
4734 ast_print(tree->right,outfile,indent+4);
4736 /*------------------------------------------------------------------*/
4737 /*----------------------------*/
4739 /*----------------------------*/
4741 fprintf(outfile,"SUBASS(-=) (%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);
4747 /*------------------------------------------------------------------*/
4748 /*----------------------------*/
4750 /*----------------------------*/
4752 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4753 printTypeChain(tree->ftype,outfile);
4754 fprintf(outfile,")\n");
4755 ast_print(tree->left,outfile,indent+4);
4756 ast_print(tree->right,outfile,indent+4);
4758 /*------------------------------------------------------------------*/
4759 /*----------------------------*/
4760 /* straight assignemnt */
4761 /*----------------------------*/
4763 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+4);
4767 ast_print(tree->right,outfile,indent+4);
4769 /*------------------------------------------------------------------*/
4770 /*----------------------------*/
4771 /* comma operator */
4772 /*----------------------------*/
4774 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4775 printTypeChain(tree->ftype,outfile);
4776 fprintf(outfile,")\n");
4777 ast_print(tree->left,outfile,indent+4);
4778 ast_print(tree->right,outfile,indent+4);
4780 /*------------------------------------------------------------------*/
4781 /*----------------------------*/
4783 /*----------------------------*/
4786 fprintf(outfile,"CALL (%p) type (",tree);
4787 printTypeChain(tree->ftype,outfile);
4788 fprintf(outfile,")\n");
4789 ast_print(tree->left,outfile,indent+4);
4790 ast_print(tree->right,outfile,indent+4);
4793 fprintf(outfile,"PARM ");
4794 ast_print(tree->left,outfile,indent+4);
4795 if (tree->right && !IS_AST_PARAM(tree->right)) {
4796 fprintf(outfile,"PARM ");
4797 ast_print(tree->right,outfile,indent+4);
4800 /*------------------------------------------------------------------*/
4801 /*----------------------------*/
4802 /* return statement */
4803 /*----------------------------*/
4805 fprintf(outfile,"RETURN (%p) type (",tree);
4806 printTypeChain(tree->right->ftype,outfile);
4807 fprintf(outfile,")\n");
4808 ast_print(tree->right,outfile,indent+4);
4810 /*------------------------------------------------------------------*/
4811 /*----------------------------*/
4812 /* label statement */
4813 /*----------------------------*/
4815 fprintf(outfile,"LABEL (%p)",tree);
4816 ast_print(tree->left,outfile,indent+4);
4817 ast_print(tree->right,outfile,indent);
4819 /*------------------------------------------------------------------*/
4820 /*----------------------------*/
4821 /* switch statement */
4822 /*----------------------------*/
4826 fprintf(outfile,"SWITCH (%p) ",tree);
4827 ast_print(tree->left,outfile,0);
4828 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4829 INDENT(indent+4,outfile);
4830 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4831 (int) floatFromVal(val),
4832 tree->values.switchVals.swNum,
4833 (int) floatFromVal(val));
4835 ast_print(tree->right,outfile,indent);
4838 /*------------------------------------------------------------------*/
4839 /*----------------------------*/
4841 /*----------------------------*/
4843 fprintf(outfile,"IF (%p) \n",tree);
4844 ast_print(tree->left,outfile,indent+4);
4845 if (tree->trueLabel) {
4846 INDENT(indent,outfile);
4847 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4849 if (tree->falseLabel) {
4850 INDENT(indent,outfile);
4851 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4853 ast_print(tree->right,outfile,indent+4);
4855 /*------------------------------------------------------------------*/
4856 /*----------------------------*/
4858 /*----------------------------*/
4860 fprintf(outfile,"FOR (%p) \n",tree);
4861 if (AST_FOR( tree, initExpr)) {
4862 INDENT(indent+4,outfile);
4863 fprintf(outfile,"INIT EXPR ");
4864 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4866 if (AST_FOR( tree, condExpr)) {
4867 INDENT(indent+4,outfile);
4868 fprintf(outfile,"COND EXPR ");
4869 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4871 if (AST_FOR( tree, loopExpr)) {
4872 INDENT(indent+4,outfile);
4873 fprintf(outfile,"LOOP EXPR ");
4874 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4876 fprintf(outfile,"FOR LOOP BODY \n");
4877 ast_print(tree->left,outfile,indent+4);
4886 ast_print(t,stdout,1);