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;
2154 DCL_TYPE (p) = POINTER;
2156 if (IS_AST_SYM_VALUE (tree->left))
2158 AST_SYMBOL (tree->left)->addrtaken = 1;
2159 AST_SYMBOL (tree->left)->allocreq = 1;
2162 p->next = LTYPE (tree);
2164 TETYPE (tree) = getSpec (TTYPE (tree));
2165 DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2166 DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2171 /*------------------------------------------------------------------*/
2172 /*----------------------------*/
2174 /*----------------------------*/
2176 /* if the rewrite succeeds then don't go any furthur */
2178 ast *wtree = optimizeRRCRLC (tree);
2180 return decorateType (wtree);
2182 /*------------------------------------------------------------------*/
2183 /*----------------------------*/
2185 /*----------------------------*/
2187 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2189 werror (E_BITWISE_OP);
2190 werror (W_CONTINUE, "left & right types are ");
2191 printTypeChain (LTYPE (tree), stderr);
2192 fprintf (stderr, ",");
2193 printTypeChain (RTYPE (tree), stderr);
2194 fprintf (stderr, "\n");
2195 goto errorTreeReturn;
2198 /* if they are both literal then */
2199 /* rewrite the tree */
2200 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2202 tree->type = EX_VALUE;
2203 tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2204 valFromType (RETYPE (tree)),
2206 tree->right = tree->left = NULL;
2207 TETYPE (tree) = tree->opval.val->etype;
2208 TTYPE (tree) = tree->opval.val->type;
2211 LRVAL (tree) = RRVAL (tree) = 1;
2212 TETYPE (tree) = getSpec (TTYPE (tree) =
2213 computeType (LTYPE (tree),
2216 /*------------------------------------------------------------------*/
2217 /*----------------------------*/
2219 /*----------------------------*/
2221 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2223 werror (E_INVALID_OP, "divide");
2224 goto errorTreeReturn;
2226 /* if they are both literal then */
2227 /* rewrite the tree */
2228 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2230 tree->type = EX_VALUE;
2231 tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2232 valFromType (RETYPE (tree)));
2233 tree->right = tree->left = NULL;
2234 TETYPE (tree) = getSpec (TTYPE (tree) =
2235 tree->opval.val->type);
2238 LRVAL (tree) = RRVAL (tree) = 1;
2239 TETYPE (tree) = getSpec (TTYPE (tree) =
2240 computeType (LTYPE (tree),
2244 /*------------------------------------------------------------------*/
2245 /*----------------------------*/
2247 /*----------------------------*/
2249 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2251 werror (E_BITWISE_OP);
2252 werror (W_CONTINUE, "left & right types are ");
2253 printTypeChain (LTYPE (tree), stderr);
2254 fprintf (stderr, ",");
2255 printTypeChain (RTYPE (tree), stderr);
2256 fprintf (stderr, "\n");
2257 goto errorTreeReturn;
2259 /* if they are both literal then */
2260 /* rewrite the tree */
2261 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2263 tree->type = EX_VALUE;
2264 tree->opval.val = valMod (valFromType (LETYPE (tree)),
2265 valFromType (RETYPE (tree)));
2266 tree->right = tree->left = NULL;
2267 TETYPE (tree) = getSpec (TTYPE (tree) =
2268 tree->opval.val->type);
2271 LRVAL (tree) = RRVAL (tree) = 1;
2272 TETYPE (tree) = getSpec (TTYPE (tree) =
2273 computeType (LTYPE (tree),
2277 /*------------------------------------------------------------------*/
2278 /*----------------------------*/
2279 /* address dereference */
2280 /*----------------------------*/
2281 case '*': /* can be unary : if right is null then unary operation */
2284 if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2286 werror (E_PTR_REQD);
2287 goto errorTreeReturn;
2292 werror (E_LVALUE_REQUIRED, "pointer deref");
2293 goto errorTreeReturn;
2295 TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2296 LTYPE (tree)->next : NULL);
2297 TETYPE (tree) = getSpec (TTYPE (tree));
2298 SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2302 /*------------------------------------------------------------------*/
2303 /*----------------------------*/
2304 /* multiplication */
2305 /*----------------------------*/
2306 if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2308 werror (E_INVALID_OP, "multiplication");
2309 goto errorTreeReturn;
2312 /* if they are both literal then */
2313 /* rewrite the tree */
2314 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2316 tree->type = EX_VALUE;
2317 tree->opval.val = valMult (valFromType (LETYPE (tree)),
2318 valFromType (RETYPE (tree)));
2319 tree->right = tree->left = NULL;
2320 TETYPE (tree) = getSpec (TTYPE (tree) =
2321 tree->opval.val->type);
2325 /* if left is a literal exchange left & right */
2326 if (IS_LITERAL (LTYPE (tree)))
2328 ast *tTree = tree->left;
2329 tree->left = tree->right;
2330 tree->right = tTree;
2333 LRVAL (tree) = RRVAL (tree) = 1;
2334 /* promote result to int if left & right are char
2335 this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2336 if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2337 TETYPE (tree) = getSpec (TTYPE (tree) =
2338 computeType (LTYPE (tree),
2340 SPEC_NOUN(TETYPE(tree)) = V_INT;
2342 TETYPE (tree) = getSpec (TTYPE (tree) =
2343 computeType (LTYPE (tree),
2348 /*------------------------------------------------------------------*/
2349 /*----------------------------*/
2350 /* unary '+' operator */
2351 /*----------------------------*/
2356 if (!IS_INTEGRAL (LTYPE (tree)))
2358 werror (E_UNARY_OP, '+');
2359 goto errorTreeReturn;
2362 /* if left is a literal then do it */
2363 if (IS_LITERAL (LTYPE (tree)))
2365 tree->type = EX_VALUE;
2366 tree->opval.val = valFromType (LETYPE (tree));
2368 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2372 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2376 /*------------------------------------------------------------------*/
2377 /*----------------------------*/
2379 /*----------------------------*/
2381 /* this is not a unary operation */
2382 /* if both pointers then problem */
2383 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2384 (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2386 werror (E_PTR_PLUS_PTR);
2387 goto errorTreeReturn;
2390 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2391 !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2393 werror (E_PLUS_INVALID, "+");
2394 goto errorTreeReturn;
2397 if (!IS_ARITHMETIC (RTYPE (tree)) &&
2398 !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2400 werror (E_PLUS_INVALID, "+");
2401 goto errorTreeReturn;
2403 /* if they are both literal then */
2404 /* rewrite the tree */
2405 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2407 tree->type = EX_VALUE;
2408 tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2409 valFromType (RETYPE (tree)));
2410 tree->right = tree->left = NULL;
2411 TETYPE (tree) = getSpec (TTYPE (tree) =
2412 tree->opval.val->type);
2416 /* if the right is a pointer or left is a literal
2417 xchange left & right */
2418 if (IS_ARRAY (RTYPE (tree)) ||
2419 IS_PTR (RTYPE (tree)) ||
2420 IS_LITERAL (LTYPE (tree)))
2422 ast *tTree = tree->left;
2423 tree->left = tree->right;
2424 tree->right = tTree;
2427 LRVAL (tree) = RRVAL (tree) = 1;
2428 /* if the left is a pointer */
2429 if (IS_PTR (LTYPE (tree)))
2430 TETYPE (tree) = getSpec (TTYPE (tree) =
2433 TETYPE (tree) = getSpec (TTYPE (tree) =
2434 computeType (LTYPE (tree),
2438 /*------------------------------------------------------------------*/
2439 /*----------------------------*/
2441 /*----------------------------*/
2442 case '-': /* can be unary */
2443 /* if right is null then unary */
2447 if (!IS_ARITHMETIC (LTYPE (tree)))
2449 werror (E_UNARY_OP, tree->opval.op);
2450 goto errorTreeReturn;
2453 /* if left is a literal then do it */
2454 if (IS_LITERAL (LTYPE (tree)))
2456 tree->type = EX_VALUE;
2457 tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2459 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2460 SPEC_USIGN(TETYPE(tree)) = 0;
2464 TTYPE (tree) = LTYPE (tree);
2468 /*------------------------------------------------------------------*/
2469 /*----------------------------*/
2471 /*----------------------------*/
2473 if (!(IS_PTR (LTYPE (tree)) ||
2474 IS_ARRAY (LTYPE (tree)) ||
2475 IS_ARITHMETIC (LTYPE (tree))))
2477 werror (E_PLUS_INVALID, "-");
2478 goto errorTreeReturn;
2481 if (!(IS_PTR (RTYPE (tree)) ||
2482 IS_ARRAY (RTYPE (tree)) ||
2483 IS_ARITHMETIC (RTYPE (tree))))
2485 werror (E_PLUS_INVALID, "-");
2486 goto errorTreeReturn;
2489 if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2490 !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2491 IS_INTEGRAL (RTYPE (tree))))
2493 werror (E_PLUS_INVALID, "-");
2494 goto errorTreeReturn;
2497 /* if they are both literal then */
2498 /* rewrite the tree */
2499 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2501 tree->type = EX_VALUE;
2502 tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2503 valFromType (RETYPE (tree)));
2504 tree->right = tree->left = NULL;
2505 TETYPE (tree) = getSpec (TTYPE (tree) =
2506 tree->opval.val->type);
2510 /* if the left & right are equal then zero */
2511 if (isAstEqual (tree->left, tree->right))
2513 tree->type = EX_VALUE;
2514 tree->left = tree->right = NULL;
2515 tree->opval.val = constVal ("0");
2516 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2520 /* if both of them are pointers or arrays then */
2521 /* the result is going to be an integer */
2522 if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2523 (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2524 TETYPE (tree) = TTYPE (tree) = newIntLink ();
2526 /* if only the left is a pointer */
2527 /* then result is a pointer */
2528 if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2529 TETYPE (tree) = getSpec (TTYPE (tree) =
2532 TETYPE (tree) = getSpec (TTYPE (tree) =
2533 computeType (LTYPE (tree),
2535 LRVAL (tree) = RRVAL (tree) = 1;
2538 /*------------------------------------------------------------------*/
2539 /*----------------------------*/
2541 /*----------------------------*/
2543 /* can be only integral type */
2544 if (!IS_INTEGRAL (LTYPE (tree)))
2546 werror (E_UNARY_OP, tree->opval.op);
2547 goto errorTreeReturn;
2550 /* if left is a literal then do it */
2551 if (IS_LITERAL (LTYPE (tree)))
2553 tree->type = EX_VALUE;
2554 tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2556 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2560 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2563 /*------------------------------------------------------------------*/
2564 /*----------------------------*/
2566 /*----------------------------*/
2568 /* can be pointer */
2569 if (!IS_ARITHMETIC (LTYPE (tree)) &&
2570 !IS_PTR (LTYPE (tree)) &&
2571 !IS_ARRAY (LTYPE (tree)))
2573 werror (E_UNARY_OP, tree->opval.op);
2574 goto errorTreeReturn;
2577 /* if left is a literal then do it */
2578 if (IS_LITERAL (LTYPE (tree)))
2580 tree->type = EX_VALUE;
2581 tree->opval.val = valNot (valFromType (LETYPE (tree)));
2583 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2587 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2590 /*------------------------------------------------------------------*/
2591 /*----------------------------*/
2593 /*----------------------------*/
2596 TTYPE (tree) = LTYPE (tree);
2597 TETYPE (tree) = LETYPE (tree);
2601 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2606 if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2608 werror (E_SHIFT_OP_INVALID);
2609 werror (W_CONTINUE, "left & right types are ");
2610 printTypeChain (LTYPE (tree), stderr);
2611 fprintf (stderr, ",");
2612 printTypeChain (RTYPE (tree), stderr);
2613 fprintf (stderr, "\n");
2614 goto errorTreeReturn;
2617 /* if they are both literal then */
2618 /* rewrite the tree */
2619 if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2621 tree->type = EX_VALUE;
2622 tree->opval.val = valShift (valFromType (LETYPE (tree)),
2623 valFromType (RETYPE (tree)),
2624 (tree->opval.op == LEFT_OP ? 1 : 0));
2625 tree->right = tree->left = NULL;
2626 TETYPE (tree) = getSpec (TTYPE (tree) =
2627 tree->opval.val->type);
2630 /* if only the right side is a literal & we are
2631 shifting more than size of the left operand then zero */
2632 if (IS_LITERAL (RTYPE (tree)) &&
2633 ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2634 (getSize (LTYPE (tree)) * 8))
2636 werror (W_SHIFT_CHANGED,
2637 (tree->opval.op == LEFT_OP ? "left" : "right"));
2638 tree->type = EX_VALUE;
2639 tree->left = tree->right = NULL;
2640 tree->opval.val = constVal ("0");
2641 TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2644 LRVAL (tree) = RRVAL (tree) = 1;
2645 if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2647 COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2651 COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2655 /*------------------------------------------------------------------*/
2656 /*----------------------------*/
2658 /*----------------------------*/
2659 case CAST: /* change the type */
2660 /* cannot cast to an aggregate type */
2661 if (IS_AGGREGATE (LTYPE (tree)))
2663 werror (E_CAST_ILLEGAL);
2664 goto errorTreeReturn;
2667 /* make sure the type is complete and sane */
2668 checkTypeSanity(LETYPE(tree), "(cast)");
2671 /* if the right is a literal replace the tree */
2672 if (IS_LITERAL (RETYPE (tree))) {
2673 if (!IS_PTR (LTYPE (tree))) {
2674 tree->type = EX_VALUE;
2676 valCastLiteral (LTYPE (tree),
2677 floatFromVal (valFromType (RETYPE (tree))));
2680 TTYPE (tree) = tree->opval.val->type;
2681 tree->values.literalFromCast = 1;
2682 } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
2683 ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
2684 sym_link *rest = LTYPE(tree)->next;
2685 werror(W_LITERAL_GENERIC);
2686 TTYPE(tree) = newLink();
2687 DCL_TYPE(TTYPE(tree)) = FPOINTER;
2688 TTYPE(tree)->next = rest;
2689 tree->left->opval.lnk = TTYPE(tree);
2692 TTYPE (tree) = LTYPE (tree);
2696 TTYPE (tree) = LTYPE (tree);
2700 /* if pointer to struct then check names */
2701 if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2702 IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2703 strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2704 werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2706 /* if the right is a literal replace the tree */
2707 if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2708 tree->type = EX_VALUE;
2710 valCastLiteral (LTYPE (tree),
2711 floatFromVal (valFromType (RETYPE (tree))));
2714 TTYPE (tree) = tree->opval.val->type;
2715 tree->values.literalFromCast = 1;
2717 TTYPE (tree) = LTYPE (tree);
2721 TETYPE (tree) = getSpec (TTYPE (tree));
2725 /*------------------------------------------------------------------*/
2726 /*----------------------------*/
2727 /* logical &&, || */
2728 /*----------------------------*/
2731 /* each must me arithmetic type or be a pointer */
2732 if (!IS_PTR (LTYPE (tree)) &&
2733 !IS_ARRAY (LTYPE (tree)) &&
2734 !IS_INTEGRAL (LTYPE (tree)))
2736 werror (E_COMPARE_OP);
2737 goto errorTreeReturn;
2740 if (!IS_PTR (RTYPE (tree)) &&
2741 !IS_ARRAY (RTYPE (tree)) &&
2742 !IS_INTEGRAL (RTYPE (tree)))
2744 werror (E_COMPARE_OP);
2745 goto errorTreeReturn;
2747 /* if they are both literal then */
2748 /* rewrite the tree */
2749 if (IS_LITERAL (RTYPE (tree)) &&
2750 IS_LITERAL (LTYPE (tree)))
2752 tree->type = EX_VALUE;
2753 tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2754 valFromType (RETYPE (tree)),
2756 tree->right = tree->left = NULL;
2757 TETYPE (tree) = getSpec (TTYPE (tree) =
2758 tree->opval.val->type);
2761 LRVAL (tree) = RRVAL (tree) = 1;
2762 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2765 /*------------------------------------------------------------------*/
2766 /*----------------------------*/
2767 /* comparison operators */
2768 /*----------------------------*/
2776 ast *lt = optimizeCompare (tree);
2782 /* if they are pointers they must be castable */
2783 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2785 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2787 werror (E_COMPARE_OP);
2788 fprintf (stderr, "comparing type ");
2789 printTypeChain (LTYPE (tree), stderr);
2790 fprintf (stderr, "to type ");
2791 printTypeChain (RTYPE (tree), stderr);
2792 fprintf (stderr, "\n");
2793 goto errorTreeReturn;
2796 /* else they should be promotable to one another */
2799 if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2800 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2802 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2804 werror (E_COMPARE_OP);
2805 fprintf (stderr, "comparing type ");
2806 printTypeChain (LTYPE (tree), stderr);
2807 fprintf (stderr, "to type ");
2808 printTypeChain (RTYPE (tree), stderr);
2809 fprintf (stderr, "\n");
2810 goto errorTreeReturn;
2814 /* if they are both literal then */
2815 /* rewrite the tree */
2816 if (IS_LITERAL (RTYPE (tree)) &&
2817 IS_LITERAL (LTYPE (tree)))
2819 tree->type = EX_VALUE;
2820 tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2821 valFromType (RETYPE (tree)),
2823 tree->right = tree->left = NULL;
2824 TETYPE (tree) = getSpec (TTYPE (tree) =
2825 tree->opval.val->type);
2828 LRVAL (tree) = RRVAL (tree) = 1;
2829 TTYPE (tree) = TETYPE (tree) = newCharLink ();
2832 /*------------------------------------------------------------------*/
2833 /*----------------------------*/
2835 /*----------------------------*/
2836 case SIZEOF: /* evaluate wihout code generation */
2837 /* change the type to a integer */
2838 tree->type = EX_VALUE;
2839 sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2840 tree->opval.val = constVal (buffer);
2841 tree->right = tree->left = NULL;
2842 TETYPE (tree) = getSpec (TTYPE (tree) =
2843 tree->opval.val->type);
2846 /*------------------------------------------------------------------*/
2847 /*----------------------------*/
2848 /* conditional operator '?' */
2849 /*----------------------------*/
2851 /* the type is value of the colon operator (on the right) */
2852 assert(IS_COLON_OP(tree->right));
2853 /* if already known then replace the tree : optimizer will do it
2854 but faster to do it here */
2855 if (IS_LITERAL (LTYPE(tree))) {
2856 if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2857 return tree->right->left ;
2859 return tree->right->right ;
2862 TTYPE (tree) = RTYPE(tree);
2863 TETYPE (tree) = getSpec (TTYPE (tree));
2868 /* if they don't match we have a problem */
2869 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2871 werror (E_TYPE_MISMATCH, "conditional operator", " ");
2872 goto errorTreeReturn;
2875 TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2876 TETYPE (tree) = getSpec (TTYPE (tree));
2880 /*------------------------------------------------------------------*/
2881 /*----------------------------*/
2882 /* assignment operators */
2883 /*----------------------------*/
2886 /* for these it must be both must be integral */
2887 if (!IS_ARITHMETIC (LTYPE (tree)) ||
2888 !IS_ARITHMETIC (RTYPE (tree)))
2890 werror (E_OPS_INTEGRAL);
2891 goto errorTreeReturn;
2894 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2896 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2897 werror (E_CODE_WRITE, " ");
2901 werror (E_LVALUE_REQUIRED, "*= or /=");
2902 goto errorTreeReturn;
2913 /* for these it must be both must be integral */
2914 if (!IS_INTEGRAL (LTYPE (tree)) ||
2915 !IS_INTEGRAL (RTYPE (tree)))
2917 werror (E_OPS_INTEGRAL);
2918 goto errorTreeReturn;
2921 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2923 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2924 werror (E_CODE_WRITE, " ");
2928 werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2929 goto errorTreeReturn;
2935 /*------------------------------------------------------------------*/
2936 /*----------------------------*/
2938 /*----------------------------*/
2940 if (!(IS_PTR (LTYPE (tree)) ||
2941 IS_ARITHMETIC (LTYPE (tree))))
2943 werror (E_PLUS_INVALID, "-=");
2944 goto errorTreeReturn;
2947 if (!(IS_PTR (RTYPE (tree)) ||
2948 IS_ARITHMETIC (RTYPE (tree))))
2950 werror (E_PLUS_INVALID, "-=");
2951 goto errorTreeReturn;
2954 TETYPE (tree) = getSpec (TTYPE (tree) =
2955 computeType (LTYPE (tree),
2958 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2959 werror (E_CODE_WRITE, " ");
2963 werror (E_LVALUE_REQUIRED, "-=");
2964 goto errorTreeReturn;
2970 /*------------------------------------------------------------------*/
2971 /*----------------------------*/
2973 /*----------------------------*/
2975 /* this is not a unary operation */
2976 /* if both pointers then problem */
2977 if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2979 werror (E_PTR_PLUS_PTR);
2980 goto errorTreeReturn;
2983 if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2985 werror (E_PLUS_INVALID, "+=");
2986 goto errorTreeReturn;
2989 if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
2991 werror (E_PLUS_INVALID, "+=");
2992 goto errorTreeReturn;
2995 TETYPE (tree) = getSpec (TTYPE (tree) =
2996 computeType (LTYPE (tree),
2999 if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3000 werror (E_CODE_WRITE, " ");
3004 werror (E_LVALUE_REQUIRED, "+=");
3005 goto errorTreeReturn;
3008 tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3009 tree->opval.op = '=';
3013 /*------------------------------------------------------------------*/
3014 /*----------------------------*/
3015 /* straight assignemnt */
3016 /*----------------------------*/
3018 /* cannot be an aggregate */
3019 if (IS_AGGREGATE (LTYPE (tree)))
3021 werror (E_AGGR_ASSIGN);
3022 goto errorTreeReturn;
3025 /* they should either match or be castable */
3026 if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3028 werror (E_TYPE_MISMATCH, "assignment", " ");
3029 fprintf (stderr, "type --> '");
3030 printTypeChain (RTYPE (tree), stderr);
3031 fprintf (stderr, "' ");
3032 fprintf (stderr, "assigned to type --> '");
3033 printTypeChain (LTYPE (tree), stderr);
3034 fprintf (stderr, "'\n");
3035 goto errorTreeReturn;
3038 /* if the left side of the tree is of type void
3039 then report error */
3040 if (IS_VOID (LTYPE (tree)))
3042 werror (E_CAST_ZERO);
3043 printFromToType(RTYPE(tree), LTYPE(tree));
3046 TETYPE (tree) = getSpec (TTYPE (tree) =
3050 if (!tree->initMode ) {
3051 if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3052 werror (E_CODE_WRITE, " ");
3056 werror (E_LVALUE_REQUIRED, "=");
3057 goto errorTreeReturn;
3062 /*------------------------------------------------------------------*/
3063 /*----------------------------*/
3064 /* comma operator */
3065 /*----------------------------*/
3067 TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3070 /*------------------------------------------------------------------*/
3071 /*----------------------------*/
3073 /*----------------------------*/
3077 if (processParms (tree->left,
3078 FUNC_ARGS(tree->left->ftype),
3079 tree->right, &parmNumber, TRUE)) {
3080 goto errorTreeReturn;
3083 if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3085 //FUNC_ARGS(tree->left->ftype) =
3086 //reverseVal (FUNC_ARGS(tree->left->ftype));
3087 reverseParms (tree->right);
3090 TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3093 /*------------------------------------------------------------------*/
3094 /*----------------------------*/
3095 /* return statement */
3096 /*----------------------------*/
3101 if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3103 werror (W_RETURN_MISMATCH);
3104 printFromToType (RTYPE(tree), currFunc->type->next);
3105 goto errorTreeReturn;
3108 if (IS_VOID (currFunc->type->next)
3110 !IS_VOID (RTYPE (tree)))
3112 werror (E_FUNC_VOID);
3113 goto errorTreeReturn;
3116 /* if there is going to be a casing required then add it */
3117 if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3120 decorateType (newNode (CAST,
3121 newAst_LINK (copyLinkChain (currFunc->type->next)),
3130 if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3132 werror (E_VOID_FUNC, currFunc->name);
3133 goto errorTreeReturn;
3136 TTYPE (tree) = TETYPE (tree) = NULL;
3139 /*------------------------------------------------------------------*/
3140 /*----------------------------*/
3141 /* switch statement */
3142 /*----------------------------*/
3144 /* the switch value must be an integer */
3145 if (!IS_INTEGRAL (LTYPE (tree)))
3147 werror (E_SWITCH_NON_INTEGER);
3148 goto errorTreeReturn;
3151 TTYPE (tree) = TETYPE (tree) = NULL;
3154 /*------------------------------------------------------------------*/
3155 /*----------------------------*/
3157 /*----------------------------*/
3159 tree->left = backPatchLabels (tree->left,
3162 TTYPE (tree) = TETYPE (tree) = NULL;
3165 /*------------------------------------------------------------------*/
3166 /*----------------------------*/
3168 /*----------------------------*/
3171 decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3172 decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3173 decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3175 /* if the for loop is reversible then
3176 reverse it otherwise do what we normally
3182 if (isLoopReversible (tree, &sym, &init, &end))
3183 return reverseLoop (tree, sym, init, end);
3185 return decorateType (createFor (AST_FOR (tree, trueLabel),
3186 AST_FOR (tree, continueLabel),
3187 AST_FOR (tree, falseLabel),
3188 AST_FOR (tree, condLabel),
3189 AST_FOR (tree, initExpr),
3190 AST_FOR (tree, condExpr),
3191 AST_FOR (tree, loopExpr),
3195 TTYPE (tree) = TETYPE (tree) = NULL;
3199 /* some error found this tree will be killed */
3201 TTYPE (tree) = TETYPE (tree) = newCharLink ();
3202 tree->opval.op = NULLOP;
3208 /*-----------------------------------------------------------------*/
3209 /* sizeofOp - processes size of operation */
3210 /*-----------------------------------------------------------------*/
3212 sizeofOp (sym_link * type)
3216 /* make sure the type is complete and sane */
3217 checkTypeSanity(type, "(sizeof)");
3219 /* get the size and convert it to character */
3220 sprintf (buff, "%d", getSize (type));
3222 /* now convert into value */
3223 return constVal (buff);
3227 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3228 #define IS_OR(ex) (ex->type == EX_OP && ex->opval.op == OR_OP )
3229 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3230 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3231 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3232 #define IS_LT(ex) (ex->type == EX_OP && ex->opval.op == '<' )
3233 #define IS_GT(ex) (ex->type == EX_OP && ex->opval.op == '>')
3235 /*-----------------------------------------------------------------*/
3236 /* backPatchLabels - change and or not operators to flow control */
3237 /*-----------------------------------------------------------------*/
3239 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3245 if (!(IS_ANDORNOT (tree)))
3248 /* if this an and */
3251 static int localLbl = 0;
3254 sprintf (buffer, "_and_%d", localLbl++);
3255 localLabel = newSymbol (buffer, NestLevel);
3257 tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3259 /* if left is already a IFX then just change the if true label in that */
3260 if (!IS_IFX (tree->left))
3261 tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3263 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3264 /* right is a IFX then just join */
3265 if (IS_IFX (tree->right))
3266 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3268 tree->right = createLabel (localLabel, tree->right);
3269 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3271 return newNode (NULLOP, tree->left, tree->right);
3274 /* if this is an or operation */
3277 static int localLbl = 0;
3280 sprintf (buffer, "_or_%d", localLbl++);
3281 localLabel = newSymbol (buffer, NestLevel);
3283 tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3285 /* if left is already a IFX then just change the if true label in that */
3286 if (!IS_IFX (tree->left))
3287 tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3289 tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3290 /* right is a IFX then just join */
3291 if (IS_IFX (tree->right))
3292 return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3294 tree->right = createLabel (localLabel, tree->right);
3295 tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3297 return newNode (NULLOP, tree->left, tree->right);
3303 int wasnot = IS_NOT (tree->left);
3304 tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3306 /* if the left is already a IFX */
3307 if (!IS_IFX (tree->left))
3308 tree->left = newNode (IFX, tree->left, NULL);
3312 tree->left->trueLabel = trueLabel;
3313 tree->left->falseLabel = falseLabel;
3317 tree->left->trueLabel = falseLabel;
3318 tree->left->falseLabel = trueLabel;
3325 tree->trueLabel = trueLabel;
3326 tree->falseLabel = falseLabel;
3333 /*-----------------------------------------------------------------*/
3334 /* createBlock - create expression tree for block */
3335 /*-----------------------------------------------------------------*/
3337 createBlock (symbol * decl, ast * body)
3341 /* if the block has nothing */
3345 ex = newNode (BLOCK, NULL, body);
3346 ex->values.sym = decl;
3348 ex->right = ex->right;
3354 /*-----------------------------------------------------------------*/
3355 /* createLabel - creates the expression tree for labels */
3356 /*-----------------------------------------------------------------*/
3358 createLabel (symbol * label, ast * stmnt)
3361 char name[SDCC_NAME_MAX + 1];
3364 /* must create fresh symbol if the symbol name */
3365 /* exists in the symbol table, since there can */
3366 /* be a variable with the same name as the labl */
3367 if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3368 (csym->level == label->level))
3369 label = newSymbol (label->name, label->level);
3371 /* change the name before putting it in add _ */
3372 sprintf (name, "%s", label->name);
3374 /* put the label in the LabelSymbol table */
3375 /* but first check if a label of the same */
3377 if ((csym = findSym (LabelTab, NULL, name)))
3378 werror (E_DUPLICATE_LABEL, label->name);
3380 addSym (LabelTab, label, name, label->level, 0, 0);
3383 label->key = labelKey++;
3384 rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3390 /*-----------------------------------------------------------------*/
3391 /* createCase - generates the parsetree for a case statement */
3392 /*-----------------------------------------------------------------*/
3394 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3396 char caseLbl[SDCC_NAME_MAX + 1];
3400 /* if the switch statement does not exist */
3401 /* then case is out of context */
3404 werror (E_CASE_CONTEXT);
3408 caseVal = decorateType (resolveSymbols (caseVal));
3409 /* if not a constant then error */
3410 if (!IS_LITERAL (caseVal->ftype))
3412 werror (E_CASE_CONSTANT);
3416 /* if not a integer than error */
3417 if (!IS_INTEGRAL (caseVal->ftype))
3419 werror (E_CASE_NON_INTEGER);
3423 /* find the end of the switch values chain */
3424 if (!(val = swStat->values.switchVals.swVals))
3425 swStat->values.switchVals.swVals = caseVal->opval.val;
3428 /* also order the cases according to value */
3430 int cVal = (int) floatFromVal (caseVal->opval.val);
3431 while (val && (int) floatFromVal (val) < cVal)
3437 /* if we reached the end then */
3440 pval->next = caseVal->opval.val;
3444 /* we found a value greater than */
3445 /* the current value we must add this */
3446 /* before the value */
3447 caseVal->opval.val->next = val;
3449 /* if this was the first in chain */
3450 if (swStat->values.switchVals.swVals == val)
3451 swStat->values.switchVals.swVals =
3454 pval->next = caseVal->opval.val;
3459 /* create the case label */
3460 sprintf (caseLbl, "_case_%d_%d",
3461 swStat->values.switchVals.swNum,
3462 (int) floatFromVal (caseVal->opval.val));
3464 rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3469 /*-----------------------------------------------------------------*/
3470 /* createDefault - creates the parse tree for the default statement */
3471 /*-----------------------------------------------------------------*/
3473 createDefault (ast * swStat, ast * stmnt)
3475 char defLbl[SDCC_NAME_MAX + 1];
3477 /* if the switch statement does not exist */
3478 /* then case is out of context */
3481 werror (E_CASE_CONTEXT);
3485 /* turn on the default flag */
3486 swStat->values.switchVals.swDefault = 1;
3488 /* create the label */
3489 sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3490 return createLabel (newSymbol (defLbl, 0), stmnt);
3493 /*-----------------------------------------------------------------*/
3494 /* createIf - creates the parsetree for the if statement */
3495 /*-----------------------------------------------------------------*/
3497 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3499 static int Lblnum = 0;
3501 symbol *ifTrue, *ifFalse, *ifEnd;
3503 /* if neither exists */
3504 if (!elseBody && !ifBody) {
3505 // if there are no side effects (i++, j() etc)
3506 if (!hasSEFcalls(condAst)) {
3511 /* create the labels */
3512 sprintf (buffer, "_iffalse_%d", Lblnum);
3513 ifFalse = newSymbol (buffer, NestLevel);
3514 /* if no else body then end == false */
3519 sprintf (buffer, "_ifend_%d", Lblnum);
3520 ifEnd = newSymbol (buffer, NestLevel);
3523 sprintf (buffer, "_iftrue_%d", Lblnum);
3524 ifTrue = newSymbol (buffer, NestLevel);
3528 /* attach the ifTrue label to the top of it body */
3529 ifBody = createLabel (ifTrue, ifBody);
3530 /* attach a goto end to the ifBody if else is present */
3533 ifBody = newNode (NULLOP, ifBody,
3535 newAst_VALUE (symbolVal (ifEnd)),
3537 /* put the elseLabel on the else body */
3538 elseBody = createLabel (ifFalse, elseBody);
3539 /* out the end at the end of the body */
3540 elseBody = newNode (NULLOP,
3542 createLabel (ifEnd, NULL));
3546 ifBody = newNode (NULLOP, ifBody,
3547 createLabel (ifFalse, NULL));
3549 condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3550 if (IS_IFX (condAst))
3553 ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3555 return newNode (NULLOP, ifTree,
3556 newNode (NULLOP, ifBody, elseBody));
3560 /*-----------------------------------------------------------------*/
3561 /* createDo - creates parse tree for do */
3564 /* _docontinue_n: */
3565 /* condition_expression +-> trueLabel -> _dobody_n */
3567 /* +-> falseLabel-> _dobreak_n */
3569 /*-----------------------------------------------------------------*/
3571 createDo (symbol * trueLabel, symbol * continueLabel,
3572 symbol * falseLabel, ast * condAst, ast * doBody)
3577 /* if the body does not exist then it is simple */
3580 condAst = backPatchLabels (condAst, continueLabel, NULL);
3581 doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3582 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3583 doTree->trueLabel = continueLabel;
3584 doTree->falseLabel = NULL;
3588 /* otherwise we have a body */
3589 condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3591 /* attach the body label to the top */
3592 doBody = createLabel (trueLabel, doBody);
3593 /* attach the continue label to end of body */
3594 doBody = newNode (NULLOP, doBody,
3595 createLabel (continueLabel, NULL));
3597 /* now put the break label at the end */
3598 if (IS_IFX (condAst))
3601 doTree = newIfxNode (condAst, trueLabel, falseLabel);
3603 doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3605 /* putting it together */
3606 return newNode (NULLOP, doBody, doTree);
3609 /*-----------------------------------------------------------------*/
3610 /* createFor - creates parse tree for 'for' statement */
3613 /* condExpr +-> trueLabel -> _forbody_n */
3615 /* +-> falseLabel-> _forbreak_n */
3618 /* _forcontinue_n: */
3620 /* goto _forcond_n ; */
3622 /*-----------------------------------------------------------------*/
3624 createFor (symbol * trueLabel, symbol * continueLabel,
3625 symbol * falseLabel, symbol * condLabel,
3626 ast * initExpr, ast * condExpr, ast * loopExpr,
3631 /* if loopexpression not present then we can generate it */
3632 /* the same way as a while */
3634 return newNode (NULLOP, initExpr,
3635 createWhile (trueLabel, continueLabel,
3636 falseLabel, condExpr, forBody));
3637 /* vanilla for statement */
3638 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3640 if (condExpr && !IS_IFX (condExpr))
3641 condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3644 /* attach condition label to condition */
3645 condExpr = createLabel (condLabel, condExpr);
3647 /* attach body label to body */
3648 forBody = createLabel (trueLabel, forBody);
3650 /* attach continue to forLoop expression & attach */
3651 /* goto the forcond @ and of loopExpression */
3652 loopExpr = createLabel (continueLabel,
3656 newAst_VALUE (symbolVal (condLabel)),
3658 /* now start putting them together */
3659 forTree = newNode (NULLOP, initExpr, condExpr);
3660 forTree = newNode (NULLOP, forTree, forBody);
3661 forTree = newNode (NULLOP, forTree, loopExpr);
3662 /* finally add the break label */
3663 forTree = newNode (NULLOP, forTree,
3664 createLabel (falseLabel, NULL));
3668 /*-----------------------------------------------------------------*/
3669 /* createWhile - creates parse tree for while statement */
3670 /* the while statement will be created as follows */
3672 /* _while_continue_n: */
3673 /* condition_expression +-> trueLabel -> _while_boby_n */
3675 /* +-> falseLabel -> _while_break_n */
3676 /* _while_body_n: */
3678 /* goto _while_continue_n */
3679 /* _while_break_n: */
3680 /*-----------------------------------------------------------------*/
3682 createWhile (symbol * trueLabel, symbol * continueLabel,
3683 symbol * falseLabel, ast * condExpr, ast * whileBody)
3687 /* put the continue label */
3688 condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3689 condExpr = createLabel (continueLabel, condExpr);
3690 condExpr->lineno = 0;
3692 /* put the body label in front of the body */
3693 whileBody = createLabel (trueLabel, whileBody);
3694 whileBody->lineno = 0;
3695 /* put a jump to continue at the end of the body */
3696 /* and put break label at the end of the body */
3697 whileBody = newNode (NULLOP,
3700 newAst_VALUE (symbolVal (continueLabel)),
3701 createLabel (falseLabel, NULL)));
3703 /* put it all together */
3704 if (IS_IFX (condExpr))
3705 whileTree = condExpr;
3708 whileTree = newNode (IFX, condExpr, NULL);
3709 /* put the true & false labels in place */
3710 whileTree->trueLabel = trueLabel;
3711 whileTree->falseLabel = falseLabel;
3714 return newNode (NULLOP, whileTree, whileBody);
3717 /*-----------------------------------------------------------------*/
3718 /* optimizeGetHbit - get highest order bit of the expression */
3719 /*-----------------------------------------------------------------*/
3721 optimizeGetHbit (ast * tree)
3724 /* if this is not a bit and */
3725 if (!IS_BITAND (tree))
3728 /* will look for tree of the form
3729 ( expr >> ((sizeof expr) -1) ) & 1 */
3730 if (!IS_AST_LIT_VALUE (tree->right))
3733 if (AST_LIT_VALUE (tree->right) != 1)
3736 if (!IS_RIGHT_OP (tree->left))
3739 if (!IS_AST_LIT_VALUE (tree->left->right))
3742 if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3743 (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3746 return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3750 /*-----------------------------------------------------------------*/
3751 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */
3752 /*-----------------------------------------------------------------*/
3754 optimizeRRCRLC (ast * root)
3756 /* will look for trees of the form
3757 (?expr << 1) | (?expr >> 7) or
3758 (?expr >> 7) | (?expr << 1) will make that
3759 into a RLC : operation ..
3761 (?expr >> 1) | (?expr << 7) or
3762 (?expr << 7) | (?expr >> 1) will make that
3763 into a RRC operation
3764 note : by 7 I mean (number of bits required to hold the
3766 /* if the root operations is not a | operation the not */
3767 if (!IS_BITOR (root))
3770 /* I have to think of a better way to match patterns this sucks */
3771 /* that aside let start looking for the first case : I use a the
3772 negative check a lot to improve the efficiency */
3773 /* (?expr << 1) | (?expr >> 7) */
3774 if (IS_LEFT_OP (root->left) &&
3775 IS_RIGHT_OP (root->right))
3778 if (!SPEC_USIGN (TETYPE (root->left->left)))
3781 if (!IS_AST_LIT_VALUE (root->left->right) ||
3782 !IS_AST_LIT_VALUE (root->right->right))
3785 /* make sure it is the same expression */
3786 if (!isAstEqual (root->left->left,
3790 if (AST_LIT_VALUE (root->left->right) != 1)
3793 if (AST_LIT_VALUE (root->right->right) !=
3794 (getSize (TTYPE (root->left->left)) * 8 - 1))
3797 /* whew got the first case : create the AST */
3798 return newNode (RLC, root->left->left, NULL);
3802 /* check for second case */
3803 /* (?expr >> 7) | (?expr << 1) */
3804 if (IS_LEFT_OP (root->right) &&
3805 IS_RIGHT_OP (root->left))
3808 if (!SPEC_USIGN (TETYPE (root->left->left)))
3811 if (!IS_AST_LIT_VALUE (root->left->right) ||
3812 !IS_AST_LIT_VALUE (root->right->right))
3815 /* make sure it is the same symbol */
3816 if (!isAstEqual (root->left->left,
3820 if (AST_LIT_VALUE (root->right->right) != 1)
3823 if (AST_LIT_VALUE (root->left->right) !=
3824 (getSize (TTYPE (root->left->left)) * 8 - 1))
3827 /* whew got the first case : create the AST */
3828 return newNode (RLC, root->left->left, NULL);
3833 /* third case for RRC */
3834 /* (?symbol >> 1) | (?symbol << 7) */
3835 if (IS_LEFT_OP (root->right) &&
3836 IS_RIGHT_OP (root->left))
3839 if (!SPEC_USIGN (TETYPE (root->left->left)))
3842 if (!IS_AST_LIT_VALUE (root->left->right) ||
3843 !IS_AST_LIT_VALUE (root->right->right))
3846 /* make sure it is the same symbol */
3847 if (!isAstEqual (root->left->left,
3851 if (AST_LIT_VALUE (root->left->right) != 1)
3854 if (AST_LIT_VALUE (root->right->right) !=
3855 (getSize (TTYPE (root->left->left)) * 8 - 1))
3858 /* whew got the first case : create the AST */
3859 return newNode (RRC, root->left->left, NULL);
3863 /* fourth and last case for now */
3864 /* (?symbol << 7) | (?symbol >> 1) */
3865 if (IS_RIGHT_OP (root->right) &&
3866 IS_LEFT_OP (root->left))
3869 if (!SPEC_USIGN (TETYPE (root->left->left)))
3872 if (!IS_AST_LIT_VALUE (root->left->right) ||
3873 !IS_AST_LIT_VALUE (root->right->right))
3876 /* make sure it is the same symbol */
3877 if (!isAstEqual (root->left->left,
3881 if (AST_LIT_VALUE (root->right->right) != 1)
3884 if (AST_LIT_VALUE (root->left->right) !=
3885 (getSize (TTYPE (root->left->left)) * 8 - 1))
3888 /* whew got the first case : create the AST */
3889 return newNode (RRC, root->left->left, NULL);
3893 /* not found return root */
3897 /*-----------------------------------------------------------------*/
3898 /* optimizeCompare - otimizes compares for bit variables */
3899 /*-----------------------------------------------------------------*/
3901 optimizeCompare (ast * root)
3903 ast *optExpr = NULL;
3906 unsigned int litValue;
3908 /* if nothing then return nothing */
3912 /* if not a compare op then do leaves */
3913 if (!IS_COMPARE_OP (root))
3915 root->left = optimizeCompare (root->left);
3916 root->right = optimizeCompare (root->right);
3920 /* if left & right are the same then depending
3921 of the operation do */
3922 if (isAstEqual (root->left, root->right))
3924 switch (root->opval.op)
3929 optExpr = newAst_VALUE (constVal ("0"));
3934 optExpr = newAst_VALUE (constVal ("1"));
3938 return decorateType (optExpr);
3941 vleft = (root->left->type == EX_VALUE ?
3942 root->left->opval.val : NULL);
3944 vright = (root->right->type == EX_VALUE ?
3945 root->right->opval.val : NULL);
3947 /* if left is a BITVAR in BITSPACE */
3948 /* and right is a LITERAL then opt- */
3949 /* imize else do nothing */
3950 if (vleft && vright &&
3951 IS_BITVAR (vleft->etype) &&
3952 IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3953 IS_LITERAL (vright->etype))
3956 /* if right side > 1 then comparison may never succeed */
3957 if ((litValue = (int) floatFromVal (vright)) > 1)
3959 werror (W_BAD_COMPARE);
3965 switch (root->opval.op)
3967 case '>': /* bit value greater than 1 cannot be */
3968 werror (W_BAD_COMPARE);
3972 case '<': /* bit value < 1 means 0 */
3974 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3977 case LE_OP: /* bit value <= 1 means no check */
3978 optExpr = newAst_VALUE (vright);
3981 case GE_OP: /* bit value >= 1 means only check for = */
3983 optExpr = newAst_VALUE (vleft);
3988 { /* literal is zero */
3989 switch (root->opval.op)
3991 case '<': /* bit value < 0 cannot be */
3992 werror (W_BAD_COMPARE);
3996 case '>': /* bit value > 0 means 1 */
3998 optExpr = newAst_VALUE (vleft);
4001 case LE_OP: /* bit value <= 0 means no check */
4002 case GE_OP: /* bit value >= 0 means no check */
4003 werror (W_BAD_COMPARE);
4007 case EQ_OP: /* bit == 0 means ! of bit */
4008 optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4012 return decorateType (resolveSymbols (optExpr));
4013 } /* end-of-if of BITVAR */
4018 /*-----------------------------------------------------------------*/
4019 /* addSymToBlock : adds the symbol to the first block we find */
4020 /*-----------------------------------------------------------------*/
4022 addSymToBlock (symbol * sym, ast * tree)
4024 /* reached end of tree or a leaf */
4025 if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4029 if (IS_AST_OP (tree) &&
4030 tree->opval.op == BLOCK)
4033 symbol *lsym = copySymbol (sym);
4035 lsym->next = AST_VALUES (tree, sym);
4036 AST_VALUES (tree, sym) = lsym;
4040 addSymToBlock (sym, tree->left);
4041 addSymToBlock (sym, tree->right);
4044 /*-----------------------------------------------------------------*/
4045 /* processRegParms - do processing for register parameters */
4046 /*-----------------------------------------------------------------*/
4048 processRegParms (value * args, ast * body)
4052 if (IS_REGPARM (args->etype))
4053 addSymToBlock (args->sym, body);
4058 /*-----------------------------------------------------------------*/
4059 /* resetParmKey - resets the operandkeys for the symbols */
4060 /*-----------------------------------------------------------------*/
4061 DEFSETFUNC (resetParmKey)
4072 /*-----------------------------------------------------------------*/
4073 /* createFunction - This is the key node that calls the iCode for */
4074 /* generating the code for a function. Note code */
4075 /* is generated function by function, later when */
4076 /* add inter-procedural analysis this will change */
4077 /*-----------------------------------------------------------------*/
4079 createFunction (symbol * name, ast * body)
4085 iCode *piCode = NULL;
4087 if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4088 fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4090 /* if check function return 0 then some problem */
4091 if (checkFunction (name, NULL) == 0)
4094 /* create a dummy block if none exists */
4096 body = newNode (BLOCK, NULL, NULL);
4100 /* check if the function name already in the symbol table */
4101 if ((csym = findSym (SymbolTab, NULL, name->name)))
4104 /* special case for compiler defined functions
4105 we need to add the name to the publics list : this
4106 actually means we are now compiling the compiler
4110 addSet (&publics, name);
4116 allocVariables (name);
4118 name->lastLine = yylineno;
4121 #if 0 // jwk: this is now done in addDecl()
4122 processFuncArgs (currFunc);
4125 /* set the stack pointer */
4126 /* PENDING: check this for the mcs51 */
4127 stackPtr = -port->stack.direction * port->stack.call_overhead;
4128 if (IFFUNC_ISISR (name->type))
4129 stackPtr -= port->stack.direction * port->stack.isr_overhead;
4130 if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4131 stackPtr -= port->stack.direction * port->stack.reent_overhead;
4133 xstackPtr = -port->stack.direction * port->stack.call_overhead;
4135 fetype = getSpec (name->type); /* get the specifier for the function */
4136 /* if this is a reentrant function then */
4137 if (IFFUNC_ISREENT (name->type))
4140 allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
4142 /* do processing for parameters that are passed in registers */
4143 processRegParms (FUNC_ARGS(name->type), body);
4145 /* set the stack pointer */
4149 /* allocate & autoinit the block variables */
4150 processBlockVars (body, &stack, ALLOCATE);
4152 /* save the stack information */
4153 if (options.useXstack)
4154 name->xstack = SPEC_STAK (fetype) = stack;
4156 name->stack = SPEC_STAK (fetype) = stack;
4158 /* name needs to be mangled */
4159 sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4161 body = resolveSymbols (body); /* resolve the symbols */
4162 body = decorateType (body); /* propagateType & do semantic checks */
4164 ex = newAst_VALUE (symbolVal (name)); /* create name */
4165 ex = newNode (FUNCTION, ex, body);
4166 ex->values.args = FUNC_ARGS(name->type);
4168 if (options.dump_tree) PA(ex);
4171 werror (E_FUNC_NO_CODE, name->name);
4175 /* create the node & generate intermediate code */
4177 codeOutFile = code->oFile;
4178 piCode = iCodeFromAst (ex);
4182 werror (E_FUNC_NO_CODE, name->name);
4186 eBBlockFromiCode (piCode);
4188 /* if there are any statics then do them */
4191 GcurMemmap = statsg;
4192 codeOutFile = statsg->oFile;
4193 eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4199 /* dealloc the block variables */
4200 processBlockVars (body, &stack, DEALLOCATE);
4201 /* deallocate paramaters */
4202 deallocParms (FUNC_ARGS(name->type));
4204 if (IFFUNC_ISREENT (name->type))
4207 /* we are done freeup memory & cleanup */
4211 FUNC_HASBODY(name->type) = 1;
4212 addSet (&operKeyReset, name);
4213 applyToSet (operKeyReset, resetParmKey);
4216 cdbStructBlock (1, cdbFile);
4218 cleanUpLevel (LabelTab, 0);
4219 cleanUpBlock (StructTab, 1);
4220 cleanUpBlock (TypedefTab, 1);
4222 xstack->syms = NULL;
4223 istack->syms = NULL;
4228 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4229 /*-----------------------------------------------------------------*/
4230 /* ast_print : prints the ast (for debugging purposes) */
4231 /*-----------------------------------------------------------------*/
4233 void ast_print (ast * tree, FILE *outfile, int indent)
4238 /* can print only decorated trees */
4239 if (!tree->decorated) return;
4241 /* if any child is an error | this one is an error do nothing */
4242 if (tree->isError ||
4243 (tree->left && tree->left->isError) ||
4244 (tree->right && tree->right->isError)) {
4245 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4249 /* print the line */
4250 /* if not block & function */
4251 if (tree->type == EX_OP &&
4252 (tree->opval.op != FUNCTION &&
4253 tree->opval.op != BLOCK &&
4254 tree->opval.op != NULLOP)) {
4257 if (tree->opval.op == FUNCTION) {
4259 value *args=FUNC_ARGS(tree->left->opval.val->type);
4260 fprintf(outfile,"FUNCTION (%s=%p) type (",
4261 tree->left->opval.val->name, tree);
4262 printTypeChain (tree->ftype,outfile);
4263 fprintf(outfile,") args (");
4266 fprintf (outfile, ", ");
4268 printTypeChain (args ? args->type : NULL, outfile);
4270 args= args ? args->next : NULL;
4272 fprintf(outfile,")\n");
4273 ast_print(tree->left,outfile,indent);
4274 ast_print(tree->right,outfile,indent);
4277 if (tree->opval.op == BLOCK) {
4278 symbol *decls = tree->values.sym;
4279 INDENT(indent,outfile);
4280 fprintf(outfile,"{\n");
4282 INDENT(indent+4,outfile);
4283 fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4284 decls->name, decls);
4285 printTypeChain(decls->type,outfile);
4286 fprintf(outfile,")\n");
4288 decls = decls->next;
4290 ast_print(tree->right,outfile,indent+4);
4291 INDENT(indent,outfile);
4292 fprintf(outfile,"}\n");
4295 if (tree->opval.op == NULLOP) {
4296 fprintf(outfile,"\n");
4297 ast_print(tree->left,outfile,indent);
4298 fprintf(outfile,"\n");
4299 ast_print(tree->right,outfile,indent);
4302 INDENT(indent,outfile);
4304 /*------------------------------------------------------------------*/
4305 /*----------------------------*/
4306 /* leaf has been reached */
4307 /*----------------------------*/
4308 /* if this is of type value */
4309 /* just get the type */
4310 if (tree->type == EX_VALUE) {
4312 if (IS_LITERAL (tree->opval.val->etype)) {
4313 fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4314 (int) floatFromVal(tree->opval.val),
4315 (int) floatFromVal(tree->opval.val),
4316 floatFromVal(tree->opval.val));
4317 } else if (tree->opval.val->sym) {
4318 /* if the undefined flag is set then give error message */
4319 if (tree->opval.val->sym->undefined) {
4320 fprintf(outfile,"UNDEFINED SYMBOL ");
4322 fprintf(outfile,"SYMBOL ");
4324 fprintf(outfile,"(%s=%p)",
4325 tree->opval.val->sym->name,tree);
4328 fprintf(outfile," type (");
4329 printTypeChain(tree->ftype,outfile);
4330 fprintf(outfile,")\n");
4332 fprintf(outfile,"\n");
4337 /* if type link for the case of cast */
4338 if (tree->type == EX_LINK) {
4339 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4340 printTypeChain(tree->opval.lnk,outfile);
4341 fprintf(outfile,")\n");
4346 /* depending on type of operator do */
4348 switch (tree->opval.op) {
4349 /*------------------------------------------------------------------*/
4350 /*----------------------------*/
4352 /*----------------------------*/
4354 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4355 printTypeChain(tree->ftype,outfile);
4356 fprintf(outfile,")\n");
4357 ast_print(tree->left,outfile,indent+4);
4358 ast_print(tree->right,outfile,indent+4);
4361 /*------------------------------------------------------------------*/
4362 /*----------------------------*/
4364 /*----------------------------*/
4366 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4367 printTypeChain(tree->ftype,outfile);
4368 fprintf(outfile,")\n");
4369 ast_print(tree->left,outfile,indent+4);
4370 ast_print(tree->right,outfile,indent+4);
4373 /*------------------------------------------------------------------*/
4374 /*----------------------------*/
4375 /* struct/union pointer */
4376 /*----------------------------*/
4378 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4379 printTypeChain(tree->ftype,outfile);
4380 fprintf(outfile,")\n");
4381 ast_print(tree->left,outfile,indent+4);
4382 ast_print(tree->right,outfile,indent+4);
4385 /*------------------------------------------------------------------*/
4386 /*----------------------------*/
4387 /* ++/-- operation */
4388 /*----------------------------*/
4389 case INC_OP: /* incerement operator unary so left only */
4390 fprintf(outfile,"INC_OP (%p) type (",tree);
4391 printTypeChain(tree->ftype,outfile);
4392 fprintf(outfile,")\n");
4393 ast_print(tree->left,outfile,indent+4);
4397 fprintf(outfile,"DEC_OP (%p) type (",tree);
4398 printTypeChain(tree->ftype,outfile);
4399 fprintf(outfile,")\n");
4400 ast_print(tree->left,outfile,indent+4);
4403 /*------------------------------------------------------------------*/
4404 /*----------------------------*/
4406 /*----------------------------*/
4409 fprintf(outfile,"& (%p) type (",tree);
4410 printTypeChain(tree->ftype,outfile);
4411 fprintf(outfile,")\n");
4412 ast_print(tree->left,outfile,indent+4);
4413 ast_print(tree->right,outfile,indent+4);
4415 fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4416 printTypeChain(tree->ftype,outfile);
4417 fprintf(outfile,")\n");
4418 ast_print(tree->left,outfile,indent+4);
4419 ast_print(tree->right,outfile,indent+4);
4422 /*----------------------------*/
4424 /*----------------------------*/
4426 fprintf(outfile,"OR (%p) type (",tree);
4427 printTypeChain(tree->ftype,outfile);
4428 fprintf(outfile,")\n");
4429 ast_print(tree->left,outfile,indent+4);
4430 ast_print(tree->right,outfile,indent+4);
4432 /*------------------------------------------------------------------*/
4433 /*----------------------------*/
4435 /*----------------------------*/
4437 fprintf(outfile,"XOR (%p) type (",tree);
4438 printTypeChain(tree->ftype,outfile);
4439 fprintf(outfile,")\n");
4440 ast_print(tree->left,outfile,indent+4);
4441 ast_print(tree->right,outfile,indent+4);
4444 /*------------------------------------------------------------------*/
4445 /*----------------------------*/
4447 /*----------------------------*/
4449 fprintf(outfile,"DIV (%p) type (",tree);
4450 printTypeChain(tree->ftype,outfile);
4451 fprintf(outfile,")\n");
4452 ast_print(tree->left,outfile,indent+4);
4453 ast_print(tree->right,outfile,indent+4);
4455 /*------------------------------------------------------------------*/
4456 /*----------------------------*/
4458 /*----------------------------*/
4460 fprintf(outfile,"MOD (%p) type (",tree);
4461 printTypeChain(tree->ftype,outfile);
4462 fprintf(outfile,")\n");
4463 ast_print(tree->left,outfile,indent+4);
4464 ast_print(tree->right,outfile,indent+4);
4467 /*------------------------------------------------------------------*/
4468 /*----------------------------*/
4469 /* address dereference */
4470 /*----------------------------*/
4471 case '*': /* can be unary : if right is null then unary operation */
4473 fprintf(outfile,"DEREF (%p) type (",tree);
4474 printTypeChain(tree->ftype,outfile);
4475 fprintf(outfile,")\n");
4476 ast_print(tree->left,outfile,indent+4);
4479 /*------------------------------------------------------------------*/
4480 /*----------------------------*/
4481 /* multiplication */
4482 /*----------------------------*/
4483 fprintf(outfile,"MULT (%p) type (",tree);
4484 printTypeChain(tree->ftype,outfile);
4485 fprintf(outfile,")\n");
4486 ast_print(tree->left,outfile,indent+4);
4487 ast_print(tree->right,outfile,indent+4);
4491 /*------------------------------------------------------------------*/
4492 /*----------------------------*/
4493 /* unary '+' operator */
4494 /*----------------------------*/
4498 fprintf(outfile,"UPLUS (%p) type (",tree);
4499 printTypeChain(tree->ftype,outfile);
4500 fprintf(outfile,")\n");
4501 ast_print(tree->left,outfile,indent+4);
4503 /*------------------------------------------------------------------*/
4504 /*----------------------------*/
4506 /*----------------------------*/
4507 fprintf(outfile,"ADD (%p) type (",tree);
4508 printTypeChain(tree->ftype,outfile);
4509 fprintf(outfile,")\n");
4510 ast_print(tree->left,outfile,indent+4);
4511 ast_print(tree->right,outfile,indent+4);
4514 /*------------------------------------------------------------------*/
4515 /*----------------------------*/
4517 /*----------------------------*/
4518 case '-': /* can be unary */
4520 fprintf(outfile,"UMINUS (%p) type (",tree);
4521 printTypeChain(tree->ftype,outfile);
4522 fprintf(outfile,")\n");
4523 ast_print(tree->left,outfile,indent+4);
4525 /*------------------------------------------------------------------*/
4526 /*----------------------------*/
4528 /*----------------------------*/
4529 fprintf(outfile,"SUB (%p) type (",tree);
4530 printTypeChain(tree->ftype,outfile);
4531 fprintf(outfile,")\n");
4532 ast_print(tree->left,outfile,indent+4);
4533 ast_print(tree->right,outfile,indent+4);
4536 /*------------------------------------------------------------------*/
4537 /*----------------------------*/
4539 /*----------------------------*/
4541 fprintf(outfile,"COMPL (%p) type (",tree);
4542 printTypeChain(tree->ftype,outfile);
4543 fprintf(outfile,")\n");
4544 ast_print(tree->left,outfile,indent+4);
4546 /*------------------------------------------------------------------*/
4547 /*----------------------------*/
4549 /*----------------------------*/
4551 fprintf(outfile,"NOT (%p) type (",tree);
4552 printTypeChain(tree->ftype,outfile);
4553 fprintf(outfile,")\n");
4554 ast_print(tree->left,outfile,indent+4);
4556 /*------------------------------------------------------------------*/
4557 /*----------------------------*/
4559 /*----------------------------*/
4561 fprintf(outfile,"RRC (%p) type (",tree);
4562 printTypeChain(tree->ftype,outfile);
4563 fprintf(outfile,")\n");
4564 ast_print(tree->left,outfile,indent+4);
4568 fprintf(outfile,"RLC (%p) type (",tree);
4569 printTypeChain(tree->ftype,outfile);
4570 fprintf(outfile,")\n");
4571 ast_print(tree->left,outfile,indent+4);
4574 fprintf(outfile,"GETHBIT (%p) type (",tree);
4575 printTypeChain(tree->ftype,outfile);
4576 fprintf(outfile,")\n");
4577 ast_print(tree->left,outfile,indent+4);
4580 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4581 printTypeChain(tree->ftype,outfile);
4582 fprintf(outfile,")\n");
4583 ast_print(tree->left,outfile,indent+4);
4584 ast_print(tree->right,outfile,indent+4);
4587 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4588 printTypeChain(tree->ftype,outfile);
4589 fprintf(outfile,")\n");
4590 ast_print(tree->left,outfile,indent+4);
4591 ast_print(tree->right,outfile,indent+4);
4593 /*------------------------------------------------------------------*/
4594 /*----------------------------*/
4596 /*----------------------------*/
4597 case CAST: /* change the type */
4598 fprintf(outfile,"CAST (%p) from type (",tree);
4599 printTypeChain(tree->right->ftype,outfile);
4600 fprintf(outfile,") to type (");
4601 printTypeChain(tree->ftype,outfile);
4602 fprintf(outfile,")\n");
4603 ast_print(tree->right,outfile,indent+4);
4607 fprintf(outfile,"ANDAND (%p) type (",tree);
4608 printTypeChain(tree->ftype,outfile);
4609 fprintf(outfile,")\n");
4610 ast_print(tree->left,outfile,indent+4);
4611 ast_print(tree->right,outfile,indent+4);
4614 fprintf(outfile,"OROR (%p) type (",tree);
4615 printTypeChain(tree->ftype,outfile);
4616 fprintf(outfile,")\n");
4617 ast_print(tree->left,outfile,indent+4);
4618 ast_print(tree->right,outfile,indent+4);
4621 /*------------------------------------------------------------------*/
4622 /*----------------------------*/
4623 /* comparison operators */
4624 /*----------------------------*/
4626 fprintf(outfile,"GT(>) (%p) type (",tree);
4627 printTypeChain(tree->ftype,outfile);
4628 fprintf(outfile,")\n");
4629 ast_print(tree->left,outfile,indent+4);
4630 ast_print(tree->right,outfile,indent+4);
4633 fprintf(outfile,"LT(<) (%p) type (",tree);
4634 printTypeChain(tree->ftype,outfile);
4635 fprintf(outfile,")\n");
4636 ast_print(tree->left,outfile,indent+4);
4637 ast_print(tree->right,outfile,indent+4);
4640 fprintf(outfile,"LE(<=) (%p) type (",tree);
4641 printTypeChain(tree->ftype,outfile);
4642 fprintf(outfile,")\n");
4643 ast_print(tree->left,outfile,indent+4);
4644 ast_print(tree->right,outfile,indent+4);
4647 fprintf(outfile,"GE(>=) (%p) type (",tree);
4648 printTypeChain(tree->ftype,outfile);
4649 fprintf(outfile,")\n");
4650 ast_print(tree->left,outfile,indent+4);
4651 ast_print(tree->right,outfile,indent+4);
4654 fprintf(outfile,"EQ(==) (%p) type (",tree);
4655 printTypeChain(tree->ftype,outfile);
4656 fprintf(outfile,")\n");
4657 ast_print(tree->left,outfile,indent+4);
4658 ast_print(tree->right,outfile,indent+4);
4661 fprintf(outfile,"NE(!=) (%p) type (",tree);
4662 printTypeChain(tree->ftype,outfile);
4663 fprintf(outfile,")\n");
4664 ast_print(tree->left,outfile,indent+4);
4665 ast_print(tree->right,outfile,indent+4);
4666 /*------------------------------------------------------------------*/
4667 /*----------------------------*/
4669 /*----------------------------*/
4670 case SIZEOF: /* evaluate wihout code generation */
4671 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4674 /*------------------------------------------------------------------*/
4675 /*----------------------------*/
4676 /* conditional operator '?' */
4677 /*----------------------------*/
4679 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4680 printTypeChain(tree->ftype,outfile);
4681 fprintf(outfile,")\n");
4682 ast_print(tree->left,outfile,indent+4);
4683 ast_print(tree->right,outfile,indent+4);
4687 fprintf(outfile,"COLON(:) (%p) type (",tree);
4688 printTypeChain(tree->ftype,outfile);
4689 fprintf(outfile,")\n");
4690 ast_print(tree->left,outfile,indent+4);
4691 ast_print(tree->right,outfile,indent+4);
4694 /*------------------------------------------------------------------*/
4695 /*----------------------------*/
4696 /* assignment operators */
4697 /*----------------------------*/
4699 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4700 printTypeChain(tree->ftype,outfile);
4701 fprintf(outfile,")\n");
4702 ast_print(tree->left,outfile,indent+4);
4703 ast_print(tree->right,outfile,indent+4);
4706 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4707 printTypeChain(tree->ftype,outfile);
4708 fprintf(outfile,")\n");
4709 ast_print(tree->left,outfile,indent+4);
4710 ast_print(tree->right,outfile,indent+4);
4713 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4714 printTypeChain(tree->ftype,outfile);
4715 fprintf(outfile,")\n");
4716 ast_print(tree->left,outfile,indent+4);
4717 ast_print(tree->right,outfile,indent+4);
4720 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4721 printTypeChain(tree->ftype,outfile);
4722 fprintf(outfile,")\n");
4723 ast_print(tree->left,outfile,indent+4);
4724 ast_print(tree->right,outfile,indent+4);
4727 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4728 printTypeChain(tree->ftype,outfile);
4729 fprintf(outfile,")\n");
4730 ast_print(tree->left,outfile,indent+4);
4731 ast_print(tree->right,outfile,indent+4);
4734 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4735 printTypeChain(tree->ftype,outfile);
4736 fprintf(outfile,")\n");
4737 ast_print(tree->left,outfile,indent+4);
4738 ast_print(tree->right,outfile,indent+4);
4741 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4742 printTypeChain(tree->ftype,outfile);
4743 fprintf(outfile,")\n");
4744 ast_print(tree->left,outfile,indent+4);
4745 ast_print(tree->right,outfile,indent+4);
4747 /*------------------------------------------------------------------*/
4748 /*----------------------------*/
4750 /*----------------------------*/
4752 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4753 printTypeChain(tree->ftype,outfile);
4754 fprintf(outfile,")\n");
4755 ast_print(tree->left,outfile,indent+4);
4756 ast_print(tree->right,outfile,indent+4);
4758 /*------------------------------------------------------------------*/
4759 /*----------------------------*/
4761 /*----------------------------*/
4763 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4764 printTypeChain(tree->ftype,outfile);
4765 fprintf(outfile,")\n");
4766 ast_print(tree->left,outfile,indent+4);
4767 ast_print(tree->right,outfile,indent+4);
4769 /*------------------------------------------------------------------*/
4770 /*----------------------------*/
4771 /* straight assignemnt */
4772 /*----------------------------*/
4774 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4775 printTypeChain(tree->ftype,outfile);
4776 fprintf(outfile,")\n");
4777 ast_print(tree->left,outfile,indent+4);
4778 ast_print(tree->right,outfile,indent+4);
4780 /*------------------------------------------------------------------*/
4781 /*----------------------------*/
4782 /* comma operator */
4783 /*----------------------------*/
4785 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4786 printTypeChain(tree->ftype,outfile);
4787 fprintf(outfile,")\n");
4788 ast_print(tree->left,outfile,indent+4);
4789 ast_print(tree->right,outfile,indent+4);
4791 /*------------------------------------------------------------------*/
4792 /*----------------------------*/
4794 /*----------------------------*/
4797 fprintf(outfile,"CALL (%p) type (",tree);
4798 printTypeChain(tree->ftype,outfile);
4799 fprintf(outfile,")\n");
4800 ast_print(tree->left,outfile,indent+4);
4801 ast_print(tree->right,outfile,indent+4);
4804 fprintf(outfile,"PARMS\n");
4805 ast_print(tree->left,outfile,indent+4);
4806 if (tree->right && !IS_AST_PARAM(tree->right)) {
4807 ast_print(tree->right,outfile,indent+4);
4810 /*------------------------------------------------------------------*/
4811 /*----------------------------*/
4812 /* return statement */
4813 /*----------------------------*/
4815 fprintf(outfile,"RETURN (%p) type (",tree);
4816 printTypeChain(tree->right->ftype,outfile);
4817 fprintf(outfile,")\n");
4818 ast_print(tree->right,outfile,indent+4);
4820 /*------------------------------------------------------------------*/
4821 /*----------------------------*/
4822 /* label statement */
4823 /*----------------------------*/
4825 fprintf(outfile,"LABEL (%p)",tree);
4826 ast_print(tree->left,outfile,indent+4);
4827 ast_print(tree->right,outfile,indent);
4829 /*------------------------------------------------------------------*/
4830 /*----------------------------*/
4831 /* switch statement */
4832 /*----------------------------*/
4836 fprintf(outfile,"SWITCH (%p) ",tree);
4837 ast_print(tree->left,outfile,0);
4838 for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4839 INDENT(indent+4,outfile);
4840 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4841 (int) floatFromVal(val),
4842 tree->values.switchVals.swNum,
4843 (int) floatFromVal(val));
4845 ast_print(tree->right,outfile,indent);
4848 /*------------------------------------------------------------------*/
4849 /*----------------------------*/
4851 /*----------------------------*/
4853 fprintf(outfile,"IF (%p) \n",tree);
4854 ast_print(tree->left,outfile,indent+4);
4855 if (tree->trueLabel) {
4856 INDENT(indent,outfile);
4857 fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4859 if (tree->falseLabel) {
4860 INDENT(indent,outfile);
4861 fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4863 ast_print(tree->right,outfile,indent+4);
4865 /*------------------------------------------------------------------*/
4866 /*----------------------------*/
4868 /*----------------------------*/
4870 fprintf(outfile,"FOR (%p) \n",tree);
4871 if (AST_FOR( tree, initExpr)) {
4872 INDENT(indent+4,outfile);
4873 fprintf(outfile,"INIT EXPR ");
4874 ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4876 if (AST_FOR( tree, condExpr)) {
4877 INDENT(indent+4,outfile);
4878 fprintf(outfile,"COND EXPR ");
4879 ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4881 if (AST_FOR( tree, loopExpr)) {
4882 INDENT(indent+4,outfile);
4883 fprintf(outfile,"LOOP EXPR ");
4884 ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4886 fprintf(outfile,"FOR LOOP BODY \n");
4887 ast_print(tree->left,outfile,indent+4);
4896 ast_print(t,stdout,0);