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;
263 dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
265 /* if this is a leaf */
267 if (src->type == EX_VALUE)
269 dest->opval.val = copyValue (src->opval.val);
274 if (src->type == EX_LINK)
276 dest->opval.lnk = copyLinkChain (src->opval.lnk);
280 dest->opval.op = src->opval.op;
282 /* if this is a node that has special values */
283 copyAstValues (dest, src);
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
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 (IS_VOID(actParm->ftype)) {
647 werror (E_VOID_VALUE_USED);
651 /* If this is a varargs function... */
652 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
657 if (IS_CAST_OP (actParm)
658 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
660 /* Parameter was explicitly typecast; don't touch it. */
664 /* The ternary ('?') operator is weird: the ftype of the
665 * operator is the type of the condition, but it will return a
666 * (possibly) different type.
668 if (IS_TERNARY_OP(actParm))
670 assert(IS_COLON_OP(actParm->right));
671 assert(actParm->right->left);
672 ftype = actParm->right->left->ftype;
676 ftype = actParm->ftype;
679 /* If it's a small integer, upcast to int. */
680 if (IS_INTEGRAL (ftype)
681 && (getSize (ftype) < (unsigned) INTSIZE))
683 newType = newAst_LINK(INTTYPE);
686 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
688 newType = newAst_LINK (copyLinkChain(ftype));
689 DCL_TYPE (newType->opval.lnk) = GPOINTER;
692 if (IS_AGGREGATE (ftype))
694 newType = newAst_LINK (copyLinkChain (ftype));
695 DCL_TYPE (newType->opval.lnk) = GPOINTER;
699 /* cast required; change this op to a cast. */
700 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
702 actParm->type = EX_OP;
703 actParm->opval.op = CAST;
704 actParm->left = newType;
705 actParm->right = parmCopy;
706 decorateType (actParm);
708 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
710 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
711 processParms (func, NULL, actParm->right, parmNumber, rightmost));
716 /* if defined parameters ended but actual has not & */
718 if (!defParm && actParm &&
719 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
722 resolveSymbols (actParm);
723 /* if this is a PARAM node then match left & right */
724 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
726 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
727 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
731 /* If we have found a value node by following only right-hand links,
732 * then we know that there are no more values after us.
734 * Therefore, if there are more defined parameters, the caller didn't
737 if (rightmost && defParm->next)
739 werror (E_TOO_FEW_PARMS);
744 /* the parameter type must be at least castable */
745 if (compareType (defParm->type, actParm->ftype) == 0) {
746 werror (E_INCOMPAT_TYPES);
747 printFromToType (actParm->ftype, defParm->type);
751 /* if the parameter is castable then add the cast */
752 if (compareType (defParm->type, actParm->ftype) < 0)
754 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
756 /* now change the current one to a cast */
757 actParm->type = EX_OP;
758 actParm->opval.op = CAST;
759 actParm->left = newAst_LINK (defParm->type);
760 actParm->right = pTree;
761 actParm->etype = defParm->etype;
762 actParm->ftype = defParm->type;
763 actParm->decorated=0; /* force typechecking */
764 decorateType (actParm);
767 /* make a copy and change the regparm type to the defined parm */
768 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
769 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
773 /*-----------------------------------------------------------------*/
774 /* createIvalType - generates ival for basic types */
775 /*-----------------------------------------------------------------*/
777 createIvalType (ast * sym, sym_link * type, initList * ilist)
781 /* if initList is deep */
782 if (ilist->type == INIT_DEEP)
783 ilist = ilist->init.deep;
785 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
786 return decorateType (newNode ('=', sym, iExpr));
789 /*-----------------------------------------------------------------*/
790 /* createIvalStruct - generates initial value for structures */
791 /*-----------------------------------------------------------------*/
793 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
800 sflds = SPEC_STRUCT (type)->fields;
801 if (ilist->type != INIT_DEEP)
803 werror (E_INIT_STRUCT, "");
807 iloop = ilist->init.deep;
809 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
811 /* if we have come to end */
815 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
816 lAst = decorateType (resolveSymbols (lAst));
817 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
823 /*-----------------------------------------------------------------*/
824 /* createIvalArray - generates code for array initialization */
825 /*-----------------------------------------------------------------*/
827 createIvalArray (ast * sym, sym_link * type, initList * ilist)
831 int lcnt = 0, size = 0;
832 literalList *literalL;
834 /* take care of the special case */
835 /* array of characters can be init */
837 if (IS_CHAR (type->next))
838 if ((rast = createIvalCharPtr (sym,
840 decorateType (resolveSymbols (list2expr (ilist))))))
842 return decorateType (resolveSymbols (rast));
844 /* not the special case */
845 if (ilist->type != INIT_DEEP)
847 werror (E_INIT_STRUCT, "");
851 iloop = ilist->init.deep;
852 lcnt = DCL_ELEM (type);
854 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
858 aSym = decorateType (resolveSymbols(sym));
860 rast = newNode(ARRAYINIT, aSym, NULL);
861 rast->values.constlist = literalL;
863 // Make sure size is set to length of initializer list.
870 if (lcnt && size > lcnt)
872 // Array size was specified, and we have more initializers than needed.
873 char *name=sym->opval.val->sym->name;
874 int lineno=sym->opval.val->sym->lineDef;
876 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
885 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
886 aSym = decorateType (resolveSymbols (aSym));
887 rast = createIval (aSym, type->next, iloop, rast);
888 iloop = (iloop ? iloop->next : NULL);
894 /* no of elements given and we */
895 /* have generated for all of them */
898 // there has to be a better way
899 char *name=sym->opval.val->sym->name;
900 int lineno=sym->opval.val->sym->lineDef;
901 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
908 /* if we have not been given a size */
909 if (!DCL_ELEM (type))
911 DCL_ELEM (type) = size;
914 return decorateType (resolveSymbols (rast));
918 /*-----------------------------------------------------------------*/
919 /* createIvalCharPtr - generates initial values for char pointers */
920 /*-----------------------------------------------------------------*/
922 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
926 /* if this is a pointer & right is a literal array then */
927 /* just assignment will do */
928 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
929 SPEC_SCLS (iexpr->etype) == S_CODE)
930 && IS_ARRAY (iexpr->ftype)))
931 return newNode ('=', sym, iexpr);
933 /* left side is an array so we have to assign each */
935 if ((IS_LITERAL (iexpr->etype) ||
936 SPEC_SCLS (iexpr->etype) == S_CODE)
937 && IS_ARRAY (iexpr->ftype))
939 /* for each character generate an assignment */
940 /* to the array element */
941 char *s = SPEC_CVAL (iexpr->etype).v_char;
946 rast = newNode (NULLOP,
950 newAst_VALUE (valueFromLit ((float) i))),
951 newAst_VALUE (valueFromLit (*s))));
955 rast = newNode (NULLOP,
959 newAst_VALUE (valueFromLit ((float) i))),
960 newAst_VALUE (valueFromLit (*s))));
961 return decorateType (resolveSymbols (rast));
967 /*-----------------------------------------------------------------*/
968 /* createIvalPtr - generates initial value for pointers */
969 /*-----------------------------------------------------------------*/
971 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
977 if (ilist->type == INIT_DEEP)
978 ilist = ilist->init.deep;
980 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
982 /* if character pointer */
983 if (IS_CHAR (type->next))
984 if ((rast = createIvalCharPtr (sym, type, iexpr)))
987 return newNode ('=', sym, iexpr);
990 /*-----------------------------------------------------------------*/
991 /* createIval - generates code for initial value */
992 /*-----------------------------------------------------------------*/
994 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1001 /* if structure then */
1002 if (IS_STRUCT (type))
1003 rast = createIvalStruct (sym, type, ilist);
1005 /* if this is a pointer */
1007 rast = createIvalPtr (sym, type, ilist);
1009 /* if this is an array */
1010 if (IS_ARRAY (type))
1011 rast = createIvalArray (sym, type, ilist);
1013 /* if type is SPECIFIER */
1015 rast = createIvalType (sym, type, ilist);
1018 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1020 return decorateType (resolveSymbols (rast));
1023 /*-----------------------------------------------------------------*/
1024 /* initAggregates - initialises aggregate variables with initv */
1025 /*-----------------------------------------------------------------*/
1027 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1029 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1033 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1035 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1036 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1037 "with -mmcs51 and --model-large\n");
1041 if (SPEC_OCLS(sym->etype)==xdata &&
1042 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1045 newSym=copySymbol (sym);
1046 SPEC_OCLS(newSym->etype)=code;
1047 sprintf (newSym->name, "%s_init__", sym->name);
1048 sprintf (newSym->rname,"%s_init__", sym->rname);
1049 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1051 // emit it in the static segment
1052 addSet(&statsg->syms, newSym);
1054 // now memcpy() the entire array from cseg
1055 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1056 newAst_VALUE (symbolVal (sym)),
1057 newAst_VALUE (symbolVal (newSym)));
1058 return decorateType(resolveSymbols(ast));
1062 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1065 /*-----------------------------------------------------------------*/
1066 /* gatherAutoInit - creates assignment expressions for initial */
1068 /*-----------------------------------------------------------------*/
1070 gatherAutoInit (symbol * autoChain)
1077 for (sym = autoChain; sym; sym = sym->next)
1080 /* resolve the symbols in the ival */
1082 resolveIvalSym (sym->ival);
1084 /* if this is a static variable & has an */
1085 /* initial value the code needs to be lifted */
1086 /* here to the main portion since they can be */
1087 /* initialised only once at the start */
1088 if (IS_STATIC (sym->etype) && sym->ival &&
1089 SPEC_SCLS (sym->etype) != S_CODE)
1093 // this can only be a constant
1094 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1095 werror (E_CONST_EXPECTED);
1098 /* insert the symbol into the symbol table */
1099 /* with level = 0 & name = rname */
1100 newSym = copySymbol (sym);
1101 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1103 /* now lift the code to main */
1104 if (IS_AGGREGATE (sym->type))
1105 work = initAggregates (sym, sym->ival, NULL);
1107 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1108 list2expr (sym->ival));
1110 setAstLineno (work, sym->lineDef);
1114 staticAutos = newNode (NULLOP, staticAutos, work);
1121 /* if there is an initial value */
1122 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1124 if (IS_AGGREGATE (sym->type))
1125 work = initAggregates (sym, sym->ival, NULL);
1127 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1128 list2expr (sym->ival));
1130 setAstLineno (work, sym->lineDef);
1133 init = newNode (NULLOP, init, work);
1142 /*-----------------------------------------------------------------*/
1143 /* stringToSymbol - creates a symbol from a literal string */
1144 /*-----------------------------------------------------------------*/
1146 stringToSymbol (value * val)
1148 char name[SDCC_NAME_MAX + 1];
1149 static int charLbl = 0;
1152 sprintf (name, "_str_%d", charLbl++);
1153 sym = newSymbol (name, 0); /* make it @ level 0 */
1154 strcpy (sym->rname, name);
1156 /* copy the type from the value passed */
1157 sym->type = copyLinkChain (val->type);
1158 sym->etype = getSpec (sym->type);
1159 /* change to storage class & output class */
1160 SPEC_SCLS (sym->etype) = S_CODE;
1161 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1162 SPEC_STAT (sym->etype) = 1;
1163 /* make the level & block = 0 */
1164 sym->block = sym->level = 0;
1166 /* create an ival */
1167 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1172 allocVariables (sym);
1175 return symbolVal (sym);
1179 /*-----------------------------------------------------------------*/
1180 /* processBlockVars - will go thru the ast looking for block if */
1181 /* a block is found then will allocate the syms */
1182 /* will also gather the auto inits present */
1183 /*-----------------------------------------------------------------*/
1185 processBlockVars (ast * tree, int *stack, int action)
1190 /* if this is a block */
1191 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1195 if (action == ALLOCATE)
1197 *stack += allocVariables (tree->values.sym);
1198 autoInit = gatherAutoInit (tree->values.sym);
1200 /* if there are auto inits then do them */
1202 tree->left = newNode (NULLOP, autoInit, tree->left);
1204 else /* action is deallocate */
1205 deallocLocal (tree->values.sym);
1208 processBlockVars (tree->left, stack, action);
1209 processBlockVars (tree->right, stack, action);
1213 /*-----------------------------------------------------------------*/
1214 /* constExprValue - returns the value of a constant expression */
1215 /* or NULL if it is not a constant expression */
1216 /*-----------------------------------------------------------------*/
1218 constExprValue (ast * cexpr, int check)
1220 cexpr = decorateType (resolveSymbols (cexpr));
1222 /* if this is not a constant then */
1223 if (!IS_LITERAL (cexpr->ftype))
1225 /* then check if this is a literal array
1227 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1228 SPEC_CVAL (cexpr->etype).v_char &&
1229 IS_ARRAY (cexpr->ftype))
1231 value *val = valFromType (cexpr->ftype);
1232 SPEC_SCLS (val->etype) = S_LITERAL;
1233 val->sym = cexpr->opval.val->sym;
1234 val->sym->type = copyLinkChain (cexpr->ftype);
1235 val->sym->etype = getSpec (val->sym->type);
1236 strcpy (val->name, cexpr->opval.val->sym->rname);
1240 /* if we are casting a literal value then */
1241 if (IS_AST_OP (cexpr) &&
1242 cexpr->opval.op == CAST &&
1243 IS_LITERAL (cexpr->left->ftype))
1244 return valCastLiteral (cexpr->ftype,
1245 floatFromVal (cexpr->left->opval.val));
1247 if (IS_AST_VALUE (cexpr))
1248 return cexpr->opval.val;
1251 werror (E_CONST_EXPECTED, "found expression");
1256 /* return the value */
1257 return cexpr->opval.val;
1261 /*-----------------------------------------------------------------*/
1262 /* isLabelInAst - will return true if a given label is found */
1263 /*-----------------------------------------------------------------*/
1265 isLabelInAst (symbol * label, ast * tree)
1267 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1270 if (IS_AST_OP (tree) &&
1271 tree->opval.op == LABEL &&
1272 isSymbolEqual (AST_SYMBOL (tree->left), label))
1275 return isLabelInAst (label, tree->right) &&
1276 isLabelInAst (label, tree->left);
1280 /*-----------------------------------------------------------------*/
1281 /* isLoopCountable - return true if the loop count can be determi- */
1282 /* -ned at compile time . */
1283 /*-----------------------------------------------------------------*/
1285 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1286 symbol ** sym, ast ** init, ast ** end)
1289 /* the loop is considered countable if the following
1290 conditions are true :-
1292 a) initExpr :- <sym> = <const>
1293 b) condExpr :- <sym> < <const1>
1294 c) loopExpr :- <sym> ++
1297 /* first check the initExpr */
1298 if (IS_AST_OP (initExpr) &&
1299 initExpr->opval.op == '=' && /* is assignment */
1300 IS_AST_SYM_VALUE (initExpr->left))
1301 { /* left is a symbol */
1303 *sym = AST_SYMBOL (initExpr->left);
1304 *init = initExpr->right;
1309 /* for now the symbol has to be of
1311 if (!IS_INTEGRAL ((*sym)->type))
1314 /* now check condExpr */
1315 if (IS_AST_OP (condExpr))
1318 switch (condExpr->opval.op)
1321 if (IS_AST_SYM_VALUE (condExpr->left) &&
1322 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1323 IS_AST_LIT_VALUE (condExpr->right))
1325 *end = condExpr->right;
1331 if (IS_AST_OP (condExpr->left) &&
1332 condExpr->left->opval.op == '>' &&
1333 IS_AST_LIT_VALUE (condExpr->left->right) &&
1334 IS_AST_SYM_VALUE (condExpr->left->left) &&
1335 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1338 *end = newNode ('+', condExpr->left->right,
1339 newAst_VALUE (constVal ("1")));
1350 /* check loop expression is of the form <sym>++ */
1351 if (!IS_AST_OP (loopExpr))
1354 /* check if <sym> ++ */
1355 if (loopExpr->opval.op == INC_OP)
1361 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1362 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1369 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1370 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1378 if (loopExpr->opval.op == ADD_ASSIGN)
1381 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1382 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1383 IS_AST_LIT_VALUE (loopExpr->right) &&
1384 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1392 /*-----------------------------------------------------------------*/
1393 /* astHasVolatile - returns true if ast contains any volatile */
1394 /*-----------------------------------------------------------------*/
1396 astHasVolatile (ast * tree)
1401 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1404 if (IS_AST_OP (tree))
1405 return astHasVolatile (tree->left) ||
1406 astHasVolatile (tree->right);
1411 /*-----------------------------------------------------------------*/
1412 /* astHasPointer - return true if the ast contains any ptr variable */
1413 /*-----------------------------------------------------------------*/
1415 astHasPointer (ast * tree)
1420 if (IS_AST_LINK (tree))
1423 /* if we hit an array expression then check
1424 only the left side */
1425 if (IS_AST_OP (tree) && tree->opval.op == '[')
1426 return astHasPointer (tree->left);
1428 if (IS_AST_VALUE (tree))
1429 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1431 return astHasPointer (tree->left) ||
1432 astHasPointer (tree->right);
1436 /*-----------------------------------------------------------------*/
1437 /* astHasSymbol - return true if the ast has the given symbol */
1438 /*-----------------------------------------------------------------*/
1440 astHasSymbol (ast * tree, symbol * sym)
1442 if (!tree || IS_AST_LINK (tree))
1445 if (IS_AST_VALUE (tree))
1447 if (IS_AST_SYM_VALUE (tree))
1448 return isSymbolEqual (AST_SYMBOL (tree), sym);
1453 return astHasSymbol (tree->left, sym) ||
1454 astHasSymbol (tree->right, sym);
1457 /*-----------------------------------------------------------------*/
1458 /* astHasDeref - return true if the ast has an indirect access */
1459 /*-----------------------------------------------------------------*/
1461 astHasDeref (ast * tree)
1463 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1466 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1468 return astHasDeref (tree->left) || astHasDeref (tree->right);
1471 /*-----------------------------------------------------------------*/
1472 /* isConformingBody - the loop body has to conform to a set of rules */
1473 /* for the loop to be considered reversible read on for rules */
1474 /*-----------------------------------------------------------------*/
1476 isConformingBody (ast * pbody, symbol * sym, ast * body)
1479 /* we are going to do a pre-order traversal of the
1480 tree && check for the following conditions. (essentially
1481 a set of very shallow tests )
1482 a) the sym passed does not participate in
1483 any arithmetic operation
1484 b) There are no function calls
1485 c) all jumps are within the body
1486 d) address of loop control variable not taken
1487 e) if an assignment has a pointer on the
1488 left hand side make sure right does not have
1489 loop control variable */
1491 /* if we reach the end or a leaf then true */
1492 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1496 /* if anything else is "volatile" */
1497 if (IS_VOLATILE (TETYPE (pbody)))
1500 /* we will walk the body in a pre-order traversal for
1502 switch (pbody->opval.op)
1504 /*------------------------------------------------------------------*/
1506 return isConformingBody (pbody->right, sym, body);
1508 /*------------------------------------------------------------------*/
1513 /*------------------------------------------------------------------*/
1514 case INC_OP: /* incerement operator unary so left only */
1517 /* sure we are not sym is not modified */
1519 IS_AST_SYM_VALUE (pbody->left) &&
1520 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1524 IS_AST_SYM_VALUE (pbody->right) &&
1525 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1530 /*------------------------------------------------------------------*/
1532 case '*': /* can be unary : if right is null then unary operation */
1537 /* if right is NULL then unary operation */
1538 /*------------------------------------------------------------------*/
1539 /*----------------------------*/
1541 /*----------------------------*/
1544 if (IS_AST_SYM_VALUE (pbody->left) &&
1545 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1548 return isConformingBody (pbody->left, sym, body);
1552 if (astHasSymbol (pbody->left, sym) ||
1553 astHasSymbol (pbody->right, sym))
1558 /*------------------------------------------------------------------*/
1566 if (IS_AST_SYM_VALUE (pbody->left) &&
1567 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1570 if (IS_AST_SYM_VALUE (pbody->right) &&
1571 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1574 return isConformingBody (pbody->left, sym, body) &&
1575 isConformingBody (pbody->right, sym, body);
1582 if (IS_AST_SYM_VALUE (pbody->left) &&
1583 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1585 return isConformingBody (pbody->left, sym, body);
1587 /*------------------------------------------------------------------*/
1599 case SIZEOF: /* evaluate wihout code generation */
1601 return isConformingBody (pbody->left, sym, body) &&
1602 isConformingBody (pbody->right, sym, body);
1604 /*------------------------------------------------------------------*/
1607 /* if left has a pointer & right has loop
1608 control variable then we cannot */
1609 if (astHasPointer (pbody->left) &&
1610 astHasSymbol (pbody->right, sym))
1612 if (astHasVolatile (pbody->left))
1615 if (IS_AST_SYM_VALUE (pbody->left) &&
1616 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1619 if (astHasVolatile (pbody->left))
1622 if (astHasDeref(pbody->right)) return FALSE;
1624 return isConformingBody (pbody->left, sym, body) &&
1625 isConformingBody (pbody->right, sym, body);
1636 assert ("Parser should not have generated this\n");
1638 /*------------------------------------------------------------------*/
1639 /*----------------------------*/
1640 /* comma operator */
1641 /*----------------------------*/
1643 return isConformingBody (pbody->left, sym, body) &&
1644 isConformingBody (pbody->right, sym, body);
1646 /*------------------------------------------------------------------*/
1647 /*----------------------------*/
1649 /*----------------------------*/
1653 /*------------------------------------------------------------------*/
1654 /*----------------------------*/
1655 /* return statement */
1656 /*----------------------------*/
1661 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1666 if (astHasSymbol (pbody->left, sym))
1673 return isConformingBody (pbody->left, sym, body) &&
1674 isConformingBody (pbody->right, sym, body);
1680 /*-----------------------------------------------------------------*/
1681 /* isLoopReversible - takes a for loop as input && returns true */
1682 /* if the for loop is reversible. If yes will set the value of */
1683 /* the loop control var & init value & termination value */
1684 /*-----------------------------------------------------------------*/
1686 isLoopReversible (ast * loop, symbol ** loopCntrl,
1687 ast ** init, ast ** end)
1689 /* if option says don't do it then don't */
1690 if (optimize.noLoopReverse)
1692 /* there are several tests to determine this */
1694 /* for loop has to be of the form
1695 for ( <sym> = <const1> ;
1696 [<sym> < <const2>] ;
1697 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1699 if (!isLoopCountable (AST_FOR (loop, initExpr),
1700 AST_FOR (loop, condExpr),
1701 AST_FOR (loop, loopExpr),
1702 loopCntrl, init, end))
1705 /* now do some serious checking on the body of the loop
1708 return isConformingBody (loop->left, *loopCntrl, loop->left);
1712 /*-----------------------------------------------------------------*/
1713 /* replLoopSym - replace the loop sym by loop sym -1 */
1714 /*-----------------------------------------------------------------*/
1716 replLoopSym (ast * body, symbol * sym)
1719 if (!body || IS_AST_LINK (body))
1722 if (IS_AST_SYM_VALUE (body))
1725 if (isSymbolEqual (AST_SYMBOL (body), sym))
1729 body->opval.op = '-';
1730 body->left = newAst_VALUE (symbolVal (sym));
1731 body->right = newAst_VALUE (constVal ("1"));
1739 replLoopSym (body->left, sym);
1740 replLoopSym (body->right, sym);
1744 /*-----------------------------------------------------------------*/
1745 /* reverseLoop - do the actual loop reversal */
1746 /*-----------------------------------------------------------------*/
1748 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1752 /* create the following tree
1757 if (sym) goto for_continue ;
1760 /* put it together piece by piece */
1761 rloop = newNode (NULLOP,
1762 createIf (newAst_VALUE (symbolVal (sym)),
1764 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1767 newAst_VALUE (symbolVal (sym)),
1770 replLoopSym (loop->left, sym);
1772 rloop = newNode (NULLOP,
1774 newAst_VALUE (symbolVal (sym)),
1775 newNode ('-', end, init)),
1776 createLabel (AST_FOR (loop, continueLabel),
1780 newNode (SUB_ASSIGN,
1781 newAst_VALUE (symbolVal (sym)),
1782 newAst_VALUE (constVal ("1"))),
1785 return decorateType (rloop);
1789 //#define DEMAND_INTEGER_PROMOTION
1791 #ifdef DEMAND_INTEGER_PROMOTION
1793 /*-----------------------------------------------------------------*/
1794 /* walk a tree looking for the leaves. Add a typecast to the given */
1795 /* type to each value leaf node. */
1796 /*-----------------------------------------------------------------*/
1798 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1800 if (!node || IS_CALLOP(node))
1802 /* WTF? We should never get here. */
1806 if (!node->left && !node->right)
1808 /* We're at a leaf; if it's a value, apply the typecast */
1809 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1811 *parentPtr = decorateType (newNode (CAST,
1812 newAst_LINK (copyLinkChain (type)),
1820 pushTypeCastToLeaves (type, node->left, &(node->left));
1824 pushTypeCastToLeaves (type, node->right, &(node->right));
1831 /*-----------------------------------------------------------------*/
1832 /* decorateType - compute type for this tree also does type cheking */
1833 /* this is done bottom up, since type have to flow upwards */
1834 /* it also does constant folding, and paramater checking */
1835 /*-----------------------------------------------------------------*/
1837 decorateType (ast * tree)
1845 /* if already has type then do nothing */
1846 if (tree->decorated)
1849 tree->decorated = 1;
1851 /* print the line */
1852 /* if not block & function */
1853 if (tree->type == EX_OP &&
1854 (tree->opval.op != FUNCTION &&
1855 tree->opval.op != BLOCK &&
1856 tree->opval.op != NULLOP))
1858 filename = tree->filename;
1859 lineno = tree->lineno;
1862 /* if any child is an error | this one is an error do nothing */
1863 if (tree->isError ||
1864 (tree->left && tree->left->isError) ||
1865 (tree->right && tree->right->isError))
1868 /*------------------------------------------------------------------*/
1869 /*----------------------------*/
1870 /* leaf has been reached */
1871 /*----------------------------*/
1872 /* if this is of type value */
1873 /* just get the type */
1874 if (tree->type == EX_VALUE)
1877 if (IS_LITERAL (tree->opval.val->etype))
1880 /* if this is a character array then declare it */
1881 if (IS_ARRAY (tree->opval.val->type))
1882 tree->opval.val = stringToSymbol (tree->opval.val);
1884 /* otherwise just copy the type information */
1885 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1889 if (tree->opval.val->sym)
1891 /* if the undefined flag is set then give error message */
1892 if (tree->opval.val->sym->undefined)
1894 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1896 TTYPE (tree) = TETYPE (tree) =
1897 tree->opval.val->type = tree->opval.val->sym->type =
1898 tree->opval.val->etype = tree->opval.val->sym->etype =
1899 copyLinkChain (INTTYPE);
1904 /* if impilicit i.e. struct/union member then no type */
1905 if (tree->opval.val->sym->implicit)
1906 TTYPE (tree) = TETYPE (tree) = NULL;
1911 /* else copy the type */
1912 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1914 /* and mark it as referenced */
1915 tree->opval.val->sym->isref = 1;
1923 /* if type link for the case of cast */
1924 if (tree->type == EX_LINK)
1926 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1933 dtl = decorateType (tree->left);
1934 dtr = decorateType (tree->right);
1936 /* this is to take care of situations
1937 when the tree gets rewritten */
1938 if (dtl != tree->left)
1940 if (dtr != tree->right)
1944 /* depending on type of operator do */
1946 switch (tree->opval.op)
1948 /*------------------------------------------------------------------*/
1949 /*----------------------------*/
1951 /*----------------------------*/
1954 /* determine which is the array & which the index */
1955 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1958 ast *tempTree = tree->left;
1959 tree->left = tree->right;
1960 tree->right = tempTree;
1963 /* first check if this is a array or a pointer */
1964 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1966 werror (E_NEED_ARRAY_PTR, "[]");
1967 goto errorTreeReturn;
1970 /* check if the type of the idx */
1971 if (!IS_INTEGRAL (RTYPE (tree)))
1973 werror (E_IDX_NOT_INT);
1974 goto errorTreeReturn;
1977 /* if the left is an rvalue then error */
1980 werror (E_LVALUE_REQUIRED, "array access");
1981 goto errorTreeReturn;
1984 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1985 if (IS_PTR(LTYPE(tree))) {
1986 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1990 /*------------------------------------------------------------------*/
1991 /*----------------------------*/
1993 /*----------------------------*/
1995 /* if this is not a structure */
1996 if (!IS_STRUCT (LTYPE (tree)))
1998 werror (E_STRUCT_UNION, ".");
1999 goto errorTreeReturn;
2001 TTYPE (tree) = structElemType (LTYPE (tree),
2002 (tree->right->type == EX_VALUE ?
2003 tree->right->opval.val : NULL));
2004 TETYPE (tree) = getSpec (TTYPE (tree));
2007 /*------------------------------------------------------------------*/
2008 /*----------------------------*/
2009 /* struct/union pointer */
2010 /*----------------------------*/
2012 /* if not pointer to a structure */
2013 if (!IS_PTR (LTYPE (tree)))
2015 werror (E_PTR_REQD);
2016 goto errorTreeReturn;
2019 if (!IS_STRUCT (LTYPE (tree)->next))
2021 werror (E_STRUCT_UNION, "->");
2022 goto errorTreeReturn;
2025 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2026 (tree->right->type == EX_VALUE ?
2027 tree->right->opval.val : NULL));
2028 TETYPE (tree) = getSpec (TTYPE (tree));
2031 /*------------------------------------------------------------------*/
2032 /*----------------------------*/
2033 /* ++/-- operation */
2034 /*----------------------------*/
2035 case INC_OP: /* incerement operator unary so left only */
2038 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2039 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2040 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2041 werror (E_CODE_WRITE, "++/--");
2050 /*------------------------------------------------------------------*/
2051 /*----------------------------*/
2053 /*----------------------------*/
2054 case '&': /* can be unary */
2055 /* if right is NULL then unary operation */
2056 if (tree->right) /* not an unary operation */
2059 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2061 werror (E_BITWISE_OP);
2062 werror (W_CONTINUE, "left & right types are ");
2063 printTypeChain (LTYPE (tree), stderr);
2064 fprintf (stderr, ",");
2065 printTypeChain (RTYPE (tree), stderr);
2066 fprintf (stderr, "\n");
2067 goto errorTreeReturn;
2070 /* if they are both literal */
2071 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2073 tree->type = EX_VALUE;
2074 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2075 valFromType (RETYPE (tree)), '&');
2077 tree->right = tree->left = NULL;
2078 TETYPE (tree) = tree->opval.val->etype;
2079 TTYPE (tree) = tree->opval.val->type;
2083 /* see if this is a GETHBIT operation if yes
2086 ast *otree = optimizeGetHbit (tree);
2089 return decorateType (otree);
2093 // we can't do this because of "(int & 0xff) << 3"
2095 /* if right or left is literal then result of that type */
2096 if (IS_LITERAL (RTYPE (tree)))
2099 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2100 TETYPE (tree) = getSpec (TTYPE (tree));
2101 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2105 if (IS_LITERAL (LTYPE (tree)))
2107 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2108 TETYPE (tree) = getSpec (TTYPE (tree));
2109 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2115 computeType (LTYPE (tree), RTYPE (tree));
2116 TETYPE (tree) = getSpec (TTYPE (tree));
2121 computeType (LTYPE (tree), RTYPE (tree));
2122 TETYPE (tree) = getSpec (TTYPE (tree));
2124 LRVAL (tree) = RRVAL (tree) = 1;
2128 /*------------------------------------------------------------------*/
2129 /*----------------------------*/
2131 /*----------------------------*/
2133 p->class = DECLARATOR;
2134 /* if bit field then error */
2135 if (IS_BITVAR (tree->left->etype))
2137 werror (E_ILLEGAL_ADDR, "address of bit variable");
2138 goto errorTreeReturn;
2141 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2143 werror (E_ILLEGAL_ADDR, "address of register variable");
2144 goto errorTreeReturn;
2147 if (IS_FUNC (LTYPE (tree)))
2149 werror (E_ILLEGAL_ADDR, "address of function");
2150 goto errorTreeReturn;
2153 if (IS_LITERAL(LTYPE(tree)))
2155 werror (E_ILLEGAL_ADDR, "address of literal");
2156 goto errorTreeReturn;
2161 werror (E_LVALUE_REQUIRED, "address of");
2162 goto errorTreeReturn;
2164 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2166 DCL_TYPE (p) = CPOINTER;
2167 DCL_PTR_CONST (p) = port->mem.code_ro;
2169 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2170 DCL_TYPE (p) = FPOINTER;
2171 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2172 DCL_TYPE (p) = PPOINTER;
2173 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2174 DCL_TYPE (p) = IPOINTER;
2175 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2176 DCL_TYPE (p) = EEPPOINTER;
2178 DCL_TYPE (p) = POINTER;
2180 if (IS_AST_SYM_VALUE (tree->left))
2182 AST_SYMBOL (tree->left)->addrtaken = 1;
2183 AST_SYMBOL (tree->left)->allocreq = 1;
2186 p->next = LTYPE (tree);
2188 TETYPE (tree) = getSpec (TTYPE (tree));
2189 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2190 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2195 /*------------------------------------------------------------------*/
2196 /*----------------------------*/
2198 /*----------------------------*/
2200 /* if the rewrite succeeds then don't go any furthur */
2202 ast *wtree = optimizeRRCRLC (tree);
2204 return decorateType (wtree);
2206 /*------------------------------------------------------------------*/
2207 /*----------------------------*/
2209 /*----------------------------*/
2211 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2213 werror (E_BITWISE_OP);
2214 werror (W_CONTINUE, "left & right types are ");
2215 printTypeChain (LTYPE (tree), stderr);
2216 fprintf (stderr, ",");
2217 printTypeChain (RTYPE (tree), stderr);
2218 fprintf (stderr, "\n");
2219 goto errorTreeReturn;
2222 /* if they are both literal then */
2223 /* rewrite the tree */
2224 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2226 tree->type = EX_VALUE;
2227 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2228 valFromType (RETYPE (tree)),
2230 tree->right = tree->left = NULL;
2231 TETYPE (tree) = tree->opval.val->etype;
2232 TTYPE (tree) = tree->opval.val->type;
2235 LRVAL (tree) = RRVAL (tree) = 1;
2236 TETYPE (tree) = getSpec (TTYPE (tree) =
2237 computeType (LTYPE (tree),
2240 /*------------------------------------------------------------------*/
2241 /*----------------------------*/
2243 /*----------------------------*/
2245 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2247 werror (E_INVALID_OP, "divide");
2248 goto errorTreeReturn;
2250 /* if they are both literal then */
2251 /* rewrite the tree */
2252 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2254 tree->type = EX_VALUE;
2255 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2256 valFromType (RETYPE (tree)));
2257 tree->right = tree->left = NULL;
2258 TETYPE (tree) = getSpec (TTYPE (tree) =
2259 tree->opval.val->type);
2262 LRVAL (tree) = RRVAL (tree) = 1;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 computeType (LTYPE (tree),
2268 /*------------------------------------------------------------------*/
2269 /*----------------------------*/
2271 /*----------------------------*/
2273 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2275 werror (E_BITWISE_OP);
2276 werror (W_CONTINUE, "left & right types are ");
2277 printTypeChain (LTYPE (tree), stderr);
2278 fprintf (stderr, ",");
2279 printTypeChain (RTYPE (tree), stderr);
2280 fprintf (stderr, "\n");
2281 goto errorTreeReturn;
2283 /* if they are both literal then */
2284 /* rewrite the tree */
2285 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2287 tree->type = EX_VALUE;
2288 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2289 valFromType (RETYPE (tree)));
2290 tree->right = tree->left = NULL;
2291 TETYPE (tree) = getSpec (TTYPE (tree) =
2292 tree->opval.val->type);
2295 LRVAL (tree) = RRVAL (tree) = 1;
2296 TETYPE (tree) = getSpec (TTYPE (tree) =
2297 computeType (LTYPE (tree),
2301 /*------------------------------------------------------------------*/
2302 /*----------------------------*/
2303 /* address dereference */
2304 /*----------------------------*/
2305 case '*': /* can be unary : if right is null then unary operation */
2308 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2310 werror (E_PTR_REQD);
2311 goto errorTreeReturn;
2316 werror (E_LVALUE_REQUIRED, "pointer deref");
2317 goto errorTreeReturn;
2319 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2320 LTYPE (tree)->next : NULL);
2321 TETYPE (tree) = getSpec (TTYPE (tree));
2322 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2326 /*------------------------------------------------------------------*/
2327 /*----------------------------*/
2328 /* multiplication */
2329 /*----------------------------*/
2330 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2332 werror (E_INVALID_OP, "multiplication");
2333 goto errorTreeReturn;
2336 /* if they are both literal then */
2337 /* rewrite the tree */
2338 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2340 tree->type = EX_VALUE;
2341 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2342 valFromType (RETYPE (tree)));
2343 tree->right = tree->left = NULL;
2344 TETYPE (tree) = getSpec (TTYPE (tree) =
2345 tree->opval.val->type);
2349 /* if left is a literal exchange left & right */
2350 if (IS_LITERAL (LTYPE (tree)))
2352 ast *tTree = tree->left;
2353 tree->left = tree->right;
2354 tree->right = tTree;
2357 LRVAL (tree) = RRVAL (tree) = 1;
2358 /* promote result to int if left & right are char
2359 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2360 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2361 TETYPE (tree) = getSpec (TTYPE (tree) =
2362 computeType (LTYPE (tree),
2364 SPEC_NOUN(TETYPE(tree)) = V_INT;
2366 TETYPE (tree) = getSpec (TTYPE (tree) =
2367 computeType (LTYPE (tree),
2372 /*------------------------------------------------------------------*/
2373 /*----------------------------*/
2374 /* unary '+' operator */
2375 /*----------------------------*/
2380 if (!IS_INTEGRAL (LTYPE (tree)))
2382 werror (E_UNARY_OP, '+');
2383 goto errorTreeReturn;
2386 /* if left is a literal then do it */
2387 if (IS_LITERAL (LTYPE (tree)))
2389 tree->type = EX_VALUE;
2390 tree->opval.val = valFromType (LETYPE (tree));
2392 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2396 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2400 /*------------------------------------------------------------------*/
2401 /*----------------------------*/
2403 /*----------------------------*/
2405 /* this is not a unary operation */
2406 /* if both pointers then problem */
2407 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2408 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2410 werror (E_PTR_PLUS_PTR);
2411 goto errorTreeReturn;
2414 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2415 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2417 werror (E_PLUS_INVALID, "+");
2418 goto errorTreeReturn;
2421 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2422 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2424 werror (E_PLUS_INVALID, "+");
2425 goto errorTreeReturn;
2427 /* if they are both literal then */
2428 /* rewrite the tree */
2429 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2431 tree->type = EX_VALUE;
2432 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2433 valFromType (RETYPE (tree)));
2434 tree->right = tree->left = NULL;
2435 TETYPE (tree) = getSpec (TTYPE (tree) =
2436 tree->opval.val->type);
2440 /* if the right is a pointer or left is a literal
2441 xchange left & right */
2442 if (IS_ARRAY (RTYPE (tree)) ||
2443 IS_PTR (RTYPE (tree)) ||
2444 IS_LITERAL (LTYPE (tree)))
2446 ast *tTree = tree->left;
2447 tree->left = tree->right;
2448 tree->right = tTree;
2451 LRVAL (tree) = RRVAL (tree) = 1;
2452 /* if the left is a pointer */
2453 if (IS_PTR (LTYPE (tree)))
2454 TETYPE (tree) = getSpec (TTYPE (tree) =
2457 TETYPE (tree) = getSpec (TTYPE (tree) =
2458 computeType (LTYPE (tree),
2462 /*------------------------------------------------------------------*/
2463 /*----------------------------*/
2465 /*----------------------------*/
2466 case '-': /* can be unary */
2467 /* if right is null then unary */
2471 if (!IS_ARITHMETIC (LTYPE (tree)))
2473 werror (E_UNARY_OP, tree->opval.op);
2474 goto errorTreeReturn;
2477 /* if left is a literal then do it */
2478 if (IS_LITERAL (LTYPE (tree)))
2480 tree->type = EX_VALUE;
2481 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2483 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2484 SPEC_USIGN(TETYPE(tree)) = 0;
2488 TTYPE (tree) = LTYPE (tree);
2492 /*------------------------------------------------------------------*/
2493 /*----------------------------*/
2495 /*----------------------------*/
2497 if (!(IS_PTR (LTYPE (tree)) ||
2498 IS_ARRAY (LTYPE (tree)) ||
2499 IS_ARITHMETIC (LTYPE (tree))))
2501 werror (E_PLUS_INVALID, "-");
2502 goto errorTreeReturn;
2505 if (!(IS_PTR (RTYPE (tree)) ||
2506 IS_ARRAY (RTYPE (tree)) ||
2507 IS_ARITHMETIC (RTYPE (tree))))
2509 werror (E_PLUS_INVALID, "-");
2510 goto errorTreeReturn;
2513 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2514 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2515 IS_INTEGRAL (RTYPE (tree))))
2517 werror (E_PLUS_INVALID, "-");
2518 goto errorTreeReturn;
2521 /* if they are both literal then */
2522 /* rewrite the tree */
2523 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2525 tree->type = EX_VALUE;
2526 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2527 valFromType (RETYPE (tree)));
2528 tree->right = tree->left = NULL;
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 tree->opval.val->type);
2534 /* if the left & right are equal then zero */
2535 if (isAstEqual (tree->left, tree->right))
2537 tree->type = EX_VALUE;
2538 tree->left = tree->right = NULL;
2539 tree->opval.val = constVal ("0");
2540 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2544 /* if both of them are pointers or arrays then */
2545 /* the result is going to be an integer */
2546 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2547 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2548 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2550 /* if only the left is a pointer */
2551 /* then result is a pointer */
2552 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2553 TETYPE (tree) = getSpec (TTYPE (tree) =
2556 TETYPE (tree) = getSpec (TTYPE (tree) =
2557 computeType (LTYPE (tree),
2559 LRVAL (tree) = RRVAL (tree) = 1;
2562 /*------------------------------------------------------------------*/
2563 /*----------------------------*/
2565 /*----------------------------*/
2567 /* can be only integral type */
2568 if (!IS_INTEGRAL (LTYPE (tree)))
2570 werror (E_UNARY_OP, tree->opval.op);
2571 goto errorTreeReturn;
2574 /* if left is a literal then do it */
2575 if (IS_LITERAL (LTYPE (tree)))
2577 tree->type = EX_VALUE;
2578 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2580 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2584 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2587 /*------------------------------------------------------------------*/
2588 /*----------------------------*/
2590 /*----------------------------*/
2592 /* can be pointer */
2593 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2594 !IS_PTR (LTYPE (tree)) &&
2595 !IS_ARRAY (LTYPE (tree)))
2597 werror (E_UNARY_OP, tree->opval.op);
2598 goto errorTreeReturn;
2601 /* if left is a literal then do it */
2602 if (IS_LITERAL (LTYPE (tree)))
2604 tree->type = EX_VALUE;
2605 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2607 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2611 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2614 /*------------------------------------------------------------------*/
2615 /*----------------------------*/
2617 /*----------------------------*/
2620 TTYPE (tree) = LTYPE (tree);
2621 TETYPE (tree) = LETYPE (tree);
2625 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2630 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2632 werror (E_SHIFT_OP_INVALID);
2633 werror (W_CONTINUE, "left & right types are ");
2634 printTypeChain (LTYPE (tree), stderr);
2635 fprintf (stderr, ",");
2636 printTypeChain (RTYPE (tree), stderr);
2637 fprintf (stderr, "\n");
2638 goto errorTreeReturn;
2641 /* if they are both literal then */
2642 /* rewrite the tree */
2643 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2645 tree->type = EX_VALUE;
2646 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2647 valFromType (RETYPE (tree)),
2648 (tree->opval.op == LEFT_OP ? 1 : 0));
2649 tree->right = tree->left = NULL;
2650 TETYPE (tree) = getSpec (TTYPE (tree) =
2651 tree->opval.val->type);
2654 /* if only the right side is a literal & we are
2655 shifting more than size of the left operand then zero */
2656 if (IS_LITERAL (RTYPE (tree)) &&
2657 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2658 (getSize (LTYPE (tree)) * 8))
2660 werror (W_SHIFT_CHANGED,
2661 (tree->opval.op == LEFT_OP ? "left" : "right"));
2662 tree->type = EX_VALUE;
2663 tree->left = tree->right = NULL;
2664 tree->opval.val = constVal ("0");
2665 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2668 LRVAL (tree) = RRVAL (tree) = 1;
2669 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2671 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2675 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2679 /*------------------------------------------------------------------*/
2680 /*----------------------------*/
2682 /*----------------------------*/
2683 case CAST: /* change the type */
2684 /* cannot cast to an aggregate type */
2685 if (IS_AGGREGATE (LTYPE (tree)))
2687 werror (E_CAST_ILLEGAL);
2688 goto errorTreeReturn;
2691 /* make sure the type is complete and sane */
2692 checkTypeSanity(LETYPE(tree), "(cast)");
2695 /* if the right is a literal replace the tree */
2696 if (IS_LITERAL (RETYPE (tree))) {
2697 if (!IS_PTR (LTYPE (tree))) {
2698 tree->type = EX_VALUE;
2700 valCastLiteral (LTYPE (tree),
2701 floatFromVal (valFromType (RETYPE (tree))));
2704 TTYPE (tree) = tree->opval.val->type;
2705 tree->values.literalFromCast = 1;
2706 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2707 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2708 sym_link *rest = LTYPE(tree)->next;
2709 werror(W_LITERAL_GENERIC);
2710 TTYPE(tree) = newLink();
2711 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2712 TTYPE(tree)->next = rest;
2713 tree->left->opval.lnk = TTYPE(tree);
2716 TTYPE (tree) = LTYPE (tree);
2720 TTYPE (tree) = LTYPE (tree);
2724 /* if pointer to struct then check names */
2725 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2726 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2727 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2728 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2730 /* if the right is a literal replace the tree */
2731 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2732 tree->type = EX_VALUE;
2734 valCastLiteral (LTYPE (tree),
2735 floatFromVal (valFromType (RETYPE (tree))));
2738 TTYPE (tree) = tree->opval.val->type;
2739 tree->values.literalFromCast = 1;
2741 TTYPE (tree) = LTYPE (tree);
2745 TETYPE (tree) = getSpec (TTYPE (tree));
2749 /*------------------------------------------------------------------*/
2750 /*----------------------------*/
2751 /* logical &&, || */
2752 /*----------------------------*/
2755 /* each must me arithmetic type or be a pointer */
2756 if (!IS_PTR (LTYPE (tree)) &&
2757 !IS_ARRAY (LTYPE (tree)) &&
2758 !IS_INTEGRAL (LTYPE (tree)))
2760 werror (E_COMPARE_OP);
2761 goto errorTreeReturn;
2764 if (!IS_PTR (RTYPE (tree)) &&
2765 !IS_ARRAY (RTYPE (tree)) &&
2766 !IS_INTEGRAL (RTYPE (tree)))
2768 werror (E_COMPARE_OP);
2769 goto errorTreeReturn;
2771 /* if they are both literal then */
2772 /* rewrite the tree */
2773 if (IS_LITERAL (RTYPE (tree)) &&
2774 IS_LITERAL (LTYPE (tree)))
2776 tree->type = EX_VALUE;
2777 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2778 valFromType (RETYPE (tree)),
2780 tree->right = tree->left = NULL;
2781 TETYPE (tree) = getSpec (TTYPE (tree) =
2782 tree->opval.val->type);
2785 LRVAL (tree) = RRVAL (tree) = 1;
2786 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2789 /*------------------------------------------------------------------*/
2790 /*----------------------------*/
2791 /* comparison operators */
2792 /*----------------------------*/
2800 ast *lt = optimizeCompare (tree);
2806 /* if they are pointers they must be castable */
2807 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2809 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2811 werror (E_COMPARE_OP);
2812 fprintf (stderr, "comparing type ");
2813 printTypeChain (LTYPE (tree), stderr);
2814 fprintf (stderr, "to type ");
2815 printTypeChain (RTYPE (tree), stderr);
2816 fprintf (stderr, "\n");
2817 goto errorTreeReturn;
2820 /* else they should be promotable to one another */
2823 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2824 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2826 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2828 werror (E_COMPARE_OP);
2829 fprintf (stderr, "comparing type ");
2830 printTypeChain (LTYPE (tree), stderr);
2831 fprintf (stderr, "to type ");
2832 printTypeChain (RTYPE (tree), stderr);
2833 fprintf (stderr, "\n");
2834 goto errorTreeReturn;
2838 /* if they are both literal then */
2839 /* rewrite the tree */
2840 if (IS_LITERAL (RTYPE (tree)) &&
2841 IS_LITERAL (LTYPE (tree)))
2843 tree->type = EX_VALUE;
2844 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2845 valFromType (RETYPE (tree)),
2847 tree->right = tree->left = NULL;
2848 TETYPE (tree) = getSpec (TTYPE (tree) =
2849 tree->opval.val->type);
2852 LRVAL (tree) = RRVAL (tree) = 1;
2853 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2856 /*------------------------------------------------------------------*/
2857 /*----------------------------*/
2859 /*----------------------------*/
2860 case SIZEOF: /* evaluate wihout code generation */
2861 /* change the type to a integer */
2862 tree->type = EX_VALUE;
2863 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2864 tree->opval.val = constVal (buffer);
2865 tree->right = tree->left = NULL;
2866 TETYPE (tree) = getSpec (TTYPE (tree) =
2867 tree->opval.val->type);
2870 /*------------------------------------------------------------------*/
2871 /*----------------------------*/
2872 /* conditional operator '?' */
2873 /*----------------------------*/
2875 /* the type is value of the colon operator (on the right) */
2876 assert(IS_COLON_OP(tree->right));
2877 /* if already known then replace the tree : optimizer will do it
2878 but faster to do it here */
2879 if (IS_LITERAL (LTYPE(tree))) {
2880 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2881 return tree->right->left ;
2883 return tree->right->right ;
2886 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2887 TETYPE (tree) = getSpec (TTYPE (tree));
2892 /* if they don't match we have a problem */
2893 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2895 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2896 goto errorTreeReturn;
2899 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2900 TETYPE (tree) = getSpec (TTYPE (tree));
2904 /*------------------------------------------------------------------*/
2905 /*----------------------------*/
2906 /* assignment operators */
2907 /*----------------------------*/
2910 /* for these it must be both must be integral */
2911 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2912 !IS_ARITHMETIC (RTYPE (tree)))
2914 werror (E_OPS_INTEGRAL);
2915 goto errorTreeReturn;
2918 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2920 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2921 werror (E_CODE_WRITE, " ");
2925 werror (E_LVALUE_REQUIRED, "*= or /=");
2926 goto errorTreeReturn;
2937 /* for these it must be both must be integral */
2938 if (!IS_INTEGRAL (LTYPE (tree)) ||
2939 !IS_INTEGRAL (RTYPE (tree)))
2941 werror (E_OPS_INTEGRAL);
2942 goto errorTreeReturn;
2945 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2947 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2948 werror (E_CODE_WRITE, " ");
2952 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2953 goto errorTreeReturn;
2959 /*------------------------------------------------------------------*/
2960 /*----------------------------*/
2962 /*----------------------------*/
2964 if (!(IS_PTR (LTYPE (tree)) ||
2965 IS_ARITHMETIC (LTYPE (tree))))
2967 werror (E_PLUS_INVALID, "-=");
2968 goto errorTreeReturn;
2971 if (!(IS_PTR (RTYPE (tree)) ||
2972 IS_ARITHMETIC (RTYPE (tree))))
2974 werror (E_PLUS_INVALID, "-=");
2975 goto errorTreeReturn;
2978 TETYPE (tree) = getSpec (TTYPE (tree) =
2979 computeType (LTYPE (tree),
2982 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2983 werror (E_CODE_WRITE, " ");
2987 werror (E_LVALUE_REQUIRED, "-=");
2988 goto errorTreeReturn;
2994 /*------------------------------------------------------------------*/
2995 /*----------------------------*/
2997 /*----------------------------*/
2999 /* this is not a unary operation */
3000 /* if both pointers then problem */
3001 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3003 werror (E_PTR_PLUS_PTR);
3004 goto errorTreeReturn;
3007 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3009 werror (E_PLUS_INVALID, "+=");
3010 goto errorTreeReturn;
3013 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3015 werror (E_PLUS_INVALID, "+=");
3016 goto errorTreeReturn;
3019 TETYPE (tree) = getSpec (TTYPE (tree) =
3020 computeType (LTYPE (tree),
3023 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3024 werror (E_CODE_WRITE, " ");
3028 werror (E_LVALUE_REQUIRED, "+=");
3029 goto errorTreeReturn;
3032 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3033 tree->opval.op = '=';
3037 /*------------------------------------------------------------------*/
3038 /*----------------------------*/
3039 /* straight assignemnt */
3040 /*----------------------------*/
3042 /* cannot be an aggregate */
3043 if (IS_AGGREGATE (LTYPE (tree)))
3045 werror (E_AGGR_ASSIGN);
3046 goto errorTreeReturn;
3049 /* they should either match or be castable */
3050 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3052 werror (E_TYPE_MISMATCH, "assignment", " ");
3053 fprintf (stderr, "type --> '");
3054 printTypeChain (RTYPE (tree), stderr);
3055 fprintf (stderr, "' ");
3056 fprintf (stderr, "assigned to type --> '");
3057 printTypeChain (LTYPE (tree), stderr);
3058 fprintf (stderr, "'\n");
3059 goto errorTreeReturn;
3062 /* if the left side of the tree is of type void
3063 then report error */
3064 if (IS_VOID (LTYPE (tree)))
3066 werror (E_CAST_ZERO);
3067 printFromToType(RTYPE(tree), LTYPE(tree));
3070 TETYPE (tree) = getSpec (TTYPE (tree) =
3074 if (!tree->initMode ) {
3075 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3076 werror (E_CODE_WRITE, " ");
3080 werror (E_LVALUE_REQUIRED, "=");
3081 goto errorTreeReturn;
3086 /*------------------------------------------------------------------*/
3087 /*----------------------------*/
3088 /* comma operator */
3089 /*----------------------------*/
3091 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3094 /*------------------------------------------------------------------*/
3095 /*----------------------------*/
3097 /*----------------------------*/
3101 if (processParms (tree->left,
3102 FUNC_ARGS(tree->left->ftype),
3103 tree->right, &parmNumber, TRUE)) {
3104 goto errorTreeReturn;
3107 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3109 //FUNC_ARGS(tree->left->ftype) =
3110 //reverseVal (FUNC_ARGS(tree->left->ftype));
3111 reverseParms (tree->right);
3114 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3117 /*------------------------------------------------------------------*/
3118 /*----------------------------*/
3119 /* return statement */
3120 /*----------------------------*/
3125 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3127 werror (W_RETURN_MISMATCH);
3128 printFromToType (RTYPE(tree), currFunc->type->next);
3129 goto errorTreeReturn;
3132 if (IS_VOID (currFunc->type->next)
3134 !IS_VOID (RTYPE (tree)))
3136 werror (E_FUNC_VOID);
3137 goto errorTreeReturn;
3140 /* if there is going to be a casing required then add it */
3141 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3144 decorateType (newNode (CAST,
3145 newAst_LINK (copyLinkChain (currFunc->type->next)),
3154 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3156 werror (E_VOID_FUNC, currFunc->name);
3157 goto errorTreeReturn;
3160 TTYPE (tree) = TETYPE (tree) = NULL;
3163 /*------------------------------------------------------------------*/
3164 /*----------------------------*/
3165 /* switch statement */
3166 /*----------------------------*/
3168 /* the switch value must be an integer */
3169 if (!IS_INTEGRAL (LTYPE (tree)))
3171 werror (E_SWITCH_NON_INTEGER);
3172 goto errorTreeReturn;
3175 TTYPE (tree) = TETYPE (tree) = NULL;
3178 /*------------------------------------------------------------------*/
3179 /*----------------------------*/
3181 /*----------------------------*/
3183 tree->left = backPatchLabels (tree->left,
3186 TTYPE (tree) = TETYPE (tree) = NULL;
3189 /*------------------------------------------------------------------*/
3190 /*----------------------------*/
3192 /*----------------------------*/
3195 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3196 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3197 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3199 /* if the for loop is reversible then
3200 reverse it otherwise do what we normally
3206 if (isLoopReversible (tree, &sym, &init, &end))
3207 return reverseLoop (tree, sym, init, end);
3209 return decorateType (createFor (AST_FOR (tree, trueLabel),
3210 AST_FOR (tree, continueLabel),
3211 AST_FOR (tree, falseLabel),
3212 AST_FOR (tree, condLabel),
3213 AST_FOR (tree, initExpr),
3214 AST_FOR (tree, condExpr),
3215 AST_FOR (tree, loopExpr),
3219 TTYPE (tree) = TETYPE (tree) = NULL;
3223 /* some error found this tree will be killed */
3225 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3226 tree->opval.op = NULLOP;
3232 /*-----------------------------------------------------------------*/
3233 /* sizeofOp - processes size of operation */
3234 /*-----------------------------------------------------------------*/
3236 sizeofOp (sym_link * type)
3240 /* make sure the type is complete and sane */
3241 checkTypeSanity(type, "(sizeof)");
3243 /* get the size and convert it to character */
3244 sprintf (buff, "%d", getSize (type));
3246 /* now convert into value */
3247 return constVal (buff);
3251 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3252 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3253 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3254 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3255 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3256 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3257 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3259 /*-----------------------------------------------------------------*/
3260 /* backPatchLabels - change and or not operators to flow control */
3261 /*-----------------------------------------------------------------*/
3263 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3269 if (!(IS_ANDORNOT (tree)))
3272 /* if this an and */
3275 static int localLbl = 0;
3278 sprintf (buffer, "_and_%d", localLbl++);
3279 localLabel = newSymbol (buffer, NestLevel);
3281 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3283 /* if left is already a IFX then just change the if true label in that */
3284 if (!IS_IFX (tree->left))
3285 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3287 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3288 /* right is a IFX then just join */
3289 if (IS_IFX (tree->right))
3290 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3292 tree->right = createLabel (localLabel, tree->right);
3293 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3295 return newNode (NULLOP, tree->left, tree->right);
3298 /* if this is an or operation */
3301 static int localLbl = 0;
3304 sprintf (buffer, "_or_%d", localLbl++);
3305 localLabel = newSymbol (buffer, NestLevel);
3307 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3309 /* if left is already a IFX then just change the if true label in that */
3310 if (!IS_IFX (tree->left))
3311 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3313 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3314 /* right is a IFX then just join */
3315 if (IS_IFX (tree->right))
3316 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3318 tree->right = createLabel (localLabel, tree->right);
3319 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3321 return newNode (NULLOP, tree->left, tree->right);
3327 int wasnot = IS_NOT (tree->left);
3328 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3330 /* if the left is already a IFX */
3331 if (!IS_IFX (tree->left))
3332 tree->left = newNode (IFX, tree->left, NULL);
3336 tree->left->trueLabel = trueLabel;
3337 tree->left->falseLabel = falseLabel;
3341 tree->left->trueLabel = falseLabel;
3342 tree->left->falseLabel = trueLabel;
3349 tree->trueLabel = trueLabel;
3350 tree->falseLabel = falseLabel;
3357 /*-----------------------------------------------------------------*/
3358 /* createBlock - create expression tree for block */
3359 /*-----------------------------------------------------------------*/
3361 createBlock (symbol * decl, ast * body)
3365 /* if the block has nothing */
3369 ex = newNode (BLOCK, NULL, body);
3370 ex->values.sym = decl;
3372 ex->right = ex->right;
3378 /*-----------------------------------------------------------------*/
3379 /* createLabel - creates the expression tree for labels */
3380 /*-----------------------------------------------------------------*/
3382 createLabel (symbol * label, ast * stmnt)
3385 char name[SDCC_NAME_MAX + 1];
3388 /* must create fresh symbol if the symbol name */
3389 /* exists in the symbol table, since there can */
3390 /* be a variable with the same name as the labl */
3391 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3392 (csym->level == label->level))
3393 label = newSymbol (label->name, label->level);
3395 /* change the name before putting it in add _ */
3396 sprintf (name, "%s", label->name);
3398 /* put the label in the LabelSymbol table */
3399 /* but first check if a label of the same */
3401 if ((csym = findSym (LabelTab, NULL, name)))
3402 werror (E_DUPLICATE_LABEL, label->name);
3404 addSym (LabelTab, label, name, label->level, 0, 0);
3407 label->key = labelKey++;
3408 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3414 /*-----------------------------------------------------------------*/
3415 /* createCase - generates the parsetree for a case statement */
3416 /*-----------------------------------------------------------------*/
3418 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3420 char caseLbl[SDCC_NAME_MAX + 1];
3424 /* if the switch statement does not exist */
3425 /* then case is out of context */
3428 werror (E_CASE_CONTEXT);
3432 caseVal = decorateType (resolveSymbols (caseVal));
3433 /* if not a constant then error */
3434 if (!IS_LITERAL (caseVal->ftype))
3436 werror (E_CASE_CONSTANT);
3440 /* if not a integer than error */
3441 if (!IS_INTEGRAL (caseVal->ftype))
3443 werror (E_CASE_NON_INTEGER);
3447 /* find the end of the switch values chain */
3448 if (!(val = swStat->values.switchVals.swVals))
3449 swStat->values.switchVals.swVals = caseVal->opval.val;
3452 /* also order the cases according to value */
3454 int cVal = (int) floatFromVal (caseVal->opval.val);
3455 while (val && (int) floatFromVal (val) < cVal)
3461 /* if we reached the end then */
3464 pval->next = caseVal->opval.val;
3468 /* we found a value greater than */
3469 /* the current value we must add this */
3470 /* before the value */
3471 caseVal->opval.val->next = val;
3473 /* if this was the first in chain */
3474 if (swStat->values.switchVals.swVals == val)
3475 swStat->values.switchVals.swVals =
3478 pval->next = caseVal->opval.val;
3483 /* create the case label */
3484 sprintf (caseLbl, "_case_%d_%d",
3485 swStat->values.switchVals.swNum,
3486 (int) floatFromVal (caseVal->opval.val));
3488 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3493 /*-----------------------------------------------------------------*/
3494 /* createDefault - creates the parse tree for the default statement */
3495 /*-----------------------------------------------------------------*/
3497 createDefault (ast * swStat, ast * stmnt)
3499 char defLbl[SDCC_NAME_MAX + 1];
3501 /* if the switch statement does not exist */
3502 /* then case is out of context */
3505 werror (E_CASE_CONTEXT);
3509 /* turn on the default flag */
3510 swStat->values.switchVals.swDefault = 1;
3512 /* create the label */
3513 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3514 return createLabel (newSymbol (defLbl, 0), stmnt);
3517 /*-----------------------------------------------------------------*/
3518 /* createIf - creates the parsetree for the if statement */
3519 /*-----------------------------------------------------------------*/
3521 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3523 static int Lblnum = 0;
3525 symbol *ifTrue, *ifFalse, *ifEnd;
3527 /* if neither exists */
3528 if (!elseBody && !ifBody) {
3529 // if there are no side effects (i++, j() etc)
3530 if (!hasSEFcalls(condAst)) {
3535 /* create the labels */
3536 sprintf (buffer, "_iffalse_%d", Lblnum);
3537 ifFalse = newSymbol (buffer, NestLevel);
3538 /* if no else body then end == false */
3543 sprintf (buffer, "_ifend_%d", Lblnum);
3544 ifEnd = newSymbol (buffer, NestLevel);
3547 sprintf (buffer, "_iftrue_%d", Lblnum);
3548 ifTrue = newSymbol (buffer, NestLevel);
3552 /* attach the ifTrue label to the top of it body */
3553 ifBody = createLabel (ifTrue, ifBody);
3554 /* attach a goto end to the ifBody if else is present */
3557 ifBody = newNode (NULLOP, ifBody,
3559 newAst_VALUE (symbolVal (ifEnd)),
3561 /* put the elseLabel on the else body */
3562 elseBody = createLabel (ifFalse, elseBody);
3563 /* out the end at the end of the body */
3564 elseBody = newNode (NULLOP,
3566 createLabel (ifEnd, NULL));
3570 ifBody = newNode (NULLOP, ifBody,
3571 createLabel (ifFalse, NULL));
3573 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3574 if (IS_IFX (condAst))
3577 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3579 return newNode (NULLOP, ifTree,
3580 newNode (NULLOP, ifBody, elseBody));
3584 /*-----------------------------------------------------------------*/
3585 /* createDo - creates parse tree for do */
3588 /* _docontinue_n: */
3589 /* condition_expression +-> trueLabel -> _dobody_n */
3591 /* +-> falseLabel-> _dobreak_n */
3593 /*-----------------------------------------------------------------*/
3595 createDo (symbol * trueLabel, symbol * continueLabel,
3596 symbol * falseLabel, ast * condAst, ast * doBody)
3601 /* if the body does not exist then it is simple */
3604 condAst = backPatchLabels (condAst, continueLabel, NULL);
3605 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3606 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3607 doTree->trueLabel = continueLabel;
3608 doTree->falseLabel = NULL;
3612 /* otherwise we have a body */
3613 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3615 /* attach the body label to the top */
3616 doBody = createLabel (trueLabel, doBody);
3617 /* attach the continue label to end of body */
3618 doBody = newNode (NULLOP, doBody,
3619 createLabel (continueLabel, NULL));
3621 /* now put the break label at the end */
3622 if (IS_IFX (condAst))
3625 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3627 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3629 /* putting it together */
3630 return newNode (NULLOP, doBody, doTree);
3633 /*-----------------------------------------------------------------*/
3634 /* createFor - creates parse tree for 'for' statement */
3637 /* condExpr +-> trueLabel -> _forbody_n */
3639 /* +-> falseLabel-> _forbreak_n */
3642 /* _forcontinue_n: */
3644 /* goto _forcond_n ; */
3646 /*-----------------------------------------------------------------*/
3648 createFor (symbol * trueLabel, symbol * continueLabel,
3649 symbol * falseLabel, symbol * condLabel,
3650 ast * initExpr, ast * condExpr, ast * loopExpr,
3655 /* if loopexpression not present then we can generate it */
3656 /* the same way as a while */
3658 return newNode (NULLOP, initExpr,
3659 createWhile (trueLabel, continueLabel,
3660 falseLabel, condExpr, forBody));
3661 /* vanilla for statement */
3662 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3664 if (condExpr && !IS_IFX (condExpr))
3665 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3668 /* attach condition label to condition */
3669 condExpr = createLabel (condLabel, condExpr);
3671 /* attach body label to body */
3672 forBody = createLabel (trueLabel, forBody);
3674 /* attach continue to forLoop expression & attach */
3675 /* goto the forcond @ and of loopExpression */
3676 loopExpr = createLabel (continueLabel,
3680 newAst_VALUE (symbolVal (condLabel)),
3682 /* now start putting them together */
3683 forTree = newNode (NULLOP, initExpr, condExpr);
3684 forTree = newNode (NULLOP, forTree, forBody);
3685 forTree = newNode (NULLOP, forTree, loopExpr);
3686 /* finally add the break label */
3687 forTree = newNode (NULLOP, forTree,
3688 createLabel (falseLabel, NULL));
3692 /*-----------------------------------------------------------------*/
3693 /* createWhile - creates parse tree for while statement */
3694 /* the while statement will be created as follows */
3696 /* _while_continue_n: */
3697 /* condition_expression +-> trueLabel -> _while_boby_n */
3699 /* +-> falseLabel -> _while_break_n */
3700 /* _while_body_n: */
3702 /* goto _while_continue_n */
3703 /* _while_break_n: */
3704 /*-----------------------------------------------------------------*/
3706 createWhile (symbol * trueLabel, symbol * continueLabel,
3707 symbol * falseLabel, ast * condExpr, ast * whileBody)
3711 /* put the continue label */
3712 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3713 condExpr = createLabel (continueLabel, condExpr);
3714 condExpr->lineno = 0;
3716 /* put the body label in front of the body */
3717 whileBody = createLabel (trueLabel, whileBody);
3718 whileBody->lineno = 0;
3719 /* put a jump to continue at the end of the body */
3720 /* and put break label at the end of the body */
3721 whileBody = newNode (NULLOP,
3724 newAst_VALUE (symbolVal (continueLabel)),
3725 createLabel (falseLabel, NULL)));
3727 /* put it all together */
3728 if (IS_IFX (condExpr))
3729 whileTree = condExpr;
3732 whileTree = newNode (IFX, condExpr, NULL);
3733 /* put the true & false labels in place */
3734 whileTree->trueLabel = trueLabel;
3735 whileTree->falseLabel = falseLabel;
3738 return newNode (NULLOP, whileTree, whileBody);
3741 /*-----------------------------------------------------------------*/
3742 /* optimizeGetHbit - get highest order bit of the expression */
3743 /*-----------------------------------------------------------------*/
3745 optimizeGetHbit (ast * tree)
3748 /* if this is not a bit and */
3749 if (!IS_BITAND (tree))
3752 /* will look for tree of the form
3753 ( expr >> ((sizeof expr) -1) ) & 1 */
3754 if (!IS_AST_LIT_VALUE (tree->right))
3757 if (AST_LIT_VALUE (tree->right) != 1)
3760 if (!IS_RIGHT_OP (tree->left))
3763 if (!IS_AST_LIT_VALUE (tree->left->right))
3766 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3767 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3770 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3774 /*-----------------------------------------------------------------*/
3775 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3776 /*-----------------------------------------------------------------*/
3778 optimizeRRCRLC (ast * root)
3780 /* will look for trees of the form
3781 (?expr << 1) | (?expr >> 7) or
3782 (?expr >> 7) | (?expr << 1) will make that
3783 into a RLC : operation ..
3785 (?expr >> 1) | (?expr << 7) or
3786 (?expr << 7) | (?expr >> 1) will make that
3787 into a RRC operation
3788 note : by 7 I mean (number of bits required to hold the
3790 /* if the root operations is not a | operation the not */
3791 if (!IS_BITOR (root))
3794 /* I have to think of a better way to match patterns this sucks */
3795 /* that aside let start looking for the first case : I use a the
3796 negative check a lot to improve the efficiency */
3797 /* (?expr << 1) | (?expr >> 7) */
3798 if (IS_LEFT_OP (root->left) &&
3799 IS_RIGHT_OP (root->right))
3802 if (!SPEC_USIGN (TETYPE (root->left->left)))
3805 if (!IS_AST_LIT_VALUE (root->left->right) ||
3806 !IS_AST_LIT_VALUE (root->right->right))
3809 /* make sure it is the same expression */
3810 if (!isAstEqual (root->left->left,
3814 if (AST_LIT_VALUE (root->left->right) != 1)
3817 if (AST_LIT_VALUE (root->right->right) !=
3818 (getSize (TTYPE (root->left->left)) * 8 - 1))
3821 /* whew got the first case : create the AST */
3822 return newNode (RLC, root->left->left, NULL);
3826 /* check for second case */
3827 /* (?expr >> 7) | (?expr << 1) */
3828 if (IS_LEFT_OP (root->right) &&
3829 IS_RIGHT_OP (root->left))
3832 if (!SPEC_USIGN (TETYPE (root->left->left)))
3835 if (!IS_AST_LIT_VALUE (root->left->right) ||
3836 !IS_AST_LIT_VALUE (root->right->right))
3839 /* make sure it is the same symbol */
3840 if (!isAstEqual (root->left->left,
3844 if (AST_LIT_VALUE (root->right->right) != 1)
3847 if (AST_LIT_VALUE (root->left->right) !=
3848 (getSize (TTYPE (root->left->left)) * 8 - 1))
3851 /* whew got the first case : create the AST */
3852 return newNode (RLC, root->left->left, NULL);
3857 /* third case for RRC */
3858 /* (?symbol >> 1) | (?symbol << 7) */
3859 if (IS_LEFT_OP (root->right) &&
3860 IS_RIGHT_OP (root->left))
3863 if (!SPEC_USIGN (TETYPE (root->left->left)))
3866 if (!IS_AST_LIT_VALUE (root->left->right) ||
3867 !IS_AST_LIT_VALUE (root->right->right))
3870 /* make sure it is the same symbol */
3871 if (!isAstEqual (root->left->left,
3875 if (AST_LIT_VALUE (root->left->right) != 1)
3878 if (AST_LIT_VALUE (root->right->right) !=
3879 (getSize (TTYPE (root->left->left)) * 8 - 1))
3882 /* whew got the first case : create the AST */
3883 return newNode (RRC, root->left->left, NULL);
3887 /* fourth and last case for now */
3888 /* (?symbol << 7) | (?symbol >> 1) */
3889 if (IS_RIGHT_OP (root->right) &&
3890 IS_LEFT_OP (root->left))
3893 if (!SPEC_USIGN (TETYPE (root->left->left)))
3896 if (!IS_AST_LIT_VALUE (root->left->right) ||
3897 !IS_AST_LIT_VALUE (root->right->right))
3900 /* make sure it is the same symbol */
3901 if (!isAstEqual (root->left->left,
3905 if (AST_LIT_VALUE (root->right->right) != 1)
3908 if (AST_LIT_VALUE (root->left->right) !=
3909 (getSize (TTYPE (root->left->left)) * 8 - 1))
3912 /* whew got the first case : create the AST */
3913 return newNode (RRC, root->left->left, NULL);
3917 /* not found return root */
3921 /*-----------------------------------------------------------------*/
3922 /* optimizeCompare - otimizes compares for bit variables */
3923 /*-----------------------------------------------------------------*/
3925 optimizeCompare (ast * root)
3927 ast *optExpr = NULL;
3930 unsigned int litValue;
3932 /* if nothing then return nothing */
3936 /* if not a compare op then do leaves */
3937 if (!IS_COMPARE_OP (root))
3939 root->left = optimizeCompare (root->left);
3940 root->right = optimizeCompare (root->right);
3944 /* if left & right are the same then depending
3945 of the operation do */
3946 if (isAstEqual (root->left, root->right))
3948 switch (root->opval.op)
3953 optExpr = newAst_VALUE (constVal ("0"));
3958 optExpr = newAst_VALUE (constVal ("1"));
3962 return decorateType (optExpr);
3965 vleft = (root->left->type == EX_VALUE ?
3966 root->left->opval.val : NULL);
3968 vright = (root->right->type == EX_VALUE ?
3969 root->right->opval.val : NULL);
3971 /* if left is a BITVAR in BITSPACE */
3972 /* and right is a LITERAL then opt- */
3973 /* imize else do nothing */
3974 if (vleft && vright &&
3975 IS_BITVAR (vleft->etype) &&
3976 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3977 IS_LITERAL (vright->etype))
3980 /* if right side > 1 then comparison may never succeed */
3981 if ((litValue = (int) floatFromVal (vright)) > 1)
3983 werror (W_BAD_COMPARE);
3989 switch (root->opval.op)
3991 case '>': /* bit value greater than 1 cannot be */
3992 werror (W_BAD_COMPARE);
3996 case '<': /* bit value < 1 means 0 */
3998 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4001 case LE_OP: /* bit value <= 1 means no check */
4002 optExpr = newAst_VALUE (vright);
4005 case GE_OP: /* bit value >= 1 means only check for = */
4007 optExpr = newAst_VALUE (vleft);
4012 { /* literal is zero */
4013 switch (root->opval.op)
4015 case '<': /* bit value < 0 cannot be */
4016 werror (W_BAD_COMPARE);
4020 case '>': /* bit value > 0 means 1 */
4022 optExpr = newAst_VALUE (vleft);
4025 case LE_OP: /* bit value <= 0 means no check */
4026 case GE_OP: /* bit value >= 0 means no check */
4027 werror (W_BAD_COMPARE);
4031 case EQ_OP: /* bit == 0 means ! of bit */
4032 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4036 return decorateType (resolveSymbols (optExpr));
4037 } /* end-of-if of BITVAR */
4042 /*-----------------------------------------------------------------*/
4043 /* addSymToBlock : adds the symbol to the first block we find */
4044 /*-----------------------------------------------------------------*/
4046 addSymToBlock (symbol * sym, ast * tree)
4048 /* reached end of tree or a leaf */
4049 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4053 if (IS_AST_OP (tree) &&
4054 tree->opval.op == BLOCK)
4057 symbol *lsym = copySymbol (sym);
4059 lsym->next = AST_VALUES (tree, sym);
4060 AST_VALUES (tree, sym) = lsym;
4064 addSymToBlock (sym, tree->left);
4065 addSymToBlock (sym, tree->right);
4068 /*-----------------------------------------------------------------*/
4069 /* processRegParms - do processing for register parameters */
4070 /*-----------------------------------------------------------------*/
4072 processRegParms (value * args, ast * body)
4076 if (IS_REGPARM (args->etype))
4077 addSymToBlock (args->sym, body);
4082 /*-----------------------------------------------------------------*/
4083 /* resetParmKey - resets the operandkeys for the symbols */
4084 /*-----------------------------------------------------------------*/
4085 DEFSETFUNC (resetParmKey)
4096 /*-----------------------------------------------------------------*/
4097 /* createFunction - This is the key node that calls the iCode for */
4098 /* generating the code for a function. Note code */
4099 /* is generated function by function, later when */
4100 /* add inter-procedural analysis this will change */
4101 /*-----------------------------------------------------------------*/
4103 createFunction (symbol * name, ast * body)
4109 iCode *piCode = NULL;
4111 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4112 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4114 /* if check function return 0 then some problem */
4115 if (checkFunction (name, NULL) == 0)
4118 /* create a dummy block if none exists */
4120 body = newNode (BLOCK, NULL, NULL);
4124 /* check if the function name already in the symbol table */
4125 if ((csym = findSym (SymbolTab, NULL, name->name)))
4128 /* special case for compiler defined functions
4129 we need to add the name to the publics list : this
4130 actually means we are now compiling the compiler
4134 addSet (&publics, name);
4140 allocVariables (name);
4142 name->lastLine = yylineno;
4145 #if 0 // jwk: this is now done in addDecl()
4146 processFuncArgs (currFunc);
4149 /* set the stack pointer */
4150 /* PENDING: check this for the mcs51 */
4151 stackPtr = -port->stack.direction * port->stack.call_overhead;
4152 if (IFFUNC_ISISR (name->type))
4153 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4154 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4155 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4157 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4159 fetype = getSpec (name->type); /* get the specifier for the function */
4160 /* if this is a reentrant function then */
4161 if (IFFUNC_ISREENT (name->type))
4164 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4166 /* do processing for parameters that are passed in registers */
4167 processRegParms (FUNC_ARGS(name->type), body);
4169 /* set the stack pointer */
4173 /* allocate & autoinit the block variables */
4174 processBlockVars (body, &stack, ALLOCATE);
4176 /* save the stack information */
4177 if (options.useXstack)
4178 name->xstack = SPEC_STAK (fetype) = stack;
4180 name->stack = SPEC_STAK (fetype) = stack;
4182 /* name needs to be mangled */
4183 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4185 body = resolveSymbols (body); /* resolve the symbols */
4186 body = decorateType (body); /* propagateType & do semantic checks */
4188 ex = newAst_VALUE (symbolVal (name)); /* create name */
4189 ex = newNode (FUNCTION, ex, body);
4190 ex->values.args = FUNC_ARGS(name->type);
4192 if (options.dump_tree) PA(ex);
4195 werror (E_FUNC_NO_CODE, name->name);
4199 /* create the node & generate intermediate code */
4201 codeOutFile = code->oFile;
4202 piCode = iCodeFromAst (ex);
4206 werror (E_FUNC_NO_CODE, name->name);
4210 eBBlockFromiCode (piCode);
4212 /* if there are any statics then do them */
4215 GcurMemmap = statsg;
4216 codeOutFile = statsg->oFile;
4217 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4223 /* dealloc the block variables */
4224 processBlockVars (body, &stack, DEALLOCATE);
4225 /* deallocate paramaters */
4226 deallocParms (FUNC_ARGS(name->type));
4228 if (IFFUNC_ISREENT (name->type))
4231 /* we are done freeup memory & cleanup */
4235 FUNC_HASBODY(name->type) = 1;
4236 addSet (&operKeyReset, name);
4237 applyToSet (operKeyReset, resetParmKey);
4240 cdbStructBlock (1, cdbFile);
4242 cleanUpLevel (LabelTab, 0);
4243 cleanUpBlock (StructTab, 1);
4244 cleanUpBlock (TypedefTab, 1);
4246 xstack->syms = NULL;
4247 istack->syms = NULL;
4252 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4253 /*-----------------------------------------------------------------*/
4254 /* ast_print : prints the ast (for debugging purposes) */
4255 /*-----------------------------------------------------------------*/
4257 void ast_print (ast * tree, FILE *outfile, int indent)
4262 /* can print only decorated trees */
4263 if (!tree->decorated) return;
4265 /* if any child is an error | this one is an error do nothing */
4266 if (tree->isError ||
4267 (tree->left && tree->left->isError) ||
4268 (tree->right && tree->right->isError)) {
4269 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4273 /* print the line */
4274 /* if not block & function */
4275 if (tree->type == EX_OP &&
4276 (tree->opval.op != FUNCTION &&
4277 tree->opval.op != BLOCK &&
4278 tree->opval.op != NULLOP)) {
4281 if (tree->opval.op == FUNCTION) {
4283 value *args=FUNC_ARGS(tree->left->opval.val->type);
4284 fprintf(outfile,"FUNCTION (%s=%p) type (",
4285 tree->left->opval.val->name, tree);
4286 printTypeChain (tree->ftype,outfile);
4287 fprintf(outfile,") args (");
4290 fprintf (outfile, ", ");
4292 printTypeChain (args ? args->type : NULL, outfile);
4294 args= args ? args->next : NULL;
4296 fprintf(outfile,")\n");
4297 ast_print(tree->left,outfile,indent);
4298 ast_print(tree->right,outfile,indent);
4301 if (tree->opval.op == BLOCK) {
4302 symbol *decls = tree->values.sym;
4303 INDENT(indent,outfile);
4304 fprintf(outfile,"{\n");
4306 INDENT(indent+4,outfile);
4307 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4308 decls->name, decls);
4309 printTypeChain(decls->type,outfile);
4310 fprintf(outfile,")\n");
4312 decls = decls->next;
4314 ast_print(tree->right,outfile,indent+4);
4315 INDENT(indent,outfile);
4316 fprintf(outfile,"}\n");
4319 if (tree->opval.op == NULLOP) {
4320 fprintf(outfile,"\n");
4321 ast_print(tree->left,outfile,indent);
4322 fprintf(outfile,"\n");
4323 ast_print(tree->right,outfile,indent);
4326 INDENT(indent,outfile);
4328 /*------------------------------------------------------------------*/
4329 /*----------------------------*/
4330 /* leaf has been reached */
4331 /*----------------------------*/
4332 /* if this is of type value */
4333 /* just get the type */
4334 if (tree->type == EX_VALUE) {
4336 if (IS_LITERAL (tree->opval.val->etype)) {
4337 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4338 (int) floatFromVal(tree->opval.val),
4339 (int) floatFromVal(tree->opval.val),
4340 floatFromVal(tree->opval.val));
4341 } else if (tree->opval.val->sym) {
4342 /* if the undefined flag is set then give error message */
4343 if (tree->opval.val->sym->undefined) {
4344 fprintf(outfile,"UNDEFINED SYMBOL ");
4346 fprintf(outfile,"SYMBOL ");
4348 fprintf(outfile,"(%s=%p)",
4349 tree->opval.val->sym->name,tree);
4352 fprintf(outfile," type (");
4353 printTypeChain(tree->ftype,outfile);
4354 fprintf(outfile,")\n");
4356 fprintf(outfile,"\n");
4361 /* if type link for the case of cast */
4362 if (tree->type == EX_LINK) {
4363 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4364 printTypeChain(tree->opval.lnk,outfile);
4365 fprintf(outfile,")\n");
4370 /* depending on type of operator do */
4372 switch (tree->opval.op) {
4373 /*------------------------------------------------------------------*/
4374 /*----------------------------*/
4376 /*----------------------------*/
4378 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4379 printTypeChain(tree->ftype,outfile);
4380 fprintf(outfile,")\n");
4381 ast_print(tree->left,outfile,indent+4);
4382 ast_print(tree->right,outfile,indent+4);
4385 /*------------------------------------------------------------------*/
4386 /*----------------------------*/
4388 /*----------------------------*/
4390 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4391 printTypeChain(tree->ftype,outfile);
4392 fprintf(outfile,")\n");
4393 ast_print(tree->left,outfile,indent+4);
4394 ast_print(tree->right,outfile,indent+4);
4397 /*------------------------------------------------------------------*/
4398 /*----------------------------*/
4399 /* struct/union pointer */
4400 /*----------------------------*/
4402 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4403 printTypeChain(tree->ftype,outfile);
4404 fprintf(outfile,")\n");
4405 ast_print(tree->left,outfile,indent+4);
4406 ast_print(tree->right,outfile,indent+4);
4409 /*------------------------------------------------------------------*/
4410 /*----------------------------*/
4411 /* ++/-- operation */
4412 /*----------------------------*/
4413 case INC_OP: /* incerement operator unary so left only */
4414 fprintf(outfile,"INC_OP (%p) type (",tree);
4415 printTypeChain(tree->ftype,outfile);
4416 fprintf(outfile,")\n");
4417 ast_print(tree->left,outfile,indent+4);
4421 fprintf(outfile,"DEC_OP (%p) type (",tree);
4422 printTypeChain(tree->ftype,outfile);
4423 fprintf(outfile,")\n");
4424 ast_print(tree->left,outfile,indent+4);
4427 /*------------------------------------------------------------------*/
4428 /*----------------------------*/
4430 /*----------------------------*/
4433 fprintf(outfile,"& (%p) type (",tree);
4434 printTypeChain(tree->ftype,outfile);
4435 fprintf(outfile,")\n");
4436 ast_print(tree->left,outfile,indent+4);
4437 ast_print(tree->right,outfile,indent+4);
4439 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4440 printTypeChain(tree->ftype,outfile);
4441 fprintf(outfile,")\n");
4442 ast_print(tree->left,outfile,indent+4);
4443 ast_print(tree->right,outfile,indent+4);
4446 /*----------------------------*/
4448 /*----------------------------*/
4450 fprintf(outfile,"OR (%p) type (",tree);
4451 printTypeChain(tree->ftype,outfile);
4452 fprintf(outfile,")\n");
4453 ast_print(tree->left,outfile,indent+4);
4454 ast_print(tree->right,outfile,indent+4);
4456 /*------------------------------------------------------------------*/
4457 /*----------------------------*/
4459 /*----------------------------*/
4461 fprintf(outfile,"XOR (%p) type (",tree);
4462 printTypeChain(tree->ftype,outfile);
4463 fprintf(outfile,")\n");
4464 ast_print(tree->left,outfile,indent+4);
4465 ast_print(tree->right,outfile,indent+4);
4468 /*------------------------------------------------------------------*/
4469 /*----------------------------*/
4471 /*----------------------------*/
4473 fprintf(outfile,"DIV (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+4);
4477 ast_print(tree->right,outfile,indent+4);
4479 /*------------------------------------------------------------------*/
4480 /*----------------------------*/
4482 /*----------------------------*/
4484 fprintf(outfile,"MOD (%p) type (",tree);
4485 printTypeChain(tree->ftype,outfile);
4486 fprintf(outfile,")\n");
4487 ast_print(tree->left,outfile,indent+4);
4488 ast_print(tree->right,outfile,indent+4);
4491 /*------------------------------------------------------------------*/
4492 /*----------------------------*/
4493 /* address dereference */
4494 /*----------------------------*/
4495 case '*': /* can be unary : if right is null then unary operation */
4497 fprintf(outfile,"DEREF (%p) type (",tree);
4498 printTypeChain(tree->ftype,outfile);
4499 fprintf(outfile,")\n");
4500 ast_print(tree->left,outfile,indent+4);
4503 /*------------------------------------------------------------------*/
4504 /*----------------------------*/
4505 /* multiplication */
4506 /*----------------------------*/
4507 fprintf(outfile,"MULT (%p) type (",tree);
4508 printTypeChain(tree->ftype,outfile);
4509 fprintf(outfile,")\n");
4510 ast_print(tree->left,outfile,indent+4);
4511 ast_print(tree->right,outfile,indent+4);
4515 /*------------------------------------------------------------------*/
4516 /*----------------------------*/
4517 /* unary '+' operator */
4518 /*----------------------------*/
4522 fprintf(outfile,"UPLUS (%p) type (",tree);
4523 printTypeChain(tree->ftype,outfile);
4524 fprintf(outfile,")\n");
4525 ast_print(tree->left,outfile,indent+4);
4527 /*------------------------------------------------------------------*/
4528 /*----------------------------*/
4530 /*----------------------------*/
4531 fprintf(outfile,"ADD (%p) type (",tree);
4532 printTypeChain(tree->ftype,outfile);
4533 fprintf(outfile,")\n");
4534 ast_print(tree->left,outfile,indent+4);
4535 ast_print(tree->right,outfile,indent+4);
4538 /*------------------------------------------------------------------*/
4539 /*----------------------------*/
4541 /*----------------------------*/
4542 case '-': /* can be unary */
4544 fprintf(outfile,"UMINUS (%p) type (",tree);
4545 printTypeChain(tree->ftype,outfile);
4546 fprintf(outfile,")\n");
4547 ast_print(tree->left,outfile,indent+4);
4549 /*------------------------------------------------------------------*/
4550 /*----------------------------*/
4552 /*----------------------------*/
4553 fprintf(outfile,"SUB (%p) type (",tree);
4554 printTypeChain(tree->ftype,outfile);
4555 fprintf(outfile,")\n");
4556 ast_print(tree->left,outfile,indent+4);
4557 ast_print(tree->right,outfile,indent+4);
4560 /*------------------------------------------------------------------*/
4561 /*----------------------------*/
4563 /*----------------------------*/
4565 fprintf(outfile,"COMPL (%p) type (",tree);
4566 printTypeChain(tree->ftype,outfile);
4567 fprintf(outfile,")\n");
4568 ast_print(tree->left,outfile,indent+4);
4570 /*------------------------------------------------------------------*/
4571 /*----------------------------*/
4573 /*----------------------------*/
4575 fprintf(outfile,"NOT (%p) type (",tree);
4576 printTypeChain(tree->ftype,outfile);
4577 fprintf(outfile,")\n");
4578 ast_print(tree->left,outfile,indent+4);
4580 /*------------------------------------------------------------------*/
4581 /*----------------------------*/
4583 /*----------------------------*/
4585 fprintf(outfile,"RRC (%p) type (",tree);
4586 printTypeChain(tree->ftype,outfile);
4587 fprintf(outfile,")\n");
4588 ast_print(tree->left,outfile,indent+4);
4592 fprintf(outfile,"RLC (%p) type (",tree);
4593 printTypeChain(tree->ftype,outfile);
4594 fprintf(outfile,")\n");
4595 ast_print(tree->left,outfile,indent+4);
4598 fprintf(outfile,"GETHBIT (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+4);
4604 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4605 printTypeChain(tree->ftype,outfile);
4606 fprintf(outfile,")\n");
4607 ast_print(tree->left,outfile,indent+4);
4608 ast_print(tree->right,outfile,indent+4);
4611 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4612 printTypeChain(tree->ftype,outfile);
4613 fprintf(outfile,")\n");
4614 ast_print(tree->left,outfile,indent+4);
4615 ast_print(tree->right,outfile,indent+4);
4617 /*------------------------------------------------------------------*/
4618 /*----------------------------*/
4620 /*----------------------------*/
4621 case CAST: /* change the type */
4622 fprintf(outfile,"CAST (%p) from type (",tree);
4623 printTypeChain(tree->right->ftype,outfile);
4624 fprintf(outfile,") to type (");
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->right,outfile,indent+4);
4631 fprintf(outfile,"ANDAND (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+4);
4635 ast_print(tree->right,outfile,indent+4);
4638 fprintf(outfile,"OROR (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+4);
4642 ast_print(tree->right,outfile,indent+4);
4645 /*------------------------------------------------------------------*/
4646 /*----------------------------*/
4647 /* comparison operators */
4648 /*----------------------------*/
4650 fprintf(outfile,"GT(>) (%p) type (",tree);
4651 printTypeChain(tree->ftype,outfile);
4652 fprintf(outfile,")\n");
4653 ast_print(tree->left,outfile,indent+4);
4654 ast_print(tree->right,outfile,indent+4);
4657 fprintf(outfile,"LT(<) (%p) type (",tree);
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->left,outfile,indent+4);
4661 ast_print(tree->right,outfile,indent+4);
4664 fprintf(outfile,"LE(<=) (%p) type (",tree);
4665 printTypeChain(tree->ftype,outfile);
4666 fprintf(outfile,")\n");
4667 ast_print(tree->left,outfile,indent+4);
4668 ast_print(tree->right,outfile,indent+4);
4671 fprintf(outfile,"GE(>=) (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+4);
4675 ast_print(tree->right,outfile,indent+4);
4678 fprintf(outfile,"EQ(==) (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+4);
4682 ast_print(tree->right,outfile,indent+4);
4685 fprintf(outfile,"NE(!=) (%p) type (",tree);
4686 printTypeChain(tree->ftype,outfile);
4687 fprintf(outfile,")\n");
4688 ast_print(tree->left,outfile,indent+4);
4689 ast_print(tree->right,outfile,indent+4);
4690 /*------------------------------------------------------------------*/
4691 /*----------------------------*/
4693 /*----------------------------*/
4694 case SIZEOF: /* evaluate wihout code generation */
4695 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4698 /*------------------------------------------------------------------*/
4699 /*----------------------------*/
4700 /* conditional operator '?' */
4701 /*----------------------------*/
4703 fprintf(outfile,"QUEST(?) (%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);
4711 fprintf(outfile,"COLON(:) (%p) type (",tree);
4712 printTypeChain(tree->ftype,outfile);
4713 fprintf(outfile,")\n");
4714 ast_print(tree->left,outfile,indent+4);
4715 ast_print(tree->right,outfile,indent+4);
4718 /*------------------------------------------------------------------*/
4719 /*----------------------------*/
4720 /* assignment operators */
4721 /*----------------------------*/
4723 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4724 printTypeChain(tree->ftype,outfile);
4725 fprintf(outfile,")\n");
4726 ast_print(tree->left,outfile,indent+4);
4727 ast_print(tree->right,outfile,indent+4);
4730 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4731 printTypeChain(tree->ftype,outfile);
4732 fprintf(outfile,")\n");
4733 ast_print(tree->left,outfile,indent+4);
4734 ast_print(tree->right,outfile,indent+4);
4737 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4738 printTypeChain(tree->ftype,outfile);
4739 fprintf(outfile,")\n");
4740 ast_print(tree->left,outfile,indent+4);
4741 ast_print(tree->right,outfile,indent+4);
4744 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+4);
4748 ast_print(tree->right,outfile,indent+4);
4751 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+4);
4755 ast_print(tree->right,outfile,indent+4);
4758 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4759 printTypeChain(tree->ftype,outfile);
4760 fprintf(outfile,")\n");
4761 ast_print(tree->left,outfile,indent+4);
4762 ast_print(tree->right,outfile,indent+4);
4765 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4766 printTypeChain(tree->ftype,outfile);
4767 fprintf(outfile,")\n");
4768 ast_print(tree->left,outfile,indent+4);
4769 ast_print(tree->right,outfile,indent+4);
4771 /*------------------------------------------------------------------*/
4772 /*----------------------------*/
4774 /*----------------------------*/
4776 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+4);
4780 ast_print(tree->right,outfile,indent+4);
4782 /*------------------------------------------------------------------*/
4783 /*----------------------------*/
4785 /*----------------------------*/
4787 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4788 printTypeChain(tree->ftype,outfile);
4789 fprintf(outfile,")\n");
4790 ast_print(tree->left,outfile,indent+4);
4791 ast_print(tree->right,outfile,indent+4);
4793 /*------------------------------------------------------------------*/
4794 /*----------------------------*/
4795 /* straight assignemnt */
4796 /*----------------------------*/
4798 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4799 printTypeChain(tree->ftype,outfile);
4800 fprintf(outfile,")\n");
4801 ast_print(tree->left,outfile,indent+4);
4802 ast_print(tree->right,outfile,indent+4);
4804 /*------------------------------------------------------------------*/
4805 /*----------------------------*/
4806 /* comma operator */
4807 /*----------------------------*/
4809 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4810 printTypeChain(tree->ftype,outfile);
4811 fprintf(outfile,")\n");
4812 ast_print(tree->left,outfile,indent+4);
4813 ast_print(tree->right,outfile,indent+4);
4815 /*------------------------------------------------------------------*/
4816 /*----------------------------*/
4818 /*----------------------------*/
4821 fprintf(outfile,"CALL (%p) type (",tree);
4822 printTypeChain(tree->ftype,outfile);
4823 fprintf(outfile,")\n");
4824 ast_print(tree->left,outfile,indent+4);
4825 ast_print(tree->right,outfile,indent+4);
4828 fprintf(outfile,"PARMS\n");
4829 ast_print(tree->left,outfile,indent+4);
4830 if (tree->right && !IS_AST_PARAM(tree->right)) {
4831 ast_print(tree->right,outfile,indent+4);
4834 /*------------------------------------------------------------------*/
4835 /*----------------------------*/
4836 /* return statement */
4837 /*----------------------------*/
4839 fprintf(outfile,"RETURN (%p) type (",tree);
4840 printTypeChain(tree->right->ftype,outfile);
4841 fprintf(outfile,")\n");
4842 ast_print(tree->right,outfile,indent+4);
4844 /*------------------------------------------------------------------*/
4845 /*----------------------------*/
4846 /* label statement */
4847 /*----------------------------*/
4849 fprintf(outfile,"LABEL (%p)",tree);
4850 ast_print(tree->left,outfile,indent+4);
4851 ast_print(tree->right,outfile,indent);
4853 /*------------------------------------------------------------------*/
4854 /*----------------------------*/
4855 /* switch statement */
4856 /*----------------------------*/
4860 fprintf(outfile,"SWITCH (%p) ",tree);
4861 ast_print(tree->left,outfile,0);
4862 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4863 INDENT(indent+4,outfile);
4864 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4865 (int) floatFromVal(val),
4866 tree->values.switchVals.swNum,
4867 (int) floatFromVal(val));
4869 ast_print(tree->right,outfile,indent);
4872 /*------------------------------------------------------------------*/
4873 /*----------------------------*/
4875 /*----------------------------*/
4877 fprintf(outfile,"IF (%p) \n",tree);
4878 ast_print(tree->left,outfile,indent+4);
4879 if (tree->trueLabel) {
4880 INDENT(indent,outfile);
4881 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4883 if (tree->falseLabel) {
4884 INDENT(indent,outfile);
4885 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4887 ast_print(tree->right,outfile,indent+4);
4889 /*------------------------------------------------------------------*/
4890 /*----------------------------*/
4892 /*----------------------------*/
4894 fprintf(outfile,"FOR (%p) \n",tree);
4895 if (AST_FOR( tree, initExpr)) {
4896 INDENT(indent+4,outfile);
4897 fprintf(outfile,"INIT EXPR ");
4898 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4900 if (AST_FOR( tree, condExpr)) {
4901 INDENT(indent+4,outfile);
4902 fprintf(outfile,"COND EXPR ");
4903 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4905 if (AST_FOR( tree, loopExpr)) {
4906 INDENT(indent+4,outfile);
4907 fprintf(outfile,"LOOP EXPR ");
4908 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4910 fprintf(outfile,"FOR LOOP BODY \n");
4911 ast_print(tree->left,outfile,indent+4);
4920 ast_print(t,stdout,0);