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 ftype = actParm->ftype;
667 /* If it's a small integer, upcast to int. */
668 if (IS_INTEGRAL (ftype)
669 && (getSize (ftype) < (unsigned) INTSIZE))
671 newType = newAst_LINK(INTTYPE);
674 if (IS_PTR(ftype) && !IS_GENPTR(ftype))
676 newType = newAst_LINK (copyLinkChain(ftype));
677 DCL_TYPE (newType->opval.lnk) = GPOINTER;
680 if (IS_AGGREGATE (ftype))
682 newType = newAst_LINK (copyLinkChain (ftype));
683 DCL_TYPE (newType->opval.lnk) = GPOINTER;
687 /* cast required; change this op to a cast. */
688 ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
690 actParm->type = EX_OP;
691 actParm->opval.op = CAST;
692 actParm->left = newType;
693 actParm->right = parmCopy;
694 decorateType (actParm);
696 else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
698 return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
699 processParms (func, NULL, actParm->right, parmNumber, rightmost));
704 /* if defined parameters ended but actual has not & */
706 if (!defParm && actParm &&
707 (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
710 resolveSymbols (actParm);
711 /* if this is a PARAM node then match left & right */
712 if (actParm->type == EX_OP && actParm->opval.op == PARAM)
714 return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
715 processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
719 /* If we have found a value node by following only right-hand links,
720 * then we know that there are no more values after us.
722 * Therefore, if there are more defined parameters, the caller didn't
725 if (rightmost && defParm->next)
727 werror (E_TOO_FEW_PARMS);
732 /* the parameter type must be at least castable */
733 if (compareType (defParm->type, actParm->ftype) == 0) {
734 werror (E_INCOMPAT_TYPES);
735 printFromToType (actParm->ftype, defParm->type);
739 /* if the parameter is castable then add the cast */
740 if (compareType (defParm->type, actParm->ftype) < 0)
742 ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
744 /* now change the current one to a cast */
745 actParm->type = EX_OP;
746 actParm->opval.op = CAST;
747 actParm->left = newAst_LINK (defParm->type);
748 actParm->right = pTree;
749 actParm->etype = defParm->etype;
750 actParm->ftype = defParm->type;
751 actParm->decorated=0; /* force typechecking */
752 decorateType (actParm);
755 /* make a copy and change the regparm type to the defined parm */
756 actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
757 SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
761 /*-----------------------------------------------------------------*/
762 /* createIvalType - generates ival for basic types */
763 /*-----------------------------------------------------------------*/
765 createIvalType (ast * sym, sym_link * type, initList * ilist)
769 /* if initList is deep */
770 if (ilist->type == INIT_DEEP)
771 ilist = ilist->init.deep;
773 iExpr = decorateType (resolveSymbols (list2expr (ilist)));
774 return decorateType (newNode ('=', sym, iExpr));
777 /*-----------------------------------------------------------------*/
778 /* createIvalStruct - generates initial value for structures */
779 /*-----------------------------------------------------------------*/
781 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
788 sflds = SPEC_STRUCT (type)->fields;
789 if (ilist->type != INIT_DEEP)
791 werror (E_INIT_STRUCT, "");
795 iloop = ilist->init.deep;
797 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
799 /* if we have come to end */
803 lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
804 lAst = decorateType (resolveSymbols (lAst));
805 rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
809 werror (W_EXCESS_INITIALIZERS, "struct",
810 sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
817 /*-----------------------------------------------------------------*/
818 /* createIvalArray - generates code for array initialization */
819 /*-----------------------------------------------------------------*/
821 createIvalArray (ast * sym, sym_link * type, initList * ilist)
825 int lcnt = 0, size = 0;
826 literalList *literalL;
828 /* take care of the special case */
829 /* array of characters can be init */
831 if (IS_CHAR (type->next))
832 if ((rast = createIvalCharPtr (sym,
834 decorateType (resolveSymbols (list2expr (ilist))))))
836 return decorateType (resolveSymbols (rast));
838 /* not the special case */
839 if (ilist->type != INIT_DEEP)
841 werror (E_INIT_STRUCT, "");
845 iloop = ilist->init.deep;
846 lcnt = DCL_ELEM (type);
848 if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
852 aSym = decorateType (resolveSymbols(sym));
854 rast = newNode(ARRAYINIT, aSym, NULL);
855 rast->values.constlist = literalL;
857 // Make sure size is set to length of initializer list.
864 if (lcnt && size > lcnt)
866 // Array size was specified, and we have more initializers than needed.
867 char *name=sym->opval.val->sym->name;
868 int lineno=sym->opval.val->sym->lineDef;
870 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
879 aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
880 aSym = decorateType (resolveSymbols (aSym));
881 rast = createIval (aSym, type->next, iloop, rast);
882 iloop = (iloop ? iloop->next : NULL);
888 /* no of elements given and we */
889 /* have generated for all of them */
892 // there has to be a better way
893 char *name=sym->opval.val->sym->name;
894 int lineno=sym->opval.val->sym->lineDef;
895 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
902 /* if we have not been given a size */
903 if (!DCL_ELEM (type))
905 DCL_ELEM (type) = size;
908 return decorateType (resolveSymbols (rast));
912 /*-----------------------------------------------------------------*/
913 /* createIvalCharPtr - generates initial values for char pointers */
914 /*-----------------------------------------------------------------*/
916 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
920 /* if this is a pointer & right is a literal array then */
921 /* just assignment will do */
922 if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
923 SPEC_SCLS (iexpr->etype) == S_CODE)
924 && IS_ARRAY (iexpr->ftype)))
925 return newNode ('=', sym, iexpr);
927 /* left side is an array so we have to assign each */
929 if ((IS_LITERAL (iexpr->etype) ||
930 SPEC_SCLS (iexpr->etype) == S_CODE)
931 && IS_ARRAY (iexpr->ftype))
933 /* for each character generate an assignment */
934 /* to the array element */
935 char *s = SPEC_CVAL (iexpr->etype).v_char;
940 rast = newNode (NULLOP,
944 newAst_VALUE (valueFromLit ((float) i))),
945 newAst_VALUE (valueFromLit (*s))));
949 rast = newNode (NULLOP,
953 newAst_VALUE (valueFromLit ((float) i))),
954 newAst_VALUE (valueFromLit (*s))));
955 return decorateType (resolveSymbols (rast));
961 /*-----------------------------------------------------------------*/
962 /* createIvalPtr - generates initial value for pointers */
963 /*-----------------------------------------------------------------*/
965 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
971 if (ilist->type == INIT_DEEP)
972 ilist = ilist->init.deep;
974 iexpr = decorateType (resolveSymbols (list2expr (ilist)));
976 /* if character pointer */
977 if (IS_CHAR (type->next))
978 if ((rast = createIvalCharPtr (sym, type, iexpr)))
981 return newNode ('=', sym, iexpr);
984 /*-----------------------------------------------------------------*/
985 /* createIval - generates code for initial value */
986 /*-----------------------------------------------------------------*/
988 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
995 /* if structure then */
996 if (IS_STRUCT (type))
997 rast = createIvalStruct (sym, type, ilist);
999 /* if this is a pointer */
1001 rast = createIvalPtr (sym, type, ilist);
1003 /* if this is an array */
1004 if (IS_ARRAY (type))
1005 rast = createIvalArray (sym, type, ilist);
1007 /* if type is SPECIFIER */
1009 rast = createIvalType (sym, type, ilist);
1012 return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1014 return decorateType (resolveSymbols (rast));
1017 /*-----------------------------------------------------------------*/
1018 /* initAggregates - initialises aggregate variables with initv */
1019 /*-----------------------------------------------------------------*/
1021 /* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
1023 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1027 if (getenv("TRY_THE_NEW_INITIALIZER")) {
1029 if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
1030 fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
1031 "with -mmcs51 and --model-large\n");
1035 if (SPEC_OCLS(sym->etype)==xdata &&
1036 getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
1039 newSym=copySymbol (sym);
1040 SPEC_OCLS(newSym->etype)=code;
1041 sprintf (newSym->name, "%s_init__", sym->name);
1042 sprintf (newSym->rname,"%s_init__", sym->rname);
1043 addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
1045 // emit it in the static segment
1046 addSet(&statsg->syms, newSym);
1048 // now memcpy() the entire array from cseg
1049 ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
1050 newAst_VALUE (symbolVal (sym)),
1051 newAst_VALUE (symbolVal (newSym)));
1052 return decorateType(resolveSymbols(ast));
1056 return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1059 /*-----------------------------------------------------------------*/
1060 /* gatherAutoInit - creates assignment expressions for initial */
1062 /*-----------------------------------------------------------------*/
1064 gatherAutoInit (symbol * autoChain)
1071 for (sym = autoChain; sym; sym = sym->next)
1074 /* resolve the symbols in the ival */
1076 resolveIvalSym (sym->ival);
1078 /* if this is a static variable & has an */
1079 /* initial value the code needs to be lifted */
1080 /* here to the main portion since they can be */
1081 /* initialised only once at the start */
1082 if (IS_STATIC (sym->etype) && sym->ival &&
1083 SPEC_SCLS (sym->etype) != S_CODE)
1087 // this can only be a constant
1088 if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
1089 werror (E_CONST_EXPECTED);
1092 /* insert the symbol into the symbol table */
1093 /* with level = 0 & name = rname */
1094 newSym = copySymbol (sym);
1095 addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1097 /* now lift the code to main */
1098 if (IS_AGGREGATE (sym->type))
1099 work = initAggregates (sym, sym->ival, NULL);
1101 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1102 list2expr (sym->ival));
1104 setAstLineno (work, sym->lineDef);
1108 staticAutos = newNode (NULLOP, staticAutos, work);
1115 /* if there is an initial value */
1116 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1118 if (IS_AGGREGATE (sym->type)) {
1119 work = initAggregates (sym, sym->ival, NULL);
1121 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1122 list2expr (sym->ival));
1125 setAstLineno (work, sym->lineDef);
1128 init = newNode (NULLOP, init, work);
1137 /*-----------------------------------------------------------------*/
1138 /* stringToSymbol - creates a symbol from a literal string */
1139 /*-----------------------------------------------------------------*/
1141 stringToSymbol (value * val)
1143 char name[SDCC_NAME_MAX + 1];
1144 static int charLbl = 0;
1147 sprintf (name, "_str_%d", charLbl++);
1148 sym = newSymbol (name, 0); /* make it @ level 0 */
1149 strcpy (sym->rname, name);
1151 /* copy the type from the value passed */
1152 sym->type = copyLinkChain (val->type);
1153 sym->etype = getSpec (sym->type);
1154 /* change to storage class & output class */
1155 SPEC_SCLS (sym->etype) = S_CODE;
1156 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1157 SPEC_STAT (sym->etype) = 1;
1158 /* make the level & block = 0 */
1159 sym->block = sym->level = 0;
1161 /* create an ival */
1162 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1167 allocVariables (sym);
1170 return symbolVal (sym);
1174 /*-----------------------------------------------------------------*/
1175 /* processBlockVars - will go thru the ast looking for block if */
1176 /* a block is found then will allocate the syms */
1177 /* will also gather the auto inits present */
1178 /*-----------------------------------------------------------------*/
1180 processBlockVars (ast * tree, int *stack, int action)
1185 /* if this is a block */
1186 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1190 if (action == ALLOCATE)
1192 *stack += allocVariables (tree->values.sym);
1193 autoInit = gatherAutoInit (tree->values.sym);
1195 /* if there are auto inits then do them */
1197 tree->left = newNode (NULLOP, autoInit, tree->left);
1199 else /* action is deallocate */
1200 deallocLocal (tree->values.sym);
1203 processBlockVars (tree->left, stack, action);
1204 processBlockVars (tree->right, stack, action);
1208 /*-----------------------------------------------------------------*/
1209 /* constExprValue - returns the value of a constant expression */
1210 /* or NULL if it is not a constant expression */
1211 /*-----------------------------------------------------------------*/
1213 constExprValue (ast * cexpr, int check)
1215 cexpr = decorateType (resolveSymbols (cexpr));
1217 /* if this is not a constant then */
1218 if (!IS_LITERAL (cexpr->ftype))
1220 /* then check if this is a literal array
1222 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1223 SPEC_CVAL (cexpr->etype).v_char &&
1224 IS_ARRAY (cexpr->ftype))
1226 value *val = valFromType (cexpr->ftype);
1227 SPEC_SCLS (val->etype) = S_LITERAL;
1228 val->sym = cexpr->opval.val->sym;
1229 val->sym->type = copyLinkChain (cexpr->ftype);
1230 val->sym->etype = getSpec (val->sym->type);
1231 strcpy (val->name, cexpr->opval.val->sym->rname);
1235 /* if we are casting a literal value then */
1236 if (IS_AST_OP (cexpr) &&
1237 cexpr->opval.op == CAST &&
1238 IS_LITERAL (cexpr->left->ftype))
1239 return valCastLiteral (cexpr->ftype,
1240 floatFromVal (cexpr->left->opval.val));
1242 if (IS_AST_VALUE (cexpr))
1243 return cexpr->opval.val;
1246 werror (E_CONST_EXPECTED, "found expression");
1251 /* return the value */
1252 return cexpr->opval.val;
1256 /*-----------------------------------------------------------------*/
1257 /* isLabelInAst - will return true if a given label is found */
1258 /*-----------------------------------------------------------------*/
1260 isLabelInAst (symbol * label, ast * tree)
1262 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1265 if (IS_AST_OP (tree) &&
1266 tree->opval.op == LABEL &&
1267 isSymbolEqual (AST_SYMBOL (tree->left), label))
1270 return isLabelInAst (label, tree->right) &&
1271 isLabelInAst (label, tree->left);
1275 /*-----------------------------------------------------------------*/
1276 /* isLoopCountable - return true if the loop count can be determi- */
1277 /* -ned at compile time . */
1278 /*-----------------------------------------------------------------*/
1280 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1281 symbol ** sym, ast ** init, ast ** end)
1284 /* the loop is considered countable if the following
1285 conditions are true :-
1287 a) initExpr :- <sym> = <const>
1288 b) condExpr :- <sym> < <const1>
1289 c) loopExpr :- <sym> ++
1292 /* first check the initExpr */
1293 if (IS_AST_OP (initExpr) &&
1294 initExpr->opval.op == '=' && /* is assignment */
1295 IS_AST_SYM_VALUE (initExpr->left))
1296 { /* left is a symbol */
1298 *sym = AST_SYMBOL (initExpr->left);
1299 *init = initExpr->right;
1304 /* for now the symbol has to be of
1306 if (!IS_INTEGRAL ((*sym)->type))
1309 /* now check condExpr */
1310 if (IS_AST_OP (condExpr))
1313 switch (condExpr->opval.op)
1316 if (IS_AST_SYM_VALUE (condExpr->left) &&
1317 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1318 IS_AST_LIT_VALUE (condExpr->right))
1320 *end = condExpr->right;
1326 if (IS_AST_OP (condExpr->left) &&
1327 condExpr->left->opval.op == '>' &&
1328 IS_AST_LIT_VALUE (condExpr->left->right) &&
1329 IS_AST_SYM_VALUE (condExpr->left->left) &&
1330 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1333 *end = newNode ('+', condExpr->left->right,
1334 newAst_VALUE (constVal ("1")));
1345 /* check loop expression is of the form <sym>++ */
1346 if (!IS_AST_OP (loopExpr))
1349 /* check if <sym> ++ */
1350 if (loopExpr->opval.op == INC_OP)
1356 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1357 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1364 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1365 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1373 if (loopExpr->opval.op == ADD_ASSIGN)
1376 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1377 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1378 IS_AST_LIT_VALUE (loopExpr->right) &&
1379 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1387 /*-----------------------------------------------------------------*/
1388 /* astHasVolatile - returns true if ast contains any volatile */
1389 /*-----------------------------------------------------------------*/
1391 astHasVolatile (ast * tree)
1396 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1399 if (IS_AST_OP (tree))
1400 return astHasVolatile (tree->left) ||
1401 astHasVolatile (tree->right);
1406 /*-----------------------------------------------------------------*/
1407 /* astHasPointer - return true if the ast contains any ptr variable */
1408 /*-----------------------------------------------------------------*/
1410 astHasPointer (ast * tree)
1415 if (IS_AST_LINK (tree))
1418 /* if we hit an array expression then check
1419 only the left side */
1420 if (IS_AST_OP (tree) && tree->opval.op == '[')
1421 return astHasPointer (tree->left);
1423 if (IS_AST_VALUE (tree))
1424 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1426 return astHasPointer (tree->left) ||
1427 astHasPointer (tree->right);
1431 /*-----------------------------------------------------------------*/
1432 /* astHasSymbol - return true if the ast has the given symbol */
1433 /*-----------------------------------------------------------------*/
1435 astHasSymbol (ast * tree, symbol * sym)
1437 if (!tree || IS_AST_LINK (tree))
1440 if (IS_AST_VALUE (tree))
1442 if (IS_AST_SYM_VALUE (tree))
1443 return isSymbolEqual (AST_SYMBOL (tree), sym);
1448 return astHasSymbol (tree->left, sym) ||
1449 astHasSymbol (tree->right, sym);
1452 /*-----------------------------------------------------------------*/
1453 /* astHasDeref - return true if the ast has an indirect access */
1454 /*-----------------------------------------------------------------*/
1456 astHasDeref (ast * tree)
1458 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1461 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1463 return astHasDeref (tree->left) || astHasDeref (tree->right);
1466 /*-----------------------------------------------------------------*/
1467 /* isConformingBody - the loop body has to conform to a set of rules */
1468 /* for the loop to be considered reversible read on for rules */
1469 /*-----------------------------------------------------------------*/
1471 isConformingBody (ast * pbody, symbol * sym, ast * body)
1474 /* we are going to do a pre-order traversal of the
1475 tree && check for the following conditions. (essentially
1476 a set of very shallow tests )
1477 a) the sym passed does not participate in
1478 any arithmetic operation
1479 b) There are no function calls
1480 c) all jumps are within the body
1481 d) address of loop control variable not taken
1482 e) if an assignment has a pointer on the
1483 left hand side make sure right does not have
1484 loop control variable */
1486 /* if we reach the end or a leaf then true */
1487 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1491 /* if anything else is "volatile" */
1492 if (IS_VOLATILE (TETYPE (pbody)))
1495 /* we will walk the body in a pre-order traversal for
1497 switch (pbody->opval.op)
1499 /*------------------------------------------------------------------*/
1501 return isConformingBody (pbody->right, sym, body);
1503 /*------------------------------------------------------------------*/
1508 /*------------------------------------------------------------------*/
1509 case INC_OP: /* incerement operator unary so left only */
1512 /* sure we are not sym is not modified */
1514 IS_AST_SYM_VALUE (pbody->left) &&
1515 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1519 IS_AST_SYM_VALUE (pbody->right) &&
1520 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1525 /*------------------------------------------------------------------*/
1527 case '*': /* can be unary : if right is null then unary operation */
1532 /* if right is NULL then unary operation */
1533 /*------------------------------------------------------------------*/
1534 /*----------------------------*/
1536 /*----------------------------*/
1539 if (IS_AST_SYM_VALUE (pbody->left) &&
1540 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1543 return isConformingBody (pbody->left, sym, body);
1547 if (astHasSymbol (pbody->left, sym) ||
1548 astHasSymbol (pbody->right, sym))
1553 /*------------------------------------------------------------------*/
1561 if (IS_AST_SYM_VALUE (pbody->left) &&
1562 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1565 if (IS_AST_SYM_VALUE (pbody->right) &&
1566 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1569 return isConformingBody (pbody->left, sym, body) &&
1570 isConformingBody (pbody->right, sym, body);
1577 if (IS_AST_SYM_VALUE (pbody->left) &&
1578 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1580 return isConformingBody (pbody->left, sym, body);
1582 /*------------------------------------------------------------------*/
1594 case SIZEOF: /* evaluate wihout code generation */
1596 return isConformingBody (pbody->left, sym, body) &&
1597 isConformingBody (pbody->right, sym, body);
1599 /*------------------------------------------------------------------*/
1602 /* if left has a pointer & right has loop
1603 control variable then we cannot */
1604 if (astHasPointer (pbody->left) &&
1605 astHasSymbol (pbody->right, sym))
1607 if (astHasVolatile (pbody->left))
1610 if (IS_AST_SYM_VALUE (pbody->left) &&
1611 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1614 if (astHasVolatile (pbody->left))
1617 if (astHasDeref(pbody->right)) return FALSE;
1619 return isConformingBody (pbody->left, sym, body) &&
1620 isConformingBody (pbody->right, sym, body);
1631 assert ("Parser should not have generated this\n");
1633 /*------------------------------------------------------------------*/
1634 /*----------------------------*/
1635 /* comma operator */
1636 /*----------------------------*/
1638 return isConformingBody (pbody->left, sym, body) &&
1639 isConformingBody (pbody->right, sym, body);
1641 /*------------------------------------------------------------------*/
1642 /*----------------------------*/
1644 /*----------------------------*/
1648 /*------------------------------------------------------------------*/
1649 /*----------------------------*/
1650 /* return statement */
1651 /*----------------------------*/
1656 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1661 if (astHasSymbol (pbody->left, sym))
1668 return isConformingBody (pbody->left, sym, body) &&
1669 isConformingBody (pbody->right, sym, body);
1675 /*-----------------------------------------------------------------*/
1676 /* isLoopReversible - takes a for loop as input && returns true */
1677 /* if the for loop is reversible. If yes will set the value of */
1678 /* the loop control var & init value & termination value */
1679 /*-----------------------------------------------------------------*/
1681 isLoopReversible (ast * loop, symbol ** loopCntrl,
1682 ast ** init, ast ** end)
1684 /* if option says don't do it then don't */
1685 if (optimize.noLoopReverse)
1687 /* there are several tests to determine this */
1689 /* for loop has to be of the form
1690 for ( <sym> = <const1> ;
1691 [<sym> < <const2>] ;
1692 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1694 if (!isLoopCountable (AST_FOR (loop, initExpr),
1695 AST_FOR (loop, condExpr),
1696 AST_FOR (loop, loopExpr),
1697 loopCntrl, init, end))
1700 /* now do some serious checking on the body of the loop
1703 return isConformingBody (loop->left, *loopCntrl, loop->left);
1707 /*-----------------------------------------------------------------*/
1708 /* replLoopSym - replace the loop sym by loop sym -1 */
1709 /*-----------------------------------------------------------------*/
1711 replLoopSym (ast * body, symbol * sym)
1714 if (!body || IS_AST_LINK (body))
1717 if (IS_AST_SYM_VALUE (body))
1720 if (isSymbolEqual (AST_SYMBOL (body), sym))
1724 body->opval.op = '-';
1725 body->left = newAst_VALUE (symbolVal (sym));
1726 body->right = newAst_VALUE (constVal ("1"));
1734 replLoopSym (body->left, sym);
1735 replLoopSym (body->right, sym);
1739 /*-----------------------------------------------------------------*/
1740 /* reverseLoop - do the actual loop reversal */
1741 /*-----------------------------------------------------------------*/
1743 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1747 /* create the following tree
1752 if (sym) goto for_continue ;
1755 /* put it together piece by piece */
1756 rloop = newNode (NULLOP,
1757 createIf (newAst_VALUE (symbolVal (sym)),
1759 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1762 newAst_VALUE (symbolVal (sym)),
1765 replLoopSym (loop->left, sym);
1767 rloop = newNode (NULLOP,
1769 newAst_VALUE (symbolVal (sym)),
1770 newNode ('-', end, init)),
1771 createLabel (AST_FOR (loop, continueLabel),
1775 newNode (SUB_ASSIGN,
1776 newAst_VALUE (symbolVal (sym)),
1777 newAst_VALUE (constVal ("1"))),
1780 return decorateType (rloop);
1784 //#define DEMAND_INTEGER_PROMOTION
1786 #ifdef DEMAND_INTEGER_PROMOTION
1788 /*-----------------------------------------------------------------*/
1789 /* walk a tree looking for the leaves. Add a typecast to the given */
1790 /* type to each value leaf node. */
1791 /*-----------------------------------------------------------------*/
1793 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1795 if (!node || IS_CALLOP(node))
1797 /* WTF? We should never get here. */
1801 if (!node->left && !node->right)
1803 /* We're at a leaf; if it's a value, apply the typecast */
1804 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1806 *parentPtr = decorateType (newNode (CAST,
1807 newAst_LINK (copyLinkChain (type)),
1815 pushTypeCastToLeaves (type, node->left, &(node->left));
1819 pushTypeCastToLeaves (type, node->right, &(node->right));
1826 /*-----------------------------------------------------------------*/
1827 /* decorateType - compute type for this tree also does type cheking */
1828 /* this is done bottom up, since type have to flow upwards */
1829 /* it also does constant folding, and paramater checking */
1830 /*-----------------------------------------------------------------*/
1832 decorateType (ast * tree)
1840 /* if already has type then do nothing */
1841 if (tree->decorated)
1844 tree->decorated = 1;
1846 /* print the line */
1847 /* if not block & function */
1848 if (tree->type == EX_OP &&
1849 (tree->opval.op != FUNCTION &&
1850 tree->opval.op != BLOCK &&
1851 tree->opval.op != NULLOP))
1853 filename = tree->filename;
1854 lineno = tree->lineno;
1857 /* if any child is an error | this one is an error do nothing */
1858 if (tree->isError ||
1859 (tree->left && tree->left->isError) ||
1860 (tree->right && tree->right->isError))
1863 /*------------------------------------------------------------------*/
1864 /*----------------------------*/
1865 /* leaf has been reached */
1866 /*----------------------------*/
1867 /* if this is of type value */
1868 /* just get the type */
1869 if (tree->type == EX_VALUE)
1872 if (IS_LITERAL (tree->opval.val->etype))
1875 /* if this is a character array then declare it */
1876 if (IS_ARRAY (tree->opval.val->type))
1877 tree->opval.val = stringToSymbol (tree->opval.val);
1879 /* otherwise just copy the type information */
1880 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1884 if (tree->opval.val->sym)
1886 /* if the undefined flag is set then give error message */
1887 if (tree->opval.val->sym->undefined)
1889 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1891 TTYPE (tree) = TETYPE (tree) =
1892 tree->opval.val->type = tree->opval.val->sym->type =
1893 tree->opval.val->etype = tree->opval.val->sym->etype =
1894 copyLinkChain (INTTYPE);
1899 /* if impilicit i.e. struct/union member then no type */
1900 if (tree->opval.val->sym->implicit)
1901 TTYPE (tree) = TETYPE (tree) = NULL;
1906 /* else copy the type */
1907 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1909 /* and mark it as referenced */
1910 tree->opval.val->sym->isref = 1;
1918 /* if type link for the case of cast */
1919 if (tree->type == EX_LINK)
1921 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1928 dtl = decorateType (tree->left);
1929 dtr = decorateType (tree->right);
1931 /* this is to take care of situations
1932 when the tree gets rewritten */
1933 if (dtl != tree->left)
1935 if (dtr != tree->right)
1939 /* depending on type of operator do */
1941 switch (tree->opval.op)
1943 /*------------------------------------------------------------------*/
1944 /*----------------------------*/
1946 /*----------------------------*/
1949 /* determine which is the array & which the index */
1950 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1953 ast *tempTree = tree->left;
1954 tree->left = tree->right;
1955 tree->right = tempTree;
1958 /* first check if this is a array or a pointer */
1959 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1961 werror (E_NEED_ARRAY_PTR, "[]");
1962 goto errorTreeReturn;
1965 /* check if the type of the idx */
1966 if (!IS_INTEGRAL (RTYPE (tree)))
1968 werror (E_IDX_NOT_INT);
1969 goto errorTreeReturn;
1972 /* if the left is an rvalue then error */
1975 werror (E_LVALUE_REQUIRED, "array access");
1976 goto errorTreeReturn;
1979 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1980 if (IS_PTR(LTYPE(tree))) {
1981 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1985 /*------------------------------------------------------------------*/
1986 /*----------------------------*/
1988 /*----------------------------*/
1990 /* if this is not a structure */
1991 if (!IS_STRUCT (LTYPE (tree)))
1993 werror (E_STRUCT_UNION, ".");
1994 goto errorTreeReturn;
1996 TTYPE (tree) = structElemType (LTYPE (tree),
1997 (tree->right->type == EX_VALUE ?
1998 tree->right->opval.val : NULL));
1999 TETYPE (tree) = getSpec (TTYPE (tree));
2002 /*------------------------------------------------------------------*/
2003 /*----------------------------*/
2004 /* struct/union pointer */
2005 /*----------------------------*/
2007 /* if not pointer to a structure */
2008 if (!IS_PTR (LTYPE (tree)))
2010 werror (E_PTR_REQD);
2011 goto errorTreeReturn;
2014 if (!IS_STRUCT (LTYPE (tree)->next))
2016 werror (E_STRUCT_UNION, "->");
2017 goto errorTreeReturn;
2020 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2021 (tree->right->type == EX_VALUE ?
2022 tree->right->opval.val : NULL));
2023 TETYPE (tree) = getSpec (TTYPE (tree));
2026 /*------------------------------------------------------------------*/
2027 /*----------------------------*/
2028 /* ++/-- operation */
2029 /*----------------------------*/
2030 case INC_OP: /* incerement operator unary so left only */
2033 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2034 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2035 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2036 werror (E_CODE_WRITE, "++/--");
2045 /*------------------------------------------------------------------*/
2046 /*----------------------------*/
2048 /*----------------------------*/
2049 case '&': /* can be unary */
2050 /* if right is NULL then unary operation */
2051 if (tree->right) /* not an unary operation */
2054 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2056 werror (E_BITWISE_OP);
2057 werror (W_CONTINUE, "left & right types are ");
2058 printTypeChain (LTYPE (tree), stderr);
2059 fprintf (stderr, ",");
2060 printTypeChain (RTYPE (tree), stderr);
2061 fprintf (stderr, "\n");
2062 goto errorTreeReturn;
2065 /* if they are both literal */
2066 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2068 tree->type = EX_VALUE;
2069 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2070 valFromType (RETYPE (tree)), '&');
2072 tree->right = tree->left = NULL;
2073 TETYPE (tree) = tree->opval.val->etype;
2074 TTYPE (tree) = tree->opval.val->type;
2078 /* see if this is a GETHBIT operation if yes
2081 ast *otree = optimizeGetHbit (tree);
2084 return decorateType (otree);
2088 computeType (LTYPE (tree), RTYPE (tree));
2089 TETYPE (tree) = getSpec (TTYPE (tree));
2091 LRVAL (tree) = RRVAL (tree) = 1;
2095 /*------------------------------------------------------------------*/
2096 /*----------------------------*/
2098 /*----------------------------*/
2100 p->class = DECLARATOR;
2101 /* if bit field then error */
2102 if (IS_BITVAR (tree->left->etype))
2104 werror (E_ILLEGAL_ADDR, "address of bit variable");
2105 goto errorTreeReturn;
2108 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2110 werror (E_ILLEGAL_ADDR, "address of register variable");
2111 goto errorTreeReturn;
2114 if (IS_FUNC (LTYPE (tree)))
2116 werror (E_ILLEGAL_ADDR, "address of function");
2117 goto errorTreeReturn;
2120 if (IS_LITERAL(LTYPE(tree)))
2122 werror (E_ILLEGAL_ADDR, "address of literal");
2123 goto errorTreeReturn;
2128 werror (E_LVALUE_REQUIRED, "address of");
2129 goto errorTreeReturn;
2131 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2133 DCL_TYPE (p) = CPOINTER;
2134 DCL_PTR_CONST (p) = port->mem.code_ro;
2136 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2137 DCL_TYPE (p) = FPOINTER;
2138 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2139 DCL_TYPE (p) = PPOINTER;
2140 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2141 DCL_TYPE (p) = IPOINTER;
2142 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2143 DCL_TYPE (p) = EEPPOINTER;
2145 DCL_TYPE (p) = POINTER;
2147 if (IS_AST_SYM_VALUE (tree->left))
2149 AST_SYMBOL (tree->left)->addrtaken = 1;
2150 AST_SYMBOL (tree->left)->allocreq = 1;
2153 p->next = LTYPE (tree);
2155 TETYPE (tree) = getSpec (TTYPE (tree));
2156 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2157 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2162 /*------------------------------------------------------------------*/
2163 /*----------------------------*/
2165 /*----------------------------*/
2167 /* if the rewrite succeeds then don't go any furthur */
2169 ast *wtree = optimizeRRCRLC (tree);
2171 return decorateType (wtree);
2173 /*------------------------------------------------------------------*/
2174 /*----------------------------*/
2176 /*----------------------------*/
2178 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2180 werror (E_BITWISE_OP);
2181 werror (W_CONTINUE, "left & right types are ");
2182 printTypeChain (LTYPE (tree), stderr);
2183 fprintf (stderr, ",");
2184 printTypeChain (RTYPE (tree), stderr);
2185 fprintf (stderr, "\n");
2186 goto errorTreeReturn;
2189 /* if they are both literal then */
2190 /* rewrite the tree */
2191 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2193 tree->type = EX_VALUE;
2194 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2195 valFromType (RETYPE (tree)),
2197 tree->right = tree->left = NULL;
2198 TETYPE (tree) = tree->opval.val->etype;
2199 TTYPE (tree) = tree->opval.val->type;
2202 LRVAL (tree) = RRVAL (tree) = 1;
2203 TETYPE (tree) = getSpec (TTYPE (tree) =
2204 computeType (LTYPE (tree),
2207 /*------------------------------------------------------------------*/
2208 /*----------------------------*/
2210 /*----------------------------*/
2212 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2214 werror (E_INVALID_OP, "divide");
2215 goto errorTreeReturn;
2217 /* if they are both literal then */
2218 /* rewrite the tree */
2219 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2221 tree->type = EX_VALUE;
2222 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2223 valFromType (RETYPE (tree)));
2224 tree->right = tree->left = NULL;
2225 TETYPE (tree) = getSpec (TTYPE (tree) =
2226 tree->opval.val->type);
2229 LRVAL (tree) = RRVAL (tree) = 1;
2230 TETYPE (tree) = getSpec (TTYPE (tree) =
2231 computeType (LTYPE (tree),
2235 /*------------------------------------------------------------------*/
2236 /*----------------------------*/
2238 /*----------------------------*/
2240 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2242 werror (E_BITWISE_OP);
2243 werror (W_CONTINUE, "left & right types are ");
2244 printTypeChain (LTYPE (tree), stderr);
2245 fprintf (stderr, ",");
2246 printTypeChain (RTYPE (tree), stderr);
2247 fprintf (stderr, "\n");
2248 goto errorTreeReturn;
2250 /* if they are both literal then */
2251 /* rewrite the tree */
2252 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2254 tree->type = EX_VALUE;
2255 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2256 valFromType (RETYPE (tree)));
2257 tree->right = tree->left = NULL;
2258 TETYPE (tree) = getSpec (TTYPE (tree) =
2259 tree->opval.val->type);
2262 LRVAL (tree) = RRVAL (tree) = 1;
2263 TETYPE (tree) = getSpec (TTYPE (tree) =
2264 computeType (LTYPE (tree),
2268 /*------------------------------------------------------------------*/
2269 /*----------------------------*/
2270 /* address dereference */
2271 /*----------------------------*/
2272 case '*': /* can be unary : if right is null then unary operation */
2275 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2277 werror (E_PTR_REQD);
2278 goto errorTreeReturn;
2283 werror (E_LVALUE_REQUIRED, "pointer deref");
2284 goto errorTreeReturn;
2286 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2287 LTYPE (tree)->next : NULL);
2288 TETYPE (tree) = getSpec (TTYPE (tree));
2289 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2293 /*------------------------------------------------------------------*/
2294 /*----------------------------*/
2295 /* multiplication */
2296 /*----------------------------*/
2297 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2299 werror (E_INVALID_OP, "multiplication");
2300 goto errorTreeReturn;
2303 /* if they are both literal then */
2304 /* rewrite the tree */
2305 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2307 tree->type = EX_VALUE;
2308 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2309 valFromType (RETYPE (tree)));
2310 tree->right = tree->left = NULL;
2311 TETYPE (tree) = getSpec (TTYPE (tree) =
2312 tree->opval.val->type);
2316 /* if left is a literal exchange left & right */
2317 if (IS_LITERAL (LTYPE (tree)))
2319 ast *tTree = tree->left;
2320 tree->left = tree->right;
2321 tree->right = tTree;
2324 LRVAL (tree) = RRVAL (tree) = 1;
2325 /* promote result to int if left & right are char
2326 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2327 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2328 TETYPE (tree) = getSpec (TTYPE (tree) =
2329 computeType (LTYPE (tree),
2331 SPEC_NOUN(TETYPE(tree)) = V_INT;
2333 TETYPE (tree) = getSpec (TTYPE (tree) =
2334 computeType (LTYPE (tree),
2339 /*------------------------------------------------------------------*/
2340 /*----------------------------*/
2341 /* unary '+' operator */
2342 /*----------------------------*/
2347 if (!IS_INTEGRAL (LTYPE (tree)))
2349 werror (E_UNARY_OP, '+');
2350 goto errorTreeReturn;
2353 /* if left is a literal then do it */
2354 if (IS_LITERAL (LTYPE (tree)))
2356 tree->type = EX_VALUE;
2357 tree->opval.val = valFromType (LETYPE (tree));
2359 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2363 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2367 /*------------------------------------------------------------------*/
2368 /*----------------------------*/
2370 /*----------------------------*/
2372 /* this is not a unary operation */
2373 /* if both pointers then problem */
2374 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2375 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2377 werror (E_PTR_PLUS_PTR);
2378 goto errorTreeReturn;
2381 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2382 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2384 werror (E_PLUS_INVALID, "+");
2385 goto errorTreeReturn;
2388 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2389 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2391 werror (E_PLUS_INVALID, "+");
2392 goto errorTreeReturn;
2394 /* if they are both literal then */
2395 /* rewrite the tree */
2396 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2398 tree->type = EX_VALUE;
2399 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2400 valFromType (RETYPE (tree)));
2401 tree->right = tree->left = NULL;
2402 TETYPE (tree) = getSpec (TTYPE (tree) =
2403 tree->opval.val->type);
2407 /* if the right is a pointer or left is a literal
2408 xchange left & right */
2409 if (IS_ARRAY (RTYPE (tree)) ||
2410 IS_PTR (RTYPE (tree)) ||
2411 IS_LITERAL (LTYPE (tree)))
2413 ast *tTree = tree->left;
2414 tree->left = tree->right;
2415 tree->right = tTree;
2418 LRVAL (tree) = RRVAL (tree) = 1;
2419 /* if the left is a pointer */
2420 if (IS_PTR (LTYPE (tree)))
2421 TETYPE (tree) = getSpec (TTYPE (tree) =
2424 TETYPE (tree) = getSpec (TTYPE (tree) =
2425 computeType (LTYPE (tree),
2429 /*------------------------------------------------------------------*/
2430 /*----------------------------*/
2432 /*----------------------------*/
2433 case '-': /* can be unary */
2434 /* if right is null then unary */
2438 if (!IS_ARITHMETIC (LTYPE (tree)))
2440 werror (E_UNARY_OP, tree->opval.op);
2441 goto errorTreeReturn;
2444 /* if left is a literal then do it */
2445 if (IS_LITERAL (LTYPE (tree)))
2447 tree->type = EX_VALUE;
2448 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2450 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2451 SPEC_USIGN(TETYPE(tree)) = 0;
2455 TTYPE (tree) = LTYPE (tree);
2459 /*------------------------------------------------------------------*/
2460 /*----------------------------*/
2462 /*----------------------------*/
2464 if (!(IS_PTR (LTYPE (tree)) ||
2465 IS_ARRAY (LTYPE (tree)) ||
2466 IS_ARITHMETIC (LTYPE (tree))))
2468 werror (E_PLUS_INVALID, "-");
2469 goto errorTreeReturn;
2472 if (!(IS_PTR (RTYPE (tree)) ||
2473 IS_ARRAY (RTYPE (tree)) ||
2474 IS_ARITHMETIC (RTYPE (tree))))
2476 werror (E_PLUS_INVALID, "-");
2477 goto errorTreeReturn;
2480 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2481 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2482 IS_INTEGRAL (RTYPE (tree))))
2484 werror (E_PLUS_INVALID, "-");
2485 goto errorTreeReturn;
2488 /* if they are both literal then */
2489 /* rewrite the tree */
2490 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2492 tree->type = EX_VALUE;
2493 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2494 valFromType (RETYPE (tree)));
2495 tree->right = tree->left = NULL;
2496 TETYPE (tree) = getSpec (TTYPE (tree) =
2497 tree->opval.val->type);
2501 /* if the left & right are equal then zero */
2502 if (isAstEqual (tree->left, tree->right))
2504 tree->type = EX_VALUE;
2505 tree->left = tree->right = NULL;
2506 tree->opval.val = constVal ("0");
2507 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2511 /* if both of them are pointers or arrays then */
2512 /* the result is going to be an integer */
2513 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2514 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2515 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2517 /* if only the left is a pointer */
2518 /* then result is a pointer */
2519 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2520 TETYPE (tree) = getSpec (TTYPE (tree) =
2523 TETYPE (tree) = getSpec (TTYPE (tree) =
2524 computeType (LTYPE (tree),
2526 LRVAL (tree) = RRVAL (tree) = 1;
2529 /*------------------------------------------------------------------*/
2530 /*----------------------------*/
2532 /*----------------------------*/
2534 /* can be only integral type */
2535 if (!IS_INTEGRAL (LTYPE (tree)))
2537 werror (E_UNARY_OP, tree->opval.op);
2538 goto errorTreeReturn;
2541 /* if left is a literal then do it */
2542 if (IS_LITERAL (LTYPE (tree)))
2544 tree->type = EX_VALUE;
2545 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2547 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2551 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2554 /*------------------------------------------------------------------*/
2555 /*----------------------------*/
2557 /*----------------------------*/
2559 /* can be pointer */
2560 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2561 !IS_PTR (LTYPE (tree)) &&
2562 !IS_ARRAY (LTYPE (tree)))
2564 werror (E_UNARY_OP, tree->opval.op);
2565 goto errorTreeReturn;
2568 /* if left is a literal then do it */
2569 if (IS_LITERAL (LTYPE (tree)))
2571 tree->type = EX_VALUE;
2572 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2574 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2578 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2581 /*------------------------------------------------------------------*/
2582 /*----------------------------*/
2584 /*----------------------------*/
2587 TTYPE (tree) = LTYPE (tree);
2588 TETYPE (tree) = LETYPE (tree);
2592 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2597 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2599 werror (E_SHIFT_OP_INVALID);
2600 werror (W_CONTINUE, "left & right types are ");
2601 printTypeChain (LTYPE (tree), stderr);
2602 fprintf (stderr, ",");
2603 printTypeChain (RTYPE (tree), stderr);
2604 fprintf (stderr, "\n");
2605 goto errorTreeReturn;
2608 /* if they are both literal then */
2609 /* rewrite the tree */
2610 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2612 tree->type = EX_VALUE;
2613 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2614 valFromType (RETYPE (tree)),
2615 (tree->opval.op == LEFT_OP ? 1 : 0));
2616 tree->right = tree->left = NULL;
2617 TETYPE (tree) = getSpec (TTYPE (tree) =
2618 tree->opval.val->type);
2621 /* if only the right side is a literal & we are
2622 shifting more than size of the left operand then zero */
2623 if (IS_LITERAL (RTYPE (tree)) &&
2624 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2625 (getSize (LTYPE (tree)) * 8))
2627 werror (W_SHIFT_CHANGED,
2628 (tree->opval.op == LEFT_OP ? "left" : "right"));
2629 tree->type = EX_VALUE;
2630 tree->left = tree->right = NULL;
2631 tree->opval.val = constVal ("0");
2632 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2635 LRVAL (tree) = RRVAL (tree) = 1;
2636 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2638 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2642 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2646 /*------------------------------------------------------------------*/
2647 /*----------------------------*/
2649 /*----------------------------*/
2650 case CAST: /* change the type */
2651 /* cannot cast to an aggregate type */
2652 if (IS_AGGREGATE (LTYPE (tree)))
2654 werror (E_CAST_ILLEGAL);
2655 goto errorTreeReturn;
2658 /* make sure the type is complete and sane */
2659 checkTypeSanity(LETYPE(tree), "(cast)");
2662 /* if the right is a literal replace the tree */
2663 if (IS_LITERAL (RETYPE (tree))) {
2664 if (!IS_PTR (LTYPE (tree))) {
2665 tree->type = EX_VALUE;
2667 valCastLiteral (LTYPE (tree),
2668 floatFromVal (valFromType (RETYPE (tree))));
2671 TTYPE (tree) = tree->opval.val->type;
2672 tree->values.literalFromCast = 1;
2673 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2674 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2675 sym_link *rest = LTYPE(tree)->next;
2676 werror(W_LITERAL_GENERIC);
2677 TTYPE(tree) = newLink();
2678 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2679 TTYPE(tree)->next = rest;
2680 tree->left->opval.lnk = TTYPE(tree);
2683 TTYPE (tree) = LTYPE (tree);
2687 TTYPE (tree) = LTYPE (tree);
2691 /* if pointer to struct then check names */
2692 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2693 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2694 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2695 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2697 /* if the right is a literal replace the tree */
2698 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2699 tree->type = EX_VALUE;
2701 valCastLiteral (LTYPE (tree),
2702 floatFromVal (valFromType (RETYPE (tree))));
2705 TTYPE (tree) = tree->opval.val->type;
2706 tree->values.literalFromCast = 1;
2708 TTYPE (tree) = LTYPE (tree);
2712 TETYPE (tree) = getSpec (TTYPE (tree));
2716 /*------------------------------------------------------------------*/
2717 /*----------------------------*/
2718 /* logical &&, || */
2719 /*----------------------------*/
2722 /* each must me arithmetic type or be a pointer */
2723 if (!IS_PTR (LTYPE (tree)) &&
2724 !IS_ARRAY (LTYPE (tree)) &&
2725 !IS_INTEGRAL (LTYPE (tree)))
2727 werror (E_COMPARE_OP);
2728 goto errorTreeReturn;
2731 if (!IS_PTR (RTYPE (tree)) &&
2732 !IS_ARRAY (RTYPE (tree)) &&
2733 !IS_INTEGRAL (RTYPE (tree)))
2735 werror (E_COMPARE_OP);
2736 goto errorTreeReturn;
2738 /* if they are both literal then */
2739 /* rewrite the tree */
2740 if (IS_LITERAL (RTYPE (tree)) &&
2741 IS_LITERAL (LTYPE (tree)))
2743 tree->type = EX_VALUE;
2744 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2745 valFromType (RETYPE (tree)),
2747 tree->right = tree->left = NULL;
2748 TETYPE (tree) = getSpec (TTYPE (tree) =
2749 tree->opval.val->type);
2752 LRVAL (tree) = RRVAL (tree) = 1;
2753 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2756 /*------------------------------------------------------------------*/
2757 /*----------------------------*/
2758 /* comparison operators */
2759 /*----------------------------*/
2767 ast *lt = optimizeCompare (tree);
2773 /* if they are pointers they must be castable */
2774 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2776 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2778 werror (E_COMPARE_OP);
2779 fprintf (stderr, "comparing type ");
2780 printTypeChain (LTYPE (tree), stderr);
2781 fprintf (stderr, "to type ");
2782 printTypeChain (RTYPE (tree), stderr);
2783 fprintf (stderr, "\n");
2784 goto errorTreeReturn;
2787 /* else they should be promotable to one another */
2790 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2791 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2793 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2795 werror (E_COMPARE_OP);
2796 fprintf (stderr, "comparing type ");
2797 printTypeChain (LTYPE (tree), stderr);
2798 fprintf (stderr, "to type ");
2799 printTypeChain (RTYPE (tree), stderr);
2800 fprintf (stderr, "\n");
2801 goto errorTreeReturn;
2805 /* if they are both literal then */
2806 /* rewrite the tree */
2807 if (IS_LITERAL (RTYPE (tree)) &&
2808 IS_LITERAL (LTYPE (tree)))
2810 tree->type = EX_VALUE;
2811 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2812 valFromType (RETYPE (tree)),
2814 tree->right = tree->left = NULL;
2815 TETYPE (tree) = getSpec (TTYPE (tree) =
2816 tree->opval.val->type);
2819 LRVAL (tree) = RRVAL (tree) = 1;
2820 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2823 /*------------------------------------------------------------------*/
2824 /*----------------------------*/
2826 /*----------------------------*/
2827 case SIZEOF: /* evaluate wihout code generation */
2828 /* change the type to a integer */
2829 tree->type = EX_VALUE;
2830 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2831 tree->opval.val = constVal (buffer);
2832 tree->right = tree->left = NULL;
2833 TETYPE (tree) = getSpec (TTYPE (tree) =
2834 tree->opval.val->type);
2837 /*------------------------------------------------------------------*/
2838 /*----------------------------*/
2839 /* conditional operator '?' */
2840 /*----------------------------*/
2842 /* the type is value of the colon operator (on the right) */
2843 assert(IS_COLON_OP(tree->right));
2844 /* if already known then replace the tree : optimizer will do it
2845 but faster to do it here */
2846 if (IS_LITERAL (LTYPE(tree))) {
2847 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2848 return tree->right->left ;
2850 return tree->right->right ;
2853 TTYPE (tree) = RTYPE(tree);
2854 TETYPE (tree) = getSpec (TTYPE (tree));
2859 /* if they don't match we have a problem */
2860 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2862 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2863 goto errorTreeReturn;
2866 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2867 TETYPE (tree) = getSpec (TTYPE (tree));
2871 /*------------------------------------------------------------------*/
2872 /*----------------------------*/
2873 /* assignment operators */
2874 /*----------------------------*/
2877 /* for these it must be both must be integral */
2878 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2879 !IS_ARITHMETIC (RTYPE (tree)))
2881 werror (E_OPS_INTEGRAL);
2882 goto errorTreeReturn;
2885 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2887 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2888 werror (E_CODE_WRITE, " ");
2892 werror (E_LVALUE_REQUIRED, "*= or /=");
2893 goto errorTreeReturn;
2904 /* for these it must be both must be integral */
2905 if (!IS_INTEGRAL (LTYPE (tree)) ||
2906 !IS_INTEGRAL (RTYPE (tree)))
2908 werror (E_OPS_INTEGRAL);
2909 goto errorTreeReturn;
2912 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2914 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2915 werror (E_CODE_WRITE, " ");
2919 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2920 goto errorTreeReturn;
2926 /*------------------------------------------------------------------*/
2927 /*----------------------------*/
2929 /*----------------------------*/
2931 if (!(IS_PTR (LTYPE (tree)) ||
2932 IS_ARITHMETIC (LTYPE (tree))))
2934 werror (E_PLUS_INVALID, "-=");
2935 goto errorTreeReturn;
2938 if (!(IS_PTR (RTYPE (tree)) ||
2939 IS_ARITHMETIC (RTYPE (tree))))
2941 werror (E_PLUS_INVALID, "-=");
2942 goto errorTreeReturn;
2945 TETYPE (tree) = getSpec (TTYPE (tree) =
2946 computeType (LTYPE (tree),
2949 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2950 werror (E_CODE_WRITE, " ");
2954 werror (E_LVALUE_REQUIRED, "-=");
2955 goto errorTreeReturn;
2961 /*------------------------------------------------------------------*/
2962 /*----------------------------*/
2964 /*----------------------------*/
2966 /* this is not a unary operation */
2967 /* if both pointers then problem */
2968 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2970 werror (E_PTR_PLUS_PTR);
2971 goto errorTreeReturn;
2974 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2976 werror (E_PLUS_INVALID, "+=");
2977 goto errorTreeReturn;
2980 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2982 werror (E_PLUS_INVALID, "+=");
2983 goto errorTreeReturn;
2986 TETYPE (tree) = getSpec (TTYPE (tree) =
2987 computeType (LTYPE (tree),
2990 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2991 werror (E_CODE_WRITE, " ");
2995 werror (E_LVALUE_REQUIRED, "+=");
2996 goto errorTreeReturn;
2999 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3000 tree->opval.op = '=';
3004 /*------------------------------------------------------------------*/
3005 /*----------------------------*/
3006 /* straight assignemnt */
3007 /*----------------------------*/
3009 /* cannot be an aggregate */
3010 if (IS_AGGREGATE (LTYPE (tree)))
3012 werror (E_AGGR_ASSIGN);
3013 goto errorTreeReturn;
3016 /* they should either match or be castable */
3017 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3019 werror (E_TYPE_MISMATCH, "assignment", " ");
3020 fprintf (stderr, "type --> '");
3021 printTypeChain (RTYPE (tree), stderr);
3022 fprintf (stderr, "' ");
3023 fprintf (stderr, "assigned to type --> '");
3024 printTypeChain (LTYPE (tree), stderr);
3025 fprintf (stderr, "'\n");
3026 goto errorTreeReturn;
3029 /* if the left side of the tree is of type void
3030 then report error */
3031 if (IS_VOID (LTYPE (tree)))
3033 werror (E_CAST_ZERO);
3034 printFromToType(RTYPE(tree), LTYPE(tree));
3037 TETYPE (tree) = getSpec (TTYPE (tree) =
3041 if (!tree->initMode ) {
3042 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3043 werror (E_CODE_WRITE, " ");
3047 werror (E_LVALUE_REQUIRED, "=");
3048 goto errorTreeReturn;
3053 /*------------------------------------------------------------------*/
3054 /*----------------------------*/
3055 /* comma operator */
3056 /*----------------------------*/
3058 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3061 /*------------------------------------------------------------------*/
3062 /*----------------------------*/
3064 /*----------------------------*/
3068 if (processParms (tree->left,
3069 FUNC_ARGS(tree->left->ftype),
3070 tree->right, &parmNumber, TRUE)) {
3071 goto errorTreeReturn;
3074 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3076 //FUNC_ARGS(tree->left->ftype) =
3077 //reverseVal (FUNC_ARGS(tree->left->ftype));
3078 reverseParms (tree->right);
3081 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3084 /*------------------------------------------------------------------*/
3085 /*----------------------------*/
3086 /* return statement */
3087 /*----------------------------*/
3092 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3094 werror (W_RETURN_MISMATCH);
3095 printFromToType (RTYPE(tree), currFunc->type->next);
3096 goto errorTreeReturn;
3099 if (IS_VOID (currFunc->type->next)
3101 !IS_VOID (RTYPE (tree)))
3103 werror (E_FUNC_VOID);
3104 goto errorTreeReturn;
3107 /* if there is going to be a casing required then add it */
3108 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3111 decorateType (newNode (CAST,
3112 newAst_LINK (copyLinkChain (currFunc->type->next)),
3121 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3123 werror (E_VOID_FUNC, currFunc->name);
3124 goto errorTreeReturn;
3127 TTYPE (tree) = TETYPE (tree) = NULL;
3130 /*------------------------------------------------------------------*/
3131 /*----------------------------*/
3132 /* switch statement */
3133 /*----------------------------*/
3135 /* the switch value must be an integer */
3136 if (!IS_INTEGRAL (LTYPE (tree)))
3138 werror (E_SWITCH_NON_INTEGER);
3139 goto errorTreeReturn;
3142 TTYPE (tree) = TETYPE (tree) = NULL;
3145 /*------------------------------------------------------------------*/
3146 /*----------------------------*/
3148 /*----------------------------*/
3150 tree->left = backPatchLabels (tree->left,
3153 TTYPE (tree) = TETYPE (tree) = NULL;
3156 /*------------------------------------------------------------------*/
3157 /*----------------------------*/
3159 /*----------------------------*/
3162 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3163 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3164 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3166 /* if the for loop is reversible then
3167 reverse it otherwise do what we normally
3173 if (isLoopReversible (tree, &sym, &init, &end))
3174 return reverseLoop (tree, sym, init, end);
3176 return decorateType (createFor (AST_FOR (tree, trueLabel),
3177 AST_FOR (tree, continueLabel),
3178 AST_FOR (tree, falseLabel),
3179 AST_FOR (tree, condLabel),
3180 AST_FOR (tree, initExpr),
3181 AST_FOR (tree, condExpr),
3182 AST_FOR (tree, loopExpr),
3186 TTYPE (tree) = TETYPE (tree) = NULL;
3190 /* some error found this tree will be killed */
3192 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3193 tree->opval.op = NULLOP;
3199 /*-----------------------------------------------------------------*/
3200 /* sizeofOp - processes size of operation */
3201 /*-----------------------------------------------------------------*/
3203 sizeofOp (sym_link * type)
3207 /* make sure the type is complete and sane */
3208 checkTypeSanity(type, "(sizeof)");
3210 /* get the size and convert it to character */
3211 sprintf (buff, "%d", getSize (type));
3213 /* now convert into value */
3214 return constVal (buff);
3218 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3219 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3220 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3221 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3222 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3223 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3224 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3226 /*-----------------------------------------------------------------*/
3227 /* backPatchLabels - change and or not operators to flow control */
3228 /*-----------------------------------------------------------------*/
3230 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3236 if (!(IS_ANDORNOT (tree)))
3239 /* if this an and */
3242 static int localLbl = 0;
3245 sprintf (buffer, "_and_%d", localLbl++);
3246 localLabel = newSymbol (buffer, NestLevel);
3248 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3250 /* if left is already a IFX then just change the if true label in that */
3251 if (!IS_IFX (tree->left))
3252 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3254 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3255 /* right is a IFX then just join */
3256 if (IS_IFX (tree->right))
3257 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3259 tree->right = createLabel (localLabel, tree->right);
3260 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3262 return newNode (NULLOP, tree->left, tree->right);
3265 /* if this is an or operation */
3268 static int localLbl = 0;
3271 sprintf (buffer, "_or_%d", localLbl++);
3272 localLabel = newSymbol (buffer, NestLevel);
3274 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3276 /* if left is already a IFX then just change the if true label in that */
3277 if (!IS_IFX (tree->left))
3278 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3280 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3281 /* right is a IFX then just join */
3282 if (IS_IFX (tree->right))
3283 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3285 tree->right = createLabel (localLabel, tree->right);
3286 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3288 return newNode (NULLOP, tree->left, tree->right);
3294 int wasnot = IS_NOT (tree->left);
3295 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3297 /* if the left is already a IFX */
3298 if (!IS_IFX (tree->left))
3299 tree->left = newNode (IFX, tree->left, NULL);
3303 tree->left->trueLabel = trueLabel;
3304 tree->left->falseLabel = falseLabel;
3308 tree->left->trueLabel = falseLabel;
3309 tree->left->falseLabel = trueLabel;
3316 tree->trueLabel = trueLabel;
3317 tree->falseLabel = falseLabel;
3324 /*-----------------------------------------------------------------*/
3325 /* createBlock - create expression tree for block */
3326 /*-----------------------------------------------------------------*/
3328 createBlock (symbol * decl, ast * body)
3332 /* if the block has nothing */
3336 ex = newNode (BLOCK, NULL, body);
3337 ex->values.sym = decl;
3339 ex->right = ex->right;
3345 /*-----------------------------------------------------------------*/
3346 /* createLabel - creates the expression tree for labels */
3347 /*-----------------------------------------------------------------*/
3349 createLabel (symbol * label, ast * stmnt)
3352 char name[SDCC_NAME_MAX + 1];
3355 /* must create fresh symbol if the symbol name */
3356 /* exists in the symbol table, since there can */
3357 /* be a variable with the same name as the labl */
3358 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3359 (csym->level == label->level))
3360 label = newSymbol (label->name, label->level);
3362 /* change the name before putting it in add _ */
3363 sprintf (name, "%s", label->name);
3365 /* put the label in the LabelSymbol table */
3366 /* but first check if a label of the same */
3368 if ((csym = findSym (LabelTab, NULL, name)))
3369 werror (E_DUPLICATE_LABEL, label->name);
3371 addSym (LabelTab, label, name, label->level, 0, 0);
3374 label->key = labelKey++;
3375 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3381 /*-----------------------------------------------------------------*/
3382 /* createCase - generates the parsetree for a case statement */
3383 /*-----------------------------------------------------------------*/
3385 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3387 char caseLbl[SDCC_NAME_MAX + 1];
3391 /* if the switch statement does not exist */
3392 /* then case is out of context */
3395 werror (E_CASE_CONTEXT);
3399 caseVal = decorateType (resolveSymbols (caseVal));
3400 /* if not a constant then error */
3401 if (!IS_LITERAL (caseVal->ftype))
3403 werror (E_CASE_CONSTANT);
3407 /* if not a integer than error */
3408 if (!IS_INTEGRAL (caseVal->ftype))
3410 werror (E_CASE_NON_INTEGER);
3414 /* find the end of the switch values chain */
3415 if (!(val = swStat->values.switchVals.swVals))
3416 swStat->values.switchVals.swVals = caseVal->opval.val;
3419 /* also order the cases according to value */
3421 int cVal = (int) floatFromVal (caseVal->opval.val);
3422 while (val && (int) floatFromVal (val) < cVal)
3428 /* if we reached the end then */
3431 pval->next = caseVal->opval.val;
3435 /* we found a value greater than */
3436 /* the current value we must add this */
3437 /* before the value */
3438 caseVal->opval.val->next = val;
3440 /* if this was the first in chain */
3441 if (swStat->values.switchVals.swVals == val)
3442 swStat->values.switchVals.swVals =
3445 pval->next = caseVal->opval.val;
3450 /* create the case label */
3451 sprintf (caseLbl, "_case_%d_%d",
3452 swStat->values.switchVals.swNum,
3453 (int) floatFromVal (caseVal->opval.val));
3455 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3460 /*-----------------------------------------------------------------*/
3461 /* createDefault - creates the parse tree for the default statement */
3462 /*-----------------------------------------------------------------*/
3464 createDefault (ast * swStat, ast * stmnt)
3466 char defLbl[SDCC_NAME_MAX + 1];
3468 /* if the switch statement does not exist */
3469 /* then case is out of context */
3472 werror (E_CASE_CONTEXT);
3476 /* turn on the default flag */
3477 swStat->values.switchVals.swDefault = 1;
3479 /* create the label */
3480 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3481 return createLabel (newSymbol (defLbl, 0), stmnt);
3484 /*-----------------------------------------------------------------*/
3485 /* createIf - creates the parsetree for the if statement */
3486 /*-----------------------------------------------------------------*/
3488 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3490 static int Lblnum = 0;
3492 symbol *ifTrue, *ifFalse, *ifEnd;
3494 /* if neither exists */
3495 if (!elseBody && !ifBody) {
3496 // if there are no side effects (i++, j() etc)
3497 if (!hasSEFcalls(condAst)) {
3502 /* create the labels */
3503 sprintf (buffer, "_iffalse_%d", Lblnum);
3504 ifFalse = newSymbol (buffer, NestLevel);
3505 /* if no else body then end == false */
3510 sprintf (buffer, "_ifend_%d", Lblnum);
3511 ifEnd = newSymbol (buffer, NestLevel);
3514 sprintf (buffer, "_iftrue_%d", Lblnum);
3515 ifTrue = newSymbol (buffer, NestLevel);
3519 /* attach the ifTrue label to the top of it body */
3520 ifBody = createLabel (ifTrue, ifBody);
3521 /* attach a goto end to the ifBody if else is present */
3524 ifBody = newNode (NULLOP, ifBody,
3526 newAst_VALUE (symbolVal (ifEnd)),
3528 /* put the elseLabel on the else body */
3529 elseBody = createLabel (ifFalse, elseBody);
3530 /* out the end at the end of the body */
3531 elseBody = newNode (NULLOP,
3533 createLabel (ifEnd, NULL));
3537 ifBody = newNode (NULLOP, ifBody,
3538 createLabel (ifFalse, NULL));
3540 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3541 if (IS_IFX (condAst))
3544 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3546 return newNode (NULLOP, ifTree,
3547 newNode (NULLOP, ifBody, elseBody));
3551 /*-----------------------------------------------------------------*/
3552 /* createDo - creates parse tree for do */
3555 /* _docontinue_n: */
3556 /* condition_expression +-> trueLabel -> _dobody_n */
3558 /* +-> falseLabel-> _dobreak_n */
3560 /*-----------------------------------------------------------------*/
3562 createDo (symbol * trueLabel, symbol * continueLabel,
3563 symbol * falseLabel, ast * condAst, ast * doBody)
3568 /* if the body does not exist then it is simple */
3571 condAst = backPatchLabels (condAst, continueLabel, NULL);
3572 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3573 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3574 doTree->trueLabel = continueLabel;
3575 doTree->falseLabel = NULL;
3579 /* otherwise we have a body */
3580 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3582 /* attach the body label to the top */
3583 doBody = createLabel (trueLabel, doBody);
3584 /* attach the continue label to end of body */
3585 doBody = newNode (NULLOP, doBody,
3586 createLabel (continueLabel, NULL));
3588 /* now put the break label at the end */
3589 if (IS_IFX (condAst))
3592 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3594 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3596 /* putting it together */
3597 return newNode (NULLOP, doBody, doTree);
3600 /*-----------------------------------------------------------------*/
3601 /* createFor - creates parse tree for 'for' statement */
3604 /* condExpr +-> trueLabel -> _forbody_n */
3606 /* +-> falseLabel-> _forbreak_n */
3609 /* _forcontinue_n: */
3611 /* goto _forcond_n ; */
3613 /*-----------------------------------------------------------------*/
3615 createFor (symbol * trueLabel, symbol * continueLabel,
3616 symbol * falseLabel, symbol * condLabel,
3617 ast * initExpr, ast * condExpr, ast * loopExpr,
3622 /* if loopexpression not present then we can generate it */
3623 /* the same way as a while */
3625 return newNode (NULLOP, initExpr,
3626 createWhile (trueLabel, continueLabel,
3627 falseLabel, condExpr, forBody));
3628 /* vanilla for statement */
3629 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3631 if (condExpr && !IS_IFX (condExpr))
3632 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3635 /* attach condition label to condition */
3636 condExpr = createLabel (condLabel, condExpr);
3638 /* attach body label to body */
3639 forBody = createLabel (trueLabel, forBody);
3641 /* attach continue to forLoop expression & attach */
3642 /* goto the forcond @ and of loopExpression */
3643 loopExpr = createLabel (continueLabel,
3647 newAst_VALUE (symbolVal (condLabel)),
3649 /* now start putting them together */
3650 forTree = newNode (NULLOP, initExpr, condExpr);
3651 forTree = newNode (NULLOP, forTree, forBody);
3652 forTree = newNode (NULLOP, forTree, loopExpr);
3653 /* finally add the break label */
3654 forTree = newNode (NULLOP, forTree,
3655 createLabel (falseLabel, NULL));
3659 /*-----------------------------------------------------------------*/
3660 /* createWhile - creates parse tree for while statement */
3661 /* the while statement will be created as follows */
3663 /* _while_continue_n: */
3664 /* condition_expression +-> trueLabel -> _while_boby_n */
3666 /* +-> falseLabel -> _while_break_n */
3667 /* _while_body_n: */
3669 /* goto _while_continue_n */
3670 /* _while_break_n: */
3671 /*-----------------------------------------------------------------*/
3673 createWhile (symbol * trueLabel, symbol * continueLabel,
3674 symbol * falseLabel, ast * condExpr, ast * whileBody)
3678 /* put the continue label */
3679 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3680 condExpr = createLabel (continueLabel, condExpr);
3681 condExpr->lineno = 0;
3683 /* put the body label in front of the body */
3684 whileBody = createLabel (trueLabel, whileBody);
3685 whileBody->lineno = 0;
3686 /* put a jump to continue at the end of the body */
3687 /* and put break label at the end of the body */
3688 whileBody = newNode (NULLOP,
3691 newAst_VALUE (symbolVal (continueLabel)),
3692 createLabel (falseLabel, NULL)));
3694 /* put it all together */
3695 if (IS_IFX (condExpr))
3696 whileTree = condExpr;
3699 whileTree = newNode (IFX, condExpr, NULL);
3700 /* put the true & false labels in place */
3701 whileTree->trueLabel = trueLabel;
3702 whileTree->falseLabel = falseLabel;
3705 return newNode (NULLOP, whileTree, whileBody);
3708 /*-----------------------------------------------------------------*/
3709 /* optimizeGetHbit - get highest order bit of the expression */
3710 /*-----------------------------------------------------------------*/
3712 optimizeGetHbit (ast * tree)
3715 /* if this is not a bit and */
3716 if (!IS_BITAND (tree))
3719 /* will look for tree of the form
3720 ( expr >> ((sizeof expr) -1) ) & 1 */
3721 if (!IS_AST_LIT_VALUE (tree->right))
3724 if (AST_LIT_VALUE (tree->right) != 1)
3727 if (!IS_RIGHT_OP (tree->left))
3730 if (!IS_AST_LIT_VALUE (tree->left->right))
3733 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3734 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3737 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3741 /*-----------------------------------------------------------------*/
3742 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3743 /*-----------------------------------------------------------------*/
3745 optimizeRRCRLC (ast * root)
3747 /* will look for trees of the form
3748 (?expr << 1) | (?expr >> 7) or
3749 (?expr >> 7) | (?expr << 1) will make that
3750 into a RLC : operation ..
3752 (?expr >> 1) | (?expr << 7) or
3753 (?expr << 7) | (?expr >> 1) will make that
3754 into a RRC operation
3755 note : by 7 I mean (number of bits required to hold the
3757 /* if the root operations is not a | operation the not */
3758 if (!IS_BITOR (root))
3761 /* I have to think of a better way to match patterns this sucks */
3762 /* that aside let start looking for the first case : I use a the
3763 negative check a lot to improve the efficiency */
3764 /* (?expr << 1) | (?expr >> 7) */
3765 if (IS_LEFT_OP (root->left) &&
3766 IS_RIGHT_OP (root->right))
3769 if (!SPEC_USIGN (TETYPE (root->left->left)))
3772 if (!IS_AST_LIT_VALUE (root->left->right) ||
3773 !IS_AST_LIT_VALUE (root->right->right))
3776 /* make sure it is the same expression */
3777 if (!isAstEqual (root->left->left,
3781 if (AST_LIT_VALUE (root->left->right) != 1)
3784 if (AST_LIT_VALUE (root->right->right) !=
3785 (getSize (TTYPE (root->left->left)) * 8 - 1))
3788 /* whew got the first case : create the AST */
3789 return newNode (RLC, root->left->left, NULL);
3793 /* check for second case */
3794 /* (?expr >> 7) | (?expr << 1) */
3795 if (IS_LEFT_OP (root->right) &&
3796 IS_RIGHT_OP (root->left))
3799 if (!SPEC_USIGN (TETYPE (root->left->left)))
3802 if (!IS_AST_LIT_VALUE (root->left->right) ||
3803 !IS_AST_LIT_VALUE (root->right->right))
3806 /* make sure it is the same symbol */
3807 if (!isAstEqual (root->left->left,
3811 if (AST_LIT_VALUE (root->right->right) != 1)
3814 if (AST_LIT_VALUE (root->left->right) !=
3815 (getSize (TTYPE (root->left->left)) * 8 - 1))
3818 /* whew got the first case : create the AST */
3819 return newNode (RLC, root->left->left, NULL);
3824 /* third case for RRC */
3825 /* (?symbol >> 1) | (?symbol << 7) */
3826 if (IS_LEFT_OP (root->right) &&
3827 IS_RIGHT_OP (root->left))
3830 if (!SPEC_USIGN (TETYPE (root->left->left)))
3833 if (!IS_AST_LIT_VALUE (root->left->right) ||
3834 !IS_AST_LIT_VALUE (root->right->right))
3837 /* make sure it is the same symbol */
3838 if (!isAstEqual (root->left->left,
3842 if (AST_LIT_VALUE (root->left->right) != 1)
3845 if (AST_LIT_VALUE (root->right->right) !=
3846 (getSize (TTYPE (root->left->left)) * 8 - 1))
3849 /* whew got the first case : create the AST */
3850 return newNode (RRC, root->left->left, NULL);
3854 /* fourth and last case for now */
3855 /* (?symbol << 7) | (?symbol >> 1) */
3856 if (IS_RIGHT_OP (root->right) &&
3857 IS_LEFT_OP (root->left))
3860 if (!SPEC_USIGN (TETYPE (root->left->left)))
3863 if (!IS_AST_LIT_VALUE (root->left->right) ||
3864 !IS_AST_LIT_VALUE (root->right->right))
3867 /* make sure it is the same symbol */
3868 if (!isAstEqual (root->left->left,
3872 if (AST_LIT_VALUE (root->right->right) != 1)
3875 if (AST_LIT_VALUE (root->left->right) !=
3876 (getSize (TTYPE (root->left->left)) * 8 - 1))
3879 /* whew got the first case : create the AST */
3880 return newNode (RRC, root->left->left, NULL);
3884 /* not found return root */
3888 /*-----------------------------------------------------------------*/
3889 /* optimizeCompare - otimizes compares for bit variables */
3890 /*-----------------------------------------------------------------*/
3892 optimizeCompare (ast * root)
3894 ast *optExpr = NULL;
3897 unsigned int litValue;
3899 /* if nothing then return nothing */
3903 /* if not a compare op then do leaves */
3904 if (!IS_COMPARE_OP (root))
3906 root->left = optimizeCompare (root->left);
3907 root->right = optimizeCompare (root->right);
3911 /* if left & right are the same then depending
3912 of the operation do */
3913 if (isAstEqual (root->left, root->right))
3915 switch (root->opval.op)
3920 optExpr = newAst_VALUE (constVal ("0"));
3925 optExpr = newAst_VALUE (constVal ("1"));
3929 return decorateType (optExpr);
3932 vleft = (root->left->type == EX_VALUE ?
3933 root->left->opval.val : NULL);
3935 vright = (root->right->type == EX_VALUE ?
3936 root->right->opval.val : NULL);
3938 /* if left is a BITVAR in BITSPACE */
3939 /* and right is a LITERAL then opt- */
3940 /* imize else do nothing */
3941 if (vleft && vright &&
3942 IS_BITVAR (vleft->etype) &&
3943 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3944 IS_LITERAL (vright->etype))
3947 /* if right side > 1 then comparison may never succeed */
3948 if ((litValue = (int) floatFromVal (vright)) > 1)
3950 werror (W_BAD_COMPARE);
3956 switch (root->opval.op)
3958 case '>': /* bit value greater than 1 cannot be */
3959 werror (W_BAD_COMPARE);
3963 case '<': /* bit value < 1 means 0 */
3965 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3968 case LE_OP: /* bit value <= 1 means no check */
3969 optExpr = newAst_VALUE (vright);
3972 case GE_OP: /* bit value >= 1 means only check for = */
3974 optExpr = newAst_VALUE (vleft);
3979 { /* literal is zero */
3980 switch (root->opval.op)
3982 case '<': /* bit value < 0 cannot be */
3983 werror (W_BAD_COMPARE);
3987 case '>': /* bit value > 0 means 1 */
3989 optExpr = newAst_VALUE (vleft);
3992 case LE_OP: /* bit value <= 0 means no check */
3993 case GE_OP: /* bit value >= 0 means no check */
3994 werror (W_BAD_COMPARE);
3998 case EQ_OP: /* bit == 0 means ! of bit */
3999 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4003 return decorateType (resolveSymbols (optExpr));
4004 } /* end-of-if of BITVAR */
4009 /*-----------------------------------------------------------------*/
4010 /* addSymToBlock : adds the symbol to the first block we find */
4011 /*-----------------------------------------------------------------*/
4013 addSymToBlock (symbol * sym, ast * tree)
4015 /* reached end of tree or a leaf */
4016 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4020 if (IS_AST_OP (tree) &&
4021 tree->opval.op == BLOCK)
4024 symbol *lsym = copySymbol (sym);
4026 lsym->next = AST_VALUES (tree, sym);
4027 AST_VALUES (tree, sym) = lsym;
4031 addSymToBlock (sym, tree->left);
4032 addSymToBlock (sym, tree->right);
4035 /*-----------------------------------------------------------------*/
4036 /* processRegParms - do processing for register parameters */
4037 /*-----------------------------------------------------------------*/
4039 processRegParms (value * args, ast * body)
4043 if (IS_REGPARM (args->etype))
4044 addSymToBlock (args->sym, body);
4049 /*-----------------------------------------------------------------*/
4050 /* resetParmKey - resets the operandkeys for the symbols */
4051 /*-----------------------------------------------------------------*/
4052 DEFSETFUNC (resetParmKey)
4063 /*-----------------------------------------------------------------*/
4064 /* createFunction - This is the key node that calls the iCode for */
4065 /* generating the code for a function. Note code */
4066 /* is generated function by function, later when */
4067 /* add inter-procedural analysis this will change */
4068 /*-----------------------------------------------------------------*/
4070 createFunction (symbol * name, ast * body)
4076 iCode *piCode = NULL;
4078 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4079 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4081 /* if check function return 0 then some problem */
4082 if (checkFunction (name, NULL) == 0)
4085 /* create a dummy block if none exists */
4087 body = newNode (BLOCK, NULL, NULL);
4091 /* check if the function name already in the symbol table */
4092 if ((csym = findSym (SymbolTab, NULL, name->name)))
4095 /* special case for compiler defined functions
4096 we need to add the name to the publics list : this
4097 actually means we are now compiling the compiler
4101 addSet (&publics, name);
4107 allocVariables (name);
4109 name->lastLine = yylineno;
4112 #if 0 // jwk: this is now done in addDecl()
4113 processFuncArgs (currFunc);
4116 /* set the stack pointer */
4117 /* PENDING: check this for the mcs51 */
4118 stackPtr = -port->stack.direction * port->stack.call_overhead;
4119 if (IFFUNC_ISISR (name->type))
4120 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4121 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4122 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4124 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4126 fetype = getSpec (name->type); /* get the specifier for the function */
4127 /* if this is a reentrant function then */
4128 if (IFFUNC_ISREENT (name->type))
4131 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4133 /* do processing for parameters that are passed in registers */
4134 processRegParms (FUNC_ARGS(name->type), body);
4136 /* set the stack pointer */
4140 /* allocate & autoinit the block variables */
4141 processBlockVars (body, &stack, ALLOCATE);
4143 /* save the stack information */
4144 if (options.useXstack)
4145 name->xstack = SPEC_STAK (fetype) = stack;
4147 name->stack = SPEC_STAK (fetype) = stack;
4149 /* name needs to be mangled */
4150 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4152 body = resolveSymbols (body); /* resolve the symbols */
4153 body = decorateType (body); /* propagateType & do semantic checks */
4155 ex = newAst_VALUE (symbolVal (name)); /* create name */
4156 ex = newNode (FUNCTION, ex, body);
4157 ex->values.args = FUNC_ARGS(name->type);
4159 if (options.dump_tree) PA(ex);
4162 werror (E_FUNC_NO_CODE, name->name);
4166 /* create the node & generate intermediate code */
4168 codeOutFile = code->oFile;
4169 piCode = iCodeFromAst (ex);
4173 werror (E_FUNC_NO_CODE, name->name);
4177 eBBlockFromiCode (piCode);
4179 /* if there are any statics then do them */
4182 GcurMemmap = statsg;
4183 codeOutFile = statsg->oFile;
4184 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4190 /* dealloc the block variables */
4191 processBlockVars (body, &stack, DEALLOCATE);
4192 /* deallocate paramaters */
4193 deallocParms (FUNC_ARGS(name->type));
4195 if (IFFUNC_ISREENT (name->type))
4198 /* we are done freeup memory & cleanup */
4202 FUNC_HASBODY(name->type) = 1;
4203 addSet (&operKeyReset, name);
4204 applyToSet (operKeyReset, resetParmKey);
4207 cdbStructBlock (1, cdbFile);
4209 cleanUpLevel (LabelTab, 0);
4210 cleanUpBlock (StructTab, 1);
4211 cleanUpBlock (TypedefTab, 1);
4213 xstack->syms = NULL;
4214 istack->syms = NULL;
4219 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4220 /*-----------------------------------------------------------------*/
4221 /* ast_print : prints the ast (for debugging purposes) */
4222 /*-----------------------------------------------------------------*/
4224 void ast_print (ast * tree, FILE *outfile, int indent)
4229 /* can print only decorated trees */
4230 if (!tree->decorated) return;
4232 /* if any child is an error | this one is an error do nothing */
4233 if (tree->isError ||
4234 (tree->left && tree->left->isError) ||
4235 (tree->right && tree->right->isError)) {
4236 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4240 /* print the line */
4241 /* if not block & function */
4242 if (tree->type == EX_OP &&
4243 (tree->opval.op != FUNCTION &&
4244 tree->opval.op != BLOCK &&
4245 tree->opval.op != NULLOP)) {
4248 if (tree->opval.op == FUNCTION) {
4250 value *args=FUNC_ARGS(tree->left->opval.val->type);
4251 fprintf(outfile,"FUNCTION (%s=%p) type (",
4252 tree->left->opval.val->name, tree);
4253 printTypeChain (tree->ftype,outfile);
4254 fprintf(outfile,") args (");
4257 fprintf (outfile, ", ");
4259 printTypeChain (args ? args->type : NULL, outfile);
4261 args= args ? args->next : NULL;
4263 fprintf(outfile,")\n");
4264 ast_print(tree->left,outfile,indent);
4265 ast_print(tree->right,outfile,indent);
4268 if (tree->opval.op == BLOCK) {
4269 symbol *decls = tree->values.sym;
4270 INDENT(indent,outfile);
4271 fprintf(outfile,"{\n");
4273 INDENT(indent+4,outfile);
4274 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4275 decls->name, decls);
4276 printTypeChain(decls->type,outfile);
4277 fprintf(outfile,")\n");
4279 decls = decls->next;
4281 ast_print(tree->right,outfile,indent+4);
4282 INDENT(indent,outfile);
4283 fprintf(outfile,"}\n");
4286 if (tree->opval.op == NULLOP) {
4287 fprintf(outfile,"\n");
4288 ast_print(tree->left,outfile,indent);
4289 fprintf(outfile,"\n");
4290 ast_print(tree->right,outfile,indent);
4293 INDENT(indent,outfile);
4295 /*------------------------------------------------------------------*/
4296 /*----------------------------*/
4297 /* leaf has been reached */
4298 /*----------------------------*/
4299 /* if this is of type value */
4300 /* just get the type */
4301 if (tree->type == EX_VALUE) {
4303 if (IS_LITERAL (tree->opval.val->etype)) {
4304 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4305 (int) floatFromVal(tree->opval.val),
4306 (int) floatFromVal(tree->opval.val),
4307 floatFromVal(tree->opval.val));
4308 } else if (tree->opval.val->sym) {
4309 /* if the undefined flag is set then give error message */
4310 if (tree->opval.val->sym->undefined) {
4311 fprintf(outfile,"UNDEFINED SYMBOL ");
4313 fprintf(outfile,"SYMBOL ");
4315 fprintf(outfile,"(%s=%p)",
4316 tree->opval.val->sym->name,tree);
4319 fprintf(outfile," type (");
4320 printTypeChain(tree->ftype,outfile);
4321 fprintf(outfile,")\n");
4323 fprintf(outfile,"\n");
4328 /* if type link for the case of cast */
4329 if (tree->type == EX_LINK) {
4330 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4331 printTypeChain(tree->opval.lnk,outfile);
4332 fprintf(outfile,")\n");
4337 /* depending on type of operator do */
4339 switch (tree->opval.op) {
4340 /*------------------------------------------------------------------*/
4341 /*----------------------------*/
4343 /*----------------------------*/
4345 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4346 printTypeChain(tree->ftype,outfile);
4347 fprintf(outfile,")\n");
4348 ast_print(tree->left,outfile,indent+4);
4349 ast_print(tree->right,outfile,indent+4);
4352 /*------------------------------------------------------------------*/
4353 /*----------------------------*/
4355 /*----------------------------*/
4357 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4358 printTypeChain(tree->ftype,outfile);
4359 fprintf(outfile,")\n");
4360 ast_print(tree->left,outfile,indent+4);
4361 ast_print(tree->right,outfile,indent+4);
4364 /*------------------------------------------------------------------*/
4365 /*----------------------------*/
4366 /* struct/union pointer */
4367 /*----------------------------*/
4369 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4370 printTypeChain(tree->ftype,outfile);
4371 fprintf(outfile,")\n");
4372 ast_print(tree->left,outfile,indent+4);
4373 ast_print(tree->right,outfile,indent+4);
4376 /*------------------------------------------------------------------*/
4377 /*----------------------------*/
4378 /* ++/-- operation */
4379 /*----------------------------*/
4380 case INC_OP: /* incerement operator unary so left only */
4381 fprintf(outfile,"INC_OP (%p) type (",tree);
4382 printTypeChain(tree->ftype,outfile);
4383 fprintf(outfile,")\n");
4384 ast_print(tree->left,outfile,indent+4);
4388 fprintf(outfile,"DEC_OP (%p) type (",tree);
4389 printTypeChain(tree->ftype,outfile);
4390 fprintf(outfile,")\n");
4391 ast_print(tree->left,outfile,indent+4);
4394 /*------------------------------------------------------------------*/
4395 /*----------------------------*/
4397 /*----------------------------*/
4400 fprintf(outfile,"& (%p) type (",tree);
4401 printTypeChain(tree->ftype,outfile);
4402 fprintf(outfile,")\n");
4403 ast_print(tree->left,outfile,indent+4);
4404 ast_print(tree->right,outfile,indent+4);
4406 fprintf(outfile,"ADDRESS_OF (%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);
4413 /*----------------------------*/
4415 /*----------------------------*/
4417 fprintf(outfile,"OR (%p) type (",tree);
4418 printTypeChain(tree->ftype,outfile);
4419 fprintf(outfile,")\n");
4420 ast_print(tree->left,outfile,indent+4);
4421 ast_print(tree->right,outfile,indent+4);
4423 /*------------------------------------------------------------------*/
4424 /*----------------------------*/
4426 /*----------------------------*/
4428 fprintf(outfile,"XOR (%p) type (",tree);
4429 printTypeChain(tree->ftype,outfile);
4430 fprintf(outfile,")\n");
4431 ast_print(tree->left,outfile,indent+4);
4432 ast_print(tree->right,outfile,indent+4);
4435 /*------------------------------------------------------------------*/
4436 /*----------------------------*/
4438 /*----------------------------*/
4440 fprintf(outfile,"DIV (%p) type (",tree);
4441 printTypeChain(tree->ftype,outfile);
4442 fprintf(outfile,")\n");
4443 ast_print(tree->left,outfile,indent+4);
4444 ast_print(tree->right,outfile,indent+4);
4446 /*------------------------------------------------------------------*/
4447 /*----------------------------*/
4449 /*----------------------------*/
4451 fprintf(outfile,"MOD (%p) type (",tree);
4452 printTypeChain(tree->ftype,outfile);
4453 fprintf(outfile,")\n");
4454 ast_print(tree->left,outfile,indent+4);
4455 ast_print(tree->right,outfile,indent+4);
4458 /*------------------------------------------------------------------*/
4459 /*----------------------------*/
4460 /* address dereference */
4461 /*----------------------------*/
4462 case '*': /* can be unary : if right is null then unary operation */
4464 fprintf(outfile,"DEREF (%p) type (",tree);
4465 printTypeChain(tree->ftype,outfile);
4466 fprintf(outfile,")\n");
4467 ast_print(tree->left,outfile,indent+4);
4470 /*------------------------------------------------------------------*/
4471 /*----------------------------*/
4472 /* multiplication */
4473 /*----------------------------*/
4474 fprintf(outfile,"MULT (%p) type (",tree);
4475 printTypeChain(tree->ftype,outfile);
4476 fprintf(outfile,")\n");
4477 ast_print(tree->left,outfile,indent+4);
4478 ast_print(tree->right,outfile,indent+4);
4482 /*------------------------------------------------------------------*/
4483 /*----------------------------*/
4484 /* unary '+' operator */
4485 /*----------------------------*/
4489 fprintf(outfile,"UPLUS (%p) type (",tree);
4490 printTypeChain(tree->ftype,outfile);
4491 fprintf(outfile,")\n");
4492 ast_print(tree->left,outfile,indent+4);
4494 /*------------------------------------------------------------------*/
4495 /*----------------------------*/
4497 /*----------------------------*/
4498 fprintf(outfile,"ADD (%p) type (",tree);
4499 printTypeChain(tree->ftype,outfile);
4500 fprintf(outfile,")\n");
4501 ast_print(tree->left,outfile,indent+4);
4502 ast_print(tree->right,outfile,indent+4);
4505 /*------------------------------------------------------------------*/
4506 /*----------------------------*/
4508 /*----------------------------*/
4509 case '-': /* can be unary */
4511 fprintf(outfile,"UMINUS (%p) type (",tree);
4512 printTypeChain(tree->ftype,outfile);
4513 fprintf(outfile,")\n");
4514 ast_print(tree->left,outfile,indent+4);
4516 /*------------------------------------------------------------------*/
4517 /*----------------------------*/
4519 /*----------------------------*/
4520 fprintf(outfile,"SUB (%p) type (",tree);
4521 printTypeChain(tree->ftype,outfile);
4522 fprintf(outfile,")\n");
4523 ast_print(tree->left,outfile,indent+4);
4524 ast_print(tree->right,outfile,indent+4);
4527 /*------------------------------------------------------------------*/
4528 /*----------------------------*/
4530 /*----------------------------*/
4532 fprintf(outfile,"COMPL (%p) type (",tree);
4533 printTypeChain(tree->ftype,outfile);
4534 fprintf(outfile,")\n");
4535 ast_print(tree->left,outfile,indent+4);
4537 /*------------------------------------------------------------------*/
4538 /*----------------------------*/
4540 /*----------------------------*/
4542 fprintf(outfile,"NOT (%p) type (",tree);
4543 printTypeChain(tree->ftype,outfile);
4544 fprintf(outfile,")\n");
4545 ast_print(tree->left,outfile,indent+4);
4547 /*------------------------------------------------------------------*/
4548 /*----------------------------*/
4550 /*----------------------------*/
4552 fprintf(outfile,"RRC (%p) type (",tree);
4553 printTypeChain(tree->ftype,outfile);
4554 fprintf(outfile,")\n");
4555 ast_print(tree->left,outfile,indent+4);
4559 fprintf(outfile,"RLC (%p) type (",tree);
4560 printTypeChain(tree->ftype,outfile);
4561 fprintf(outfile,")\n");
4562 ast_print(tree->left,outfile,indent+4);
4565 fprintf(outfile,"GETHBIT (%p) type (",tree);
4566 printTypeChain(tree->ftype,outfile);
4567 fprintf(outfile,")\n");
4568 ast_print(tree->left,outfile,indent+4);
4571 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4572 printTypeChain(tree->ftype,outfile);
4573 fprintf(outfile,")\n");
4574 ast_print(tree->left,outfile,indent+4);
4575 ast_print(tree->right,outfile,indent+4);
4578 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4579 printTypeChain(tree->ftype,outfile);
4580 fprintf(outfile,")\n");
4581 ast_print(tree->left,outfile,indent+4);
4582 ast_print(tree->right,outfile,indent+4);
4584 /*------------------------------------------------------------------*/
4585 /*----------------------------*/
4587 /*----------------------------*/
4588 case CAST: /* change the type */
4589 fprintf(outfile,"CAST (%p) from type (",tree);
4590 printTypeChain(tree->right->ftype,outfile);
4591 fprintf(outfile,") to type (");
4592 printTypeChain(tree->ftype,outfile);
4593 fprintf(outfile,")\n");
4594 ast_print(tree->right,outfile,indent+4);
4598 fprintf(outfile,"ANDAND (%p) type (",tree);
4599 printTypeChain(tree->ftype,outfile);
4600 fprintf(outfile,")\n");
4601 ast_print(tree->left,outfile,indent+4);
4602 ast_print(tree->right,outfile,indent+4);
4605 fprintf(outfile,"OROR (%p) type (",tree);
4606 printTypeChain(tree->ftype,outfile);
4607 fprintf(outfile,")\n");
4608 ast_print(tree->left,outfile,indent+4);
4609 ast_print(tree->right,outfile,indent+4);
4612 /*------------------------------------------------------------------*/
4613 /*----------------------------*/
4614 /* comparison operators */
4615 /*----------------------------*/
4617 fprintf(outfile,"GT(>) (%p) type (",tree);
4618 printTypeChain(tree->ftype,outfile);
4619 fprintf(outfile,")\n");
4620 ast_print(tree->left,outfile,indent+4);
4621 ast_print(tree->right,outfile,indent+4);
4624 fprintf(outfile,"LT(<) (%p) type (",tree);
4625 printTypeChain(tree->ftype,outfile);
4626 fprintf(outfile,")\n");
4627 ast_print(tree->left,outfile,indent+4);
4628 ast_print(tree->right,outfile,indent+4);
4631 fprintf(outfile,"LE(<=) (%p) type (",tree);
4632 printTypeChain(tree->ftype,outfile);
4633 fprintf(outfile,")\n");
4634 ast_print(tree->left,outfile,indent+4);
4635 ast_print(tree->right,outfile,indent+4);
4638 fprintf(outfile,"GE(>=) (%p) type (",tree);
4639 printTypeChain(tree->ftype,outfile);
4640 fprintf(outfile,")\n");
4641 ast_print(tree->left,outfile,indent+4);
4642 ast_print(tree->right,outfile,indent+4);
4645 fprintf(outfile,"EQ(==) (%p) type (",tree);
4646 printTypeChain(tree->ftype,outfile);
4647 fprintf(outfile,")\n");
4648 ast_print(tree->left,outfile,indent+4);
4649 ast_print(tree->right,outfile,indent+4);
4652 fprintf(outfile,"NE(!=) (%p) type (",tree);
4653 printTypeChain(tree->ftype,outfile);
4654 fprintf(outfile,")\n");
4655 ast_print(tree->left,outfile,indent+4);
4656 ast_print(tree->right,outfile,indent+4);
4657 /*------------------------------------------------------------------*/
4658 /*----------------------------*/
4660 /*----------------------------*/
4661 case SIZEOF: /* evaluate wihout code generation */
4662 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4665 /*------------------------------------------------------------------*/
4666 /*----------------------------*/
4667 /* conditional operator '?' */
4668 /*----------------------------*/
4670 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4671 printTypeChain(tree->ftype,outfile);
4672 fprintf(outfile,")\n");
4673 ast_print(tree->left,outfile,indent+4);
4674 ast_print(tree->right,outfile,indent+4);
4678 fprintf(outfile,"COLON(:) (%p) type (",tree);
4679 printTypeChain(tree->ftype,outfile);
4680 fprintf(outfile,")\n");
4681 ast_print(tree->left,outfile,indent+4);
4682 ast_print(tree->right,outfile,indent+4);
4685 /*------------------------------------------------------------------*/
4686 /*----------------------------*/
4687 /* assignment operators */
4688 /*----------------------------*/
4690 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4691 printTypeChain(tree->ftype,outfile);
4692 fprintf(outfile,")\n");
4693 ast_print(tree->left,outfile,indent+4);
4694 ast_print(tree->right,outfile,indent+4);
4697 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4698 printTypeChain(tree->ftype,outfile);
4699 fprintf(outfile,")\n");
4700 ast_print(tree->left,outfile,indent+4);
4701 ast_print(tree->right,outfile,indent+4);
4704 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4705 printTypeChain(tree->ftype,outfile);
4706 fprintf(outfile,")\n");
4707 ast_print(tree->left,outfile,indent+4);
4708 ast_print(tree->right,outfile,indent+4);
4711 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4712 printTypeChain(tree->ftype,outfile);
4713 fprintf(outfile,")\n");
4714 ast_print(tree->left,outfile,indent+4);
4715 ast_print(tree->right,outfile,indent+4);
4718 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4719 printTypeChain(tree->ftype,outfile);
4720 fprintf(outfile,")\n");
4721 ast_print(tree->left,outfile,indent+4);
4722 ast_print(tree->right,outfile,indent+4);
4725 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4726 printTypeChain(tree->ftype,outfile);
4727 fprintf(outfile,")\n");
4728 ast_print(tree->left,outfile,indent+4);
4729 ast_print(tree->right,outfile,indent+4);
4732 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4733 printTypeChain(tree->ftype,outfile);
4734 fprintf(outfile,")\n");
4735 ast_print(tree->left,outfile,indent+4);
4736 ast_print(tree->right,outfile,indent+4);
4738 /*------------------------------------------------------------------*/
4739 /*----------------------------*/
4741 /*----------------------------*/
4743 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4744 printTypeChain(tree->ftype,outfile);
4745 fprintf(outfile,")\n");
4746 ast_print(tree->left,outfile,indent+4);
4747 ast_print(tree->right,outfile,indent+4);
4749 /*------------------------------------------------------------------*/
4750 /*----------------------------*/
4752 /*----------------------------*/
4754 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4755 printTypeChain(tree->ftype,outfile);
4756 fprintf(outfile,")\n");
4757 ast_print(tree->left,outfile,indent+4);
4758 ast_print(tree->right,outfile,indent+4);
4760 /*------------------------------------------------------------------*/
4761 /*----------------------------*/
4762 /* straight assignemnt */
4763 /*----------------------------*/
4765 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4766 printTypeChain(tree->ftype,outfile);
4767 fprintf(outfile,")\n");
4768 ast_print(tree->left,outfile,indent+4);
4769 ast_print(tree->right,outfile,indent+4);
4771 /*------------------------------------------------------------------*/
4772 /*----------------------------*/
4773 /* comma operator */
4774 /*----------------------------*/
4776 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4777 printTypeChain(tree->ftype,outfile);
4778 fprintf(outfile,")\n");
4779 ast_print(tree->left,outfile,indent+4);
4780 ast_print(tree->right,outfile,indent+4);
4782 /*------------------------------------------------------------------*/
4783 /*----------------------------*/
4785 /*----------------------------*/
4788 fprintf(outfile,"CALL (%p) type (",tree);
4789 printTypeChain(tree->ftype,outfile);
4790 fprintf(outfile,")\n");
4791 ast_print(tree->left,outfile,indent+4);
4792 ast_print(tree->right,outfile,indent+4);
4795 fprintf(outfile,"PARMS\n");
4796 ast_print(tree->left,outfile,indent+4);
4797 if (tree->right && !IS_AST_PARAM(tree->right)) {
4798 ast_print(tree->right,outfile,indent+4);
4801 /*------------------------------------------------------------------*/
4802 /*----------------------------*/
4803 /* return statement */
4804 /*----------------------------*/
4806 fprintf(outfile,"RETURN (%p) type (",tree);
4807 printTypeChain(tree->right->ftype,outfile);
4808 fprintf(outfile,")\n");
4809 ast_print(tree->right,outfile,indent+4);
4811 /*------------------------------------------------------------------*/
4812 /*----------------------------*/
4813 /* label statement */
4814 /*----------------------------*/
4816 fprintf(outfile,"LABEL (%p)",tree);
4817 ast_print(tree->left,outfile,indent+4);
4818 ast_print(tree->right,outfile,indent);
4820 /*------------------------------------------------------------------*/
4821 /*----------------------------*/
4822 /* switch statement */
4823 /*----------------------------*/
4827 fprintf(outfile,"SWITCH (%p) ",tree);
4828 ast_print(tree->left,outfile,0);
4829 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4830 INDENT(indent+4,outfile);
4831 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4832 (int) floatFromVal(val),
4833 tree->values.switchVals.swNum,
4834 (int) floatFromVal(val));
4836 ast_print(tree->right,outfile,indent);
4839 /*------------------------------------------------------------------*/
4840 /*----------------------------*/
4842 /*----------------------------*/
4844 fprintf(outfile,"IF (%p) \n",tree);
4845 ast_print(tree->left,outfile,indent+4);
4846 if (tree->trueLabel) {
4847 INDENT(indent,outfile);
4848 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4850 if (tree->falseLabel) {
4851 INDENT(indent,outfile);
4852 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4854 ast_print(tree->right,outfile,indent+4);
4856 /*------------------------------------------------------------------*/
4857 /*----------------------------*/
4859 /*----------------------------*/
4861 fprintf(outfile,"FOR (%p) \n",tree);
4862 if (AST_FOR( tree, initExpr)) {
4863 INDENT(indent+4,outfile);
4864 fprintf(outfile,"INIT EXPR ");
4865 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4867 if (AST_FOR( tree, condExpr)) {
4868 INDENT(indent+4,outfile);
4869 fprintf(outfile,"COND EXPR ");
4870 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4872 if (AST_FOR( tree, loopExpr)) {
4873 INDENT(indent+4,outfile);
4874 fprintf(outfile,"LOOP EXPR ");
4875 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4877 fprintf(outfile,"FOR LOOP BODY \n");
4878 ast_print(tree->left,outfile,indent+4);
4887 ast_print(t,stdout,0);