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 computeType (LTYPE (tree), RTYPE (tree));
2094 TETYPE (tree) = getSpec (TTYPE (tree));
2096 LRVAL (tree) = RRVAL (tree) = 1;
2100 /*------------------------------------------------------------------*/
2101 /*----------------------------*/
2103 /*----------------------------*/
2105 p->class = DECLARATOR;
2106 /* if bit field then error */
2107 if (IS_BITVAR (tree->left->etype))
2109 werror (E_ILLEGAL_ADDR, "address of bit variable");
2110 goto errorTreeReturn;
2113 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2115 werror (E_ILLEGAL_ADDR, "address of register variable");
2116 goto errorTreeReturn;
2119 if (IS_FUNC (LTYPE (tree)))
2121 werror (E_ILLEGAL_ADDR, "address of function");
2122 goto errorTreeReturn;
2125 if (IS_LITERAL(LTYPE(tree)))
2127 werror (E_ILLEGAL_ADDR, "address of literal");
2128 goto errorTreeReturn;
2133 werror (E_LVALUE_REQUIRED, "address of");
2134 goto errorTreeReturn;
2136 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2138 DCL_TYPE (p) = CPOINTER;
2139 DCL_PTR_CONST (p) = port->mem.code_ro;
2141 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2142 DCL_TYPE (p) = FPOINTER;
2143 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2144 DCL_TYPE (p) = PPOINTER;
2145 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2146 DCL_TYPE (p) = IPOINTER;
2147 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2148 DCL_TYPE (p) = EEPPOINTER;
2150 DCL_TYPE (p) = POINTER;
2152 if (IS_AST_SYM_VALUE (tree->left))
2154 AST_SYMBOL (tree->left)->addrtaken = 1;
2155 AST_SYMBOL (tree->left)->allocreq = 1;
2158 p->next = LTYPE (tree);
2160 TETYPE (tree) = getSpec (TTYPE (tree));
2161 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2162 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2167 /*------------------------------------------------------------------*/
2168 /*----------------------------*/
2170 /*----------------------------*/
2172 /* if the rewrite succeeds then don't go any furthur */
2174 ast *wtree = optimizeRRCRLC (tree);
2176 return decorateType (wtree);
2178 /*------------------------------------------------------------------*/
2179 /*----------------------------*/
2181 /*----------------------------*/
2183 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2185 werror (E_BITWISE_OP);
2186 werror (W_CONTINUE, "left & right types are ");
2187 printTypeChain (LTYPE (tree), stderr);
2188 fprintf (stderr, ",");
2189 printTypeChain (RTYPE (tree), stderr);
2190 fprintf (stderr, "\n");
2191 goto errorTreeReturn;
2194 /* if they are both literal then */
2195 /* rewrite the tree */
2196 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2198 tree->type = EX_VALUE;
2199 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2200 valFromType (RETYPE (tree)),
2202 tree->right = tree->left = NULL;
2203 TETYPE (tree) = tree->opval.val->etype;
2204 TTYPE (tree) = tree->opval.val->type;
2207 LRVAL (tree) = RRVAL (tree) = 1;
2208 TETYPE (tree) = getSpec (TTYPE (tree) =
2209 computeType (LTYPE (tree),
2212 /*------------------------------------------------------------------*/
2213 /*----------------------------*/
2215 /*----------------------------*/
2217 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2219 werror (E_INVALID_OP, "divide");
2220 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 = valDiv (valFromType (LETYPE (tree)),
2228 valFromType (RETYPE (tree)));
2229 tree->right = tree->left = NULL;
2230 TETYPE (tree) = getSpec (TTYPE (tree) =
2231 tree->opval.val->type);
2234 LRVAL (tree) = RRVAL (tree) = 1;
2235 TETYPE (tree) = getSpec (TTYPE (tree) =
2236 computeType (LTYPE (tree),
2240 /*------------------------------------------------------------------*/
2241 /*----------------------------*/
2243 /*----------------------------*/
2245 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2247 werror (E_BITWISE_OP);
2248 werror (W_CONTINUE, "left & right types are ");
2249 printTypeChain (LTYPE (tree), stderr);
2250 fprintf (stderr, ",");
2251 printTypeChain (RTYPE (tree), stderr);
2252 fprintf (stderr, "\n");
2253 goto errorTreeReturn;
2255 /* if they are both literal then */
2256 /* rewrite the tree */
2257 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2259 tree->type = EX_VALUE;
2260 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2261 valFromType (RETYPE (tree)));
2262 tree->right = tree->left = NULL;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 tree->opval.val->type);
2267 LRVAL (tree) = RRVAL (tree) = 1;
2268 TETYPE (tree) = getSpec (TTYPE (tree) =
2269 computeType (LTYPE (tree),
2273 /*------------------------------------------------------------------*/
2274 /*----------------------------*/
2275 /* address dereference */
2276 /*----------------------------*/
2277 case '*': /* can be unary : if right is null then unary operation */
2280 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2282 werror (E_PTR_REQD);
2283 goto errorTreeReturn;
2288 werror (E_LVALUE_REQUIRED, "pointer deref");
2289 goto errorTreeReturn;
2291 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2292 LTYPE (tree)->next : NULL);
2293 TETYPE (tree) = getSpec (TTYPE (tree));
2294 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2298 /*------------------------------------------------------------------*/
2299 /*----------------------------*/
2300 /* multiplication */
2301 /*----------------------------*/
2302 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2304 werror (E_INVALID_OP, "multiplication");
2305 goto errorTreeReturn;
2308 /* if they are both literal then */
2309 /* rewrite the tree */
2310 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2312 tree->type = EX_VALUE;
2313 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2314 valFromType (RETYPE (tree)));
2315 tree->right = tree->left = NULL;
2316 TETYPE (tree) = getSpec (TTYPE (tree) =
2317 tree->opval.val->type);
2321 /* if left is a literal exchange left & right */
2322 if (IS_LITERAL (LTYPE (tree)))
2324 ast *tTree = tree->left;
2325 tree->left = tree->right;
2326 tree->right = tTree;
2329 LRVAL (tree) = RRVAL (tree) = 1;
2330 /* promote result to int if left & right are char
2331 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2332 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2333 TETYPE (tree) = getSpec (TTYPE (tree) =
2334 computeType (LTYPE (tree),
2336 SPEC_NOUN(TETYPE(tree)) = V_INT;
2338 TETYPE (tree) = getSpec (TTYPE (tree) =
2339 computeType (LTYPE (tree),
2344 /*------------------------------------------------------------------*/
2345 /*----------------------------*/
2346 /* unary '+' operator */
2347 /*----------------------------*/
2352 if (!IS_INTEGRAL (LTYPE (tree)))
2354 werror (E_UNARY_OP, '+');
2355 goto errorTreeReturn;
2358 /* if left is a literal then do it */
2359 if (IS_LITERAL (LTYPE (tree)))
2361 tree->type = EX_VALUE;
2362 tree->opval.val = valFromType (LETYPE (tree));
2364 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2368 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2372 /*------------------------------------------------------------------*/
2373 /*----------------------------*/
2375 /*----------------------------*/
2377 /* this is not a unary operation */
2378 /* if both pointers then problem */
2379 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2380 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2382 werror (E_PTR_PLUS_PTR);
2383 goto errorTreeReturn;
2386 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2387 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2389 werror (E_PLUS_INVALID, "+");
2390 goto errorTreeReturn;
2393 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2394 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2396 werror (E_PLUS_INVALID, "+");
2397 goto errorTreeReturn;
2399 /* if they are both literal then */
2400 /* rewrite the tree */
2401 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2403 tree->type = EX_VALUE;
2404 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2405 valFromType (RETYPE (tree)));
2406 tree->right = tree->left = NULL;
2407 TETYPE (tree) = getSpec (TTYPE (tree) =
2408 tree->opval.val->type);
2412 /* if the right is a pointer or left is a literal
2413 xchange left & right */
2414 if (IS_ARRAY (RTYPE (tree)) ||
2415 IS_PTR (RTYPE (tree)) ||
2416 IS_LITERAL (LTYPE (tree)))
2418 ast *tTree = tree->left;
2419 tree->left = tree->right;
2420 tree->right = tTree;
2423 LRVAL (tree) = RRVAL (tree) = 1;
2424 /* if the left is a pointer */
2425 if (IS_PTR (LTYPE (tree)))
2426 TETYPE (tree) = getSpec (TTYPE (tree) =
2429 TETYPE (tree) = getSpec (TTYPE (tree) =
2430 computeType (LTYPE (tree),
2434 /*------------------------------------------------------------------*/
2435 /*----------------------------*/
2437 /*----------------------------*/
2438 case '-': /* can be unary */
2439 /* if right is null then unary */
2443 if (!IS_ARITHMETIC (LTYPE (tree)))
2445 werror (E_UNARY_OP, tree->opval.op);
2446 goto errorTreeReturn;
2449 /* if left is a literal then do it */
2450 if (IS_LITERAL (LTYPE (tree)))
2452 tree->type = EX_VALUE;
2453 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2455 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2456 SPEC_USIGN(TETYPE(tree)) = 0;
2460 TTYPE (tree) = LTYPE (tree);
2464 /*------------------------------------------------------------------*/
2465 /*----------------------------*/
2467 /*----------------------------*/
2469 if (!(IS_PTR (LTYPE (tree)) ||
2470 IS_ARRAY (LTYPE (tree)) ||
2471 IS_ARITHMETIC (LTYPE (tree))))
2473 werror (E_PLUS_INVALID, "-");
2474 goto errorTreeReturn;
2477 if (!(IS_PTR (RTYPE (tree)) ||
2478 IS_ARRAY (RTYPE (tree)) ||
2479 IS_ARITHMETIC (RTYPE (tree))))
2481 werror (E_PLUS_INVALID, "-");
2482 goto errorTreeReturn;
2485 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2486 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2487 IS_INTEGRAL (RTYPE (tree))))
2489 werror (E_PLUS_INVALID, "-");
2490 goto errorTreeReturn;
2493 /* if they are both literal then */
2494 /* rewrite the tree */
2495 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2497 tree->type = EX_VALUE;
2498 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2499 valFromType (RETYPE (tree)));
2500 tree->right = tree->left = NULL;
2501 TETYPE (tree) = getSpec (TTYPE (tree) =
2502 tree->opval.val->type);
2506 /* if the left & right are equal then zero */
2507 if (isAstEqual (tree->left, tree->right))
2509 tree->type = EX_VALUE;
2510 tree->left = tree->right = NULL;
2511 tree->opval.val = constVal ("0");
2512 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2516 /* if both of them are pointers or arrays then */
2517 /* the result is going to be an integer */
2518 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2519 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2520 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2522 /* if only the left is a pointer */
2523 /* then result is a pointer */
2524 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2525 TETYPE (tree) = getSpec (TTYPE (tree) =
2528 TETYPE (tree) = getSpec (TTYPE (tree) =
2529 computeType (LTYPE (tree),
2531 LRVAL (tree) = RRVAL (tree) = 1;
2534 /*------------------------------------------------------------------*/
2535 /*----------------------------*/
2537 /*----------------------------*/
2539 /* can be only integral type */
2540 if (!IS_INTEGRAL (LTYPE (tree)))
2542 werror (E_UNARY_OP, tree->opval.op);
2543 goto errorTreeReturn;
2546 /* if left is a literal then do it */
2547 if (IS_LITERAL (LTYPE (tree)))
2549 tree->type = EX_VALUE;
2550 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2552 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2556 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2559 /*------------------------------------------------------------------*/
2560 /*----------------------------*/
2562 /*----------------------------*/
2564 /* can be pointer */
2565 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2566 !IS_PTR (LTYPE (tree)) &&
2567 !IS_ARRAY (LTYPE (tree)))
2569 werror (E_UNARY_OP, tree->opval.op);
2570 goto errorTreeReturn;
2573 /* if left is a literal then do it */
2574 if (IS_LITERAL (LTYPE (tree)))
2576 tree->type = EX_VALUE;
2577 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2579 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2583 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2586 /*------------------------------------------------------------------*/
2587 /*----------------------------*/
2589 /*----------------------------*/
2592 TTYPE (tree) = LTYPE (tree);
2593 TETYPE (tree) = LETYPE (tree);
2597 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2602 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2604 werror (E_SHIFT_OP_INVALID);
2605 werror (W_CONTINUE, "left & right types are ");
2606 printTypeChain (LTYPE (tree), stderr);
2607 fprintf (stderr, ",");
2608 printTypeChain (RTYPE (tree), stderr);
2609 fprintf (stderr, "\n");
2610 goto errorTreeReturn;
2613 /* if they are both literal then */
2614 /* rewrite the tree */
2615 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2617 tree->type = EX_VALUE;
2618 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2619 valFromType (RETYPE (tree)),
2620 (tree->opval.op == LEFT_OP ? 1 : 0));
2621 tree->right = tree->left = NULL;
2622 TETYPE (tree) = getSpec (TTYPE (tree) =
2623 tree->opval.val->type);
2626 /* if only the right side is a literal & we are
2627 shifting more than size of the left operand then zero */
2628 if (IS_LITERAL (RTYPE (tree)) &&
2629 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2630 (getSize (LTYPE (tree)) * 8))
2632 werror (W_SHIFT_CHANGED,
2633 (tree->opval.op == LEFT_OP ? "left" : "right"));
2634 tree->type = EX_VALUE;
2635 tree->left = tree->right = NULL;
2636 tree->opval.val = constVal ("0");
2637 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2640 LRVAL (tree) = RRVAL (tree) = 1;
2641 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2643 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2647 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2651 /*------------------------------------------------------------------*/
2652 /*----------------------------*/
2654 /*----------------------------*/
2655 case CAST: /* change the type */
2656 /* cannot cast to an aggregate type */
2657 if (IS_AGGREGATE (LTYPE (tree)))
2659 werror (E_CAST_ILLEGAL);
2660 goto errorTreeReturn;
2663 /* make sure the type is complete and sane */
2664 checkTypeSanity(LETYPE(tree), "(cast)");
2667 /* if the right is a literal replace the tree */
2668 if (IS_LITERAL (RETYPE (tree))) {
2669 if (!IS_PTR (LTYPE (tree))) {
2670 tree->type = EX_VALUE;
2672 valCastLiteral (LTYPE (tree),
2673 floatFromVal (valFromType (RETYPE (tree))));
2676 TTYPE (tree) = tree->opval.val->type;
2677 tree->values.literalFromCast = 1;
2678 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2679 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2680 sym_link *rest = LTYPE(tree)->next;
2681 werror(W_LITERAL_GENERIC);
2682 TTYPE(tree) = newLink();
2683 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2684 TTYPE(tree)->next = rest;
2685 tree->left->opval.lnk = TTYPE(tree);
2688 TTYPE (tree) = LTYPE (tree);
2692 TTYPE (tree) = LTYPE (tree);
2696 /* if pointer to struct then check names */
2697 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2698 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2699 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2700 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2702 /* if the right is a literal replace the tree */
2703 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2704 tree->type = EX_VALUE;
2706 valCastLiteral (LTYPE (tree),
2707 floatFromVal (valFromType (RETYPE (tree))));
2710 TTYPE (tree) = tree->opval.val->type;
2711 tree->values.literalFromCast = 1;
2713 TTYPE (tree) = LTYPE (tree);
2717 TETYPE (tree) = getSpec (TTYPE (tree));
2721 /*------------------------------------------------------------------*/
2722 /*----------------------------*/
2723 /* logical &&, || */
2724 /*----------------------------*/
2727 /* each must me arithmetic type or be a pointer */
2728 if (!IS_PTR (LTYPE (tree)) &&
2729 !IS_ARRAY (LTYPE (tree)) &&
2730 !IS_INTEGRAL (LTYPE (tree)))
2732 werror (E_COMPARE_OP);
2733 goto errorTreeReturn;
2736 if (!IS_PTR (RTYPE (tree)) &&
2737 !IS_ARRAY (RTYPE (tree)) &&
2738 !IS_INTEGRAL (RTYPE (tree)))
2740 werror (E_COMPARE_OP);
2741 goto errorTreeReturn;
2743 /* if they are both literal then */
2744 /* rewrite the tree */
2745 if (IS_LITERAL (RTYPE (tree)) &&
2746 IS_LITERAL (LTYPE (tree)))
2748 tree->type = EX_VALUE;
2749 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2750 valFromType (RETYPE (tree)),
2752 tree->right = tree->left = NULL;
2753 TETYPE (tree) = getSpec (TTYPE (tree) =
2754 tree->opval.val->type);
2757 LRVAL (tree) = RRVAL (tree) = 1;
2758 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2761 /*------------------------------------------------------------------*/
2762 /*----------------------------*/
2763 /* comparison operators */
2764 /*----------------------------*/
2772 ast *lt = optimizeCompare (tree);
2778 /* if they are pointers they must be castable */
2779 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2781 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2783 werror (E_COMPARE_OP);
2784 fprintf (stderr, "comparing type ");
2785 printTypeChain (LTYPE (tree), stderr);
2786 fprintf (stderr, "to type ");
2787 printTypeChain (RTYPE (tree), stderr);
2788 fprintf (stderr, "\n");
2789 goto errorTreeReturn;
2792 /* else they should be promotable to one another */
2795 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2796 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2798 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2800 werror (E_COMPARE_OP);
2801 fprintf (stderr, "comparing type ");
2802 printTypeChain (LTYPE (tree), stderr);
2803 fprintf (stderr, "to type ");
2804 printTypeChain (RTYPE (tree), stderr);
2805 fprintf (stderr, "\n");
2806 goto errorTreeReturn;
2810 /* if they are both literal then */
2811 /* rewrite the tree */
2812 if (IS_LITERAL (RTYPE (tree)) &&
2813 IS_LITERAL (LTYPE (tree)))
2815 tree->type = EX_VALUE;
2816 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2817 valFromType (RETYPE (tree)),
2819 tree->right = tree->left = NULL;
2820 TETYPE (tree) = getSpec (TTYPE (tree) =
2821 tree->opval.val->type);
2824 LRVAL (tree) = RRVAL (tree) = 1;
2825 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2828 /*------------------------------------------------------------------*/
2829 /*----------------------------*/
2831 /*----------------------------*/
2832 case SIZEOF: /* evaluate wihout code generation */
2833 /* change the type to a integer */
2834 tree->type = EX_VALUE;
2835 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2836 tree->opval.val = constVal (buffer);
2837 tree->right = tree->left = NULL;
2838 TETYPE (tree) = getSpec (TTYPE (tree) =
2839 tree->opval.val->type);
2842 /*------------------------------------------------------------------*/
2843 /*----------------------------*/
2844 /* conditional operator '?' */
2845 /*----------------------------*/
2847 /* the type is value of the colon operator (on the right) */
2848 assert(IS_COLON_OP(tree->right));
2849 /* if already known then replace the tree : optimizer will do it
2850 but faster to do it here */
2851 if (IS_LITERAL (LTYPE(tree))) {
2852 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2853 return tree->right->left ;
2855 return tree->right->right ;
2858 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2859 TETYPE (tree) = getSpec (TTYPE (tree));
2864 /* if they don't match we have a problem */
2865 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2867 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2868 goto errorTreeReturn;
2871 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2872 TETYPE (tree) = getSpec (TTYPE (tree));
2876 /*------------------------------------------------------------------*/
2877 /*----------------------------*/
2878 /* assignment operators */
2879 /*----------------------------*/
2882 /* for these it must be both must be integral */
2883 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2884 !IS_ARITHMETIC (RTYPE (tree)))
2886 werror (E_OPS_INTEGRAL);
2887 goto errorTreeReturn;
2890 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2892 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2893 werror (E_CODE_WRITE, " ");
2897 werror (E_LVALUE_REQUIRED, "*= or /=");
2898 goto errorTreeReturn;
2909 /* for these it must be both must be integral */
2910 if (!IS_INTEGRAL (LTYPE (tree)) ||
2911 !IS_INTEGRAL (RTYPE (tree)))
2913 werror (E_OPS_INTEGRAL);
2914 goto errorTreeReturn;
2917 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2919 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2920 werror (E_CODE_WRITE, " ");
2924 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2925 goto errorTreeReturn;
2931 /*------------------------------------------------------------------*/
2932 /*----------------------------*/
2934 /*----------------------------*/
2936 if (!(IS_PTR (LTYPE (tree)) ||
2937 IS_ARITHMETIC (LTYPE (tree))))
2939 werror (E_PLUS_INVALID, "-=");
2940 goto errorTreeReturn;
2943 if (!(IS_PTR (RTYPE (tree)) ||
2944 IS_ARITHMETIC (RTYPE (tree))))
2946 werror (E_PLUS_INVALID, "-=");
2947 goto errorTreeReturn;
2950 TETYPE (tree) = getSpec (TTYPE (tree) =
2951 computeType (LTYPE (tree),
2954 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2955 werror (E_CODE_WRITE, " ");
2959 werror (E_LVALUE_REQUIRED, "-=");
2960 goto errorTreeReturn;
2966 /*------------------------------------------------------------------*/
2967 /*----------------------------*/
2969 /*----------------------------*/
2971 /* this is not a unary operation */
2972 /* if both pointers then problem */
2973 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2975 werror (E_PTR_PLUS_PTR);
2976 goto errorTreeReturn;
2979 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2981 werror (E_PLUS_INVALID, "+=");
2982 goto errorTreeReturn;
2985 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2987 werror (E_PLUS_INVALID, "+=");
2988 goto errorTreeReturn;
2991 TETYPE (tree) = getSpec (TTYPE (tree) =
2992 computeType (LTYPE (tree),
2995 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2996 werror (E_CODE_WRITE, " ");
3000 werror (E_LVALUE_REQUIRED, "+=");
3001 goto errorTreeReturn;
3004 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3005 tree->opval.op = '=';
3009 /*------------------------------------------------------------------*/
3010 /*----------------------------*/
3011 /* straight assignemnt */
3012 /*----------------------------*/
3014 /* cannot be an aggregate */
3015 if (IS_AGGREGATE (LTYPE (tree)))
3017 werror (E_AGGR_ASSIGN);
3018 goto errorTreeReturn;
3021 /* they should either match or be castable */
3022 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3024 werror (E_TYPE_MISMATCH, "assignment", " ");
3025 fprintf (stderr, "type --> '");
3026 printTypeChain (RTYPE (tree), stderr);
3027 fprintf (stderr, "' ");
3028 fprintf (stderr, "assigned to type --> '");
3029 printTypeChain (LTYPE (tree), stderr);
3030 fprintf (stderr, "'\n");
3031 goto errorTreeReturn;
3034 /* if the left side of the tree is of type void
3035 then report error */
3036 if (IS_VOID (LTYPE (tree)))
3038 werror (E_CAST_ZERO);
3039 printFromToType(RTYPE(tree), LTYPE(tree));
3042 TETYPE (tree) = getSpec (TTYPE (tree) =
3046 if (!tree->initMode ) {
3047 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3048 werror (E_CODE_WRITE, " ");
3052 werror (E_LVALUE_REQUIRED, "=");
3053 goto errorTreeReturn;
3058 /*------------------------------------------------------------------*/
3059 /*----------------------------*/
3060 /* comma operator */
3061 /*----------------------------*/
3063 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3066 /*------------------------------------------------------------------*/
3067 /*----------------------------*/
3069 /*----------------------------*/
3073 if (processParms (tree->left,
3074 FUNC_ARGS(tree->left->ftype),
3075 tree->right, &parmNumber, TRUE)) {
3076 goto errorTreeReturn;
3079 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3081 //FUNC_ARGS(tree->left->ftype) =
3082 //reverseVal (FUNC_ARGS(tree->left->ftype));
3083 reverseParms (tree->right);
3086 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3089 /*------------------------------------------------------------------*/
3090 /*----------------------------*/
3091 /* return statement */
3092 /*----------------------------*/
3097 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3099 werror (W_RETURN_MISMATCH);
3100 printFromToType (RTYPE(tree), currFunc->type->next);
3101 goto errorTreeReturn;
3104 if (IS_VOID (currFunc->type->next)
3106 !IS_VOID (RTYPE (tree)))
3108 werror (E_FUNC_VOID);
3109 goto errorTreeReturn;
3112 /* if there is going to be a casing required then add it */
3113 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3116 decorateType (newNode (CAST,
3117 newAst_LINK (copyLinkChain (currFunc->type->next)),
3126 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3128 werror (E_VOID_FUNC, currFunc->name);
3129 goto errorTreeReturn;
3132 TTYPE (tree) = TETYPE (tree) = NULL;
3135 /*------------------------------------------------------------------*/
3136 /*----------------------------*/
3137 /* switch statement */
3138 /*----------------------------*/
3140 /* the switch value must be an integer */
3141 if (!IS_INTEGRAL (LTYPE (tree)))
3143 werror (E_SWITCH_NON_INTEGER);
3144 goto errorTreeReturn;
3147 TTYPE (tree) = TETYPE (tree) = NULL;
3150 /*------------------------------------------------------------------*/
3151 /*----------------------------*/
3153 /*----------------------------*/
3155 tree->left = backPatchLabels (tree->left,
3158 TTYPE (tree) = TETYPE (tree) = NULL;
3161 /*------------------------------------------------------------------*/
3162 /*----------------------------*/
3164 /*----------------------------*/
3167 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3168 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3169 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3171 /* if the for loop is reversible then
3172 reverse it otherwise do what we normally
3178 if (isLoopReversible (tree, &sym, &init, &end))
3179 return reverseLoop (tree, sym, init, end);
3181 return decorateType (createFor (AST_FOR (tree, trueLabel),
3182 AST_FOR (tree, continueLabel),
3183 AST_FOR (tree, falseLabel),
3184 AST_FOR (tree, condLabel),
3185 AST_FOR (tree, initExpr),
3186 AST_FOR (tree, condExpr),
3187 AST_FOR (tree, loopExpr),
3191 TTYPE (tree) = TETYPE (tree) = NULL;
3195 /* some error found this tree will be killed */
3197 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3198 tree->opval.op = NULLOP;
3204 /*-----------------------------------------------------------------*/
3205 /* sizeofOp - processes size of operation */
3206 /*-----------------------------------------------------------------*/
3208 sizeofOp (sym_link * type)
3212 /* make sure the type is complete and sane */
3213 checkTypeSanity(type, "(sizeof)");
3215 /* get the size and convert it to character */
3216 sprintf (buff, "%d", getSize (type));
3218 /* now convert into value */
3219 return constVal (buff);
3223 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3224 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3225 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3226 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3227 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3228 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3229 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3231 /*-----------------------------------------------------------------*/
3232 /* backPatchLabels - change and or not operators to flow control */
3233 /*-----------------------------------------------------------------*/
3235 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3241 if (!(IS_ANDORNOT (tree)))
3244 /* if this an and */
3247 static int localLbl = 0;
3250 sprintf (buffer, "_and_%d", localLbl++);
3251 localLabel = newSymbol (buffer, NestLevel);
3253 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3255 /* if left is already a IFX then just change the if true label in that */
3256 if (!IS_IFX (tree->left))
3257 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3259 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3260 /* right is a IFX then just join */
3261 if (IS_IFX (tree->right))
3262 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3264 tree->right = createLabel (localLabel, tree->right);
3265 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3267 return newNode (NULLOP, tree->left, tree->right);
3270 /* if this is an or operation */
3273 static int localLbl = 0;
3276 sprintf (buffer, "_or_%d", localLbl++);
3277 localLabel = newSymbol (buffer, NestLevel);
3279 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3281 /* if left is already a IFX then just change the if true label in that */
3282 if (!IS_IFX (tree->left))
3283 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3285 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3286 /* right is a IFX then just join */
3287 if (IS_IFX (tree->right))
3288 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3290 tree->right = createLabel (localLabel, tree->right);
3291 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3293 return newNode (NULLOP, tree->left, tree->right);
3299 int wasnot = IS_NOT (tree->left);
3300 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3302 /* if the left is already a IFX */
3303 if (!IS_IFX (tree->left))
3304 tree->left = newNode (IFX, tree->left, NULL);
3308 tree->left->trueLabel = trueLabel;
3309 tree->left->falseLabel = falseLabel;
3313 tree->left->trueLabel = falseLabel;
3314 tree->left->falseLabel = trueLabel;
3321 tree->trueLabel = trueLabel;
3322 tree->falseLabel = falseLabel;
3329 /*-----------------------------------------------------------------*/
3330 /* createBlock - create expression tree for block */
3331 /*-----------------------------------------------------------------*/
3333 createBlock (symbol * decl, ast * body)
3337 /* if the block has nothing */
3341 ex = newNode (BLOCK, NULL, body);
3342 ex->values.sym = decl;
3344 ex->right = ex->right;
3350 /*-----------------------------------------------------------------*/
3351 /* createLabel - creates the expression tree for labels */
3352 /*-----------------------------------------------------------------*/
3354 createLabel (symbol * label, ast * stmnt)
3357 char name[SDCC_NAME_MAX + 1];
3360 /* must create fresh symbol if the symbol name */
3361 /* exists in the symbol table, since there can */
3362 /* be a variable with the same name as the labl */
3363 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3364 (csym->level == label->level))
3365 label = newSymbol (label->name, label->level);
3367 /* change the name before putting it in add _ */
3368 sprintf (name, "%s", label->name);
3370 /* put the label in the LabelSymbol table */
3371 /* but first check if a label of the same */
3373 if ((csym = findSym (LabelTab, NULL, name)))
3374 werror (E_DUPLICATE_LABEL, label->name);
3376 addSym (LabelTab, label, name, label->level, 0, 0);
3379 label->key = labelKey++;
3380 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3386 /*-----------------------------------------------------------------*/
3387 /* createCase - generates the parsetree for a case statement */
3388 /*-----------------------------------------------------------------*/
3390 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3392 char caseLbl[SDCC_NAME_MAX + 1];
3396 /* if the switch statement does not exist */
3397 /* then case is out of context */
3400 werror (E_CASE_CONTEXT);
3404 caseVal = decorateType (resolveSymbols (caseVal));
3405 /* if not a constant then error */
3406 if (!IS_LITERAL (caseVal->ftype))
3408 werror (E_CASE_CONSTANT);
3412 /* if not a integer than error */
3413 if (!IS_INTEGRAL (caseVal->ftype))
3415 werror (E_CASE_NON_INTEGER);
3419 /* find the end of the switch values chain */
3420 if (!(val = swStat->values.switchVals.swVals))
3421 swStat->values.switchVals.swVals = caseVal->opval.val;
3424 /* also order the cases according to value */
3426 int cVal = (int) floatFromVal (caseVal->opval.val);
3427 while (val && (int) floatFromVal (val) < cVal)
3433 /* if we reached the end then */
3436 pval->next = caseVal->opval.val;
3440 /* we found a value greater than */
3441 /* the current value we must add this */
3442 /* before the value */
3443 caseVal->opval.val->next = val;
3445 /* if this was the first in chain */
3446 if (swStat->values.switchVals.swVals == val)
3447 swStat->values.switchVals.swVals =
3450 pval->next = caseVal->opval.val;
3455 /* create the case label */
3456 sprintf (caseLbl, "_case_%d_%d",
3457 swStat->values.switchVals.swNum,
3458 (int) floatFromVal (caseVal->opval.val));
3460 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3465 /*-----------------------------------------------------------------*/
3466 /* createDefault - creates the parse tree for the default statement */
3467 /*-----------------------------------------------------------------*/
3469 createDefault (ast * swStat, ast * stmnt)
3471 char defLbl[SDCC_NAME_MAX + 1];
3473 /* if the switch statement does not exist */
3474 /* then case is out of context */
3477 werror (E_CASE_CONTEXT);
3481 /* turn on the default flag */
3482 swStat->values.switchVals.swDefault = 1;
3484 /* create the label */
3485 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3486 return createLabel (newSymbol (defLbl, 0), stmnt);
3489 /*-----------------------------------------------------------------*/
3490 /* createIf - creates the parsetree for the if statement */
3491 /*-----------------------------------------------------------------*/
3493 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3495 static int Lblnum = 0;
3497 symbol *ifTrue, *ifFalse, *ifEnd;
3499 /* if neither exists */
3500 if (!elseBody && !ifBody) {
3501 // if there are no side effects (i++, j() etc)
3502 if (!hasSEFcalls(condAst)) {
3507 /* create the labels */
3508 sprintf (buffer, "_iffalse_%d", Lblnum);
3509 ifFalse = newSymbol (buffer, NestLevel);
3510 /* if no else body then end == false */
3515 sprintf (buffer, "_ifend_%d", Lblnum);
3516 ifEnd = newSymbol (buffer, NestLevel);
3519 sprintf (buffer, "_iftrue_%d", Lblnum);
3520 ifTrue = newSymbol (buffer, NestLevel);
3524 /* attach the ifTrue label to the top of it body */
3525 ifBody = createLabel (ifTrue, ifBody);
3526 /* attach a goto end to the ifBody if else is present */
3529 ifBody = newNode (NULLOP, ifBody,
3531 newAst_VALUE (symbolVal (ifEnd)),
3533 /* put the elseLabel on the else body */
3534 elseBody = createLabel (ifFalse, elseBody);
3535 /* out the end at the end of the body */
3536 elseBody = newNode (NULLOP,
3538 createLabel (ifEnd, NULL));
3542 ifBody = newNode (NULLOP, ifBody,
3543 createLabel (ifFalse, NULL));
3545 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3546 if (IS_IFX (condAst))
3549 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3551 return newNode (NULLOP, ifTree,
3552 newNode (NULLOP, ifBody, elseBody));
3556 /*-----------------------------------------------------------------*/
3557 /* createDo - creates parse tree for do */
3560 /* _docontinue_n: */
3561 /* condition_expression +-> trueLabel -> _dobody_n */
3563 /* +-> falseLabel-> _dobreak_n */
3565 /*-----------------------------------------------------------------*/
3567 createDo (symbol * trueLabel, symbol * continueLabel,
3568 symbol * falseLabel, ast * condAst, ast * doBody)
3573 /* if the body does not exist then it is simple */
3576 condAst = backPatchLabels (condAst, continueLabel, NULL);
3577 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3578 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3579 doTree->trueLabel = continueLabel;
3580 doTree->falseLabel = NULL;
3584 /* otherwise we have a body */
3585 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3587 /* attach the body label to the top */
3588 doBody = createLabel (trueLabel, doBody);
3589 /* attach the continue label to end of body */
3590 doBody = newNode (NULLOP, doBody,
3591 createLabel (continueLabel, NULL));
3593 /* now put the break label at the end */
3594 if (IS_IFX (condAst))
3597 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3599 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3601 /* putting it together */
3602 return newNode (NULLOP, doBody, doTree);
3605 /*-----------------------------------------------------------------*/
3606 /* createFor - creates parse tree for 'for' statement */
3609 /* condExpr +-> trueLabel -> _forbody_n */
3611 /* +-> falseLabel-> _forbreak_n */
3614 /* _forcontinue_n: */
3616 /* goto _forcond_n ; */
3618 /*-----------------------------------------------------------------*/
3620 createFor (symbol * trueLabel, symbol * continueLabel,
3621 symbol * falseLabel, symbol * condLabel,
3622 ast * initExpr, ast * condExpr, ast * loopExpr,
3627 /* if loopexpression not present then we can generate it */
3628 /* the same way as a while */
3630 return newNode (NULLOP, initExpr,
3631 createWhile (trueLabel, continueLabel,
3632 falseLabel, condExpr, forBody));
3633 /* vanilla for statement */
3634 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3636 if (condExpr && !IS_IFX (condExpr))
3637 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3640 /* attach condition label to condition */
3641 condExpr = createLabel (condLabel, condExpr);
3643 /* attach body label to body */
3644 forBody = createLabel (trueLabel, forBody);
3646 /* attach continue to forLoop expression & attach */
3647 /* goto the forcond @ and of loopExpression */
3648 loopExpr = createLabel (continueLabel,
3652 newAst_VALUE (symbolVal (condLabel)),
3654 /* now start putting them together */
3655 forTree = newNode (NULLOP, initExpr, condExpr);
3656 forTree = newNode (NULLOP, forTree, forBody);
3657 forTree = newNode (NULLOP, forTree, loopExpr);
3658 /* finally add the break label */
3659 forTree = newNode (NULLOP, forTree,
3660 createLabel (falseLabel, NULL));
3664 /*-----------------------------------------------------------------*/
3665 /* createWhile - creates parse tree for while statement */
3666 /* the while statement will be created as follows */
3668 /* _while_continue_n: */
3669 /* condition_expression +-> trueLabel -> _while_boby_n */
3671 /* +-> falseLabel -> _while_break_n */
3672 /* _while_body_n: */
3674 /* goto _while_continue_n */
3675 /* _while_break_n: */
3676 /*-----------------------------------------------------------------*/
3678 createWhile (symbol * trueLabel, symbol * continueLabel,
3679 symbol * falseLabel, ast * condExpr, ast * whileBody)
3683 /* put the continue label */
3684 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3685 condExpr = createLabel (continueLabel, condExpr);
3686 condExpr->lineno = 0;
3688 /* put the body label in front of the body */
3689 whileBody = createLabel (trueLabel, whileBody);
3690 whileBody->lineno = 0;
3691 /* put a jump to continue at the end of the body */
3692 /* and put break label at the end of the body */
3693 whileBody = newNode (NULLOP,
3696 newAst_VALUE (symbolVal (continueLabel)),
3697 createLabel (falseLabel, NULL)));
3699 /* put it all together */
3700 if (IS_IFX (condExpr))
3701 whileTree = condExpr;
3704 whileTree = newNode (IFX, condExpr, NULL);
3705 /* put the true & false labels in place */
3706 whileTree->trueLabel = trueLabel;
3707 whileTree->falseLabel = falseLabel;
3710 return newNode (NULLOP, whileTree, whileBody);
3713 /*-----------------------------------------------------------------*/
3714 /* optimizeGetHbit - get highest order bit of the expression */
3715 /*-----------------------------------------------------------------*/
3717 optimizeGetHbit (ast * tree)
3720 /* if this is not a bit and */
3721 if (!IS_BITAND (tree))
3724 /* will look for tree of the form
3725 ( expr >> ((sizeof expr) -1) ) & 1 */
3726 if (!IS_AST_LIT_VALUE (tree->right))
3729 if (AST_LIT_VALUE (tree->right) != 1)
3732 if (!IS_RIGHT_OP (tree->left))
3735 if (!IS_AST_LIT_VALUE (tree->left->right))
3738 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3739 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3742 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3746 /*-----------------------------------------------------------------*/
3747 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3748 /*-----------------------------------------------------------------*/
3750 optimizeRRCRLC (ast * root)
3752 /* will look for trees of the form
3753 (?expr << 1) | (?expr >> 7) or
3754 (?expr >> 7) | (?expr << 1) will make that
3755 into a RLC : operation ..
3757 (?expr >> 1) | (?expr << 7) or
3758 (?expr << 7) | (?expr >> 1) will make that
3759 into a RRC operation
3760 note : by 7 I mean (number of bits required to hold the
3762 /* if the root operations is not a | operation the not */
3763 if (!IS_BITOR (root))
3766 /* I have to think of a better way to match patterns this sucks */
3767 /* that aside let start looking for the first case : I use a the
3768 negative check a lot to improve the efficiency */
3769 /* (?expr << 1) | (?expr >> 7) */
3770 if (IS_LEFT_OP (root->left) &&
3771 IS_RIGHT_OP (root->right))
3774 if (!SPEC_USIGN (TETYPE (root->left->left)))
3777 if (!IS_AST_LIT_VALUE (root->left->right) ||
3778 !IS_AST_LIT_VALUE (root->right->right))
3781 /* make sure it is the same expression */
3782 if (!isAstEqual (root->left->left,
3786 if (AST_LIT_VALUE (root->left->right) != 1)
3789 if (AST_LIT_VALUE (root->right->right) !=
3790 (getSize (TTYPE (root->left->left)) * 8 - 1))
3793 /* whew got the first case : create the AST */
3794 return newNode (RLC, root->left->left, NULL);
3798 /* check for second case */
3799 /* (?expr >> 7) | (?expr << 1) */
3800 if (IS_LEFT_OP (root->right) &&
3801 IS_RIGHT_OP (root->left))
3804 if (!SPEC_USIGN (TETYPE (root->left->left)))
3807 if (!IS_AST_LIT_VALUE (root->left->right) ||
3808 !IS_AST_LIT_VALUE (root->right->right))
3811 /* make sure it is the same symbol */
3812 if (!isAstEqual (root->left->left,
3816 if (AST_LIT_VALUE (root->right->right) != 1)
3819 if (AST_LIT_VALUE (root->left->right) !=
3820 (getSize (TTYPE (root->left->left)) * 8 - 1))
3823 /* whew got the first case : create the AST */
3824 return newNode (RLC, root->left->left, NULL);
3829 /* third case for RRC */
3830 /* (?symbol >> 1) | (?symbol << 7) */
3831 if (IS_LEFT_OP (root->right) &&
3832 IS_RIGHT_OP (root->left))
3835 if (!SPEC_USIGN (TETYPE (root->left->left)))
3838 if (!IS_AST_LIT_VALUE (root->left->right) ||
3839 !IS_AST_LIT_VALUE (root->right->right))
3842 /* make sure it is the same symbol */
3843 if (!isAstEqual (root->left->left,
3847 if (AST_LIT_VALUE (root->left->right) != 1)
3850 if (AST_LIT_VALUE (root->right->right) !=
3851 (getSize (TTYPE (root->left->left)) * 8 - 1))
3854 /* whew got the first case : create the AST */
3855 return newNode (RRC, root->left->left, NULL);
3859 /* fourth and last case for now */
3860 /* (?symbol << 7) | (?symbol >> 1) */
3861 if (IS_RIGHT_OP (root->right) &&
3862 IS_LEFT_OP (root->left))
3865 if (!SPEC_USIGN (TETYPE (root->left->left)))
3868 if (!IS_AST_LIT_VALUE (root->left->right) ||
3869 !IS_AST_LIT_VALUE (root->right->right))
3872 /* make sure it is the same symbol */
3873 if (!isAstEqual (root->left->left,
3877 if (AST_LIT_VALUE (root->right->right) != 1)
3880 if (AST_LIT_VALUE (root->left->right) !=
3881 (getSize (TTYPE (root->left->left)) * 8 - 1))
3884 /* whew got the first case : create the AST */
3885 return newNode (RRC, root->left->left, NULL);
3889 /* not found return root */
3893 /*-----------------------------------------------------------------*/
3894 /* optimizeCompare - otimizes compares for bit variables */
3895 /*-----------------------------------------------------------------*/
3897 optimizeCompare (ast * root)
3899 ast *optExpr = NULL;
3902 unsigned int litValue;
3904 /* if nothing then return nothing */
3908 /* if not a compare op then do leaves */
3909 if (!IS_COMPARE_OP (root))
3911 root->left = optimizeCompare (root->left);
3912 root->right = optimizeCompare (root->right);
3916 /* if left & right are the same then depending
3917 of the operation do */
3918 if (isAstEqual (root->left, root->right))
3920 switch (root->opval.op)
3925 optExpr = newAst_VALUE (constVal ("0"));
3930 optExpr = newAst_VALUE (constVal ("1"));
3934 return decorateType (optExpr);
3937 vleft = (root->left->type == EX_VALUE ?
3938 root->left->opval.val : NULL);
3940 vright = (root->right->type == EX_VALUE ?
3941 root->right->opval.val : NULL);
3943 /* if left is a BITVAR in BITSPACE */
3944 /* and right is a LITERAL then opt- */
3945 /* imize else do nothing */
3946 if (vleft && vright &&
3947 IS_BITVAR (vleft->etype) &&
3948 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3949 IS_LITERAL (vright->etype))
3952 /* if right side > 1 then comparison may never succeed */
3953 if ((litValue = (int) floatFromVal (vright)) > 1)
3955 werror (W_BAD_COMPARE);
3961 switch (root->opval.op)
3963 case '>': /* bit value greater than 1 cannot be */
3964 werror (W_BAD_COMPARE);
3968 case '<': /* bit value < 1 means 0 */
3970 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3973 case LE_OP: /* bit value <= 1 means no check */
3974 optExpr = newAst_VALUE (vright);
3977 case GE_OP: /* bit value >= 1 means only check for = */
3979 optExpr = newAst_VALUE (vleft);
3984 { /* literal is zero */
3985 switch (root->opval.op)
3987 case '<': /* bit value < 0 cannot be */
3988 werror (W_BAD_COMPARE);
3992 case '>': /* bit value > 0 means 1 */
3994 optExpr = newAst_VALUE (vleft);
3997 case LE_OP: /* bit value <= 0 means no check */
3998 case GE_OP: /* bit value >= 0 means no check */
3999 werror (W_BAD_COMPARE);
4003 case EQ_OP: /* bit == 0 means ! of bit */
4004 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4008 return decorateType (resolveSymbols (optExpr));
4009 } /* end-of-if of BITVAR */
4014 /*-----------------------------------------------------------------*/
4015 /* addSymToBlock : adds the symbol to the first block we find */
4016 /*-----------------------------------------------------------------*/
4018 addSymToBlock (symbol * sym, ast * tree)
4020 /* reached end of tree or a leaf */
4021 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4025 if (IS_AST_OP (tree) &&
4026 tree->opval.op == BLOCK)
4029 symbol *lsym = copySymbol (sym);
4031 lsym->next = AST_VALUES (tree, sym);
4032 AST_VALUES (tree, sym) = lsym;
4036 addSymToBlock (sym, tree->left);
4037 addSymToBlock (sym, tree->right);
4040 /*-----------------------------------------------------------------*/
4041 /* processRegParms - do processing for register parameters */
4042 /*-----------------------------------------------------------------*/
4044 processRegParms (value * args, ast * body)
4048 if (IS_REGPARM (args->etype))
4049 addSymToBlock (args->sym, body);
4054 /*-----------------------------------------------------------------*/
4055 /* resetParmKey - resets the operandkeys for the symbols */
4056 /*-----------------------------------------------------------------*/
4057 DEFSETFUNC (resetParmKey)
4068 /*-----------------------------------------------------------------*/
4069 /* createFunction - This is the key node that calls the iCode for */
4070 /* generating the code for a function. Note code */
4071 /* is generated function by function, later when */
4072 /* add inter-procedural analysis this will change */
4073 /*-----------------------------------------------------------------*/
4075 createFunction (symbol * name, ast * body)
4081 iCode *piCode = NULL;
4083 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4084 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4086 /* if check function return 0 then some problem */
4087 if (checkFunction (name, NULL) == 0)
4090 /* create a dummy block if none exists */
4092 body = newNode (BLOCK, NULL, NULL);
4096 /* check if the function name already in the symbol table */
4097 if ((csym = findSym (SymbolTab, NULL, name->name)))
4100 /* special case for compiler defined functions
4101 we need to add the name to the publics list : this
4102 actually means we are now compiling the compiler
4106 addSet (&publics, name);
4112 allocVariables (name);
4114 name->lastLine = yylineno;
4117 #if 0 // jwk: this is now done in addDecl()
4118 processFuncArgs (currFunc);
4121 /* set the stack pointer */
4122 /* PENDING: check this for the mcs51 */
4123 stackPtr = -port->stack.direction * port->stack.call_overhead;
4124 if (IFFUNC_ISISR (name->type))
4125 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4126 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4127 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4129 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4131 fetype = getSpec (name->type); /* get the specifier for the function */
4132 /* if this is a reentrant function then */
4133 if (IFFUNC_ISREENT (name->type))
4136 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4138 /* do processing for parameters that are passed in registers */
4139 processRegParms (FUNC_ARGS(name->type), body);
4141 /* set the stack pointer */
4145 /* allocate & autoinit the block variables */
4146 processBlockVars (body, &stack, ALLOCATE);
4148 /* save the stack information */
4149 if (options.useXstack)
4150 name->xstack = SPEC_STAK (fetype) = stack;
4152 name->stack = SPEC_STAK (fetype) = stack;
4154 /* name needs to be mangled */
4155 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4157 body = resolveSymbols (body); /* resolve the symbols */
4158 body = decorateType (body); /* propagateType & do semantic checks */
4160 ex = newAst_VALUE (symbolVal (name)); /* create name */
4161 ex = newNode (FUNCTION, ex, body);
4162 ex->values.args = FUNC_ARGS(name->type);
4164 if (options.dump_tree) PA(ex);
4167 werror (E_FUNC_NO_CODE, name->name);
4171 /* create the node & generate intermediate code */
4173 codeOutFile = code->oFile;
4174 piCode = iCodeFromAst (ex);
4178 werror (E_FUNC_NO_CODE, name->name);
4182 eBBlockFromiCode (piCode);
4184 /* if there are any statics then do them */
4187 GcurMemmap = statsg;
4188 codeOutFile = statsg->oFile;
4189 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4195 /* dealloc the block variables */
4196 processBlockVars (body, &stack, DEALLOCATE);
4197 /* deallocate paramaters */
4198 deallocParms (FUNC_ARGS(name->type));
4200 if (IFFUNC_ISREENT (name->type))
4203 /* we are done freeup memory & cleanup */
4207 FUNC_HASBODY(name->type) = 1;
4208 addSet (&operKeyReset, name);
4209 applyToSet (operKeyReset, resetParmKey);
4212 cdbStructBlock (1, cdbFile);
4214 cleanUpLevel (LabelTab, 0);
4215 cleanUpBlock (StructTab, 1);
4216 cleanUpBlock (TypedefTab, 1);
4218 xstack->syms = NULL;
4219 istack->syms = NULL;
4224 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4225 /*-----------------------------------------------------------------*/
4226 /* ast_print : prints the ast (for debugging purposes) */
4227 /*-----------------------------------------------------------------*/
4229 void ast_print (ast * tree, FILE *outfile, int indent)
4234 /* can print only decorated trees */
4235 if (!tree->decorated) return;
4237 /* if any child is an error | this one is an error do nothing */
4238 if (tree->isError ||
4239 (tree->left && tree->left->isError) ||
4240 (tree->right && tree->right->isError)) {
4241 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4245 /* print the line */
4246 /* if not block & function */
4247 if (tree->type == EX_OP &&
4248 (tree->opval.op != FUNCTION &&
4249 tree->opval.op != BLOCK &&
4250 tree->opval.op != NULLOP)) {
4253 if (tree->opval.op == FUNCTION) {
4255 value *args=FUNC_ARGS(tree->left->opval.val->type);
4256 fprintf(outfile,"FUNCTION (%s=%p) type (",
4257 tree->left->opval.val->name, tree);
4258 printTypeChain (tree->ftype,outfile);
4259 fprintf(outfile,") args (");
4262 fprintf (outfile, ", ");
4264 printTypeChain (args ? args->type : NULL, outfile);
4266 args= args ? args->next : NULL;
4268 fprintf(outfile,")\n");
4269 ast_print(tree->left,outfile,indent);
4270 ast_print(tree->right,outfile,indent);
4273 if (tree->opval.op == BLOCK) {
4274 symbol *decls = tree->values.sym;
4275 INDENT(indent,outfile);
4276 fprintf(outfile,"{\n");
4278 INDENT(indent+4,outfile);
4279 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4280 decls->name, decls);
4281 printTypeChain(decls->type,outfile);
4282 fprintf(outfile,")\n");
4284 decls = decls->next;
4286 ast_print(tree->right,outfile,indent+4);
4287 INDENT(indent,outfile);
4288 fprintf(outfile,"}\n");
4291 if (tree->opval.op == NULLOP) {
4292 fprintf(outfile,"\n");
4293 ast_print(tree->left,outfile,indent);
4294 fprintf(outfile,"\n");
4295 ast_print(tree->right,outfile,indent);
4298 INDENT(indent,outfile);
4300 /*------------------------------------------------------------------*/
4301 /*----------------------------*/
4302 /* leaf has been reached */
4303 /*----------------------------*/
4304 /* if this is of type value */
4305 /* just get the type */
4306 if (tree->type == EX_VALUE) {
4308 if (IS_LITERAL (tree->opval.val->etype)) {
4309 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4310 (int) floatFromVal(tree->opval.val),
4311 (int) floatFromVal(tree->opval.val),
4312 floatFromVal(tree->opval.val));
4313 } else if (tree->opval.val->sym) {
4314 /* if the undefined flag is set then give error message */
4315 if (tree->opval.val->sym->undefined) {
4316 fprintf(outfile,"UNDEFINED SYMBOL ");
4318 fprintf(outfile,"SYMBOL ");
4320 fprintf(outfile,"(%s=%p)",
4321 tree->opval.val->sym->name,tree);
4324 fprintf(outfile," type (");
4325 printTypeChain(tree->ftype,outfile);
4326 fprintf(outfile,")\n");
4328 fprintf(outfile,"\n");
4333 /* if type link for the case of cast */
4334 if (tree->type == EX_LINK) {
4335 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4336 printTypeChain(tree->opval.lnk,outfile);
4337 fprintf(outfile,")\n");
4342 /* depending on type of operator do */
4344 switch (tree->opval.op) {
4345 /*------------------------------------------------------------------*/
4346 /*----------------------------*/
4348 /*----------------------------*/
4350 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4351 printTypeChain(tree->ftype,outfile);
4352 fprintf(outfile,")\n");
4353 ast_print(tree->left,outfile,indent+4);
4354 ast_print(tree->right,outfile,indent+4);
4357 /*------------------------------------------------------------------*/
4358 /*----------------------------*/
4360 /*----------------------------*/
4362 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4363 printTypeChain(tree->ftype,outfile);
4364 fprintf(outfile,")\n");
4365 ast_print(tree->left,outfile,indent+4);
4366 ast_print(tree->right,outfile,indent+4);
4369 /*------------------------------------------------------------------*/
4370 /*----------------------------*/
4371 /* struct/union pointer */
4372 /*----------------------------*/
4374 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4375 printTypeChain(tree->ftype,outfile);
4376 fprintf(outfile,")\n");
4377 ast_print(tree->left,outfile,indent+4);
4378 ast_print(tree->right,outfile,indent+4);
4381 /*------------------------------------------------------------------*/
4382 /*----------------------------*/
4383 /* ++/-- operation */
4384 /*----------------------------*/
4385 case INC_OP: /* incerement operator unary so left only */
4386 fprintf(outfile,"INC_OP (%p) type (",tree);
4387 printTypeChain(tree->ftype,outfile);
4388 fprintf(outfile,")\n");
4389 ast_print(tree->left,outfile,indent+4);
4393 fprintf(outfile,"DEC_OP (%p) type (",tree);
4394 printTypeChain(tree->ftype,outfile);
4395 fprintf(outfile,")\n");
4396 ast_print(tree->left,outfile,indent+4);
4399 /*------------------------------------------------------------------*/
4400 /*----------------------------*/
4402 /*----------------------------*/
4405 fprintf(outfile,"& (%p) type (",tree);
4406 printTypeChain(tree->ftype,outfile);
4407 fprintf(outfile,")\n");
4408 ast_print(tree->left,outfile,indent+4);
4409 ast_print(tree->right,outfile,indent+4);
4411 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4412 printTypeChain(tree->ftype,outfile);
4413 fprintf(outfile,")\n");
4414 ast_print(tree->left,outfile,indent+4);
4415 ast_print(tree->right,outfile,indent+4);
4418 /*----------------------------*/
4420 /*----------------------------*/
4422 fprintf(outfile,"OR (%p) type (",tree);
4423 printTypeChain(tree->ftype,outfile);
4424 fprintf(outfile,")\n");
4425 ast_print(tree->left,outfile,indent+4);
4426 ast_print(tree->right,outfile,indent+4);
4428 /*------------------------------------------------------------------*/
4429 /*----------------------------*/
4431 /*----------------------------*/
4433 fprintf(outfile,"XOR (%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);
4440 /*------------------------------------------------------------------*/
4441 /*----------------------------*/
4443 /*----------------------------*/
4445 fprintf(outfile,"DIV (%p) type (",tree);
4446 printTypeChain(tree->ftype,outfile);
4447 fprintf(outfile,")\n");
4448 ast_print(tree->left,outfile,indent+4);
4449 ast_print(tree->right,outfile,indent+4);
4451 /*------------------------------------------------------------------*/
4452 /*----------------------------*/
4454 /*----------------------------*/
4456 fprintf(outfile,"MOD (%p) type (",tree);
4457 printTypeChain(tree->ftype,outfile);
4458 fprintf(outfile,")\n");
4459 ast_print(tree->left,outfile,indent+4);
4460 ast_print(tree->right,outfile,indent+4);
4463 /*------------------------------------------------------------------*/
4464 /*----------------------------*/
4465 /* address dereference */
4466 /*----------------------------*/
4467 case '*': /* can be unary : if right is null then unary operation */
4469 fprintf(outfile,"DEREF (%p) type (",tree);
4470 printTypeChain(tree->ftype,outfile);
4471 fprintf(outfile,")\n");
4472 ast_print(tree->left,outfile,indent+4);
4475 /*------------------------------------------------------------------*/
4476 /*----------------------------*/
4477 /* multiplication */
4478 /*----------------------------*/
4479 fprintf(outfile,"MULT (%p) type (",tree);
4480 printTypeChain(tree->ftype,outfile);
4481 fprintf(outfile,")\n");
4482 ast_print(tree->left,outfile,indent+4);
4483 ast_print(tree->right,outfile,indent+4);
4487 /*------------------------------------------------------------------*/
4488 /*----------------------------*/
4489 /* unary '+' operator */
4490 /*----------------------------*/
4494 fprintf(outfile,"UPLUS (%p) type (",tree);
4495 printTypeChain(tree->ftype,outfile);
4496 fprintf(outfile,")\n");
4497 ast_print(tree->left,outfile,indent+4);
4499 /*------------------------------------------------------------------*/
4500 /*----------------------------*/
4502 /*----------------------------*/
4503 fprintf(outfile,"ADD (%p) type (",tree);
4504 printTypeChain(tree->ftype,outfile);
4505 fprintf(outfile,")\n");
4506 ast_print(tree->left,outfile,indent+4);
4507 ast_print(tree->right,outfile,indent+4);
4510 /*------------------------------------------------------------------*/
4511 /*----------------------------*/
4513 /*----------------------------*/
4514 case '-': /* can be unary */
4516 fprintf(outfile,"UMINUS (%p) type (",tree);
4517 printTypeChain(tree->ftype,outfile);
4518 fprintf(outfile,")\n");
4519 ast_print(tree->left,outfile,indent+4);
4521 /*------------------------------------------------------------------*/
4522 /*----------------------------*/
4524 /*----------------------------*/
4525 fprintf(outfile,"SUB (%p) type (",tree);
4526 printTypeChain(tree->ftype,outfile);
4527 fprintf(outfile,")\n");
4528 ast_print(tree->left,outfile,indent+4);
4529 ast_print(tree->right,outfile,indent+4);
4532 /*------------------------------------------------------------------*/
4533 /*----------------------------*/
4535 /*----------------------------*/
4537 fprintf(outfile,"COMPL (%p) type (",tree);
4538 printTypeChain(tree->ftype,outfile);
4539 fprintf(outfile,")\n");
4540 ast_print(tree->left,outfile,indent+4);
4542 /*------------------------------------------------------------------*/
4543 /*----------------------------*/
4545 /*----------------------------*/
4547 fprintf(outfile,"NOT (%p) type (",tree);
4548 printTypeChain(tree->ftype,outfile);
4549 fprintf(outfile,")\n");
4550 ast_print(tree->left,outfile,indent+4);
4552 /*------------------------------------------------------------------*/
4553 /*----------------------------*/
4555 /*----------------------------*/
4557 fprintf(outfile,"RRC (%p) type (",tree);
4558 printTypeChain(tree->ftype,outfile);
4559 fprintf(outfile,")\n");
4560 ast_print(tree->left,outfile,indent+4);
4564 fprintf(outfile,"RLC (%p) type (",tree);
4565 printTypeChain(tree->ftype,outfile);
4566 fprintf(outfile,")\n");
4567 ast_print(tree->left,outfile,indent+4);
4570 fprintf(outfile,"GETHBIT (%p) type (",tree);
4571 printTypeChain(tree->ftype,outfile);
4572 fprintf(outfile,")\n");
4573 ast_print(tree->left,outfile,indent+4);
4576 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4577 printTypeChain(tree->ftype,outfile);
4578 fprintf(outfile,")\n");
4579 ast_print(tree->left,outfile,indent+4);
4580 ast_print(tree->right,outfile,indent+4);
4583 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4584 printTypeChain(tree->ftype,outfile);
4585 fprintf(outfile,")\n");
4586 ast_print(tree->left,outfile,indent+4);
4587 ast_print(tree->right,outfile,indent+4);
4589 /*------------------------------------------------------------------*/
4590 /*----------------------------*/
4592 /*----------------------------*/
4593 case CAST: /* change the type */
4594 fprintf(outfile,"CAST (%p) from type (",tree);
4595 printTypeChain(tree->right->ftype,outfile);
4596 fprintf(outfile,") to type (");
4597 printTypeChain(tree->ftype,outfile);
4598 fprintf(outfile,")\n");
4599 ast_print(tree->right,outfile,indent+4);
4603 fprintf(outfile,"ANDAND (%p) type (",tree);
4604 printTypeChain(tree->ftype,outfile);
4605 fprintf(outfile,")\n");
4606 ast_print(tree->left,outfile,indent+4);
4607 ast_print(tree->right,outfile,indent+4);
4610 fprintf(outfile,"OROR (%p) type (",tree);
4611 printTypeChain(tree->ftype,outfile);
4612 fprintf(outfile,")\n");
4613 ast_print(tree->left,outfile,indent+4);
4614 ast_print(tree->right,outfile,indent+4);
4617 /*------------------------------------------------------------------*/
4618 /*----------------------------*/
4619 /* comparison operators */
4620 /*----------------------------*/
4622 fprintf(outfile,"GT(>) (%p) type (",tree);
4623 printTypeChain(tree->ftype,outfile);
4624 fprintf(outfile,")\n");
4625 ast_print(tree->left,outfile,indent+4);
4626 ast_print(tree->right,outfile,indent+4);
4629 fprintf(outfile,"LT(<) (%p) type (",tree);
4630 printTypeChain(tree->ftype,outfile);
4631 fprintf(outfile,")\n");
4632 ast_print(tree->left,outfile,indent+4);
4633 ast_print(tree->right,outfile,indent+4);
4636 fprintf(outfile,"LE(<=) (%p) type (",tree);
4637 printTypeChain(tree->ftype,outfile);
4638 fprintf(outfile,")\n");
4639 ast_print(tree->left,outfile,indent+4);
4640 ast_print(tree->right,outfile,indent+4);
4643 fprintf(outfile,"GE(>=) (%p) type (",tree);
4644 printTypeChain(tree->ftype,outfile);
4645 fprintf(outfile,")\n");
4646 ast_print(tree->left,outfile,indent+4);
4647 ast_print(tree->right,outfile,indent+4);
4650 fprintf(outfile,"EQ(==) (%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,"NE(!=) (%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);
4662 /*------------------------------------------------------------------*/
4663 /*----------------------------*/
4665 /*----------------------------*/
4666 case SIZEOF: /* evaluate wihout code generation */
4667 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4670 /*------------------------------------------------------------------*/
4671 /*----------------------------*/
4672 /* conditional operator '?' */
4673 /*----------------------------*/
4675 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4676 printTypeChain(tree->ftype,outfile);
4677 fprintf(outfile,")\n");
4678 ast_print(tree->left,outfile,indent+4);
4679 ast_print(tree->right,outfile,indent+4);
4683 fprintf(outfile,"COLON(:) (%p) type (",tree);
4684 printTypeChain(tree->ftype,outfile);
4685 fprintf(outfile,")\n");
4686 ast_print(tree->left,outfile,indent+4);
4687 ast_print(tree->right,outfile,indent+4);
4690 /*------------------------------------------------------------------*/
4691 /*----------------------------*/
4692 /* assignment operators */
4693 /*----------------------------*/
4695 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4696 printTypeChain(tree->ftype,outfile);
4697 fprintf(outfile,")\n");
4698 ast_print(tree->left,outfile,indent+4);
4699 ast_print(tree->right,outfile,indent+4);
4702 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4703 printTypeChain(tree->ftype,outfile);
4704 fprintf(outfile,")\n");
4705 ast_print(tree->left,outfile,indent+4);
4706 ast_print(tree->right,outfile,indent+4);
4709 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4710 printTypeChain(tree->ftype,outfile);
4711 fprintf(outfile,")\n");
4712 ast_print(tree->left,outfile,indent+4);
4713 ast_print(tree->right,outfile,indent+4);
4716 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4717 printTypeChain(tree->ftype,outfile);
4718 fprintf(outfile,")\n");
4719 ast_print(tree->left,outfile,indent+4);
4720 ast_print(tree->right,outfile,indent+4);
4723 fprintf(outfile,"XORASS(*=) (%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,"RSHFTASS(>>=) (%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,"LSHFTASS(*=) (%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);
4743 /*------------------------------------------------------------------*/
4744 /*----------------------------*/
4746 /*----------------------------*/
4748 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4749 printTypeChain(tree->ftype,outfile);
4750 fprintf(outfile,")\n");
4751 ast_print(tree->left,outfile,indent+4);
4752 ast_print(tree->right,outfile,indent+4);
4754 /*------------------------------------------------------------------*/
4755 /*----------------------------*/
4757 /*----------------------------*/
4759 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4760 printTypeChain(tree->ftype,outfile);
4761 fprintf(outfile,")\n");
4762 ast_print(tree->left,outfile,indent+4);
4763 ast_print(tree->right,outfile,indent+4);
4765 /*------------------------------------------------------------------*/
4766 /*----------------------------*/
4767 /* straight assignemnt */
4768 /*----------------------------*/
4770 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4771 printTypeChain(tree->ftype,outfile);
4772 fprintf(outfile,")\n");
4773 ast_print(tree->left,outfile,indent+4);
4774 ast_print(tree->right,outfile,indent+4);
4776 /*------------------------------------------------------------------*/
4777 /*----------------------------*/
4778 /* comma operator */
4779 /*----------------------------*/
4781 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4782 printTypeChain(tree->ftype,outfile);
4783 fprintf(outfile,")\n");
4784 ast_print(tree->left,outfile,indent+4);
4785 ast_print(tree->right,outfile,indent+4);
4787 /*------------------------------------------------------------------*/
4788 /*----------------------------*/
4790 /*----------------------------*/
4793 fprintf(outfile,"CALL (%p) type (",tree);
4794 printTypeChain(tree->ftype,outfile);
4795 fprintf(outfile,")\n");
4796 ast_print(tree->left,outfile,indent+4);
4797 ast_print(tree->right,outfile,indent+4);
4800 fprintf(outfile,"PARMS\n");
4801 ast_print(tree->left,outfile,indent+4);
4802 if (tree->right && !IS_AST_PARAM(tree->right)) {
4803 ast_print(tree->right,outfile,indent+4);
4806 /*------------------------------------------------------------------*/
4807 /*----------------------------*/
4808 /* return statement */
4809 /*----------------------------*/
4811 fprintf(outfile,"RETURN (%p) type (",tree);
4812 printTypeChain(tree->right->ftype,outfile);
4813 fprintf(outfile,")\n");
4814 ast_print(tree->right,outfile,indent+4);
4816 /*------------------------------------------------------------------*/
4817 /*----------------------------*/
4818 /* label statement */
4819 /*----------------------------*/
4821 fprintf(outfile,"LABEL (%p)",tree);
4822 ast_print(tree->left,outfile,indent+4);
4823 ast_print(tree->right,outfile,indent);
4825 /*------------------------------------------------------------------*/
4826 /*----------------------------*/
4827 /* switch statement */
4828 /*----------------------------*/
4832 fprintf(outfile,"SWITCH (%p) ",tree);
4833 ast_print(tree->left,outfile,0);
4834 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4835 INDENT(indent+4,outfile);
4836 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4837 (int) floatFromVal(val),
4838 tree->values.switchVals.swNum,
4839 (int) floatFromVal(val));
4841 ast_print(tree->right,outfile,indent);
4844 /*------------------------------------------------------------------*/
4845 /*----------------------------*/
4847 /*----------------------------*/
4849 fprintf(outfile,"IF (%p) \n",tree);
4850 ast_print(tree->left,outfile,indent+4);
4851 if (tree->trueLabel) {
4852 INDENT(indent,outfile);
4853 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4855 if (tree->falseLabel) {
4856 INDENT(indent,outfile);
4857 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4859 ast_print(tree->right,outfile,indent+4);
4861 /*------------------------------------------------------------------*/
4862 /*----------------------------*/
4864 /*----------------------------*/
4866 fprintf(outfile,"FOR (%p) \n",tree);
4867 if (AST_FOR( tree, initExpr)) {
4868 INDENT(indent+4,outfile);
4869 fprintf(outfile,"INIT EXPR ");
4870 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4872 if (AST_FOR( tree, condExpr)) {
4873 INDENT(indent+4,outfile);
4874 fprintf(outfile,"COND EXPR ");
4875 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4877 if (AST_FOR( tree, loopExpr)) {
4878 INDENT(indent+4,outfile);
4879 fprintf(outfile,"LOOP EXPR ");
4880 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4882 fprintf(outfile,"FOR LOOP BODY \n");
4883 ast_print(tree->left,outfile,indent+4);
4892 ast_print(t,stdout,0);