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 if (getNelements(sym->type, sym->ival)>1) {
1102 werror (W_EXCESS_INITIALIZERS, "scalar",
1103 sym->name, sym->lineDef);
1105 work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1106 list2expr (sym->ival));
1109 setAstLineno (work, sym->lineDef);
1113 staticAutos = newNode (NULLOP, staticAutos, work);
1120 /* if there is an initial value */
1121 if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1123 if (IS_AGGREGATE (sym->type)) {
1124 work = initAggregates (sym, sym->ival, NULL);
1126 if (getNelements(sym->type, sym->ival)>1) {
1127 werror (W_EXCESS_INITIALIZERS, "scalar",
1128 sym->name, sym->lineDef);
1130 work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1131 list2expr (sym->ival));
1134 setAstLineno (work, sym->lineDef);
1137 init = newNode (NULLOP, init, work);
1146 /*-----------------------------------------------------------------*/
1147 /* stringToSymbol - creates a symbol from a literal string */
1148 /*-----------------------------------------------------------------*/
1150 stringToSymbol (value * val)
1152 char name[SDCC_NAME_MAX + 1];
1153 static int charLbl = 0;
1156 sprintf (name, "_str_%d", charLbl++);
1157 sym = newSymbol (name, 0); /* make it @ level 0 */
1158 strcpy (sym->rname, name);
1160 /* copy the type from the value passed */
1161 sym->type = copyLinkChain (val->type);
1162 sym->etype = getSpec (sym->type);
1163 /* change to storage class & output class */
1164 SPEC_SCLS (sym->etype) = S_CODE;
1165 SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1166 SPEC_STAT (sym->etype) = 1;
1167 /* make the level & block = 0 */
1168 sym->block = sym->level = 0;
1170 /* create an ival */
1171 sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1176 allocVariables (sym);
1179 return symbolVal (sym);
1183 /*-----------------------------------------------------------------*/
1184 /* processBlockVars - will go thru the ast looking for block if */
1185 /* a block is found then will allocate the syms */
1186 /* will also gather the auto inits present */
1187 /*-----------------------------------------------------------------*/
1189 processBlockVars (ast * tree, int *stack, int action)
1194 /* if this is a block */
1195 if (tree->type == EX_OP && tree->opval.op == BLOCK)
1199 if (action == ALLOCATE)
1201 *stack += allocVariables (tree->values.sym);
1202 autoInit = gatherAutoInit (tree->values.sym);
1204 /* if there are auto inits then do them */
1206 tree->left = newNode (NULLOP, autoInit, tree->left);
1208 else /* action is deallocate */
1209 deallocLocal (tree->values.sym);
1212 processBlockVars (tree->left, stack, action);
1213 processBlockVars (tree->right, stack, action);
1217 /*-----------------------------------------------------------------*/
1218 /* constExprValue - returns the value of a constant expression */
1219 /* or NULL if it is not a constant expression */
1220 /*-----------------------------------------------------------------*/
1222 constExprValue (ast * cexpr, int check)
1224 cexpr = decorateType (resolveSymbols (cexpr));
1226 /* if this is not a constant then */
1227 if (!IS_LITERAL (cexpr->ftype))
1229 /* then check if this is a literal array
1231 if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1232 SPEC_CVAL (cexpr->etype).v_char &&
1233 IS_ARRAY (cexpr->ftype))
1235 value *val = valFromType (cexpr->ftype);
1236 SPEC_SCLS (val->etype) = S_LITERAL;
1237 val->sym = cexpr->opval.val->sym;
1238 val->sym->type = copyLinkChain (cexpr->ftype);
1239 val->sym->etype = getSpec (val->sym->type);
1240 strcpy (val->name, cexpr->opval.val->sym->rname);
1244 /* if we are casting a literal value then */
1245 if (IS_AST_OP (cexpr) &&
1246 cexpr->opval.op == CAST &&
1247 IS_LITERAL (cexpr->left->ftype))
1248 return valCastLiteral (cexpr->ftype,
1249 floatFromVal (cexpr->left->opval.val));
1251 if (IS_AST_VALUE (cexpr))
1252 return cexpr->opval.val;
1255 werror (E_CONST_EXPECTED, "found expression");
1260 /* return the value */
1261 return cexpr->opval.val;
1265 /*-----------------------------------------------------------------*/
1266 /* isLabelInAst - will return true if a given label is found */
1267 /*-----------------------------------------------------------------*/
1269 isLabelInAst (symbol * label, ast * tree)
1271 if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1274 if (IS_AST_OP (tree) &&
1275 tree->opval.op == LABEL &&
1276 isSymbolEqual (AST_SYMBOL (tree->left), label))
1279 return isLabelInAst (label, tree->right) &&
1280 isLabelInAst (label, tree->left);
1284 /*-----------------------------------------------------------------*/
1285 /* isLoopCountable - return true if the loop count can be determi- */
1286 /* -ned at compile time . */
1287 /*-----------------------------------------------------------------*/
1289 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1290 symbol ** sym, ast ** init, ast ** end)
1293 /* the loop is considered countable if the following
1294 conditions are true :-
1296 a) initExpr :- <sym> = <const>
1297 b) condExpr :- <sym> < <const1>
1298 c) loopExpr :- <sym> ++
1301 /* first check the initExpr */
1302 if (IS_AST_OP (initExpr) &&
1303 initExpr->opval.op == '=' && /* is assignment */
1304 IS_AST_SYM_VALUE (initExpr->left))
1305 { /* left is a symbol */
1307 *sym = AST_SYMBOL (initExpr->left);
1308 *init = initExpr->right;
1313 /* for now the symbol has to be of
1315 if (!IS_INTEGRAL ((*sym)->type))
1318 /* now check condExpr */
1319 if (IS_AST_OP (condExpr))
1322 switch (condExpr->opval.op)
1325 if (IS_AST_SYM_VALUE (condExpr->left) &&
1326 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1327 IS_AST_LIT_VALUE (condExpr->right))
1329 *end = condExpr->right;
1335 if (IS_AST_OP (condExpr->left) &&
1336 condExpr->left->opval.op == '>' &&
1337 IS_AST_LIT_VALUE (condExpr->left->right) &&
1338 IS_AST_SYM_VALUE (condExpr->left->left) &&
1339 isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1342 *end = newNode ('+', condExpr->left->right,
1343 newAst_VALUE (constVal ("1")));
1354 /* check loop expression is of the form <sym>++ */
1355 if (!IS_AST_OP (loopExpr))
1358 /* check if <sym> ++ */
1359 if (loopExpr->opval.op == INC_OP)
1365 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1366 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1373 if (IS_AST_SYM_VALUE (loopExpr->right) &&
1374 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1382 if (loopExpr->opval.op == ADD_ASSIGN)
1385 if (IS_AST_SYM_VALUE (loopExpr->left) &&
1386 isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1387 IS_AST_LIT_VALUE (loopExpr->right) &&
1388 (int) AST_LIT_VALUE (loopExpr->right) != 1)
1396 /*-----------------------------------------------------------------*/
1397 /* astHasVolatile - returns true if ast contains any volatile */
1398 /*-----------------------------------------------------------------*/
1400 astHasVolatile (ast * tree)
1405 if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1408 if (IS_AST_OP (tree))
1409 return astHasVolatile (tree->left) ||
1410 astHasVolatile (tree->right);
1415 /*-----------------------------------------------------------------*/
1416 /* astHasPointer - return true if the ast contains any ptr variable */
1417 /*-----------------------------------------------------------------*/
1419 astHasPointer (ast * tree)
1424 if (IS_AST_LINK (tree))
1427 /* if we hit an array expression then check
1428 only the left side */
1429 if (IS_AST_OP (tree) && tree->opval.op == '[')
1430 return astHasPointer (tree->left);
1432 if (IS_AST_VALUE (tree))
1433 return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1435 return astHasPointer (tree->left) ||
1436 astHasPointer (tree->right);
1440 /*-----------------------------------------------------------------*/
1441 /* astHasSymbol - return true if the ast has the given symbol */
1442 /*-----------------------------------------------------------------*/
1444 astHasSymbol (ast * tree, symbol * sym)
1446 if (!tree || IS_AST_LINK (tree))
1449 if (IS_AST_VALUE (tree))
1451 if (IS_AST_SYM_VALUE (tree))
1452 return isSymbolEqual (AST_SYMBOL (tree), sym);
1457 return astHasSymbol (tree->left, sym) ||
1458 astHasSymbol (tree->right, sym);
1461 /*-----------------------------------------------------------------*/
1462 /* astHasDeref - return true if the ast has an indirect access */
1463 /*-----------------------------------------------------------------*/
1465 astHasDeref (ast * tree)
1467 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1470 if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1472 return astHasDeref (tree->left) || astHasDeref (tree->right);
1475 /*-----------------------------------------------------------------*/
1476 /* isConformingBody - the loop body has to conform to a set of rules */
1477 /* for the loop to be considered reversible read on for rules */
1478 /*-----------------------------------------------------------------*/
1480 isConformingBody (ast * pbody, symbol * sym, ast * body)
1483 /* we are going to do a pre-order traversal of the
1484 tree && check for the following conditions. (essentially
1485 a set of very shallow tests )
1486 a) the sym passed does not participate in
1487 any arithmetic operation
1488 b) There are no function calls
1489 c) all jumps are within the body
1490 d) address of loop control variable not taken
1491 e) if an assignment has a pointer on the
1492 left hand side make sure right does not have
1493 loop control variable */
1495 /* if we reach the end or a leaf then true */
1496 if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1500 /* if anything else is "volatile" */
1501 if (IS_VOLATILE (TETYPE (pbody)))
1504 /* we will walk the body in a pre-order traversal for
1506 switch (pbody->opval.op)
1508 /*------------------------------------------------------------------*/
1510 return isConformingBody (pbody->right, sym, body);
1512 /*------------------------------------------------------------------*/
1517 /*------------------------------------------------------------------*/
1518 case INC_OP: /* incerement operator unary so left only */
1521 /* sure we are not sym is not modified */
1523 IS_AST_SYM_VALUE (pbody->left) &&
1524 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1528 IS_AST_SYM_VALUE (pbody->right) &&
1529 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1534 /*------------------------------------------------------------------*/
1536 case '*': /* can be unary : if right is null then unary operation */
1541 /* if right is NULL then unary operation */
1542 /*------------------------------------------------------------------*/
1543 /*----------------------------*/
1545 /*----------------------------*/
1548 if (IS_AST_SYM_VALUE (pbody->left) &&
1549 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1552 return isConformingBody (pbody->left, sym, body);
1556 if (astHasSymbol (pbody->left, sym) ||
1557 astHasSymbol (pbody->right, sym))
1562 /*------------------------------------------------------------------*/
1570 if (IS_AST_SYM_VALUE (pbody->left) &&
1571 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1574 if (IS_AST_SYM_VALUE (pbody->right) &&
1575 isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1578 return isConformingBody (pbody->left, sym, body) &&
1579 isConformingBody (pbody->right, sym, body);
1586 if (IS_AST_SYM_VALUE (pbody->left) &&
1587 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1589 return isConformingBody (pbody->left, sym, body);
1591 /*------------------------------------------------------------------*/
1603 case SIZEOF: /* evaluate wihout code generation */
1605 return isConformingBody (pbody->left, sym, body) &&
1606 isConformingBody (pbody->right, sym, body);
1608 /*------------------------------------------------------------------*/
1611 /* if left has a pointer & right has loop
1612 control variable then we cannot */
1613 if (astHasPointer (pbody->left) &&
1614 astHasSymbol (pbody->right, sym))
1616 if (astHasVolatile (pbody->left))
1619 if (IS_AST_SYM_VALUE (pbody->left) &&
1620 isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1623 if (astHasVolatile (pbody->left))
1626 if (astHasDeref(pbody->right)) return FALSE;
1628 return isConformingBody (pbody->left, sym, body) &&
1629 isConformingBody (pbody->right, sym, body);
1640 assert ("Parser should not have generated this\n");
1642 /*------------------------------------------------------------------*/
1643 /*----------------------------*/
1644 /* comma operator */
1645 /*----------------------------*/
1647 return isConformingBody (pbody->left, sym, body) &&
1648 isConformingBody (pbody->right, sym, body);
1650 /*------------------------------------------------------------------*/
1651 /*----------------------------*/
1653 /*----------------------------*/
1657 /*------------------------------------------------------------------*/
1658 /*----------------------------*/
1659 /* return statement */
1660 /*----------------------------*/
1665 if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1670 if (astHasSymbol (pbody->left, sym))
1677 return isConformingBody (pbody->left, sym, body) &&
1678 isConformingBody (pbody->right, sym, body);
1684 /*-----------------------------------------------------------------*/
1685 /* isLoopReversible - takes a for loop as input && returns true */
1686 /* if the for loop is reversible. If yes will set the value of */
1687 /* the loop control var & init value & termination value */
1688 /*-----------------------------------------------------------------*/
1690 isLoopReversible (ast * loop, symbol ** loopCntrl,
1691 ast ** init, ast ** end)
1693 /* if option says don't do it then don't */
1694 if (optimize.noLoopReverse)
1696 /* there are several tests to determine this */
1698 /* for loop has to be of the form
1699 for ( <sym> = <const1> ;
1700 [<sym> < <const2>] ;
1701 [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1703 if (!isLoopCountable (AST_FOR (loop, initExpr),
1704 AST_FOR (loop, condExpr),
1705 AST_FOR (loop, loopExpr),
1706 loopCntrl, init, end))
1709 /* now do some serious checking on the body of the loop
1712 return isConformingBody (loop->left, *loopCntrl, loop->left);
1716 /*-----------------------------------------------------------------*/
1717 /* replLoopSym - replace the loop sym by loop sym -1 */
1718 /*-----------------------------------------------------------------*/
1720 replLoopSym (ast * body, symbol * sym)
1723 if (!body || IS_AST_LINK (body))
1726 if (IS_AST_SYM_VALUE (body))
1729 if (isSymbolEqual (AST_SYMBOL (body), sym))
1733 body->opval.op = '-';
1734 body->left = newAst_VALUE (symbolVal (sym));
1735 body->right = newAst_VALUE (constVal ("1"));
1743 replLoopSym (body->left, sym);
1744 replLoopSym (body->right, sym);
1748 /*-----------------------------------------------------------------*/
1749 /* reverseLoop - do the actual loop reversal */
1750 /*-----------------------------------------------------------------*/
1752 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1756 /* create the following tree
1761 if (sym) goto for_continue ;
1764 /* put it together piece by piece */
1765 rloop = newNode (NULLOP,
1766 createIf (newAst_VALUE (symbolVal (sym)),
1768 newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1771 newAst_VALUE (symbolVal (sym)),
1774 replLoopSym (loop->left, sym);
1776 rloop = newNode (NULLOP,
1778 newAst_VALUE (symbolVal (sym)),
1779 newNode ('-', end, init)),
1780 createLabel (AST_FOR (loop, continueLabel),
1784 newNode (SUB_ASSIGN,
1785 newAst_VALUE (symbolVal (sym)),
1786 newAst_VALUE (constVal ("1"))),
1789 return decorateType (rloop);
1793 //#define DEMAND_INTEGER_PROMOTION
1795 #ifdef DEMAND_INTEGER_PROMOTION
1797 /*-----------------------------------------------------------------*/
1798 /* walk a tree looking for the leaves. Add a typecast to the given */
1799 /* type to each value leaf node. */
1800 /*-----------------------------------------------------------------*/
1802 pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
1804 if (!node || IS_CALLOP(node))
1806 /* WTF? We should never get here. */
1810 if (!node->left && !node->right)
1812 /* We're at a leaf; if it's a value, apply the typecast */
1813 if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
1815 *parentPtr = decorateType (newNode (CAST,
1816 newAst_LINK (copyLinkChain (type)),
1824 pushTypeCastToLeaves (type, node->left, &(node->left));
1828 pushTypeCastToLeaves (type, node->right, &(node->right));
1835 /*-----------------------------------------------------------------*/
1836 /* decorateType - compute type for this tree also does type cheking */
1837 /* this is done bottom up, since type have to flow upwards */
1838 /* it also does constant folding, and paramater checking */
1839 /*-----------------------------------------------------------------*/
1841 decorateType (ast * tree)
1849 /* if already has type then do nothing */
1850 if (tree->decorated)
1853 tree->decorated = 1;
1855 /* print the line */
1856 /* if not block & function */
1857 if (tree->type == EX_OP &&
1858 (tree->opval.op != FUNCTION &&
1859 tree->opval.op != BLOCK &&
1860 tree->opval.op != NULLOP))
1862 filename = tree->filename;
1863 lineno = tree->lineno;
1866 /* if any child is an error | this one is an error do nothing */
1867 if (tree->isError ||
1868 (tree->left && tree->left->isError) ||
1869 (tree->right && tree->right->isError))
1872 /*------------------------------------------------------------------*/
1873 /*----------------------------*/
1874 /* leaf has been reached */
1875 /*----------------------------*/
1876 /* if this is of type value */
1877 /* just get the type */
1878 if (tree->type == EX_VALUE)
1881 if (IS_LITERAL (tree->opval.val->etype))
1884 /* if this is a character array then declare it */
1885 if (IS_ARRAY (tree->opval.val->type))
1886 tree->opval.val = stringToSymbol (tree->opval.val);
1888 /* otherwise just copy the type information */
1889 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1893 if (tree->opval.val->sym)
1895 /* if the undefined flag is set then give error message */
1896 if (tree->opval.val->sym->undefined)
1898 werror (E_ID_UNDEF, tree->opval.val->sym->name);
1900 TTYPE (tree) = TETYPE (tree) =
1901 tree->opval.val->type = tree->opval.val->sym->type =
1902 tree->opval.val->etype = tree->opval.val->sym->etype =
1903 copyLinkChain (INTTYPE);
1908 /* if impilicit i.e. struct/union member then no type */
1909 if (tree->opval.val->sym->implicit)
1910 TTYPE (tree) = TETYPE (tree) = NULL;
1915 /* else copy the type */
1916 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1918 /* and mark it as referenced */
1919 tree->opval.val->sym->isref = 1;
1927 /* if type link for the case of cast */
1928 if (tree->type == EX_LINK)
1930 COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1937 dtl = decorateType (tree->left);
1938 dtr = decorateType (tree->right);
1940 /* this is to take care of situations
1941 when the tree gets rewritten */
1942 if (dtl != tree->left)
1944 if (dtr != tree->right)
1948 /* depending on type of operator do */
1950 switch (tree->opval.op)
1952 /*------------------------------------------------------------------*/
1953 /*----------------------------*/
1955 /*----------------------------*/
1958 /* determine which is the array & which the index */
1959 if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1962 ast *tempTree = tree->left;
1963 tree->left = tree->right;
1964 tree->right = tempTree;
1967 /* first check if this is a array or a pointer */
1968 if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1970 werror (E_NEED_ARRAY_PTR, "[]");
1971 goto errorTreeReturn;
1974 /* check if the type of the idx */
1975 if (!IS_INTEGRAL (RTYPE (tree)))
1977 werror (E_IDX_NOT_INT);
1978 goto errorTreeReturn;
1981 /* if the left is an rvalue then error */
1984 werror (E_LVALUE_REQUIRED, "array access");
1985 goto errorTreeReturn;
1988 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1989 if (IS_PTR(LTYPE(tree))) {
1990 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1994 /*------------------------------------------------------------------*/
1995 /*----------------------------*/
1997 /*----------------------------*/
1999 /* if this is not a structure */
2000 if (!IS_STRUCT (LTYPE (tree)))
2002 werror (E_STRUCT_UNION, ".");
2003 goto errorTreeReturn;
2005 TTYPE (tree) = structElemType (LTYPE (tree),
2006 (tree->right->type == EX_VALUE ?
2007 tree->right->opval.val : NULL));
2008 TETYPE (tree) = getSpec (TTYPE (tree));
2011 /*------------------------------------------------------------------*/
2012 /*----------------------------*/
2013 /* struct/union pointer */
2014 /*----------------------------*/
2016 /* if not pointer to a structure */
2017 if (!IS_PTR (LTYPE (tree)))
2019 werror (E_PTR_REQD);
2020 goto errorTreeReturn;
2023 if (!IS_STRUCT (LTYPE (tree)->next))
2025 werror (E_STRUCT_UNION, "->");
2026 goto errorTreeReturn;
2029 TTYPE (tree) = structElemType (LTYPE (tree)->next,
2030 (tree->right->type == EX_VALUE ?
2031 tree->right->opval.val : NULL));
2032 TETYPE (tree) = getSpec (TTYPE (tree));
2035 /*------------------------------------------------------------------*/
2036 /*----------------------------*/
2037 /* ++/-- operation */
2038 /*----------------------------*/
2039 case INC_OP: /* incerement operator unary so left only */
2042 sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2043 COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2044 if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2045 werror (E_CODE_WRITE, "++/--");
2054 /*------------------------------------------------------------------*/
2055 /*----------------------------*/
2057 /*----------------------------*/
2058 case '&': /* can be unary */
2059 /* if right is NULL then unary operation */
2060 if (tree->right) /* not an unary operation */
2063 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2065 werror (E_BITWISE_OP);
2066 werror (W_CONTINUE, "left & right types are ");
2067 printTypeChain (LTYPE (tree), stderr);
2068 fprintf (stderr, ",");
2069 printTypeChain (RTYPE (tree), stderr);
2070 fprintf (stderr, "\n");
2071 goto errorTreeReturn;
2074 /* if they are both literal */
2075 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2077 tree->type = EX_VALUE;
2078 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2079 valFromType (RETYPE (tree)), '&');
2081 tree->right = tree->left = NULL;
2082 TETYPE (tree) = tree->opval.val->etype;
2083 TTYPE (tree) = tree->opval.val->type;
2087 /* see if this is a GETHBIT operation if yes
2090 ast *otree = optimizeGetHbit (tree);
2093 return decorateType (otree);
2097 computeType (LTYPE (tree), RTYPE (tree));
2098 TETYPE (tree) = getSpec (TTYPE (tree));
2100 LRVAL (tree) = RRVAL (tree) = 1;
2104 /*------------------------------------------------------------------*/
2105 /*----------------------------*/
2107 /*----------------------------*/
2109 p->class = DECLARATOR;
2110 /* if bit field then error */
2111 if (IS_BITVAR (tree->left->etype))
2113 werror (E_ILLEGAL_ADDR, "address of bit variable");
2114 goto errorTreeReturn;
2117 if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2119 werror (E_ILLEGAL_ADDR, "address of register variable");
2120 goto errorTreeReturn;
2123 if (IS_FUNC (LTYPE (tree)))
2125 werror (E_ILLEGAL_ADDR, "address of function");
2126 goto errorTreeReturn;
2129 if (IS_LITERAL(LTYPE(tree)))
2131 werror (E_ILLEGAL_ADDR, "address of literal");
2132 goto errorTreeReturn;
2137 werror (E_LVALUE_REQUIRED, "address of");
2138 goto errorTreeReturn;
2140 if (SPEC_SCLS (tree->left->etype) == S_CODE)
2142 DCL_TYPE (p) = CPOINTER;
2143 DCL_PTR_CONST (p) = port->mem.code_ro;
2145 else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2146 DCL_TYPE (p) = FPOINTER;
2147 else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2148 DCL_TYPE (p) = PPOINTER;
2149 else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2150 DCL_TYPE (p) = IPOINTER;
2151 else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2152 DCL_TYPE (p) = EEPPOINTER;
2153 else if (SPEC_OCLS(tree->left->etype))
2154 DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2156 DCL_TYPE (p) = POINTER;
2158 if (IS_AST_SYM_VALUE (tree->left))
2160 AST_SYMBOL (tree->left)->addrtaken = 1;
2161 AST_SYMBOL (tree->left)->allocreq = 1;
2164 p->next = LTYPE (tree);
2166 TETYPE (tree) = getSpec (TTYPE (tree));
2167 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2168 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2173 /*------------------------------------------------------------------*/
2174 /*----------------------------*/
2176 /*----------------------------*/
2178 /* if the rewrite succeeds then don't go any furthur */
2180 ast *wtree = optimizeRRCRLC (tree);
2182 return decorateType (wtree);
2184 /*------------------------------------------------------------------*/
2185 /*----------------------------*/
2187 /*----------------------------*/
2189 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2191 werror (E_BITWISE_OP);
2192 werror (W_CONTINUE, "left & right types are ");
2193 printTypeChain (LTYPE (tree), stderr);
2194 fprintf (stderr, ",");
2195 printTypeChain (RTYPE (tree), stderr);
2196 fprintf (stderr, "\n");
2197 goto errorTreeReturn;
2200 /* if they are both literal then */
2201 /* rewrite the tree */
2202 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2204 tree->type = EX_VALUE;
2205 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2206 valFromType (RETYPE (tree)),
2208 tree->right = tree->left = NULL;
2209 TETYPE (tree) = tree->opval.val->etype;
2210 TTYPE (tree) = tree->opval.val->type;
2213 LRVAL (tree) = RRVAL (tree) = 1;
2214 TETYPE (tree) = getSpec (TTYPE (tree) =
2215 computeType (LTYPE (tree),
2218 /*------------------------------------------------------------------*/
2219 /*----------------------------*/
2221 /*----------------------------*/
2223 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2225 werror (E_INVALID_OP, "divide");
2226 goto errorTreeReturn;
2228 /* if they are both literal then */
2229 /* rewrite the tree */
2230 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2232 tree->type = EX_VALUE;
2233 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2234 valFromType (RETYPE (tree)));
2235 tree->right = tree->left = NULL;
2236 TETYPE (tree) = getSpec (TTYPE (tree) =
2237 tree->opval.val->type);
2240 LRVAL (tree) = RRVAL (tree) = 1;
2241 TETYPE (tree) = getSpec (TTYPE (tree) =
2242 computeType (LTYPE (tree),
2246 /*------------------------------------------------------------------*/
2247 /*----------------------------*/
2249 /*----------------------------*/
2251 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2253 werror (E_BITWISE_OP);
2254 werror (W_CONTINUE, "left & right types are ");
2255 printTypeChain (LTYPE (tree), stderr);
2256 fprintf (stderr, ",");
2257 printTypeChain (RTYPE (tree), stderr);
2258 fprintf (stderr, "\n");
2259 goto errorTreeReturn;
2261 /* if they are both literal then */
2262 /* rewrite the tree */
2263 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2265 tree->type = EX_VALUE;
2266 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2267 valFromType (RETYPE (tree)));
2268 tree->right = tree->left = NULL;
2269 TETYPE (tree) = getSpec (TTYPE (tree) =
2270 tree->opval.val->type);
2273 LRVAL (tree) = RRVAL (tree) = 1;
2274 TETYPE (tree) = getSpec (TTYPE (tree) =
2275 computeType (LTYPE (tree),
2279 /*------------------------------------------------------------------*/
2280 /*----------------------------*/
2281 /* address dereference */
2282 /*----------------------------*/
2283 case '*': /* can be unary : if right is null then unary operation */
2286 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2288 werror (E_PTR_REQD);
2289 goto errorTreeReturn;
2294 werror (E_LVALUE_REQUIRED, "pointer deref");
2295 goto errorTreeReturn;
2297 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2298 LTYPE (tree)->next : NULL);
2299 TETYPE (tree) = getSpec (TTYPE (tree));
2300 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2304 /*------------------------------------------------------------------*/
2305 /*----------------------------*/
2306 /* multiplication */
2307 /*----------------------------*/
2308 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2310 werror (E_INVALID_OP, "multiplication");
2311 goto errorTreeReturn;
2314 /* if they are both literal then */
2315 /* rewrite the tree */
2316 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2318 tree->type = EX_VALUE;
2319 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2320 valFromType (RETYPE (tree)));
2321 tree->right = tree->left = NULL;
2322 TETYPE (tree) = getSpec (TTYPE (tree) =
2323 tree->opval.val->type);
2327 /* if left is a literal exchange left & right */
2328 if (IS_LITERAL (LTYPE (tree)))
2330 ast *tTree = tree->left;
2331 tree->left = tree->right;
2332 tree->right = tTree;
2335 LRVAL (tree) = RRVAL (tree) = 1;
2336 /* promote result to int if left & right are char
2337 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2338 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2339 TETYPE (tree) = getSpec (TTYPE (tree) =
2340 computeType (LTYPE (tree),
2342 SPEC_NOUN(TETYPE(tree)) = V_INT;
2344 TETYPE (tree) = getSpec (TTYPE (tree) =
2345 computeType (LTYPE (tree),
2350 /*------------------------------------------------------------------*/
2351 /*----------------------------*/
2352 /* unary '+' operator */
2353 /*----------------------------*/
2358 if (!IS_INTEGRAL (LTYPE (tree)))
2360 werror (E_UNARY_OP, '+');
2361 goto errorTreeReturn;
2364 /* if left is a literal then do it */
2365 if (IS_LITERAL (LTYPE (tree)))
2367 tree->type = EX_VALUE;
2368 tree->opval.val = valFromType (LETYPE (tree));
2370 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2374 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2378 /*------------------------------------------------------------------*/
2379 /*----------------------------*/
2381 /*----------------------------*/
2383 /* this is not a unary operation */
2384 /* if both pointers then problem */
2385 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2386 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2388 werror (E_PTR_PLUS_PTR);
2389 goto errorTreeReturn;
2392 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2393 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2395 werror (E_PLUS_INVALID, "+");
2396 goto errorTreeReturn;
2399 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2400 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2402 werror (E_PLUS_INVALID, "+");
2403 goto errorTreeReturn;
2405 /* if they are both literal then */
2406 /* rewrite the tree */
2407 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2409 tree->type = EX_VALUE;
2410 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2411 valFromType (RETYPE (tree)));
2412 tree->right = tree->left = NULL;
2413 TETYPE (tree) = getSpec (TTYPE (tree) =
2414 tree->opval.val->type);
2418 /* if the right is a pointer or left is a literal
2419 xchange left & right */
2420 if (IS_ARRAY (RTYPE (tree)) ||
2421 IS_PTR (RTYPE (tree)) ||
2422 IS_LITERAL (LTYPE (tree)))
2424 ast *tTree = tree->left;
2425 tree->left = tree->right;
2426 tree->right = tTree;
2429 LRVAL (tree) = RRVAL (tree) = 1;
2430 /* if the left is a pointer */
2431 if (IS_PTR (LTYPE (tree)))
2432 TETYPE (tree) = getSpec (TTYPE (tree) =
2435 TETYPE (tree) = getSpec (TTYPE (tree) =
2436 computeType (LTYPE (tree),
2440 /*------------------------------------------------------------------*/
2441 /*----------------------------*/
2443 /*----------------------------*/
2444 case '-': /* can be unary */
2445 /* if right is null then unary */
2449 if (!IS_ARITHMETIC (LTYPE (tree)))
2451 werror (E_UNARY_OP, tree->opval.op);
2452 goto errorTreeReturn;
2455 /* if left is a literal then do it */
2456 if (IS_LITERAL (LTYPE (tree)))
2458 tree->type = EX_VALUE;
2459 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2461 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2462 SPEC_USIGN(TETYPE(tree)) = 0;
2466 TTYPE (tree) = LTYPE (tree);
2470 /*------------------------------------------------------------------*/
2471 /*----------------------------*/
2473 /*----------------------------*/
2475 if (!(IS_PTR (LTYPE (tree)) ||
2476 IS_ARRAY (LTYPE (tree)) ||
2477 IS_ARITHMETIC (LTYPE (tree))))
2479 werror (E_PLUS_INVALID, "-");
2480 goto errorTreeReturn;
2483 if (!(IS_PTR (RTYPE (tree)) ||
2484 IS_ARRAY (RTYPE (tree)) ||
2485 IS_ARITHMETIC (RTYPE (tree))))
2487 werror (E_PLUS_INVALID, "-");
2488 goto errorTreeReturn;
2491 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2492 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2493 IS_INTEGRAL (RTYPE (tree))))
2495 werror (E_PLUS_INVALID, "-");
2496 goto errorTreeReturn;
2499 /* if they are both literal then */
2500 /* rewrite the tree */
2501 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2503 tree->type = EX_VALUE;
2504 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2505 valFromType (RETYPE (tree)));
2506 tree->right = tree->left = NULL;
2507 TETYPE (tree) = getSpec (TTYPE (tree) =
2508 tree->opval.val->type);
2512 /* if the left & right are equal then zero */
2513 if (isAstEqual (tree->left, tree->right))
2515 tree->type = EX_VALUE;
2516 tree->left = tree->right = NULL;
2517 tree->opval.val = constVal ("0");
2518 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2522 /* if both of them are pointers or arrays then */
2523 /* the result is going to be an integer */
2524 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2525 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2526 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2528 /* if only the left is a pointer */
2529 /* then result is a pointer */
2530 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2531 TETYPE (tree) = getSpec (TTYPE (tree) =
2534 TETYPE (tree) = getSpec (TTYPE (tree) =
2535 computeType (LTYPE (tree),
2537 LRVAL (tree) = RRVAL (tree) = 1;
2540 /*------------------------------------------------------------------*/
2541 /*----------------------------*/
2543 /*----------------------------*/
2545 /* can be only integral type */
2546 if (!IS_INTEGRAL (LTYPE (tree)))
2548 werror (E_UNARY_OP, tree->opval.op);
2549 goto errorTreeReturn;
2552 /* if left is a literal then do it */
2553 if (IS_LITERAL (LTYPE (tree)))
2555 tree->type = EX_VALUE;
2556 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2558 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2562 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2565 /*------------------------------------------------------------------*/
2566 /*----------------------------*/
2568 /*----------------------------*/
2570 /* can be pointer */
2571 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2572 !IS_PTR (LTYPE (tree)) &&
2573 !IS_ARRAY (LTYPE (tree)))
2575 werror (E_UNARY_OP, tree->opval.op);
2576 goto errorTreeReturn;
2579 /* if left is a literal then do it */
2580 if (IS_LITERAL (LTYPE (tree)))
2582 tree->type = EX_VALUE;
2583 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2585 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2589 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2592 /*------------------------------------------------------------------*/
2593 /*----------------------------*/
2595 /*----------------------------*/
2598 TTYPE (tree) = LTYPE (tree);
2599 TETYPE (tree) = LETYPE (tree);
2603 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2608 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2610 werror (E_SHIFT_OP_INVALID);
2611 werror (W_CONTINUE, "left & right types are ");
2612 printTypeChain (LTYPE (tree), stderr);
2613 fprintf (stderr, ",");
2614 printTypeChain (RTYPE (tree), stderr);
2615 fprintf (stderr, "\n");
2616 goto errorTreeReturn;
2619 /* if they are both literal then */
2620 /* rewrite the tree */
2621 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2623 tree->type = EX_VALUE;
2624 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2625 valFromType (RETYPE (tree)),
2626 (tree->opval.op == LEFT_OP ? 1 : 0));
2627 tree->right = tree->left = NULL;
2628 TETYPE (tree) = getSpec (TTYPE (tree) =
2629 tree->opval.val->type);
2632 /* if only the right side is a literal & we are
2633 shifting more than size of the left operand then zero */
2634 if (IS_LITERAL (RTYPE (tree)) &&
2635 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2636 (getSize (LTYPE (tree)) * 8))
2638 werror (W_SHIFT_CHANGED,
2639 (tree->opval.op == LEFT_OP ? "left" : "right"));
2640 tree->type = EX_VALUE;
2641 tree->left = tree->right = NULL;
2642 tree->opval.val = constVal ("0");
2643 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2646 LRVAL (tree) = RRVAL (tree) = 1;
2647 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2649 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2653 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2657 /*------------------------------------------------------------------*/
2658 /*----------------------------*/
2660 /*----------------------------*/
2661 case CAST: /* change the type */
2662 /* cannot cast to an aggregate type */
2663 if (IS_AGGREGATE (LTYPE (tree)))
2665 werror (E_CAST_ILLEGAL);
2666 goto errorTreeReturn;
2669 /* make sure the type is complete and sane */
2670 checkTypeSanity(LETYPE(tree), "(cast)");
2673 /* if the right is a literal replace the tree */
2674 if (IS_LITERAL (RETYPE (tree))) {
2675 if (!IS_PTR (LTYPE (tree))) {
2676 tree->type = EX_VALUE;
2678 valCastLiteral (LTYPE (tree),
2679 floatFromVal (valFromType (RETYPE (tree))));
2682 TTYPE (tree) = tree->opval.val->type;
2683 tree->values.literalFromCast = 1;
2684 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2685 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2686 sym_link *rest = LTYPE(tree)->next;
2687 werror(W_LITERAL_GENERIC);
2688 TTYPE(tree) = newLink();
2689 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2690 TTYPE(tree)->next = rest;
2691 tree->left->opval.lnk = TTYPE(tree);
2694 TTYPE (tree) = LTYPE (tree);
2698 TTYPE (tree) = LTYPE (tree);
2702 /* if pointer to struct then check names */
2703 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2704 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2705 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2706 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2708 /* if the right is a literal replace the tree */
2709 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2710 tree->type = EX_VALUE;
2712 valCastLiteral (LTYPE (tree),
2713 floatFromVal (valFromType (RETYPE (tree))));
2716 TTYPE (tree) = tree->opval.val->type;
2717 tree->values.literalFromCast = 1;
2719 TTYPE (tree) = LTYPE (tree);
2723 TETYPE (tree) = getSpec (TTYPE (tree));
2727 /*------------------------------------------------------------------*/
2728 /*----------------------------*/
2729 /* logical &&, || */
2730 /*----------------------------*/
2733 /* each must me arithmetic type or be a pointer */
2734 if (!IS_PTR (LTYPE (tree)) &&
2735 !IS_ARRAY (LTYPE (tree)) &&
2736 !IS_INTEGRAL (LTYPE (tree)))
2738 werror (E_COMPARE_OP);
2739 goto errorTreeReturn;
2742 if (!IS_PTR (RTYPE (tree)) &&
2743 !IS_ARRAY (RTYPE (tree)) &&
2744 !IS_INTEGRAL (RTYPE (tree)))
2746 werror (E_COMPARE_OP);
2747 goto errorTreeReturn;
2749 /* if they are both literal then */
2750 /* rewrite the tree */
2751 if (IS_LITERAL (RTYPE (tree)) &&
2752 IS_LITERAL (LTYPE (tree)))
2754 tree->type = EX_VALUE;
2755 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2756 valFromType (RETYPE (tree)),
2758 tree->right = tree->left = NULL;
2759 TETYPE (tree) = getSpec (TTYPE (tree) =
2760 tree->opval.val->type);
2763 LRVAL (tree) = RRVAL (tree) = 1;
2764 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2767 /*------------------------------------------------------------------*/
2768 /*----------------------------*/
2769 /* comparison operators */
2770 /*----------------------------*/
2778 ast *lt = optimizeCompare (tree);
2784 /* if they are pointers they must be castable */
2785 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2787 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2789 werror (E_COMPARE_OP);
2790 fprintf (stderr, "comparing type ");
2791 printTypeChain (LTYPE (tree), stderr);
2792 fprintf (stderr, "to type ");
2793 printTypeChain (RTYPE (tree), stderr);
2794 fprintf (stderr, "\n");
2795 goto errorTreeReturn;
2798 /* else they should be promotable to one another */
2801 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2802 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2804 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2806 werror (E_COMPARE_OP);
2807 fprintf (stderr, "comparing type ");
2808 printTypeChain (LTYPE (tree), stderr);
2809 fprintf (stderr, "to type ");
2810 printTypeChain (RTYPE (tree), stderr);
2811 fprintf (stderr, "\n");
2812 goto errorTreeReturn;
2816 /* if they are both literal then */
2817 /* rewrite the tree */
2818 if (IS_LITERAL (RTYPE (tree)) &&
2819 IS_LITERAL (LTYPE (tree)))
2821 tree->type = EX_VALUE;
2822 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2823 valFromType (RETYPE (tree)),
2825 tree->right = tree->left = NULL;
2826 TETYPE (tree) = getSpec (TTYPE (tree) =
2827 tree->opval.val->type);
2830 LRVAL (tree) = RRVAL (tree) = 1;
2831 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2834 /*------------------------------------------------------------------*/
2835 /*----------------------------*/
2837 /*----------------------------*/
2838 case SIZEOF: /* evaluate wihout code generation */
2839 /* change the type to a integer */
2840 tree->type = EX_VALUE;
2841 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2842 tree->opval.val = constVal (buffer);
2843 tree->right = tree->left = NULL;
2844 TETYPE (tree) = getSpec (TTYPE (tree) =
2845 tree->opval.val->type);
2848 /*------------------------------------------------------------------*/
2849 /*----------------------------*/
2850 /* conditional operator '?' */
2851 /*----------------------------*/
2853 /* the type is value of the colon operator (on the right) */
2854 assert(IS_COLON_OP(tree->right));
2855 /* if already known then replace the tree : optimizer will do it
2856 but faster to do it here */
2857 if (IS_LITERAL (LTYPE(tree))) {
2858 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2859 return tree->right->left ;
2861 return tree->right->right ;
2864 TTYPE (tree) = RTYPE(tree);
2865 TETYPE (tree) = getSpec (TTYPE (tree));
2870 /* if they don't match we have a problem */
2871 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2873 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2874 goto errorTreeReturn;
2877 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2878 TETYPE (tree) = getSpec (TTYPE (tree));
2882 /*------------------------------------------------------------------*/
2883 /*----------------------------*/
2884 /* assignment operators */
2885 /*----------------------------*/
2888 /* for these it must be both must be integral */
2889 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2890 !IS_ARITHMETIC (RTYPE (tree)))
2892 werror (E_OPS_INTEGRAL);
2893 goto errorTreeReturn;
2896 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2898 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2899 werror (E_CODE_WRITE, " ");
2903 werror (E_LVALUE_REQUIRED, "*= or /=");
2904 goto errorTreeReturn;
2915 /* for these it must be both must be integral */
2916 if (!IS_INTEGRAL (LTYPE (tree)) ||
2917 !IS_INTEGRAL (RTYPE (tree)))
2919 werror (E_OPS_INTEGRAL);
2920 goto errorTreeReturn;
2923 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2925 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2926 werror (E_CODE_WRITE, " ");
2930 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2931 goto errorTreeReturn;
2937 /*------------------------------------------------------------------*/
2938 /*----------------------------*/
2940 /*----------------------------*/
2942 if (!(IS_PTR (LTYPE (tree)) ||
2943 IS_ARITHMETIC (LTYPE (tree))))
2945 werror (E_PLUS_INVALID, "-=");
2946 goto errorTreeReturn;
2949 if (!(IS_PTR (RTYPE (tree)) ||
2950 IS_ARITHMETIC (RTYPE (tree))))
2952 werror (E_PLUS_INVALID, "-=");
2953 goto errorTreeReturn;
2956 TETYPE (tree) = getSpec (TTYPE (tree) =
2957 computeType (LTYPE (tree),
2960 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2961 werror (E_CODE_WRITE, " ");
2965 werror (E_LVALUE_REQUIRED, "-=");
2966 goto errorTreeReturn;
2972 /*------------------------------------------------------------------*/
2973 /*----------------------------*/
2975 /*----------------------------*/
2977 /* this is not a unary operation */
2978 /* if both pointers then problem */
2979 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2981 werror (E_PTR_PLUS_PTR);
2982 goto errorTreeReturn;
2985 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2987 werror (E_PLUS_INVALID, "+=");
2988 goto errorTreeReturn;
2991 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2993 werror (E_PLUS_INVALID, "+=");
2994 goto errorTreeReturn;
2997 TETYPE (tree) = getSpec (TTYPE (tree) =
2998 computeType (LTYPE (tree),
3001 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3002 werror (E_CODE_WRITE, " ");
3006 werror (E_LVALUE_REQUIRED, "+=");
3007 goto errorTreeReturn;
3010 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3011 tree->opval.op = '=';
3015 /*------------------------------------------------------------------*/
3016 /*----------------------------*/
3017 /* straight assignemnt */
3018 /*----------------------------*/
3020 /* cannot be an aggregate */
3021 if (IS_AGGREGATE (LTYPE (tree)))
3023 werror (E_AGGR_ASSIGN);
3024 goto errorTreeReturn;
3027 /* they should either match or be castable */
3028 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3030 werror (E_TYPE_MISMATCH, "assignment", " ");
3031 fprintf (stderr, "type --> '");
3032 printTypeChain (RTYPE (tree), stderr);
3033 fprintf (stderr, "' ");
3034 fprintf (stderr, "assigned to type --> '");
3035 printTypeChain (LTYPE (tree), stderr);
3036 fprintf (stderr, "'\n");
3037 goto errorTreeReturn;
3040 /* if the left side of the tree is of type void
3041 then report error */
3042 if (IS_VOID (LTYPE (tree)))
3044 werror (E_CAST_ZERO);
3045 printFromToType(RTYPE(tree), LTYPE(tree));
3048 TETYPE (tree) = getSpec (TTYPE (tree) =
3052 if (!tree->initMode ) {
3053 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3054 werror (E_CODE_WRITE, " ");
3058 werror (E_LVALUE_REQUIRED, "=");
3059 goto errorTreeReturn;
3064 /*------------------------------------------------------------------*/
3065 /*----------------------------*/
3066 /* comma operator */
3067 /*----------------------------*/
3069 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3072 /*------------------------------------------------------------------*/
3073 /*----------------------------*/
3075 /*----------------------------*/
3079 if (processParms (tree->left,
3080 FUNC_ARGS(tree->left->ftype),
3081 tree->right, &parmNumber, TRUE)) {
3082 goto errorTreeReturn;
3085 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3087 //FUNC_ARGS(tree->left->ftype) =
3088 //reverseVal (FUNC_ARGS(tree->left->ftype));
3089 reverseParms (tree->right);
3092 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3095 /*------------------------------------------------------------------*/
3096 /*----------------------------*/
3097 /* return statement */
3098 /*----------------------------*/
3103 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3105 werror (W_RETURN_MISMATCH);
3106 printFromToType (RTYPE(tree), currFunc->type->next);
3107 goto errorTreeReturn;
3110 if (IS_VOID (currFunc->type->next)
3112 !IS_VOID (RTYPE (tree)))
3114 werror (E_FUNC_VOID);
3115 goto errorTreeReturn;
3118 /* if there is going to be a casing required then add it */
3119 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3122 decorateType (newNode (CAST,
3123 newAst_LINK (copyLinkChain (currFunc->type->next)),
3132 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3134 werror (E_VOID_FUNC, currFunc->name);
3135 goto errorTreeReturn;
3138 TTYPE (tree) = TETYPE (tree) = NULL;
3141 /*------------------------------------------------------------------*/
3142 /*----------------------------*/
3143 /* switch statement */
3144 /*----------------------------*/
3146 /* the switch value must be an integer */
3147 if (!IS_INTEGRAL (LTYPE (tree)))
3149 werror (E_SWITCH_NON_INTEGER);
3150 goto errorTreeReturn;
3153 TTYPE (tree) = TETYPE (tree) = NULL;
3156 /*------------------------------------------------------------------*/
3157 /*----------------------------*/
3159 /*----------------------------*/
3161 tree->left = backPatchLabels (tree->left,
3164 TTYPE (tree) = TETYPE (tree) = NULL;
3167 /*------------------------------------------------------------------*/
3168 /*----------------------------*/
3170 /*----------------------------*/
3173 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3174 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3175 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3177 /* if the for loop is reversible then
3178 reverse it otherwise do what we normally
3184 if (isLoopReversible (tree, &sym, &init, &end))
3185 return reverseLoop (tree, sym, init, end);
3187 return decorateType (createFor (AST_FOR (tree, trueLabel),
3188 AST_FOR (tree, continueLabel),
3189 AST_FOR (tree, falseLabel),
3190 AST_FOR (tree, condLabel),
3191 AST_FOR (tree, initExpr),
3192 AST_FOR (tree, condExpr),
3193 AST_FOR (tree, loopExpr),
3197 TTYPE (tree) = TETYPE (tree) = NULL;
3201 /* some error found this tree will be killed */
3203 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3204 tree->opval.op = NULLOP;
3210 /*-----------------------------------------------------------------*/
3211 /* sizeofOp - processes size of operation */
3212 /*-----------------------------------------------------------------*/
3214 sizeofOp (sym_link * type)
3218 /* make sure the type is complete and sane */
3219 checkTypeSanity(type, "(sizeof)");
3221 /* get the size and convert it to character */
3222 sprintf (buff, "%d", getSize (type));
3224 /* now convert into value */
3225 return constVal (buff);
3229 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3230 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3231 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3232 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3233 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3234 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3235 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3237 /*-----------------------------------------------------------------*/
3238 /* backPatchLabels - change and or not operators to flow control */
3239 /*-----------------------------------------------------------------*/
3241 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3247 if (!(IS_ANDORNOT (tree)))
3250 /* if this an and */
3253 static int localLbl = 0;
3256 sprintf (buffer, "_and_%d", localLbl++);
3257 localLabel = newSymbol (buffer, NestLevel);
3259 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3261 /* if left is already a IFX then just change the if true label in that */
3262 if (!IS_IFX (tree->left))
3263 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3265 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3266 /* right is a IFX then just join */
3267 if (IS_IFX (tree->right))
3268 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3270 tree->right = createLabel (localLabel, tree->right);
3271 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3273 return newNode (NULLOP, tree->left, tree->right);
3276 /* if this is an or operation */
3279 static int localLbl = 0;
3282 sprintf (buffer, "_or_%d", localLbl++);
3283 localLabel = newSymbol (buffer, NestLevel);
3285 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3287 /* if left is already a IFX then just change the if true label in that */
3288 if (!IS_IFX (tree->left))
3289 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3291 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3292 /* right is a IFX then just join */
3293 if (IS_IFX (tree->right))
3294 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3296 tree->right = createLabel (localLabel, tree->right);
3297 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3299 return newNode (NULLOP, tree->left, tree->right);
3305 int wasnot = IS_NOT (tree->left);
3306 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3308 /* if the left is already a IFX */
3309 if (!IS_IFX (tree->left))
3310 tree->left = newNode (IFX, tree->left, NULL);
3314 tree->left->trueLabel = trueLabel;
3315 tree->left->falseLabel = falseLabel;
3319 tree->left->trueLabel = falseLabel;
3320 tree->left->falseLabel = trueLabel;
3327 tree->trueLabel = trueLabel;
3328 tree->falseLabel = falseLabel;
3335 /*-----------------------------------------------------------------*/
3336 /* createBlock - create expression tree for block */
3337 /*-----------------------------------------------------------------*/
3339 createBlock (symbol * decl, ast * body)
3343 /* if the block has nothing */
3347 ex = newNode (BLOCK, NULL, body);
3348 ex->values.sym = decl;
3350 ex->right = ex->right;
3356 /*-----------------------------------------------------------------*/
3357 /* createLabel - creates the expression tree for labels */
3358 /*-----------------------------------------------------------------*/
3360 createLabel (symbol * label, ast * stmnt)
3363 char name[SDCC_NAME_MAX + 1];
3366 /* must create fresh symbol if the symbol name */
3367 /* exists in the symbol table, since there can */
3368 /* be a variable with the same name as the labl */
3369 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3370 (csym->level == label->level))
3371 label = newSymbol (label->name, label->level);
3373 /* change the name before putting it in add _ */
3374 sprintf (name, "%s", label->name);
3376 /* put the label in the LabelSymbol table */
3377 /* but first check if a label of the same */
3379 if ((csym = findSym (LabelTab, NULL, name)))
3380 werror (E_DUPLICATE_LABEL, label->name);
3382 addSym (LabelTab, label, name, label->level, 0, 0);
3385 label->key = labelKey++;
3386 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3392 /*-----------------------------------------------------------------*/
3393 /* createCase - generates the parsetree for a case statement */
3394 /*-----------------------------------------------------------------*/
3396 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3398 char caseLbl[SDCC_NAME_MAX + 1];
3402 /* if the switch statement does not exist */
3403 /* then case is out of context */
3406 werror (E_CASE_CONTEXT);
3410 caseVal = decorateType (resolveSymbols (caseVal));
3411 /* if not a constant then error */
3412 if (!IS_LITERAL (caseVal->ftype))
3414 werror (E_CASE_CONSTANT);
3418 /* if not a integer than error */
3419 if (!IS_INTEGRAL (caseVal->ftype))
3421 werror (E_CASE_NON_INTEGER);
3425 /* find the end of the switch values chain */
3426 if (!(val = swStat->values.switchVals.swVals))
3427 swStat->values.switchVals.swVals = caseVal->opval.val;
3430 /* also order the cases according to value */
3432 int cVal = (int) floatFromVal (caseVal->opval.val);
3433 while (val && (int) floatFromVal (val) < cVal)
3439 /* if we reached the end then */
3442 pval->next = caseVal->opval.val;
3446 /* we found a value greater than */
3447 /* the current value we must add this */
3448 /* before the value */
3449 caseVal->opval.val->next = val;
3451 /* if this was the first in chain */
3452 if (swStat->values.switchVals.swVals == val)
3453 swStat->values.switchVals.swVals =
3456 pval->next = caseVal->opval.val;
3461 /* create the case label */
3462 sprintf (caseLbl, "_case_%d_%d",
3463 swStat->values.switchVals.swNum,
3464 (int) floatFromVal (caseVal->opval.val));
3466 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3471 /*-----------------------------------------------------------------*/
3472 /* createDefault - creates the parse tree for the default statement */
3473 /*-----------------------------------------------------------------*/
3475 createDefault (ast * swStat, ast * stmnt)
3477 char defLbl[SDCC_NAME_MAX + 1];
3479 /* if the switch statement does not exist */
3480 /* then case is out of context */
3483 werror (E_CASE_CONTEXT);
3487 /* turn on the default flag */
3488 swStat->values.switchVals.swDefault = 1;
3490 /* create the label */
3491 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3492 return createLabel (newSymbol (defLbl, 0), stmnt);
3495 /*-----------------------------------------------------------------*/
3496 /* createIf - creates the parsetree for the if statement */
3497 /*-----------------------------------------------------------------*/
3499 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3501 static int Lblnum = 0;
3503 symbol *ifTrue, *ifFalse, *ifEnd;
3505 /* if neither exists */
3506 if (!elseBody && !ifBody) {
3507 // if there are no side effects (i++, j() etc)
3508 if (!hasSEFcalls(condAst)) {
3513 /* create the labels */
3514 sprintf (buffer, "_iffalse_%d", Lblnum);
3515 ifFalse = newSymbol (buffer, NestLevel);
3516 /* if no else body then end == false */
3521 sprintf (buffer, "_ifend_%d", Lblnum);
3522 ifEnd = newSymbol (buffer, NestLevel);
3525 sprintf (buffer, "_iftrue_%d", Lblnum);
3526 ifTrue = newSymbol (buffer, NestLevel);
3530 /* attach the ifTrue label to the top of it body */
3531 ifBody = createLabel (ifTrue, ifBody);
3532 /* attach a goto end to the ifBody if else is present */
3535 ifBody = newNode (NULLOP, ifBody,
3537 newAst_VALUE (symbolVal (ifEnd)),
3539 /* put the elseLabel on the else body */
3540 elseBody = createLabel (ifFalse, elseBody);
3541 /* out the end at the end of the body */
3542 elseBody = newNode (NULLOP,
3544 createLabel (ifEnd, NULL));
3548 ifBody = newNode (NULLOP, ifBody,
3549 createLabel (ifFalse, NULL));
3551 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3552 if (IS_IFX (condAst))
3555 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3557 return newNode (NULLOP, ifTree,
3558 newNode (NULLOP, ifBody, elseBody));
3562 /*-----------------------------------------------------------------*/
3563 /* createDo - creates parse tree for do */
3566 /* _docontinue_n: */
3567 /* condition_expression +-> trueLabel -> _dobody_n */
3569 /* +-> falseLabel-> _dobreak_n */
3571 /*-----------------------------------------------------------------*/
3573 createDo (symbol * trueLabel, symbol * continueLabel,
3574 symbol * falseLabel, ast * condAst, ast * doBody)
3579 /* if the body does not exist then it is simple */
3582 condAst = backPatchLabels (condAst, continueLabel, NULL);
3583 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3584 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3585 doTree->trueLabel = continueLabel;
3586 doTree->falseLabel = NULL;
3590 /* otherwise we have a body */
3591 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3593 /* attach the body label to the top */
3594 doBody = createLabel (trueLabel, doBody);
3595 /* attach the continue label to end of body */
3596 doBody = newNode (NULLOP, doBody,
3597 createLabel (continueLabel, NULL));
3599 /* now put the break label at the end */
3600 if (IS_IFX (condAst))
3603 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3605 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3607 /* putting it together */
3608 return newNode (NULLOP, doBody, doTree);
3611 /*-----------------------------------------------------------------*/
3612 /* createFor - creates parse tree for 'for' statement */
3615 /* condExpr +-> trueLabel -> _forbody_n */
3617 /* +-> falseLabel-> _forbreak_n */
3620 /* _forcontinue_n: */
3622 /* goto _forcond_n ; */
3624 /*-----------------------------------------------------------------*/
3626 createFor (symbol * trueLabel, symbol * continueLabel,
3627 symbol * falseLabel, symbol * condLabel,
3628 ast * initExpr, ast * condExpr, ast * loopExpr,
3633 /* if loopexpression not present then we can generate it */
3634 /* the same way as a while */
3636 return newNode (NULLOP, initExpr,
3637 createWhile (trueLabel, continueLabel,
3638 falseLabel, condExpr, forBody));
3639 /* vanilla for statement */
3640 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3642 if (condExpr && !IS_IFX (condExpr))
3643 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3646 /* attach condition label to condition */
3647 condExpr = createLabel (condLabel, condExpr);
3649 /* attach body label to body */
3650 forBody = createLabel (trueLabel, forBody);
3652 /* attach continue to forLoop expression & attach */
3653 /* goto the forcond @ and of loopExpression */
3654 loopExpr = createLabel (continueLabel,
3658 newAst_VALUE (symbolVal (condLabel)),
3660 /* now start putting them together */
3661 forTree = newNode (NULLOP, initExpr, condExpr);
3662 forTree = newNode (NULLOP, forTree, forBody);
3663 forTree = newNode (NULLOP, forTree, loopExpr);
3664 /* finally add the break label */
3665 forTree = newNode (NULLOP, forTree,
3666 createLabel (falseLabel, NULL));
3670 /*-----------------------------------------------------------------*/
3671 /* createWhile - creates parse tree for while statement */
3672 /* the while statement will be created as follows */
3674 /* _while_continue_n: */
3675 /* condition_expression +-> trueLabel -> _while_boby_n */
3677 /* +-> falseLabel -> _while_break_n */
3678 /* _while_body_n: */
3680 /* goto _while_continue_n */
3681 /* _while_break_n: */
3682 /*-----------------------------------------------------------------*/
3684 createWhile (symbol * trueLabel, symbol * continueLabel,
3685 symbol * falseLabel, ast * condExpr, ast * whileBody)
3689 /* put the continue label */
3690 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3691 condExpr = createLabel (continueLabel, condExpr);
3692 condExpr->lineno = 0;
3694 /* put the body label in front of the body */
3695 whileBody = createLabel (trueLabel, whileBody);
3696 whileBody->lineno = 0;
3697 /* put a jump to continue at the end of the body */
3698 /* and put break label at the end of the body */
3699 whileBody = newNode (NULLOP,
3702 newAst_VALUE (symbolVal (continueLabel)),
3703 createLabel (falseLabel, NULL)));
3705 /* put it all together */
3706 if (IS_IFX (condExpr))
3707 whileTree = condExpr;
3710 whileTree = newNode (IFX, condExpr, NULL);
3711 /* put the true & false labels in place */
3712 whileTree->trueLabel = trueLabel;
3713 whileTree->falseLabel = falseLabel;
3716 return newNode (NULLOP, whileTree, whileBody);
3719 /*-----------------------------------------------------------------*/
3720 /* optimizeGetHbit - get highest order bit of the expression */
3721 /*-----------------------------------------------------------------*/
3723 optimizeGetHbit (ast * tree)
3726 /* if this is not a bit and */
3727 if (!IS_BITAND (tree))
3730 /* will look for tree of the form
3731 ( expr >> ((sizeof expr) -1) ) & 1 */
3732 if (!IS_AST_LIT_VALUE (tree->right))
3735 if (AST_LIT_VALUE (tree->right) != 1)
3738 if (!IS_RIGHT_OP (tree->left))
3741 if (!IS_AST_LIT_VALUE (tree->left->right))
3744 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3745 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3748 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3752 /*-----------------------------------------------------------------*/
3753 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3754 /*-----------------------------------------------------------------*/
3756 optimizeRRCRLC (ast * root)
3758 /* will look for trees of the form
3759 (?expr << 1) | (?expr >> 7) or
3760 (?expr >> 7) | (?expr << 1) will make that
3761 into a RLC : operation ..
3763 (?expr >> 1) | (?expr << 7) or
3764 (?expr << 7) | (?expr >> 1) will make that
3765 into a RRC operation
3766 note : by 7 I mean (number of bits required to hold the
3768 /* if the root operations is not a | operation the not */
3769 if (!IS_BITOR (root))
3772 /* I have to think of a better way to match patterns this sucks */
3773 /* that aside let start looking for the first case : I use a the
3774 negative check a lot to improve the efficiency */
3775 /* (?expr << 1) | (?expr >> 7) */
3776 if (IS_LEFT_OP (root->left) &&
3777 IS_RIGHT_OP (root->right))
3780 if (!SPEC_USIGN (TETYPE (root->left->left)))
3783 if (!IS_AST_LIT_VALUE (root->left->right) ||
3784 !IS_AST_LIT_VALUE (root->right->right))
3787 /* make sure it is the same expression */
3788 if (!isAstEqual (root->left->left,
3792 if (AST_LIT_VALUE (root->left->right) != 1)
3795 if (AST_LIT_VALUE (root->right->right) !=
3796 (getSize (TTYPE (root->left->left)) * 8 - 1))
3799 /* whew got the first case : create the AST */
3800 return newNode (RLC, root->left->left, NULL);
3804 /* check for second case */
3805 /* (?expr >> 7) | (?expr << 1) */
3806 if (IS_LEFT_OP (root->right) &&
3807 IS_RIGHT_OP (root->left))
3810 if (!SPEC_USIGN (TETYPE (root->left->left)))
3813 if (!IS_AST_LIT_VALUE (root->left->right) ||
3814 !IS_AST_LIT_VALUE (root->right->right))
3817 /* make sure it is the same symbol */
3818 if (!isAstEqual (root->left->left,
3822 if (AST_LIT_VALUE (root->right->right) != 1)
3825 if (AST_LIT_VALUE (root->left->right) !=
3826 (getSize (TTYPE (root->left->left)) * 8 - 1))
3829 /* whew got the first case : create the AST */
3830 return newNode (RLC, root->left->left, NULL);
3835 /* third case for RRC */
3836 /* (?symbol >> 1) | (?symbol << 7) */
3837 if (IS_LEFT_OP (root->right) &&
3838 IS_RIGHT_OP (root->left))
3841 if (!SPEC_USIGN (TETYPE (root->left->left)))
3844 if (!IS_AST_LIT_VALUE (root->left->right) ||
3845 !IS_AST_LIT_VALUE (root->right->right))
3848 /* make sure it is the same symbol */
3849 if (!isAstEqual (root->left->left,
3853 if (AST_LIT_VALUE (root->left->right) != 1)
3856 if (AST_LIT_VALUE (root->right->right) !=
3857 (getSize (TTYPE (root->left->left)) * 8 - 1))
3860 /* whew got the first case : create the AST */
3861 return newNode (RRC, root->left->left, NULL);
3865 /* fourth and last case for now */
3866 /* (?symbol << 7) | (?symbol >> 1) */
3867 if (IS_RIGHT_OP (root->right) &&
3868 IS_LEFT_OP (root->left))
3871 if (!SPEC_USIGN (TETYPE (root->left->left)))
3874 if (!IS_AST_LIT_VALUE (root->left->right) ||
3875 !IS_AST_LIT_VALUE (root->right->right))
3878 /* make sure it is the same symbol */
3879 if (!isAstEqual (root->left->left,
3883 if (AST_LIT_VALUE (root->right->right) != 1)
3886 if (AST_LIT_VALUE (root->left->right) !=
3887 (getSize (TTYPE (root->left->left)) * 8 - 1))
3890 /* whew got the first case : create the AST */
3891 return newNode (RRC, root->left->left, NULL);
3895 /* not found return root */
3899 /*-----------------------------------------------------------------*/
3900 /* optimizeCompare - otimizes compares for bit variables */
3901 /*-----------------------------------------------------------------*/
3903 optimizeCompare (ast * root)
3905 ast *optExpr = NULL;
3908 unsigned int litValue;
3910 /* if nothing then return nothing */
3914 /* if not a compare op then do leaves */
3915 if (!IS_COMPARE_OP (root))
3917 root->left = optimizeCompare (root->left);
3918 root->right = optimizeCompare (root->right);
3922 /* if left & right are the same then depending
3923 of the operation do */
3924 if (isAstEqual (root->left, root->right))
3926 switch (root->opval.op)
3931 optExpr = newAst_VALUE (constVal ("0"));
3936 optExpr = newAst_VALUE (constVal ("1"));
3940 return decorateType (optExpr);
3943 vleft = (root->left->type == EX_VALUE ?
3944 root->left->opval.val : NULL);
3946 vright = (root->right->type == EX_VALUE ?
3947 root->right->opval.val : NULL);
3949 /* if left is a BITVAR in BITSPACE */
3950 /* and right is a LITERAL then opt- */
3951 /* imize else do nothing */
3952 if (vleft && vright &&
3953 IS_BITVAR (vleft->etype) &&
3954 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3955 IS_LITERAL (vright->etype))
3958 /* if right side > 1 then comparison may never succeed */
3959 if ((litValue = (int) floatFromVal (vright)) > 1)
3961 werror (W_BAD_COMPARE);
3967 switch (root->opval.op)
3969 case '>': /* bit value greater than 1 cannot be */
3970 werror (W_BAD_COMPARE);
3974 case '<': /* bit value < 1 means 0 */
3976 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3979 case LE_OP: /* bit value <= 1 means no check */
3980 optExpr = newAst_VALUE (vright);
3983 case GE_OP: /* bit value >= 1 means only check for = */
3985 optExpr = newAst_VALUE (vleft);
3990 { /* literal is zero */
3991 switch (root->opval.op)
3993 case '<': /* bit value < 0 cannot be */
3994 werror (W_BAD_COMPARE);
3998 case '>': /* bit value > 0 means 1 */
4000 optExpr = newAst_VALUE (vleft);
4003 case LE_OP: /* bit value <= 0 means no check */
4004 case GE_OP: /* bit value >= 0 means no check */
4005 werror (W_BAD_COMPARE);
4009 case EQ_OP: /* bit == 0 means ! of bit */
4010 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4014 return decorateType (resolveSymbols (optExpr));
4015 } /* end-of-if of BITVAR */
4020 /*-----------------------------------------------------------------*/
4021 /* addSymToBlock : adds the symbol to the first block we find */
4022 /*-----------------------------------------------------------------*/
4024 addSymToBlock (symbol * sym, ast * tree)
4026 /* reached end of tree or a leaf */
4027 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4031 if (IS_AST_OP (tree) &&
4032 tree->opval.op == BLOCK)
4035 symbol *lsym = copySymbol (sym);
4037 lsym->next = AST_VALUES (tree, sym);
4038 AST_VALUES (tree, sym) = lsym;
4042 addSymToBlock (sym, tree->left);
4043 addSymToBlock (sym, tree->right);
4046 /*-----------------------------------------------------------------*/
4047 /* processRegParms - do processing for register parameters */
4048 /*-----------------------------------------------------------------*/
4050 processRegParms (value * args, ast * body)
4054 if (IS_REGPARM (args->etype))
4055 addSymToBlock (args->sym, body);
4060 /*-----------------------------------------------------------------*/
4061 /* resetParmKey - resets the operandkeys for the symbols */
4062 /*-----------------------------------------------------------------*/
4063 DEFSETFUNC (resetParmKey)
4074 /*-----------------------------------------------------------------*/
4075 /* createFunction - This is the key node that calls the iCode for */
4076 /* generating the code for a function. Note code */
4077 /* is generated function by function, later when */
4078 /* add inter-procedural analysis this will change */
4079 /*-----------------------------------------------------------------*/
4081 createFunction (symbol * name, ast * body)
4087 iCode *piCode = NULL;
4089 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4090 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4092 /* if check function return 0 then some problem */
4093 if (checkFunction (name, NULL) == 0)
4096 /* create a dummy block if none exists */
4098 body = newNode (BLOCK, NULL, NULL);
4102 /* check if the function name already in the symbol table */
4103 if ((csym = findSym (SymbolTab, NULL, name->name)))
4106 /* special case for compiler defined functions
4107 we need to add the name to the publics list : this
4108 actually means we are now compiling the compiler
4112 addSet (&publics, name);
4118 allocVariables (name);
4120 name->lastLine = yylineno;
4123 #if 0 // jwk: this is now done in addDecl()
4124 processFuncArgs (currFunc);
4127 /* set the stack pointer */
4128 /* PENDING: check this for the mcs51 */
4129 stackPtr = -port->stack.direction * port->stack.call_overhead;
4130 if (IFFUNC_ISISR (name->type))
4131 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4132 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4133 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4135 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4137 fetype = getSpec (name->type); /* get the specifier for the function */
4138 /* if this is a reentrant function then */
4139 if (IFFUNC_ISREENT (name->type))
4142 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4144 /* do processing for parameters that are passed in registers */
4145 processRegParms (FUNC_ARGS(name->type), body);
4147 /* set the stack pointer */
4151 /* allocate & autoinit the block variables */
4152 processBlockVars (body, &stack, ALLOCATE);
4154 /* save the stack information */
4155 if (options.useXstack)
4156 name->xstack = SPEC_STAK (fetype) = stack;
4158 name->stack = SPEC_STAK (fetype) = stack;
4160 /* name needs to be mangled */
4161 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4163 body = resolveSymbols (body); /* resolve the symbols */
4164 body = decorateType (body); /* propagateType & do semantic checks */
4166 ex = newAst_VALUE (symbolVal (name)); /* create name */
4167 ex = newNode (FUNCTION, ex, body);
4168 ex->values.args = FUNC_ARGS(name->type);
4170 if (options.dump_tree) PA(ex);
4173 werror (E_FUNC_NO_CODE, name->name);
4177 /* create the node & generate intermediate code */
4179 codeOutFile = code->oFile;
4180 piCode = iCodeFromAst (ex);
4184 werror (E_FUNC_NO_CODE, name->name);
4188 eBBlockFromiCode (piCode);
4190 /* if there are any statics then do them */
4193 GcurMemmap = statsg;
4194 codeOutFile = statsg->oFile;
4195 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4201 /* dealloc the block variables */
4202 processBlockVars (body, &stack, DEALLOCATE);
4203 /* deallocate paramaters */
4204 deallocParms (FUNC_ARGS(name->type));
4206 if (IFFUNC_ISREENT (name->type))
4209 /* we are done freeup memory & cleanup */
4213 FUNC_HASBODY(name->type) = 1;
4214 addSet (&operKeyReset, name);
4215 applyToSet (operKeyReset, resetParmKey);
4218 cdbStructBlock (1, cdbFile);
4220 cleanUpLevel (LabelTab, 0);
4221 cleanUpBlock (StructTab, 1);
4222 cleanUpBlock (TypedefTab, 1);
4224 xstack->syms = NULL;
4225 istack->syms = NULL;
4230 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4231 /*-----------------------------------------------------------------*/
4232 /* ast_print : prints the ast (for debugging purposes) */
4233 /*-----------------------------------------------------------------*/
4235 void ast_print (ast * tree, FILE *outfile, int indent)
4240 /* can print only decorated trees */
4241 if (!tree->decorated) return;
4243 /* if any child is an error | this one is an error do nothing */
4244 if (tree->isError ||
4245 (tree->left && tree->left->isError) ||
4246 (tree->right && tree->right->isError)) {
4247 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4251 /* print the line */
4252 /* if not block & function */
4253 if (tree->type == EX_OP &&
4254 (tree->opval.op != FUNCTION &&
4255 tree->opval.op != BLOCK &&
4256 tree->opval.op != NULLOP)) {
4259 if (tree->opval.op == FUNCTION) {
4261 value *args=FUNC_ARGS(tree->left->opval.val->type);
4262 fprintf(outfile,"FUNCTION (%s=%p) type (",
4263 tree->left->opval.val->name, tree);
4264 printTypeChain (tree->ftype,outfile);
4265 fprintf(outfile,") args (");
4268 fprintf (outfile, ", ");
4270 printTypeChain (args ? args->type : NULL, outfile);
4272 args= args ? args->next : NULL;
4274 fprintf(outfile,")\n");
4275 ast_print(tree->left,outfile,indent);
4276 ast_print(tree->right,outfile,indent);
4279 if (tree->opval.op == BLOCK) {
4280 symbol *decls = tree->values.sym;
4281 INDENT(indent,outfile);
4282 fprintf(outfile,"{\n");
4284 INDENT(indent+4,outfile);
4285 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4286 decls->name, decls);
4287 printTypeChain(decls->type,outfile);
4288 fprintf(outfile,")\n");
4290 decls = decls->next;
4292 ast_print(tree->right,outfile,indent+4);
4293 INDENT(indent,outfile);
4294 fprintf(outfile,"}\n");
4297 if (tree->opval.op == NULLOP) {
4298 fprintf(outfile,"\n");
4299 ast_print(tree->left,outfile,indent);
4300 fprintf(outfile,"\n");
4301 ast_print(tree->right,outfile,indent);
4304 INDENT(indent,outfile);
4306 /*------------------------------------------------------------------*/
4307 /*----------------------------*/
4308 /* leaf has been reached */
4309 /*----------------------------*/
4310 /* if this is of type value */
4311 /* just get the type */
4312 if (tree->type == EX_VALUE) {
4314 if (IS_LITERAL (tree->opval.val->etype)) {
4315 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4316 (int) floatFromVal(tree->opval.val),
4317 (int) floatFromVal(tree->opval.val),
4318 floatFromVal(tree->opval.val));
4319 } else if (tree->opval.val->sym) {
4320 /* if the undefined flag is set then give error message */
4321 if (tree->opval.val->sym->undefined) {
4322 fprintf(outfile,"UNDEFINED SYMBOL ");
4324 fprintf(outfile,"SYMBOL ");
4326 fprintf(outfile,"(%s=%p)",
4327 tree->opval.val->sym->name,tree);
4330 fprintf(outfile," type (");
4331 printTypeChain(tree->ftype,outfile);
4332 fprintf(outfile,")\n");
4334 fprintf(outfile,"\n");
4339 /* if type link for the case of cast */
4340 if (tree->type == EX_LINK) {
4341 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4342 printTypeChain(tree->opval.lnk,outfile);
4343 fprintf(outfile,")\n");
4348 /* depending on type of operator do */
4350 switch (tree->opval.op) {
4351 /*------------------------------------------------------------------*/
4352 /*----------------------------*/
4354 /*----------------------------*/
4356 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4357 printTypeChain(tree->ftype,outfile);
4358 fprintf(outfile,")\n");
4359 ast_print(tree->left,outfile,indent+4);
4360 ast_print(tree->right,outfile,indent+4);
4363 /*------------------------------------------------------------------*/
4364 /*----------------------------*/
4366 /*----------------------------*/
4368 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4369 printTypeChain(tree->ftype,outfile);
4370 fprintf(outfile,")\n");
4371 ast_print(tree->left,outfile,indent+4);
4372 ast_print(tree->right,outfile,indent+4);
4375 /*------------------------------------------------------------------*/
4376 /*----------------------------*/
4377 /* struct/union pointer */
4378 /*----------------------------*/
4380 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4381 printTypeChain(tree->ftype,outfile);
4382 fprintf(outfile,")\n");
4383 ast_print(tree->left,outfile,indent+4);
4384 ast_print(tree->right,outfile,indent+4);
4387 /*------------------------------------------------------------------*/
4388 /*----------------------------*/
4389 /* ++/-- operation */
4390 /*----------------------------*/
4391 case INC_OP: /* incerement operator unary so left only */
4392 fprintf(outfile,"INC_OP (%p) type (",tree);
4393 printTypeChain(tree->ftype,outfile);
4394 fprintf(outfile,")\n");
4395 ast_print(tree->left,outfile,indent+4);
4399 fprintf(outfile,"DEC_OP (%p) type (",tree);
4400 printTypeChain(tree->ftype,outfile);
4401 fprintf(outfile,")\n");
4402 ast_print(tree->left,outfile,indent+4);
4405 /*------------------------------------------------------------------*/
4406 /*----------------------------*/
4408 /*----------------------------*/
4411 fprintf(outfile,"& (%p) type (",tree);
4412 printTypeChain(tree->ftype,outfile);
4413 fprintf(outfile,")\n");
4414 ast_print(tree->left,outfile,indent+4);
4415 ast_print(tree->right,outfile,indent+4);
4417 fprintf(outfile,"ADDRESS_OF (%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);
4424 /*----------------------------*/
4426 /*----------------------------*/
4428 fprintf(outfile,"OR (%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);
4434 /*------------------------------------------------------------------*/
4435 /*----------------------------*/
4437 /*----------------------------*/
4439 fprintf(outfile,"XOR (%p) type (",tree);
4440 printTypeChain(tree->ftype,outfile);
4441 fprintf(outfile,")\n");
4442 ast_print(tree->left,outfile,indent+4);
4443 ast_print(tree->right,outfile,indent+4);
4446 /*------------------------------------------------------------------*/
4447 /*----------------------------*/
4449 /*----------------------------*/
4451 fprintf(outfile,"DIV (%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);
4457 /*------------------------------------------------------------------*/
4458 /*----------------------------*/
4460 /*----------------------------*/
4462 fprintf(outfile,"MOD (%p) type (",tree);
4463 printTypeChain(tree->ftype,outfile);
4464 fprintf(outfile,")\n");
4465 ast_print(tree->left,outfile,indent+4);
4466 ast_print(tree->right,outfile,indent+4);
4469 /*------------------------------------------------------------------*/
4470 /*----------------------------*/
4471 /* address dereference */
4472 /*----------------------------*/
4473 case '*': /* can be unary : if right is null then unary operation */
4475 fprintf(outfile,"DEREF (%p) type (",tree);
4476 printTypeChain(tree->ftype,outfile);
4477 fprintf(outfile,")\n");
4478 ast_print(tree->left,outfile,indent+4);
4481 /*------------------------------------------------------------------*/
4482 /*----------------------------*/
4483 /* multiplication */
4484 /*----------------------------*/
4485 fprintf(outfile,"MULT (%p) type (",tree);
4486 printTypeChain(tree->ftype,outfile);
4487 fprintf(outfile,")\n");
4488 ast_print(tree->left,outfile,indent+4);
4489 ast_print(tree->right,outfile,indent+4);
4493 /*------------------------------------------------------------------*/
4494 /*----------------------------*/
4495 /* unary '+' operator */
4496 /*----------------------------*/
4500 fprintf(outfile,"UPLUS (%p) type (",tree);
4501 printTypeChain(tree->ftype,outfile);
4502 fprintf(outfile,")\n");
4503 ast_print(tree->left,outfile,indent+4);
4505 /*------------------------------------------------------------------*/
4506 /*----------------------------*/
4508 /*----------------------------*/
4509 fprintf(outfile,"ADD (%p) type (",tree);
4510 printTypeChain(tree->ftype,outfile);
4511 fprintf(outfile,")\n");
4512 ast_print(tree->left,outfile,indent+4);
4513 ast_print(tree->right,outfile,indent+4);
4516 /*------------------------------------------------------------------*/
4517 /*----------------------------*/
4519 /*----------------------------*/
4520 case '-': /* can be unary */
4522 fprintf(outfile,"UMINUS (%p) type (",tree);
4523 printTypeChain(tree->ftype,outfile);
4524 fprintf(outfile,")\n");
4525 ast_print(tree->left,outfile,indent+4);
4527 /*------------------------------------------------------------------*/
4528 /*----------------------------*/
4530 /*----------------------------*/
4531 fprintf(outfile,"SUB (%p) type (",tree);
4532 printTypeChain(tree->ftype,outfile);
4533 fprintf(outfile,")\n");
4534 ast_print(tree->left,outfile,indent+4);
4535 ast_print(tree->right,outfile,indent+4);
4538 /*------------------------------------------------------------------*/
4539 /*----------------------------*/
4541 /*----------------------------*/
4543 fprintf(outfile,"COMPL (%p) type (",tree);
4544 printTypeChain(tree->ftype,outfile);
4545 fprintf(outfile,")\n");
4546 ast_print(tree->left,outfile,indent+4);
4548 /*------------------------------------------------------------------*/
4549 /*----------------------------*/
4551 /*----------------------------*/
4553 fprintf(outfile,"NOT (%p) type (",tree);
4554 printTypeChain(tree->ftype,outfile);
4555 fprintf(outfile,")\n");
4556 ast_print(tree->left,outfile,indent+4);
4558 /*------------------------------------------------------------------*/
4559 /*----------------------------*/
4561 /*----------------------------*/
4563 fprintf(outfile,"RRC (%p) type (",tree);
4564 printTypeChain(tree->ftype,outfile);
4565 fprintf(outfile,")\n");
4566 ast_print(tree->left,outfile,indent+4);
4570 fprintf(outfile,"RLC (%p) type (",tree);
4571 printTypeChain(tree->ftype,outfile);
4572 fprintf(outfile,")\n");
4573 ast_print(tree->left,outfile,indent+4);
4576 fprintf(outfile,"GETHBIT (%p) type (",tree);
4577 printTypeChain(tree->ftype,outfile);
4578 fprintf(outfile,")\n");
4579 ast_print(tree->left,outfile,indent+4);
4582 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4583 printTypeChain(tree->ftype,outfile);
4584 fprintf(outfile,")\n");
4585 ast_print(tree->left,outfile,indent+4);
4586 ast_print(tree->right,outfile,indent+4);
4589 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4590 printTypeChain(tree->ftype,outfile);
4591 fprintf(outfile,")\n");
4592 ast_print(tree->left,outfile,indent+4);
4593 ast_print(tree->right,outfile,indent+4);
4595 /*------------------------------------------------------------------*/
4596 /*----------------------------*/
4598 /*----------------------------*/
4599 case CAST: /* change the type */
4600 fprintf(outfile,"CAST (%p) from type (",tree);
4601 printTypeChain(tree->right->ftype,outfile);
4602 fprintf(outfile,") to type (");
4603 printTypeChain(tree->ftype,outfile);
4604 fprintf(outfile,")\n");
4605 ast_print(tree->right,outfile,indent+4);
4609 fprintf(outfile,"ANDAND (%p) type (",tree);
4610 printTypeChain(tree->ftype,outfile);
4611 fprintf(outfile,")\n");
4612 ast_print(tree->left,outfile,indent+4);
4613 ast_print(tree->right,outfile,indent+4);
4616 fprintf(outfile,"OROR (%p) type (",tree);
4617 printTypeChain(tree->ftype,outfile);
4618 fprintf(outfile,")\n");
4619 ast_print(tree->left,outfile,indent+4);
4620 ast_print(tree->right,outfile,indent+4);
4623 /*------------------------------------------------------------------*/
4624 /*----------------------------*/
4625 /* comparison operators */
4626 /*----------------------------*/
4628 fprintf(outfile,"GT(>) (%p) type (",tree);
4629 printTypeChain(tree->ftype,outfile);
4630 fprintf(outfile,")\n");
4631 ast_print(tree->left,outfile,indent+4);
4632 ast_print(tree->right,outfile,indent+4);
4635 fprintf(outfile,"LT(<) (%p) type (",tree);
4636 printTypeChain(tree->ftype,outfile);
4637 fprintf(outfile,")\n");
4638 ast_print(tree->left,outfile,indent+4);
4639 ast_print(tree->right,outfile,indent+4);
4642 fprintf(outfile,"LE(<=) (%p) type (",tree);
4643 printTypeChain(tree->ftype,outfile);
4644 fprintf(outfile,")\n");
4645 ast_print(tree->left,outfile,indent+4);
4646 ast_print(tree->right,outfile,indent+4);
4649 fprintf(outfile,"GE(>=) (%p) type (",tree);
4650 printTypeChain(tree->ftype,outfile);
4651 fprintf(outfile,")\n");
4652 ast_print(tree->left,outfile,indent+4);
4653 ast_print(tree->right,outfile,indent+4);
4656 fprintf(outfile,"EQ(==) (%p) type (",tree);
4657 printTypeChain(tree->ftype,outfile);
4658 fprintf(outfile,")\n");
4659 ast_print(tree->left,outfile,indent+4);
4660 ast_print(tree->right,outfile,indent+4);
4663 fprintf(outfile,"NE(!=) (%p) type (",tree);
4664 printTypeChain(tree->ftype,outfile);
4665 fprintf(outfile,")\n");
4666 ast_print(tree->left,outfile,indent+4);
4667 ast_print(tree->right,outfile,indent+4);
4668 /*------------------------------------------------------------------*/
4669 /*----------------------------*/
4671 /*----------------------------*/
4672 case SIZEOF: /* evaluate wihout code generation */
4673 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4676 /*------------------------------------------------------------------*/
4677 /*----------------------------*/
4678 /* conditional operator '?' */
4679 /*----------------------------*/
4681 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4682 printTypeChain(tree->ftype,outfile);
4683 fprintf(outfile,")\n");
4684 ast_print(tree->left,outfile,indent+4);
4685 ast_print(tree->right,outfile,indent+4);
4689 fprintf(outfile,"COLON(:) (%p) type (",tree);
4690 printTypeChain(tree->ftype,outfile);
4691 fprintf(outfile,")\n");
4692 ast_print(tree->left,outfile,indent+4);
4693 ast_print(tree->right,outfile,indent+4);
4696 /*------------------------------------------------------------------*/
4697 /*----------------------------*/
4698 /* assignment operators */
4699 /*----------------------------*/
4701 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4702 printTypeChain(tree->ftype,outfile);
4703 fprintf(outfile,")\n");
4704 ast_print(tree->left,outfile,indent+4);
4705 ast_print(tree->right,outfile,indent+4);
4708 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4709 printTypeChain(tree->ftype,outfile);
4710 fprintf(outfile,")\n");
4711 ast_print(tree->left,outfile,indent+4);
4712 ast_print(tree->right,outfile,indent+4);
4715 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4716 printTypeChain(tree->ftype,outfile);
4717 fprintf(outfile,")\n");
4718 ast_print(tree->left,outfile,indent+4);
4719 ast_print(tree->right,outfile,indent+4);
4722 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4723 printTypeChain(tree->ftype,outfile);
4724 fprintf(outfile,")\n");
4725 ast_print(tree->left,outfile,indent+4);
4726 ast_print(tree->right,outfile,indent+4);
4729 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4730 printTypeChain(tree->ftype,outfile);
4731 fprintf(outfile,")\n");
4732 ast_print(tree->left,outfile,indent+4);
4733 ast_print(tree->right,outfile,indent+4);
4736 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4737 printTypeChain(tree->ftype,outfile);
4738 fprintf(outfile,")\n");
4739 ast_print(tree->left,outfile,indent+4);
4740 ast_print(tree->right,outfile,indent+4);
4743 fprintf(outfile,"LSHFTASS(*=) (%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,"SUBASS(-=) (%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 /*----------------------------*/
4763 /*----------------------------*/
4765 fprintf(outfile,"ADDASS(+=) (%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 /* straight assignemnt */
4774 /*----------------------------*/
4776 fprintf(outfile,"ASSIGN(=) (%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 /*----------------------------*/
4784 /* comma operator */
4785 /*----------------------------*/
4787 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4788 printTypeChain(tree->ftype,outfile);
4789 fprintf(outfile,")\n");
4790 ast_print(tree->left,outfile,indent+4);
4791 ast_print(tree->right,outfile,indent+4);
4793 /*------------------------------------------------------------------*/
4794 /*----------------------------*/
4796 /*----------------------------*/
4799 fprintf(outfile,"CALL (%p) type (",tree);
4800 printTypeChain(tree->ftype,outfile);
4801 fprintf(outfile,")\n");
4802 ast_print(tree->left,outfile,indent+4);
4803 ast_print(tree->right,outfile,indent+4);
4806 fprintf(outfile,"PARMS\n");
4807 ast_print(tree->left,outfile,indent+4);
4808 if (tree->right && !IS_AST_PARAM(tree->right)) {
4809 ast_print(tree->right,outfile,indent+4);
4812 /*------------------------------------------------------------------*/
4813 /*----------------------------*/
4814 /* return statement */
4815 /*----------------------------*/
4817 fprintf(outfile,"RETURN (%p) type (",tree);
4818 printTypeChain(tree->right->ftype,outfile);
4819 fprintf(outfile,")\n");
4820 ast_print(tree->right,outfile,indent+4);
4822 /*------------------------------------------------------------------*/
4823 /*----------------------------*/
4824 /* label statement */
4825 /*----------------------------*/
4827 fprintf(outfile,"LABEL (%p)",tree);
4828 ast_print(tree->left,outfile,indent+4);
4829 ast_print(tree->right,outfile,indent);
4831 /*------------------------------------------------------------------*/
4832 /*----------------------------*/
4833 /* switch statement */
4834 /*----------------------------*/
4838 fprintf(outfile,"SWITCH (%p) ",tree);
4839 ast_print(tree->left,outfile,0);
4840 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4841 INDENT(indent+4,outfile);
4842 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4843 (int) floatFromVal(val),
4844 tree->values.switchVals.swNum,
4845 (int) floatFromVal(val));
4847 ast_print(tree->right,outfile,indent);
4850 /*------------------------------------------------------------------*/
4851 /*----------------------------*/
4853 /*----------------------------*/
4855 fprintf(outfile,"IF (%p) \n",tree);
4856 ast_print(tree->left,outfile,indent+4);
4857 if (tree->trueLabel) {
4858 INDENT(indent,outfile);
4859 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4861 if (tree->falseLabel) {
4862 INDENT(indent,outfile);
4863 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4865 ast_print(tree->right,outfile,indent+4);
4867 /*------------------------------------------------------------------*/
4868 /*----------------------------*/
4870 /*----------------------------*/
4872 fprintf(outfile,"FOR (%p) \n",tree);
4873 if (AST_FOR( tree, initExpr)) {
4874 INDENT(indent+4,outfile);
4875 fprintf(outfile,"INIT EXPR ");
4876 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4878 if (AST_FOR( tree, condExpr)) {
4879 INDENT(indent+4,outfile);
4880 fprintf(outfile,"COND EXPR ");
4881 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4883 if (AST_FOR( tree, loopExpr)) {
4884 INDENT(indent+4,outfile);
4885 fprintf(outfile,"LOOP EXPR ");
4886 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4888 fprintf(outfile,"FOR LOOP BODY \n");
4889 ast_print(tree->left,outfile,indent+4);
4898 ast_print(t,stdout,0);