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, "addrress 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;
2148 werror (E_LVALUE_REQUIRED, "address of");
2149 goto errorTreeReturn;
2151 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2153 DCL_TYPE (p) = CPOINTER;
2154 DCL_PTR_CONST (p) = port->mem.code_ro;
2156 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2157 DCL_TYPE (p) = FPOINTER;
2158 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2159 DCL_TYPE (p) = PPOINTER;
2160 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2161 DCL_TYPE (p) = IPOINTER;
2162 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2163 DCL_TYPE (p) = EEPPOINTER;
2165 DCL_TYPE (p) = POINTER;
2167 if (IS_AST_SYM_VALUE (tree->left))
2169 AST_SYMBOL (tree->left)->addrtaken = 1;
2170 AST_SYMBOL (tree->left)->allocreq = 1;
2173 p->next = LTYPE (tree);
2175 TETYPE (tree) = getSpec (TTYPE (tree));
2176 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2177 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2182 /*------------------------------------------------------------------*/
2183 /*----------------------------*/
2185 /*----------------------------*/
2187 /* if the rewrite succeeds then don't go any furthur */
2189 ast *wtree = optimizeRRCRLC (tree);
2191 return decorateType (wtree);
2193 /*------------------------------------------------------------------*/
2194 /*----------------------------*/
2196 /*----------------------------*/
2198 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2200 werror (E_BITWISE_OP);
2201 werror (W_CONTINUE, "left & right types are ");
2202 printTypeChain (LTYPE (tree), stderr);
2203 fprintf (stderr, ",");
2204 printTypeChain (RTYPE (tree), stderr);
2205 fprintf (stderr, "\n");
2206 goto errorTreeReturn;
2209 /* if they are both literal then */
2210 /* rewrite the tree */
2211 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2213 tree->type = EX_VALUE;
2214 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2215 valFromType (RETYPE (tree)),
2217 tree->right = tree->left = NULL;
2218 TETYPE (tree) = tree->opval.val->etype;
2219 TTYPE (tree) = tree->opval.val->type;
2222 LRVAL (tree) = RRVAL (tree) = 1;
2223 TETYPE (tree) = getSpec (TTYPE (tree) =
2224 computeType (LTYPE (tree),
2227 /*------------------------------------------------------------------*/
2228 /*----------------------------*/
2230 /*----------------------------*/
2232 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2234 werror (E_INVALID_OP, "divide");
2235 goto errorTreeReturn;
2237 /* if they are both literal then */
2238 /* rewrite the tree */
2239 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2241 tree->type = EX_VALUE;
2242 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2243 valFromType (RETYPE (tree)));
2244 tree->right = tree->left = NULL;
2245 TETYPE (tree) = getSpec (TTYPE (tree) =
2246 tree->opval.val->type);
2249 LRVAL (tree) = RRVAL (tree) = 1;
2250 TETYPE (tree) = getSpec (TTYPE (tree) =
2251 computeType (LTYPE (tree),
2255 /*------------------------------------------------------------------*/
2256 /*----------------------------*/
2258 /*----------------------------*/
2260 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2262 werror (E_BITWISE_OP);
2263 werror (W_CONTINUE, "left & right types are ");
2264 printTypeChain (LTYPE (tree), stderr);
2265 fprintf (stderr, ",");
2266 printTypeChain (RTYPE (tree), stderr);
2267 fprintf (stderr, "\n");
2268 goto errorTreeReturn;
2270 /* if they are both literal then */
2271 /* rewrite the tree */
2272 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2274 tree->type = EX_VALUE;
2275 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2276 valFromType (RETYPE (tree)));
2277 tree->right = tree->left = NULL;
2278 TETYPE (tree) = getSpec (TTYPE (tree) =
2279 tree->opval.val->type);
2282 LRVAL (tree) = RRVAL (tree) = 1;
2283 TETYPE (tree) = getSpec (TTYPE (tree) =
2284 computeType (LTYPE (tree),
2288 /*------------------------------------------------------------------*/
2289 /*----------------------------*/
2290 /* address dereference */
2291 /*----------------------------*/
2292 case '*': /* can be unary : if right is null then unary operation */
2295 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2297 werror (E_PTR_REQD);
2298 goto errorTreeReturn;
2303 werror (E_LVALUE_REQUIRED, "pointer deref");
2304 goto errorTreeReturn;
2306 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2307 LTYPE (tree)->next : NULL);
2308 TETYPE (tree) = getSpec (TTYPE (tree));
2309 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2313 /*------------------------------------------------------------------*/
2314 /*----------------------------*/
2315 /* multiplication */
2316 /*----------------------------*/
2317 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2319 werror (E_INVALID_OP, "multiplication");
2320 goto errorTreeReturn;
2323 /* if they are both literal then */
2324 /* rewrite the tree */
2325 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2327 tree->type = EX_VALUE;
2328 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2329 valFromType (RETYPE (tree)));
2330 tree->right = tree->left = NULL;
2331 TETYPE (tree) = getSpec (TTYPE (tree) =
2332 tree->opval.val->type);
2336 /* if left is a literal exchange left & right */
2337 if (IS_LITERAL (LTYPE (tree)))
2339 ast *tTree = tree->left;
2340 tree->left = tree->right;
2341 tree->right = tTree;
2344 LRVAL (tree) = RRVAL (tree) = 1;
2345 /* promote result to int if left & right are char
2346 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2347 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2348 TETYPE (tree) = getSpec (TTYPE (tree) =
2349 computeType (LTYPE (tree),
2351 SPEC_NOUN(TETYPE(tree)) = V_INT;
2353 TETYPE (tree) = getSpec (TTYPE (tree) =
2354 computeType (LTYPE (tree),
2359 /*------------------------------------------------------------------*/
2360 /*----------------------------*/
2361 /* unary '+' operator */
2362 /*----------------------------*/
2367 if (!IS_INTEGRAL (LTYPE (tree)))
2369 werror (E_UNARY_OP, '+');
2370 goto errorTreeReturn;
2373 /* if left is a literal then do it */
2374 if (IS_LITERAL (LTYPE (tree)))
2376 tree->type = EX_VALUE;
2377 tree->opval.val = valFromType (LETYPE (tree));
2379 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2383 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2387 /*------------------------------------------------------------------*/
2388 /*----------------------------*/
2390 /*----------------------------*/
2392 /* this is not a unary operation */
2393 /* if both pointers then problem */
2394 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2395 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2397 werror (E_PTR_PLUS_PTR);
2398 goto errorTreeReturn;
2401 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2402 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2404 werror (E_PLUS_INVALID, "+");
2405 goto errorTreeReturn;
2408 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2409 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2411 werror (E_PLUS_INVALID, "+");
2412 goto errorTreeReturn;
2414 /* if they are both literal then */
2415 /* rewrite the tree */
2416 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2418 tree->type = EX_VALUE;
2419 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2420 valFromType (RETYPE (tree)));
2421 tree->right = tree->left = NULL;
2422 TETYPE (tree) = getSpec (TTYPE (tree) =
2423 tree->opval.val->type);
2427 /* if the right is a pointer or left is a literal
2428 xchange left & right */
2429 if (IS_ARRAY (RTYPE (tree)) ||
2430 IS_PTR (RTYPE (tree)) ||
2431 IS_LITERAL (LTYPE (tree)))
2433 ast *tTree = tree->left;
2434 tree->left = tree->right;
2435 tree->right = tTree;
2438 LRVAL (tree) = RRVAL (tree) = 1;
2439 /* if the left is a pointer */
2440 if (IS_PTR (LTYPE (tree)))
2441 TETYPE (tree) = getSpec (TTYPE (tree) =
2444 TETYPE (tree) = getSpec (TTYPE (tree) =
2445 computeType (LTYPE (tree),
2449 /*------------------------------------------------------------------*/
2450 /*----------------------------*/
2452 /*----------------------------*/
2453 case '-': /* can be unary */
2454 /* if right is null then unary */
2458 if (!IS_ARITHMETIC (LTYPE (tree)))
2460 werror (E_UNARY_OP, tree->opval.op);
2461 goto errorTreeReturn;
2464 /* if left is a literal then do it */
2465 if (IS_LITERAL (LTYPE (tree)))
2467 tree->type = EX_VALUE;
2468 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2470 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2471 SPEC_USIGN(TETYPE(tree)) = 0;
2475 TTYPE (tree) = LTYPE (tree);
2479 /*------------------------------------------------------------------*/
2480 /*----------------------------*/
2482 /*----------------------------*/
2484 if (!(IS_PTR (LTYPE (tree)) ||
2485 IS_ARRAY (LTYPE (tree)) ||
2486 IS_ARITHMETIC (LTYPE (tree))))
2488 werror (E_PLUS_INVALID, "-");
2489 goto errorTreeReturn;
2492 if (!(IS_PTR (RTYPE (tree)) ||
2493 IS_ARRAY (RTYPE (tree)) ||
2494 IS_ARITHMETIC (RTYPE (tree))))
2496 werror (E_PLUS_INVALID, "-");
2497 goto errorTreeReturn;
2500 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2501 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2502 IS_INTEGRAL (RTYPE (tree))))
2504 werror (E_PLUS_INVALID, "-");
2505 goto errorTreeReturn;
2508 /* if they are both literal then */
2509 /* rewrite the tree */
2510 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2512 tree->type = EX_VALUE;
2513 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2514 valFromType (RETYPE (tree)));
2515 tree->right = tree->left = NULL;
2516 TETYPE (tree) = getSpec (TTYPE (tree) =
2517 tree->opval.val->type);
2521 /* if the left & right are equal then zero */
2522 if (isAstEqual (tree->left, tree->right))
2524 tree->type = EX_VALUE;
2525 tree->left = tree->right = NULL;
2526 tree->opval.val = constVal ("0");
2527 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2531 /* if both of them are pointers or arrays then */
2532 /* the result is going to be an integer */
2533 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2534 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2535 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2537 /* if only the left is a pointer */
2538 /* then result is a pointer */
2539 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2540 TETYPE (tree) = getSpec (TTYPE (tree) =
2543 TETYPE (tree) = getSpec (TTYPE (tree) =
2544 computeType (LTYPE (tree),
2546 LRVAL (tree) = RRVAL (tree) = 1;
2549 /*------------------------------------------------------------------*/
2550 /*----------------------------*/
2552 /*----------------------------*/
2554 /* can be only integral type */
2555 if (!IS_INTEGRAL (LTYPE (tree)))
2557 werror (E_UNARY_OP, tree->opval.op);
2558 goto errorTreeReturn;
2561 /* if left is a literal then do it */
2562 if (IS_LITERAL (LTYPE (tree)))
2564 tree->type = EX_VALUE;
2565 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2567 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2571 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2574 /*------------------------------------------------------------------*/
2575 /*----------------------------*/
2577 /*----------------------------*/
2579 /* can be pointer */
2580 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2581 !IS_PTR (LTYPE (tree)) &&
2582 !IS_ARRAY (LTYPE (tree)))
2584 werror (E_UNARY_OP, tree->opval.op);
2585 goto errorTreeReturn;
2588 /* if left is a literal then do it */
2589 if (IS_LITERAL (LTYPE (tree)))
2591 tree->type = EX_VALUE;
2592 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2594 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2598 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2601 /*------------------------------------------------------------------*/
2602 /*----------------------------*/
2604 /*----------------------------*/
2607 TTYPE (tree) = LTYPE (tree);
2608 TETYPE (tree) = LETYPE (tree);
2612 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2617 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2619 werror (E_SHIFT_OP_INVALID);
2620 werror (W_CONTINUE, "left & right types are ");
2621 printTypeChain (LTYPE (tree), stderr);
2622 fprintf (stderr, ",");
2623 printTypeChain (RTYPE (tree), stderr);
2624 fprintf (stderr, "\n");
2625 goto errorTreeReturn;
2628 /* if they are both literal then */
2629 /* rewrite the tree */
2630 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2632 tree->type = EX_VALUE;
2633 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2634 valFromType (RETYPE (tree)),
2635 (tree->opval.op == LEFT_OP ? 1 : 0));
2636 tree->right = tree->left = NULL;
2637 TETYPE (tree) = getSpec (TTYPE (tree) =
2638 tree->opval.val->type);
2641 /* if only the right side is a literal & we are
2642 shifting more than size of the left operand then zero */
2643 if (IS_LITERAL (RTYPE (tree)) &&
2644 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2645 (getSize (LTYPE (tree)) * 8))
2647 werror (W_SHIFT_CHANGED,
2648 (tree->opval.op == LEFT_OP ? "left" : "right"));
2649 tree->type = EX_VALUE;
2650 tree->left = tree->right = NULL;
2651 tree->opval.val = constVal ("0");
2652 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2655 LRVAL (tree) = RRVAL (tree) = 1;
2656 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2658 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2662 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2666 /*------------------------------------------------------------------*/
2667 /*----------------------------*/
2669 /*----------------------------*/
2670 case CAST: /* change the type */
2671 /* cannot cast to an aggregate type */
2672 if (IS_AGGREGATE (LTYPE (tree)))
2674 werror (E_CAST_ILLEGAL);
2675 goto errorTreeReturn;
2678 /* make sure the type is complete and sane */
2679 checkTypeSanity(LETYPE(tree), "(cast)");
2682 /* if the right is a literal replace the tree */
2683 if (IS_LITERAL (RETYPE (tree))) {
2684 if (!IS_PTR (LTYPE (tree))) {
2685 tree->type = EX_VALUE;
2687 valCastLiteral (LTYPE (tree),
2688 floatFromVal (valFromType (RETYPE (tree))));
2691 TTYPE (tree) = tree->opval.val->type;
2692 tree->values.literalFromCast = 1;
2693 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2694 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2695 sym_link *rest = LTYPE(tree)->next;
2696 werror(W_LITERAL_GENERIC);
2697 TTYPE(tree) = newLink();
2698 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2699 TTYPE(tree)->next = rest;
2700 tree->left->opval.lnk = TTYPE(tree);
2703 TTYPE (tree) = LTYPE (tree);
2707 TTYPE (tree) = LTYPE (tree);
2711 /* if the right is a literal replace the tree */
2712 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2713 tree->type = EX_VALUE;
2715 valCastLiteral (LTYPE (tree),
2716 floatFromVal (valFromType (RETYPE (tree))));
2719 TTYPE (tree) = tree->opval.val->type;
2720 tree->values.literalFromCast = 1;
2722 TTYPE (tree) = LTYPE (tree);
2727 TETYPE (tree) = getSpec (TTYPE (tree));
2731 /*------------------------------------------------------------------*/
2732 /*----------------------------*/
2733 /* logical &&, || */
2734 /*----------------------------*/
2737 /* each must me arithmetic type or be a pointer */
2738 if (!IS_PTR (LTYPE (tree)) &&
2739 !IS_ARRAY (LTYPE (tree)) &&
2740 !IS_INTEGRAL (LTYPE (tree)))
2742 werror (E_COMPARE_OP);
2743 goto errorTreeReturn;
2746 if (!IS_PTR (RTYPE (tree)) &&
2747 !IS_ARRAY (RTYPE (tree)) &&
2748 !IS_INTEGRAL (RTYPE (tree)))
2750 werror (E_COMPARE_OP);
2751 goto errorTreeReturn;
2753 /* if they are both literal then */
2754 /* rewrite the tree */
2755 if (IS_LITERAL (RTYPE (tree)) &&
2756 IS_LITERAL (LTYPE (tree)))
2758 tree->type = EX_VALUE;
2759 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2760 valFromType (RETYPE (tree)),
2762 tree->right = tree->left = NULL;
2763 TETYPE (tree) = getSpec (TTYPE (tree) =
2764 tree->opval.val->type);
2767 LRVAL (tree) = RRVAL (tree) = 1;
2768 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2771 /*------------------------------------------------------------------*/
2772 /*----------------------------*/
2773 /* comparison operators */
2774 /*----------------------------*/
2782 ast *lt = optimizeCompare (tree);
2788 /* if they are pointers they must be castable */
2789 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2791 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2793 werror (E_COMPARE_OP);
2794 fprintf (stderr, "comparing type ");
2795 printTypeChain (LTYPE (tree), stderr);
2796 fprintf (stderr, "to type ");
2797 printTypeChain (RTYPE (tree), stderr);
2798 fprintf (stderr, "\n");
2799 goto errorTreeReturn;
2802 /* else they should be promotable to one another */
2805 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2806 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2808 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2810 werror (E_COMPARE_OP);
2811 fprintf (stderr, "comparing type ");
2812 printTypeChain (LTYPE (tree), stderr);
2813 fprintf (stderr, "to type ");
2814 printTypeChain (RTYPE (tree), stderr);
2815 fprintf (stderr, "\n");
2816 goto errorTreeReturn;
2820 /* if they are both literal then */
2821 /* rewrite the tree */
2822 if (IS_LITERAL (RTYPE (tree)) &&
2823 IS_LITERAL (LTYPE (tree)))
2825 tree->type = EX_VALUE;
2826 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2827 valFromType (RETYPE (tree)),
2829 tree->right = tree->left = NULL;
2830 TETYPE (tree) = getSpec (TTYPE (tree) =
2831 tree->opval.val->type);
2834 LRVAL (tree) = RRVAL (tree) = 1;
2835 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2838 /*------------------------------------------------------------------*/
2839 /*----------------------------*/
2841 /*----------------------------*/
2842 case SIZEOF: /* evaluate wihout code generation */
2843 /* change the type to a integer */
2844 tree->type = EX_VALUE;
2845 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2846 tree->opval.val = constVal (buffer);
2847 tree->right = tree->left = NULL;
2848 TETYPE (tree) = getSpec (TTYPE (tree) =
2849 tree->opval.val->type);
2852 /*------------------------------------------------------------------*/
2853 /*----------------------------*/
2854 /* conditional operator '?' */
2855 /*----------------------------*/
2857 /* the type is value of the colon operator (on the right) */
2858 assert(IS_COLON_OP(tree->right));
2859 /* if already known then replace the tree : optimizer will do it
2860 but faster to do it here */
2861 if (IS_LITERAL (LTYPE(tree))) {
2862 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2863 return tree->right->left ;
2865 return tree->right->right ;
2868 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2869 TETYPE (tree) = getSpec (TTYPE (tree));
2874 /* if they don't match we have a problem */
2875 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2877 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2878 goto errorTreeReturn;
2881 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2882 TETYPE (tree) = getSpec (TTYPE (tree));
2886 /*------------------------------------------------------------------*/
2887 /*----------------------------*/
2888 /* assignment operators */
2889 /*----------------------------*/
2892 /* for these it must be both must be integral */
2893 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2894 !IS_ARITHMETIC (RTYPE (tree)))
2896 werror (E_OPS_INTEGRAL);
2897 goto errorTreeReturn;
2900 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2902 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2903 werror (E_CODE_WRITE, " ");
2907 werror (E_LVALUE_REQUIRED, "*= or /=");
2908 goto errorTreeReturn;
2919 /* for these it must be both must be integral */
2920 if (!IS_INTEGRAL (LTYPE (tree)) ||
2921 !IS_INTEGRAL (RTYPE (tree)))
2923 werror (E_OPS_INTEGRAL);
2924 goto errorTreeReturn;
2927 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2929 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2930 werror (E_CODE_WRITE, " ");
2934 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2935 goto errorTreeReturn;
2941 /*------------------------------------------------------------------*/
2942 /*----------------------------*/
2944 /*----------------------------*/
2946 if (!(IS_PTR (LTYPE (tree)) ||
2947 IS_ARITHMETIC (LTYPE (tree))))
2949 werror (E_PLUS_INVALID, "-=");
2950 goto errorTreeReturn;
2953 if (!(IS_PTR (RTYPE (tree)) ||
2954 IS_ARITHMETIC (RTYPE (tree))))
2956 werror (E_PLUS_INVALID, "-=");
2957 goto errorTreeReturn;
2960 TETYPE (tree) = getSpec (TTYPE (tree) =
2961 computeType (LTYPE (tree),
2964 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2965 werror (E_CODE_WRITE, " ");
2969 werror (E_LVALUE_REQUIRED, "-=");
2970 goto errorTreeReturn;
2976 /*------------------------------------------------------------------*/
2977 /*----------------------------*/
2979 /*----------------------------*/
2981 /* this is not a unary operation */
2982 /* if both pointers then problem */
2983 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2985 werror (E_PTR_PLUS_PTR);
2986 goto errorTreeReturn;
2989 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2991 werror (E_PLUS_INVALID, "+=");
2992 goto errorTreeReturn;
2995 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2997 werror (E_PLUS_INVALID, "+=");
2998 goto errorTreeReturn;
3001 TETYPE (tree) = getSpec (TTYPE (tree) =
3002 computeType (LTYPE (tree),
3005 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3006 werror (E_CODE_WRITE, " ");
3010 werror (E_LVALUE_REQUIRED, "+=");
3011 goto errorTreeReturn;
3014 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3015 tree->opval.op = '=';
3019 /*------------------------------------------------------------------*/
3020 /*----------------------------*/
3021 /* straight assignemnt */
3022 /*----------------------------*/
3024 /* cannot be an aggregate */
3025 if (IS_AGGREGATE (LTYPE (tree)))
3027 werror (E_AGGR_ASSIGN);
3028 goto errorTreeReturn;
3031 /* they should either match or be castable */
3032 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3034 werror (E_TYPE_MISMATCH, "assignment", " ");
3035 fprintf (stderr, "type --> '");
3036 printTypeChain (RTYPE (tree), stderr);
3037 fprintf (stderr, "' ");
3038 fprintf (stderr, "assigned to type --> '");
3039 printTypeChain (LTYPE (tree), stderr);
3040 fprintf (stderr, "'\n");
3041 goto errorTreeReturn;
3044 /* if the left side of the tree is of type void
3045 then report error */
3046 if (IS_VOID (LTYPE (tree)))
3048 werror (E_CAST_ZERO);
3049 printFromToType(RTYPE(tree), LTYPE(tree));
3052 TETYPE (tree) = getSpec (TTYPE (tree) =
3056 if (!tree->initMode ) {
3057 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3058 werror (E_CODE_WRITE, " ");
3062 werror (E_LVALUE_REQUIRED, "=");
3063 goto errorTreeReturn;
3068 /*------------------------------------------------------------------*/
3069 /*----------------------------*/
3070 /* comma operator */
3071 /*----------------------------*/
3073 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3076 /*------------------------------------------------------------------*/
3077 /*----------------------------*/
3079 /*----------------------------*/
3083 if (processParms (tree->left,
3084 FUNC_ARGS(tree->left->ftype),
3085 tree->right, &parmNumber, TRUE))
3086 goto errorTreeReturn;
3088 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3090 //IFFUNC_ARGS(tree->left->ftype) =
3091 //reverseVal (IFFUNC_ARGS(tree->left->ftype));
3092 reverseParms (tree->right);
3095 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3098 /*------------------------------------------------------------------*/
3099 /*----------------------------*/
3100 /* return statement */
3101 /*----------------------------*/
3106 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3108 werror (W_RETURN_MISMATCH);
3109 printFromToType (RTYPE(tree), currFunc->type->next);
3110 goto errorTreeReturn;
3113 if (IS_VOID (currFunc->type->next)
3115 !IS_VOID (RTYPE (tree)))
3117 werror (E_FUNC_VOID);
3118 goto errorTreeReturn;
3121 /* if there is going to be a casing required then add it */
3122 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3125 decorateType (newNode (CAST,
3126 newAst_LINK (copyLinkChain (currFunc->type->next)),
3135 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3137 werror (E_VOID_FUNC, currFunc->name);
3138 goto errorTreeReturn;
3141 TTYPE (tree) = TETYPE (tree) = NULL;
3144 /*------------------------------------------------------------------*/
3145 /*----------------------------*/
3146 /* switch statement */
3147 /*----------------------------*/
3149 /* the switch value must be an integer */
3150 if (!IS_INTEGRAL (LTYPE (tree)))
3152 werror (E_SWITCH_NON_INTEGER);
3153 goto errorTreeReturn;
3156 TTYPE (tree) = TETYPE (tree) = NULL;
3159 /*------------------------------------------------------------------*/
3160 /*----------------------------*/
3162 /*----------------------------*/
3164 tree->left = backPatchLabels (tree->left,
3167 TTYPE (tree) = TETYPE (tree) = NULL;
3170 /*------------------------------------------------------------------*/
3171 /*----------------------------*/
3173 /*----------------------------*/
3176 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3177 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3178 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3180 /* if the for loop is reversible then
3181 reverse it otherwise do what we normally
3187 if (isLoopReversible (tree, &sym, &init, &end))
3188 return reverseLoop (tree, sym, init, end);
3190 return decorateType (createFor (AST_FOR (tree, trueLabel),
3191 AST_FOR (tree, continueLabel),
3192 AST_FOR (tree, falseLabel),
3193 AST_FOR (tree, condLabel),
3194 AST_FOR (tree, initExpr),
3195 AST_FOR (tree, condExpr),
3196 AST_FOR (tree, loopExpr),
3200 TTYPE (tree) = TETYPE (tree) = NULL;
3204 /* some error found this tree will be killed */
3206 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3207 tree->opval.op = NULLOP;
3213 /*-----------------------------------------------------------------*/
3214 /* sizeofOp - processes size of operation */
3215 /*-----------------------------------------------------------------*/
3217 sizeofOp (sym_link * type)
3221 /* make sure the type is complete and sane */
3222 checkTypeSanity(type, "(sizeof)");
3224 /* get the size and convert it to character */
3225 sprintf (buff, "%d", getSize (type));
3227 /* now convert into value */
3228 return constVal (buff);
3232 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3233 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3234 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3235 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3236 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3237 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3238 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3240 /*-----------------------------------------------------------------*/
3241 /* backPatchLabels - change and or not operators to flow control */
3242 /*-----------------------------------------------------------------*/
3244 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3250 if (!(IS_ANDORNOT (tree)))
3253 /* if this an and */
3256 static int localLbl = 0;
3259 sprintf (buffer, "_and_%d", localLbl++);
3260 localLabel = newSymbol (buffer, NestLevel);
3262 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3264 /* if left is already a IFX then just change the if true label in that */
3265 if (!IS_IFX (tree->left))
3266 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3268 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3269 /* right is a IFX then just join */
3270 if (IS_IFX (tree->right))
3271 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3273 tree->right = createLabel (localLabel, tree->right);
3274 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3276 return newNode (NULLOP, tree->left, tree->right);
3279 /* if this is an or operation */
3282 static int localLbl = 0;
3285 sprintf (buffer, "_or_%d", localLbl++);
3286 localLabel = newSymbol (buffer, NestLevel);
3288 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3290 /* if left is already a IFX then just change the if true label in that */
3291 if (!IS_IFX (tree->left))
3292 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3294 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3295 /* right is a IFX then just join */
3296 if (IS_IFX (tree->right))
3297 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3299 tree->right = createLabel (localLabel, tree->right);
3300 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3302 return newNode (NULLOP, tree->left, tree->right);
3308 int wasnot = IS_NOT (tree->left);
3309 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3311 /* if the left is already a IFX */
3312 if (!IS_IFX (tree->left))
3313 tree->left = newNode (IFX, tree->left, NULL);
3317 tree->left->trueLabel = trueLabel;
3318 tree->left->falseLabel = falseLabel;
3322 tree->left->trueLabel = falseLabel;
3323 tree->left->falseLabel = trueLabel;
3330 tree->trueLabel = trueLabel;
3331 tree->falseLabel = falseLabel;
3338 /*-----------------------------------------------------------------*/
3339 /* createBlock - create expression tree for block */
3340 /*-----------------------------------------------------------------*/
3342 createBlock (symbol * decl, ast * body)
3346 /* if the block has nothing */
3350 ex = newNode (BLOCK, NULL, body);
3351 ex->values.sym = decl;
3353 ex->right = ex->right;
3359 /*-----------------------------------------------------------------*/
3360 /* createLabel - creates the expression tree for labels */
3361 /*-----------------------------------------------------------------*/
3363 createLabel (symbol * label, ast * stmnt)
3366 char name[SDCC_NAME_MAX + 1];
3369 /* must create fresh symbol if the symbol name */
3370 /* exists in the symbol table, since there can */
3371 /* be a variable with the same name as the labl */
3372 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3373 (csym->level == label->level))
3374 label = newSymbol (label->name, label->level);
3376 /* change the name before putting it in add _ */
3377 sprintf (name, "%s", label->name);
3379 /* put the label in the LabelSymbol table */
3380 /* but first check if a label of the same */
3382 if ((csym = findSym (LabelTab, NULL, name)))
3383 werror (E_DUPLICATE_LABEL, label->name);
3385 addSym (LabelTab, label, name, label->level, 0, 0);
3388 label->key = labelKey++;
3389 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3395 /*-----------------------------------------------------------------*/
3396 /* createCase - generates the parsetree for a case statement */
3397 /*-----------------------------------------------------------------*/
3399 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3401 char caseLbl[SDCC_NAME_MAX + 1];
3405 /* if the switch statement does not exist */
3406 /* then case is out of context */
3409 werror (E_CASE_CONTEXT);
3413 caseVal = decorateType (resolveSymbols (caseVal));
3414 /* if not a constant then error */
3415 if (!IS_LITERAL (caseVal->ftype))
3417 werror (E_CASE_CONSTANT);
3421 /* if not a integer than error */
3422 if (!IS_INTEGRAL (caseVal->ftype))
3424 werror (E_CASE_NON_INTEGER);
3428 /* find the end of the switch values chain */
3429 if (!(val = swStat->values.switchVals.swVals))
3430 swStat->values.switchVals.swVals = caseVal->opval.val;
3433 /* also order the cases according to value */
3435 int cVal = (int) floatFromVal (caseVal->opval.val);
3436 while (val && (int) floatFromVal (val) < cVal)
3442 /* if we reached the end then */
3445 pval->next = caseVal->opval.val;
3449 /* we found a value greater than */
3450 /* the current value we must add this */
3451 /* before the value */
3452 caseVal->opval.val->next = val;
3454 /* if this was the first in chain */
3455 if (swStat->values.switchVals.swVals == val)
3456 swStat->values.switchVals.swVals =
3459 pval->next = caseVal->opval.val;
3464 /* create the case label */
3465 sprintf (caseLbl, "_case_%d_%d",
3466 swStat->values.switchVals.swNum,
3467 (int) floatFromVal (caseVal->opval.val));
3469 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3474 /*-----------------------------------------------------------------*/
3475 /* createDefault - creates the parse tree for the default statement */
3476 /*-----------------------------------------------------------------*/
3478 createDefault (ast * swStat, ast * stmnt)
3480 char defLbl[SDCC_NAME_MAX + 1];
3482 /* if the switch statement does not exist */
3483 /* then case is out of context */
3486 werror (E_CASE_CONTEXT);
3490 /* turn on the default flag */
3491 swStat->values.switchVals.swDefault = 1;
3493 /* create the label */
3494 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3495 return createLabel (newSymbol (defLbl, 0), stmnt);
3498 /*-----------------------------------------------------------------*/
3499 /* createIf - creates the parsetree for the if statement */
3500 /*-----------------------------------------------------------------*/
3502 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3504 static int Lblnum = 0;
3506 symbol *ifTrue, *ifFalse, *ifEnd;
3508 /* if neither exists */
3509 if (!elseBody && !ifBody) {
3510 // if there are no side effects (i++, j() etc)
3511 if (!hasSEFcalls(condAst)) {
3516 /* create the labels */
3517 sprintf (buffer, "_iffalse_%d", Lblnum);
3518 ifFalse = newSymbol (buffer, NestLevel);
3519 /* if no else body then end == false */
3524 sprintf (buffer, "_ifend_%d", Lblnum);
3525 ifEnd = newSymbol (buffer, NestLevel);
3528 sprintf (buffer, "_iftrue_%d", Lblnum);
3529 ifTrue = newSymbol (buffer, NestLevel);
3533 /* attach the ifTrue label to the top of it body */
3534 ifBody = createLabel (ifTrue, ifBody);
3535 /* attach a goto end to the ifBody if else is present */
3538 ifBody = newNode (NULLOP, ifBody,
3540 newAst_VALUE (symbolVal (ifEnd)),
3542 /* put the elseLabel on the else body */
3543 elseBody = createLabel (ifFalse, elseBody);
3544 /* out the end at the end of the body */
3545 elseBody = newNode (NULLOP,
3547 createLabel (ifEnd, NULL));
3551 ifBody = newNode (NULLOP, ifBody,
3552 createLabel (ifFalse, NULL));
3554 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3555 if (IS_IFX (condAst))
3558 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3560 return newNode (NULLOP, ifTree,
3561 newNode (NULLOP, ifBody, elseBody));
3565 /*-----------------------------------------------------------------*/
3566 /* createDo - creates parse tree for do */
3569 /* _docontinue_n: */
3570 /* condition_expression +-> trueLabel -> _dobody_n */
3572 /* +-> falseLabel-> _dobreak_n */
3574 /*-----------------------------------------------------------------*/
3576 createDo (symbol * trueLabel, symbol * continueLabel,
3577 symbol * falseLabel, ast * condAst, ast * doBody)
3582 /* if the body does not exist then it is simple */
3585 condAst = backPatchLabels (condAst, continueLabel, NULL);
3586 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3587 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3588 doTree->trueLabel = continueLabel;
3589 doTree->falseLabel = NULL;
3593 /* otherwise we have a body */
3594 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3596 /* attach the body label to the top */
3597 doBody = createLabel (trueLabel, doBody);
3598 /* attach the continue label to end of body */
3599 doBody = newNode (NULLOP, doBody,
3600 createLabel (continueLabel, NULL));
3602 /* now put the break label at the end */
3603 if (IS_IFX (condAst))
3606 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3608 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3610 /* putting it together */
3611 return newNode (NULLOP, doBody, doTree);
3614 /*-----------------------------------------------------------------*/
3615 /* createFor - creates parse tree for 'for' statement */
3618 /* condExpr +-> trueLabel -> _forbody_n */
3620 /* +-> falseLabel-> _forbreak_n */
3623 /* _forcontinue_n: */
3625 /* goto _forcond_n ; */
3627 /*-----------------------------------------------------------------*/
3629 createFor (symbol * trueLabel, symbol * continueLabel,
3630 symbol * falseLabel, symbol * condLabel,
3631 ast * initExpr, ast * condExpr, ast * loopExpr,
3636 /* if loopexpression not present then we can generate it */
3637 /* the same way as a while */
3639 return newNode (NULLOP, initExpr,
3640 createWhile (trueLabel, continueLabel,
3641 falseLabel, condExpr, forBody));
3642 /* vanilla for statement */
3643 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3645 if (condExpr && !IS_IFX (condExpr))
3646 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3649 /* attach condition label to condition */
3650 condExpr = createLabel (condLabel, condExpr);
3652 /* attach body label to body */
3653 forBody = createLabel (trueLabel, forBody);
3655 /* attach continue to forLoop expression & attach */
3656 /* goto the forcond @ and of loopExpression */
3657 loopExpr = createLabel (continueLabel,
3661 newAst_VALUE (symbolVal (condLabel)),
3663 /* now start putting them together */
3664 forTree = newNode (NULLOP, initExpr, condExpr);
3665 forTree = newNode (NULLOP, forTree, forBody);
3666 forTree = newNode (NULLOP, forTree, loopExpr);
3667 /* finally add the break label */
3668 forTree = newNode (NULLOP, forTree,
3669 createLabel (falseLabel, NULL));
3673 /*-----------------------------------------------------------------*/
3674 /* createWhile - creates parse tree for while statement */
3675 /* the while statement will be created as follows */
3677 /* _while_continue_n: */
3678 /* condition_expression +-> trueLabel -> _while_boby_n */
3680 /* +-> falseLabel -> _while_break_n */
3681 /* _while_body_n: */
3683 /* goto _while_continue_n */
3684 /* _while_break_n: */
3685 /*-----------------------------------------------------------------*/
3687 createWhile (symbol * trueLabel, symbol * continueLabel,
3688 symbol * falseLabel, ast * condExpr, ast * whileBody)
3692 /* put the continue label */
3693 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3694 condExpr = createLabel (continueLabel, condExpr);
3695 condExpr->lineno = 0;
3697 /* put the body label in front of the body */
3698 whileBody = createLabel (trueLabel, whileBody);
3699 whileBody->lineno = 0;
3700 /* put a jump to continue at the end of the body */
3701 /* and put break label at the end of the body */
3702 whileBody = newNode (NULLOP,
3705 newAst_VALUE (symbolVal (continueLabel)),
3706 createLabel (falseLabel, NULL)));
3708 /* put it all together */
3709 if (IS_IFX (condExpr))
3710 whileTree = condExpr;
3713 whileTree = newNode (IFX, condExpr, NULL);
3714 /* put the true & false labels in place */
3715 whileTree->trueLabel = trueLabel;
3716 whileTree->falseLabel = falseLabel;
3719 return newNode (NULLOP, whileTree, whileBody);
3722 /*-----------------------------------------------------------------*/
3723 /* optimizeGetHbit - get highest order bit of the expression */
3724 /*-----------------------------------------------------------------*/
3726 optimizeGetHbit (ast * tree)
3729 /* if this is not a bit and */
3730 if (!IS_BITAND (tree))
3733 /* will look for tree of the form
3734 ( expr >> ((sizeof expr) -1) ) & 1 */
3735 if (!IS_AST_LIT_VALUE (tree->right))
3738 if (AST_LIT_VALUE (tree->right) != 1)
3741 if (!IS_RIGHT_OP (tree->left))
3744 if (!IS_AST_LIT_VALUE (tree->left->right))
3747 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3748 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3751 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3755 /*-----------------------------------------------------------------*/
3756 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3757 /*-----------------------------------------------------------------*/
3759 optimizeRRCRLC (ast * root)
3761 /* will look for trees of the form
3762 (?expr << 1) | (?expr >> 7) or
3763 (?expr >> 7) | (?expr << 1) will make that
3764 into a RLC : operation ..
3766 (?expr >> 1) | (?expr << 7) or
3767 (?expr << 7) | (?expr >> 1) will make that
3768 into a RRC operation
3769 note : by 7 I mean (number of bits required to hold the
3771 /* if the root operations is not a | operation the not */
3772 if (!IS_BITOR (root))
3775 /* I have to think of a better way to match patterns this sucks */
3776 /* that aside let start looking for the first case : I use a the
3777 negative check a lot to improve the efficiency */
3778 /* (?expr << 1) | (?expr >> 7) */
3779 if (IS_LEFT_OP (root->left) &&
3780 IS_RIGHT_OP (root->right))
3783 if (!SPEC_USIGN (TETYPE (root->left->left)))
3786 if (!IS_AST_LIT_VALUE (root->left->right) ||
3787 !IS_AST_LIT_VALUE (root->right->right))
3790 /* make sure it is the same expression */
3791 if (!isAstEqual (root->left->left,
3795 if (AST_LIT_VALUE (root->left->right) != 1)
3798 if (AST_LIT_VALUE (root->right->right) !=
3799 (getSize (TTYPE (root->left->left)) * 8 - 1))
3802 /* whew got the first case : create the AST */
3803 return newNode (RLC, root->left->left, NULL);
3807 /* check for second case */
3808 /* (?expr >> 7) | (?expr << 1) */
3809 if (IS_LEFT_OP (root->right) &&
3810 IS_RIGHT_OP (root->left))
3813 if (!SPEC_USIGN (TETYPE (root->left->left)))
3816 if (!IS_AST_LIT_VALUE (root->left->right) ||
3817 !IS_AST_LIT_VALUE (root->right->right))
3820 /* make sure it is the same symbol */
3821 if (!isAstEqual (root->left->left,
3825 if (AST_LIT_VALUE (root->right->right) != 1)
3828 if (AST_LIT_VALUE (root->left->right) !=
3829 (getSize (TTYPE (root->left->left)) * 8 - 1))
3832 /* whew got the first case : create the AST */
3833 return newNode (RLC, root->left->left, NULL);
3838 /* third case for RRC */
3839 /* (?symbol >> 1) | (?symbol << 7) */
3840 if (IS_LEFT_OP (root->right) &&
3841 IS_RIGHT_OP (root->left))
3844 if (!SPEC_USIGN (TETYPE (root->left->left)))
3847 if (!IS_AST_LIT_VALUE (root->left->right) ||
3848 !IS_AST_LIT_VALUE (root->right->right))
3851 /* make sure it is the same symbol */
3852 if (!isAstEqual (root->left->left,
3856 if (AST_LIT_VALUE (root->left->right) != 1)
3859 if (AST_LIT_VALUE (root->right->right) !=
3860 (getSize (TTYPE (root->left->left)) * 8 - 1))
3863 /* whew got the first case : create the AST */
3864 return newNode (RRC, root->left->left, NULL);
3868 /* fourth and last case for now */
3869 /* (?symbol << 7) | (?symbol >> 1) */
3870 if (IS_RIGHT_OP (root->right) &&
3871 IS_LEFT_OP (root->left))
3874 if (!SPEC_USIGN (TETYPE (root->left->left)))
3877 if (!IS_AST_LIT_VALUE (root->left->right) ||
3878 !IS_AST_LIT_VALUE (root->right->right))
3881 /* make sure it is the same symbol */
3882 if (!isAstEqual (root->left->left,
3886 if (AST_LIT_VALUE (root->right->right) != 1)
3889 if (AST_LIT_VALUE (root->left->right) !=
3890 (getSize (TTYPE (root->left->left)) * 8 - 1))
3893 /* whew got the first case : create the AST */
3894 return newNode (RRC, root->left->left, NULL);
3898 /* not found return root */
3902 /*-----------------------------------------------------------------*/
3903 /* optimizeCompare - otimizes compares for bit variables */
3904 /*-----------------------------------------------------------------*/
3906 optimizeCompare (ast * root)
3908 ast *optExpr = NULL;
3911 unsigned int litValue;
3913 /* if nothing then return nothing */
3917 /* if not a compare op then do leaves */
3918 if (!IS_COMPARE_OP (root))
3920 root->left = optimizeCompare (root->left);
3921 root->right = optimizeCompare (root->right);
3925 /* if left & right are the same then depending
3926 of the operation do */
3927 if (isAstEqual (root->left, root->right))
3929 switch (root->opval.op)
3934 optExpr = newAst_VALUE (constVal ("0"));
3939 optExpr = newAst_VALUE (constVal ("1"));
3943 return decorateType (optExpr);
3946 vleft = (root->left->type == EX_VALUE ?
3947 root->left->opval.val : NULL);
3949 vright = (root->right->type == EX_VALUE ?
3950 root->right->opval.val : NULL);
3952 /* if left is a BITVAR in BITSPACE */
3953 /* and right is a LITERAL then opt- */
3954 /* imize else do nothing */
3955 if (vleft && vright &&
3956 IS_BITVAR (vleft->etype) &&
3957 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3958 IS_LITERAL (vright->etype))
3961 /* if right side > 1 then comparison may never succeed */
3962 if ((litValue = (int) floatFromVal (vright)) > 1)
3964 werror (W_BAD_COMPARE);
3970 switch (root->opval.op)
3972 case '>': /* bit value greater than 1 cannot be */
3973 werror (W_BAD_COMPARE);
3977 case '<': /* bit value < 1 means 0 */
3979 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3982 case LE_OP: /* bit value <= 1 means no check */
3983 optExpr = newAst_VALUE (vright);
3986 case GE_OP: /* bit value >= 1 means only check for = */
3988 optExpr = newAst_VALUE (vleft);
3993 { /* literal is zero */
3994 switch (root->opval.op)
3996 case '<': /* bit value < 0 cannot be */
3997 werror (W_BAD_COMPARE);
4001 case '>': /* bit value > 0 means 1 */
4003 optExpr = newAst_VALUE (vleft);
4006 case LE_OP: /* bit value <= 0 means no check */
4007 case GE_OP: /* bit value >= 0 means no check */
4008 werror (W_BAD_COMPARE);
4012 case EQ_OP: /* bit == 0 means ! of bit */
4013 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4017 return decorateType (resolveSymbols (optExpr));
4018 } /* end-of-if of BITVAR */
4023 /*-----------------------------------------------------------------*/
4024 /* addSymToBlock : adds the symbol to the first block we find */
4025 /*-----------------------------------------------------------------*/
4027 addSymToBlock (symbol * sym, ast * tree)
4029 /* reached end of tree or a leaf */
4030 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4034 if (IS_AST_OP (tree) &&
4035 tree->opval.op == BLOCK)
4038 symbol *lsym = copySymbol (sym);
4040 lsym->next = AST_VALUES (tree, sym);
4041 AST_VALUES (tree, sym) = lsym;
4045 addSymToBlock (sym, tree->left);
4046 addSymToBlock (sym, tree->right);
4049 /*-----------------------------------------------------------------*/
4050 /* processRegParms - do processing for register parameters */
4051 /*-----------------------------------------------------------------*/
4053 processRegParms (value * args, ast * body)
4057 if (IS_REGPARM (args->etype))
4058 addSymToBlock (args->sym, body);
4063 /*-----------------------------------------------------------------*/
4064 /* resetParmKey - resets the operandkeys for the symbols */
4065 /*-----------------------------------------------------------------*/
4066 DEFSETFUNC (resetParmKey)
4077 /*-----------------------------------------------------------------*/
4078 /* createFunction - This is the key node that calls the iCode for */
4079 /* generating the code for a function. Note code */
4080 /* is generated function by function, later when */
4081 /* add inter-procedural analysis this will change */
4082 /*-----------------------------------------------------------------*/
4084 createFunction (symbol * name, ast * body)
4090 iCode *piCode = NULL;
4092 /* if check function return 0 then some problem */
4093 if (checkFunction (name, NULL) == 0)
4096 /* create a dummy block if none exists */
4098 body = newNode (BLOCK, NULL, NULL);
4102 /* check if the function name already in the symbol table */
4103 if ((csym = findSym (SymbolTab, NULL, name->name)))
4106 /* special case for compiler defined functions
4107 we need to add the name to the publics list : this
4108 actually means we are now compiling the compiler
4112 addSet (&publics, name);
4118 allocVariables (name);
4120 name->lastLine = yylineno;
4122 processFuncArgs (currFunc, 0);
4124 /* set the stack pointer */
4125 /* PENDING: check this for the mcs51 */
4126 stackPtr = -port->stack.direction * port->stack.call_overhead;
4127 if (IFFUNC_ISISR (name->type))
4128 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4129 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4130 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4132 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4134 fetype = getSpec (name->type); /* get the specifier for the function */
4135 /* if this is a reentrant function then */
4136 if (IFFUNC_ISREENT (name->type))
4139 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4141 /* do processing for parameters that are passed in registers */
4142 processRegParms (FUNC_ARGS(name->type), body);
4144 /* set the stack pointer */
4148 /* allocate & autoinit the block variables */
4149 processBlockVars (body, &stack, ALLOCATE);
4151 /* save the stack information */
4152 if (options.useXstack)
4153 name->xstack = SPEC_STAK (fetype) = stack;
4155 name->stack = SPEC_STAK (fetype) = stack;
4157 /* name needs to be mangled */
4158 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4160 body = resolveSymbols (body); /* resolve the symbols */
4161 body = decorateType (body); /* propagateType & do semantic checks */
4163 ex = newAst_VALUE (symbolVal (name)); /* create name */
4164 ex = newNode (FUNCTION, ex, body);
4165 ex->values.args = FUNC_ARGS(name->type);
4167 if (options.dump_tree) PA(ex);
4170 werror (E_FUNC_NO_CODE, name->name);
4174 /* create the node & generate intermediate code */
4176 codeOutFile = code->oFile;
4177 piCode = iCodeFromAst (ex);
4181 werror (E_FUNC_NO_CODE, name->name);
4185 eBBlockFromiCode (piCode);
4187 /* if there are any statics then do them */
4190 GcurMemmap = statsg;
4191 codeOutFile = statsg->oFile;
4192 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4198 /* dealloc the block variables */
4199 processBlockVars (body, &stack, DEALLOCATE);
4200 /* deallocate paramaters */
4201 deallocParms (FUNC_ARGS(name->type));
4203 if (IFFUNC_ISREENT (name->type))
4206 /* we are done freeup memory & cleanup */
4210 FUNC_HASBODY(name->type) = 1;
4211 addSet (&operKeyReset, name);
4212 applyToSet (operKeyReset, resetParmKey);
4215 cdbStructBlock (1, cdbFile);
4217 cleanUpLevel (LabelTab, 0);
4218 cleanUpBlock (StructTab, 1);
4219 cleanUpBlock (TypedefTab, 1);
4221 xstack->syms = NULL;
4222 istack->syms = NULL;
4227 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4228 /*-----------------------------------------------------------------*/
4229 /* ast_print : prints the ast (for debugging purposes) */
4230 /*-----------------------------------------------------------------*/
4232 void ast_print (ast * tree, FILE *outfile, int indent)
4237 /* can print only decorated trees */
4238 if (!tree->decorated) return;
4240 /* if any child is an error | this one is an error do nothing */
4241 if (tree->isError ||
4242 (tree->left && tree->left->isError) ||
4243 (tree->right && tree->right->isError)) {
4244 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4248 /* print the line */
4249 /* if not block & function */
4250 if (tree->type == EX_OP &&
4251 (tree->opval.op != FUNCTION &&
4252 tree->opval.op != BLOCK &&
4253 tree->opval.op != NULLOP)) {
4256 if (tree->opval.op == FUNCTION) {
4257 fprintf(outfile,"FUNCTION (%p) type (",tree);
4258 printTypeChain (tree->ftype,outfile);
4259 fprintf(outfile,")\n");
4260 ast_print(tree->left,outfile,indent+4);
4261 ast_print(tree->right,outfile,indent+4);
4264 if (tree->opval.op == BLOCK) {
4265 symbol *decls = tree->values.sym;
4266 INDENT(indent+4,outfile);
4267 fprintf(outfile,"{\n");
4269 INDENT(indent+4,outfile);
4270 fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4271 printTypeChain(decls->type,outfile);
4272 fprintf(outfile,")\n");
4274 decls = decls->next;
4276 ast_print(tree->right,outfile,indent+4);
4277 INDENT(indent+4,outfile);
4278 fprintf(outfile,"}\n");
4281 if (tree->opval.op == NULLOP) {
4282 fprintf(outfile,"\n");
4283 ast_print(tree->left,outfile,indent);
4284 fprintf(outfile,"\n");
4285 ast_print(tree->right,outfile,indent);
4288 INDENT(indent,outfile);
4290 /*------------------------------------------------------------------*/
4291 /*----------------------------*/
4292 /* leaf has been reached */
4293 /*----------------------------*/
4294 /* if this is of type value */
4295 /* just get the type */
4296 if (tree->type == EX_VALUE) {
4298 if (IS_LITERAL (tree->opval.val->etype)) {
4299 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4300 (int) floatFromVal(tree->opval.val),
4301 (int) floatFromVal(tree->opval.val),
4302 floatFromVal(tree->opval.val));
4303 } else if (tree->opval.val->sym) {
4304 /* if the undefined flag is set then give error message */
4305 if (tree->opval.val->sym->undefined) {
4306 fprintf(outfile,"UNDEFINED SYMBOL ");
4308 fprintf(outfile,"SYMBOL ");
4310 fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4313 fprintf(outfile," type (");
4314 printTypeChain(tree->ftype,outfile);
4315 fprintf(outfile,")\n");
4317 fprintf(outfile,"\n");
4322 /* if type link for the case of cast */
4323 if (tree->type == EX_LINK) {
4324 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4325 printTypeChain(tree->opval.lnk,outfile);
4326 fprintf(outfile,")\n");
4331 /* depending on type of operator do */
4333 switch (tree->opval.op) {
4334 /*------------------------------------------------------------------*/
4335 /*----------------------------*/
4337 /*----------------------------*/
4339 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4340 printTypeChain(tree->ftype,outfile);
4341 fprintf(outfile,")\n");
4342 ast_print(tree->left,outfile,indent+4);
4343 ast_print(tree->right,outfile,indent+4);
4346 /*------------------------------------------------------------------*/
4347 /*----------------------------*/
4349 /*----------------------------*/
4351 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4352 printTypeChain(tree->ftype,outfile);
4353 fprintf(outfile,")\n");
4354 ast_print(tree->left,outfile,indent+4);
4355 ast_print(tree->right,outfile,indent+4);
4358 /*------------------------------------------------------------------*/
4359 /*----------------------------*/
4360 /* struct/union pointer */
4361 /*----------------------------*/
4363 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4364 printTypeChain(tree->ftype,outfile);
4365 fprintf(outfile,")\n");
4366 ast_print(tree->left,outfile,indent+4);
4367 ast_print(tree->right,outfile,indent+4);
4370 /*------------------------------------------------------------------*/
4371 /*----------------------------*/
4372 /* ++/-- operation */
4373 /*----------------------------*/
4374 case INC_OP: /* incerement operator unary so left only */
4375 fprintf(outfile,"INC_OP (%p) type (",tree);
4376 printTypeChain(tree->ftype,outfile);
4377 fprintf(outfile,")\n");
4378 ast_print(tree->left,outfile,indent+4);
4382 fprintf(outfile,"DEC_OP (%p) type (",tree);
4383 printTypeChain(tree->ftype,outfile);
4384 fprintf(outfile,")\n");
4385 ast_print(tree->left,outfile,indent+4);
4388 /*------------------------------------------------------------------*/
4389 /*----------------------------*/
4391 /*----------------------------*/
4394 fprintf(outfile,"& (%p) type (",tree);
4395 printTypeChain(tree->ftype,outfile);
4396 fprintf(outfile,")\n");
4397 ast_print(tree->left,outfile,indent+4);
4398 ast_print(tree->right,outfile,indent+4);
4400 fprintf(outfile,"ADDRESS_OF (%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);
4407 /*----------------------------*/
4409 /*----------------------------*/
4411 fprintf(outfile,"OR (%p) type (",tree);
4412 printTypeChain(tree->ftype,outfile);
4413 fprintf(outfile,")\n");
4414 ast_print(tree->left,outfile,indent+4);
4415 ast_print(tree->right,outfile,indent+4);
4417 /*------------------------------------------------------------------*/
4418 /*----------------------------*/
4420 /*----------------------------*/
4422 fprintf(outfile,"XOR (%p) type (",tree);
4423 printTypeChain(tree->ftype,outfile);
4424 fprintf(outfile,")\n");
4425 ast_print(tree->left,outfile,indent+4);
4426 ast_print(tree->right,outfile,indent+4);
4429 /*------------------------------------------------------------------*/
4430 /*----------------------------*/
4432 /*----------------------------*/
4434 fprintf(outfile,"DIV (%p) type (",tree);
4435 printTypeChain(tree->ftype,outfile);
4436 fprintf(outfile,")\n");
4437 ast_print(tree->left,outfile,indent+4);
4438 ast_print(tree->right,outfile,indent+4);
4440 /*------------------------------------------------------------------*/
4441 /*----------------------------*/
4443 /*----------------------------*/
4445 fprintf(outfile,"MOD (%p) type (",tree);
4446 printTypeChain(tree->ftype,outfile);
4447 fprintf(outfile,")\n");
4448 ast_print(tree->left,outfile,indent+4);
4449 ast_print(tree->right,outfile,indent+4);
4452 /*------------------------------------------------------------------*/
4453 /*----------------------------*/
4454 /* address dereference */
4455 /*----------------------------*/
4456 case '*': /* can be unary : if right is null then unary operation */
4458 fprintf(outfile,"DEREF (%p) type (",tree);
4459 printTypeChain(tree->ftype,outfile);
4460 fprintf(outfile,")\n");
4461 ast_print(tree->left,outfile,indent+4);
4464 /*------------------------------------------------------------------*/
4465 /*----------------------------*/
4466 /* multiplication */
4467 /*----------------------------*/
4468 fprintf(outfile,"MULT (%p) type (",tree);
4469 printTypeChain(tree->ftype,outfile);
4470 fprintf(outfile,")\n");
4471 ast_print(tree->left,outfile,indent+4);
4472 ast_print(tree->right,outfile,indent+4);
4476 /*------------------------------------------------------------------*/
4477 /*----------------------------*/
4478 /* unary '+' operator */
4479 /*----------------------------*/
4483 fprintf(outfile,"UPLUS (%p) type (",tree);
4484 printTypeChain(tree->ftype,outfile);
4485 fprintf(outfile,")\n");
4486 ast_print(tree->left,outfile,indent+4);
4488 /*------------------------------------------------------------------*/
4489 /*----------------------------*/
4491 /*----------------------------*/
4492 fprintf(outfile,"ADD (%p) type (",tree);
4493 printTypeChain(tree->ftype,outfile);
4494 fprintf(outfile,")\n");
4495 ast_print(tree->left,outfile,indent+4);
4496 ast_print(tree->right,outfile,indent+4);
4499 /*------------------------------------------------------------------*/
4500 /*----------------------------*/
4502 /*----------------------------*/
4503 case '-': /* can be unary */
4505 fprintf(outfile,"UMINUS (%p) type (",tree);
4506 printTypeChain(tree->ftype,outfile);
4507 fprintf(outfile,")\n");
4508 ast_print(tree->left,outfile,indent+4);
4510 /*------------------------------------------------------------------*/
4511 /*----------------------------*/
4513 /*----------------------------*/
4514 fprintf(outfile,"SUB (%p) type (",tree);
4515 printTypeChain(tree->ftype,outfile);
4516 fprintf(outfile,")\n");
4517 ast_print(tree->left,outfile,indent+4);
4518 ast_print(tree->right,outfile,indent+4);
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4524 /*----------------------------*/
4526 fprintf(outfile,"COMPL (%p) type (",tree);
4527 printTypeChain(tree->ftype,outfile);
4528 fprintf(outfile,")\n");
4529 ast_print(tree->left,outfile,indent+4);
4531 /*------------------------------------------------------------------*/
4532 /*----------------------------*/
4534 /*----------------------------*/
4536 fprintf(outfile,"NOT (%p) type (",tree);
4537 printTypeChain(tree->ftype,outfile);
4538 fprintf(outfile,")\n");
4539 ast_print(tree->left,outfile,indent+4);
4541 /*------------------------------------------------------------------*/
4542 /*----------------------------*/
4544 /*----------------------------*/
4546 fprintf(outfile,"RRC (%p) type (",tree);
4547 printTypeChain(tree->ftype,outfile);
4548 fprintf(outfile,")\n");
4549 ast_print(tree->left,outfile,indent+4);
4553 fprintf(outfile,"RLC (%p) type (",tree);
4554 printTypeChain(tree->ftype,outfile);
4555 fprintf(outfile,")\n");
4556 ast_print(tree->left,outfile,indent+4);
4559 fprintf(outfile,"GETHBIT (%p) type (",tree);
4560 printTypeChain(tree->ftype,outfile);
4561 fprintf(outfile,")\n");
4562 ast_print(tree->left,outfile,indent+4);
4565 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4566 printTypeChain(tree->ftype,outfile);
4567 fprintf(outfile,")\n");
4568 ast_print(tree->left,outfile,indent+4);
4569 ast_print(tree->right,outfile,indent+4);
4572 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4573 printTypeChain(tree->ftype,outfile);
4574 fprintf(outfile,")\n");
4575 ast_print(tree->left,outfile,indent+4);
4576 ast_print(tree->right,outfile,indent+4);
4578 /*------------------------------------------------------------------*/
4579 /*----------------------------*/
4581 /*----------------------------*/
4582 case CAST: /* change the type */
4583 fprintf(outfile,"CAST (%p) type (",tree);
4584 printTypeChain(tree->ftype,outfile);
4585 fprintf(outfile,")\n");
4586 ast_print(tree->right,outfile,indent+4);
4590 fprintf(outfile,"ANDAND (%p) type (",tree);
4591 printTypeChain(tree->ftype,outfile);
4592 fprintf(outfile,")\n");
4593 ast_print(tree->left,outfile,indent+4);
4594 ast_print(tree->right,outfile,indent+4);
4597 fprintf(outfile,"OROR (%p) type (",tree);
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->left,outfile,indent+4);
4601 ast_print(tree->right,outfile,indent+4);
4604 /*------------------------------------------------------------------*/
4605 /*----------------------------*/
4606 /* comparison operators */
4607 /*----------------------------*/
4609 fprintf(outfile,"GT(>) (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+4);
4613 ast_print(tree->right,outfile,indent+4);
4616 fprintf(outfile,"LT(<) (%p) type (",tree);
4617 printTypeChain(tree->ftype,outfile);
4618 fprintf(outfile,")\n");
4619 ast_print(tree->left,outfile,indent+4);
4620 ast_print(tree->right,outfile,indent+4);
4623 fprintf(outfile,"LE(<=) (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+4);
4627 ast_print(tree->right,outfile,indent+4);
4630 fprintf(outfile,"GE(>=) (%p) type (",tree);
4631 printTypeChain(tree->ftype,outfile);
4632 fprintf(outfile,")\n");
4633 ast_print(tree->left,outfile,indent+4);
4634 ast_print(tree->right,outfile,indent+4);
4637 fprintf(outfile,"EQ(==) (%p) type (",tree);
4638 printTypeChain(tree->ftype,outfile);
4639 fprintf(outfile,")\n");
4640 ast_print(tree->left,outfile,indent+4);
4641 ast_print(tree->right,outfile,indent+4);
4644 fprintf(outfile,"NE(!=) (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+4);
4648 ast_print(tree->right,outfile,indent+4);
4649 /*------------------------------------------------------------------*/
4650 /*----------------------------*/
4652 /*----------------------------*/
4653 case SIZEOF: /* evaluate wihout code generation */
4654 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4657 /*------------------------------------------------------------------*/
4658 /*----------------------------*/
4659 /* conditional operator '?' */
4660 /*----------------------------*/
4662 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4663 printTypeChain(tree->ftype,outfile);
4664 fprintf(outfile,")\n");
4665 ast_print(tree->left,outfile,indent+4);
4666 ast_print(tree->right,outfile,indent+4);
4670 fprintf(outfile,"COLON(:) (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+4);
4674 ast_print(tree->right,outfile,indent+4);
4677 /*------------------------------------------------------------------*/
4678 /*----------------------------*/
4679 /* assignment operators */
4680 /*----------------------------*/
4682 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4683 printTypeChain(tree->ftype,outfile);
4684 fprintf(outfile,")\n");
4685 ast_print(tree->left,outfile,indent+4);
4686 ast_print(tree->right,outfile,indent+4);
4689 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+4);
4693 ast_print(tree->right,outfile,indent+4);
4696 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4703 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+4);
4707 ast_print(tree->right,outfile,indent+4);
4710 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+4);
4714 ast_print(tree->right,outfile,indent+4);
4717 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4718 printTypeChain(tree->ftype,outfile);
4719 fprintf(outfile,")\n");
4720 ast_print(tree->left,outfile,indent+4);
4721 ast_print(tree->right,outfile,indent+4);
4724 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4725 printTypeChain(tree->ftype,outfile);
4726 fprintf(outfile,")\n");
4727 ast_print(tree->left,outfile,indent+4);
4728 ast_print(tree->right,outfile,indent+4);
4730 /*------------------------------------------------------------------*/
4731 /*----------------------------*/
4733 /*----------------------------*/
4735 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4736 printTypeChain(tree->ftype,outfile);
4737 fprintf(outfile,")\n");
4738 ast_print(tree->left,outfile,indent+4);
4739 ast_print(tree->right,outfile,indent+4);
4741 /*------------------------------------------------------------------*/
4742 /*----------------------------*/
4744 /*----------------------------*/
4746 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4747 printTypeChain(tree->ftype,outfile);
4748 fprintf(outfile,")\n");
4749 ast_print(tree->left,outfile,indent+4);
4750 ast_print(tree->right,outfile,indent+4);
4752 /*------------------------------------------------------------------*/
4753 /*----------------------------*/
4754 /* straight assignemnt */
4755 /*----------------------------*/
4757 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4758 printTypeChain(tree->ftype,outfile);
4759 fprintf(outfile,")\n");
4760 ast_print(tree->left,outfile,indent+4);
4761 ast_print(tree->right,outfile,indent+4);
4763 /*------------------------------------------------------------------*/
4764 /*----------------------------*/
4765 /* comma operator */
4766 /*----------------------------*/
4768 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4769 printTypeChain(tree->ftype,outfile);
4770 fprintf(outfile,")\n");
4771 ast_print(tree->left,outfile,indent+4);
4772 ast_print(tree->right,outfile,indent+4);
4774 /*------------------------------------------------------------------*/
4775 /*----------------------------*/
4777 /*----------------------------*/
4780 fprintf(outfile,"CALL (%p) type (",tree);
4781 printTypeChain(tree->ftype,outfile);
4782 fprintf(outfile,")\n");
4783 ast_print(tree->left,outfile,indent+4);
4784 ast_print(tree->right,outfile,indent+4);
4787 fprintf(outfile,"PARM ");
4788 ast_print(tree->left,outfile,indent+4);
4789 if (tree->right && !IS_AST_PARAM(tree->right)) {
4790 fprintf(outfile,"PARM ");
4791 ast_print(tree->right,outfile,indent+4);
4794 /*------------------------------------------------------------------*/
4795 /*----------------------------*/
4796 /* return statement */
4797 /*----------------------------*/
4799 fprintf(outfile,"RETURN (%p) type (",tree);
4800 printTypeChain(tree->right->ftype,outfile);
4801 fprintf(outfile,")\n");
4802 ast_print(tree->right,outfile,indent+4);
4804 /*------------------------------------------------------------------*/
4805 /*----------------------------*/
4806 /* label statement */
4807 /*----------------------------*/
4809 fprintf(outfile,"LABEL (%p)",tree);
4810 ast_print(tree->left,outfile,indent+4);
4811 ast_print(tree->right,outfile,indent);
4813 /*------------------------------------------------------------------*/
4814 /*----------------------------*/
4815 /* switch statement */
4816 /*----------------------------*/
4820 fprintf(outfile,"SWITCH (%p) ",tree);
4821 ast_print(tree->left,outfile,0);
4822 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4823 INDENT(indent+4,outfile);
4824 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4825 (int) floatFromVal(val),
4826 tree->values.switchVals.swNum,
4827 (int) floatFromVal(val));
4829 ast_print(tree->right,outfile,indent);
4832 /*------------------------------------------------------------------*/
4833 /*----------------------------*/
4835 /*----------------------------*/
4837 fprintf(outfile,"IF (%p) \n",tree);
4838 ast_print(tree->left,outfile,indent+4);
4839 if (tree->trueLabel) {
4840 INDENT(indent,outfile);
4841 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4843 if (tree->falseLabel) {
4844 INDENT(indent,outfile);
4845 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4847 ast_print(tree->right,outfile,indent+4);
4849 /*------------------------------------------------------------------*/
4850 /*----------------------------*/
4852 /*----------------------------*/
4854 fprintf(outfile,"FOR (%p) \n",tree);
4855 if (AST_FOR( tree, initExpr)) {
4856 INDENT(indent+4,outfile);
4857 fprintf(outfile,"INIT EXPR ");
4858 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4860 if (AST_FOR( tree, condExpr)) {
4861 INDENT(indent+4,outfile);
4862 fprintf(outfile,"COND EXPR ");
4863 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4865 if (AST_FOR( tree, loopExpr)) {
4866 INDENT(indent+4,outfile);
4867 fprintf(outfile,"LOOP EXPR ");
4868 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4870 fprintf(outfile,"FOR LOOP BODY \n");
4871 ast_print(tree->left,outfile,indent+4);
4880 ast_print(t,stdout,1);