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;
765 /* make a copy and change the regparm type to the defined parm */
766 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
767 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
771 /*-----------------------------------------------------------------*/
772 /* createIvalType - generates ival for basic types */
773 /*-----------------------------------------------------------------*/
775 createIvalType (ast * sym, sym_link * type, initList * ilist)
779 /* if initList is deep */
780 if (ilist->type == INIT_DEEP)
781 ilist = ilist->init.deep;
783 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
784 return decorateType (newNode ('=', sym, iExpr));
787 /*-----------------------------------------------------------------*/
788 /* createIvalStruct - generates initial value for structures */
789 /*-----------------------------------------------------------------*/
791 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
798 sflds = SPEC_STRUCT (type)->fields;
799 if (ilist->type != INIT_DEEP)
801 werror (E_INIT_STRUCT, "");
805 iloop = ilist->init.deep;
807 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
809 /* if we have come to end */
813 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
814 lAst = decorateType (resolveSymbols (lAst));
815 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
821 /*-----------------------------------------------------------------*/
822 /* createIvalArray - generates code for array initialization */
823 /*-----------------------------------------------------------------*/
825 createIvalArray (ast * sym, sym_link * type, initList * ilist)
829 int lcnt = 0, size = 0;
830 literalList *literalL;
832 /* take care of the special case */
833 /* array of characters can be init */
835 if (IS_CHAR (type->next))
836 if ((rast = createIvalCharPtr (sym,
838 decorateType (resolveSymbols (list2expr (ilist))))))
840 return decorateType (resolveSymbols (rast));
842 /* not the special case */
843 if (ilist->type != INIT_DEEP)
845 werror (E_INIT_STRUCT, "");
849 iloop = ilist->init.deep;
850 lcnt = DCL_ELEM (type);
852 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
856 aSym = decorateType (resolveSymbols(sym));
858 rast = newNode(ARRAYINIT, aSym, NULL);
859 rast->values.constlist = literalL;
861 // Make sure size is set to length of initializer list.
868 if (lcnt && size > lcnt)
870 // Array size was specified, and we have more initializers than needed.
871 char *name=sym->opval.val->sym->name;
872 int lineno=sym->opval.val->sym->lineDef;
874 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
883 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
884 aSym = decorateType (resolveSymbols (aSym));
885 rast = createIval (aSym, type->next, iloop, rast);
886 iloop = (iloop ? iloop->next : NULL);
892 /* no of elements given and we */
893 /* have generated for all of them */
896 // there has to be a better way
897 char *name=sym->opval.val->sym->name;
898 int lineno=sym->opval.val->sym->lineDef;
899 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
906 /* if we have not been given a size */
907 if (!DCL_ELEM (type))
909 DCL_ELEM (type) = size;
912 return decorateType (resolveSymbols (rast));
916 /*-----------------------------------------------------------------*/
917 /* createIvalCharPtr - generates initial values for char pointers */
918 /*-----------------------------------------------------------------*/
920 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
924 /* if this is a pointer & right is a literal array then */
925 /* just assignment will do */
926 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
927 SPEC_SCLS (iexpr->etype) == S_CODE)
928 && IS_ARRAY (iexpr->ftype)))
929 return newNode ('=', sym, iexpr);
931 /* left side is an array so we have to assign each */
933 if ((IS_LITERAL (iexpr->etype) ||
934 SPEC_SCLS (iexpr->etype) == S_CODE)
935 && IS_ARRAY (iexpr->ftype))
937 /* for each character generate an assignment */
938 /* to the array element */
939 char *s = SPEC_CVAL (iexpr->etype).v_char;
944 rast = newNode (NULLOP,
948 newAst_VALUE (valueFromLit ((float) i))),
949 newAst_VALUE (valueFromLit (*s))));
953 rast = newNode (NULLOP,
957 newAst_VALUE (valueFromLit ((float) i))),
958 newAst_VALUE (valueFromLit (*s))));
959 return decorateType (resolveSymbols (rast));
965 /*-----------------------------------------------------------------*/
966 /* createIvalPtr - generates initial value for pointers */
967 /*-----------------------------------------------------------------*/
969 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
975 if (ilist->type == INIT_DEEP)
976 ilist = ilist->init.deep;
978 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
980 /* if character pointer */
981 if (IS_CHAR (type->next))
982 if ((rast = createIvalCharPtr (sym, type, iexpr)))
985 return newNode ('=', sym, iexpr);
988 /*-----------------------------------------------------------------*/
989 /* createIval - generates code for initial value */
990 /*-----------------------------------------------------------------*/
992 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
999 /* if structure then */
1000 if (IS_STRUCT (type))
1001 rast = createIvalStruct (sym, type, ilist);
1003 /* if this is a pointer */
1005 rast = createIvalPtr (sym, type, ilist);
1007 /* if this is an array */
1008 if (IS_ARRAY (type))
1009 rast = createIvalArray (sym, type, ilist);
1011 /* if type is SPECIFIER */
1013 rast = createIvalType (sym, type, ilist);
1016 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1018 return decorateType (resolveSymbols (rast));
1021 /*-----------------------------------------------------------------*/
1022 /* initAggregates - initialises aggregate variables with initv */
1023 /*-----------------------------------------------------------------*/
1025 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1027 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1031 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1033 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1034 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1035 "with -mmcs51 and --model-large\n");
1039 if (SPEC_OCLS(sym->etype)==xdata &&
1040 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1043 newSym=copySymbol (sym);
1044 SPEC_OCLS(newSym->etype)=code;
1045 sprintf (newSym->name, "%s_init__", sym->name);
1046 sprintf (newSym->rname,"%s_init__", sym->rname);
1047 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1049 // emit it in the static segment
1050 addSet(&statsg->syms, newSym);
1052 // now memcpy() the entire array from cseg
1053 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1054 newAst_VALUE (symbolVal (sym)),
1055 newAst_VALUE (symbolVal (newSym)));
1056 return decorateType(resolveSymbols(ast));
1060 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1063 /*-----------------------------------------------------------------*/
1064 /* gatherAutoInit - creates assignment expressions for initial */
1066 /*-----------------------------------------------------------------*/
1068 gatherAutoInit (symbol * autoChain)
1075 for (sym = autoChain; sym; sym = sym->next)
1078 /* resolve the symbols in the ival */
1080 resolveIvalSym (sym->ival);
1082 /* if this is a static variable & has an */
1083 /* initial value the code needs to be lifted */
1084 /* here to the main portion since they can be */
1085 /* initialised only once at the start */
1086 if (IS_STATIC (sym->etype) && sym->ival &&
1087 SPEC_SCLS (sym->etype) != S_CODE)
1091 // this can only be a constant
1092 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1093 werror (E_CONST_EXPECTED);
1096 /* insert the symbol into the symbol table */
1097 /* with level = 0 & name = rname */
1098 newSym = copySymbol (sym);
1099 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1101 /* now lift the code to main */
1102 if (IS_AGGREGATE (sym->type))
1103 work = initAggregates (sym, sym->ival, NULL);
1105 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1106 list2expr (sym->ival));
1108 setAstLineno (work, sym->lineDef);
1112 staticAutos = newNode (NULLOP, staticAutos, work);
1119 /* if there is an initial value */
1120 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1122 if (IS_AGGREGATE (sym->type))
1123 work = initAggregates (sym, sym->ival, NULL);
1125 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1126 list2expr (sym->ival));
1128 setAstLineno (work, sym->lineDef);
1131 init = newNode (NULLOP, init, work);
1140 /*-----------------------------------------------------------------*/
1141 /* stringToSymbol - creates a symbol from a literal string */
1142 /*-----------------------------------------------------------------*/
1144 stringToSymbol (value * val)
1146 char name[SDCC_NAME_MAX + 1];
1147 static int charLbl = 0;
1150 sprintf (name, "_str_%d", charLbl++);
1151 sym = newSymbol (name, 0); /* make it @ level 0 */
1152 strcpy (sym->rname, name);
1154 /* copy the type from the value passed */
1155 sym->type = copyLinkChain (val->type);
1156 sym->etype = getSpec (sym->type);
1157 /* change to storage class & output class */
1158 SPEC_SCLS (sym->etype) = S_CODE;
1159 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1160 SPEC_STAT (sym->etype) = 1;
1161 /* make the level & block = 0 */
1162 sym->block = sym->level = 0;
1164 /* create an ival */
1165 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1170 allocVariables (sym);
1173 return symbolVal (sym);
1177 /*-----------------------------------------------------------------*/
1178 /* processBlockVars - will go thru the ast looking for block if */
1179 /* a block is found then will allocate the syms */
1180 /* will also gather the auto inits present */
1181 /*-----------------------------------------------------------------*/
1183 processBlockVars (ast * tree, int *stack, int action)
1188 /* if this is a block */
1189 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1193 if (action == ALLOCATE)
1195 *stack += allocVariables (tree->values.sym);
1196 autoInit = gatherAutoInit (tree->values.sym);
1198 /* if there are auto inits then do them */
1200 tree->left = newNode (NULLOP, autoInit, tree->left);
1202 else /* action is deallocate */
1203 deallocLocal (tree->values.sym);
1206 processBlockVars (tree->left, stack, action);
1207 processBlockVars (tree->right, stack, action);
1211 /*-----------------------------------------------------------------*/
1212 /* constExprValue - returns the value of a constant expression */
1213 /* or NULL if it is not a constant expression */
1214 /*-----------------------------------------------------------------*/
1216 constExprValue (ast * cexpr, int check)
1218 cexpr = decorateType (resolveSymbols (cexpr));
1220 /* if this is not a constant then */
1221 if (!IS_LITERAL (cexpr->ftype))
1223 /* then check if this is a literal array
1225 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1226 SPEC_CVAL (cexpr->etype).v_char &&
1227 IS_ARRAY (cexpr->ftype))
1229 value *val = valFromType (cexpr->ftype);
1230 SPEC_SCLS (val->etype) = S_LITERAL;
1231 val->sym = cexpr->opval.val->sym;
1232 val->sym->type = copyLinkChain (cexpr->ftype);
1233 val->sym->etype = getSpec (val->sym->type);
1234 strcpy (val->name, cexpr->opval.val->sym->rname);
1238 /* if we are casting a literal value then */
1239 if (IS_AST_OP (cexpr) &&
1240 cexpr->opval.op == CAST &&
1241 IS_LITERAL (cexpr->left->ftype))
1242 return valCastLiteral (cexpr->ftype,
1243 floatFromVal (cexpr->left->opval.val));
1245 if (IS_AST_VALUE (cexpr))
1246 return cexpr->opval.val;
1249 werror (E_CONST_EXPECTED, "found expression");
1254 /* return the value */
1255 return cexpr->opval.val;
1259 /*-----------------------------------------------------------------*/
1260 /* isLabelInAst - will return true if a given label is found */
1261 /*-----------------------------------------------------------------*/
1263 isLabelInAst (symbol * label, ast * tree)
1265 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1268 if (IS_AST_OP (tree) &&
1269 tree->opval.op == LABEL &&
1270 isSymbolEqual (AST_SYMBOL (tree->left), label))
1273 return isLabelInAst (label, tree->right) &&
1274 isLabelInAst (label, tree->left);
1278 /*-----------------------------------------------------------------*/
1279 /* isLoopCountable - return true if the loop count can be determi- */
1280 /* -ned at compile time . */
1281 /*-----------------------------------------------------------------*/
1283 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1284 symbol ** sym, ast ** init, ast ** end)
1287 /* the loop is considered countable if the following
1288 conditions are true :-
1290 a) initExpr :- <sym> = <const>
1291 b) condExpr :- <sym> < <const1>
1292 c) loopExpr :- <sym> ++
1295 /* first check the initExpr */
1296 if (IS_AST_OP (initExpr) &&
1297 initExpr->opval.op == '=' && /* is assignment */
1298 IS_AST_SYM_VALUE (initExpr->left))
1299 { /* left is a symbol */
1301 *sym = AST_SYMBOL (initExpr->left);
1302 *init = initExpr->right;
1307 /* for now the symbol has to be of
1309 if (!IS_INTEGRAL ((*sym)->type))
1312 /* now check condExpr */
1313 if (IS_AST_OP (condExpr))
1316 switch (condExpr->opval.op)
1319 if (IS_AST_SYM_VALUE (condExpr->left) &&
1320 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1321 IS_AST_LIT_VALUE (condExpr->right))
1323 *end = condExpr->right;
1329 if (IS_AST_OP (condExpr->left) &&
1330 condExpr->left->opval.op == '>' &&
1331 IS_AST_LIT_VALUE (condExpr->left->right) &&
1332 IS_AST_SYM_VALUE (condExpr->left->left) &&
1333 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1336 *end = newNode ('+', condExpr->left->right,
1337 newAst_VALUE (constVal ("1")));
1348 /* check loop expression is of the form <sym>++ */
1349 if (!IS_AST_OP (loopExpr))
1352 /* check if <sym> ++ */
1353 if (loopExpr->opval.op == INC_OP)
1359 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1360 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1367 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1368 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1376 if (loopExpr->opval.op == ADD_ASSIGN)
1379 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1380 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1381 IS_AST_LIT_VALUE (loopExpr->right) &&
1382 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1390 /*-----------------------------------------------------------------*/
1391 /* astHasVolatile - returns true if ast contains any volatile */
1392 /*-----------------------------------------------------------------*/
1394 astHasVolatile (ast * tree)
1399 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1402 if (IS_AST_OP (tree))
1403 return astHasVolatile (tree->left) ||
1404 astHasVolatile (tree->right);
1409 /*-----------------------------------------------------------------*/
1410 /* astHasPointer - return true if the ast contains any ptr variable */
1411 /*-----------------------------------------------------------------*/
1413 astHasPointer (ast * tree)
1418 if (IS_AST_LINK (tree))
1421 /* if we hit an array expression then check
1422 only the left side */
1423 if (IS_AST_OP (tree) && tree->opval.op == '[')
1424 return astHasPointer (tree->left);
1426 if (IS_AST_VALUE (tree))
1427 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1429 return astHasPointer (tree->left) ||
1430 astHasPointer (tree->right);
1434 /*-----------------------------------------------------------------*/
1435 /* astHasSymbol - return true if the ast has the given symbol */
1436 /*-----------------------------------------------------------------*/
1438 astHasSymbol (ast * tree, symbol * sym)
1440 if (!tree || IS_AST_LINK (tree))
1443 if (IS_AST_VALUE (tree))
1445 if (IS_AST_SYM_VALUE (tree))
1446 return isSymbolEqual (AST_SYMBOL (tree), sym);
1451 return astHasSymbol (tree->left, sym) ||
1452 astHasSymbol (tree->right, sym);
1455 /*-----------------------------------------------------------------*/
1456 /* astHasDeref - return true if the ast has an indirect access */
1457 /*-----------------------------------------------------------------*/
1459 astHasDeref (ast * tree)
1461 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1464 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1466 return astHasDeref (tree->left) || astHasDeref (tree->right);
1469 /*-----------------------------------------------------------------*/
1470 /* isConformingBody - the loop body has to conform to a set of rules */
1471 /* for the loop to be considered reversible read on for rules */
1472 /*-----------------------------------------------------------------*/
1474 isConformingBody (ast * pbody, symbol * sym, ast * body)
1477 /* we are going to do a pre-order traversal of the
1478 tree && check for the following conditions. (essentially
1479 a set of very shallow tests )
1480 a) the sym passed does not participate in
1481 any arithmetic operation
1482 b) There are no function calls
1483 c) all jumps are within the body
1484 d) address of loop control variable not taken
1485 e) if an assignment has a pointer on the
1486 left hand side make sure right does not have
1487 loop control variable */
1489 /* if we reach the end or a leaf then true */
1490 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1494 /* if anything else is "volatile" */
1495 if (IS_VOLATILE (TETYPE (pbody)))
1498 /* we will walk the body in a pre-order traversal for
1500 switch (pbody->opval.op)
1502 /*------------------------------------------------------------------*/
1504 return isConformingBody (pbody->right, sym, body);
1506 /*------------------------------------------------------------------*/
1511 /*------------------------------------------------------------------*/
1512 case INC_OP: /* incerement operator unary so left only */
1515 /* sure we are not sym is not modified */
1517 IS_AST_SYM_VALUE (pbody->left) &&
1518 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1522 IS_AST_SYM_VALUE (pbody->right) &&
1523 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1528 /*------------------------------------------------------------------*/
1530 case '*': /* can be unary : if right is null then unary operation */
1535 /* if right is NULL then unary operation */
1536 /*------------------------------------------------------------------*/
1537 /*----------------------------*/
1539 /*----------------------------*/
1542 if (IS_AST_SYM_VALUE (pbody->left) &&
1543 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1546 return isConformingBody (pbody->left, sym, body);
1550 if (astHasSymbol (pbody->left, sym) ||
1551 astHasSymbol (pbody->right, sym))
1556 /*------------------------------------------------------------------*/
1564 if (IS_AST_SYM_VALUE (pbody->left) &&
1565 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1568 if (IS_AST_SYM_VALUE (pbody->right) &&
1569 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1572 return isConformingBody (pbody->left, sym, body) &&
1573 isConformingBody (pbody->right, sym, body);
1580 if (IS_AST_SYM_VALUE (pbody->left) &&
1581 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1583 return isConformingBody (pbody->left, sym, body);
1585 /*------------------------------------------------------------------*/
1597 case SIZEOF: /* evaluate wihout code generation */
1599 return isConformingBody (pbody->left, sym, body) &&
1600 isConformingBody (pbody->right, sym, body);
1602 /*------------------------------------------------------------------*/
1605 /* if left has a pointer & right has loop
1606 control variable then we cannot */
1607 if (astHasPointer (pbody->left) &&
1608 astHasSymbol (pbody->right, sym))
1610 if (astHasVolatile (pbody->left))
1613 if (IS_AST_SYM_VALUE (pbody->left) &&
1614 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1617 if (astHasVolatile (pbody->left))
1620 if (astHasDeref(pbody->right)) return FALSE;
1622 return isConformingBody (pbody->left, sym, body) &&
1623 isConformingBody (pbody->right, sym, body);
1634 assert ("Parser should not have generated this\n");
1636 /*------------------------------------------------------------------*/
1637 /*----------------------------*/
1638 /* comma operator */
1639 /*----------------------------*/
1641 return isConformingBody (pbody->left, sym, body) &&
1642 isConformingBody (pbody->right, sym, body);
1644 /*------------------------------------------------------------------*/
1645 /*----------------------------*/
1647 /*----------------------------*/
1651 /*------------------------------------------------------------------*/
1652 /*----------------------------*/
1653 /* return statement */
1654 /*----------------------------*/
1659 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1664 if (astHasSymbol (pbody->left, sym))
1671 return isConformingBody (pbody->left, sym, body) &&
1672 isConformingBody (pbody->right, sym, body);
1678 /*-----------------------------------------------------------------*/
1679 /* isLoopReversible - takes a for loop as input && returns true */
1680 /* if the for loop is reversible. If yes will set the value of */
1681 /* the loop control var & init value & termination value */
1682 /*-----------------------------------------------------------------*/
1684 isLoopReversible (ast * loop, symbol ** loopCntrl,
1685 ast ** init, ast ** end)
1687 /* if option says don't do it then don't */
1688 if (optimize.noLoopReverse)
1690 /* there are several tests to determine this */
1692 /* for loop has to be of the form
1693 for ( <sym> = <const1> ;
1694 [<sym> < <const2>] ;
1695 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1697 if (!isLoopCountable (AST_FOR (loop, initExpr),
1698 AST_FOR (loop, condExpr),
1699 AST_FOR (loop, loopExpr),
1700 loopCntrl, init, end))
1703 /* now do some serious checking on the body of the loop
1706 return isConformingBody (loop->left, *loopCntrl, loop->left);
1710 /*-----------------------------------------------------------------*/
1711 /* replLoopSym - replace the loop sym by loop sym -1 */
1712 /*-----------------------------------------------------------------*/
1714 replLoopSym (ast * body, symbol * sym)
1717 if (!body || IS_AST_LINK (body))
1720 if (IS_AST_SYM_VALUE (body))
1723 if (isSymbolEqual (AST_SYMBOL (body), sym))
1727 body->opval.op = '-';
1728 body->left = newAst_VALUE (symbolVal (sym));
1729 body->right = newAst_VALUE (constVal ("1"));
1737 replLoopSym (body->left, sym);
1738 replLoopSym (body->right, sym);
1742 /*-----------------------------------------------------------------*/
1743 /* reverseLoop - do the actual loop reversal */
1744 /*-----------------------------------------------------------------*/
1746 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1750 /* create the following tree
1755 if (sym) goto for_continue ;
1758 /* put it together piece by piece */
1759 rloop = newNode (NULLOP,
1760 createIf (newAst_VALUE (symbolVal (sym)),
1762 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1765 newAst_VALUE (symbolVal (sym)),
1768 replLoopSym (loop->left, sym);
1770 rloop = newNode (NULLOP,
1772 newAst_VALUE (symbolVal (sym)),
1773 newNode ('-', end, init)),
1774 createLabel (AST_FOR (loop, continueLabel),
1778 newNode (SUB_ASSIGN,
1779 newAst_VALUE (symbolVal (sym)),
1780 newAst_VALUE (constVal ("1"))),
1783 return decorateType (rloop);
1787 //#define DEMAND_INTEGER_PROMOTION
1789 #ifdef DEMAND_INTEGER_PROMOTION
1791 /*-----------------------------------------------------------------*/
1792 /* walk a tree looking for the leaves. Add a typecast to the given */
1793 /* type to each value leaf node. */
1794 /*-----------------------------------------------------------------*/
1796 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1798 if (!node || IS_CALLOP(node))
1800 /* WTF? We should never get here. */
1804 if (!node->left && !node->right)
1806 /* We're at a leaf; if it's a value, apply the typecast */
1807 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1809 *parentPtr = decorateType (newNode (CAST,
1810 newAst_LINK (copyLinkChain (type)),
1818 pushTypeCastToLeaves (type, node->left, &(node->left));
1822 pushTypeCastToLeaves (type, node->right, &(node->right));
1829 /*-----------------------------------------------------------------*/
1830 /* decorateType - compute type for this tree also does type cheking */
1831 /* this is done bottom up, since type have to flow upwards */
1832 /* it also does constant folding, and paramater checking */
1833 /*-----------------------------------------------------------------*/
1835 decorateType (ast * tree)
1843 /* if already has type then do nothing */
1844 if (tree->decorated)
1847 tree->decorated = 1;
1849 /* print the line */
1850 /* if not block & function */
1851 if (tree->type == EX_OP &&
1852 (tree->opval.op != FUNCTION &&
1853 tree->opval.op != BLOCK &&
1854 tree->opval.op != NULLOP))
1856 filename = tree->filename;
1857 lineno = tree->lineno;
1860 /* if any child is an error | this one is an error do nothing */
1861 if (tree->isError ||
1862 (tree->left && tree->left->isError) ||
1863 (tree->right && tree->right->isError))
1866 /*------------------------------------------------------------------*/
1867 /*----------------------------*/
1868 /* leaf has been reached */
1869 /*----------------------------*/
1870 /* if this is of type value */
1871 /* just get the type */
1872 if (tree->type == EX_VALUE)
1875 if (IS_LITERAL (tree->opval.val->etype))
1878 /* if this is a character array then declare it */
1879 if (IS_ARRAY (tree->opval.val->type))
1880 tree->opval.val = stringToSymbol (tree->opval.val);
1882 /* otherwise just copy the type information */
1883 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1887 if (tree->opval.val->sym)
1889 /* if the undefined flag is set then give error message */
1890 if (tree->opval.val->sym->undefined)
1892 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1894 TTYPE (tree) = TETYPE (tree) =
1895 tree->opval.val->type = tree->opval.val->sym->type =
1896 tree->opval.val->etype = tree->opval.val->sym->etype =
1897 copyLinkChain (INTTYPE);
1902 /* if impilicit i.e. struct/union member then no type */
1903 if (tree->opval.val->sym->implicit)
1904 TTYPE (tree) = TETYPE (tree) = NULL;
1909 /* else copy the type */
1910 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1912 /* and mark it as referenced */
1913 tree->opval.val->sym->isref = 1;
1921 /* if type link for the case of cast */
1922 if (tree->type == EX_LINK)
1924 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1931 dtl = decorateType (tree->left);
1932 dtr = decorateType (tree->right);
1934 /* this is to take care of situations
1935 when the tree gets rewritten */
1936 if (dtl != tree->left)
1938 if (dtr != tree->right)
1942 /* depending on type of operator do */
1944 switch (tree->opval.op)
1946 /*------------------------------------------------------------------*/
1947 /*----------------------------*/
1949 /*----------------------------*/
1952 /* determine which is the array & which the index */
1953 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1956 ast *tempTree = tree->left;
1957 tree->left = tree->right;
1958 tree->right = tempTree;
1961 /* first check if this is a array or a pointer */
1962 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1964 werror (E_NEED_ARRAY_PTR, "[]");
1965 goto errorTreeReturn;
1968 /* check if the type of the idx */
1969 if (!IS_INTEGRAL (RTYPE (tree)))
1971 werror (E_IDX_NOT_INT);
1972 goto errorTreeReturn;
1975 /* if the left is an rvalue then error */
1978 werror (E_LVALUE_REQUIRED, "array access");
1979 goto errorTreeReturn;
1982 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1983 if (IS_PTR(LTYPE(tree))) {
1984 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1988 /*------------------------------------------------------------------*/
1989 /*----------------------------*/
1991 /*----------------------------*/
1993 /* if this is not a structure */
1994 if (!IS_STRUCT (LTYPE (tree)))
1996 werror (E_STRUCT_UNION, ".");
1997 goto errorTreeReturn;
1999 TTYPE (tree) = structElemType (LTYPE (tree),
2000 (tree->right->type == EX_VALUE ?
2001 tree->right->opval.val : NULL));
2002 TETYPE (tree) = getSpec (TTYPE (tree));
2005 /*------------------------------------------------------------------*/
2006 /*----------------------------*/
2007 /* struct/union pointer */
2008 /*----------------------------*/
2010 /* if not pointer to a structure */
2011 if (!IS_PTR (LTYPE (tree)))
2013 werror (E_PTR_REQD);
2014 goto errorTreeReturn;
2017 if (!IS_STRUCT (LTYPE (tree)->next))
2019 werror (E_STRUCT_UNION, "->");
2020 goto errorTreeReturn;
2023 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2024 (tree->right->type == EX_VALUE ?
2025 tree->right->opval.val : NULL));
2026 TETYPE (tree) = getSpec (TTYPE (tree));
2029 /*------------------------------------------------------------------*/
2030 /*----------------------------*/
2031 /* ++/-- operation */
2032 /*----------------------------*/
2033 case INC_OP: /* incerement operator unary so left only */
2036 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2037 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2038 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2039 werror (E_CODE_WRITE, "++/--");
2048 /*------------------------------------------------------------------*/
2049 /*----------------------------*/
2051 /*----------------------------*/
2052 case '&': /* can be unary */
2053 /* if right is NULL then unary operation */
2054 if (tree->right) /* not an unary operation */
2057 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2059 werror (E_BITWISE_OP);
2060 werror (W_CONTINUE, "left & right types are ");
2061 printTypeChain (LTYPE (tree), stderr);
2062 fprintf (stderr, ",");
2063 printTypeChain (RTYPE (tree), stderr);
2064 fprintf (stderr, "\n");
2065 goto errorTreeReturn;
2068 /* if they are both literal */
2069 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2071 tree->type = EX_VALUE;
2072 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2073 valFromType (RETYPE (tree)), '&');
2075 tree->right = tree->left = NULL;
2076 TETYPE (tree) = tree->opval.val->etype;
2077 TTYPE (tree) = tree->opval.val->type;
2081 /* see if this is a GETHBIT operation if yes
2084 ast *otree = optimizeGetHbit (tree);
2087 return decorateType (otree);
2091 // we can't do this because of "(int & 0xff) << 3"
2093 /* if right or left is literal then result of that type */
2094 if (IS_LITERAL (RTYPE (tree)))
2097 TTYPE (tree) = copyLinkChain (RTYPE (tree));
2098 TETYPE (tree) = getSpec (TTYPE (tree));
2099 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2103 if (IS_LITERAL (LTYPE (tree)))
2105 TTYPE (tree) = copyLinkChain (LTYPE (tree));
2106 TETYPE (tree) = getSpec (TTYPE (tree));
2107 SPEC_SCLS (TETYPE (tree)) = S_AUTO;
2113 computeType (LTYPE (tree), RTYPE (tree));
2114 TETYPE (tree) = getSpec (TTYPE (tree));
2119 computeType (LTYPE (tree), RTYPE (tree));
2120 TETYPE (tree) = getSpec (TTYPE (tree));
2122 LRVAL (tree) = RRVAL (tree) = 1;
2126 /*------------------------------------------------------------------*/
2127 /*----------------------------*/
2129 /*----------------------------*/
2131 p->class = DECLARATOR;
2132 /* if bit field then error */
2133 if (IS_BITVAR (tree->left->etype))
2135 werror (E_ILLEGAL_ADDR, "address of bit variable");
2136 goto errorTreeReturn;
2139 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2141 werror (E_ILLEGAL_ADDR, "address of register variable");
2142 goto errorTreeReturn;
2145 if (IS_FUNC (LTYPE (tree)))
2147 werror (E_ILLEGAL_ADDR, "address of function");
2148 goto errorTreeReturn;
2151 if (IS_LITERAL(LTYPE(tree)))
2153 werror (E_ILLEGAL_ADDR, "address of literal");
2154 goto errorTreeReturn;
2159 werror (E_LVALUE_REQUIRED, "address of");
2160 goto errorTreeReturn;
2162 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2164 DCL_TYPE (p) = CPOINTER;
2165 DCL_PTR_CONST (p) = port->mem.code_ro;
2167 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2168 DCL_TYPE (p) = FPOINTER;
2169 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2170 DCL_TYPE (p) = PPOINTER;
2171 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2172 DCL_TYPE (p) = IPOINTER;
2173 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2174 DCL_TYPE (p) = EEPPOINTER;
2176 DCL_TYPE (p) = POINTER;
2178 if (IS_AST_SYM_VALUE (tree->left))
2180 AST_SYMBOL (tree->left)->addrtaken = 1;
2181 AST_SYMBOL (tree->left)->allocreq = 1;
2184 p->next = LTYPE (tree);
2186 TETYPE (tree) = getSpec (TTYPE (tree));
2187 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2188 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2193 /*------------------------------------------------------------------*/
2194 /*----------------------------*/
2196 /*----------------------------*/
2198 /* if the rewrite succeeds then don't go any furthur */
2200 ast *wtree = optimizeRRCRLC (tree);
2202 return decorateType (wtree);
2204 /*------------------------------------------------------------------*/
2205 /*----------------------------*/
2207 /*----------------------------*/
2209 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2211 werror (E_BITWISE_OP);
2212 werror (W_CONTINUE, "left & right types are ");
2213 printTypeChain (LTYPE (tree), stderr);
2214 fprintf (stderr, ",");
2215 printTypeChain (RTYPE (tree), stderr);
2216 fprintf (stderr, "\n");
2217 goto errorTreeReturn;
2220 /* if they are both literal then */
2221 /* rewrite the tree */
2222 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2224 tree->type = EX_VALUE;
2225 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2226 valFromType (RETYPE (tree)),
2228 tree->right = tree->left = NULL;
2229 TETYPE (tree) = tree->opval.val->etype;
2230 TTYPE (tree) = tree->opval.val->type;
2233 LRVAL (tree) = RRVAL (tree) = 1;
2234 TETYPE (tree) = getSpec (TTYPE (tree) =
2235 computeType (LTYPE (tree),
2238 /*------------------------------------------------------------------*/
2239 /*----------------------------*/
2241 /*----------------------------*/
2243 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2245 werror (E_INVALID_OP, "divide");
2246 goto errorTreeReturn;
2248 /* if they are both literal then */
2249 /* rewrite the tree */
2250 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2252 tree->type = EX_VALUE;
2253 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2254 valFromType (RETYPE (tree)));
2255 tree->right = tree->left = NULL;
2256 TETYPE (tree) = getSpec (TTYPE (tree) =
2257 tree->opval.val->type);
2260 LRVAL (tree) = RRVAL (tree) = 1;
2261 TETYPE (tree) = getSpec (TTYPE (tree) =
2262 computeType (LTYPE (tree),
2266 /*------------------------------------------------------------------*/
2267 /*----------------------------*/
2269 /*----------------------------*/
2271 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2273 werror (E_BITWISE_OP);
2274 werror (W_CONTINUE, "left & right types are ");
2275 printTypeChain (LTYPE (tree), stderr);
2276 fprintf (stderr, ",");
2277 printTypeChain (RTYPE (tree), stderr);
2278 fprintf (stderr, "\n");
2279 goto errorTreeReturn;
2281 /* if they are both literal then */
2282 /* rewrite the tree */
2283 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2285 tree->type = EX_VALUE;
2286 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2287 valFromType (RETYPE (tree)));
2288 tree->right = tree->left = NULL;
2289 TETYPE (tree) = getSpec (TTYPE (tree) =
2290 tree->opval.val->type);
2293 LRVAL (tree) = RRVAL (tree) = 1;
2294 TETYPE (tree) = getSpec (TTYPE (tree) =
2295 computeType (LTYPE (tree),
2299 /*------------------------------------------------------------------*/
2300 /*----------------------------*/
2301 /* address dereference */
2302 /*----------------------------*/
2303 case '*': /* can be unary : if right is null then unary operation */
2306 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2308 werror (E_PTR_REQD);
2309 goto errorTreeReturn;
2314 werror (E_LVALUE_REQUIRED, "pointer deref");
2315 goto errorTreeReturn;
2317 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2318 LTYPE (tree)->next : NULL);
2319 TETYPE (tree) = getSpec (TTYPE (tree));
2320 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2324 /*------------------------------------------------------------------*/
2325 /*----------------------------*/
2326 /* multiplication */
2327 /*----------------------------*/
2328 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2330 werror (E_INVALID_OP, "multiplication");
2331 goto errorTreeReturn;
2334 /* if they are both literal then */
2335 /* rewrite the tree */
2336 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2338 tree->type = EX_VALUE;
2339 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2340 valFromType (RETYPE (tree)));
2341 tree->right = tree->left = NULL;
2342 TETYPE (tree) = getSpec (TTYPE (tree) =
2343 tree->opval.val->type);
2347 /* if left is a literal exchange left & right */
2348 if (IS_LITERAL (LTYPE (tree)))
2350 ast *tTree = tree->left;
2351 tree->left = tree->right;
2352 tree->right = tTree;
2355 LRVAL (tree) = RRVAL (tree) = 1;
2356 /* promote result to int if left & right are char
2357 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2358 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2359 TETYPE (tree) = getSpec (TTYPE (tree) =
2360 computeType (LTYPE (tree),
2362 SPEC_NOUN(TETYPE(tree)) = V_INT;
2364 TETYPE (tree) = getSpec (TTYPE (tree) =
2365 computeType (LTYPE (tree),
2370 /*------------------------------------------------------------------*/
2371 /*----------------------------*/
2372 /* unary '+' operator */
2373 /*----------------------------*/
2378 if (!IS_INTEGRAL (LTYPE (tree)))
2380 werror (E_UNARY_OP, '+');
2381 goto errorTreeReturn;
2384 /* if left is a literal then do it */
2385 if (IS_LITERAL (LTYPE (tree)))
2387 tree->type = EX_VALUE;
2388 tree->opval.val = valFromType (LETYPE (tree));
2390 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2394 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2398 /*------------------------------------------------------------------*/
2399 /*----------------------------*/
2401 /*----------------------------*/
2403 /* this is not a unary operation */
2404 /* if both pointers then problem */
2405 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2406 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2408 werror (E_PTR_PLUS_PTR);
2409 goto errorTreeReturn;
2412 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2413 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2415 werror (E_PLUS_INVALID, "+");
2416 goto errorTreeReturn;
2419 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2420 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2422 werror (E_PLUS_INVALID, "+");
2423 goto errorTreeReturn;
2425 /* if they are both literal then */
2426 /* rewrite the tree */
2427 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2429 tree->type = EX_VALUE;
2430 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2431 valFromType (RETYPE (tree)));
2432 tree->right = tree->left = NULL;
2433 TETYPE (tree) = getSpec (TTYPE (tree) =
2434 tree->opval.val->type);
2438 /* if the right is a pointer or left is a literal
2439 xchange left & right */
2440 if (IS_ARRAY (RTYPE (tree)) ||
2441 IS_PTR (RTYPE (tree)) ||
2442 IS_LITERAL (LTYPE (tree)))
2444 ast *tTree = tree->left;
2445 tree->left = tree->right;
2446 tree->right = tTree;
2449 LRVAL (tree) = RRVAL (tree) = 1;
2450 /* if the left is a pointer */
2451 if (IS_PTR (LTYPE (tree)))
2452 TETYPE (tree) = getSpec (TTYPE (tree) =
2455 TETYPE (tree) = getSpec (TTYPE (tree) =
2456 computeType (LTYPE (tree),
2460 /*------------------------------------------------------------------*/
2461 /*----------------------------*/
2463 /*----------------------------*/
2464 case '-': /* can be unary */
2465 /* if right is null then unary */
2469 if (!IS_ARITHMETIC (LTYPE (tree)))
2471 werror (E_UNARY_OP, tree->opval.op);
2472 goto errorTreeReturn;
2475 /* if left is a literal then do it */
2476 if (IS_LITERAL (LTYPE (tree)))
2478 tree->type = EX_VALUE;
2479 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2481 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2482 SPEC_USIGN(TETYPE(tree)) = 0;
2486 TTYPE (tree) = LTYPE (tree);
2490 /*------------------------------------------------------------------*/
2491 /*----------------------------*/
2493 /*----------------------------*/
2495 if (!(IS_PTR (LTYPE (tree)) ||
2496 IS_ARRAY (LTYPE (tree)) ||
2497 IS_ARITHMETIC (LTYPE (tree))))
2499 werror (E_PLUS_INVALID, "-");
2500 goto errorTreeReturn;
2503 if (!(IS_PTR (RTYPE (tree)) ||
2504 IS_ARRAY (RTYPE (tree)) ||
2505 IS_ARITHMETIC (RTYPE (tree))))
2507 werror (E_PLUS_INVALID, "-");
2508 goto errorTreeReturn;
2511 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2512 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2513 IS_INTEGRAL (RTYPE (tree))))
2515 werror (E_PLUS_INVALID, "-");
2516 goto errorTreeReturn;
2519 /* if they are both literal then */
2520 /* rewrite the tree */
2521 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2523 tree->type = EX_VALUE;
2524 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2525 valFromType (RETYPE (tree)));
2526 tree->right = tree->left = NULL;
2527 TETYPE (tree) = getSpec (TTYPE (tree) =
2528 tree->opval.val->type);
2532 /* if the left & right are equal then zero */
2533 if (isAstEqual (tree->left, tree->right))
2535 tree->type = EX_VALUE;
2536 tree->left = tree->right = NULL;
2537 tree->opval.val = constVal ("0");
2538 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2542 /* if both of them are pointers or arrays then */
2543 /* the result is going to be an integer */
2544 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2545 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2546 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2548 /* if only the left is a pointer */
2549 /* then result is a pointer */
2550 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2551 TETYPE (tree) = getSpec (TTYPE (tree) =
2554 TETYPE (tree) = getSpec (TTYPE (tree) =
2555 computeType (LTYPE (tree),
2557 LRVAL (tree) = RRVAL (tree) = 1;
2560 /*------------------------------------------------------------------*/
2561 /*----------------------------*/
2563 /*----------------------------*/
2565 /* can be only integral type */
2566 if (!IS_INTEGRAL (LTYPE (tree)))
2568 werror (E_UNARY_OP, tree->opval.op);
2569 goto errorTreeReturn;
2572 /* if left is a literal then do it */
2573 if (IS_LITERAL (LTYPE (tree)))
2575 tree->type = EX_VALUE;
2576 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2578 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2582 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2585 /*------------------------------------------------------------------*/
2586 /*----------------------------*/
2588 /*----------------------------*/
2590 /* can be pointer */
2591 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2592 !IS_PTR (LTYPE (tree)) &&
2593 !IS_ARRAY (LTYPE (tree)))
2595 werror (E_UNARY_OP, tree->opval.op);
2596 goto errorTreeReturn;
2599 /* if left is a literal then do it */
2600 if (IS_LITERAL (LTYPE (tree)))
2602 tree->type = EX_VALUE;
2603 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2605 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2609 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2612 /*------------------------------------------------------------------*/
2613 /*----------------------------*/
2615 /*----------------------------*/
2618 TTYPE (tree) = LTYPE (tree);
2619 TETYPE (tree) = LETYPE (tree);
2623 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2628 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2630 werror (E_SHIFT_OP_INVALID);
2631 werror (W_CONTINUE, "left & right types are ");
2632 printTypeChain (LTYPE (tree), stderr);
2633 fprintf (stderr, ",");
2634 printTypeChain (RTYPE (tree), stderr);
2635 fprintf (stderr, "\n");
2636 goto errorTreeReturn;
2639 /* if they are both literal then */
2640 /* rewrite the tree */
2641 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2643 tree->type = EX_VALUE;
2644 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2645 valFromType (RETYPE (tree)),
2646 (tree->opval.op == LEFT_OP ? 1 : 0));
2647 tree->right = tree->left = NULL;
2648 TETYPE (tree) = getSpec (TTYPE (tree) =
2649 tree->opval.val->type);
2652 /* if only the right side is a literal & we are
2653 shifting more than size of the left operand then zero */
2654 if (IS_LITERAL (RTYPE (tree)) &&
2655 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2656 (getSize (LTYPE (tree)) * 8))
2658 werror (W_SHIFT_CHANGED,
2659 (tree->opval.op == LEFT_OP ? "left" : "right"));
2660 tree->type = EX_VALUE;
2661 tree->left = tree->right = NULL;
2662 tree->opval.val = constVal ("0");
2663 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2666 LRVAL (tree) = RRVAL (tree) = 1;
2667 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2669 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2673 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2677 /*------------------------------------------------------------------*/
2678 /*----------------------------*/
2680 /*----------------------------*/
2681 case CAST: /* change the type */
2682 /* cannot cast to an aggregate type */
2683 if (IS_AGGREGATE (LTYPE (tree)))
2685 werror (E_CAST_ILLEGAL);
2686 goto errorTreeReturn;
2689 /* make sure the type is complete and sane */
2690 checkTypeSanity(LETYPE(tree), "(cast)");
2693 /* if the right is a literal replace the tree */
2694 if (IS_LITERAL (RETYPE (tree))) {
2695 if (!IS_PTR (LTYPE (tree))) {
2696 tree->type = EX_VALUE;
2698 valCastLiteral (LTYPE (tree),
2699 floatFromVal (valFromType (RETYPE (tree))));
2702 TTYPE (tree) = tree->opval.val->type;
2703 tree->values.literalFromCast = 1;
2704 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2705 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2706 sym_link *rest = LTYPE(tree)->next;
2707 werror(W_LITERAL_GENERIC);
2708 TTYPE(tree) = newLink();
2709 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2710 TTYPE(tree)->next = rest;
2711 tree->left->opval.lnk = TTYPE(tree);
2714 TTYPE (tree) = LTYPE (tree);
2718 TTYPE (tree) = LTYPE (tree);
2722 /* if the right is a literal replace the tree */
2723 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2724 tree->type = EX_VALUE;
2726 valCastLiteral (LTYPE (tree),
2727 floatFromVal (valFromType (RETYPE (tree))));
2730 TTYPE (tree) = tree->opval.val->type;
2731 tree->values.literalFromCast = 1;
2733 TTYPE (tree) = LTYPE (tree);
2738 TETYPE (tree) = getSpec (TTYPE (tree));
2742 /*------------------------------------------------------------------*/
2743 /*----------------------------*/
2744 /* logical &&, || */
2745 /*----------------------------*/
2748 /* each must me arithmetic type or be a pointer */
2749 if (!IS_PTR (LTYPE (tree)) &&
2750 !IS_ARRAY (LTYPE (tree)) &&
2751 !IS_INTEGRAL (LTYPE (tree)))
2753 werror (E_COMPARE_OP);
2754 goto errorTreeReturn;
2757 if (!IS_PTR (RTYPE (tree)) &&
2758 !IS_ARRAY (RTYPE (tree)) &&
2759 !IS_INTEGRAL (RTYPE (tree)))
2761 werror (E_COMPARE_OP);
2762 goto errorTreeReturn;
2764 /* if they are both literal then */
2765 /* rewrite the tree */
2766 if (IS_LITERAL (RTYPE (tree)) &&
2767 IS_LITERAL (LTYPE (tree)))
2769 tree->type = EX_VALUE;
2770 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2771 valFromType (RETYPE (tree)),
2773 tree->right = tree->left = NULL;
2774 TETYPE (tree) = getSpec (TTYPE (tree) =
2775 tree->opval.val->type);
2778 LRVAL (tree) = RRVAL (tree) = 1;
2779 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2782 /*------------------------------------------------------------------*/
2783 /*----------------------------*/
2784 /* comparison operators */
2785 /*----------------------------*/
2793 ast *lt = optimizeCompare (tree);
2799 /* if they are pointers they must be castable */
2800 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2802 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2804 werror (E_COMPARE_OP);
2805 fprintf (stderr, "comparing type ");
2806 printTypeChain (LTYPE (tree), stderr);
2807 fprintf (stderr, "to type ");
2808 printTypeChain (RTYPE (tree), stderr);
2809 fprintf (stderr, "\n");
2810 goto errorTreeReturn;
2813 /* else they should be promotable to one another */
2816 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2817 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2819 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2821 werror (E_COMPARE_OP);
2822 fprintf (stderr, "comparing type ");
2823 printTypeChain (LTYPE (tree), stderr);
2824 fprintf (stderr, "to type ");
2825 printTypeChain (RTYPE (tree), stderr);
2826 fprintf (stderr, "\n");
2827 goto errorTreeReturn;
2831 /* if they are both literal then */
2832 /* rewrite the tree */
2833 if (IS_LITERAL (RTYPE (tree)) &&
2834 IS_LITERAL (LTYPE (tree)))
2836 tree->type = EX_VALUE;
2837 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2838 valFromType (RETYPE (tree)),
2840 tree->right = tree->left = NULL;
2841 TETYPE (tree) = getSpec (TTYPE (tree) =
2842 tree->opval.val->type);
2845 LRVAL (tree) = RRVAL (tree) = 1;
2846 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2849 /*------------------------------------------------------------------*/
2850 /*----------------------------*/
2852 /*----------------------------*/
2853 case SIZEOF: /* evaluate wihout code generation */
2854 /* change the type to a integer */
2855 tree->type = EX_VALUE;
2856 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2857 tree->opval.val = constVal (buffer);
2858 tree->right = tree->left = NULL;
2859 TETYPE (tree) = getSpec (TTYPE (tree) =
2860 tree->opval.val->type);
2863 /*------------------------------------------------------------------*/
2864 /*----------------------------*/
2865 /* conditional operator '?' */
2866 /*----------------------------*/
2868 /* the type is value of the colon operator (on the right) */
2869 assert(IS_COLON_OP(tree->right));
2870 /* if already known then replace the tree : optimizer will do it
2871 but faster to do it here */
2872 if (IS_LITERAL (LTYPE(tree))) {
2873 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2874 return tree->right->left ;
2876 return tree->right->right ;
2879 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2880 TETYPE (tree) = getSpec (TTYPE (tree));
2885 /* if they don't match we have a problem */
2886 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2888 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2889 goto errorTreeReturn;
2892 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2893 TETYPE (tree) = getSpec (TTYPE (tree));
2897 /*------------------------------------------------------------------*/
2898 /*----------------------------*/
2899 /* assignment operators */
2900 /*----------------------------*/
2903 /* for these it must be both must be integral */
2904 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2905 !IS_ARITHMETIC (RTYPE (tree)))
2907 werror (E_OPS_INTEGRAL);
2908 goto errorTreeReturn;
2911 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2913 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2914 werror (E_CODE_WRITE, " ");
2918 werror (E_LVALUE_REQUIRED, "*= or /=");
2919 goto errorTreeReturn;
2930 /* for these it must be both must be integral */
2931 if (!IS_INTEGRAL (LTYPE (tree)) ||
2932 !IS_INTEGRAL (RTYPE (tree)))
2934 werror (E_OPS_INTEGRAL);
2935 goto errorTreeReturn;
2938 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2940 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2941 werror (E_CODE_WRITE, " ");
2945 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2946 goto errorTreeReturn;
2952 /*------------------------------------------------------------------*/
2953 /*----------------------------*/
2955 /*----------------------------*/
2957 if (!(IS_PTR (LTYPE (tree)) ||
2958 IS_ARITHMETIC (LTYPE (tree))))
2960 werror (E_PLUS_INVALID, "-=");
2961 goto errorTreeReturn;
2964 if (!(IS_PTR (RTYPE (tree)) ||
2965 IS_ARITHMETIC (RTYPE (tree))))
2967 werror (E_PLUS_INVALID, "-=");
2968 goto errorTreeReturn;
2971 TETYPE (tree) = getSpec (TTYPE (tree) =
2972 computeType (LTYPE (tree),
2975 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2976 werror (E_CODE_WRITE, " ");
2980 werror (E_LVALUE_REQUIRED, "-=");
2981 goto errorTreeReturn;
2987 /*------------------------------------------------------------------*/
2988 /*----------------------------*/
2990 /*----------------------------*/
2992 /* this is not a unary operation */
2993 /* if both pointers then problem */
2994 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2996 werror (E_PTR_PLUS_PTR);
2997 goto errorTreeReturn;
3000 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3002 werror (E_PLUS_INVALID, "+=");
3003 goto errorTreeReturn;
3006 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3008 werror (E_PLUS_INVALID, "+=");
3009 goto errorTreeReturn;
3012 TETYPE (tree) = getSpec (TTYPE (tree) =
3013 computeType (LTYPE (tree),
3016 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3017 werror (E_CODE_WRITE, " ");
3021 werror (E_LVALUE_REQUIRED, "+=");
3022 goto errorTreeReturn;
3025 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3026 tree->opval.op = '=';
3030 /*------------------------------------------------------------------*/
3031 /*----------------------------*/
3032 /* straight assignemnt */
3033 /*----------------------------*/
3035 /* cannot be an aggregate */
3036 if (IS_AGGREGATE (LTYPE (tree)))
3038 werror (E_AGGR_ASSIGN);
3039 goto errorTreeReturn;
3042 /* they should either match or be castable */
3043 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3045 werror (E_TYPE_MISMATCH, "assignment", " ");
3046 fprintf (stderr, "type --> '");
3047 printTypeChain (RTYPE (tree), stderr);
3048 fprintf (stderr, "' ");
3049 fprintf (stderr, "assigned to type --> '");
3050 printTypeChain (LTYPE (tree), stderr);
3051 fprintf (stderr, "'\n");
3052 goto errorTreeReturn;
3055 /* if the left side of the tree is of type void
3056 then report error */
3057 if (IS_VOID (LTYPE (tree)))
3059 werror (E_CAST_ZERO);
3060 printFromToType(RTYPE(tree), LTYPE(tree));
3063 TETYPE (tree) = getSpec (TTYPE (tree) =
3067 if (!tree->initMode ) {
3068 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3069 werror (E_CODE_WRITE, " ");
3073 werror (E_LVALUE_REQUIRED, "=");
3074 goto errorTreeReturn;
3079 /*------------------------------------------------------------------*/
3080 /*----------------------------*/
3081 /* comma operator */
3082 /*----------------------------*/
3084 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3087 /*------------------------------------------------------------------*/
3088 /*----------------------------*/
3090 /*----------------------------*/
3094 if (processParms (tree->left,
3095 FUNC_ARGS(tree->left->ftype),
3096 tree->right, &parmNumber, TRUE)) {
3097 goto errorTreeReturn;
3100 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3102 //FUNC_ARGS(tree->left->ftype) =
3103 //reverseVal (FUNC_ARGS(tree->left->ftype));
3104 reverseParms (tree->right);
3107 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3110 /*------------------------------------------------------------------*/
3111 /*----------------------------*/
3112 /* return statement */
3113 /*----------------------------*/
3118 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3120 werror (W_RETURN_MISMATCH);
3121 printFromToType (RTYPE(tree), currFunc->type->next);
3122 goto errorTreeReturn;
3125 if (IS_VOID (currFunc->type->next)
3127 !IS_VOID (RTYPE (tree)))
3129 werror (E_FUNC_VOID);
3130 goto errorTreeReturn;
3133 /* if there is going to be a casing required then add it */
3134 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3137 decorateType (newNode (CAST,
3138 newAst_LINK (copyLinkChain (currFunc->type->next)),
3147 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3149 werror (E_VOID_FUNC, currFunc->name);
3150 goto errorTreeReturn;
3153 TTYPE (tree) = TETYPE (tree) = NULL;
3156 /*------------------------------------------------------------------*/
3157 /*----------------------------*/
3158 /* switch statement */
3159 /*----------------------------*/
3161 /* the switch value must be an integer */
3162 if (!IS_INTEGRAL (LTYPE (tree)))
3164 werror (E_SWITCH_NON_INTEGER);
3165 goto errorTreeReturn;
3168 TTYPE (tree) = TETYPE (tree) = NULL;
3171 /*------------------------------------------------------------------*/
3172 /*----------------------------*/
3174 /*----------------------------*/
3176 tree->left = backPatchLabels (tree->left,
3179 TTYPE (tree) = TETYPE (tree) = NULL;
3182 /*------------------------------------------------------------------*/
3183 /*----------------------------*/
3185 /*----------------------------*/
3188 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3189 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3190 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3192 /* if the for loop is reversible then
3193 reverse it otherwise do what we normally
3199 if (isLoopReversible (tree, &sym, &init, &end))
3200 return reverseLoop (tree, sym, init, end);
3202 return decorateType (createFor (AST_FOR (tree, trueLabel),
3203 AST_FOR (tree, continueLabel),
3204 AST_FOR (tree, falseLabel),
3205 AST_FOR (tree, condLabel),
3206 AST_FOR (tree, initExpr),
3207 AST_FOR (tree, condExpr),
3208 AST_FOR (tree, loopExpr),
3212 TTYPE (tree) = TETYPE (tree) = NULL;
3216 /* some error found this tree will be killed */
3218 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3219 tree->opval.op = NULLOP;
3225 /*-----------------------------------------------------------------*/
3226 /* sizeofOp - processes size of operation */
3227 /*-----------------------------------------------------------------*/
3229 sizeofOp (sym_link * type)
3233 /* make sure the type is complete and sane */
3234 checkTypeSanity(type, "(sizeof)");
3236 /* get the size and convert it to character */
3237 sprintf (buff, "%d", getSize (type));
3239 /* now convert into value */
3240 return constVal (buff);
3244 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3245 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3246 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3247 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3248 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3249 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3250 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3252 /*-----------------------------------------------------------------*/
3253 /* backPatchLabels - change and or not operators to flow control */
3254 /*-----------------------------------------------------------------*/
3256 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3262 if (!(IS_ANDORNOT (tree)))
3265 /* if this an and */
3268 static int localLbl = 0;
3271 sprintf (buffer, "_and_%d", localLbl++);
3272 localLabel = newSymbol (buffer, NestLevel);
3274 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3276 /* if left is already a IFX then just change the if true label in that */
3277 if (!IS_IFX (tree->left))
3278 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3280 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3281 /* right is a IFX then just join */
3282 if (IS_IFX (tree->right))
3283 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3285 tree->right = createLabel (localLabel, tree->right);
3286 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3288 return newNode (NULLOP, tree->left, tree->right);
3291 /* if this is an or operation */
3294 static int localLbl = 0;
3297 sprintf (buffer, "_or_%d", localLbl++);
3298 localLabel = newSymbol (buffer, NestLevel);
3300 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3302 /* if left is already a IFX then just change the if true label in that */
3303 if (!IS_IFX (tree->left))
3304 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3306 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3307 /* right is a IFX then just join */
3308 if (IS_IFX (tree->right))
3309 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3311 tree->right = createLabel (localLabel, tree->right);
3312 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3314 return newNode (NULLOP, tree->left, tree->right);
3320 int wasnot = IS_NOT (tree->left);
3321 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3323 /* if the left is already a IFX */
3324 if (!IS_IFX (tree->left))
3325 tree->left = newNode (IFX, tree->left, NULL);
3329 tree->left->trueLabel = trueLabel;
3330 tree->left->falseLabel = falseLabel;
3334 tree->left->trueLabel = falseLabel;
3335 tree->left->falseLabel = trueLabel;
3342 tree->trueLabel = trueLabel;
3343 tree->falseLabel = falseLabel;
3350 /*-----------------------------------------------------------------*/
3351 /* createBlock - create expression tree for block */
3352 /*-----------------------------------------------------------------*/
3354 createBlock (symbol * decl, ast * body)
3358 /* if the block has nothing */
3362 ex = newNode (BLOCK, NULL, body);
3363 ex->values.sym = decl;
3365 ex->right = ex->right;
3371 /*-----------------------------------------------------------------*/
3372 /* createLabel - creates the expression tree for labels */
3373 /*-----------------------------------------------------------------*/
3375 createLabel (symbol * label, ast * stmnt)
3378 char name[SDCC_NAME_MAX + 1];
3381 /* must create fresh symbol if the symbol name */
3382 /* exists in the symbol table, since there can */
3383 /* be a variable with the same name as the labl */
3384 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3385 (csym->level == label->level))
3386 label = newSymbol (label->name, label->level);
3388 /* change the name before putting it in add _ */
3389 sprintf (name, "%s", label->name);
3391 /* put the label in the LabelSymbol table */
3392 /* but first check if a label of the same */
3394 if ((csym = findSym (LabelTab, NULL, name)))
3395 werror (E_DUPLICATE_LABEL, label->name);
3397 addSym (LabelTab, label, name, label->level, 0, 0);
3400 label->key = labelKey++;
3401 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3407 /*-----------------------------------------------------------------*/
3408 /* createCase - generates the parsetree for a case statement */
3409 /*-----------------------------------------------------------------*/
3411 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3413 char caseLbl[SDCC_NAME_MAX + 1];
3417 /* if the switch statement does not exist */
3418 /* then case is out of context */
3421 werror (E_CASE_CONTEXT);
3425 caseVal = decorateType (resolveSymbols (caseVal));
3426 /* if not a constant then error */
3427 if (!IS_LITERAL (caseVal->ftype))
3429 werror (E_CASE_CONSTANT);
3433 /* if not a integer than error */
3434 if (!IS_INTEGRAL (caseVal->ftype))
3436 werror (E_CASE_NON_INTEGER);
3440 /* find the end of the switch values chain */
3441 if (!(val = swStat->values.switchVals.swVals))
3442 swStat->values.switchVals.swVals = caseVal->opval.val;
3445 /* also order the cases according to value */
3447 int cVal = (int) floatFromVal (caseVal->opval.val);
3448 while (val && (int) floatFromVal (val) < cVal)
3454 /* if we reached the end then */
3457 pval->next = caseVal->opval.val;
3461 /* we found a value greater than */
3462 /* the current value we must add this */
3463 /* before the value */
3464 caseVal->opval.val->next = val;
3466 /* if this was the first in chain */
3467 if (swStat->values.switchVals.swVals == val)
3468 swStat->values.switchVals.swVals =
3471 pval->next = caseVal->opval.val;
3476 /* create the case label */
3477 sprintf (caseLbl, "_case_%d_%d",
3478 swStat->values.switchVals.swNum,
3479 (int) floatFromVal (caseVal->opval.val));
3481 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3486 /*-----------------------------------------------------------------*/
3487 /* createDefault - creates the parse tree for the default statement */
3488 /*-----------------------------------------------------------------*/
3490 createDefault (ast * swStat, ast * stmnt)
3492 char defLbl[SDCC_NAME_MAX + 1];
3494 /* if the switch statement does not exist */
3495 /* then case is out of context */
3498 werror (E_CASE_CONTEXT);
3502 /* turn on the default flag */
3503 swStat->values.switchVals.swDefault = 1;
3505 /* create the label */
3506 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3507 return createLabel (newSymbol (defLbl, 0), stmnt);
3510 /*-----------------------------------------------------------------*/
3511 /* createIf - creates the parsetree for the if statement */
3512 /*-----------------------------------------------------------------*/
3514 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3516 static int Lblnum = 0;
3518 symbol *ifTrue, *ifFalse, *ifEnd;
3520 /* if neither exists */
3521 if (!elseBody && !ifBody) {
3522 // if there are no side effects (i++, j() etc)
3523 if (!hasSEFcalls(condAst)) {
3528 /* create the labels */
3529 sprintf (buffer, "_iffalse_%d", Lblnum);
3530 ifFalse = newSymbol (buffer, NestLevel);
3531 /* if no else body then end == false */
3536 sprintf (buffer, "_ifend_%d", Lblnum);
3537 ifEnd = newSymbol (buffer, NestLevel);
3540 sprintf (buffer, "_iftrue_%d", Lblnum);
3541 ifTrue = newSymbol (buffer, NestLevel);
3545 /* attach the ifTrue label to the top of it body */
3546 ifBody = createLabel (ifTrue, ifBody);
3547 /* attach a goto end to the ifBody if else is present */
3550 ifBody = newNode (NULLOP, ifBody,
3552 newAst_VALUE (symbolVal (ifEnd)),
3554 /* put the elseLabel on the else body */
3555 elseBody = createLabel (ifFalse, elseBody);
3556 /* out the end at the end of the body */
3557 elseBody = newNode (NULLOP,
3559 createLabel (ifEnd, NULL));
3563 ifBody = newNode (NULLOP, ifBody,
3564 createLabel (ifFalse, NULL));
3566 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3567 if (IS_IFX (condAst))
3570 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3572 return newNode (NULLOP, ifTree,
3573 newNode (NULLOP, ifBody, elseBody));
3577 /*-----------------------------------------------------------------*/
3578 /* createDo - creates parse tree for do */
3581 /* _docontinue_n: */
3582 /* condition_expression +-> trueLabel -> _dobody_n */
3584 /* +-> falseLabel-> _dobreak_n */
3586 /*-----------------------------------------------------------------*/
3588 createDo (symbol * trueLabel, symbol * continueLabel,
3589 symbol * falseLabel, ast * condAst, ast * doBody)
3594 /* if the body does not exist then it is simple */
3597 condAst = backPatchLabels (condAst, continueLabel, NULL);
3598 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3599 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3600 doTree->trueLabel = continueLabel;
3601 doTree->falseLabel = NULL;
3605 /* otherwise we have a body */
3606 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3608 /* attach the body label to the top */
3609 doBody = createLabel (trueLabel, doBody);
3610 /* attach the continue label to end of body */
3611 doBody = newNode (NULLOP, doBody,
3612 createLabel (continueLabel, NULL));
3614 /* now put the break label at the end */
3615 if (IS_IFX (condAst))
3618 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3620 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3622 /* putting it together */
3623 return newNode (NULLOP, doBody, doTree);
3626 /*-----------------------------------------------------------------*/
3627 /* createFor - creates parse tree for 'for' statement */
3630 /* condExpr +-> trueLabel -> _forbody_n */
3632 /* +-> falseLabel-> _forbreak_n */
3635 /* _forcontinue_n: */
3637 /* goto _forcond_n ; */
3639 /*-----------------------------------------------------------------*/
3641 createFor (symbol * trueLabel, symbol * continueLabel,
3642 symbol * falseLabel, symbol * condLabel,
3643 ast * initExpr, ast * condExpr, ast * loopExpr,
3648 /* if loopexpression not present then we can generate it */
3649 /* the same way as a while */
3651 return newNode (NULLOP, initExpr,
3652 createWhile (trueLabel, continueLabel,
3653 falseLabel, condExpr, forBody));
3654 /* vanilla for statement */
3655 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3657 if (condExpr && !IS_IFX (condExpr))
3658 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3661 /* attach condition label to condition */
3662 condExpr = createLabel (condLabel, condExpr);
3664 /* attach body label to body */
3665 forBody = createLabel (trueLabel, forBody);
3667 /* attach continue to forLoop expression & attach */
3668 /* goto the forcond @ and of loopExpression */
3669 loopExpr = createLabel (continueLabel,
3673 newAst_VALUE (symbolVal (condLabel)),
3675 /* now start putting them together */
3676 forTree = newNode (NULLOP, initExpr, condExpr);
3677 forTree = newNode (NULLOP, forTree, forBody);
3678 forTree = newNode (NULLOP, forTree, loopExpr);
3679 /* finally add the break label */
3680 forTree = newNode (NULLOP, forTree,
3681 createLabel (falseLabel, NULL));
3685 /*-----------------------------------------------------------------*/
3686 /* createWhile - creates parse tree for while statement */
3687 /* the while statement will be created as follows */
3689 /* _while_continue_n: */
3690 /* condition_expression +-> trueLabel -> _while_boby_n */
3692 /* +-> falseLabel -> _while_break_n */
3693 /* _while_body_n: */
3695 /* goto _while_continue_n */
3696 /* _while_break_n: */
3697 /*-----------------------------------------------------------------*/
3699 createWhile (symbol * trueLabel, symbol * continueLabel,
3700 symbol * falseLabel, ast * condExpr, ast * whileBody)
3704 /* put the continue label */
3705 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3706 condExpr = createLabel (continueLabel, condExpr);
3707 condExpr->lineno = 0;
3709 /* put the body label in front of the body */
3710 whileBody = createLabel (trueLabel, whileBody);
3711 whileBody->lineno = 0;
3712 /* put a jump to continue at the end of the body */
3713 /* and put break label at the end of the body */
3714 whileBody = newNode (NULLOP,
3717 newAst_VALUE (symbolVal (continueLabel)),
3718 createLabel (falseLabel, NULL)));
3720 /* put it all together */
3721 if (IS_IFX (condExpr))
3722 whileTree = condExpr;
3725 whileTree = newNode (IFX, condExpr, NULL);
3726 /* put the true & false labels in place */
3727 whileTree->trueLabel = trueLabel;
3728 whileTree->falseLabel = falseLabel;
3731 return newNode (NULLOP, whileTree, whileBody);
3734 /*-----------------------------------------------------------------*/
3735 /* optimizeGetHbit - get highest order bit of the expression */
3736 /*-----------------------------------------------------------------*/
3738 optimizeGetHbit (ast * tree)
3741 /* if this is not a bit and */
3742 if (!IS_BITAND (tree))
3745 /* will look for tree of the form
3746 ( expr >> ((sizeof expr) -1) ) & 1 */
3747 if (!IS_AST_LIT_VALUE (tree->right))
3750 if (AST_LIT_VALUE (tree->right) != 1)
3753 if (!IS_RIGHT_OP (tree->left))
3756 if (!IS_AST_LIT_VALUE (tree->left->right))
3759 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3760 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3763 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3767 /*-----------------------------------------------------------------*/
3768 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3769 /*-----------------------------------------------------------------*/
3771 optimizeRRCRLC (ast * root)
3773 /* will look for trees of the form
3774 (?expr << 1) | (?expr >> 7) or
3775 (?expr >> 7) | (?expr << 1) will make that
3776 into a RLC : operation ..
3778 (?expr >> 1) | (?expr << 7) or
3779 (?expr << 7) | (?expr >> 1) will make that
3780 into a RRC operation
3781 note : by 7 I mean (number of bits required to hold the
3783 /* if the root operations is not a | operation the not */
3784 if (!IS_BITOR (root))
3787 /* I have to think of a better way to match patterns this sucks */
3788 /* that aside let start looking for the first case : I use a the
3789 negative check a lot to improve the efficiency */
3790 /* (?expr << 1) | (?expr >> 7) */
3791 if (IS_LEFT_OP (root->left) &&
3792 IS_RIGHT_OP (root->right))
3795 if (!SPEC_USIGN (TETYPE (root->left->left)))
3798 if (!IS_AST_LIT_VALUE (root->left->right) ||
3799 !IS_AST_LIT_VALUE (root->right->right))
3802 /* make sure it is the same expression */
3803 if (!isAstEqual (root->left->left,
3807 if (AST_LIT_VALUE (root->left->right) != 1)
3810 if (AST_LIT_VALUE (root->right->right) !=
3811 (getSize (TTYPE (root->left->left)) * 8 - 1))
3814 /* whew got the first case : create the AST */
3815 return newNode (RLC, root->left->left, NULL);
3819 /* check for second case */
3820 /* (?expr >> 7) | (?expr << 1) */
3821 if (IS_LEFT_OP (root->right) &&
3822 IS_RIGHT_OP (root->left))
3825 if (!SPEC_USIGN (TETYPE (root->left->left)))
3828 if (!IS_AST_LIT_VALUE (root->left->right) ||
3829 !IS_AST_LIT_VALUE (root->right->right))
3832 /* make sure it is the same symbol */
3833 if (!isAstEqual (root->left->left,
3837 if (AST_LIT_VALUE (root->right->right) != 1)
3840 if (AST_LIT_VALUE (root->left->right) !=
3841 (getSize (TTYPE (root->left->left)) * 8 - 1))
3844 /* whew got the first case : create the AST */
3845 return newNode (RLC, root->left->left, NULL);
3850 /* third case for RRC */
3851 /* (?symbol >> 1) | (?symbol << 7) */
3852 if (IS_LEFT_OP (root->right) &&
3853 IS_RIGHT_OP (root->left))
3856 if (!SPEC_USIGN (TETYPE (root->left->left)))
3859 if (!IS_AST_LIT_VALUE (root->left->right) ||
3860 !IS_AST_LIT_VALUE (root->right->right))
3863 /* make sure it is the same symbol */
3864 if (!isAstEqual (root->left->left,
3868 if (AST_LIT_VALUE (root->left->right) != 1)
3871 if (AST_LIT_VALUE (root->right->right) !=
3872 (getSize (TTYPE (root->left->left)) * 8 - 1))
3875 /* whew got the first case : create the AST */
3876 return newNode (RRC, root->left->left, NULL);
3880 /* fourth and last case for now */
3881 /* (?symbol << 7) | (?symbol >> 1) */
3882 if (IS_RIGHT_OP (root->right) &&
3883 IS_LEFT_OP (root->left))
3886 if (!SPEC_USIGN (TETYPE (root->left->left)))
3889 if (!IS_AST_LIT_VALUE (root->left->right) ||
3890 !IS_AST_LIT_VALUE (root->right->right))
3893 /* make sure it is the same symbol */
3894 if (!isAstEqual (root->left->left,
3898 if (AST_LIT_VALUE (root->right->right) != 1)
3901 if (AST_LIT_VALUE (root->left->right) !=
3902 (getSize (TTYPE (root->left->left)) * 8 - 1))
3905 /* whew got the first case : create the AST */
3906 return newNode (RRC, root->left->left, NULL);
3910 /* not found return root */
3914 /*-----------------------------------------------------------------*/
3915 /* optimizeCompare - otimizes compares for bit variables */
3916 /*-----------------------------------------------------------------*/
3918 optimizeCompare (ast * root)
3920 ast *optExpr = NULL;
3923 unsigned int litValue;
3925 /* if nothing then return nothing */
3929 /* if not a compare op then do leaves */
3930 if (!IS_COMPARE_OP (root))
3932 root->left = optimizeCompare (root->left);
3933 root->right = optimizeCompare (root->right);
3937 /* if left & right are the same then depending
3938 of the operation do */
3939 if (isAstEqual (root->left, root->right))
3941 switch (root->opval.op)
3946 optExpr = newAst_VALUE (constVal ("0"));
3951 optExpr = newAst_VALUE (constVal ("1"));
3955 return decorateType (optExpr);
3958 vleft = (root->left->type == EX_VALUE ?
3959 root->left->opval.val : NULL);
3961 vright = (root->right->type == EX_VALUE ?
3962 root->right->opval.val : NULL);
3964 /* if left is a BITVAR in BITSPACE */
3965 /* and right is a LITERAL then opt- */
3966 /* imize else do nothing */
3967 if (vleft && vright &&
3968 IS_BITVAR (vleft->etype) &&
3969 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3970 IS_LITERAL (vright->etype))
3973 /* if right side > 1 then comparison may never succeed */
3974 if ((litValue = (int) floatFromVal (vright)) > 1)
3976 werror (W_BAD_COMPARE);
3982 switch (root->opval.op)
3984 case '>': /* bit value greater than 1 cannot be */
3985 werror (W_BAD_COMPARE);
3989 case '<': /* bit value < 1 means 0 */
3991 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3994 case LE_OP: /* bit value <= 1 means no check */
3995 optExpr = newAst_VALUE (vright);
3998 case GE_OP: /* bit value >= 1 means only check for = */
4000 optExpr = newAst_VALUE (vleft);
4005 { /* literal is zero */
4006 switch (root->opval.op)
4008 case '<': /* bit value < 0 cannot be */
4009 werror (W_BAD_COMPARE);
4013 case '>': /* bit value > 0 means 1 */
4015 optExpr = newAst_VALUE (vleft);
4018 case LE_OP: /* bit value <= 0 means no check */
4019 case GE_OP: /* bit value >= 0 means no check */
4020 werror (W_BAD_COMPARE);
4024 case EQ_OP: /* bit == 0 means ! of bit */
4025 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4029 return decorateType (resolveSymbols (optExpr));
4030 } /* end-of-if of BITVAR */
4035 /*-----------------------------------------------------------------*/
4036 /* addSymToBlock : adds the symbol to the first block we find */
4037 /*-----------------------------------------------------------------*/
4039 addSymToBlock (symbol * sym, ast * tree)
4041 /* reached end of tree or a leaf */
4042 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4046 if (IS_AST_OP (tree) &&
4047 tree->opval.op == BLOCK)
4050 symbol *lsym = copySymbol (sym);
4052 lsym->next = AST_VALUES (tree, sym);
4053 AST_VALUES (tree, sym) = lsym;
4057 addSymToBlock (sym, tree->left);
4058 addSymToBlock (sym, tree->right);
4061 /*-----------------------------------------------------------------*/
4062 /* processRegParms - do processing for register parameters */
4063 /*-----------------------------------------------------------------*/
4065 processRegParms (value * args, ast * body)
4069 if (IS_REGPARM (args->etype))
4070 addSymToBlock (args->sym, body);
4075 /*-----------------------------------------------------------------*/
4076 /* resetParmKey - resets the operandkeys for the symbols */
4077 /*-----------------------------------------------------------------*/
4078 DEFSETFUNC (resetParmKey)
4089 /*-----------------------------------------------------------------*/
4090 /* createFunction - This is the key node that calls the iCode for */
4091 /* generating the code for a function. Note code */
4092 /* is generated function by function, later when */
4093 /* add inter-procedural analysis this will change */
4094 /*-----------------------------------------------------------------*/
4096 createFunction (symbol * name, ast * body)
4102 iCode *piCode = NULL;
4104 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4105 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4107 /* if check function return 0 then some problem */
4108 if (checkFunction (name, NULL) == 0)
4111 /* create a dummy block if none exists */
4113 body = newNode (BLOCK, NULL, NULL);
4117 /* check if the function name already in the symbol table */
4118 if ((csym = findSym (SymbolTab, NULL, name->name)))
4121 /* special case for compiler defined functions
4122 we need to add the name to the publics list : this
4123 actually means we are now compiling the compiler
4127 addSet (&publics, name);
4133 allocVariables (name);
4135 name->lastLine = yylineno;
4138 #if 0 // jwk: this is now done in addDecl()
4139 processFuncArgs (currFunc);
4142 /* set the stack pointer */
4143 /* PENDING: check this for the mcs51 */
4144 stackPtr = -port->stack.direction * port->stack.call_overhead;
4145 if (IFFUNC_ISISR (name->type))
4146 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4147 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4148 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4150 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4152 fetype = getSpec (name->type); /* get the specifier for the function */
4153 /* if this is a reentrant function then */
4154 if (IFFUNC_ISREENT (name->type))
4157 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4159 /* do processing for parameters that are passed in registers */
4160 processRegParms (FUNC_ARGS(name->type), body);
4162 /* set the stack pointer */
4166 /* allocate & autoinit the block variables */
4167 processBlockVars (body, &stack, ALLOCATE);
4169 /* save the stack information */
4170 if (options.useXstack)
4171 name->xstack = SPEC_STAK (fetype) = stack;
4173 name->stack = SPEC_STAK (fetype) = stack;
4175 /* name needs to be mangled */
4176 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4178 body = resolveSymbols (body); /* resolve the symbols */
4179 body = decorateType (body); /* propagateType & do semantic checks */
4181 ex = newAst_VALUE (symbolVal (name)); /* create name */
4182 ex = newNode (FUNCTION, ex, body);
4183 ex->values.args = FUNC_ARGS(name->type);
4185 if (options.dump_tree) PA(ex);
4188 werror (E_FUNC_NO_CODE, name->name);
4192 /* create the node & generate intermediate code */
4194 codeOutFile = code->oFile;
4195 piCode = iCodeFromAst (ex);
4199 werror (E_FUNC_NO_CODE, name->name);
4203 eBBlockFromiCode (piCode);
4205 /* if there are any statics then do them */
4208 GcurMemmap = statsg;
4209 codeOutFile = statsg->oFile;
4210 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4216 /* dealloc the block variables */
4217 processBlockVars (body, &stack, DEALLOCATE);
4218 /* deallocate paramaters */
4219 deallocParms (FUNC_ARGS(name->type));
4221 if (IFFUNC_ISREENT (name->type))
4224 /* we are done freeup memory & cleanup */
4228 FUNC_HASBODY(name->type) = 1;
4229 addSet (&operKeyReset, name);
4230 applyToSet (operKeyReset, resetParmKey);
4233 cdbStructBlock (1, cdbFile);
4235 cleanUpLevel (LabelTab, 0);
4236 cleanUpBlock (StructTab, 1);
4237 cleanUpBlock (TypedefTab, 1);
4239 xstack->syms = NULL;
4240 istack->syms = NULL;
4245 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4246 /*-----------------------------------------------------------------*/
4247 /* ast_print : prints the ast (for debugging purposes) */
4248 /*-----------------------------------------------------------------*/
4250 void ast_print (ast * tree, FILE *outfile, int indent)
4255 /* can print only decorated trees */
4256 if (!tree->decorated) return;
4258 /* if any child is an error | this one is an error do nothing */
4259 if (tree->isError ||
4260 (tree->left && tree->left->isError) ||
4261 (tree->right && tree->right->isError)) {
4262 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4266 /* print the line */
4267 /* if not block & function */
4268 if (tree->type == EX_OP &&
4269 (tree->opval.op != FUNCTION &&
4270 tree->opval.op != BLOCK &&
4271 tree->opval.op != NULLOP)) {
4274 if (tree->opval.op == FUNCTION) {
4276 value *args=FUNC_ARGS(tree->left->opval.val->type);
4277 fprintf(outfile,"FUNCTION (%s=%p) type (",
4278 tree->left->opval.val->name, tree);
4279 printTypeChain (tree->ftype,outfile);
4280 fprintf(outfile,") args (");
4283 fprintf (outfile, ", ");
4285 printTypeChain (args ? args->type : NULL, outfile);
4287 args= args ? args->next : NULL;
4289 fprintf(outfile,")\n");
4290 ast_print(tree->left,outfile,indent);
4291 ast_print(tree->right,outfile,indent);
4294 if (tree->opval.op == BLOCK) {
4295 symbol *decls = tree->values.sym;
4296 INDENT(indent,outfile);
4297 fprintf(outfile,"{\n");
4299 INDENT(indent+4,outfile);
4300 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4301 decls->name, decls);
4302 printTypeChain(decls->type,outfile);
4303 fprintf(outfile,")\n");
4305 decls = decls->next;
4307 ast_print(tree->right,outfile,indent+4);
4308 INDENT(indent,outfile);
4309 fprintf(outfile,"}\n");
4312 if (tree->opval.op == NULLOP) {
4313 fprintf(outfile,"\n");
4314 ast_print(tree->left,outfile,indent);
4315 fprintf(outfile,"\n");
4316 ast_print(tree->right,outfile,indent);
4319 INDENT(indent,outfile);
4321 /*------------------------------------------------------------------*/
4322 /*----------------------------*/
4323 /* leaf has been reached */
4324 /*----------------------------*/
4325 /* if this is of type value */
4326 /* just get the type */
4327 if (tree->type == EX_VALUE) {
4329 if (IS_LITERAL (tree->opval.val->etype)) {
4330 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4331 (int) floatFromVal(tree->opval.val),
4332 (int) floatFromVal(tree->opval.val),
4333 floatFromVal(tree->opval.val));
4334 } else if (tree->opval.val->sym) {
4335 /* if the undefined flag is set then give error message */
4336 if (tree->opval.val->sym->undefined) {
4337 fprintf(outfile,"UNDEFINED SYMBOL ");
4339 fprintf(outfile,"SYMBOL ");
4341 fprintf(outfile,"(%s=%p)",
4342 tree->opval.val->sym->name,tree);
4345 fprintf(outfile," type (");
4346 printTypeChain(tree->ftype,outfile);
4347 fprintf(outfile,")\n");
4349 fprintf(outfile,"\n");
4354 /* if type link for the case of cast */
4355 if (tree->type == EX_LINK) {
4356 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4357 printTypeChain(tree->opval.lnk,outfile);
4358 fprintf(outfile,")\n");
4363 /* depending on type of operator do */
4365 switch (tree->opval.op) {
4366 /*------------------------------------------------------------------*/
4367 /*----------------------------*/
4369 /*----------------------------*/
4371 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4372 printTypeChain(tree->ftype,outfile);
4373 fprintf(outfile,")\n");
4374 ast_print(tree->left,outfile,indent+4);
4375 ast_print(tree->right,outfile,indent+4);
4378 /*------------------------------------------------------------------*/
4379 /*----------------------------*/
4381 /*----------------------------*/
4383 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4384 printTypeChain(tree->ftype,outfile);
4385 fprintf(outfile,")\n");
4386 ast_print(tree->left,outfile,indent+4);
4387 ast_print(tree->right,outfile,indent+4);
4390 /*------------------------------------------------------------------*/
4391 /*----------------------------*/
4392 /* struct/union pointer */
4393 /*----------------------------*/
4395 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4396 printTypeChain(tree->ftype,outfile);
4397 fprintf(outfile,")\n");
4398 ast_print(tree->left,outfile,indent+4);
4399 ast_print(tree->right,outfile,indent+4);
4402 /*------------------------------------------------------------------*/
4403 /*----------------------------*/
4404 /* ++/-- operation */
4405 /*----------------------------*/
4406 case INC_OP: /* incerement operator unary so left only */
4407 fprintf(outfile,"INC_OP (%p) type (",tree);
4408 printTypeChain(tree->ftype,outfile);
4409 fprintf(outfile,")\n");
4410 ast_print(tree->left,outfile,indent+4);
4414 fprintf(outfile,"DEC_OP (%p) type (",tree);
4415 printTypeChain(tree->ftype,outfile);
4416 fprintf(outfile,")\n");
4417 ast_print(tree->left,outfile,indent+4);
4420 /*------------------------------------------------------------------*/
4421 /*----------------------------*/
4423 /*----------------------------*/
4426 fprintf(outfile,"& (%p) type (",tree);
4427 printTypeChain(tree->ftype,outfile);
4428 fprintf(outfile,")\n");
4429 ast_print(tree->left,outfile,indent+4);
4430 ast_print(tree->right,outfile,indent+4);
4432 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4433 printTypeChain(tree->ftype,outfile);
4434 fprintf(outfile,")\n");
4435 ast_print(tree->left,outfile,indent+4);
4436 ast_print(tree->right,outfile,indent+4);
4439 /*----------------------------*/
4441 /*----------------------------*/
4443 fprintf(outfile,"OR (%p) type (",tree);
4444 printTypeChain(tree->ftype,outfile);
4445 fprintf(outfile,")\n");
4446 ast_print(tree->left,outfile,indent+4);
4447 ast_print(tree->right,outfile,indent+4);
4449 /*------------------------------------------------------------------*/
4450 /*----------------------------*/
4452 /*----------------------------*/
4454 fprintf(outfile,"XOR (%p) type (",tree);
4455 printTypeChain(tree->ftype,outfile);
4456 fprintf(outfile,")\n");
4457 ast_print(tree->left,outfile,indent+4);
4458 ast_print(tree->right,outfile,indent+4);
4461 /*------------------------------------------------------------------*/
4462 /*----------------------------*/
4464 /*----------------------------*/
4466 fprintf(outfile,"DIV (%p) type (",tree);
4467 printTypeChain(tree->ftype,outfile);
4468 fprintf(outfile,")\n");
4469 ast_print(tree->left,outfile,indent+4);
4470 ast_print(tree->right,outfile,indent+4);
4472 /*------------------------------------------------------------------*/
4473 /*----------------------------*/
4475 /*----------------------------*/
4477 fprintf(outfile,"MOD (%p) type (",tree);
4478 printTypeChain(tree->ftype,outfile);
4479 fprintf(outfile,")\n");
4480 ast_print(tree->left,outfile,indent+4);
4481 ast_print(tree->right,outfile,indent+4);
4484 /*------------------------------------------------------------------*/
4485 /*----------------------------*/
4486 /* address dereference */
4487 /*----------------------------*/
4488 case '*': /* can be unary : if right is null then unary operation */
4490 fprintf(outfile,"DEREF (%p) type (",tree);
4491 printTypeChain(tree->ftype,outfile);
4492 fprintf(outfile,")\n");
4493 ast_print(tree->left,outfile,indent+4);
4496 /*------------------------------------------------------------------*/
4497 /*----------------------------*/
4498 /* multiplication */
4499 /*----------------------------*/
4500 fprintf(outfile,"MULT (%p) type (",tree);
4501 printTypeChain(tree->ftype,outfile);
4502 fprintf(outfile,")\n");
4503 ast_print(tree->left,outfile,indent+4);
4504 ast_print(tree->right,outfile,indent+4);
4508 /*------------------------------------------------------------------*/
4509 /*----------------------------*/
4510 /* unary '+' operator */
4511 /*----------------------------*/
4515 fprintf(outfile,"UPLUS (%p) type (",tree);
4516 printTypeChain(tree->ftype,outfile);
4517 fprintf(outfile,")\n");
4518 ast_print(tree->left,outfile,indent+4);
4520 /*------------------------------------------------------------------*/
4521 /*----------------------------*/
4523 /*----------------------------*/
4524 fprintf(outfile,"ADD (%p) type (",tree);
4525 printTypeChain(tree->ftype,outfile);
4526 fprintf(outfile,")\n");
4527 ast_print(tree->left,outfile,indent+4);
4528 ast_print(tree->right,outfile,indent+4);
4531 /*------------------------------------------------------------------*/
4532 /*----------------------------*/
4534 /*----------------------------*/
4535 case '-': /* can be unary */
4537 fprintf(outfile,"UMINUS (%p) type (",tree);
4538 printTypeChain(tree->ftype,outfile);
4539 fprintf(outfile,")\n");
4540 ast_print(tree->left,outfile,indent+4);
4542 /*------------------------------------------------------------------*/
4543 /*----------------------------*/
4545 /*----------------------------*/
4546 fprintf(outfile,"SUB (%p) type (",tree);
4547 printTypeChain(tree->ftype,outfile);
4548 fprintf(outfile,")\n");
4549 ast_print(tree->left,outfile,indent+4);
4550 ast_print(tree->right,outfile,indent+4);
4553 /*------------------------------------------------------------------*/
4554 /*----------------------------*/
4556 /*----------------------------*/
4558 fprintf(outfile,"COMPL (%p) type (",tree);
4559 printTypeChain(tree->ftype,outfile);
4560 fprintf(outfile,")\n");
4561 ast_print(tree->left,outfile,indent+4);
4563 /*------------------------------------------------------------------*/
4564 /*----------------------------*/
4566 /*----------------------------*/
4568 fprintf(outfile,"NOT (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+4);
4573 /*------------------------------------------------------------------*/
4574 /*----------------------------*/
4576 /*----------------------------*/
4578 fprintf(outfile,"RRC (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+4);
4585 fprintf(outfile,"RLC (%p) type (",tree);
4586 printTypeChain(tree->ftype,outfile);
4587 fprintf(outfile,")\n");
4588 ast_print(tree->left,outfile,indent+4);
4591 fprintf(outfile,"GETHBIT (%p) type (",tree);
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->left,outfile,indent+4);
4597 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->left,outfile,indent+4);
4601 ast_print(tree->right,outfile,indent+4);
4604 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4605 printTypeChain(tree->ftype,outfile);
4606 fprintf(outfile,")\n");
4607 ast_print(tree->left,outfile,indent+4);
4608 ast_print(tree->right,outfile,indent+4);
4610 /*------------------------------------------------------------------*/
4611 /*----------------------------*/
4613 /*----------------------------*/
4614 case CAST: /* change the type */
4615 fprintf(outfile,"CAST (%p) from type (",tree);
4616 printTypeChain(tree->right->ftype,outfile);
4617 fprintf(outfile,") to type (");
4618 printTypeChain(tree->ftype,outfile);
4619 fprintf(outfile,")\n");
4620 ast_print(tree->right,outfile,indent+4);
4624 fprintf(outfile,"ANDAND (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+4);
4628 ast_print(tree->right,outfile,indent+4);
4631 fprintf(outfile,"OROR (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+4);
4635 ast_print(tree->right,outfile,indent+4);
4638 /*------------------------------------------------------------------*/
4639 /*----------------------------*/
4640 /* comparison operators */
4641 /*----------------------------*/
4643 fprintf(outfile,"GT(>) (%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,"LT(<) (%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,"LE(<=) (%p) type (",tree);
4658 printTypeChain(tree->ftype,outfile);
4659 fprintf(outfile,")\n");
4660 ast_print(tree->left,outfile,indent+4);
4661 ast_print(tree->right,outfile,indent+4);
4664 fprintf(outfile,"GE(>=) (%p) type (",tree);
4665 printTypeChain(tree->ftype,outfile);
4666 fprintf(outfile,")\n");
4667 ast_print(tree->left,outfile,indent+4);
4668 ast_print(tree->right,outfile,indent+4);
4671 fprintf(outfile,"EQ(==) (%p) type (",tree);
4672 printTypeChain(tree->ftype,outfile);
4673 fprintf(outfile,")\n");
4674 ast_print(tree->left,outfile,indent+4);
4675 ast_print(tree->right,outfile,indent+4);
4678 fprintf(outfile,"NE(!=) (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+4);
4682 ast_print(tree->right,outfile,indent+4);
4683 /*------------------------------------------------------------------*/
4684 /*----------------------------*/
4686 /*----------------------------*/
4687 case SIZEOF: /* evaluate wihout code generation */
4688 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4691 /*------------------------------------------------------------------*/
4692 /*----------------------------*/
4693 /* conditional operator '?' */
4694 /*----------------------------*/
4696 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4704 fprintf(outfile,"COLON(:) (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+4);
4708 ast_print(tree->right,outfile,indent+4);
4711 /*------------------------------------------------------------------*/
4712 /*----------------------------*/
4713 /* assignment operators */
4714 /*----------------------------*/
4716 fprintf(outfile,"MULASS(*=) (%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,"DIVASS(/=) (%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,"ANDASS(&=) (%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,"ORASS(*=) (%p) type (",tree);
4738 printTypeChain(tree->ftype,outfile);
4739 fprintf(outfile,")\n");
4740 ast_print(tree->left,outfile,indent+4);
4741 ast_print(tree->right,outfile,indent+4);
4744 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4745 printTypeChain(tree->ftype,outfile);
4746 fprintf(outfile,")\n");
4747 ast_print(tree->left,outfile,indent+4);
4748 ast_print(tree->right,outfile,indent+4);
4751 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4752 printTypeChain(tree->ftype,outfile);
4753 fprintf(outfile,")\n");
4754 ast_print(tree->left,outfile,indent+4);
4755 ast_print(tree->right,outfile,indent+4);
4758 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4759 printTypeChain(tree->ftype,outfile);
4760 fprintf(outfile,")\n");
4761 ast_print(tree->left,outfile,indent+4);
4762 ast_print(tree->right,outfile,indent+4);
4764 /*------------------------------------------------------------------*/
4765 /*----------------------------*/
4767 /*----------------------------*/
4769 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4770 printTypeChain(tree->ftype,outfile);
4771 fprintf(outfile,")\n");
4772 ast_print(tree->left,outfile,indent+4);
4773 ast_print(tree->right,outfile,indent+4);
4775 /*------------------------------------------------------------------*/
4776 /*----------------------------*/
4778 /*----------------------------*/
4780 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4781 printTypeChain(tree->ftype,outfile);
4782 fprintf(outfile,")\n");
4783 ast_print(tree->left,outfile,indent+4);
4784 ast_print(tree->right,outfile,indent+4);
4786 /*------------------------------------------------------------------*/
4787 /*----------------------------*/
4788 /* straight assignemnt */
4789 /*----------------------------*/
4791 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4792 printTypeChain(tree->ftype,outfile);
4793 fprintf(outfile,")\n");
4794 ast_print(tree->left,outfile,indent+4);
4795 ast_print(tree->right,outfile,indent+4);
4797 /*------------------------------------------------------------------*/
4798 /*----------------------------*/
4799 /* comma operator */
4800 /*----------------------------*/
4802 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4803 printTypeChain(tree->ftype,outfile);
4804 fprintf(outfile,")\n");
4805 ast_print(tree->left,outfile,indent+4);
4806 ast_print(tree->right,outfile,indent+4);
4808 /*------------------------------------------------------------------*/
4809 /*----------------------------*/
4811 /*----------------------------*/
4814 fprintf(outfile,"CALL (%p) type (",tree);
4815 printTypeChain(tree->ftype,outfile);
4816 fprintf(outfile,")\n");
4817 ast_print(tree->left,outfile,indent+4);
4818 ast_print(tree->right,outfile,indent+4);
4821 fprintf(outfile,"PARMS\n");
4822 ast_print(tree->left,outfile,indent+4);
4823 if (tree->right && !IS_AST_PARAM(tree->right)) {
4824 ast_print(tree->right,outfile,indent+4);
4827 /*------------------------------------------------------------------*/
4828 /*----------------------------*/
4829 /* return statement */
4830 /*----------------------------*/
4832 fprintf(outfile,"RETURN (%p) type (",tree);
4833 printTypeChain(tree->right->ftype,outfile);
4834 fprintf(outfile,")\n");
4835 ast_print(tree->right,outfile,indent+4);
4837 /*------------------------------------------------------------------*/
4838 /*----------------------------*/
4839 /* label statement */
4840 /*----------------------------*/
4842 fprintf(outfile,"LABEL (%p)",tree);
4843 ast_print(tree->left,outfile,indent+4);
4844 ast_print(tree->right,outfile,indent);
4846 /*------------------------------------------------------------------*/
4847 /*----------------------------*/
4848 /* switch statement */
4849 /*----------------------------*/
4853 fprintf(outfile,"SWITCH (%p) ",tree);
4854 ast_print(tree->left,outfile,0);
4855 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4856 INDENT(indent+4,outfile);
4857 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4858 (int) floatFromVal(val),
4859 tree->values.switchVals.swNum,
4860 (int) floatFromVal(val));
4862 ast_print(tree->right,outfile,indent);
4865 /*------------------------------------------------------------------*/
4866 /*----------------------------*/
4868 /*----------------------------*/
4870 fprintf(outfile,"IF (%p) \n",tree);
4871 ast_print(tree->left,outfile,indent+4);
4872 if (tree->trueLabel) {
4873 INDENT(indent,outfile);
4874 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4876 if (tree->falseLabel) {
4877 INDENT(indent,outfile);
4878 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4880 ast_print(tree->right,outfile,indent+4);
4882 /*------------------------------------------------------------------*/
4883 /*----------------------------*/
4885 /*----------------------------*/
4887 fprintf(outfile,"FOR (%p) \n",tree);
4888 if (AST_FOR( tree, initExpr)) {
4889 INDENT(indent+4,outfile);
4890 fprintf(outfile,"INIT EXPR ");
4891 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4893 if (AST_FOR( tree, condExpr)) {
4894 INDENT(indent+4,outfile);
4895 fprintf(outfile,"COND EXPR ");
4896 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4898 if (AST_FOR( tree, loopExpr)) {
4899 INDENT(indent+4,outfile);
4900 fprintf(outfile,"LOOP EXPR ");
4901 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4903 fprintf(outfile,"FOR LOOP BODY \n");
4904 ast_print(tree->left,outfile,indent+4);
4913 ast_print(t,stdout,0);