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);
562 SPEC_EXTR(args->etype)=1;
565 args = args->next = newValue ();
572 allocVariables (sym);
577 /*-----------------------------------------------------------------*/
578 /* reverseParms - will reverse a parameter tree */
579 /*-----------------------------------------------------------------*/
581 reverseParms (ast * ptree)
587 /* top down if we find a nonParm tree then quit */
588 if (ptree->type == EX_OP && ptree->opval.op == PARAM)
591 ptree->left = ptree->right;
592 ptree->right = ttree;
593 reverseParms (ptree->left);
594 reverseParms (ptree->right);
600 /*-----------------------------------------------------------------*/
601 /* processParms - makes sure the parameters are okay and do some */
602 /* processing with them */
603 /*-----------------------------------------------------------------*/
605 processParms (ast * func,
608 int *parmNumber, // unused, although updated
611 /* if none of them exist */
612 if (!defParm && !actParm)
616 if (getenv("DEBUG_SANITY")) {
617 fprintf (stderr, "processParms: %s ", defParm->name);
619 /* make sure the type is complete and sane */
620 checkTypeSanity(defParm->etype, defParm->name);
623 /* if the function is being called via a pointer & */
624 /* it has not been defined a reentrant then we cannot */
625 /* have parameters */
626 if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
628 werror (W_NONRENT_ARGS);
632 /* if defined parameters ended but actual parameters */
633 /* exist and this is not defined as a variable arg */
634 if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
636 werror (E_TOO_MANY_PARMS);
640 /* if defined parameters present but no actual parameters */
641 if (defParm && !actParm)
643 werror (E_TOO_FEW_PARMS);
647 if (IS_VOID(actParm->ftype)) {
648 werror (E_VOID_VALUE_USED);
652 /* If this is a varargs function... */
653 if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
658 if (IS_CAST_OP (actParm)
659 || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
661 /* Parameter was explicitly typecast; don't touch it. */
665 /* The ternary ('?') operator is weird: the ftype of the
666 * operator is the type of the condition, but it will return a
667 * (possibly) different type.
669 if (IS_TERNARY_OP(actParm))
671 assert(IS_COLON_OP(actParm->right));
672 assert(actParm->right->left);
673 ftype = actParm->right->left->ftype;
677 ftype = actParm->ftype;
680 /* If it's a small integer, upcast to int. */
681 if (IS_INTEGRAL (ftype)
682 && (getSize (ftype) < (unsigned) INTSIZE))
684 newType = newAst_LINK(INTTYPE);
687 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
689 newType = newAst_LINK (copyLinkChain(ftype));
690 DCL_TYPE (newType->opval.lnk) = GPOINTER;
693 if (IS_AGGREGATE (ftype))
695 newType = newAst_LINK (copyLinkChain (ftype));
696 DCL_TYPE (newType->opval.lnk) = GPOINTER;
700 /* cast required; change this op to a cast. */
701 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
703 actParm->type = EX_OP;
704 actParm->opval.op = CAST;
705 actParm->left = newType;
706 actParm->right = parmCopy;
707 decorateType (actParm);
709 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
711 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
712 processParms (func, NULL, actParm->right, parmNumber, rightmost));
717 /* if defined parameters ended but actual has not & */
719 if (!defParm && actParm &&
720 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
723 resolveSymbols (actParm);
724 /* if this is a PARAM node then match left & right */
725 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
727 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
728 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
732 /* If we have found a value node by following only right-hand links,
733 * then we know that there are no more values after us.
735 * Therefore, if there are more defined parameters, the caller didn't
738 if (rightmost && defParm->next)
740 werror (E_TOO_FEW_PARMS);
745 /* the parameter type must be at least castable */
746 if (compareType (defParm->type, actParm->ftype) == 0) {
747 werror (E_INCOMPAT_TYPES);
748 printFromToType (actParm->ftype, defParm->type);
752 /* if the parameter is castable then add the cast */
753 if (compareType (defParm->type, actParm->ftype) < 0)
755 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
757 /* now change the current one to a cast */
758 actParm->type = EX_OP;
759 actParm->opval.op = CAST;
760 actParm->left = newAst_LINK (defParm->type);
761 actParm->right = pTree;
762 actParm->etype = defParm->etype;
763 actParm->ftype = defParm->type;
764 actParm->decorated=0; /* force typechecking */
765 decorateType (actParm);
768 /* make a copy and change the regparm type to the defined parm */
769 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
770 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
774 /*-----------------------------------------------------------------*/
775 /* createIvalType - generates ival for basic types */
776 /*-----------------------------------------------------------------*/
778 createIvalType (ast * sym, sym_link * type, initList * ilist)
782 /* if initList is deep */
783 if (ilist->type == INIT_DEEP)
784 ilist = ilist->init.deep;
786 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
787 return decorateType (newNode ('=', sym, iExpr));
790 /*-----------------------------------------------------------------*/
791 /* createIvalStruct - generates initial value for structures */
792 /*-----------------------------------------------------------------*/
794 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
801 sflds = SPEC_STRUCT (type)->fields;
802 if (ilist->type != INIT_DEEP)
804 werror (E_INIT_STRUCT, "");
808 iloop = ilist->init.deep;
810 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
812 /* if we have come to end */
816 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
817 lAst = decorateType (resolveSymbols (lAst));
818 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
824 /*-----------------------------------------------------------------*/
825 /* createIvalArray - generates code for array initialization */
826 /*-----------------------------------------------------------------*/
828 createIvalArray (ast * sym, sym_link * type, initList * ilist)
832 int lcnt = 0, size = 0;
833 literalList *literalL;
835 /* take care of the special case */
836 /* array of characters can be init */
838 if (IS_CHAR (type->next))
839 if ((rast = createIvalCharPtr (sym,
841 decorateType (resolveSymbols (list2expr (ilist))))))
843 return decorateType (resolveSymbols (rast));
845 /* not the special case */
846 if (ilist->type != INIT_DEEP)
848 werror (E_INIT_STRUCT, "");
852 iloop = ilist->init.deep;
853 lcnt = DCL_ELEM (type);
855 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
859 aSym = decorateType (resolveSymbols(sym));
861 rast = newNode(ARRAYINIT, aSym, NULL);
862 rast->values.constlist = literalL;
864 // Make sure size is set to length of initializer list.
871 if (lcnt && size > lcnt)
873 // Array size was specified, and we have more initializers than needed.
874 char *name=sym->opval.val->sym->name;
875 int lineno=sym->opval.val->sym->lineDef;
877 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
886 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
887 aSym = decorateType (resolveSymbols (aSym));
888 rast = createIval (aSym, type->next, iloop, rast);
889 iloop = (iloop ? iloop->next : NULL);
895 /* no of elements given and we */
896 /* have generated for all of them */
899 // there has to be a better way
900 char *name=sym->opval.val->sym->name;
901 int lineno=sym->opval.val->sym->lineDef;
902 werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
909 /* if we have not been given a size */
910 if (!DCL_ELEM (type))
912 DCL_ELEM (type) = size;
915 return decorateType (resolveSymbols (rast));
919 /*-----------------------------------------------------------------*/
920 /* createIvalCharPtr - generates initial values for char pointers */
921 /*-----------------------------------------------------------------*/
923 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
927 /* if this is a pointer & right is a literal array then */
928 /* just assignment will do */
929 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
930 SPEC_SCLS (iexpr->etype) == S_CODE)
931 && IS_ARRAY (iexpr->ftype)))
932 return newNode ('=', sym, iexpr);
934 /* left side is an array so we have to assign each */
936 if ((IS_LITERAL (iexpr->etype) ||
937 SPEC_SCLS (iexpr->etype) == S_CODE)
938 && IS_ARRAY (iexpr->ftype))
940 /* for each character generate an assignment */
941 /* to the array element */
942 char *s = SPEC_CVAL (iexpr->etype).v_char;
947 rast = newNode (NULLOP,
951 newAst_VALUE (valueFromLit ((float) i))),
952 newAst_VALUE (valueFromLit (*s))));
956 rast = newNode (NULLOP,
960 newAst_VALUE (valueFromLit ((float) i))),
961 newAst_VALUE (valueFromLit (*s))));
962 return decorateType (resolveSymbols (rast));
968 /*-----------------------------------------------------------------*/
969 /* createIvalPtr - generates initial value for pointers */
970 /*-----------------------------------------------------------------*/
972 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
978 if (ilist->type == INIT_DEEP)
979 ilist = ilist->init.deep;
981 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
983 /* if character pointer */
984 if (IS_CHAR (type->next))
985 if ((rast = createIvalCharPtr (sym, type, iexpr)))
988 return newNode ('=', sym, iexpr);
991 /*-----------------------------------------------------------------*/
992 /* createIval - generates code for initial value */
993 /*-----------------------------------------------------------------*/
995 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1002 /* if structure then */
1003 if (IS_STRUCT (type))
1004 rast = createIvalStruct (sym, type, ilist);
1006 /* if this is a pointer */
1008 rast = createIvalPtr (sym, type, ilist);
1010 /* if this is an array */
1011 if (IS_ARRAY (type))
1012 rast = createIvalArray (sym, type, ilist);
1014 /* if type is SPECIFIER */
1016 rast = createIvalType (sym, type, ilist);
1019 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1021 return decorateType (resolveSymbols (rast));
1024 /*-----------------------------------------------------------------*/
1025 /* initAggregates - initialises aggregate variables with initv */
1026 /*-----------------------------------------------------------------*/
1028 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1030 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1034 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1036 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1037 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1038 "with -mmcs51 and --model-large\n");
1042 if (SPEC_OCLS(sym->etype)==xdata &&
1043 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1046 newSym=copySymbol (sym);
1047 SPEC_OCLS(newSym->etype)=code;
1048 sprintf (newSym->name, "%s_init__", sym->name);
1049 sprintf (newSym->rname,"%s_init__", sym->rname);
1050 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1052 // emit it in the static segment
1053 addSet(&statsg->syms, newSym);
1055 // now memcpy() the entire array from cseg
1056 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1057 newAst_VALUE (symbolVal (sym)),
1058 newAst_VALUE (symbolVal (newSym)));
1059 return decorateType(resolveSymbols(ast));
1063 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1066 /*-----------------------------------------------------------------*/
1067 /* gatherAutoInit - creates assignment expressions for initial */
1069 /*-----------------------------------------------------------------*/
1071 gatherAutoInit (symbol * autoChain)
1078 for (sym = autoChain; sym; sym = sym->next)
1081 /* resolve the symbols in the ival */
1083 resolveIvalSym (sym->ival);
1085 /* if this is a static variable & has an */
1086 /* initial value the code needs to be lifted */
1087 /* here to the main portion since they can be */
1088 /* initialised only once at the start */
1089 if (IS_STATIC (sym->etype) && sym->ival &&
1090 SPEC_SCLS (sym->etype) != S_CODE)
1094 // this can only be a constant
1095 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1096 werror (E_CONST_EXPECTED);
1099 /* insert the symbol into the symbol table */
1100 /* with level = 0 & name = rname */
1101 newSym = copySymbol (sym);
1102 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1104 /* now lift the code to main */
1105 if (IS_AGGREGATE (sym->type))
1106 work = initAggregates (sym, sym->ival, NULL);
1108 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1109 list2expr (sym->ival));
1111 setAstLineno (work, sym->lineDef);
1115 staticAutos = newNode (NULLOP, staticAutos, work);
1122 /* if there is an initial value */
1123 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1125 if (IS_AGGREGATE (sym->type))
1126 work = initAggregates (sym, sym->ival, NULL);
1128 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1129 list2expr (sym->ival));
1131 setAstLineno (work, sym->lineDef);
1134 init = newNode (NULLOP, init, work);
1143 /*-----------------------------------------------------------------*/
1144 /* stringToSymbol - creates a symbol from a literal string */
1145 /*-----------------------------------------------------------------*/
1147 stringToSymbol (value * val)
1149 char name[SDCC_NAME_MAX + 1];
1150 static int charLbl = 0;
1153 sprintf (name, "_str_%d", charLbl++);
1154 sym = newSymbol (name, 0); /* make it @ level 0 */
1155 strcpy (sym->rname, name);
1157 /* copy the type from the value passed */
1158 sym->type = copyLinkChain (val->type);
1159 sym->etype = getSpec (sym->type);
1160 /* change to storage class & output class */
1161 SPEC_SCLS (sym->etype) = S_CODE;
1162 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1163 SPEC_STAT (sym->etype) = 1;
1164 /* make the level & block = 0 */
1165 sym->block = sym->level = 0;
1167 /* create an ival */
1168 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1173 allocVariables (sym);
1176 return symbolVal (sym);
1180 /*-----------------------------------------------------------------*/
1181 /* processBlockVars - will go thru the ast looking for block if */
1182 /* a block is found then will allocate the syms */
1183 /* will also gather the auto inits present */
1184 /*-----------------------------------------------------------------*/
1186 processBlockVars (ast * tree, int *stack, int action)
1191 /* if this is a block */
1192 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1196 if (action == ALLOCATE)
1198 *stack += allocVariables (tree->values.sym);
1199 autoInit = gatherAutoInit (tree->values.sym);
1201 /* if there are auto inits then do them */
1203 tree->left = newNode (NULLOP, autoInit, tree->left);
1205 else /* action is deallocate */
1206 deallocLocal (tree->values.sym);
1209 processBlockVars (tree->left, stack, action);
1210 processBlockVars (tree->right, stack, action);
1214 /*-----------------------------------------------------------------*/
1215 /* constExprValue - returns the value of a constant expression */
1216 /* or NULL if it is not a constant expression */
1217 /*-----------------------------------------------------------------*/
1219 constExprValue (ast * cexpr, int check)
1221 cexpr = decorateType (resolveSymbols (cexpr));
1223 /* if this is not a constant then */
1224 if (!IS_LITERAL (cexpr->ftype))
1226 /* then check if this is a literal array
1228 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1229 SPEC_CVAL (cexpr->etype).v_char &&
1230 IS_ARRAY (cexpr->ftype))
1232 value *val = valFromType (cexpr->ftype);
1233 SPEC_SCLS (val->etype) = S_LITERAL;
1234 val->sym = cexpr->opval.val->sym;
1235 val->sym->type = copyLinkChain (cexpr->ftype);
1236 val->sym->etype = getSpec (val->sym->type);
1237 strcpy (val->name, cexpr->opval.val->sym->rname);
1241 /* if we are casting a literal value then */
1242 if (IS_AST_OP (cexpr) &&
1243 cexpr->opval.op == CAST &&
1244 IS_LITERAL (cexpr->left->ftype))
1245 return valCastLiteral (cexpr->ftype,
1246 floatFromVal (cexpr->left->opval.val));
1248 if (IS_AST_VALUE (cexpr))
1249 return cexpr->opval.val;
1252 werror (E_CONST_EXPECTED, "found expression");
1257 /* return the value */
1258 return cexpr->opval.val;
1262 /*-----------------------------------------------------------------*/
1263 /* isLabelInAst - will return true if a given label is found */
1264 /*-----------------------------------------------------------------*/
1266 isLabelInAst (symbol * label, ast * tree)
1268 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1271 if (IS_AST_OP (tree) &&
1272 tree->opval.op == LABEL &&
1273 isSymbolEqual (AST_SYMBOL (tree->left), label))
1276 return isLabelInAst (label, tree->right) &&
1277 isLabelInAst (label, tree->left);
1281 /*-----------------------------------------------------------------*/
1282 /* isLoopCountable - return true if the loop count can be determi- */
1283 /* -ned at compile time . */
1284 /*-----------------------------------------------------------------*/
1286 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1287 symbol ** sym, ast ** init, ast ** end)
1290 /* the loop is considered countable if the following
1291 conditions are true :-
1293 a) initExpr :- <sym> = <const>
1294 b) condExpr :- <sym> < <const1>
1295 c) loopExpr :- <sym> ++
1298 /* first check the initExpr */
1299 if (IS_AST_OP (initExpr) &&
1300 initExpr->opval.op == '=' && /* is assignment */
1301 IS_AST_SYM_VALUE (initExpr->left))
1302 { /* left is a symbol */
1304 *sym = AST_SYMBOL (initExpr->left);
1305 *init = initExpr->right;
1310 /* for now the symbol has to be of
1312 if (!IS_INTEGRAL ((*sym)->type))
1315 /* now check condExpr */
1316 if (IS_AST_OP (condExpr))
1319 switch (condExpr->opval.op)
1322 if (IS_AST_SYM_VALUE (condExpr->left) &&
1323 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1324 IS_AST_LIT_VALUE (condExpr->right))
1326 *end = condExpr->right;
1332 if (IS_AST_OP (condExpr->left) &&
1333 condExpr->left->opval.op == '>' &&
1334 IS_AST_LIT_VALUE (condExpr->left->right) &&
1335 IS_AST_SYM_VALUE (condExpr->left->left) &&
1336 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1339 *end = newNode ('+', condExpr->left->right,
1340 newAst_VALUE (constVal ("1")));
1351 /* check loop expression is of the form <sym>++ */
1352 if (!IS_AST_OP (loopExpr))
1355 /* check if <sym> ++ */
1356 if (loopExpr->opval.op == INC_OP)
1362 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1363 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1370 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1371 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1379 if (loopExpr->opval.op == ADD_ASSIGN)
1382 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1383 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1384 IS_AST_LIT_VALUE (loopExpr->right) &&
1385 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1393 /*-----------------------------------------------------------------*/
1394 /* astHasVolatile - returns true if ast contains any volatile */
1395 /*-----------------------------------------------------------------*/
1397 astHasVolatile (ast * tree)
1402 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1405 if (IS_AST_OP (tree))
1406 return astHasVolatile (tree->left) ||
1407 astHasVolatile (tree->right);
1412 /*-----------------------------------------------------------------*/
1413 /* astHasPointer - return true if the ast contains any ptr variable */
1414 /*-----------------------------------------------------------------*/
1416 astHasPointer (ast * tree)
1421 if (IS_AST_LINK (tree))
1424 /* if we hit an array expression then check
1425 only the left side */
1426 if (IS_AST_OP (tree) && tree->opval.op == '[')
1427 return astHasPointer (tree->left);
1429 if (IS_AST_VALUE (tree))
1430 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1432 return astHasPointer (tree->left) ||
1433 astHasPointer (tree->right);
1437 /*-----------------------------------------------------------------*/
1438 /* astHasSymbol - return true if the ast has the given symbol */
1439 /*-----------------------------------------------------------------*/
1441 astHasSymbol (ast * tree, symbol * sym)
1443 if (!tree || IS_AST_LINK (tree))
1446 if (IS_AST_VALUE (tree))
1448 if (IS_AST_SYM_VALUE (tree))
1449 return isSymbolEqual (AST_SYMBOL (tree), sym);
1454 return astHasSymbol (tree->left, sym) ||
1455 astHasSymbol (tree->right, sym);
1458 /*-----------------------------------------------------------------*/
1459 /* astHasDeref - return true if the ast has an indirect access */
1460 /*-----------------------------------------------------------------*/
1462 astHasDeref (ast * tree)
1464 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1467 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1469 return astHasDeref (tree->left) || astHasDeref (tree->right);
1472 /*-----------------------------------------------------------------*/
1473 /* isConformingBody - the loop body has to conform to a set of rules */
1474 /* for the loop to be considered reversible read on for rules */
1475 /*-----------------------------------------------------------------*/
1477 isConformingBody (ast * pbody, symbol * sym, ast * body)
1480 /* we are going to do a pre-order traversal of the
1481 tree && check for the following conditions. (essentially
1482 a set of very shallow tests )
1483 a) the sym passed does not participate in
1484 any arithmetic operation
1485 b) There are no function calls
1486 c) all jumps are within the body
1487 d) address of loop control variable not taken
1488 e) if an assignment has a pointer on the
1489 left hand side make sure right does not have
1490 loop control variable */
1492 /* if we reach the end or a leaf then true */
1493 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1497 /* if anything else is "volatile" */
1498 if (IS_VOLATILE (TETYPE (pbody)))
1501 /* we will walk the body in a pre-order traversal for
1503 switch (pbody->opval.op)
1505 /*------------------------------------------------------------------*/
1507 return isConformingBody (pbody->right, sym, body);
1509 /*------------------------------------------------------------------*/
1514 /*------------------------------------------------------------------*/
1515 case INC_OP: /* incerement operator unary so left only */
1518 /* sure we are not sym is not modified */
1520 IS_AST_SYM_VALUE (pbody->left) &&
1521 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1525 IS_AST_SYM_VALUE (pbody->right) &&
1526 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1531 /*------------------------------------------------------------------*/
1533 case '*': /* can be unary : if right is null then unary operation */
1538 /* if right is NULL then unary operation */
1539 /*------------------------------------------------------------------*/
1540 /*----------------------------*/
1542 /*----------------------------*/
1545 if (IS_AST_SYM_VALUE (pbody->left) &&
1546 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1549 return isConformingBody (pbody->left, sym, body);
1553 if (astHasSymbol (pbody->left, sym) ||
1554 astHasSymbol (pbody->right, sym))
1559 /*------------------------------------------------------------------*/
1567 if (IS_AST_SYM_VALUE (pbody->left) &&
1568 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1571 if (IS_AST_SYM_VALUE (pbody->right) &&
1572 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1575 return isConformingBody (pbody->left, sym, body) &&
1576 isConformingBody (pbody->right, sym, body);
1583 if (IS_AST_SYM_VALUE (pbody->left) &&
1584 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1586 return isConformingBody (pbody->left, sym, body);
1588 /*------------------------------------------------------------------*/
1600 case SIZEOF: /* evaluate wihout code generation */
1602 return isConformingBody (pbody->left, sym, body) &&
1603 isConformingBody (pbody->right, sym, body);
1605 /*------------------------------------------------------------------*/
1608 /* if left has a pointer & right has loop
1609 control variable then we cannot */
1610 if (astHasPointer (pbody->left) &&
1611 astHasSymbol (pbody->right, sym))
1613 if (astHasVolatile (pbody->left))
1616 if (IS_AST_SYM_VALUE (pbody->left) &&
1617 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1620 if (astHasVolatile (pbody->left))
1623 if (astHasDeref(pbody->right)) return FALSE;
1625 return isConformingBody (pbody->left, sym, body) &&
1626 isConformingBody (pbody->right, sym, body);
1637 assert ("Parser should not have generated this\n");
1639 /*------------------------------------------------------------------*/
1640 /*----------------------------*/
1641 /* comma operator */
1642 /*----------------------------*/
1644 return isConformingBody (pbody->left, sym, body) &&
1645 isConformingBody (pbody->right, sym, body);
1647 /*------------------------------------------------------------------*/
1648 /*----------------------------*/
1650 /*----------------------------*/
1654 /*------------------------------------------------------------------*/
1655 /*----------------------------*/
1656 /* return statement */
1657 /*----------------------------*/
1662 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1667 if (astHasSymbol (pbody->left, sym))
1674 return isConformingBody (pbody->left, sym, body) &&
1675 isConformingBody (pbody->right, sym, body);
1681 /*-----------------------------------------------------------------*/
1682 /* isLoopReversible - takes a for loop as input && returns true */
1683 /* if the for loop is reversible. If yes will set the value of */
1684 /* the loop control var & init value & termination value */
1685 /*-----------------------------------------------------------------*/
1687 isLoopReversible (ast * loop, symbol ** loopCntrl,
1688 ast ** init, ast ** end)
1690 /* if option says don't do it then don't */
1691 if (optimize.noLoopReverse)
1693 /* there are several tests to determine this */
1695 /* for loop has to be of the form
1696 for ( <sym> = <const1> ;
1697 [<sym> < <const2>] ;
1698 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1700 if (!isLoopCountable (AST_FOR (loop, initExpr),
1701 AST_FOR (loop, condExpr),
1702 AST_FOR (loop, loopExpr),
1703 loopCntrl, init, end))
1706 /* now do some serious checking on the body of the loop
1709 return isConformingBody (loop->left, *loopCntrl, loop->left);
1713 /*-----------------------------------------------------------------*/
1714 /* replLoopSym - replace the loop sym by loop sym -1 */
1715 /*-----------------------------------------------------------------*/
1717 replLoopSym (ast * body, symbol * sym)
1720 if (!body || IS_AST_LINK (body))
1723 if (IS_AST_SYM_VALUE (body))
1726 if (isSymbolEqual (AST_SYMBOL (body), sym))
1730 body->opval.op = '-';
1731 body->left = newAst_VALUE (symbolVal (sym));
1732 body->right = newAst_VALUE (constVal ("1"));
1740 replLoopSym (body->left, sym);
1741 replLoopSym (body->right, sym);
1745 /*-----------------------------------------------------------------*/
1746 /* reverseLoop - do the actual loop reversal */
1747 /*-----------------------------------------------------------------*/
1749 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1753 /* create the following tree
1758 if (sym) goto for_continue ;
1761 /* put it together piece by piece */
1762 rloop = newNode (NULLOP,
1763 createIf (newAst_VALUE (symbolVal (sym)),
1765 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1768 newAst_VALUE (symbolVal (sym)),
1771 replLoopSym (loop->left, sym);
1773 rloop = newNode (NULLOP,
1775 newAst_VALUE (symbolVal (sym)),
1776 newNode ('-', end, init)),
1777 createLabel (AST_FOR (loop, continueLabel),
1781 newNode (SUB_ASSIGN,
1782 newAst_VALUE (symbolVal (sym)),
1783 newAst_VALUE (constVal ("1"))),
1786 return decorateType (rloop);
1790 //#define DEMAND_INTEGER_PROMOTION
1792 #ifdef DEMAND_INTEGER_PROMOTION
1794 /*-----------------------------------------------------------------*/
1795 /* walk a tree looking for the leaves. Add a typecast to the given */
1796 /* type to each value leaf node. */
1797 /*-----------------------------------------------------------------*/
1799 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1801 if (!node || IS_CALLOP(node))
1803 /* WTF? We should never get here. */
1807 if (!node->left && !node->right)
1809 /* We're at a leaf; if it's a value, apply the typecast */
1810 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1812 *parentPtr = decorateType (newNode (CAST,
1813 newAst_LINK (copyLinkChain (type)),
1821 pushTypeCastToLeaves (type, node->left, &(node->left));
1825 pushTypeCastToLeaves (type, node->right, &(node->right));
1832 /*-----------------------------------------------------------------*/
1833 /* decorateType - compute type for this tree also does type cheking */
1834 /* this is done bottom up, since type have to flow upwards */
1835 /* it also does constant folding, and paramater checking */
1836 /*-----------------------------------------------------------------*/
1838 decorateType (ast * tree)
1846 /* if already has type then do nothing */
1847 if (tree->decorated)
1850 tree->decorated = 1;
1852 /* print the line */
1853 /* if not block & function */
1854 if (tree->type == EX_OP &&
1855 (tree->opval.op != FUNCTION &&
1856 tree->opval.op != BLOCK &&
1857 tree->opval.op != NULLOP))
1859 filename = tree->filename;
1860 lineno = tree->lineno;
1863 /* if any child is an error | this one is an error do nothing */
1864 if (tree->isError ||
1865 (tree->left && tree->left->isError) ||
1866 (tree->right && tree->right->isError))
1869 /*------------------------------------------------------------------*/
1870 /*----------------------------*/
1871 /* leaf has been reached */
1872 /*----------------------------*/
1873 /* if this is of type value */
1874 /* just get the type */
1875 if (tree->type == EX_VALUE)
1878 if (IS_LITERAL (tree->opval.val->etype))
1881 /* if this is a character array then declare it */
1882 if (IS_ARRAY (tree->opval.val->type))
1883 tree->opval.val = stringToSymbol (tree->opval.val);
1885 /* otherwise just copy the type information */
1886 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1890 if (tree->opval.val->sym)
1892 /* if the undefined flag is set then give error message */
1893 if (tree->opval.val->sym->undefined)
1895 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1897 TTYPE (tree) = TETYPE (tree) =
1898 tree->opval.val->type = tree->opval.val->sym->type =
1899 tree->opval.val->etype = tree->opval.val->sym->etype =
1900 copyLinkChain (INTTYPE);
1905 /* if impilicit i.e. struct/union member then no type */
1906 if (tree->opval.val->sym->implicit)
1907 TTYPE (tree) = TETYPE (tree) = NULL;
1912 /* else copy the type */
1913 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1915 /* and mark it as referenced */
1916 tree->opval.val->sym->isref = 1;
1924 /* if type link for the case of cast */
1925 if (tree->type == EX_LINK)
1927 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1934 dtl = decorateType (tree->left);
1935 dtr = decorateType (tree->right);
1937 /* this is to take care of situations
1938 when the tree gets rewritten */
1939 if (dtl != tree->left)
1941 if (dtr != tree->right)
1945 /* depending on type of operator do */
1947 switch (tree->opval.op)
1949 /*------------------------------------------------------------------*/
1950 /*----------------------------*/
1952 /*----------------------------*/
1955 /* determine which is the array & which the index */
1956 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1959 ast *tempTree = tree->left;
1960 tree->left = tree->right;
1961 tree->right = tempTree;
1964 /* first check if this is a array or a pointer */
1965 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1967 werror (E_NEED_ARRAY_PTR, "[]");
1968 goto errorTreeReturn;
1971 /* check if the type of the idx */
1972 if (!IS_INTEGRAL (RTYPE (tree)))
1974 werror (E_IDX_NOT_INT);
1975 goto errorTreeReturn;
1978 /* if the left is an rvalue then error */
1981 werror (E_LVALUE_REQUIRED, "array access");
1982 goto errorTreeReturn;
1985 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1986 if (IS_PTR(LTYPE(tree))) {
1987 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1991 /*------------------------------------------------------------------*/
1992 /*----------------------------*/
1994 /*----------------------------*/
1996 /* if this is not a structure */
1997 if (!IS_STRUCT (LTYPE (tree)))
1999 werror (E_STRUCT_UNION, ".");
2000 goto errorTreeReturn;
2002 TTYPE (tree) = structElemType (LTYPE (tree),
2003 (tree->right->type == EX_VALUE ?
2004 tree->right->opval.val : NULL));
2005 TETYPE (tree) = getSpec (TTYPE (tree));
2008 /*------------------------------------------------------------------*/
2009 /*----------------------------*/
2010 /* struct/union pointer */
2011 /*----------------------------*/
2013 /* if not pointer to a structure */
2014 if (!IS_PTR (LTYPE (tree)))
2016 werror (E_PTR_REQD);
2017 goto errorTreeReturn;
2020 if (!IS_STRUCT (LTYPE (tree)->next))
2022 werror (E_STRUCT_UNION, "->");
2023 goto errorTreeReturn;
2026 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2027 (tree->right->type == EX_VALUE ?
2028 tree->right->opval.val : NULL));
2029 TETYPE (tree) = getSpec (TTYPE (tree));
2032 /*------------------------------------------------------------------*/
2033 /*----------------------------*/
2034 /* ++/-- operation */
2035 /*----------------------------*/
2036 case INC_OP: /* incerement operator unary so left only */
2039 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2040 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2041 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2042 werror (E_CODE_WRITE, "++/--");
2051 /*------------------------------------------------------------------*/
2052 /*----------------------------*/
2054 /*----------------------------*/
2055 case '&': /* can be unary */
2056 /* if right is NULL then unary operation */
2057 if (tree->right) /* not an unary operation */
2060 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2062 werror (E_BITWISE_OP);
2063 werror (W_CONTINUE, "left & right types are ");
2064 printTypeChain (LTYPE (tree), stderr);
2065 fprintf (stderr, ",");
2066 printTypeChain (RTYPE (tree), stderr);
2067 fprintf (stderr, "\n");
2068 goto errorTreeReturn;
2071 /* if they are both literal */
2072 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2074 tree->type = EX_VALUE;
2075 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2076 valFromType (RETYPE (tree)), '&');
2078 tree->right = tree->left = NULL;
2079 TETYPE (tree) = tree->opval.val->etype;
2080 TTYPE (tree) = tree->opval.val->type;
2084 /* see if this is a GETHBIT operation if yes
2087 ast *otree = optimizeGetHbit (tree);
2090 return decorateType (otree);
2094 computeType (LTYPE (tree), RTYPE (tree));
2095 TETYPE (tree) = getSpec (TTYPE (tree));
2097 LRVAL (tree) = RRVAL (tree) = 1;
2101 /*------------------------------------------------------------------*/
2102 /*----------------------------*/
2104 /*----------------------------*/
2106 p->class = DECLARATOR;
2107 /* if bit field then error */
2108 if (IS_BITVAR (tree->left->etype))
2110 werror (E_ILLEGAL_ADDR, "address of bit variable");
2111 goto errorTreeReturn;
2114 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2116 werror (E_ILLEGAL_ADDR, "address of register variable");
2117 goto errorTreeReturn;
2120 if (IS_FUNC (LTYPE (tree)))
2122 werror (E_ILLEGAL_ADDR, "address of function");
2123 goto errorTreeReturn;
2126 if (IS_LITERAL(LTYPE(tree)))
2128 werror (E_ILLEGAL_ADDR, "address of literal");
2129 goto errorTreeReturn;
2134 werror (E_LVALUE_REQUIRED, "address of");
2135 goto errorTreeReturn;
2137 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2139 DCL_TYPE (p) = CPOINTER;
2140 DCL_PTR_CONST (p) = port->mem.code_ro;
2142 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2143 DCL_TYPE (p) = FPOINTER;
2144 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2145 DCL_TYPE (p) = PPOINTER;
2146 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2147 DCL_TYPE (p) = IPOINTER;
2148 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2149 DCL_TYPE (p) = EEPPOINTER;
2151 DCL_TYPE (p) = POINTER;
2153 if (IS_AST_SYM_VALUE (tree->left))
2155 AST_SYMBOL (tree->left)->addrtaken = 1;
2156 AST_SYMBOL (tree->left)->allocreq = 1;
2159 p->next = LTYPE (tree);
2161 TETYPE (tree) = getSpec (TTYPE (tree));
2162 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2163 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2168 /*------------------------------------------------------------------*/
2169 /*----------------------------*/
2171 /*----------------------------*/
2173 /* if the rewrite succeeds then don't go any furthur */
2175 ast *wtree = optimizeRRCRLC (tree);
2177 return decorateType (wtree);
2179 /*------------------------------------------------------------------*/
2180 /*----------------------------*/
2182 /*----------------------------*/
2184 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2186 werror (E_BITWISE_OP);
2187 werror (W_CONTINUE, "left & right types are ");
2188 printTypeChain (LTYPE (tree), stderr);
2189 fprintf (stderr, ",");
2190 printTypeChain (RTYPE (tree), stderr);
2191 fprintf (stderr, "\n");
2192 goto errorTreeReturn;
2195 /* if they are both literal then */
2196 /* rewrite the tree */
2197 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2199 tree->type = EX_VALUE;
2200 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2201 valFromType (RETYPE (tree)),
2203 tree->right = tree->left = NULL;
2204 TETYPE (tree) = tree->opval.val->etype;
2205 TTYPE (tree) = tree->opval.val->type;
2208 LRVAL (tree) = RRVAL (tree) = 1;
2209 TETYPE (tree) = getSpec (TTYPE (tree) =
2210 computeType (LTYPE (tree),
2213 /*------------------------------------------------------------------*/
2214 /*----------------------------*/
2216 /*----------------------------*/
2218 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2220 werror (E_INVALID_OP, "divide");
2221 goto errorTreeReturn;
2223 /* if they are both literal then */
2224 /* rewrite the tree */
2225 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2227 tree->type = EX_VALUE;
2228 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2229 valFromType (RETYPE (tree)));
2230 tree->right = tree->left = NULL;
2231 TETYPE (tree) = getSpec (TTYPE (tree) =
2232 tree->opval.val->type);
2235 LRVAL (tree) = RRVAL (tree) = 1;
2236 TETYPE (tree) = getSpec (TTYPE (tree) =
2237 computeType (LTYPE (tree),
2241 /*------------------------------------------------------------------*/
2242 /*----------------------------*/
2244 /*----------------------------*/
2246 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2248 werror (E_BITWISE_OP);
2249 werror (W_CONTINUE, "left & right types are ");
2250 printTypeChain (LTYPE (tree), stderr);
2251 fprintf (stderr, ",");
2252 printTypeChain (RTYPE (tree), stderr);
2253 fprintf (stderr, "\n");
2254 goto errorTreeReturn;
2256 /* if they are both literal then */
2257 /* rewrite the tree */
2258 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2260 tree->type = EX_VALUE;
2261 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2262 valFromType (RETYPE (tree)));
2263 tree->right = tree->left = NULL;
2264 TETYPE (tree) = getSpec (TTYPE (tree) =
2265 tree->opval.val->type);
2268 LRVAL (tree) = RRVAL (tree) = 1;
2269 TETYPE (tree) = getSpec (TTYPE (tree) =
2270 computeType (LTYPE (tree),
2274 /*------------------------------------------------------------------*/
2275 /*----------------------------*/
2276 /* address dereference */
2277 /*----------------------------*/
2278 case '*': /* can be unary : if right is null then unary operation */
2281 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2283 werror (E_PTR_REQD);
2284 goto errorTreeReturn;
2289 werror (E_LVALUE_REQUIRED, "pointer deref");
2290 goto errorTreeReturn;
2292 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2293 LTYPE (tree)->next : NULL);
2294 TETYPE (tree) = getSpec (TTYPE (tree));
2295 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2299 /*------------------------------------------------------------------*/
2300 /*----------------------------*/
2301 /* multiplication */
2302 /*----------------------------*/
2303 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2305 werror (E_INVALID_OP, "multiplication");
2306 goto errorTreeReturn;
2309 /* if they are both literal then */
2310 /* rewrite the tree */
2311 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2313 tree->type = EX_VALUE;
2314 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2315 valFromType (RETYPE (tree)));
2316 tree->right = tree->left = NULL;
2317 TETYPE (tree) = getSpec (TTYPE (tree) =
2318 tree->opval.val->type);
2322 /* if left is a literal exchange left & right */
2323 if (IS_LITERAL (LTYPE (tree)))
2325 ast *tTree = tree->left;
2326 tree->left = tree->right;
2327 tree->right = tTree;
2330 LRVAL (tree) = RRVAL (tree) = 1;
2331 /* promote result to int if left & right are char
2332 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2333 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2334 TETYPE (tree) = getSpec (TTYPE (tree) =
2335 computeType (LTYPE (tree),
2337 SPEC_NOUN(TETYPE(tree)) = V_INT;
2339 TETYPE (tree) = getSpec (TTYPE (tree) =
2340 computeType (LTYPE (tree),
2345 /*------------------------------------------------------------------*/
2346 /*----------------------------*/
2347 /* unary '+' operator */
2348 /*----------------------------*/
2353 if (!IS_INTEGRAL (LTYPE (tree)))
2355 werror (E_UNARY_OP, '+');
2356 goto errorTreeReturn;
2359 /* if left is a literal then do it */
2360 if (IS_LITERAL (LTYPE (tree)))
2362 tree->type = EX_VALUE;
2363 tree->opval.val = valFromType (LETYPE (tree));
2365 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2369 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2373 /*------------------------------------------------------------------*/
2374 /*----------------------------*/
2376 /*----------------------------*/
2378 /* this is not a unary operation */
2379 /* if both pointers then problem */
2380 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2381 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2383 werror (E_PTR_PLUS_PTR);
2384 goto errorTreeReturn;
2387 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2388 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2390 werror (E_PLUS_INVALID, "+");
2391 goto errorTreeReturn;
2394 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2395 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2397 werror (E_PLUS_INVALID, "+");
2398 goto errorTreeReturn;
2400 /* if they are both literal then */
2401 /* rewrite the tree */
2402 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2404 tree->type = EX_VALUE;
2405 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2406 valFromType (RETYPE (tree)));
2407 tree->right = tree->left = NULL;
2408 TETYPE (tree) = getSpec (TTYPE (tree) =
2409 tree->opval.val->type);
2413 /* if the right is a pointer or left is a literal
2414 xchange left & right */
2415 if (IS_ARRAY (RTYPE (tree)) ||
2416 IS_PTR (RTYPE (tree)) ||
2417 IS_LITERAL (LTYPE (tree)))
2419 ast *tTree = tree->left;
2420 tree->left = tree->right;
2421 tree->right = tTree;
2424 LRVAL (tree) = RRVAL (tree) = 1;
2425 /* if the left is a pointer */
2426 if (IS_PTR (LTYPE (tree)))
2427 TETYPE (tree) = getSpec (TTYPE (tree) =
2430 TETYPE (tree) = getSpec (TTYPE (tree) =
2431 computeType (LTYPE (tree),
2435 /*------------------------------------------------------------------*/
2436 /*----------------------------*/
2438 /*----------------------------*/
2439 case '-': /* can be unary */
2440 /* if right is null then unary */
2444 if (!IS_ARITHMETIC (LTYPE (tree)))
2446 werror (E_UNARY_OP, tree->opval.op);
2447 goto errorTreeReturn;
2450 /* if left is a literal then do it */
2451 if (IS_LITERAL (LTYPE (tree)))
2453 tree->type = EX_VALUE;
2454 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2456 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2457 SPEC_USIGN(TETYPE(tree)) = 0;
2461 TTYPE (tree) = LTYPE (tree);
2465 /*------------------------------------------------------------------*/
2466 /*----------------------------*/
2468 /*----------------------------*/
2470 if (!(IS_PTR (LTYPE (tree)) ||
2471 IS_ARRAY (LTYPE (tree)) ||
2472 IS_ARITHMETIC (LTYPE (tree))))
2474 werror (E_PLUS_INVALID, "-");
2475 goto errorTreeReturn;
2478 if (!(IS_PTR (RTYPE (tree)) ||
2479 IS_ARRAY (RTYPE (tree)) ||
2480 IS_ARITHMETIC (RTYPE (tree))))
2482 werror (E_PLUS_INVALID, "-");
2483 goto errorTreeReturn;
2486 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2487 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2488 IS_INTEGRAL (RTYPE (tree))))
2490 werror (E_PLUS_INVALID, "-");
2491 goto errorTreeReturn;
2494 /* if they are both literal then */
2495 /* rewrite the tree */
2496 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2498 tree->type = EX_VALUE;
2499 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2500 valFromType (RETYPE (tree)));
2501 tree->right = tree->left = NULL;
2502 TETYPE (tree) = getSpec (TTYPE (tree) =
2503 tree->opval.val->type);
2507 /* if the left & right are equal then zero */
2508 if (isAstEqual (tree->left, tree->right))
2510 tree->type = EX_VALUE;
2511 tree->left = tree->right = NULL;
2512 tree->opval.val = constVal ("0");
2513 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2517 /* if both of them are pointers or arrays then */
2518 /* the result is going to be an integer */
2519 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2520 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2521 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2523 /* if only the left is a pointer */
2524 /* then result is a pointer */
2525 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2526 TETYPE (tree) = getSpec (TTYPE (tree) =
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2530 computeType (LTYPE (tree),
2532 LRVAL (tree) = RRVAL (tree) = 1;
2535 /*------------------------------------------------------------------*/
2536 /*----------------------------*/
2538 /*----------------------------*/
2540 /* can be only integral type */
2541 if (!IS_INTEGRAL (LTYPE (tree)))
2543 werror (E_UNARY_OP, tree->opval.op);
2544 goto errorTreeReturn;
2547 /* if left is a literal then do it */
2548 if (IS_LITERAL (LTYPE (tree)))
2550 tree->type = EX_VALUE;
2551 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2553 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2557 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2560 /*------------------------------------------------------------------*/
2561 /*----------------------------*/
2563 /*----------------------------*/
2565 /* can be pointer */
2566 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2567 !IS_PTR (LTYPE (tree)) &&
2568 !IS_ARRAY (LTYPE (tree)))
2570 werror (E_UNARY_OP, tree->opval.op);
2571 goto errorTreeReturn;
2574 /* if left is a literal then do it */
2575 if (IS_LITERAL (LTYPE (tree)))
2577 tree->type = EX_VALUE;
2578 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2580 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2584 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2587 /*------------------------------------------------------------------*/
2588 /*----------------------------*/
2590 /*----------------------------*/
2593 TTYPE (tree) = LTYPE (tree);
2594 TETYPE (tree) = LETYPE (tree);
2598 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2603 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2605 werror (E_SHIFT_OP_INVALID);
2606 werror (W_CONTINUE, "left & right types are ");
2607 printTypeChain (LTYPE (tree), stderr);
2608 fprintf (stderr, ",");
2609 printTypeChain (RTYPE (tree), stderr);
2610 fprintf (stderr, "\n");
2611 goto errorTreeReturn;
2614 /* if they are both literal then */
2615 /* rewrite the tree */
2616 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2618 tree->type = EX_VALUE;
2619 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2620 valFromType (RETYPE (tree)),
2621 (tree->opval.op == LEFT_OP ? 1 : 0));
2622 tree->right = tree->left = NULL;
2623 TETYPE (tree) = getSpec (TTYPE (tree) =
2624 tree->opval.val->type);
2627 /* if only the right side is a literal & we are
2628 shifting more than size of the left operand then zero */
2629 if (IS_LITERAL (RTYPE (tree)) &&
2630 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2631 (getSize (LTYPE (tree)) * 8))
2633 werror (W_SHIFT_CHANGED,
2634 (tree->opval.op == LEFT_OP ? "left" : "right"));
2635 tree->type = EX_VALUE;
2636 tree->left = tree->right = NULL;
2637 tree->opval.val = constVal ("0");
2638 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2641 LRVAL (tree) = RRVAL (tree) = 1;
2642 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2644 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2648 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2652 /*------------------------------------------------------------------*/
2653 /*----------------------------*/
2655 /*----------------------------*/
2656 case CAST: /* change the type */
2657 /* cannot cast to an aggregate type */
2658 if (IS_AGGREGATE (LTYPE (tree)))
2660 werror (E_CAST_ILLEGAL);
2661 goto errorTreeReturn;
2664 /* make sure the type is complete and sane */
2665 checkTypeSanity(LETYPE(tree), "(cast)");
2668 /* if the right is a literal replace the tree */
2669 if (IS_LITERAL (RETYPE (tree))) {
2670 if (!IS_PTR (LTYPE (tree))) {
2671 tree->type = EX_VALUE;
2673 valCastLiteral (LTYPE (tree),
2674 floatFromVal (valFromType (RETYPE (tree))));
2677 TTYPE (tree) = tree->opval.val->type;
2678 tree->values.literalFromCast = 1;
2679 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2680 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2681 sym_link *rest = LTYPE(tree)->next;
2682 werror(W_LITERAL_GENERIC);
2683 TTYPE(tree) = newLink();
2684 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2685 TTYPE(tree)->next = rest;
2686 tree->left->opval.lnk = TTYPE(tree);
2689 TTYPE (tree) = LTYPE (tree);
2693 TTYPE (tree) = LTYPE (tree);
2697 /* if pointer to struct then check names */
2698 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2699 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2700 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2701 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2703 /* if the right is a literal replace the tree */
2704 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2705 tree->type = EX_VALUE;
2707 valCastLiteral (LTYPE (tree),
2708 floatFromVal (valFromType (RETYPE (tree))));
2711 TTYPE (tree) = tree->opval.val->type;
2712 tree->values.literalFromCast = 1;
2714 TTYPE (tree) = LTYPE (tree);
2718 TETYPE (tree) = getSpec (TTYPE (tree));
2722 /*------------------------------------------------------------------*/
2723 /*----------------------------*/
2724 /* logical &&, || */
2725 /*----------------------------*/
2728 /* each must me arithmetic type or be a pointer */
2729 if (!IS_PTR (LTYPE (tree)) &&
2730 !IS_ARRAY (LTYPE (tree)) &&
2731 !IS_INTEGRAL (LTYPE (tree)))
2733 werror (E_COMPARE_OP);
2734 goto errorTreeReturn;
2737 if (!IS_PTR (RTYPE (tree)) &&
2738 !IS_ARRAY (RTYPE (tree)) &&
2739 !IS_INTEGRAL (RTYPE (tree)))
2741 werror (E_COMPARE_OP);
2742 goto errorTreeReturn;
2744 /* if they are both literal then */
2745 /* rewrite the tree */
2746 if (IS_LITERAL (RTYPE (tree)) &&
2747 IS_LITERAL (LTYPE (tree)))
2749 tree->type = EX_VALUE;
2750 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2751 valFromType (RETYPE (tree)),
2753 tree->right = tree->left = NULL;
2754 TETYPE (tree) = getSpec (TTYPE (tree) =
2755 tree->opval.val->type);
2758 LRVAL (tree) = RRVAL (tree) = 1;
2759 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2762 /*------------------------------------------------------------------*/
2763 /*----------------------------*/
2764 /* comparison operators */
2765 /*----------------------------*/
2773 ast *lt = optimizeCompare (tree);
2779 /* if they are pointers they must be castable */
2780 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2782 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2784 werror (E_COMPARE_OP);
2785 fprintf (stderr, "comparing type ");
2786 printTypeChain (LTYPE (tree), stderr);
2787 fprintf (stderr, "to type ");
2788 printTypeChain (RTYPE (tree), stderr);
2789 fprintf (stderr, "\n");
2790 goto errorTreeReturn;
2793 /* else they should be promotable to one another */
2796 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2797 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2799 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2801 werror (E_COMPARE_OP);
2802 fprintf (stderr, "comparing type ");
2803 printTypeChain (LTYPE (tree), stderr);
2804 fprintf (stderr, "to type ");
2805 printTypeChain (RTYPE (tree), stderr);
2806 fprintf (stderr, "\n");
2807 goto errorTreeReturn;
2811 /* if they are both literal then */
2812 /* rewrite the tree */
2813 if (IS_LITERAL (RTYPE (tree)) &&
2814 IS_LITERAL (LTYPE (tree)))
2816 tree->type = EX_VALUE;
2817 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2818 valFromType (RETYPE (tree)),
2820 tree->right = tree->left = NULL;
2821 TETYPE (tree) = getSpec (TTYPE (tree) =
2822 tree->opval.val->type);
2825 LRVAL (tree) = RRVAL (tree) = 1;
2826 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2829 /*------------------------------------------------------------------*/
2830 /*----------------------------*/
2832 /*----------------------------*/
2833 case SIZEOF: /* evaluate wihout code generation */
2834 /* change the type to a integer */
2835 tree->type = EX_VALUE;
2836 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2837 tree->opval.val = constVal (buffer);
2838 tree->right = tree->left = NULL;
2839 TETYPE (tree) = getSpec (TTYPE (tree) =
2840 tree->opval.val->type);
2843 /*------------------------------------------------------------------*/
2844 /*----------------------------*/
2845 /* conditional operator '?' */
2846 /*----------------------------*/
2848 /* the type is value of the colon operator (on the right) */
2849 assert(IS_COLON_OP(tree->right));
2850 /* if already known then replace the tree : optimizer will do it
2851 but faster to do it here */
2852 if (IS_LITERAL (LTYPE(tree))) {
2853 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2854 return tree->right->left ;
2856 return tree->right->right ;
2859 TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2860 TETYPE (tree) = getSpec (TTYPE (tree));
2865 /* if they don't match we have a problem */
2866 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2868 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2869 goto errorTreeReturn;
2872 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2873 TETYPE (tree) = getSpec (TTYPE (tree));
2877 /*------------------------------------------------------------------*/
2878 /*----------------------------*/
2879 /* assignment operators */
2880 /*----------------------------*/
2883 /* for these it must be both must be integral */
2884 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2885 !IS_ARITHMETIC (RTYPE (tree)))
2887 werror (E_OPS_INTEGRAL);
2888 goto errorTreeReturn;
2891 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2893 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2894 werror (E_CODE_WRITE, " ");
2898 werror (E_LVALUE_REQUIRED, "*= or /=");
2899 goto errorTreeReturn;
2910 /* for these it must be both must be integral */
2911 if (!IS_INTEGRAL (LTYPE (tree)) ||
2912 !IS_INTEGRAL (RTYPE (tree)))
2914 werror (E_OPS_INTEGRAL);
2915 goto errorTreeReturn;
2918 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2920 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2921 werror (E_CODE_WRITE, " ");
2925 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2926 goto errorTreeReturn;
2932 /*------------------------------------------------------------------*/
2933 /*----------------------------*/
2935 /*----------------------------*/
2937 if (!(IS_PTR (LTYPE (tree)) ||
2938 IS_ARITHMETIC (LTYPE (tree))))
2940 werror (E_PLUS_INVALID, "-=");
2941 goto errorTreeReturn;
2944 if (!(IS_PTR (RTYPE (tree)) ||
2945 IS_ARITHMETIC (RTYPE (tree))))
2947 werror (E_PLUS_INVALID, "-=");
2948 goto errorTreeReturn;
2951 TETYPE (tree) = getSpec (TTYPE (tree) =
2952 computeType (LTYPE (tree),
2955 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2956 werror (E_CODE_WRITE, " ");
2960 werror (E_LVALUE_REQUIRED, "-=");
2961 goto errorTreeReturn;
2967 /*------------------------------------------------------------------*/
2968 /*----------------------------*/
2970 /*----------------------------*/
2972 /* this is not a unary operation */
2973 /* if both pointers then problem */
2974 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2976 werror (E_PTR_PLUS_PTR);
2977 goto errorTreeReturn;
2980 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2982 werror (E_PLUS_INVALID, "+=");
2983 goto errorTreeReturn;
2986 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2988 werror (E_PLUS_INVALID, "+=");
2989 goto errorTreeReturn;
2992 TETYPE (tree) = getSpec (TTYPE (tree) =
2993 computeType (LTYPE (tree),
2996 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2997 werror (E_CODE_WRITE, " ");
3001 werror (E_LVALUE_REQUIRED, "+=");
3002 goto errorTreeReturn;
3005 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3006 tree->opval.op = '=';
3010 /*------------------------------------------------------------------*/
3011 /*----------------------------*/
3012 /* straight assignemnt */
3013 /*----------------------------*/
3015 /* cannot be an aggregate */
3016 if (IS_AGGREGATE (LTYPE (tree)))
3018 werror (E_AGGR_ASSIGN);
3019 goto errorTreeReturn;
3022 /* they should either match or be castable */
3023 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3025 werror (E_TYPE_MISMATCH, "assignment", " ");
3026 fprintf (stderr, "type --> '");
3027 printTypeChain (RTYPE (tree), stderr);
3028 fprintf (stderr, "' ");
3029 fprintf (stderr, "assigned to type --> '");
3030 printTypeChain (LTYPE (tree), stderr);
3031 fprintf (stderr, "'\n");
3032 goto errorTreeReturn;
3035 /* if the left side of the tree is of type void
3036 then report error */
3037 if (IS_VOID (LTYPE (tree)))
3039 werror (E_CAST_ZERO);
3040 printFromToType(RTYPE(tree), LTYPE(tree));
3043 TETYPE (tree) = getSpec (TTYPE (tree) =
3047 if (!tree->initMode ) {
3048 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3049 werror (E_CODE_WRITE, " ");
3053 werror (E_LVALUE_REQUIRED, "=");
3054 goto errorTreeReturn;
3059 /*------------------------------------------------------------------*/
3060 /*----------------------------*/
3061 /* comma operator */
3062 /*----------------------------*/
3064 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3067 /*------------------------------------------------------------------*/
3068 /*----------------------------*/
3070 /*----------------------------*/
3074 if (processParms (tree->left,
3075 FUNC_ARGS(tree->left->ftype),
3076 tree->right, &parmNumber, TRUE)) {
3077 goto errorTreeReturn;
3080 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3082 //FUNC_ARGS(tree->left->ftype) =
3083 //reverseVal (FUNC_ARGS(tree->left->ftype));
3084 reverseParms (tree->right);
3087 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3090 /*------------------------------------------------------------------*/
3091 /*----------------------------*/
3092 /* return statement */
3093 /*----------------------------*/
3098 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3100 werror (W_RETURN_MISMATCH);
3101 printFromToType (RTYPE(tree), currFunc->type->next);
3102 goto errorTreeReturn;
3105 if (IS_VOID (currFunc->type->next)
3107 !IS_VOID (RTYPE (tree)))
3109 werror (E_FUNC_VOID);
3110 goto errorTreeReturn;
3113 /* if there is going to be a casing required then add it */
3114 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3117 decorateType (newNode (CAST,
3118 newAst_LINK (copyLinkChain (currFunc->type->next)),
3127 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3129 werror (E_VOID_FUNC, currFunc->name);
3130 goto errorTreeReturn;
3133 TTYPE (tree) = TETYPE (tree) = NULL;
3136 /*------------------------------------------------------------------*/
3137 /*----------------------------*/
3138 /* switch statement */
3139 /*----------------------------*/
3141 /* the switch value must be an integer */
3142 if (!IS_INTEGRAL (LTYPE (tree)))
3144 werror (E_SWITCH_NON_INTEGER);
3145 goto errorTreeReturn;
3148 TTYPE (tree) = TETYPE (tree) = NULL;
3151 /*------------------------------------------------------------------*/
3152 /*----------------------------*/
3154 /*----------------------------*/
3156 tree->left = backPatchLabels (tree->left,
3159 TTYPE (tree) = TETYPE (tree) = NULL;
3162 /*------------------------------------------------------------------*/
3163 /*----------------------------*/
3165 /*----------------------------*/
3168 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3169 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3170 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3172 /* if the for loop is reversible then
3173 reverse it otherwise do what we normally
3179 if (isLoopReversible (tree, &sym, &init, &end))
3180 return reverseLoop (tree, sym, init, end);
3182 return decorateType (createFor (AST_FOR (tree, trueLabel),
3183 AST_FOR (tree, continueLabel),
3184 AST_FOR (tree, falseLabel),
3185 AST_FOR (tree, condLabel),
3186 AST_FOR (tree, initExpr),
3187 AST_FOR (tree, condExpr),
3188 AST_FOR (tree, loopExpr),
3192 TTYPE (tree) = TETYPE (tree) = NULL;
3196 /* some error found this tree will be killed */
3198 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3199 tree->opval.op = NULLOP;
3205 /*-----------------------------------------------------------------*/
3206 /* sizeofOp - processes size of operation */
3207 /*-----------------------------------------------------------------*/
3209 sizeofOp (sym_link * type)
3213 /* make sure the type is complete and sane */
3214 checkTypeSanity(type, "(sizeof)");
3216 /* get the size and convert it to character */
3217 sprintf (buff, "%d", getSize (type));
3219 /* now convert into value */
3220 return constVal (buff);
3224 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3225 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3226 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3227 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3228 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3229 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3230 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3232 /*-----------------------------------------------------------------*/
3233 /* backPatchLabels - change and or not operators to flow control */
3234 /*-----------------------------------------------------------------*/
3236 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3242 if (!(IS_ANDORNOT (tree)))
3245 /* if this an and */
3248 static int localLbl = 0;
3251 sprintf (buffer, "_and_%d", localLbl++);
3252 localLabel = newSymbol (buffer, NestLevel);
3254 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3256 /* if left is already a IFX then just change the if true label in that */
3257 if (!IS_IFX (tree->left))
3258 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3260 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3261 /* right is a IFX then just join */
3262 if (IS_IFX (tree->right))
3263 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3265 tree->right = createLabel (localLabel, tree->right);
3266 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3268 return newNode (NULLOP, tree->left, tree->right);
3271 /* if this is an or operation */
3274 static int localLbl = 0;
3277 sprintf (buffer, "_or_%d", localLbl++);
3278 localLabel = newSymbol (buffer, NestLevel);
3280 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3282 /* if left is already a IFX then just change the if true label in that */
3283 if (!IS_IFX (tree->left))
3284 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3286 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3287 /* right is a IFX then just join */
3288 if (IS_IFX (tree->right))
3289 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3291 tree->right = createLabel (localLabel, tree->right);
3292 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3294 return newNode (NULLOP, tree->left, tree->right);
3300 int wasnot = IS_NOT (tree->left);
3301 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3303 /* if the left is already a IFX */
3304 if (!IS_IFX (tree->left))
3305 tree->left = newNode (IFX, tree->left, NULL);
3309 tree->left->trueLabel = trueLabel;
3310 tree->left->falseLabel = falseLabel;
3314 tree->left->trueLabel = falseLabel;
3315 tree->left->falseLabel = trueLabel;
3322 tree->trueLabel = trueLabel;
3323 tree->falseLabel = falseLabel;
3330 /*-----------------------------------------------------------------*/
3331 /* createBlock - create expression tree for block */
3332 /*-----------------------------------------------------------------*/
3334 createBlock (symbol * decl, ast * body)
3338 /* if the block has nothing */
3342 ex = newNode (BLOCK, NULL, body);
3343 ex->values.sym = decl;
3345 ex->right = ex->right;
3351 /*-----------------------------------------------------------------*/
3352 /* createLabel - creates the expression tree for labels */
3353 /*-----------------------------------------------------------------*/
3355 createLabel (symbol * label, ast * stmnt)
3358 char name[SDCC_NAME_MAX + 1];
3361 /* must create fresh symbol if the symbol name */
3362 /* exists in the symbol table, since there can */
3363 /* be a variable with the same name as the labl */
3364 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3365 (csym->level == label->level))
3366 label = newSymbol (label->name, label->level);
3368 /* change the name before putting it in add _ */
3369 sprintf (name, "%s", label->name);
3371 /* put the label in the LabelSymbol table */
3372 /* but first check if a label of the same */
3374 if ((csym = findSym (LabelTab, NULL, name)))
3375 werror (E_DUPLICATE_LABEL, label->name);
3377 addSym (LabelTab, label, name, label->level, 0, 0);
3380 label->key = labelKey++;
3381 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3387 /*-----------------------------------------------------------------*/
3388 /* createCase - generates the parsetree for a case statement */
3389 /*-----------------------------------------------------------------*/
3391 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3393 char caseLbl[SDCC_NAME_MAX + 1];
3397 /* if the switch statement does not exist */
3398 /* then case is out of context */
3401 werror (E_CASE_CONTEXT);
3405 caseVal = decorateType (resolveSymbols (caseVal));
3406 /* if not a constant then error */
3407 if (!IS_LITERAL (caseVal->ftype))
3409 werror (E_CASE_CONSTANT);
3413 /* if not a integer than error */
3414 if (!IS_INTEGRAL (caseVal->ftype))
3416 werror (E_CASE_NON_INTEGER);
3420 /* find the end of the switch values chain */
3421 if (!(val = swStat->values.switchVals.swVals))
3422 swStat->values.switchVals.swVals = caseVal->opval.val;
3425 /* also order the cases according to value */
3427 int cVal = (int) floatFromVal (caseVal->opval.val);
3428 while (val && (int) floatFromVal (val) < cVal)
3434 /* if we reached the end then */
3437 pval->next = caseVal->opval.val;
3441 /* we found a value greater than */
3442 /* the current value we must add this */
3443 /* before the value */
3444 caseVal->opval.val->next = val;
3446 /* if this was the first in chain */
3447 if (swStat->values.switchVals.swVals == val)
3448 swStat->values.switchVals.swVals =
3451 pval->next = caseVal->opval.val;
3456 /* create the case label */
3457 sprintf (caseLbl, "_case_%d_%d",
3458 swStat->values.switchVals.swNum,
3459 (int) floatFromVal (caseVal->opval.val));
3461 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3466 /*-----------------------------------------------------------------*/
3467 /* createDefault - creates the parse tree for the default statement */
3468 /*-----------------------------------------------------------------*/
3470 createDefault (ast * swStat, ast * stmnt)
3472 char defLbl[SDCC_NAME_MAX + 1];
3474 /* if the switch statement does not exist */
3475 /* then case is out of context */
3478 werror (E_CASE_CONTEXT);
3482 /* turn on the default flag */
3483 swStat->values.switchVals.swDefault = 1;
3485 /* create the label */
3486 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3487 return createLabel (newSymbol (defLbl, 0), stmnt);
3490 /*-----------------------------------------------------------------*/
3491 /* createIf - creates the parsetree for the if statement */
3492 /*-----------------------------------------------------------------*/
3494 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3496 static int Lblnum = 0;
3498 symbol *ifTrue, *ifFalse, *ifEnd;
3500 /* if neither exists */
3501 if (!elseBody && !ifBody) {
3502 // if there are no side effects (i++, j() etc)
3503 if (!hasSEFcalls(condAst)) {
3508 /* create the labels */
3509 sprintf (buffer, "_iffalse_%d", Lblnum);
3510 ifFalse = newSymbol (buffer, NestLevel);
3511 /* if no else body then end == false */
3516 sprintf (buffer, "_ifend_%d", Lblnum);
3517 ifEnd = newSymbol (buffer, NestLevel);
3520 sprintf (buffer, "_iftrue_%d", Lblnum);
3521 ifTrue = newSymbol (buffer, NestLevel);
3525 /* attach the ifTrue label to the top of it body */
3526 ifBody = createLabel (ifTrue, ifBody);
3527 /* attach a goto end to the ifBody if else is present */
3530 ifBody = newNode (NULLOP, ifBody,
3532 newAst_VALUE (symbolVal (ifEnd)),
3534 /* put the elseLabel on the else body */
3535 elseBody = createLabel (ifFalse, elseBody);
3536 /* out the end at the end of the body */
3537 elseBody = newNode (NULLOP,
3539 createLabel (ifEnd, NULL));
3543 ifBody = newNode (NULLOP, ifBody,
3544 createLabel (ifFalse, NULL));
3546 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3547 if (IS_IFX (condAst))
3550 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3552 return newNode (NULLOP, ifTree,
3553 newNode (NULLOP, ifBody, elseBody));
3557 /*-----------------------------------------------------------------*/
3558 /* createDo - creates parse tree for do */
3561 /* _docontinue_n: */
3562 /* condition_expression +-> trueLabel -> _dobody_n */
3564 /* +-> falseLabel-> _dobreak_n */
3566 /*-----------------------------------------------------------------*/
3568 createDo (symbol * trueLabel, symbol * continueLabel,
3569 symbol * falseLabel, ast * condAst, ast * doBody)
3574 /* if the body does not exist then it is simple */
3577 condAst = backPatchLabels (condAst, continueLabel, NULL);
3578 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3579 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3580 doTree->trueLabel = continueLabel;
3581 doTree->falseLabel = NULL;
3585 /* otherwise we have a body */
3586 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3588 /* attach the body label to the top */
3589 doBody = createLabel (trueLabel, doBody);
3590 /* attach the continue label to end of body */
3591 doBody = newNode (NULLOP, doBody,
3592 createLabel (continueLabel, NULL));
3594 /* now put the break label at the end */
3595 if (IS_IFX (condAst))
3598 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3600 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3602 /* putting it together */
3603 return newNode (NULLOP, doBody, doTree);
3606 /*-----------------------------------------------------------------*/
3607 /* createFor - creates parse tree for 'for' statement */
3610 /* condExpr +-> trueLabel -> _forbody_n */
3612 /* +-> falseLabel-> _forbreak_n */
3615 /* _forcontinue_n: */
3617 /* goto _forcond_n ; */
3619 /*-----------------------------------------------------------------*/
3621 createFor (symbol * trueLabel, symbol * continueLabel,
3622 symbol * falseLabel, symbol * condLabel,
3623 ast * initExpr, ast * condExpr, ast * loopExpr,
3628 /* if loopexpression not present then we can generate it */
3629 /* the same way as a while */
3631 return newNode (NULLOP, initExpr,
3632 createWhile (trueLabel, continueLabel,
3633 falseLabel, condExpr, forBody));
3634 /* vanilla for statement */
3635 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3637 if (condExpr && !IS_IFX (condExpr))
3638 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3641 /* attach condition label to condition */
3642 condExpr = createLabel (condLabel, condExpr);
3644 /* attach body label to body */
3645 forBody = createLabel (trueLabel, forBody);
3647 /* attach continue to forLoop expression & attach */
3648 /* goto the forcond @ and of loopExpression */
3649 loopExpr = createLabel (continueLabel,
3653 newAst_VALUE (symbolVal (condLabel)),
3655 /* now start putting them together */
3656 forTree = newNode (NULLOP, initExpr, condExpr);
3657 forTree = newNode (NULLOP, forTree, forBody);
3658 forTree = newNode (NULLOP, forTree, loopExpr);
3659 /* finally add the break label */
3660 forTree = newNode (NULLOP, forTree,
3661 createLabel (falseLabel, NULL));
3665 /*-----------------------------------------------------------------*/
3666 /* createWhile - creates parse tree for while statement */
3667 /* the while statement will be created as follows */
3669 /* _while_continue_n: */
3670 /* condition_expression +-> trueLabel -> _while_boby_n */
3672 /* +-> falseLabel -> _while_break_n */
3673 /* _while_body_n: */
3675 /* goto _while_continue_n */
3676 /* _while_break_n: */
3677 /*-----------------------------------------------------------------*/
3679 createWhile (symbol * trueLabel, symbol * continueLabel,
3680 symbol * falseLabel, ast * condExpr, ast * whileBody)
3684 /* put the continue label */
3685 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3686 condExpr = createLabel (continueLabel, condExpr);
3687 condExpr->lineno = 0;
3689 /* put the body label in front of the body */
3690 whileBody = createLabel (trueLabel, whileBody);
3691 whileBody->lineno = 0;
3692 /* put a jump to continue at the end of the body */
3693 /* and put break label at the end of the body */
3694 whileBody = newNode (NULLOP,
3697 newAst_VALUE (symbolVal (continueLabel)),
3698 createLabel (falseLabel, NULL)));
3700 /* put it all together */
3701 if (IS_IFX (condExpr))
3702 whileTree = condExpr;
3705 whileTree = newNode (IFX, condExpr, NULL);
3706 /* put the true & false labels in place */
3707 whileTree->trueLabel = trueLabel;
3708 whileTree->falseLabel = falseLabel;
3711 return newNode (NULLOP, whileTree, whileBody);
3714 /*-----------------------------------------------------------------*/
3715 /* optimizeGetHbit - get highest order bit of the expression */
3716 /*-----------------------------------------------------------------*/
3718 optimizeGetHbit (ast * tree)
3721 /* if this is not a bit and */
3722 if (!IS_BITAND (tree))
3725 /* will look for tree of the form
3726 ( expr >> ((sizeof expr) -1) ) & 1 */
3727 if (!IS_AST_LIT_VALUE (tree->right))
3730 if (AST_LIT_VALUE (tree->right) != 1)
3733 if (!IS_RIGHT_OP (tree->left))
3736 if (!IS_AST_LIT_VALUE (tree->left->right))
3739 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3740 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3743 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3747 /*-----------------------------------------------------------------*/
3748 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3749 /*-----------------------------------------------------------------*/
3751 optimizeRRCRLC (ast * root)
3753 /* will look for trees of the form
3754 (?expr << 1) | (?expr >> 7) or
3755 (?expr >> 7) | (?expr << 1) will make that
3756 into a RLC : operation ..
3758 (?expr >> 1) | (?expr << 7) or
3759 (?expr << 7) | (?expr >> 1) will make that
3760 into a RRC operation
3761 note : by 7 I mean (number of bits required to hold the
3763 /* if the root operations is not a | operation the not */
3764 if (!IS_BITOR (root))
3767 /* I have to think of a better way to match patterns this sucks */
3768 /* that aside let start looking for the first case : I use a the
3769 negative check a lot to improve the efficiency */
3770 /* (?expr << 1) | (?expr >> 7) */
3771 if (IS_LEFT_OP (root->left) &&
3772 IS_RIGHT_OP (root->right))
3775 if (!SPEC_USIGN (TETYPE (root->left->left)))
3778 if (!IS_AST_LIT_VALUE (root->left->right) ||
3779 !IS_AST_LIT_VALUE (root->right->right))
3782 /* make sure it is the same expression */
3783 if (!isAstEqual (root->left->left,
3787 if (AST_LIT_VALUE (root->left->right) != 1)
3790 if (AST_LIT_VALUE (root->right->right) !=
3791 (getSize (TTYPE (root->left->left)) * 8 - 1))
3794 /* whew got the first case : create the AST */
3795 return newNode (RLC, root->left->left, NULL);
3799 /* check for second case */
3800 /* (?expr >> 7) | (?expr << 1) */
3801 if (IS_LEFT_OP (root->right) &&
3802 IS_RIGHT_OP (root->left))
3805 if (!SPEC_USIGN (TETYPE (root->left->left)))
3808 if (!IS_AST_LIT_VALUE (root->left->right) ||
3809 !IS_AST_LIT_VALUE (root->right->right))
3812 /* make sure it is the same symbol */
3813 if (!isAstEqual (root->left->left,
3817 if (AST_LIT_VALUE (root->right->right) != 1)
3820 if (AST_LIT_VALUE (root->left->right) !=
3821 (getSize (TTYPE (root->left->left)) * 8 - 1))
3824 /* whew got the first case : create the AST */
3825 return newNode (RLC, root->left->left, NULL);
3830 /* third case for RRC */
3831 /* (?symbol >> 1) | (?symbol << 7) */
3832 if (IS_LEFT_OP (root->right) &&
3833 IS_RIGHT_OP (root->left))
3836 if (!SPEC_USIGN (TETYPE (root->left->left)))
3839 if (!IS_AST_LIT_VALUE (root->left->right) ||
3840 !IS_AST_LIT_VALUE (root->right->right))
3843 /* make sure it is the same symbol */
3844 if (!isAstEqual (root->left->left,
3848 if (AST_LIT_VALUE (root->left->right) != 1)
3851 if (AST_LIT_VALUE (root->right->right) !=
3852 (getSize (TTYPE (root->left->left)) * 8 - 1))
3855 /* whew got the first case : create the AST */
3856 return newNode (RRC, root->left->left, NULL);
3860 /* fourth and last case for now */
3861 /* (?symbol << 7) | (?symbol >> 1) */
3862 if (IS_RIGHT_OP (root->right) &&
3863 IS_LEFT_OP (root->left))
3866 if (!SPEC_USIGN (TETYPE (root->left->left)))
3869 if (!IS_AST_LIT_VALUE (root->left->right) ||
3870 !IS_AST_LIT_VALUE (root->right->right))
3873 /* make sure it is the same symbol */
3874 if (!isAstEqual (root->left->left,
3878 if (AST_LIT_VALUE (root->right->right) != 1)
3881 if (AST_LIT_VALUE (root->left->right) !=
3882 (getSize (TTYPE (root->left->left)) * 8 - 1))
3885 /* whew got the first case : create the AST */
3886 return newNode (RRC, root->left->left, NULL);
3890 /* not found return root */
3894 /*-----------------------------------------------------------------*/
3895 /* optimizeCompare - otimizes compares for bit variables */
3896 /*-----------------------------------------------------------------*/
3898 optimizeCompare (ast * root)
3900 ast *optExpr = NULL;
3903 unsigned int litValue;
3905 /* if nothing then return nothing */
3909 /* if not a compare op then do leaves */
3910 if (!IS_COMPARE_OP (root))
3912 root->left = optimizeCompare (root->left);
3913 root->right = optimizeCompare (root->right);
3917 /* if left & right are the same then depending
3918 of the operation do */
3919 if (isAstEqual (root->left, root->right))
3921 switch (root->opval.op)
3926 optExpr = newAst_VALUE (constVal ("0"));
3931 optExpr = newAst_VALUE (constVal ("1"));
3935 return decorateType (optExpr);
3938 vleft = (root->left->type == EX_VALUE ?
3939 root->left->opval.val : NULL);
3941 vright = (root->right->type == EX_VALUE ?
3942 root->right->opval.val : NULL);
3944 /* if left is a BITVAR in BITSPACE */
3945 /* and right is a LITERAL then opt- */
3946 /* imize else do nothing */
3947 if (vleft && vright &&
3948 IS_BITVAR (vleft->etype) &&
3949 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3950 IS_LITERAL (vright->etype))
3953 /* if right side > 1 then comparison may never succeed */
3954 if ((litValue = (int) floatFromVal (vright)) > 1)
3956 werror (W_BAD_COMPARE);
3962 switch (root->opval.op)
3964 case '>': /* bit value greater than 1 cannot be */
3965 werror (W_BAD_COMPARE);
3969 case '<': /* bit value < 1 means 0 */
3971 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3974 case LE_OP: /* bit value <= 1 means no check */
3975 optExpr = newAst_VALUE (vright);
3978 case GE_OP: /* bit value >= 1 means only check for = */
3980 optExpr = newAst_VALUE (vleft);
3985 { /* literal is zero */
3986 switch (root->opval.op)
3988 case '<': /* bit value < 0 cannot be */
3989 werror (W_BAD_COMPARE);
3993 case '>': /* bit value > 0 means 1 */
3995 optExpr = newAst_VALUE (vleft);
3998 case LE_OP: /* bit value <= 0 means no check */
3999 case GE_OP: /* bit value >= 0 means no check */
4000 werror (W_BAD_COMPARE);
4004 case EQ_OP: /* bit == 0 means ! of bit */
4005 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4009 return decorateType (resolveSymbols (optExpr));
4010 } /* end-of-if of BITVAR */
4015 /*-----------------------------------------------------------------*/
4016 /* addSymToBlock : adds the symbol to the first block we find */
4017 /*-----------------------------------------------------------------*/
4019 addSymToBlock (symbol * sym, ast * tree)
4021 /* reached end of tree or a leaf */
4022 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4026 if (IS_AST_OP (tree) &&
4027 tree->opval.op == BLOCK)
4030 symbol *lsym = copySymbol (sym);
4032 lsym->next = AST_VALUES (tree, sym);
4033 AST_VALUES (tree, sym) = lsym;
4037 addSymToBlock (sym, tree->left);
4038 addSymToBlock (sym, tree->right);
4041 /*-----------------------------------------------------------------*/
4042 /* processRegParms - do processing for register parameters */
4043 /*-----------------------------------------------------------------*/
4045 processRegParms (value * args, ast * body)
4049 if (IS_REGPARM (args->etype))
4050 addSymToBlock (args->sym, body);
4055 /*-----------------------------------------------------------------*/
4056 /* resetParmKey - resets the operandkeys for the symbols */
4057 /*-----------------------------------------------------------------*/
4058 DEFSETFUNC (resetParmKey)
4069 /*-----------------------------------------------------------------*/
4070 /* createFunction - This is the key node that calls the iCode for */
4071 /* generating the code for a function. Note code */
4072 /* is generated function by function, later when */
4073 /* add inter-procedural analysis this will change */
4074 /*-----------------------------------------------------------------*/
4076 createFunction (symbol * name, ast * body)
4082 iCode *piCode = NULL;
4084 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4085 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4087 /* if check function return 0 then some problem */
4088 if (checkFunction (name, NULL) == 0)
4091 /* create a dummy block if none exists */
4093 body = newNode (BLOCK, NULL, NULL);
4097 /* check if the function name already in the symbol table */
4098 if ((csym = findSym (SymbolTab, NULL, name->name)))
4101 /* special case for compiler defined functions
4102 we need to add the name to the publics list : this
4103 actually means we are now compiling the compiler
4107 addSet (&publics, name);
4113 allocVariables (name);
4115 name->lastLine = yylineno;
4118 #if 0 // jwk: this is now done in addDecl()
4119 processFuncArgs (currFunc);
4122 /* set the stack pointer */
4123 /* PENDING: check this for the mcs51 */
4124 stackPtr = -port->stack.direction * port->stack.call_overhead;
4125 if (IFFUNC_ISISR (name->type))
4126 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4127 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4128 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4130 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4132 fetype = getSpec (name->type); /* get the specifier for the function */
4133 /* if this is a reentrant function then */
4134 if (IFFUNC_ISREENT (name->type))
4137 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4139 /* do processing for parameters that are passed in registers */
4140 processRegParms (FUNC_ARGS(name->type), body);
4142 /* set the stack pointer */
4146 /* allocate & autoinit the block variables */
4147 processBlockVars (body, &stack, ALLOCATE);
4149 /* save the stack information */
4150 if (options.useXstack)
4151 name->xstack = SPEC_STAK (fetype) = stack;
4153 name->stack = SPEC_STAK (fetype) = stack;
4155 /* name needs to be mangled */
4156 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4158 body = resolveSymbols (body); /* resolve the symbols */
4159 body = decorateType (body); /* propagateType & do semantic checks */
4161 ex = newAst_VALUE (symbolVal (name)); /* create name */
4162 ex = newNode (FUNCTION, ex, body);
4163 ex->values.args = FUNC_ARGS(name->type);
4165 if (options.dump_tree) PA(ex);
4168 werror (E_FUNC_NO_CODE, name->name);
4172 /* create the node & generate intermediate code */
4174 codeOutFile = code->oFile;
4175 piCode = iCodeFromAst (ex);
4179 werror (E_FUNC_NO_CODE, name->name);
4183 eBBlockFromiCode (piCode);
4185 /* if there are any statics then do them */
4188 GcurMemmap = statsg;
4189 codeOutFile = statsg->oFile;
4190 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4196 /* dealloc the block variables */
4197 processBlockVars (body, &stack, DEALLOCATE);
4198 /* deallocate paramaters */
4199 deallocParms (FUNC_ARGS(name->type));
4201 if (IFFUNC_ISREENT (name->type))
4204 /* we are done freeup memory & cleanup */
4208 FUNC_HASBODY(name->type) = 1;
4209 addSet (&operKeyReset, name);
4210 applyToSet (operKeyReset, resetParmKey);
4213 cdbStructBlock (1, cdbFile);
4215 cleanUpLevel (LabelTab, 0);
4216 cleanUpBlock (StructTab, 1);
4217 cleanUpBlock (TypedefTab, 1);
4219 xstack->syms = NULL;
4220 istack->syms = NULL;
4225 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4226 /*-----------------------------------------------------------------*/
4227 /* ast_print : prints the ast (for debugging purposes) */
4228 /*-----------------------------------------------------------------*/
4230 void ast_print (ast * tree, FILE *outfile, int indent)
4235 /* can print only decorated trees */
4236 if (!tree->decorated) return;
4238 /* if any child is an error | this one is an error do nothing */
4239 if (tree->isError ||
4240 (tree->left && tree->left->isError) ||
4241 (tree->right && tree->right->isError)) {
4242 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4246 /* print the line */
4247 /* if not block & function */
4248 if (tree->type == EX_OP &&
4249 (tree->opval.op != FUNCTION &&
4250 tree->opval.op != BLOCK &&
4251 tree->opval.op != NULLOP)) {
4254 if (tree->opval.op == FUNCTION) {
4256 value *args=FUNC_ARGS(tree->left->opval.val->type);
4257 fprintf(outfile,"FUNCTION (%s=%p) type (",
4258 tree->left->opval.val->name, tree);
4259 printTypeChain (tree->ftype,outfile);
4260 fprintf(outfile,") args (");
4263 fprintf (outfile, ", ");
4265 printTypeChain (args ? args->type : NULL, outfile);
4267 args= args ? args->next : NULL;
4269 fprintf(outfile,")\n");
4270 ast_print(tree->left,outfile,indent);
4271 ast_print(tree->right,outfile,indent);
4274 if (tree->opval.op == BLOCK) {
4275 symbol *decls = tree->values.sym;
4276 INDENT(indent,outfile);
4277 fprintf(outfile,"{\n");
4279 INDENT(indent+4,outfile);
4280 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4281 decls->name, decls);
4282 printTypeChain(decls->type,outfile);
4283 fprintf(outfile,")\n");
4285 decls = decls->next;
4287 ast_print(tree->right,outfile,indent+4);
4288 INDENT(indent,outfile);
4289 fprintf(outfile,"}\n");
4292 if (tree->opval.op == NULLOP) {
4293 fprintf(outfile,"\n");
4294 ast_print(tree->left,outfile,indent);
4295 fprintf(outfile,"\n");
4296 ast_print(tree->right,outfile,indent);
4299 INDENT(indent,outfile);
4301 /*------------------------------------------------------------------*/
4302 /*----------------------------*/
4303 /* leaf has been reached */
4304 /*----------------------------*/
4305 /* if this is of type value */
4306 /* just get the type */
4307 if (tree->type == EX_VALUE) {
4309 if (IS_LITERAL (tree->opval.val->etype)) {
4310 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4311 (int) floatFromVal(tree->opval.val),
4312 (int) floatFromVal(tree->opval.val),
4313 floatFromVal(tree->opval.val));
4314 } else if (tree->opval.val->sym) {
4315 /* if the undefined flag is set then give error message */
4316 if (tree->opval.val->sym->undefined) {
4317 fprintf(outfile,"UNDEFINED SYMBOL ");
4319 fprintf(outfile,"SYMBOL ");
4321 fprintf(outfile,"(%s=%p)",
4322 tree->opval.val->sym->name,tree);
4325 fprintf(outfile," type (");
4326 printTypeChain(tree->ftype,outfile);
4327 fprintf(outfile,")\n");
4329 fprintf(outfile,"\n");
4334 /* if type link for the case of cast */
4335 if (tree->type == EX_LINK) {
4336 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4337 printTypeChain(tree->opval.lnk,outfile);
4338 fprintf(outfile,")\n");
4343 /* depending on type of operator do */
4345 switch (tree->opval.op) {
4346 /*------------------------------------------------------------------*/
4347 /*----------------------------*/
4349 /*----------------------------*/
4351 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4352 printTypeChain(tree->ftype,outfile);
4353 fprintf(outfile,")\n");
4354 ast_print(tree->left,outfile,indent+4);
4355 ast_print(tree->right,outfile,indent+4);
4358 /*------------------------------------------------------------------*/
4359 /*----------------------------*/
4361 /*----------------------------*/
4363 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4364 printTypeChain(tree->ftype,outfile);
4365 fprintf(outfile,")\n");
4366 ast_print(tree->left,outfile,indent+4);
4367 ast_print(tree->right,outfile,indent+4);
4370 /*------------------------------------------------------------------*/
4371 /*----------------------------*/
4372 /* struct/union pointer */
4373 /*----------------------------*/
4375 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4376 printTypeChain(tree->ftype,outfile);
4377 fprintf(outfile,")\n");
4378 ast_print(tree->left,outfile,indent+4);
4379 ast_print(tree->right,outfile,indent+4);
4382 /*------------------------------------------------------------------*/
4383 /*----------------------------*/
4384 /* ++/-- operation */
4385 /*----------------------------*/
4386 case INC_OP: /* incerement operator unary so left only */
4387 fprintf(outfile,"INC_OP (%p) type (",tree);
4388 printTypeChain(tree->ftype,outfile);
4389 fprintf(outfile,")\n");
4390 ast_print(tree->left,outfile,indent+4);
4394 fprintf(outfile,"DEC_OP (%p) type (",tree);
4395 printTypeChain(tree->ftype,outfile);
4396 fprintf(outfile,")\n");
4397 ast_print(tree->left,outfile,indent+4);
4400 /*------------------------------------------------------------------*/
4401 /*----------------------------*/
4403 /*----------------------------*/
4406 fprintf(outfile,"& (%p) type (",tree);
4407 printTypeChain(tree->ftype,outfile);
4408 fprintf(outfile,")\n");
4409 ast_print(tree->left,outfile,indent+4);
4410 ast_print(tree->right,outfile,indent+4);
4412 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4413 printTypeChain(tree->ftype,outfile);
4414 fprintf(outfile,")\n");
4415 ast_print(tree->left,outfile,indent+4);
4416 ast_print(tree->right,outfile,indent+4);
4419 /*----------------------------*/
4421 /*----------------------------*/
4423 fprintf(outfile,"OR (%p) type (",tree);
4424 printTypeChain(tree->ftype,outfile);
4425 fprintf(outfile,")\n");
4426 ast_print(tree->left,outfile,indent+4);
4427 ast_print(tree->right,outfile,indent+4);
4429 /*------------------------------------------------------------------*/
4430 /*----------------------------*/
4432 /*----------------------------*/
4434 fprintf(outfile,"XOR (%p) type (",tree);
4435 printTypeChain(tree->ftype,outfile);
4436 fprintf(outfile,")\n");
4437 ast_print(tree->left,outfile,indent+4);
4438 ast_print(tree->right,outfile,indent+4);
4441 /*------------------------------------------------------------------*/
4442 /*----------------------------*/
4444 /*----------------------------*/
4446 fprintf(outfile,"DIV (%p) type (",tree);
4447 printTypeChain(tree->ftype,outfile);
4448 fprintf(outfile,")\n");
4449 ast_print(tree->left,outfile,indent+4);
4450 ast_print(tree->right,outfile,indent+4);
4452 /*------------------------------------------------------------------*/
4453 /*----------------------------*/
4455 /*----------------------------*/
4457 fprintf(outfile,"MOD (%p) type (",tree);
4458 printTypeChain(tree->ftype,outfile);
4459 fprintf(outfile,")\n");
4460 ast_print(tree->left,outfile,indent+4);
4461 ast_print(tree->right,outfile,indent+4);
4464 /*------------------------------------------------------------------*/
4465 /*----------------------------*/
4466 /* address dereference */
4467 /*----------------------------*/
4468 case '*': /* can be unary : if right is null then unary operation */
4470 fprintf(outfile,"DEREF (%p) type (",tree);
4471 printTypeChain(tree->ftype,outfile);
4472 fprintf(outfile,")\n");
4473 ast_print(tree->left,outfile,indent+4);
4476 /*------------------------------------------------------------------*/
4477 /*----------------------------*/
4478 /* multiplication */
4479 /*----------------------------*/
4480 fprintf(outfile,"MULT (%p) type (",tree);
4481 printTypeChain(tree->ftype,outfile);
4482 fprintf(outfile,")\n");
4483 ast_print(tree->left,outfile,indent+4);
4484 ast_print(tree->right,outfile,indent+4);
4488 /*------------------------------------------------------------------*/
4489 /*----------------------------*/
4490 /* unary '+' operator */
4491 /*----------------------------*/
4495 fprintf(outfile,"UPLUS (%p) type (",tree);
4496 printTypeChain(tree->ftype,outfile);
4497 fprintf(outfile,")\n");
4498 ast_print(tree->left,outfile,indent+4);
4500 /*------------------------------------------------------------------*/
4501 /*----------------------------*/
4503 /*----------------------------*/
4504 fprintf(outfile,"ADD (%p) type (",tree);
4505 printTypeChain(tree->ftype,outfile);
4506 fprintf(outfile,")\n");
4507 ast_print(tree->left,outfile,indent+4);
4508 ast_print(tree->right,outfile,indent+4);
4511 /*------------------------------------------------------------------*/
4512 /*----------------------------*/
4514 /*----------------------------*/
4515 case '-': /* can be unary */
4517 fprintf(outfile,"UMINUS (%p) type (",tree);
4518 printTypeChain(tree->ftype,outfile);
4519 fprintf(outfile,")\n");
4520 ast_print(tree->left,outfile,indent+4);
4522 /*------------------------------------------------------------------*/
4523 /*----------------------------*/
4525 /*----------------------------*/
4526 fprintf(outfile,"SUB (%p) type (",tree);
4527 printTypeChain(tree->ftype,outfile);
4528 fprintf(outfile,")\n");
4529 ast_print(tree->left,outfile,indent+4);
4530 ast_print(tree->right,outfile,indent+4);
4533 /*------------------------------------------------------------------*/
4534 /*----------------------------*/
4536 /*----------------------------*/
4538 fprintf(outfile,"COMPL (%p) type (",tree);
4539 printTypeChain(tree->ftype,outfile);
4540 fprintf(outfile,")\n");
4541 ast_print(tree->left,outfile,indent+4);
4543 /*------------------------------------------------------------------*/
4544 /*----------------------------*/
4546 /*----------------------------*/
4548 fprintf(outfile,"NOT (%p) type (",tree);
4549 printTypeChain(tree->ftype,outfile);
4550 fprintf(outfile,")\n");
4551 ast_print(tree->left,outfile,indent+4);
4553 /*------------------------------------------------------------------*/
4554 /*----------------------------*/
4556 /*----------------------------*/
4558 fprintf(outfile,"RRC (%p) type (",tree);
4559 printTypeChain(tree->ftype,outfile);
4560 fprintf(outfile,")\n");
4561 ast_print(tree->left,outfile,indent+4);
4565 fprintf(outfile,"RLC (%p) type (",tree);
4566 printTypeChain(tree->ftype,outfile);
4567 fprintf(outfile,")\n");
4568 ast_print(tree->left,outfile,indent+4);
4571 fprintf(outfile,"GETHBIT (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+4);
4577 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4578 printTypeChain(tree->ftype,outfile);
4579 fprintf(outfile,")\n");
4580 ast_print(tree->left,outfile,indent+4);
4581 ast_print(tree->right,outfile,indent+4);
4584 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4585 printTypeChain(tree->ftype,outfile);
4586 fprintf(outfile,")\n");
4587 ast_print(tree->left,outfile,indent+4);
4588 ast_print(tree->right,outfile,indent+4);
4590 /*------------------------------------------------------------------*/
4591 /*----------------------------*/
4593 /*----------------------------*/
4594 case CAST: /* change the type */
4595 fprintf(outfile,"CAST (%p) from type (",tree);
4596 printTypeChain(tree->right->ftype,outfile);
4597 fprintf(outfile,") to type (");
4598 printTypeChain(tree->ftype,outfile);
4599 fprintf(outfile,")\n");
4600 ast_print(tree->right,outfile,indent+4);
4604 fprintf(outfile,"ANDAND (%p) type (",tree);
4605 printTypeChain(tree->ftype,outfile);
4606 fprintf(outfile,")\n");
4607 ast_print(tree->left,outfile,indent+4);
4608 ast_print(tree->right,outfile,indent+4);
4611 fprintf(outfile,"OROR (%p) type (",tree);
4612 printTypeChain(tree->ftype,outfile);
4613 fprintf(outfile,")\n");
4614 ast_print(tree->left,outfile,indent+4);
4615 ast_print(tree->right,outfile,indent+4);
4618 /*------------------------------------------------------------------*/
4619 /*----------------------------*/
4620 /* comparison operators */
4621 /*----------------------------*/
4623 fprintf(outfile,"GT(>) (%p) type (",tree);
4624 printTypeChain(tree->ftype,outfile);
4625 fprintf(outfile,")\n");
4626 ast_print(tree->left,outfile,indent+4);
4627 ast_print(tree->right,outfile,indent+4);
4630 fprintf(outfile,"LT(<) (%p) type (",tree);
4631 printTypeChain(tree->ftype,outfile);
4632 fprintf(outfile,")\n");
4633 ast_print(tree->left,outfile,indent+4);
4634 ast_print(tree->right,outfile,indent+4);
4637 fprintf(outfile,"LE(<=) (%p) type (",tree);
4638 printTypeChain(tree->ftype,outfile);
4639 fprintf(outfile,")\n");
4640 ast_print(tree->left,outfile,indent+4);
4641 ast_print(tree->right,outfile,indent+4);
4644 fprintf(outfile,"GE(>=) (%p) type (",tree);
4645 printTypeChain(tree->ftype,outfile);
4646 fprintf(outfile,")\n");
4647 ast_print(tree->left,outfile,indent+4);
4648 ast_print(tree->right,outfile,indent+4);
4651 fprintf(outfile,"EQ(==) (%p) type (",tree);
4652 printTypeChain(tree->ftype,outfile);
4653 fprintf(outfile,")\n");
4654 ast_print(tree->left,outfile,indent+4);
4655 ast_print(tree->right,outfile,indent+4);
4658 fprintf(outfile,"NE(!=) (%p) type (",tree);
4659 printTypeChain(tree->ftype,outfile);
4660 fprintf(outfile,")\n");
4661 ast_print(tree->left,outfile,indent+4);
4662 ast_print(tree->right,outfile,indent+4);
4663 /*------------------------------------------------------------------*/
4664 /*----------------------------*/
4666 /*----------------------------*/
4667 case SIZEOF: /* evaluate wihout code generation */
4668 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4671 /*------------------------------------------------------------------*/
4672 /*----------------------------*/
4673 /* conditional operator '?' */
4674 /*----------------------------*/
4676 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4677 printTypeChain(tree->ftype,outfile);
4678 fprintf(outfile,")\n");
4679 ast_print(tree->left,outfile,indent+4);
4680 ast_print(tree->right,outfile,indent+4);
4684 fprintf(outfile,"COLON(:) (%p) type (",tree);
4685 printTypeChain(tree->ftype,outfile);
4686 fprintf(outfile,")\n");
4687 ast_print(tree->left,outfile,indent+4);
4688 ast_print(tree->right,outfile,indent+4);
4691 /*------------------------------------------------------------------*/
4692 /*----------------------------*/
4693 /* assignment operators */
4694 /*----------------------------*/
4696 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4697 printTypeChain(tree->ftype,outfile);
4698 fprintf(outfile,")\n");
4699 ast_print(tree->left,outfile,indent+4);
4700 ast_print(tree->right,outfile,indent+4);
4703 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4704 printTypeChain(tree->ftype,outfile);
4705 fprintf(outfile,")\n");
4706 ast_print(tree->left,outfile,indent+4);
4707 ast_print(tree->right,outfile,indent+4);
4710 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4711 printTypeChain(tree->ftype,outfile);
4712 fprintf(outfile,")\n");
4713 ast_print(tree->left,outfile,indent+4);
4714 ast_print(tree->right,outfile,indent+4);
4717 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4718 printTypeChain(tree->ftype,outfile);
4719 fprintf(outfile,")\n");
4720 ast_print(tree->left,outfile,indent+4);
4721 ast_print(tree->right,outfile,indent+4);
4724 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4725 printTypeChain(tree->ftype,outfile);
4726 fprintf(outfile,")\n");
4727 ast_print(tree->left,outfile,indent+4);
4728 ast_print(tree->right,outfile,indent+4);
4731 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4732 printTypeChain(tree->ftype,outfile);
4733 fprintf(outfile,")\n");
4734 ast_print(tree->left,outfile,indent+4);
4735 ast_print(tree->right,outfile,indent+4);
4738 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4739 printTypeChain(tree->ftype,outfile);
4740 fprintf(outfile,")\n");
4741 ast_print(tree->left,outfile,indent+4);
4742 ast_print(tree->right,outfile,indent+4);
4744 /*------------------------------------------------------------------*/
4745 /*----------------------------*/
4747 /*----------------------------*/
4749 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4750 printTypeChain(tree->ftype,outfile);
4751 fprintf(outfile,")\n");
4752 ast_print(tree->left,outfile,indent+4);
4753 ast_print(tree->right,outfile,indent+4);
4755 /*------------------------------------------------------------------*/
4756 /*----------------------------*/
4758 /*----------------------------*/
4760 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4761 printTypeChain(tree->ftype,outfile);
4762 fprintf(outfile,")\n");
4763 ast_print(tree->left,outfile,indent+4);
4764 ast_print(tree->right,outfile,indent+4);
4766 /*------------------------------------------------------------------*/
4767 /*----------------------------*/
4768 /* straight assignemnt */
4769 /*----------------------------*/
4771 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4772 printTypeChain(tree->ftype,outfile);
4773 fprintf(outfile,")\n");
4774 ast_print(tree->left,outfile,indent+4);
4775 ast_print(tree->right,outfile,indent+4);
4777 /*------------------------------------------------------------------*/
4778 /*----------------------------*/
4779 /* comma operator */
4780 /*----------------------------*/
4782 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4783 printTypeChain(tree->ftype,outfile);
4784 fprintf(outfile,")\n");
4785 ast_print(tree->left,outfile,indent+4);
4786 ast_print(tree->right,outfile,indent+4);
4788 /*------------------------------------------------------------------*/
4789 /*----------------------------*/
4791 /*----------------------------*/
4794 fprintf(outfile,"CALL (%p) type (",tree);
4795 printTypeChain(tree->ftype,outfile);
4796 fprintf(outfile,")\n");
4797 ast_print(tree->left,outfile,indent+4);
4798 ast_print(tree->right,outfile,indent+4);
4801 fprintf(outfile,"PARMS\n");
4802 ast_print(tree->left,outfile,indent+4);
4803 if (tree->right && !IS_AST_PARAM(tree->right)) {
4804 ast_print(tree->right,outfile,indent+4);
4807 /*------------------------------------------------------------------*/
4808 /*----------------------------*/
4809 /* return statement */
4810 /*----------------------------*/
4812 fprintf(outfile,"RETURN (%p) type (",tree);
4813 printTypeChain(tree->right->ftype,outfile);
4814 fprintf(outfile,")\n");
4815 ast_print(tree->right,outfile,indent+4);
4817 /*------------------------------------------------------------------*/
4818 /*----------------------------*/
4819 /* label statement */
4820 /*----------------------------*/
4822 fprintf(outfile,"LABEL (%p)",tree);
4823 ast_print(tree->left,outfile,indent+4);
4824 ast_print(tree->right,outfile,indent);
4826 /*------------------------------------------------------------------*/
4827 /*----------------------------*/
4828 /* switch statement */
4829 /*----------------------------*/
4833 fprintf(outfile,"SWITCH (%p) ",tree);
4834 ast_print(tree->left,outfile,0);
4835 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4836 INDENT(indent+4,outfile);
4837 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4838 (int) floatFromVal(val),
4839 tree->values.switchVals.swNum,
4840 (int) floatFromVal(val));
4842 ast_print(tree->right,outfile,indent);
4845 /*------------------------------------------------------------------*/
4846 /*----------------------------*/
4848 /*----------------------------*/
4850 fprintf(outfile,"IF (%p) \n",tree);
4851 ast_print(tree->left,outfile,indent+4);
4852 if (tree->trueLabel) {
4853 INDENT(indent,outfile);
4854 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4856 if (tree->falseLabel) {
4857 INDENT(indent,outfile);
4858 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4860 ast_print(tree->right,outfile,indent+4);
4862 /*------------------------------------------------------------------*/
4863 /*----------------------------*/
4865 /*----------------------------*/
4867 fprintf(outfile,"FOR (%p) \n",tree);
4868 if (AST_FOR( tree, initExpr)) {
4869 INDENT(indent+4,outfile);
4870 fprintf(outfile,"INIT EXPR ");
4871 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4873 if (AST_FOR( tree, condExpr)) {
4874 INDENT(indent+4,outfile);
4875 fprintf(outfile,"COND EXPR ");
4876 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4878 if (AST_FOR( tree, loopExpr)) {
4879 INDENT(indent+4,outfile);
4880 fprintf(outfile,"LOOP EXPR ");
4881 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4883 fprintf(outfile,"FOR LOOP BODY \n");
4884 ast_print(tree->left,outfile,indent+4);
4893 ast_print(t,stdout,0);